aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/mac80211-injection.txt4
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile1
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h172
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c250
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c59
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c186
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_paprd.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c97
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h52
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_rtt.c153
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_rtt.h28
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_1p0_initvals.h (renamed from drivers/net/wireless/ath/ath9k/ar9480_1p0_initvals.h)62
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h (renamed from drivers/net/wireless/ath/ath9k/ar9480_2p0_initvals.h)68
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h13
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c29
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c35
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c45
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c158
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h39
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c25
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c35
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h29
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c40
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c1
-rw-r--r--drivers/net/wireless/b43/xmit.c18
-rw-r--r--drivers/net/wireless/b43/xmit.h10
-rw-r--r--drivers/net/wireless/brcm80211/Kconfig35
-rw-r--r--drivers/net/wireless/brcm80211/Makefile23
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile33
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h32
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c371
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c626
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h776
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h57
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c498
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c895
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h58
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c1356
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h60
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c4591
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h252
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c3868
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h375
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/Makefile51
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/aiutils.c2079
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/aiutils.h378
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ampdu.c1241
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ampdu.h30
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/antsel.c307
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/antsel.h29
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c23
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h92
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/channel.c1591
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/channel.h53
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/d11.h1898
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/dma.c1425
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/dma.h120
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c1696
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h108
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c8775
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.h735
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/nicpci.c835
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/nicpci.h82
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/otp.c426
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/otp.h36
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c2988
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h301
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h1169
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c5154
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h121
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c28876
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c308
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h42
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h1533
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h167
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c3250
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h54
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c10630
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h50
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c225
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h182
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pmu.c458
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pmu.h38
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pub.h634
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/rate.c514
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/rate.h250
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/scb.h82
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/srom.c1298
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/srom.h34
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/stf.c436
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/stf.h42
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/types.h352
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c109
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h58
-rw-r--r--drivers/net/wireless/brcm80211/brcmutil/Makefile28
-rw-r--r--drivers/net/wireless/brcm80211/brcmutil/utils.c386
-rw-r--r--drivers/net/wireless/brcm80211/include/brcm_hw_ids.h59
-rw-r--r--drivers/net/wireless/brcm80211/include/brcmu_utils.h195
-rw-r--r--drivers/net/wireless/brcm80211/include/brcmu_wifi.h239
-rw-r--r--drivers/net/wireless/brcm80211/include/chipcommon.h284
-rw-r--r--drivers/net/wireless/brcm80211/include/defs.h104
-rw-r--r--drivers/net/wireless/brcm80211/include/soc.h90
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig4
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h88
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000-hw.h81
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hw.h15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rx.c (renamed from drivers/net/wireless/iwlwifi/iwl-rx.c)112
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c861
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c126
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h131
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-cfg.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c83
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h72
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-pci.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-shared.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c835
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h141
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sv-open.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie.c21
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c6
-rw-r--r--drivers/net/wireless/libertas/cfg.c20
-rw-r--r--drivers/net/wireless/libertas/decl.h2
-rw-r--r--drivers/net/wireless/libertas/main.c32
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c3
-rw-r--r--drivers/net/wireless/mwifiex/Kconfig11
-rw-r--r--drivers/net/wireless/mwifiex/Makefile3
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c10
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c34
-rw-r--r--drivers/net/wireless/mwifiex/decl.h1
-rw-r--r--drivers/net/wireless/mwifiex/fw.h36
-rw-r--r--drivers/net/wireless/mwifiex/init.c73
-rw-r--r--drivers/net/wireless/mwifiex/main.c10
-rw-r--r--drivers/net/wireless/mwifiex/main.h35
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c1948
-rw-r--r--drivers/net/wireless/mwifiex/pcie.h148
-rw-r--r--drivers/net/wireless/mwifiex/scan.c56
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c19
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h24
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c64
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c12
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c2
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c45
-rw-r--r--drivers/net/wireless/mwifiex/util.c5
-rw-r--r--drivers/net/wireless/mwifiex/util.h9
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c4
-rw-r--r--drivers/net/wireless/rtlwifi/base.c6
-rw-r--r--drivers/net/wireless/rtlwifi/debug.c6
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c19
-rw-r--r--drivers/net/wireless/rtlwifi/pci.h4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/def.h14
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.c35
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/def.h4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c7
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/def.h135
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/hw.c15
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/sw.c21
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.c22
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/reg.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/sw.c22
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.c55
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h5
-rw-r--r--drivers/net/wireless/wl12xx/acx.c16
-rw-r--r--drivers/net/wireless/wl12xx/acx.h1
-rw-r--r--drivers/net/wireless/wl12xx/boot.c6
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c63
-rw-r--r--drivers/net/wireless/wl12xx/cmd.h20
-rw-r--r--drivers/net/wireless/wl12xx/conf.h6
-rw-r--r--drivers/net/wireless/wl12xx/event.c15
-rw-r--r--drivers/net/wireless/wl12xx/main.c48
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h7
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile4
-rw-r--r--include/linux/nl80211.h2
-rw-r--r--include/net/cfg80211.h5
-rw-r--r--include/net/mac80211.h10
-rw-r--r--net/mac80211/cfg.c22
-rw-r--r--net/mac80211/ieee80211_i.h15
-rw-r--r--net/mac80211/main.c6
-rw-r--r--net/mac80211/mesh_hwmp.c9
-rw-r--r--net/mac80211/scan.c1
-rw-r--r--net/mac80211/sta_info.c6
-rw-r--r--net/mac80211/status.c137
-rw-r--r--net/mac80211/tx.c360
-rw-r--r--net/mac80211/work.c2
-rw-r--r--net/mac80211/wpa.c3
-rw-r--r--net/wireless/nl80211.c4
226 files changed, 102247 insertions, 2686 deletions
diff --git a/Documentation/networking/mac80211-injection.txt b/Documentation/networking/mac80211-injection.txt
index b30e81ad5307..3a930072b161 100644
--- a/Documentation/networking/mac80211-injection.txt
+++ b/Documentation/networking/mac80211-injection.txt
@@ -23,6 +23,10 @@ radiotap headers and used to control injection:
23 IEEE80211_RADIOTAP_F_FRAG: frame will be fragmented if longer than the 23 IEEE80211_RADIOTAP_F_FRAG: frame will be fragmented if longer than the
24 current fragmentation threshold. 24 current fragmentation threshold.
25 25
26 * IEEE80211_RADIOTAP_TX_FLAGS
27
28 IEEE80211_RADIOTAP_F_TX_NOACK: frame should be sent without waiting for
29 an ACK even if it is a unicast frame
26 30
27The injection code can also skip all other currently defined radiotap fields 31The injection code can also skip all other currently defined radiotap fields
28facilitating replay of captured radiotap headers directly. 32facilitating replay of captured radiotap headers directly.
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index f354bd4e121e..abd3b71cd4ab 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -271,6 +271,7 @@ config MWL8K
271source "drivers/net/wireless/ath/Kconfig" 271source "drivers/net/wireless/ath/Kconfig"
272source "drivers/net/wireless/b43/Kconfig" 272source "drivers/net/wireless/b43/Kconfig"
273source "drivers/net/wireless/b43legacy/Kconfig" 273source "drivers/net/wireless/b43legacy/Kconfig"
274source "drivers/net/wireless/brcm80211/Kconfig"
274source "drivers/net/wireless/hostap/Kconfig" 275source "drivers/net/wireless/hostap/Kconfig"
275source "drivers/net/wireless/ipw2x00/Kconfig" 276source "drivers/net/wireless/ipw2x00/Kconfig"
276source "drivers/net/wireless/iwlwifi/Kconfig" 277source "drivers/net/wireless/iwlwifi/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 4cf0ad312da1..0a304b060b6c 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -58,3 +58,6 @@ obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/
58obj-$(CONFIG_IWM) += iwmc3200wifi/ 58obj-$(CONFIG_IWM) += iwmc3200wifi/
59 59
60obj-$(CONFIG_MWIFIEX) += mwifiex/ 60obj-$(CONFIG_MWIFIEX) += mwifiex/
61obj-$(CONFIG_BRCMFMAC) += brcm80211/
62obj-$(CONFIG_BRCMUMAC) += brcm80211/
63obj-$(CONFIG_BRCMSMAC) += brcm80211/
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 4ed7f248a577..908fdbc3e0ee 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -71,9 +71,7 @@ struct ath_regulatory {
71 char alpha2[2]; 71 char alpha2[2];
72 u16 country_code; 72 u16 country_code;
73 u16 max_power_level; 73 u16 max_power_level;
74 u32 tp_scale;
75 u16 current_rd; 74 u16 current_rd;
76 u16 current_rd_ext;
77 int16_t power_limit; 75 int16_t power_limit;
78 struct reg_dmn_pair_mapping *regpair; 76 struct reg_dmn_pair_mapping *regpair;
79}; 77};
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index e9ea38d0fff6..b346d0492001 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -921,12 +921,6 @@ ath5k_txq_setup(struct ath5k_hw *ah,
921 */ 921 */
922 return ERR_PTR(qnum); 922 return ERR_PTR(qnum);
923 } 923 }
924 if (qnum >= ARRAY_SIZE(ah->txqs)) {
925 ATH5K_ERR(ah, "hw qnum %u out of range, max %tu!\n",
926 qnum, ARRAY_SIZE(ah->txqs));
927 ath5k_hw_release_tx_queue(ah, qnum);
928 return ERR_PTR(-EINVAL);
929 }
930 txq = &ah->txqs[qnum]; 924 txq = &ah->txqs[qnum];
931 if (!txq->setup) { 925 if (!txq->setup) {
932 txq->qnum = qnum; 926 txq->qnum = qnum;
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 05a6fade7b1c..36ed3c46fec6 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -21,6 +21,7 @@ ath9k_hw-y:= \
21 ar5008_phy.o \ 21 ar5008_phy.o \
22 ar9002_calib.o \ 22 ar9002_calib.o \
23 ar9003_calib.o \ 23 ar9003_calib.o \
24 ar9003_rtt.o \
24 calib.o \ 25 calib.o \
25 eeprom.o \ 26 eeprom.o \
26 eeprom_def.o \ 27 eeprom_def.o \
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 01240d63896e..2776c3c1f506 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -504,9 +504,6 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
504 ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR, 504 ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
505 ATH9K_ANI_CCK_WEAK_SIG_THR); 505 ATH9K_ANI_CCK_WEAK_SIG_THR);
506 506
507 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
508 ATH9K_RX_FILTER_PHYERR);
509
510 ath9k_ani_restart(ah); 507 ath9k_ani_restart(ah);
511 return; 508 return;
512 } 509 }
@@ -527,8 +524,6 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
527 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 524 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
528 aniState->firstepLevel); 525 aniState->firstepLevel);
529 526
530 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
531 ~ATH9K_RX_FILTER_PHYERR);
532 ath9k_ani_restart(ah); 527 ath9k_ani_restart(ah);
533 528
534 ENABLE_REGWRITE_BUFFER(ah); 529 ENABLE_REGWRITE_BUFFER(ah);
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 0a749c8fa634..f199e9e25149 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -763,10 +763,8 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
763static int ar5008_hw_process_ini(struct ath_hw *ah, 763static int ar5008_hw_process_ini(struct ath_hw *ah,
764 struct ath9k_channel *chan) 764 struct ath9k_channel *chan)
765{ 765{
766 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
767 struct ath_common *common = ath9k_hw_common(ah); 766 struct ath_common *common = ath9k_hw_common(ah);
768 int i, regWrites = 0; 767 int i, regWrites = 0;
769 struct ieee80211_channel *channel = chan->chan;
770 u32 modesIndex, freqIndex; 768 u32 modesIndex, freqIndex;
771 769
772 switch (chan->chanmode) { 770 switch (chan->chanmode) {
@@ -903,14 +901,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
903 ar5008_hw_set_channel_regs(ah, chan); 901 ar5008_hw_set_channel_regs(ah, chan);
904 ar5008_hw_init_chain_masks(ah); 902 ar5008_hw_init_chain_masks(ah);
905 ath9k_olc_init(ah); 903 ath9k_olc_init(ah);
906 904 ath9k_hw_apply_txpower(ah, chan);
907 /* Set TX power */
908 ah->eep_ops->set_txpower(ah, chan,
909 ath9k_regd_get_ctl(regulatory, chan),
910 channel->max_antenna_gain * 2,
911 channel->max_power * 2,
912 min((u32) MAX_RATE_POWER,
913 (u32) regulatory->power_limit), false);
914 905
915 /* Write analog registers */ 906 /* Write analog registers */
916 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { 907 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index 08e9341f6368..026f9de15d15 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -24,11 +24,11 @@ static const u32 ar9300_2p2_radio_postamble[][5] = {
24 {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31}, 24 {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
25 {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800}, 25 {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
26 {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20}, 26 {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
27 {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, 27 {0x0001610c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
28 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 28 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
29 {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, 29 {0x0001650c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
30 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 30 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
31 {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, 31 {0x0001690c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
32 {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 32 {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
33}; 33};
34 34
@@ -190,7 +190,7 @@ static const u32 ar9300_2p2_radio_core[][2] = {
190 {0x00016288, 0x05a20408}, 190 {0x00016288, 0x05a20408},
191 {0x0001628c, 0x00038c07}, 191 {0x0001628c, 0x00038c07},
192 {0x00016290, 0x00000004}, 192 {0x00016290, 0x00000004},
193 {0x00016294, 0x458aa14f}, 193 {0x00016294, 0x458a214f},
194 {0x00016380, 0x00000000}, 194 {0x00016380, 0x00000000},
195 {0x00016384, 0x00000000}, 195 {0x00016384, 0x00000000},
196 {0x00016388, 0x00800700}, 196 {0x00016388, 0x00800700},
@@ -835,107 +835,107 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
835 835
836static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { 836static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
837 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 837 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
838 {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, 838 {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
839 {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, 839 {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
840 {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, 840 {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
841 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 841 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
842 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, 842 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
843 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 843 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
844 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, 844 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
845 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, 845 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
846 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, 846 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
847 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, 847 {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
848 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, 848 {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
849 {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402}, 849 {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
850 {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, 850 {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
851 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, 851 {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
852 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, 852 {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
853 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, 853 {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
854 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, 854 {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
855 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, 855 {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
856 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, 856 {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
857 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, 857 {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
858 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, 858 {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
859 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, 859 {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
860 {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861}, 860 {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
861 {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81}, 861 {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
862 {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83}, 862 {0x0000a54c, 0x5a08442e, 0x5a08442e, 0x47001a83, 0x47001a83},
863 {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84}, 863 {0x0000a550, 0x5e0a4431, 0x5e0a4431, 0x4a001c84, 0x4a001c84},
864 {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3}, 864 {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
865 {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5}, 865 {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
866 {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9}, 866 {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
867 {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb}, 867 {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
868 {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, 868 {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
869 {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, 869 {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
870 {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, 870 {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
871 {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, 871 {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
872 {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, 872 {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
873 {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, 873 {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
874 {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, 874 {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
875 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, 875 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
876 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, 876 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
877 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, 877 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
878 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, 878 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
879 {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, 879 {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202},
880 {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, 880 {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400},
881 {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402}, 881 {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402},
882 {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404}, 882 {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404},
883 {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, 883 {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603},
884 {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, 884 {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02},
885 {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, 885 {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04},
886 {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, 886 {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20},
887 {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, 887 {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20},
888 {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, 888 {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22},
889 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, 889 {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24},
890 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, 890 {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640},
891 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, 891 {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660},
892 {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861}, 892 {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861},
893 {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81}, 893 {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81},
894 {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83}, 894 {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83},
895 {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84}, 895 {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84},
896 {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3}, 896 {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3},
897 {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5}, 897 {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5},
898 {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9}, 898 {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9},
899 {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb}, 899 {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb},
900 {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, 900 {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
901 {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, 901 {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
902 {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, 902 {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
903 {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, 903 {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
904 {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, 904 {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
905 {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, 905 {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
906 {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, 906 {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
907 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 907 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
908 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 908 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
909 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 909 {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
910 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 910 {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
911 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 911 {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
912 {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000}, 912 {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
913 {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501}, 913 {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
914 {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501}, 914 {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
915 {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03}, 915 {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
916 {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04}, 916 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
917 {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04}, 917 {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
918 {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, 918 {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
919 {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, 919 {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
920 {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, 920 {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
921 {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, 921 {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
922 {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, 922 {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
923 {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, 923 {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
924 {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, 924 {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
925 {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, 925 {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
926 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 926 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
927 {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, 927 {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
928 {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, 928 {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
929 {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, 929 {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
930 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 930 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
931 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, 931 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
932 {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, 932 {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
933 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 933 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
934 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, 934 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
935 {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, 935 {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
936 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 936 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
937 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, 937 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
938 {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, 938 {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
939 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 939 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
940}; 940};
941 941
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index e4b1a8300854..16851cb109a6 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -17,8 +17,9 @@
17#include "hw.h" 17#include "hw.h"
18#include "hw-ops.h" 18#include "hw-ops.h"
19#include "ar9003_phy.h" 19#include "ar9003_phy.h"
20#include "ar9003_rtt.h"
20 21
21#define MAX_MEASUREMENT 8 22#define MAX_MEASUREMENT MAX_IQCAL_MEASUREMENT
22#define MAX_MAG_DELTA 11 23#define MAX_MAG_DELTA 11
23#define MAX_PHS_DELTA 10 24#define MAX_PHS_DELTA 10
24 25
@@ -659,10 +660,12 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
659 660
660static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, 661static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
661 u8 num_chains, 662 u8 num_chains,
662 struct coeff *coeff) 663 struct coeff *coeff,
664 bool is_reusable)
663{ 665{
664 int i, im, nmeasurement; 666 int i, im, nmeasurement;
665 u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; 667 u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
668 struct ath9k_hw_cal_data *caldata = ah->caldata;
666 669
667 memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff)); 670 memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
668 for (i = 0; i < MAX_MEASUREMENT / 2; i++) { 671 for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
@@ -712,7 +715,13 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
712 REG_RMW_FIELD(ah, tx_corr_coeff[im][i], 715 REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
713 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, 716 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
714 coeff->iqc_coeff[0]); 717 coeff->iqc_coeff[0]);
718
719 if (caldata)
720 caldata->tx_corr_coeff[im][i] =
721 coeff->iqc_coeff[0];
715 } 722 }
723 if (caldata)
724 caldata->num_measures[i] = nmeasurement;
716 } 725 }
717 726
718 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, 727 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
@@ -720,8 +729,10 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
720 REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, 729 REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
721 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); 730 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
722 731
723 return; 732 if (caldata)
733 caldata->done_txiqcal_once = is_reusable;
724 734
735 return;
725} 736}
726 737
727static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah) 738static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
@@ -748,7 +759,7 @@ static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
748 return true; 759 return true;
749} 760}
750 761
751static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) 762static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable)
752{ 763{
753 struct ath_common *common = ath9k_hw_common(ah); 764 struct ath_common *common = ath9k_hw_common(ah);
754 const u32 txiqcal_status[AR9300_MAX_CHAINS] = { 765 const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
@@ -837,7 +848,8 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
837 coeff.phs_coeff[i][im] -= 128; 848 coeff.phs_coeff[i][im] -= 128;
838 } 849 }
839 } 850 }
840 ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff); 851 ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains,
852 &coeff, is_reusable);
841 853
842 return; 854 return;
843 855
@@ -845,11 +857,129 @@ tx_iqcal_fail:
845 ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n"); 857 ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
846 return; 858 return;
847} 859}
860
861static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah)
862{
863 struct ath9k_hw_cal_data *caldata = ah->caldata;
864 u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
865 int i, im;
866
867 memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
868 for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
869 tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] =
870 AR_PHY_TX_IQCAL_CORR_COEFF_B0(i);
871 if (!AR_SREV_9485(ah)) {
872 tx_corr_coeff[i * 2][1] =
873 tx_corr_coeff[(i * 2) + 1][1] =
874 AR_PHY_TX_IQCAL_CORR_COEFF_B1(i);
875
876 tx_corr_coeff[i * 2][2] =
877 tx_corr_coeff[(i * 2) + 1][2] =
878 AR_PHY_TX_IQCAL_CORR_COEFF_B2(i);
879 }
880 }
881
882 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
883 if (!(ah->txchainmask & (1 << i)))
884 continue;
885
886 for (im = 0; im < caldata->num_measures[i]; im++) {
887 if ((im % 2) == 0)
888 REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
889 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
890 caldata->tx_corr_coeff[im][i]);
891 else
892 REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
893 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
894 caldata->tx_corr_coeff[im][i]);
895 }
896 }
897
898 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
899 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
900 REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
901 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
902}
903
904static bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
905{
906 struct ath9k_rtt_hist *hist;
907 u32 *table;
908 int i;
909 bool restore;
910
911 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT) || !ah->caldata)
912 return false;
913
914 hist = &ah->caldata->rtt_hist;
915 ar9003_hw_rtt_enable(ah);
916 ar9003_hw_rtt_set_mask(ah, 0x10);
917 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
918 if (!(ah->rxchainmask & (1 << i)))
919 continue;
920 table = &hist->table[i][hist->num_readings][0];
921 ar9003_hw_rtt_load_hist(ah, i, table);
922 }
923 restore = ar9003_hw_rtt_force_restore(ah);
924 ar9003_hw_rtt_disable(ah);
925
926 return restore;
927}
928
848static bool ar9003_hw_init_cal(struct ath_hw *ah, 929static bool ar9003_hw_init_cal(struct ath_hw *ah,
849 struct ath9k_channel *chan) 930 struct ath9k_channel *chan)
850{ 931{
851 struct ath_common *common = ath9k_hw_common(ah); 932 struct ath_common *common = ath9k_hw_common(ah);
852 bool txiqcal_done = false; 933 struct ath9k_hw_cal_data *caldata = ah->caldata;
934 bool txiqcal_done = false, txclcal_done = false;
935 bool is_reusable = true, status = true;
936 bool run_rtt_cal = false, run_agc_cal;
937 bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT);
938 u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL |
939 AR_PHY_AGC_CONTROL_FLTR_CAL |
940 AR_PHY_AGC_CONTROL_PKDET_CAL;
941 int i, j;
942 u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0,
943 AR_PHY_CL_TAB_1,
944 AR_PHY_CL_TAB_2 };
945
946 if (rtt) {
947 if (!ar9003_hw_rtt_restore(ah, chan))
948 run_rtt_cal = true;
949
950 ath_dbg(common, ATH_DBG_CALIBRATE, "RTT restore %s\n",
951 run_rtt_cal ? "failed" : "succeed");
952 }
953 run_agc_cal = run_rtt_cal;
954
955 if (run_rtt_cal) {
956 ar9003_hw_rtt_enable(ah);
957 ar9003_hw_rtt_set_mask(ah, 0x00);
958 ar9003_hw_rtt_clear_hist(ah);
959 }
960
961 if (rtt && !run_rtt_cal) {
962 agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL);
963 agc_supp_cals &= agc_ctrl;
964 agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL |
965 AR_PHY_AGC_CONTROL_FLTR_CAL |
966 AR_PHY_AGC_CONTROL_PKDET_CAL);
967 REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl);
968 }
969
970 if (ah->enabled_cals & TX_CL_CAL) {
971 if (caldata && caldata->done_txclcal_once)
972 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL,
973 AR_PHY_CL_CAL_ENABLE);
974 else {
975 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL,
976 AR_PHY_CL_CAL_ENABLE);
977 run_agc_cal = true;
978 }
979 }
980
981 if (!(ah->enabled_cals & TX_IQ_CAL))
982 goto skip_tx_iqcal;
853 983
854 /* Do Tx IQ Calibration */ 984 /* Do Tx IQ Calibration */
855 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, 985 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
@@ -860,30 +990,96 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
860 * For AR9485 or later chips, TxIQ cal runs as part of 990 * For AR9485 or later chips, TxIQ cal runs as part of
861 * AGC calibration 991 * AGC calibration
862 */ 992 */
863 if (AR_SREV_9485_OR_LATER(ah)) 993 if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
864 txiqcal_done = true; 994 if (caldata && !caldata->done_txiqcal_once)
865 else { 995 REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
866 txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); 996 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
867 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); 997 else
868 udelay(5); 998 REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
869 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 999 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
870 } 1000 txiqcal_done = run_agc_cal = true;
871 1001 goto skip_tx_iqcal;
872 /* Calibrate the AGC */ 1002 } else if (caldata && !caldata->done_txiqcal_once)
873 REG_WRITE(ah, AR_PHY_AGC_CONTROL, 1003 run_agc_cal = true;
874 REG_READ(ah, AR_PHY_AGC_CONTROL) | 1004
875 AR_PHY_AGC_CONTROL_CAL); 1005 txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
876 1006 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
877 /* Poll for offset calibration complete */ 1007 udelay(5);
878 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 1008 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
879 0, AH_WAIT_TIMEOUT)) { 1009
1010skip_tx_iqcal:
1011 if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
1012 /* Calibrate the AGC */
1013 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
1014 REG_READ(ah, AR_PHY_AGC_CONTROL) |
1015 AR_PHY_AGC_CONTROL_CAL);
1016
1017 /* Poll for offset calibration complete */
1018 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
1019 AR_PHY_AGC_CONTROL_CAL,
1020 0, AH_WAIT_TIMEOUT);
1021 }
1022 if (rtt && !run_rtt_cal) {
1023 agc_ctrl |= agc_supp_cals;
1024 REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl);
1025 }
1026
1027 if (!status) {
1028 if (run_rtt_cal)
1029 ar9003_hw_rtt_disable(ah);
1030
880 ath_dbg(common, ATH_DBG_CALIBRATE, 1031 ath_dbg(common, ATH_DBG_CALIBRATE,
881 "offset calibration failed to complete in 1ms; noisy environment?\n"); 1032 "offset calibration failed to complete in 1ms;"
1033 "noisy environment?\n");
882 return false; 1034 return false;
883 } 1035 }
884 1036
885 if (txiqcal_done) 1037 if (txiqcal_done)
886 ar9003_hw_tx_iq_cal_post_proc(ah); 1038 ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
1039 else if (caldata && caldata->done_txiqcal_once)
1040 ar9003_hw_tx_iq_cal_reload(ah);
1041
1042#define CL_TAB_ENTRY(reg_base) (reg_base + (4 * j))
1043 if (caldata && (ah->enabled_cals & TX_CL_CAL)) {
1044 txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) &
1045 AR_PHY_AGC_CONTROL_CLC_SUCCESS);
1046 if (caldata->done_txclcal_once) {
1047 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1048 if (!(ah->txchainmask & (1 << i)))
1049 continue;
1050 for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
1051 REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]),
1052 caldata->tx_clcal[i][j]);
1053 }
1054 } else if (is_reusable && txclcal_done) {
1055 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1056 if (!(ah->txchainmask & (1 << i)))
1057 continue;
1058 for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
1059 caldata->tx_clcal[i][j] =
1060 REG_READ(ah,
1061 CL_TAB_ENTRY(cl_idx[i]));
1062 }
1063 caldata->done_txclcal_once = true;
1064 }
1065 }
1066#undef CL_TAB_ENTRY
1067
1068 if (run_rtt_cal && caldata) {
1069 struct ath9k_rtt_hist *hist = &caldata->rtt_hist;
1070 if (is_reusable && (hist->num_readings < RTT_HIST_MAX)) {
1071 u32 *table;
1072
1073 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1074 if (!(ah->rxchainmask & (1 << i)))
1075 continue;
1076 table = &hist->table[i][hist->num_readings][0];
1077 ar9003_hw_rtt_fill_hist(ah, i, table);
1078 }
1079 }
1080
1081 ar9003_hw_rtt_disable(ah);
1082 }
887 1083
888 ath9k_hw_loadnf(ah, chan); 1084 ath9k_hw_loadnf(ah, chan);
889 ath9k_hw_start_nfcal(ah, true); 1085 ath9k_hw_start_nfcal(ah, true);
@@ -912,8 +1108,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
912 if (ah->cal_list_curr) 1108 if (ah->cal_list_curr)
913 ath9k_hw_reset_calibration(ah, ah->cal_list_curr); 1109 ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
914 1110
915 if (ah->caldata) 1111 if (caldata)
916 ah->caldata->CalValid = 0; 1112 caldata->CalValid = 0;
917 1113
918 return true; 1114 return true;
919} 1115}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 51398f0063e2..3b262ba6b172 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -2995,8 +2995,6 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
2995 return get_unaligned_be16(eep->macAddr + 4); 2995 return get_unaligned_be16(eep->macAddr + 4);
2996 case EEP_REG_0: 2996 case EEP_REG_0:
2997 return le16_to_cpu(pBase->regDmn[0]); 2997 return le16_to_cpu(pBase->regDmn[0]);
2998 case EEP_REG_1:
2999 return le16_to_cpu(pBase->regDmn[1]);
3000 case EEP_OP_CAP: 2998 case EEP_OP_CAP:
3001 return pBase->deviceCap; 2999 return pBase->deviceCap;
3002 case EEP_OP_MODE: 3000 case EEP_OP_MODE:
@@ -3021,6 +3019,10 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
3021 return (pBase->miscConfiguration >> 0x3) & 0x1; 3019 return (pBase->miscConfiguration >> 0x3) & 0x1;
3022 case EEP_ANT_DIV_CTL1: 3020 case EEP_ANT_DIV_CTL1:
3023 return eep->base_ext1.ant_div_control; 3021 return eep->base_ext1.ant_div_control;
3022 case EEP_ANTENNA_GAIN_5G:
3023 return eep->modalHeader5G.antennaGain;
3024 case EEP_ANTENNA_GAIN_2G:
3025 return eep->modalHeader2G.antennaGain;
3024 default: 3026 default:
3025 return 0; 3027 return 0;
3026 } 3028 }
@@ -3554,7 +3556,7 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3554 3556
3555 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) 3557 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
3556 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); 3558 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3557 else if (AR_SREV_9480(ah)) 3559 else if (AR_SREV_9462(ah))
3558 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); 3560 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3559 else { 3561 else {
3560 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); 3562 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
@@ -3633,20 +3635,20 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3633 3635
3634 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz); 3636 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
3635 3637
3636 if (AR_SREV_9480(ah)) { 3638 if (AR_SREV_9462(ah)) {
3637 if (AR_SREV_9480_10(ah)) { 3639 if (AR_SREV_9462_10(ah)) {
3638 value &= ~AR_SWITCH_TABLE_COM_SPDT; 3640 value &= ~AR_SWITCH_TABLE_COM_SPDT;
3639 value |= 0x00100000; 3641 value |= 0x00100000;
3640 } 3642 }
3641 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 3643 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3642 AR_SWITCH_TABLE_COM_AR9480_ALL, value); 3644 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3643 } else 3645 } else
3644 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 3646 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3645 AR_SWITCH_TABLE_COM_ALL, value); 3647 AR_SWITCH_TABLE_COM_ALL, value);
3646 3648
3647 3649
3648 /* 3650 /*
3649 * AR9480 defines new switch table for BT/WLAN, 3651 * AR9462 defines new switch table for BT/WLAN,
3650 * here's new field name in XXX.ref for both 2G and 5G. 3652 * here's new field name in XXX.ref for both 2G and 5G.
3651 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044) 3653 * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
3652 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX 3654 * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
@@ -3658,7 +3660,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3658 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE 3660 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3659 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE 3661 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3660 */ 3662 */
3661 if (AR_SREV_9480_20_OR_LATER(ah)) { 3663 if (AR_SREV_9462_20_OR_LATER(ah)) {
3662 value = ar9003_switch_com_spdt_get(ah, is2ghz); 3664 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3663 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, 3665 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3664 AR_SWITCH_TABLE_COM_SPDT_ALL, value); 3666 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
@@ -3907,7 +3909,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3907 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set); 3909 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3908 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set)) 3910 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3909 return; 3911 return;
3910 } else if (AR_SREV_9480(ah)) { 3912 } else if (AR_SREV_9462(ah)) {
3911 reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG); 3913 reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
3912 REG_WRITE(ah, AR_PHY_PMU1, reg_val); 3914 REG_WRITE(ah, AR_PHY_PMU1, reg_val);
3913 } else { 3915 } else {
@@ -3938,7 +3940,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3938 while (!REG_READ_FIELD(ah, AR_PHY_PMU2, 3940 while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
3939 AR_PHY_PMU2_PGM)) 3941 AR_PHY_PMU2_PGM))
3940 udelay(10); 3942 udelay(10);
3941 } else if (AR_SREV_9480(ah)) 3943 } else if (AR_SREV_9462(ah))
3942 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1); 3944 REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
3943 else { 3945 else {
3944 reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) | 3946 reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
@@ -4525,7 +4527,7 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah,
4525 4527
4526 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope); 4528 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
4527 4529
4528 if (AR_SREV_9480_20(ah)) 4530 if (AR_SREV_9462_20(ah))
4529 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, 4531 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4530 AR_PHY_TPC_19_B1_ALPHA_THERM, tempSlope); 4532 AR_PHY_TPC_19_B1_ALPHA_THERM, tempSlope);
4531 4533
@@ -4764,20 +4766,14 @@ static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
4764static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, 4766static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4765 struct ath9k_channel *chan, 4767 struct ath9k_channel *chan,
4766 u8 *pPwrArray, u16 cfgCtl, 4768 u8 *pPwrArray, u16 cfgCtl,
4767 u8 twiceAntennaReduction, 4769 u8 antenna_reduction,
4768 u8 twiceMaxRegulatoryPower,
4769 u16 powerLimit) 4770 u16 powerLimit)
4770{ 4771{
4771 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
4772 struct ath_common *common = ath9k_hw_common(ah); 4772 struct ath_common *common = ath9k_hw_common(ah);
4773 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep; 4773 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
4774 u16 twiceMaxEdgePower = MAX_RATE_POWER; 4774 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4775 static const u16 tpScaleReductionTable[5] = {
4776 0, 3, 6, 9, MAX_RATE_POWER
4777 };
4778 int i; 4775 int i;
4779 int16_t twiceLargestAntenna; 4776 u16 scaledPower = 0, minCtlPower;
4780 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
4781 static const u16 ctlModesFor11a[] = { 4777 static const u16 ctlModesFor11a[] = {
4782 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 4778 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
4783 }; 4779 };
@@ -4795,28 +4791,7 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4795 bool is2ghz = IS_CHAN_2GHZ(chan); 4791 bool is2ghz = IS_CHAN_2GHZ(chan);
4796 4792
4797 ath9k_hw_get_channel_centers(ah, chan, &centers); 4793 ath9k_hw_get_channel_centers(ah, chan, &centers);
4798 4794 scaledPower = powerLimit - antenna_reduction;
4799 /* Compute TxPower reduction due to Antenna Gain */
4800 if (is2ghz)
4801 twiceLargestAntenna = pEepData->modalHeader2G.antennaGain;
4802 else
4803 twiceLargestAntenna = pEepData->modalHeader5G.antennaGain;
4804
4805 twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) -
4806 twiceLargestAntenna, 0);
4807
4808 /*
4809 * scaledPower is the minimum of the user input power level
4810 * and the regulatory allowed power level
4811 */
4812 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
4813
4814 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
4815 maxRegAllowedPower -=
4816 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
4817 }
4818
4819 scaledPower = min(powerLimit, maxRegAllowedPower);
4820 4795
4821 /* 4796 /*
4822 * Reduce scaled Power by number of chains active to get 4797 * Reduce scaled Power by number of chains active to get
@@ -5003,7 +4978,6 @@ static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
5003static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, 4978static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5004 struct ath9k_channel *chan, u16 cfgCtl, 4979 struct ath9k_channel *chan, u16 cfgCtl,
5005 u8 twiceAntennaReduction, 4980 u8 twiceAntennaReduction,
5006 u8 twiceMaxRegulatoryPower,
5007 u8 powerLimit, bool test) 4981 u8 powerLimit, bool test)
5008{ 4982{
5009 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 4983 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
@@ -5056,7 +5030,6 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5056 ar9003_hw_set_power_per_rate_table(ah, chan, 5030 ar9003_hw_set_power_per_rate_table(ah, chan,
5057 targetPowerValT2, cfgCtl, 5031 targetPowerValT2, cfgCtl,
5058 twiceAntennaReduction, 5032 twiceAntennaReduction,
5059 twiceMaxRegulatoryPower,
5060 powerLimit); 5033 powerLimit);
5061 5034
5062 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) { 5035 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 901f417bb036..fb937ba93e0c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -22,8 +22,8 @@
22#include "ar9330_1p1_initvals.h" 22#include "ar9330_1p1_initvals.h"
23#include "ar9330_1p2_initvals.h" 23#include "ar9330_1p2_initvals.h"
24#include "ar9580_1p0_initvals.h" 24#include "ar9580_1p0_initvals.h"
25#include "ar9480_1p0_initvals.h" 25#include "ar9462_1p0_initvals.h"
26#include "ar9480_2p0_initvals.h" 26#include "ar9462_2p0_initvals.h"
27 27
28/* General hardware code for the AR9003 hadware family */ 28/* General hardware code for the AR9003 hadware family */
29 29
@@ -35,13 +35,13 @@
35static void ar9003_hw_init_mode_regs(struct ath_hw *ah) 35static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
36{ 36{
37#define PCIE_PLL_ON_CREQ_DIS_L1_2P0 \ 37#define PCIE_PLL_ON_CREQ_DIS_L1_2P0 \
38 ar9480_pciephy_pll_on_clkreq_disable_L1_2p0 38 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0
39 39
40#define AR9480_BB_CTX_COEFJ(x) \ 40#define AR9462_BB_CTX_COEFJ(x) \
41 ar9480_##x##_baseband_core_txfir_coeff_japan_2484 41 ar9462_##x##_baseband_core_txfir_coeff_japan_2484
42 42
43#define AR9480_BBC_TXIFR_COEFFJ \ 43#define AR9462_BBC_TXIFR_COEFFJ \
44 ar9480_2p0_baseband_core_txfir_coeff_japan_2484 44 ar9462_2p0_baseband_core_txfir_coeff_japan_2484
45 if (AR_SREV_9330_11(ah)) { 45 if (AR_SREV_9330_11(ah)) {
46 /* mac */ 46 /* mac */
47 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); 47 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
@@ -264,107 +264,107 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
264 ar9485_1_1_pcie_phy_clkreq_disable_L1, 264 ar9485_1_1_pcie_phy_clkreq_disable_L1,
265 ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), 265 ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
266 2); 266 2);
267 } else if (AR_SREV_9480_10(ah)) { 267 } else if (AR_SREV_9462_10(ah)) {
268 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); 268 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
269 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9480_1p0_mac_core, 269 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_1p0_mac_core,
270 ARRAY_SIZE(ar9480_1p0_mac_core), 2); 270 ARRAY_SIZE(ar9462_1p0_mac_core), 2);
271 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], 271 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
272 ar9480_1p0_mac_postamble, 272 ar9462_1p0_mac_postamble,
273 ARRAY_SIZE(ar9480_1p0_mac_postamble), 273 ARRAY_SIZE(ar9462_1p0_mac_postamble),
274 5); 274 5);
275 275
276 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); 276 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
277 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], 277 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
278 ar9480_1p0_baseband_core, 278 ar9462_1p0_baseband_core,
279 ARRAY_SIZE(ar9480_1p0_baseband_core), 279 ARRAY_SIZE(ar9462_1p0_baseband_core),
280 2); 280 2);
281 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], 281 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
282 ar9480_1p0_baseband_postamble, 282 ar9462_1p0_baseband_postamble,
283 ARRAY_SIZE(ar9480_1p0_baseband_postamble), 5); 283 ARRAY_SIZE(ar9462_1p0_baseband_postamble), 5);
284 284
285 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); 285 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
286 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], 286 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
287 ar9480_1p0_radio_core, 287 ar9462_1p0_radio_core,
288 ARRAY_SIZE(ar9480_1p0_radio_core), 2); 288 ARRAY_SIZE(ar9462_1p0_radio_core), 2);
289 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], 289 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
290 ar9480_1p0_radio_postamble, 290 ar9462_1p0_radio_postamble,
291 ARRAY_SIZE(ar9480_1p0_radio_postamble), 5); 291 ARRAY_SIZE(ar9462_1p0_radio_postamble), 5);
292 292
293 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], 293 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
294 ar9480_1p0_soc_preamble, 294 ar9462_1p0_soc_preamble,
295 ARRAY_SIZE(ar9480_1p0_soc_preamble), 2); 295 ARRAY_SIZE(ar9462_1p0_soc_preamble), 2);
296 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); 296 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
297 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], 297 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
298 ar9480_1p0_soc_postamble, 298 ar9462_1p0_soc_postamble,
299 ARRAY_SIZE(ar9480_1p0_soc_postamble), 5); 299 ARRAY_SIZE(ar9462_1p0_soc_postamble), 5);
300 300
301 INIT_INI_ARRAY(&ah->iniModesRxGain, 301 INIT_INI_ARRAY(&ah->iniModesRxGain,
302 ar9480_common_rx_gain_table_1p0, 302 ar9462_common_rx_gain_table_1p0,
303 ARRAY_SIZE(ar9480_common_rx_gain_table_1p0), 2); 303 ARRAY_SIZE(ar9462_common_rx_gain_table_1p0), 2);
304 304
305 /* Awake -> Sleep Setting */ 305 /* Awake -> Sleep Setting */
306 INIT_INI_ARRAY(&ah->iniPcieSerdes, 306 INIT_INI_ARRAY(&ah->iniPcieSerdes,
307 ar9480_pcie_phy_clkreq_disable_L1_1p0, 307 ar9462_pcie_phy_clkreq_disable_L1_1p0,
308 ARRAY_SIZE(ar9480_pcie_phy_clkreq_disable_L1_1p0), 308 ARRAY_SIZE(ar9462_pcie_phy_clkreq_disable_L1_1p0),
309 2); 309 2);
310 310
311 /* Sleep -> Awake Setting */ 311 /* Sleep -> Awake Setting */
312 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, 312 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
313 ar9480_pcie_phy_clkreq_disable_L1_1p0, 313 ar9462_pcie_phy_clkreq_disable_L1_1p0,
314 ARRAY_SIZE(ar9480_pcie_phy_clkreq_disable_L1_1p0), 314 ARRAY_SIZE(ar9462_pcie_phy_clkreq_disable_L1_1p0),
315 2); 315 2);
316 316
317 INIT_INI_ARRAY(&ah->iniModesAdditional, 317 INIT_INI_ARRAY(&ah->iniModesAdditional,
318 ar9480_modes_fast_clock_1p0, 318 ar9462_modes_fast_clock_1p0,
319 ARRAY_SIZE(ar9480_modes_fast_clock_1p0), 3); 319 ARRAY_SIZE(ar9462_modes_fast_clock_1p0), 3);
320 INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 320 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
321 AR9480_BB_CTX_COEFJ(1p0), 321 AR9462_BB_CTX_COEFJ(1p0),
322 ARRAY_SIZE(AR9480_BB_CTX_COEFJ(1p0)), 2); 322 ARRAY_SIZE(AR9462_BB_CTX_COEFJ(1p0)), 2);
323 323
324 } else if (AR_SREV_9480_20(ah)) { 324 } else if (AR_SREV_9462_20(ah)) {
325 325
326 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); 326 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
327 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9480_2p0_mac_core, 327 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core,
328 ARRAY_SIZE(ar9480_2p0_mac_core), 2); 328 ARRAY_SIZE(ar9462_2p0_mac_core), 2);
329 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], 329 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
330 ar9480_2p0_mac_postamble, 330 ar9462_2p0_mac_postamble,
331 ARRAY_SIZE(ar9480_2p0_mac_postamble), 5); 331 ARRAY_SIZE(ar9462_2p0_mac_postamble), 5);
332 332
333 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); 333 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
334 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], 334 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
335 ar9480_2p0_baseband_core, 335 ar9462_2p0_baseband_core,
336 ARRAY_SIZE(ar9480_2p0_baseband_core), 2); 336 ARRAY_SIZE(ar9462_2p0_baseband_core), 2);
337 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], 337 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
338 ar9480_2p0_baseband_postamble, 338 ar9462_2p0_baseband_postamble,
339 ARRAY_SIZE(ar9480_2p0_baseband_postamble), 5); 339 ARRAY_SIZE(ar9462_2p0_baseband_postamble), 5);
340 340
341 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); 341 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
342 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], 342 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
343 ar9480_2p0_radio_core, 343 ar9462_2p0_radio_core,
344 ARRAY_SIZE(ar9480_2p0_radio_core), 2); 344 ARRAY_SIZE(ar9462_2p0_radio_core), 2);
345 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], 345 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
346 ar9480_2p0_radio_postamble, 346 ar9462_2p0_radio_postamble,
347 ARRAY_SIZE(ar9480_2p0_radio_postamble), 5); 347 ARRAY_SIZE(ar9462_2p0_radio_postamble), 5);
348 INIT_INI_ARRAY(&ah->ini_radio_post_sys2ant, 348 INIT_INI_ARRAY(&ah->ini_radio_post_sys2ant,
349 ar9480_2p0_radio_postamble_sys2ant, 349 ar9462_2p0_radio_postamble_sys2ant,
350 ARRAY_SIZE(ar9480_2p0_radio_postamble_sys2ant), 350 ARRAY_SIZE(ar9462_2p0_radio_postamble_sys2ant),
351 5); 351 5);
352 352
353 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], 353 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
354 ar9480_2p0_soc_preamble, 354 ar9462_2p0_soc_preamble,
355 ARRAY_SIZE(ar9480_2p0_soc_preamble), 2); 355 ARRAY_SIZE(ar9462_2p0_soc_preamble), 2);
356 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); 356 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
357 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], 357 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
358 ar9480_2p0_soc_postamble, 358 ar9462_2p0_soc_postamble,
359 ARRAY_SIZE(ar9480_2p0_soc_postamble), 5); 359 ARRAY_SIZE(ar9462_2p0_soc_postamble), 5);
360 360
361 INIT_INI_ARRAY(&ah->iniModesRxGain, 361 INIT_INI_ARRAY(&ah->iniModesRxGain,
362 ar9480_common_rx_gain_table_2p0, 362 ar9462_common_rx_gain_table_2p0,
363 ARRAY_SIZE(ar9480_common_rx_gain_table_2p0), 2); 363 ARRAY_SIZE(ar9462_common_rx_gain_table_2p0), 2);
364 364
365 INIT_INI_ARRAY(&ah->ini_BTCOEX_MAX_TXPWR, 365 INIT_INI_ARRAY(&ah->ini_BTCOEX_MAX_TXPWR,
366 ar9480_2p0_BTCOEX_MAX_TXPWR_table, 366 ar9462_2p0_BTCOEX_MAX_TXPWR_table,
367 ARRAY_SIZE(ar9480_2p0_BTCOEX_MAX_TXPWR_table), 367 ARRAY_SIZE(ar9462_2p0_BTCOEX_MAX_TXPWR_table),
368 2); 368 2);
369 369
370 /* Awake -> Sleep Setting */ 370 /* Awake -> Sleep Setting */
@@ -380,15 +380,15 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
380 380
381 /* Fast clock modal settings */ 381 /* Fast clock modal settings */
382 INIT_INI_ARRAY(&ah->iniModesAdditional, 382 INIT_INI_ARRAY(&ah->iniModesAdditional,
383 ar9480_modes_fast_clock_2p0, 383 ar9462_modes_fast_clock_2p0,
384 ARRAY_SIZE(ar9480_modes_fast_clock_2p0), 3); 384 ARRAY_SIZE(ar9462_modes_fast_clock_2p0), 3);
385 385
386 INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 386 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
387 AR9480_BB_CTX_COEFJ(2p0), 387 AR9462_BB_CTX_COEFJ(2p0),
388 ARRAY_SIZE(AR9480_BB_CTX_COEFJ(2p0)), 2); 388 ARRAY_SIZE(AR9462_BB_CTX_COEFJ(2p0)), 2);
389 389
390 INIT_INI_ARRAY(&ah->ini_japan2484, AR9480_BBC_TXIFR_COEFFJ, 390 INIT_INI_ARRAY(&ah->ini_japan2484, AR9462_BBC_TXIFR_COEFFJ,
391 ARRAY_SIZE(AR9480_BBC_TXIFR_COEFFJ), 2); 391 ARRAY_SIZE(AR9462_BBC_TXIFR_COEFFJ), 2);
392 392
393 } else if (AR_SREV_9580(ah)) { 393 } else if (AR_SREV_9580(ah)) {
394 /* mac */ 394 /* mac */
@@ -537,15 +537,15 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
537 ar9580_1p0_lowest_ob_db_tx_gain_table, 537 ar9580_1p0_lowest_ob_db_tx_gain_table,
538 ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table), 538 ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table),
539 5); 539 5);
540 else if (AR_SREV_9480_10(ah)) 540 else if (AR_SREV_9462_10(ah))
541 INIT_INI_ARRAY(&ah->iniModesTxGain, 541 INIT_INI_ARRAY(&ah->iniModesTxGain,
542 ar9480_modes_low_ob_db_tx_gain_table_1p0, 542 ar9462_modes_low_ob_db_tx_gain_table_1p0,
543 ARRAY_SIZE(ar9480_modes_low_ob_db_tx_gain_table_1p0), 543 ARRAY_SIZE(ar9462_modes_low_ob_db_tx_gain_table_1p0),
544 5); 544 5);
545 else if (AR_SREV_9480_20(ah)) 545 else if (AR_SREV_9462_20(ah))
546 INIT_INI_ARRAY(&ah->iniModesTxGain, 546 INIT_INI_ARRAY(&ah->iniModesTxGain,
547 ar9480_modes_low_ob_db_tx_gain_table_2p0, 547 ar9462_modes_low_ob_db_tx_gain_table_2p0,
548 ARRAY_SIZE(ar9480_modes_low_ob_db_tx_gain_table_2p0), 548 ARRAY_SIZE(ar9462_modes_low_ob_db_tx_gain_table_2p0),
549 5); 549 5);
550 else 550 else
551 INIT_INI_ARRAY(&ah->iniModesTxGain, 551 INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -581,15 +581,15 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
581 ar9580_1p0_high_ob_db_tx_gain_table, 581 ar9580_1p0_high_ob_db_tx_gain_table,
582 ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table), 582 ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table),
583 5); 583 5);
584 else if (AR_SREV_9480_10(ah)) 584 else if (AR_SREV_9462_10(ah))
585 INIT_INI_ARRAY(&ah->iniModesTxGain, 585 INIT_INI_ARRAY(&ah->iniModesTxGain,
586 ar9480_modes_high_ob_db_tx_gain_table_1p0, 586 ar9462_modes_high_ob_db_tx_gain_table_1p0,
587 ARRAY_SIZE(ar9480_modes_high_ob_db_tx_gain_table_1p0), 587 ARRAY_SIZE(ar9462_modes_high_ob_db_tx_gain_table_1p0),
588 5); 588 5);
589 else if (AR_SREV_9480_20(ah)) 589 else if (AR_SREV_9462_20(ah))
590 INIT_INI_ARRAY(&ah->iniModesTxGain, 590 INIT_INI_ARRAY(&ah->iniModesTxGain,
591 ar9480_modes_high_ob_db_tx_gain_table_2p0, 591 ar9462_modes_high_ob_db_tx_gain_table_2p0,
592 ARRAY_SIZE(ar9480_modes_high_ob_db_tx_gain_table_2p0), 592 ARRAY_SIZE(ar9462_modes_high_ob_db_tx_gain_table_2p0),
593 5); 593 5);
594 else 594 else
595 INIT_INI_ARRAY(&ah->iniModesTxGain, 595 INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -712,15 +712,15 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
712 ar9580_1p0_rx_gain_table, 712 ar9580_1p0_rx_gain_table,
713 ARRAY_SIZE(ar9580_1p0_rx_gain_table), 713 ARRAY_SIZE(ar9580_1p0_rx_gain_table),
714 2); 714 2);
715 else if (AR_SREV_9480_10(ah)) 715 else if (AR_SREV_9462_10(ah))
716 INIT_INI_ARRAY(&ah->iniModesRxGain, 716 INIT_INI_ARRAY(&ah->iniModesRxGain,
717 ar9480_common_rx_gain_table_1p0, 717 ar9462_common_rx_gain_table_1p0,
718 ARRAY_SIZE(ar9480_common_rx_gain_table_1p0), 718 ARRAY_SIZE(ar9462_common_rx_gain_table_1p0),
719 2); 719 2);
720 else if (AR_SREV_9480_20(ah)) 720 else if (AR_SREV_9462_20(ah))
721 INIT_INI_ARRAY(&ah->iniModesRxGain, 721 INIT_INI_ARRAY(&ah->iniModesRxGain,
722 ar9480_common_rx_gain_table_2p0, 722 ar9462_common_rx_gain_table_2p0,
723 ARRAY_SIZE(ar9480_common_rx_gain_table_2p0), 723 ARRAY_SIZE(ar9462_common_rx_gain_table_2p0),
724 2); 724 2);
725 else 725 else
726 INIT_INI_ARRAY(&ah->iniModesRxGain, 726 INIT_INI_ARRAY(&ah->iniModesRxGain,
@@ -751,15 +751,15 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
751 ar9485Common_wo_xlna_rx_gain_1_1, 751 ar9485Common_wo_xlna_rx_gain_1_1,
752 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 752 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
753 2); 753 2);
754 else if (AR_SREV_9480_10(ah)) 754 else if (AR_SREV_9462_10(ah))
755 INIT_INI_ARRAY(&ah->iniModesRxGain, 755 INIT_INI_ARRAY(&ah->iniModesRxGain,
756 ar9480_common_wo_xlna_rx_gain_table_1p0, 756 ar9462_common_wo_xlna_rx_gain_table_1p0,
757 ARRAY_SIZE(ar9480_common_wo_xlna_rx_gain_table_1p0), 757 ARRAY_SIZE(ar9462_common_wo_xlna_rx_gain_table_1p0),
758 2); 758 2);
759 else if (AR_SREV_9480_20(ah)) 759 else if (AR_SREV_9462_20(ah))
760 INIT_INI_ARRAY(&ah->iniModesRxGain, 760 INIT_INI_ARRAY(&ah->iniModesRxGain,
761 ar9480_common_wo_xlna_rx_gain_table_2p0, 761 ar9462_common_wo_xlna_rx_gain_table_2p0,
762 ARRAY_SIZE(ar9480_common_wo_xlna_rx_gain_table_2p0), 762 ARRAY_SIZE(ar9462_common_wo_xlna_rx_gain_table_2p0),
763 2); 763 2);
764 else if (AR_SREV_9580(ah)) 764 else if (AR_SREV_9580(ah))
765 INIT_INI_ARRAY(&ah->iniModesRxGain, 765 INIT_INI_ARRAY(&ah->iniModesRxGain,
@@ -775,14 +775,14 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
775 775
776static void ar9003_rx_gain_table_mode2(struct ath_hw *ah) 776static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
777{ 777{
778 if (AR_SREV_9480_10(ah)) 778 if (AR_SREV_9462_10(ah))
779 INIT_INI_ARRAY(&ah->iniModesRxGain, 779 INIT_INI_ARRAY(&ah->iniModesRxGain,
780 ar9480_common_mixed_rx_gain_table_1p0, 780 ar9462_common_mixed_rx_gain_table_1p0,
781 ARRAY_SIZE(ar9480_common_mixed_rx_gain_table_1p0), 2); 781 ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_1p0), 2);
782 else if (AR_SREV_9480_20(ah)) 782 else if (AR_SREV_9462_20(ah))
783 INIT_INI_ARRAY(&ah->iniModesRxGain, 783 INIT_INI_ARRAY(&ah->iniModesRxGain,
784 ar9480_common_mixed_rx_gain_table_2p0, 784 ar9462_common_mixed_rx_gain_table_2p0,
785 ARRAY_SIZE(ar9480_common_mixed_rx_gain_table_2p0), 2); 785 ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_2p0), 2);
786} 786}
787 787
788static void ar9003_rx_gain_table_apply(struct ath_hw *ah) 788static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 6cabc85bf61b..b363cc06cfd9 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -525,8 +525,8 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
525 rxs->rs_status |= ATH9K_RXERR_DECRYPT; 525 rxs->rs_status |= ATH9K_RXERR_DECRYPT;
526 else if (rxsp->status11 & AR_MichaelErr) 526 else if (rxsp->status11 & AR_MichaelErr)
527 rxs->rs_status |= ATH9K_RXERR_MIC; 527 rxs->rs_status |= ATH9K_RXERR_MIC;
528 else if (rxsp->status11 & AR_KeyMiss) 528 if (rxsp->status11 & AR_KeyMiss)
529 rxs->rs_status |= ATH9K_RXERR_DECRYPT; 529 rxs->rs_status |= ATH9K_RXERR_KEYMISS;
530 } 530 }
531 531
532 return 0; 532 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 609acb2b504f..0c462c904cbe 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -19,7 +19,6 @@
19 19
20void ar9003_paprd_enable(struct ath_hw *ah, bool val) 20void ar9003_paprd_enable(struct ath_hw *ah, bool val)
21{ 21{
22 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
23 struct ath9k_channel *chan = ah->curchan; 22 struct ath9k_channel *chan = ah->curchan;
24 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 23 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
25 24
@@ -54,13 +53,7 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
54 53
55 if (val) { 54 if (val) {
56 ah->paprd_table_write_done = true; 55 ah->paprd_table_write_done = true;
57 56 ath9k_hw_apply_txpower(ah, chan);
58 ah->eep_ops->set_txpower(ah, chan,
59 ath9k_regd_get_ctl(regulatory, chan),
60 chan->chan->max_antenna_gain * 2,
61 chan->chan->max_power * 2,
62 min((u32) MAX_RATE_POWER,
63 (u32) regulatory->power_limit), false);
64 } 57 }
65 58
66 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, 59 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
@@ -207,7 +200,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
207 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28); 200 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28);
208 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, 201 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
209 AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1); 202 AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1);
210 val = AR_SREV_9480(ah) ? 0x91 : 147; 203 val = AR_SREV_9462(ah) ? 0x91 : 147;
211 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL2, 204 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
212 AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, val); 205 AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, val);
213 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, 206 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
@@ -218,7 +211,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
218 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7); 211 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7);
219 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, 212 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
220 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1); 213 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1);
221 if (AR_SREV_9485(ah) || AR_SREV_9480(ah)) 214 if (AR_SREV_9485(ah) || AR_SREV_9462(ah))
222 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, 215 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
223 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, 216 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
224 -3); 217 -3);
@@ -226,7 +219,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
226 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, 219 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
227 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, 220 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
228 -6); 221 -6);
229 val = AR_SREV_9480(ah) ? -10 : -15; 222 val = AR_SREV_9462(ah) ? -10 : -15;
230 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, 223 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
231 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, 224 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE,
232 val); 225 val);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 7db6e8647a01..fe96997921d3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -559,7 +559,7 @@ static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
559 559
560 if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7)) 560 if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
561 REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); 561 REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
562 else if (AR_SREV_9480(ah)) 562 else if (AR_SREV_9462(ah))
563 /* xxx only when MCI support is enabled */ 563 /* xxx only when MCI support is enabled */
564 REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); 564 REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
565 else 565 else
@@ -631,9 +631,7 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah,
631static int ar9003_hw_process_ini(struct ath_hw *ah, 631static int ar9003_hw_process_ini(struct ath_hw *ah,
632 struct ath9k_channel *chan) 632 struct ath9k_channel *chan)
633{ 633{
634 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
635 unsigned int regWrites = 0, i; 634 unsigned int regWrites = 0, i;
636 struct ieee80211_channel *channel = chan->chan;
637 u32 modesIndex; 635 u32 modesIndex;
638 636
639 switch (chan->chanmode) { 637 switch (chan->chanmode) {
@@ -664,7 +662,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
664 ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex); 662 ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex);
665 ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex); 663 ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex);
666 ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex); 664 ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex);
667 if (i == ATH_INI_POST && AR_SREV_9480_20(ah)) 665 if (i == ATH_INI_POST && AR_SREV_9462_20(ah))
668 ar9003_hw_prog_ini(ah, 666 ar9003_hw_prog_ini(ah,
669 &ah->ini_radio_post_sys2ant, 667 &ah->ini_radio_post_sys2ant,
670 modesIndex); 668 modesIndex);
@@ -687,20 +685,27 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
687 if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) 685 if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
688 REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); 686 REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
689 687
690 if (AR_SREV_9480(ah)) 688 if (AR_SREV_9462(ah))
691 ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1); 689 ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1);
692 690
691 ah->modes_index = modesIndex;
693 ar9003_hw_override_ini(ah); 692 ar9003_hw_override_ini(ah);
694 ar9003_hw_set_channel_regs(ah, chan); 693 ar9003_hw_set_channel_regs(ah, chan);
695 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); 694 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
695 ath9k_hw_apply_txpower(ah, chan);
696 696
697 /* Set TX power */ 697 if (AR_SREV_9462(ah)) {
698 ah->eep_ops->set_txpower(ah, chan, 698 if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
699 ath9k_regd_get_ctl(regulatory, chan), 699 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL))
700 channel->max_antenna_gain * 2, 700 ah->enabled_cals |= TX_IQ_CAL;
701 channel->max_power * 2, 701 else
702 min((u32) MAX_RATE_POWER, 702 ah->enabled_cals &= ~TX_IQ_CAL;
703 (u32) regulatory->power_limit), false); 703
704 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE)
705 ah->enabled_cals |= TX_CL_CAL;
706 else
707 ah->enabled_cals &= ~TX_CL_CAL;
708 }
704 709
705 return 0; 710 return 0;
706} 711}
@@ -1256,6 +1261,73 @@ static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah,
1256 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); 1261 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
1257} 1262}
1258 1263
1264static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
1265 struct ath9k_channel *chan,
1266 u8 *ini_reloaded)
1267{
1268 unsigned int regWrites = 0;
1269 u32 modesIndex;
1270
1271 switch (chan->chanmode) {
1272 case CHANNEL_A:
1273 case CHANNEL_A_HT20:
1274 modesIndex = 1;
1275 break;
1276 case CHANNEL_A_HT40PLUS:
1277 case CHANNEL_A_HT40MINUS:
1278 modesIndex = 2;
1279 break;
1280 case CHANNEL_G:
1281 case CHANNEL_G_HT20:
1282 case CHANNEL_B:
1283 modesIndex = 4;
1284 break;
1285 case CHANNEL_G_HT40PLUS:
1286 case CHANNEL_G_HT40MINUS:
1287 modesIndex = 3;
1288 break;
1289
1290 default:
1291 return -EINVAL;
1292 }
1293
1294 if (modesIndex == ah->modes_index) {
1295 *ini_reloaded = false;
1296 goto set_rfmode;
1297 }
1298
1299 ar9003_hw_prog_ini(ah, &ah->iniSOC[ATH_INI_POST], modesIndex);
1300 ar9003_hw_prog_ini(ah, &ah->iniMac[ATH_INI_POST], modesIndex);
1301 ar9003_hw_prog_ini(ah, &ah->iniBB[ATH_INI_POST], modesIndex);
1302 ar9003_hw_prog_ini(ah, &ah->iniRadio[ATH_INI_POST], modesIndex);
1303 if (AR_SREV_9462_20(ah))
1304 ar9003_hw_prog_ini(ah,
1305 &ah->ini_radio_post_sys2ant,
1306 modesIndex);
1307
1308 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
1309
1310 /*
1311 * For 5GHz channels requiring Fast Clock, apply
1312 * different modal values.
1313 */
1314 if (IS_CHAN_A_FAST_CLOCK(ah, chan))
1315 REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, regWrites);
1316
1317 if (AR_SREV_9330(ah))
1318 REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites);
1319
1320 if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
1321 REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
1322
1323 ah->modes_index = modesIndex;
1324 *ini_reloaded = true;
1325
1326set_rfmode:
1327 ar9003_hw_set_rfmode(ah, chan);
1328 return 0;
1329}
1330
1259void ar9003_hw_attach_phy_ops(struct ath_hw *ah) 1331void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1260{ 1332{
1261 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1333 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -1284,6 +1356,7 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1284 priv_ops->do_getnf = ar9003_hw_do_getnf; 1356 priv_ops->do_getnf = ar9003_hw_do_getnf;
1285 priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs; 1357 priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
1286 priv_ops->set_radar_params = ar9003_hw_set_radar_params; 1358 priv_ops->set_radar_params = ar9003_hw_set_radar_params;
1359 priv_ops->fast_chan_change = ar9003_hw_fast_chan_change;
1287 1360
1288 ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get; 1361 ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
1289 ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set; 1362 ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 6cea546a1507..2f4023e66081 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -325,10 +325,10 @@
325 325
326#define AR_PHY_RX_OCGAIN (AR_AGC_BASE + 0x200) 326#define AR_PHY_RX_OCGAIN (AR_AGC_BASE + 0x200)
327 327
328#define AR_PHY_CCA_NOM_VAL_9300_2GHZ -110 328#define AR_PHY_CCA_NOM_VAL_9300_2GHZ (AR_SREV_9462(ah) ? -127 : -110)
329#define AR_PHY_CCA_NOM_VAL_9300_5GHZ -115 329#define AR_PHY_CCA_NOM_VAL_9300_5GHZ (AR_SREV_9462(ah) ? -127 : -115)
330#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ -125 330#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ (AR_SREV_9462(ah) ? -127 : -125)
331#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ -125 331#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ (AR_SREV_9462(ah) ? -127 : -125)
332#define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -95 332#define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -95
333#define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -100 333#define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -100
334 334
@@ -572,6 +572,8 @@
572 572
573#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300) 573#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300)
574 574
575#define AR_PHY_TX_IQCAL_CONTROL_0 (AR_SM_BASE + AR_SREV_9485(ah) ? \
576 0x3c4 : 0x444)
575#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + AR_SREV_9485(ah) ? \ 577#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + AR_SREV_9485(ah) ? \
576 0x3c8 : 0x448) 578 0x3c8 : 0x448)
577#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + AR_SREV_9485(ah) ? \ 579#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + AR_SREV_9485(ah) ? \
@@ -582,8 +584,6 @@
582 (AR_SREV_9485(ah) ? \ 584 (AR_SREV_9485(ah) ? \
583 0x3d0 : 0x450) + ((_i) << 2)) 585 0x3d0 : 0x450) + ((_i) << 2))
584#define AR_PHY_RTT_CTRL (AR_SM_BASE + 0x380) 586#define AR_PHY_RTT_CTRL (AR_SM_BASE + 0x380)
585#define AR_PHY_RTT_TABLE_SW_INTF_B (AR_SM_BASE + 0x384)
586#define AR_PHY_RTT_TABLE_SW_INTF_1_B0 (AR_SM_BASE + 0x388)
587 587
588#define AR_PHY_WATCHDOG_STATUS (AR_SM_BASE + 0x5c0) 588#define AR_PHY_WATCHDOG_STATUS (AR_SM_BASE + 0x5c0)
589#define AR_PHY_WATCHDOG_CTL_1 (AR_SM_BASE + 0x5c4) 589#define AR_PHY_WATCHDOG_CTL_1 (AR_SM_BASE + 0x5c4)
@@ -608,9 +608,9 @@
608#define AR_PHY_AIC_CTRL_1_B0 (AR_SM_BASE + 0x4b4) 608#define AR_PHY_AIC_CTRL_1_B0 (AR_SM_BASE + 0x4b4)
609#define AR_PHY_AIC_CTRL_2_B0 (AR_SM_BASE + 0x4b8) 609#define AR_PHY_AIC_CTRL_2_B0 (AR_SM_BASE + 0x4b8)
610#define AR_PHY_AIC_CTRL_3_B0 (AR_SM_BASE + 0x4bc) 610#define AR_PHY_AIC_CTRL_3_B0 (AR_SM_BASE + 0x4bc)
611#define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + (AR_SREV_9480_10(ah) ? \ 611#define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + (AR_SREV_9462_10(ah) ? \
612 0x4c0 : 0x4c4)) 612 0x4c0 : 0x4c4))
613#define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + (AR_SREV_9480_10(ah) ? \ 613#define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + (AR_SREV_9462_10(ah) ? \
614 0x4c4 : 0x4c8)) 614 0x4c4 : 0x4c8))
615#define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) 615#define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0)
616#define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc) 616#define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc)
@@ -625,7 +625,7 @@
625#define AR_PHY_65NM_CH0_RXTX4 0x1610c 625#define AR_PHY_65NM_CH0_RXTX4 0x1610c
626 626
627#define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \ 627#define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \
628 ((AR_SREV_9480(ah) ? 0x1628c : 0x16280))) 628 ((AR_SREV_9462(ah) ? 0x1628c : 0x16280)))
629#define AR_CH0_TOP_XPABIASLVL (0x300) 629#define AR_CH0_TOP_XPABIASLVL (0x300)
630#define AR_CH0_TOP_XPABIASLVL_S (8) 630#define AR_CH0_TOP_XPABIASLVL_S (8)
631 631
@@ -638,8 +638,8 @@
638 638
639#define AR_SWITCH_TABLE_COM_ALL (0xffff) 639#define AR_SWITCH_TABLE_COM_ALL (0xffff)
640#define AR_SWITCH_TABLE_COM_ALL_S (0) 640#define AR_SWITCH_TABLE_COM_ALL_S (0)
641#define AR_SWITCH_TABLE_COM_AR9480_ALL (0xffffff) 641#define AR_SWITCH_TABLE_COM_AR9462_ALL (0xffffff)
642#define AR_SWITCH_TABLE_COM_AR9480_ALL_S (0) 642#define AR_SWITCH_TABLE_COM_AR9462_ALL_S (0)
643#define AR_SWITCH_TABLE_COM_SPDT (0x00f00000) 643#define AR_SWITCH_TABLE_COM_SPDT (0x00f00000)
644#define AR_SWITCH_TABLE_COM_SPDT_ALL (0x0000fff0) 644#define AR_SWITCH_TABLE_COM_SPDT_ALL (0x0000fff0)
645#define AR_SWITCH_TABLE_COM_SPDT_ALL_S (4) 645#define AR_SWITCH_TABLE_COM_SPDT_ALL_S (4)
@@ -679,11 +679,11 @@
679#define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000 679#define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000
680#define AR_CH0_XTAL_CAPOUTDAC_S 17 680#define AR_CH0_XTAL_CAPOUTDAC_S 17
681 681
682#define AR_PHY_PMU1 (AR_SREV_9480(ah) ? 0x16340 : 0x16c40) 682#define AR_PHY_PMU1 (AR_SREV_9462(ah) ? 0x16340 : 0x16c40)
683#define AR_PHY_PMU1_PWD 0x1 683#define AR_PHY_PMU1_PWD 0x1
684#define AR_PHY_PMU1_PWD_S 0 684#define AR_PHY_PMU1_PWD_S 0
685 685
686#define AR_PHY_PMU2 (AR_SREV_9480(ah) ? 0x16344 : 0x16c44) 686#define AR_PHY_PMU2 (AR_SREV_9462(ah) ? 0x16344 : 0x16c44)
687#define AR_PHY_PMU2_PGM 0x00200000 687#define AR_PHY_PMU2_PGM 0x00200000
688#define AR_PHY_PMU2_PGM_S 21 688#define AR_PHY_PMU2_PGM_S 21
689 689
@@ -823,6 +823,22 @@
823#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 823#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000
824#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 824#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24
825#define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004 825#define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004
826#define AR_PHY_RTT_CTRL_ENA_RADIO_RETENTION 0x00000001
827#define AR_PHY_RTT_CTRL_ENA_RADIO_RETENTION_S 0
828#define AR_PHY_RTT_CTRL_RESTORE_MASK 0x0000007E
829#define AR_PHY_RTT_CTRL_RESTORE_MASK_S 1
830#define AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE 0x00000080
831#define AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE_S 7
832#define AR_PHY_RTT_SW_RTT_TABLE_ACCESS 0x00000001
833#define AR_PHY_RTT_SW_RTT_TABLE_ACCESS_S 0
834#define AR_PHY_RTT_SW_RTT_TABLE_WRITE 0x00000002
835#define AR_PHY_RTT_SW_RTT_TABLE_WRITE_S 1
836#define AR_PHY_RTT_SW_RTT_TABLE_ADDR 0x0000001C
837#define AR_PHY_RTT_SW_RTT_TABLE_ADDR_S 2
838#define AR_PHY_RTT_SW_RTT_TABLE_DATA 0xFFFFFFF0
839#define AR_PHY_RTT_SW_RTT_TABLE_DATA_S 4
840#define AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL 0x80000000
841#define AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL_S 31
826#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000 842#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000
827#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18 843#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18
828#define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001 844#define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001
@@ -905,9 +921,9 @@
905#define AR_PHY_AIC_CTRL_0_B1 (AR_SM1_BASE + 0x4b0) 921#define AR_PHY_AIC_CTRL_0_B1 (AR_SM1_BASE + 0x4b0)
906#define AR_PHY_AIC_CTRL_1_B1 (AR_SM1_BASE + 0x4b4) 922#define AR_PHY_AIC_CTRL_1_B1 (AR_SM1_BASE + 0x4b4)
907#define AR_PHY_AIC_CTRL_2_B1 (AR_SM1_BASE + 0x4b8) 923#define AR_PHY_AIC_CTRL_2_B1 (AR_SM1_BASE + 0x4b8)
908#define AR_PHY_AIC_STAT_0_B1 (AR_SM1_BASE + (AR_SREV_9480_10(ah) ? \ 924#define AR_PHY_AIC_STAT_0_B1 (AR_SM1_BASE + (AR_SREV_9462_10(ah) ? \
909 0x4c0 : 0x4c4)) 925 0x4c0 : 0x4c4))
910#define AR_PHY_AIC_STAT_1_B1 (AR_SM1_BASE + (AR_SREV_9480_10(ah) ? \ 926#define AR_PHY_AIC_STAT_1_B1 (AR_SM1_BASE + (AR_SREV_9462_10(ah) ? \
911 0x4c4 : 0x4c8)) 927 0x4c4 : 0x4c8))
912#define AR_PHY_AIC_CTRL_4_B1 (AR_SM1_BASE + 0x4c0) 928#define AR_PHY_AIC_CTRL_4_B1 (AR_SM1_BASE + 0x4c0)
913#define AR_PHY_AIC_STAT_2_B1 (AR_SM1_BASE + 0x4cc) 929#define AR_PHY_AIC_STAT_2_B1 (AR_SM1_BASE + 0x4cc)
@@ -915,6 +931,10 @@
915#define AR_PHY_AIC_SRAM_ADDR_B1 (AR_SM1_BASE + 0x5f0) 931#define AR_PHY_AIC_SRAM_ADDR_B1 (AR_SM1_BASE + 0x5f0)
916#define AR_PHY_AIC_SRAM_DATA_B1 (AR_SM1_BASE + 0x5f4) 932#define AR_PHY_AIC_SRAM_DATA_B1 (AR_SM1_BASE + 0x5f4)
917 933
934#define AR_PHY_RTT_TABLE_SW_INTF_B(i) (0x384 + (i) ? \
935 AR_SM1_BASE : AR_SM_BASE)
936#define AR_PHY_RTT_TABLE_SW_INTF_1_B(i) (0x388 + (i) ? \
937 AR_SM1_BASE : AR_SM_BASE)
918/* 938/*
919 * Channel 2 Register Map 939 * Channel 2 Register Map
920 */ 940 */
@@ -981,7 +1001,7 @@
981#define AR_GLB_BASE 0x20000 1001#define AR_GLB_BASE 0x20000
982#define AR_PHY_GLB_CONTROL (AR_GLB_BASE + 0x44) 1002#define AR_PHY_GLB_CONTROL (AR_GLB_BASE + 0x44)
983#define AR_GLB_SCRATCH(_ah) (AR_GLB_BASE + \ 1003#define AR_GLB_SCRATCH(_ah) (AR_GLB_BASE + \
984 (AR_SREV_9480_20(_ah) ? 0x4c : 0x50)) 1004 (AR_SREV_9462_20(_ah) ? 0x4c : 0x50))
985#define AR_GLB_STATUS (AR_GLB_BASE + 0x48) 1005#define AR_GLB_STATUS (AR_GLB_BASE + 0x48)
986 1006
987/* 1007/*
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
new file mode 100644
index 000000000000..48803ee9c0d6
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
@@ -0,0 +1,153 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "hw.h"
18#include "ar9003_phy.h"
19
20#define RTT_RESTORE_TIMEOUT 1000
21#define RTT_ACCESS_TIMEOUT 100
22#define RTT_BAD_VALUE 0x0bad0bad
23
24/*
25 * RTT (Radio Retention Table) hardware implementation information
26 *
27 * There is an internal table (i.e. the rtt) for each chain (or bank).
28 * Each table contains 6 entries and each entry is corresponding to
29 * a specific calibration parameter as depicted below.
30 * 0~2 - DC offset DAC calibration: loop, low, high (offsetI/Q_...)
31 * 3 - Filter cal (filterfc)
32 * 4 - RX gain settings
33 * 5 - Peak detector offset calibration (agc_caldac)
34 */
35
36void ar9003_hw_rtt_enable(struct ath_hw *ah)
37{
38 REG_WRITE(ah, AR_PHY_RTT_CTRL, 1);
39}
40
41void ar9003_hw_rtt_disable(struct ath_hw *ah)
42{
43 REG_WRITE(ah, AR_PHY_RTT_CTRL, 0);
44}
45
46void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask)
47{
48 REG_RMW_FIELD(ah, AR_PHY_RTT_CTRL,
49 AR_PHY_RTT_CTRL_RESTORE_MASK, rtt_mask);
50}
51
52bool ar9003_hw_rtt_force_restore(struct ath_hw *ah)
53{
54 if (!ath9k_hw_wait(ah, AR_PHY_RTT_CTRL,
55 AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE,
56 0, RTT_RESTORE_TIMEOUT))
57 return false;
58
59 REG_RMW_FIELD(ah, AR_PHY_RTT_CTRL,
60 AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE, 1);
61
62 if (!ath9k_hw_wait(ah, AR_PHY_RTT_CTRL,
63 AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE,
64 0, RTT_RESTORE_TIMEOUT))
65 return false;
66
67 return true;
68}
69
70static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain,
71 u32 index, u32 data28)
72{
73 u32 val;
74
75 val = SM(data28, AR_PHY_RTT_SW_RTT_TABLE_DATA);
76 REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain), val);
77
78 val = SM(0, AR_PHY_RTT_SW_RTT_TABLE_ACCESS) |
79 SM(1, AR_PHY_RTT_SW_RTT_TABLE_WRITE) |
80 SM(index, AR_PHY_RTT_SW_RTT_TABLE_ADDR);
81 REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
82 udelay(1);
83
84 val |= SM(1, AR_PHY_RTT_SW_RTT_TABLE_ACCESS);
85 REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
86 udelay(1);
87
88 if (!ath9k_hw_wait(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain),
89 AR_PHY_RTT_SW_RTT_TABLE_ACCESS, 0,
90 RTT_ACCESS_TIMEOUT))
91 return;
92
93 val &= ~SM(1, AR_PHY_RTT_SW_RTT_TABLE_WRITE);
94 REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
95 udelay(1);
96
97 ath9k_hw_wait(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain),
98 AR_PHY_RTT_SW_RTT_TABLE_ACCESS, 0,
99 RTT_ACCESS_TIMEOUT);
100}
101
102void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table)
103{
104 int i;
105
106 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
107 ar9003_hw_rtt_load_hist_entry(ah, chain, i, table[i]);
108}
109
110static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index)
111{
112 u32 val;
113
114 val = SM(0, AR_PHY_RTT_SW_RTT_TABLE_ACCESS) |
115 SM(0, AR_PHY_RTT_SW_RTT_TABLE_WRITE) |
116 SM(index, AR_PHY_RTT_SW_RTT_TABLE_ADDR);
117
118 REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
119 udelay(1);
120
121 val |= SM(1, AR_PHY_RTT_SW_RTT_TABLE_ACCESS);
122 REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
123 udelay(1);
124
125 if (!ath9k_hw_wait(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain),
126 AR_PHY_RTT_SW_RTT_TABLE_ACCESS, 0,
127 RTT_ACCESS_TIMEOUT))
128 return RTT_BAD_VALUE;
129
130 val = REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain));
131
132 return val;
133}
134
135void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table)
136{
137 int i;
138
139 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
140 table[i] = ar9003_hw_rtt_fill_hist_entry(ah, chain, i);
141}
142
143void ar9003_hw_rtt_clear_hist(struct ath_hw *ah)
144{
145 int i, j;
146
147 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
148 if (!(ah->rxchainmask & (1 << i)))
149 continue;
150 for (j = 0; j < MAX_RTT_TABLE_ENTRY; j++)
151 ar9003_hw_rtt_load_hist_entry(ah, i, j, 0);
152 }
153}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h
new file mode 100644
index 000000000000..030758d087d6
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h
@@ -0,0 +1,28 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef AR9003_RTT_H
18#define AR9003_RTT_H
19
20void ar9003_hw_rtt_enable(struct ath_hw *ah);
21void ar9003_hw_rtt_disable(struct ath_hw *ah);
22void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask);
23bool ar9003_hw_rtt_force_restore(struct ath_hw *ah);
24void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table);
25void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table);
26void ar9003_hw_rtt_clear_hist(struct ath_hw *ah);
27
28#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9480_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_1p0_initvals.h
index 4071bd2bd03f..5c55ae389adb 100644
--- a/drivers/net/wireless/ath/ath9k/ar9480_1p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9462_1p0_initvals.h
@@ -14,12 +14,12 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#ifndef INITVALS_9480_1P0_H 17#ifndef INITVALS_9462_1P0_H
18#define INITVALS_9480_1P0_H 18#define INITVALS_9462_1P0_H
19 19
20/* AR9480 1.0 */ 20/* AR9462 1.0 */
21 21
22static const u32 ar9480_1p0_mac_core[][2] = { 22static const u32 ar9462_1p0_mac_core[][2] = {
23 /* Addr allmodes */ 23 /* Addr allmodes */
24 {0x00000008, 0x00000000}, 24 {0x00000008, 0x00000000},
25 {0x00000030, 0x00060085}, 25 {0x00000030, 0x00060085},
@@ -183,27 +183,27 @@ static const u32 ar9480_1p0_mac_core[][2] = {
183 {0x000083d0, 0x000301ff}, 183 {0x000083d0, 0x000301ff},
184}; 184};
185 185
186static const u32 ar9480_1p0_baseband_core_txfir_coeff_japan_2484[][2] = { 186static const u32 ar9462_1p0_baseband_core_txfir_coeff_japan_2484[][2] = {
187 /* Addr allmodes */ 187 /* Addr allmodes */
188 {0x0000a398, 0x00000000}, 188 {0x0000a398, 0x00000000},
189 {0x0000a39c, 0x6f7f0301}, 189 {0x0000a39c, 0x6f7f0301},
190 {0x0000a3a0, 0xca9228ee}, 190 {0x0000a3a0, 0xca9228ee},
191}; 191};
192 192
193static const u32 ar9480_1p0_sys3ant[][2] = { 193static const u32 ar9462_1p0_sys3ant[][2] = {
194 /* Addr allmodes */ 194 /* Addr allmodes */
195 {0x00063280, 0x00040807}, 195 {0x00063280, 0x00040807},
196 {0x00063284, 0x104ccccc}, 196 {0x00063284, 0x104ccccc},
197}; 197};
198 198
199static const u32 ar9480_pcie_phy_clkreq_enable_L1_1p0[][2] = { 199static const u32 ar9462_pcie_phy_clkreq_enable_L1_1p0[][2] = {
200 /* Addr allmodes */ 200 /* Addr allmodes */
201 {0x00018c00, 0x10053e5e}, 201 {0x00018c00, 0x10053e5e},
202 {0x00018c04, 0x000801d8}, 202 {0x00018c04, 0x000801d8},
203 {0x00018c08, 0x0000580c}, 203 {0x00018c08, 0x0000580c},
204}; 204};
205 205
206static const u32 ar9480_1p0_mac_core_emulation[][2] = { 206static const u32 ar9462_1p0_mac_core_emulation[][2] = {
207 /* Addr allmodes */ 207 /* Addr allmodes */
208 {0x00000030, 0x00060085}, 208 {0x00000030, 0x00060085},
209 {0x00000044, 0x00000008}, 209 {0x00000044, 0x00000008},
@@ -211,7 +211,7 @@ static const u32 ar9480_1p0_mac_core_emulation[][2] = {
211 {0x00008344, 0xaa4a105b}, 211 {0x00008344, 0xaa4a105b},
212}; 212};
213 213
214static const u32 ar9480_common_rx_gain_table_ar9280_2p0_1p0[][2] = { 214static const u32 ar9462_common_rx_gain_table_ar9280_2p0_1p0[][2] = {
215 /* Addr allmodes */ 215 /* Addr allmodes */
216 {0x0000a000, 0x02000101}, 216 {0x0000a000, 0x02000101},
217 {0x0000a004, 0x02000102}, 217 {0x0000a004, 0x02000102},
@@ -513,7 +513,7 @@ static const u32 ar9200_ar9280_2p0_radio_core_1p0[][2] = {
513 {0x00007894, 0x5a108000}, 513 {0x00007894, 0x5a108000},
514}; 514};
515 515
516static const u32 ar9480_1p0_baseband_postamble_emulation[][5] = { 516static const u32 ar9462_1p0_baseband_postamble_emulation[][5] = {
517 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 517 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
518 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 518 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
519 {0x00009e3c, 0xcf946221, 0xcf946221, 0xcf946221, 0xcf946221}, 519 {0x00009e3c, 0xcf946221, 0xcf946221, 0xcf946221, 0xcf946221},
@@ -535,14 +535,14 @@ static const u32 ar9480_1p0_baseband_postamble_emulation[][5] = {
535 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 535 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
536}; 536};
537 537
538static const u32 ar9480_pcie_phy_pll_on_clkreq_disable_L1_1p0[][2] = { 538static const u32 ar9462_pcie_phy_pll_on_clkreq_disable_L1_1p0[][2] = {
539 /* Addr allmodes */ 539 /* Addr allmodes */
540 {0x00018c00, 0x10012e5e}, 540 {0x00018c00, 0x10012e5e},
541 {0x00018c04, 0x000801d8}, 541 {0x00018c04, 0x000801d8},
542 {0x00018c08, 0x0000580c}, 542 {0x00018c08, 0x0000580c},
543}; 543};
544 544
545static const u32 ar9480_common_rx_gain_table_1p0[][2] = { 545static const u32 ar9462_common_rx_gain_table_1p0[][2] = {
546 /* Addr allmodes */ 546 /* Addr allmodes */
547 {0x0000a000, 0x00010000}, 547 {0x0000a000, 0x00010000},
548 {0x0000a004, 0x00030002}, 548 {0x0000a004, 0x00030002},
@@ -802,7 +802,7 @@ static const u32 ar9480_common_rx_gain_table_1p0[][2] = {
802 {0x0000b1fc, 0x00000196}, 802 {0x0000b1fc, 0x00000196},
803}; 803};
804 804
805static const u32 ar9480_modes_high_ob_db_tx_gain_table_1p0[][5] = { 805static const u32 ar9462_modes_high_ob_db_tx_gain_table_1p0[][5] = {
806 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 806 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
807 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, 807 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
808 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, 808 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
@@ -867,7 +867,7 @@ static const u32 ar9480_modes_high_ob_db_tx_gain_table_1p0[][5] = {
867 {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000}, 867 {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000},
868}; 868};
869 869
870static const u32 ar9480_common_wo_xlna_rx_gain_table_1p0[][2] = { 870static const u32 ar9462_common_wo_xlna_rx_gain_table_1p0[][2] = {
871 /* Addr allmodes */ 871 /* Addr allmodes */
872 {0x0000a000, 0x00010000}, 872 {0x0000a000, 0x00010000},
873 {0x0000a004, 0x00030002}, 873 {0x0000a004, 0x00030002},
@@ -1127,7 +1127,7 @@ static const u32 ar9480_common_wo_xlna_rx_gain_table_1p0[][2] = {
1127 {0x0000b1fc, 0x00000196}, 1127 {0x0000b1fc, 0x00000196},
1128}; 1128};
1129 1129
1130static const u32 ar9480_1p0_mac_postamble[][5] = { 1130static const u32 ar9462_1p0_mac_postamble[][5] = {
1131 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1131 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1132 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, 1132 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
1133 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, 1133 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
@@ -1139,13 +1139,13 @@ static const u32 ar9480_1p0_mac_postamble[][5] = {
1139 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, 1139 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
1140}; 1140};
1141 1141
1142static const u32 ar9480_1p0_mac_postamble_emulation[][5] = { 1142static const u32 ar9462_1p0_mac_postamble_emulation[][5] = {
1143 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1143 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1144 {0x00008014, 0x10f810f8, 0x10f810f8, 0x10f810f8, 0x10f810f8}, 1144 {0x00008014, 0x10f810f8, 0x10f810f8, 0x10f810f8, 0x10f810f8},
1145 {0x0000801c, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017}, 1145 {0x0000801c, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017},
1146}; 1146};
1147 1147
1148static const u32 ar9480_1p0_tx_gain_table_baseband_postamble_emulation[][5] = { 1148static const u32 ar9462_1p0_tx_gain_table_baseband_postamble_emulation[][5] = {
1149 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1149 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1150 {0x0000a410, 0x000000d5, 0x000000d5, 0x000000d5, 0x000000d5}, 1150 {0x0000a410, 0x000000d5, 0x000000d5, 0x000000d5, 0x000000d5},
1151 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1151 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -1163,7 +1163,7 @@ static const u32 ar9480_1p0_tx_gain_table_baseband_postamble_emulation[][5] = {
1163 {0x0000a534, 0x00034e8a, 0x00034e8a, 0x00034e8a, 0x00034e8a}, 1163 {0x0000a534, 0x00034e8a, 0x00034e8a, 0x00034e8a, 0x00034e8a},
1164}; 1164};
1165 1165
1166static const u32 ar9480_1p0_radio_postamble[][5] = { 1166static const u32 ar9462_1p0_radio_postamble[][5] = {
1167 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1167 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1168 {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524}, 1168 {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
1169 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24646c08, 0x24646c08}, 1169 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24646c08, 0x24646c08},
@@ -1174,12 +1174,12 @@ static const u32 ar9480_1p0_radio_postamble[][5] = {
1174 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 1174 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
1175}; 1175};
1176 1176
1177static const u32 ar9480_1p0_soc_postamble_emulation[][5] = { 1177static const u32 ar9462_1p0_soc_postamble_emulation[][5] = {
1178 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1178 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1179 {0x00007010, 0x00001133, 0x00001133, 0x00001133, 0x00001133}, 1179 {0x00007010, 0x00001133, 0x00001133, 0x00001133, 0x00001133},
1180}; 1180};
1181 1181
1182static const u32 ar9480_1p0_baseband_core[][2] = { 1182static const u32 ar9462_1p0_baseband_core[][2] = {
1183 /* Addr allmodes */ 1183 /* Addr allmodes */
1184 {0x00009800, 0xafe68e30}, 1184 {0x00009800, 0xafe68e30},
1185 {0x00009804, 0xfd14e000}, 1185 {0x00009804, 0xfd14e000},
@@ -1336,7 +1336,7 @@ static const u32 ar9480_1p0_baseband_core[][2] = {
1336 {0x0000b6b4, 0x00c00001}, 1336 {0x0000b6b4, 0x00c00001},
1337}; 1337};
1338 1338
1339static const u32 ar9480_1p0_baseband_postamble[][5] = { 1339static const u32 ar9462_1p0_baseband_postamble[][5] = {
1340 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1340 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1341 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, 1341 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
1342 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, 1342 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
@@ -1386,7 +1386,7 @@ static const u32 ar9480_1p0_baseband_postamble[][5] = {
1386 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, 1386 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
1387}; 1387};
1388 1388
1389static const u32 ar9480_modes_fast_clock_1p0[][3] = { 1389static const u32 ar9462_modes_fast_clock_1p0[][3] = {
1390 /* Addr 5G_HT20 5G_HT40 */ 1390 /* Addr 5G_HT20 5G_HT40 */
1391 {0x00001030, 0x00000268, 0x000004d0}, 1391 {0x00001030, 0x00000268, 0x000004d0},
1392 {0x00001070, 0x0000018c, 0x00000318}, 1392 {0x00001070, 0x0000018c, 0x00000318},
@@ -1399,7 +1399,7 @@ static const u32 ar9480_modes_fast_clock_1p0[][3] = {
1399 {0x0000a254, 0x00000898, 0x00001130}, 1399 {0x0000a254, 0x00000898, 0x00001130},
1400}; 1400};
1401 1401
1402static const u32 ar9480_modes_low_ob_db_tx_gain_table_1p0[][5] = { 1402static const u32 ar9462_modes_low_ob_db_tx_gain_table_1p0[][5] = {
1403 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1403 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1404 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 1404 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
1405 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, 1405 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
@@ -1464,12 +1464,12 @@ static const u32 ar9480_modes_low_ob_db_tx_gain_table_1p0[][5] = {
1464 {0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000}, 1464 {0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000},
1465}; 1465};
1466 1466
1467static const u32 ar9480_1p0_soc_postamble[][5] = { 1467static const u32 ar9462_1p0_soc_postamble[][5] = {
1468 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1468 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1469 {0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233}, 1469 {0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233},
1470}; 1470};
1471 1471
1472static const u32 ar9480_common_mixed_rx_gain_table_1p0[][2] = { 1472static const u32 ar9462_common_mixed_rx_gain_table_1p0[][2] = {
1473 /* Addr allmodes */ 1473 /* Addr allmodes */
1474 {0x0000a000, 0x00010000}, 1474 {0x0000a000, 0x00010000},
1475 {0x0000a004, 0x00030002}, 1475 {0x0000a004, 0x00030002},
@@ -1729,14 +1729,14 @@ static const u32 ar9480_common_mixed_rx_gain_table_1p0[][2] = {
1729 {0x0000b1fc, 0x00000196}, 1729 {0x0000b1fc, 0x00000196},
1730}; 1730};
1731 1731
1732static const u32 ar9480_pcie_phy_clkreq_disable_L1_1p0[][2] = { 1732static const u32 ar9462_pcie_phy_clkreq_disable_L1_1p0[][2] = {
1733 /* Addr allmodes */ 1733 /* Addr allmodes */
1734 {0x00018c00, 0x10013e5e}, 1734 {0x00018c00, 0x10013e5e},
1735 {0x00018c04, 0x000801d8}, 1735 {0x00018c04, 0x000801d8},
1736 {0x00018c08, 0x0000580c}, 1736 {0x00018c08, 0x0000580c},
1737}; 1737};
1738 1738
1739static const u32 ar9480_1p0_baseband_core_emulation[][2] = { 1739static const u32 ar9462_1p0_baseband_core_emulation[][2] = {
1740 /* Addr allmodes */ 1740 /* Addr allmodes */
1741 {0x00009800, 0xafa68e30}, 1741 {0x00009800, 0xafa68e30},
1742 {0x00009884, 0x00002842}, 1742 {0x00009884, 0x00002842},
@@ -1758,7 +1758,7 @@ static const u32 ar9480_1p0_baseband_core_emulation[][2] = {
1758 {0x0000a690, 0x00000038}, 1758 {0x0000a690, 0x00000038},
1759}; 1759};
1760 1760
1761static const u32 ar9480_1p0_radio_core[][2] = { 1761static const u32 ar9462_1p0_radio_core[][2] = {
1762 /* Addr allmodes */ 1762 /* Addr allmodes */
1763 {0x00016000, 0x36db6db6}, 1763 {0x00016000, 0x36db6db6},
1764 {0x00016004, 0x6db6db40}, 1764 {0x00016004, 0x6db6db40},
@@ -1818,16 +1818,16 @@ static const u32 ar9480_1p0_radio_core[][2] = {
1818 {0x00016548, 0x000080c0}, 1818 {0x00016548, 0x000080c0},
1819}; 1819};
1820 1820
1821static const u32 ar9480_1p0_soc_preamble[][2] = { 1821static const u32 ar9462_1p0_soc_preamble[][2] = {
1822 /* Addr allmodes */ 1822 /* Addr allmodes */
1823 {0x00007020, 0x00000000}, 1823 {0x00007020, 0x00000000},
1824 {0x00007034, 0x00000002}, 1824 {0x00007034, 0x00000002},
1825 {0x00007038, 0x000004c2}, 1825 {0x00007038, 0x000004c2},
1826}; 1826};
1827 1827
1828static const u32 ar9480_1p0_sys2ant[][2] = { 1828static const u32 ar9462_1p0_sys2ant[][2] = {
1829 /* Addr allmodes */ 1829 /* Addr allmodes */
1830 {0x00063120, 0x00801980}, 1830 {0x00063120, 0x00801980},
1831}; 1831};
1832 1832
1833#endif /* INITVALS_9480_1P0_H */ 1833#endif /* INITVALS_9462_1P0_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9480_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
index d54163d8d69f..9c51b395b4ff 100644
--- a/drivers/net/wireless/ath/ath9k/ar9480_2p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
@@ -14,12 +14,12 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#ifndef INITVALS_9480_2P0_H 17#ifndef INITVALS_9462_2P0_H
18#define INITVALS_9480_2P0_H 18#define INITVALS_9462_2P0_H
19 19
20/* AR9480 2.0 */ 20/* AR9462 2.0 */
21 21
22static const u32 ar9480_modes_fast_clock_2p0[][3] = { 22static const u32 ar9462_modes_fast_clock_2p0[][3] = {
23 /* Addr 5G_HT20 5G_HT40 */ 23 /* Addr 5G_HT20 5G_HT40 */
24 {0x00001030, 0x00000268, 0x000004d0}, 24 {0x00001030, 0x00000268, 0x000004d0},
25 {0x00001070, 0x0000018c, 0x00000318}, 25 {0x00001070, 0x0000018c, 0x00000318},
@@ -32,14 +32,14 @@ static const u32 ar9480_modes_fast_clock_2p0[][3] = {
32 {0x0000a254, 0x00000898, 0x00001130}, 32 {0x0000a254, 0x00000898, 0x00001130},
33}; 33};
34 34
35static const u32 ar9480_pciephy_clkreq_enable_L1_2p0[][2] = { 35static const u32 ar9462_pciephy_clkreq_enable_L1_2p0[][2] = {
36 /* Addr allmodes */ 36 /* Addr allmodes */
37 {0x00018c00, 0x18253ede}, 37 {0x00018c00, 0x18253ede},
38 {0x00018c04, 0x000801d8}, 38 {0x00018c04, 0x000801d8},
39 {0x00018c08, 0x0003580c}, 39 {0x00018c08, 0x0003580c},
40}; 40};
41 41
42static const u32 ar9480_2p0_baseband_postamble[][5] = { 42static const u32 ar9462_2p0_baseband_postamble[][5] = {
43 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 43 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
44 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, 44 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
45 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, 45 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
@@ -89,7 +89,7 @@ static const u32 ar9480_2p0_baseband_postamble[][5] = {
89 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, 89 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
90}; 90};
91 91
92static const u32 ar9480_2p0_mac_core_emulation[][2] = { 92static const u32 ar9462_2p0_mac_core_emulation[][2] = {
93 /* Addr allmodes */ 93 /* Addr allmodes */
94 {0x00000030, 0x000e0085}, 94 {0x00000030, 0x000e0085},
95 {0x00000044, 0x00000008}, 95 {0x00000044, 0x00000008},
@@ -97,7 +97,7 @@ static const u32 ar9480_2p0_mac_core_emulation[][2] = {
97 {0x00008344, 0xaa4a105b}, 97 {0x00008344, 0xaa4a105b},
98}; 98};
99 99
100static const u32 ar9480_common_rx_gain_table_2p0[][2] = { 100static const u32 ar9462_common_rx_gain_table_2p0[][2] = {
101 /* Addr allmodes */ 101 /* Addr allmodes */
102 {0x0000a000, 0x00010000}, 102 {0x0000a000, 0x00010000},
103 {0x0000a004, 0x00030002}, 103 {0x0000a004, 0x00030002},
@@ -357,27 +357,27 @@ static const u32 ar9480_common_rx_gain_table_2p0[][2] = {
357 {0x0000b1fc, 0x00000196}, 357 {0x0000b1fc, 0x00000196},
358}; 358};
359 359
360static const u32 ar9480_pciephy_clkreq_disable_L1_2p0[][2] = { 360static const u32 ar9462_pciephy_clkreq_disable_L1_2p0[][2] = {
361 /* Addr allmodes */ 361 /* Addr allmodes */
362 {0x00018c00, 0x18213ede}, 362 {0x00018c00, 0x18213ede},
363 {0x00018c04, 0x000801d8}, 363 {0x00018c04, 0x000801d8},
364 {0x00018c08, 0x0003580c}, 364 {0x00018c08, 0x0003580c},
365}; 365};
366 366
367static const u32 ar9480_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = { 367static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = {
368 /* Addr allmodes */ 368 /* Addr allmodes */
369 {0x00018c00, 0x18212ede}, 369 {0x00018c00, 0x18212ede},
370 {0x00018c04, 0x000801d8}, 370 {0x00018c04, 0x000801d8},
371 {0x00018c08, 0x0003580c}, 371 {0x00018c08, 0x0003580c},
372}; 372};
373 373
374static const u32 ar9480_2p0_sys3ant[][2] = { 374static const u32 ar9462_2p0_sys3ant[][2] = {
375 /* Addr allmodes */ 375 /* Addr allmodes */
376 {0x00063280, 0x00040807}, 376 {0x00063280, 0x00040807},
377 {0x00063284, 0x104ccccc}, 377 {0x00063284, 0x104ccccc},
378}; 378};
379 379
380static const u32 ar9480_common_rx_gain_table_ar9280_2p0[][2] = { 380static const u32 ar9462_common_rx_gain_table_ar9280_2p0[][2] = {
381 /* Addr allmodes */ 381 /* Addr allmodes */
382 {0x0000a000, 0x02000101}, 382 {0x0000a000, 0x02000101},
383 {0x0000a004, 0x02000102}, 383 {0x0000a004, 0x02000102},
@@ -679,20 +679,20 @@ static const u32 ar9200_ar9280_2p0_radio_core[][2] = {
679 {0x00007894, 0x5a108000}, 679 {0x00007894, 0x5a108000},
680}; 680};
681 681
682static const u32 ar9480_2p0_mac_postamble_emulation[][5] = { 682static const u32 ar9462_2p0_mac_postamble_emulation[][5] = {
683 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 683 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
684 {0x00008014, 0x10f810f8, 0x10f810f8, 0x10f810f8, 0x10f810f8}, 684 {0x00008014, 0x10f810f8, 0x10f810f8, 0x10f810f8, 0x10f810f8},
685 {0x0000801c, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017}, 685 {0x0000801c, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017},
686}; 686};
687 687
688static const u32 ar9480_2p0_radio_postamble_sys3ant[][5] = { 688static const u32 ar9462_2p0_radio_postamble_sys3ant[][5] = {
689 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 689 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
690 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, 690 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
691 {0x00016140, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, 691 {0x00016140, 0x10804008, 0x10804008, 0x90804008, 0x90804008},
692 {0x00016540, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, 692 {0x00016540, 0x10804008, 0x10804008, 0x90804008, 0x90804008},
693}; 693};
694 694
695static const u32 ar9480_2p0_baseband_postamble_emulation[][5] = { 695static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = {
696 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 696 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
697 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 697 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
698 {0x00009e3c, 0xcf946221, 0xcf946221, 0xcf946221, 0xcf946221}, 698 {0x00009e3c, 0xcf946221, 0xcf946221, 0xcf946221, 0xcf946221},
@@ -714,14 +714,14 @@ static const u32 ar9480_2p0_baseband_postamble_emulation[][5] = {
714 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 714 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
715}; 715};
716 716
717static const u32 ar9480_2p0_radio_postamble_sys2ant[][5] = { 717static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = {
718 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 718 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
719 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, 719 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
720 {0x00016140, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, 720 {0x00016140, 0x10804008, 0x10804008, 0x90804008, 0x90804008},
721 {0x00016540, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, 721 {0x00016540, 0x10804008, 0x10804008, 0x90804008, 0x90804008},
722}; 722};
723 723
724static const u32 ar9480_common_wo_xlna_rx_gain_table_2p0[][2] = { 724static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = {
725 /* Addr allmodes */ 725 /* Addr allmodes */
726 {0x0000a000, 0x00010000}, 726 {0x0000a000, 0x00010000},
727 {0x0000a004, 0x00030002}, 727 {0x0000a004, 0x00030002},
@@ -981,14 +981,14 @@ static const u32 ar9480_common_wo_xlna_rx_gain_table_2p0[][2] = {
981 {0x0000b1fc, 0x00000196}, 981 {0x0000b1fc, 0x00000196},
982}; 982};
983 983
984static const u32 ar9480_2p0_baseband_core_txfir_coeff_japan_2484[][2] = { 984static const u32 ar9462_2p0_baseband_core_txfir_coeff_japan_2484[][2] = {
985 /* Addr allmodes */ 985 /* Addr allmodes */
986 {0x0000a398, 0x00000000}, 986 {0x0000a398, 0x00000000},
987 {0x0000a39c, 0x6f7f0301}, 987 {0x0000a39c, 0x6f7f0301},
988 {0x0000a3a0, 0xca9228ee}, 988 {0x0000a3a0, 0xca9228ee},
989}; 989};
990 990
991static const u32 ar9480_modes_low_ob_db_tx_gain_table_2p0[][5] = { 991static const u32 ar9462_modes_low_ob_db_tx_gain_table_2p0[][5] = {
992 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 992 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
993 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 993 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
994 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 994 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
@@ -1057,12 +1057,12 @@ static const u32 ar9480_modes_low_ob_db_tx_gain_table_2p0[][5] = {
1057 {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, 1057 {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1058}; 1058};
1059 1059
1060static const u32 ar9480_2p0_soc_postamble[][5] = { 1060static const u32 ar9462_2p0_soc_postamble[][5] = {
1061 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1061 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1062 {0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233}, 1062 {0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233},
1063}; 1063};
1064 1064
1065static const u32 ar9480_2p0_baseband_core[][2] = { 1065static const u32 ar9462_2p0_baseband_core[][2] = {
1066 /* Addr allmodes */ 1066 /* Addr allmodes */
1067 {0x00009800, 0xafe68e30}, 1067 {0x00009800, 0xafe68e30},
1068 {0x00009804, 0xfd14e000}, 1068 {0x00009804, 0xfd14e000},
@@ -1221,7 +1221,7 @@ static const u32 ar9480_2p0_baseband_core[][2] = {
1221 {0x0000b6b4, 0x00000001}, 1221 {0x0000b6b4, 0x00000001},
1222}; 1222};
1223 1223
1224static const u32 ar9480_2p0_radio_postamble[][5] = { 1224static const u32 ar9462_2p0_radio_postamble[][5] = {
1225 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1225 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1226 {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524}, 1226 {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
1227 {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70}, 1227 {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70},
@@ -1229,7 +1229,7 @@ static const u32 ar9480_2p0_radio_postamble[][5] = {
1229 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, 1229 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
1230}; 1230};
1231 1231
1232static const u32 ar9480_modes_high_ob_db_tx_gain_table_2p0[][5] = { 1232static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = {
1233 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1233 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1234 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 1234 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
1235 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, 1235 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
@@ -1298,7 +1298,7 @@ static const u32 ar9480_modes_high_ob_db_tx_gain_table_2p0[][5] = {
1298 {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, 1298 {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1299}; 1299};
1300 1300
1301static const u32 ar9480_2p0_radio_core[][2] = { 1301static const u32 ar9462_2p0_radio_core[][2] = {
1302 /* Addr allmodes */ 1302 /* Addr allmodes */
1303 {0x00016000, 0x36db6db6}, 1303 {0x00016000, 0x36db6db6},
1304 {0x00016004, 0x6db6db40}, 1304 {0x00016004, 0x6db6db40},
@@ -1356,7 +1356,7 @@ static const u32 ar9480_2p0_radio_core[][2] = {
1356 {0x00016548, 0x000080c0}, 1356 {0x00016548, 0x000080c0},
1357}; 1357};
1358 1358
1359static const u32 ar9480_2p0_tx_gain_table_baseband_postamble_emulation[][5] = { 1359static const u32 ar9462_2p0_tx_gain_table_baseband_postamble_emulation[][5] = {
1360 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1360 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1361 {0x0000a410, 0x000000d5, 0x000000d5, 0x000000d5, 0x000000d5}, 1361 {0x0000a410, 0x000000d5, 0x000000d5, 0x000000d5, 0x000000d5},
1362 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1362 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -1374,19 +1374,19 @@ static const u32 ar9480_2p0_tx_gain_table_baseband_postamble_emulation[][5] = {
1374 {0x0000a534, 0x00034e8a, 0x00034e8a, 0x00034e8a, 0x00034e8a}, 1374 {0x0000a534, 0x00034e8a, 0x00034e8a, 0x00034e8a, 0x00034e8a},
1375}; 1375};
1376 1376
1377static const u32 ar9480_2p0_soc_preamble[][2] = { 1377static const u32 ar9462_2p0_soc_preamble[][2] = {
1378 /* Addr allmodes */ 1378 /* Addr allmodes */
1379 {0x00007020, 0x00000000}, 1379 {0x00007020, 0x00000000},
1380 {0x00007034, 0x00000002}, 1380 {0x00007034, 0x00000002},
1381 {0x00007038, 0x000004c2}, 1381 {0x00007038, 0x000004c2},
1382}; 1382};
1383 1383
1384static const u32 ar9480_2p0_sys2ant[][2] = { 1384static const u32 ar9462_2p0_sys2ant[][2] = {
1385 /* Addr allmodes */ 1385 /* Addr allmodes */
1386 {0x00063120, 0x00801980}, 1386 {0x00063120, 0x00801980},
1387}; 1387};
1388 1388
1389static const u32 ar9480_2p0_mac_core[][2] = { 1389static const u32 ar9462_2p0_mac_core[][2] = {
1390 /* Addr allmodes */ 1390 /* Addr allmodes */
1391 {0x00000008, 0x00000000}, 1391 {0x00000008, 0x00000000},
1392 {0x00000030, 0x000e0085}, 1392 {0x00000030, 0x000e0085},
@@ -1550,7 +1550,7 @@ static const u32 ar9480_2p0_mac_core[][2] = {
1550 {0x000083d0, 0x000301ff}, 1550 {0x000083d0, 0x000301ff},
1551}; 1551};
1552 1552
1553static const u32 ar9480_2p0_mac_postamble[][5] = { 1553static const u32 ar9462_2p0_mac_postamble[][5] = {
1554 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1554 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1555 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, 1555 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
1556 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, 1556 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
@@ -1562,7 +1562,7 @@ static const u32 ar9480_2p0_mac_postamble[][5] = {
1562 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, 1562 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
1563}; 1563};
1564 1564
1565static const u32 ar9480_common_mixed_rx_gain_table_2p0[][2] = { 1565static const u32 ar9462_common_mixed_rx_gain_table_2p0[][2] = {
1566 /* Addr allmodes */ 1566 /* Addr allmodes */
1567 {0x0000a000, 0x00010000}, 1567 {0x0000a000, 0x00010000},
1568 {0x0000a004, 0x00030002}, 1568 {0x0000a004, 0x00030002},
@@ -1822,7 +1822,7 @@ static const u32 ar9480_common_mixed_rx_gain_table_2p0[][2] = {
1822 {0x0000b1fc, 0x00000196}, 1822 {0x0000b1fc, 0x00000196},
1823}; 1823};
1824 1824
1825static const u32 ar9480_modes_green_ob_db_tx_gain_table_2p0[][5] = { 1825static const u32 ar9462_modes_green_ob_db_tx_gain_table_2p0[][5] = {
1826 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1826 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1827 {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003}, 1827 {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003},
1828 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, 1828 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
@@ -1891,7 +1891,7 @@ static const u32 ar9480_modes_green_ob_db_tx_gain_table_2p0[][5] = {
1891 {0x00016454, 0x6db60180, 0x6db60180, 0x6db60180, 0x6db60180}, 1891 {0x00016454, 0x6db60180, 0x6db60180, 0x6db60180, 0x6db60180},
1892}; 1892};
1893 1893
1894static const u32 ar9480_2p0_BTCOEX_MAX_TXPWR_table[][2] = { 1894static const u32 ar9462_2p0_BTCOEX_MAX_TXPWR_table[][2] = {
1895 /* Addr allmodes */ 1895 /* Addr allmodes */
1896 {0x000018c0, 0x10101010}, 1896 {0x000018c0, 0x10101010},
1897 {0x000018c4, 0x10101010}, 1897 {0x000018c4, 0x10101010},
@@ -1903,7 +1903,7 @@ static const u32 ar9480_2p0_BTCOEX_MAX_TXPWR_table[][2] = {
1903 {0x000018dc, 0x10101010}, 1903 {0x000018dc, 0x10101010},
1904}; 1904};
1905 1905
1906static const u32 ar9480_2p0_baseband_core_emulation[][2] = { 1906static const u32 ar9462_2p0_baseband_core_emulation[][2] = {
1907 /* Addr allmodes */ 1907 /* Addr allmodes */
1908 {0x00009800, 0xafa68e30}, 1908 {0x00009800, 0xafa68e30},
1909 {0x00009884, 0x00002842}, 1909 {0x00009884, 0x00002842},
@@ -1925,4 +1925,4 @@ static const u32 ar9480_2p0_baseband_core_emulation[][2] = {
1925 {0x0000a690, 0x00000038}, 1925 {0x0000a690, 0x00000038},
1926}; 1926};
1927 1927
1928#endif /* INITVALS_9480_2P0_H */ 1928#endif /* INITVALS_9462_2P0_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 1e8614783181..1c269f50822b 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -458,7 +458,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc);
458#define ATH_LED_PIN_9287 8 458#define ATH_LED_PIN_9287 8
459#define ATH_LED_PIN_9300 10 459#define ATH_LED_PIN_9300 10
460#define ATH_LED_PIN_9485 6 460#define ATH_LED_PIN_9485 6
461#define ATH_LED_PIN_9480 0 461#define ATH_LED_PIN_9462 0
462 462
463#ifdef CONFIG_MAC80211_LEDS 463#ifdef CONFIG_MAC80211_LEDS
464void ath_init_leds(struct ath_softc *sc); 464void ath_init_leds(struct ath_softc *sc);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 9cdeaebc844f..a13cabb95435 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -515,7 +515,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
515 sc->sc_flags |= SC_OP_TSF_RESET; 515 sc->sc_flags |= SC_OP_TSF_RESET;
516 ath9k_beacon_init(sc, nexttbtt, intval); 516 ath9k_beacon_init(sc, nexttbtt, intval);
517 sc->beacon.bmisscnt = 0; 517 sc->beacon.bmisscnt = 0;
518 ath9k_hw_set_interrupts(ah, ah->imask); 518 ath9k_hw_set_interrupts(ah);
519 ath9k_hw_enable_interrupts(ah); 519 ath9k_hw_enable_interrupts(ah);
520} 520}
521 521
@@ -643,7 +643,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
643 ath9k_hw_set_sta_beacon_timers(ah, &bs); 643 ath9k_hw_set_sta_beacon_timers(ah, &bs);
644 ah->imask |= ATH9K_INT_BMISS; 644 ah->imask |= ATH9K_INT_BMISS;
645 645
646 ath9k_hw_set_interrupts(ah, ah->imask); 646 ath9k_hw_set_interrupts(ah);
647 ath9k_hw_enable_interrupts(ah); 647 ath9k_hw_enable_interrupts(ah);
648} 648}
649 649
@@ -679,7 +679,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
679 ath9k_beacon_init(sc, nexttbtt, intval); 679 ath9k_beacon_init(sc, nexttbtt, intval);
680 sc->beacon.bmisscnt = 0; 680 sc->beacon.bmisscnt = 0;
681 681
682 ath9k_hw_set_interrupts(ah, ah->imask); 682 ath9k_hw_set_interrupts(ah);
683 ath9k_hw_enable_interrupts(ah); 683 ath9k_hw_enable_interrupts(ah);
684} 684}
685 685
@@ -821,11 +821,11 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status)
821 if (status) { 821 if (status) {
822 /* Re-enable beaconing */ 822 /* Re-enable beaconing */
823 ah->imask |= ATH9K_INT_SWBA; 823 ah->imask |= ATH9K_INT_SWBA;
824 ath9k_hw_set_interrupts(ah, ah->imask); 824 ath9k_hw_set_interrupts(ah);
825 } else { 825 } else {
826 /* Disable SWBA interrupt */ 826 /* Disable SWBA interrupt */
827 ah->imask &= ~ATH9K_INT_SWBA; 827 ah->imask &= ~ATH9K_INT_SWBA;
828 ath9k_hw_set_interrupts(ah, ah->imask); 828 ath9k_hw_set_interrupts(ah);
829 tasklet_kill(&sc->bcon_tasklet); 829 tasklet_kill(&sc->bcon_tasklet);
830 ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); 830 ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
831 } 831 }
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index dc705a224952..905f1b313961 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -161,10 +161,12 @@ EXPORT_SYMBOL(ath9k_cmn_count_streams);
161void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, 161void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
162 u16 new_txpow, u16 *txpower) 162 u16 new_txpow, u16 *txpower)
163{ 163{
164 if (cur_txpow != new_txpow) { 164 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
165
166 if (reg->power_limit != new_txpow) {
165 ath9k_hw_set_txpowerlimit(ah, new_txpow, false); 167 ath9k_hw_set_txpowerlimit(ah, new_txpow, false);
166 /* read back in case value is clamped */ 168 /* read back in case value is clamped */
167 *txpower = ath9k_hw_regulatory(ah)->power_limit; 169 *txpower = reg->max_power_level;
168 } 170 }
169} 171}
170EXPORT_SYMBOL(ath9k_cmn_update_txpow); 172EXPORT_SYMBOL(ath9k_cmn_update_txpow);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index a5329c98f9ea..327aa28f6030 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -523,9 +523,22 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
523 if (tmp & ATH9K_RX_FILTER_PHYRADAR) 523 if (tmp & ATH9K_RX_FILTER_PHYRADAR)
524 len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR"); 524 len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR");
525 if (tmp & ATH9K_RX_FILTER_MCAST_BCAST_ALL) 525 if (tmp & ATH9K_RX_FILTER_MCAST_BCAST_ALL)
526 len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL\n"); 526 len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL");
527 else 527
528 len += snprintf(buf + len, sizeof(buf) - len, "\n"); 528 len += snprintf(buf + len, sizeof(buf) - len,
529 "\n\nReset causes:\n"
530 " baseband hang: %d\n"
531 " baseband watchdog: %d\n"
532 " fatal hardware error interrupt: %d\n"
533 " tx hardware error: %d\n"
534 " tx path hang: %d\n"
535 " pll rx hang: %d\n",
536 sc->debug.stats.reset[RESET_TYPE_BB_HANG],
537 sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG],
538 sc->debug.stats.reset[RESET_TYPE_FATAL_INT],
539 sc->debug.stats.reset[RESET_TYPE_TX_ERROR],
540 sc->debug.stats.reset[RESET_TYPE_TX_HANG],
541 sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
529 542
530 if (len > sizeof(buf)) 543 if (len > sizeof(buf))
531 len = sizeof(buf); 544 len = sizeof(buf);
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index b93e88bd8c58..356352ac2d6e 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -25,8 +25,10 @@ struct ath_buf;
25 25
26#ifdef CONFIG_ATH9K_DEBUGFS 26#ifdef CONFIG_ATH9K_DEBUGFS
27#define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++ 27#define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
28#define RESET_STAT_INC(sc, type) sc->debug.stats.reset[type]++
28#else 29#else
29#define TX_STAT_INC(q, c) do { } while (0) 30#define TX_STAT_INC(q, c) do { } while (0)
31#define RESET_STAT_INC(sc, type) do { } while (0)
30#endif 32#endif
31 33
32#ifdef CONFIG_ATH9K_DEBUGFS 34#ifdef CONFIG_ATH9K_DEBUGFS
@@ -171,10 +173,21 @@ struct ath_rx_stats {
171 u8 rs_antenna; 173 u8 rs_antenna;
172}; 174};
173 175
176enum ath_reset_type {
177 RESET_TYPE_BB_HANG,
178 RESET_TYPE_BB_WATCHDOG,
179 RESET_TYPE_FATAL_INT,
180 RESET_TYPE_TX_ERROR,
181 RESET_TYPE_TX_HANG,
182 RESET_TYPE_PLL_HANG,
183 __RESET_TYPE_MAX
184};
185
174struct ath_stats { 186struct ath_stats {
175 struct ath_interrupt_stats istats; 187 struct ath_interrupt_stats istats;
176 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; 188 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
177 struct ath_rx_stats rxstats; 189 struct ath_rx_stats rxstats;
190 u32 reset[__RESET_TYPE_MAX];
178}; 191};
179 192
180#define ATH_DBG_MAX_SAMPLES 10 193#define ATH_DBG_MAX_SAMPLES 10
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 5d92f96980e6..49abd34be741 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -108,7 +108,7 @@
108#define EEP_RFSILENT_ENABLED_S 0 108#define EEP_RFSILENT_ENABLED_S 0
109#define EEP_RFSILENT_POLARITY 0x0002 109#define EEP_RFSILENT_POLARITY 0x0002
110#define EEP_RFSILENT_POLARITY_S 1 110#define EEP_RFSILENT_POLARITY_S 1
111#define EEP_RFSILENT_GPIO_SEL (AR_SREV_9480(ah) ? 0x00fc : 0x001c) 111#define EEP_RFSILENT_GPIO_SEL (AR_SREV_9462(ah) ? 0x00fc : 0x001c)
112#define EEP_RFSILENT_GPIO_SEL_S 2 112#define EEP_RFSILENT_GPIO_SEL_S 2
113 113
114#define AR5416_OPFLAGS_11A 0x01 114#define AR5416_OPFLAGS_11A 0x01
@@ -220,7 +220,6 @@ enum eeprom_param {
220 EEP_MAC_MID, 220 EEP_MAC_MID,
221 EEP_MAC_LSW, 221 EEP_MAC_LSW,
222 EEP_REG_0, 222 EEP_REG_0,
223 EEP_REG_1,
224 EEP_OP_CAP, 223 EEP_OP_CAP,
225 EEP_OP_MODE, 224 EEP_OP_MODE,
226 EEP_RF_SILENT, 225 EEP_RF_SILENT,
@@ -248,7 +247,9 @@ enum eeprom_param {
248 EEP_PAPRD, 247 EEP_PAPRD,
249 EEP_MODAL_VER, 248 EEP_MODAL_VER,
250 EEP_ANT_DIV_CTL1, 249 EEP_ANT_DIV_CTL1,
251 EEP_CHAIN_MASK_REDUCE 250 EEP_CHAIN_MASK_REDUCE,
251 EEP_ANTENNA_GAIN_2G,
252 EEP_ANTENNA_GAIN_5G
252}; 253};
253 254
254enum ar5416_rates { 255enum ar5416_rates {
@@ -652,8 +653,7 @@ struct eeprom_ops {
652 void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan); 653 void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
653 void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan, 654 void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
654 u16 cfgCtl, u8 twiceAntennaReduction, 655 u16 cfgCtl, u8 twiceAntennaReduction,
655 u8 twiceMaxRegulatoryPower, u8 powerLimit, 656 u8 powerLimit, bool test);
656 bool test);
657 u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz); 657 u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
658}; 658};
659 659
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 303560e49ac8..9a7520f987f0 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -322,8 +322,6 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
322 return get_unaligned_be16(pBase->macAddr + 4); 322 return get_unaligned_be16(pBase->macAddr + 4);
323 case EEP_REG_0: 323 case EEP_REG_0:
324 return pBase->regDmn[0]; 324 return pBase->regDmn[0];
325 case EEP_REG_1:
326 return pBase->regDmn[1];
327 case EEP_OP_CAP: 325 case EEP_OP_CAP:
328 return pBase->deviceCap; 326 return pBase->deviceCap;
329 case EEP_OP_MODE: 327 case EEP_OP_MODE:
@@ -350,6 +348,8 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
350 return pModal->antdiv_ctl1; 348 return pModal->antdiv_ctl1;
351 case EEP_TXGAIN_TYPE: 349 case EEP_TXGAIN_TYPE:
352 return pBase->txGainType; 350 return pBase->txGainType;
351 case EEP_ANTENNA_GAIN_2G:
352 return pModal->antennaGainCh[0];
353 default: 353 default:
354 return 0; 354 return 0;
355 } 355 }
@@ -462,8 +462,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
462 struct ath9k_channel *chan, 462 struct ath9k_channel *chan,
463 int16_t *ratesArray, 463 int16_t *ratesArray,
464 u16 cfgCtl, 464 u16 cfgCtl,
465 u16 AntennaReduction, 465 u16 antenna_reduction,
466 u16 twiceMaxRegulatoryPower,
467 u16 powerLimit) 466 u16 powerLimit)
468{ 467{
469#define CMP_TEST_GRP \ 468#define CMP_TEST_GRP \
@@ -472,20 +471,16 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
472 || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \ 471 || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
473 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL)) 472 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
474 473
475 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
476 int i; 474 int i;
477 int16_t twiceLargestAntenna;
478 u16 twiceMinEdgePower; 475 u16 twiceMinEdgePower;
479 u16 twiceMaxEdgePower = MAX_RATE_POWER; 476 u16 twiceMaxEdgePower = MAX_RATE_POWER;
480 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 477 u16 scaledPower = 0, minCtlPower;
481 u16 numCtlModes; 478 u16 numCtlModes;
482 const u16 *pCtlMode; 479 const u16 *pCtlMode;
483 u16 ctlMode, freq; 480 u16 ctlMode, freq;
484 struct chan_centers centers; 481 struct chan_centers centers;
485 struct cal_ctl_data_4k *rep; 482 struct cal_ctl_data_4k *rep;
486 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 483 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
487 static const u16 tpScaleReductionTable[5] =
488 { 0, 3, 6, 9, MAX_RATE_POWER };
489 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { 484 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
490 0, { 0, 0, 0, 0} 485 0, { 0, 0, 0, 0}
491 }; 486 };
@@ -503,19 +498,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
503 498
504 ath9k_hw_get_channel_centers(ah, chan, &centers); 499 ath9k_hw_get_channel_centers(ah, chan, &centers);
505 500
506 twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0]; 501 scaledPower = powerLimit - antenna_reduction;
507 twiceLargestAntenna = (int16_t)min(AntennaReduction -
508 twiceLargestAntenna, 0);
509
510 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
511 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
512 maxRegAllowedPower -=
513 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
514 }
515
516 scaledPower = min(powerLimit, maxRegAllowedPower);
517 scaledPower = max((u16)0, scaledPower);
518
519 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; 502 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
520 pCtlMode = ctlModesFor11g; 503 pCtlMode = ctlModesFor11g;
521 504
@@ -671,7 +654,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
671 struct ath9k_channel *chan, 654 struct ath9k_channel *chan,
672 u16 cfgCtl, 655 u16 cfgCtl,
673 u8 twiceAntennaReduction, 656 u8 twiceAntennaReduction,
674 u8 twiceMaxRegulatoryPower,
675 u8 powerLimit, bool test) 657 u8 powerLimit, bool test)
676{ 658{
677 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 659 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
@@ -691,7 +673,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
691 ath9k_hw_set_4k_power_per_rate_table(ah, chan, 673 ath9k_hw_set_4k_power_per_rate_table(ah, chan,
692 &ratesArray[0], cfgCtl, 674 &ratesArray[0], cfgCtl,
693 twiceAntennaReduction, 675 twiceAntennaReduction,
694 twiceMaxRegulatoryPower,
695 powerLimit); 676 powerLimit);
696 677
697 ath9k_hw_set_4k_power_cal_table(ah, chan); 678 ath9k_hw_set_4k_power_cal_table(ah, chan);
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 6698b722b604..4f5c50a87ce3 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -308,8 +308,6 @@ static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
308 return get_unaligned_be16(pBase->macAddr + 4); 308 return get_unaligned_be16(pBase->macAddr + 4);
309 case EEP_REG_0: 309 case EEP_REG_0:
310 return pBase->regDmn[0]; 310 return pBase->regDmn[0];
311 case EEP_REG_1:
312 return pBase->regDmn[1];
313 case EEP_OP_CAP: 311 case EEP_OP_CAP:
314 return pBase->deviceCap; 312 return pBase->deviceCap;
315 case EEP_OP_MODE: 313 case EEP_OP_MODE:
@@ -336,6 +334,9 @@ static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
336 return pBase->tempSensSlopePalOn; 334 return pBase->tempSensSlopePalOn;
337 else 335 else
338 return 0; 336 return 0;
337 case EEP_ANTENNA_GAIN_2G:
338 return max_t(u8, pModal->antennaGainCh[0],
339 pModal->antennaGainCh[1]);
339 default: 340 default:
340 return 0; 341 return 0;
341 } 342 }
@@ -554,8 +555,7 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
554 struct ath9k_channel *chan, 555 struct ath9k_channel *chan,
555 int16_t *ratesArray, 556 int16_t *ratesArray,
556 u16 cfgCtl, 557 u16 cfgCtl,
557 u16 AntennaReduction, 558 u16 antenna_reduction,
558 u16 twiceMaxRegulatoryPower,
559 u16 powerLimit) 559 u16 powerLimit)
560{ 560{
561#define CMP_CTL \ 561#define CMP_CTL \
@@ -569,12 +569,8 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
569#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 569#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
570#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 570#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
571 571
572 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
573 u16 twiceMaxEdgePower = MAX_RATE_POWER; 572 u16 twiceMaxEdgePower = MAX_RATE_POWER;
574 static const u16 tpScaleReductionTable[5] =
575 { 0, 3, 6, 9, MAX_RATE_POWER };
576 int i; 573 int i;
577 int16_t twiceLargestAntenna;
578 struct cal_ctl_data_ar9287 *rep; 574 struct cal_ctl_data_ar9287 *rep;
579 struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} }, 575 struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} },
580 targetPowerCck = {0, {0, 0, 0, 0} }; 576 targetPowerCck = {0, {0, 0, 0, 0} };
@@ -582,7 +578,7 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
582 targetPowerCckExt = {0, {0, 0, 0, 0} }; 578 targetPowerCckExt = {0, {0, 0, 0, 0} };
583 struct cal_target_power_ht targetPowerHt20, 579 struct cal_target_power_ht targetPowerHt20,
584 targetPowerHt40 = {0, {0, 0, 0, 0} }; 580 targetPowerHt40 = {0, {0, 0, 0, 0} };
585 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 581 u16 scaledPower = 0, minCtlPower;
586 static const u16 ctlModesFor11g[] = { 582 static const u16 ctlModesFor11g[] = {
587 CTL_11B, CTL_11G, CTL_2GHT20, 583 CTL_11B, CTL_11G, CTL_2GHT20,
588 CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 584 CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
@@ -597,24 +593,7 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
597 tx_chainmask = ah->txchainmask; 593 tx_chainmask = ah->txchainmask;
598 594
599 ath9k_hw_get_channel_centers(ah, chan, &centers); 595 ath9k_hw_get_channel_centers(ah, chan, &centers);
600 596 scaledPower = powerLimit - antenna_reduction;
601 /* Compute TxPower reduction due to Antenna Gain */
602 twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0],
603 pEepData->modalHeader.antennaGainCh[1]);
604 twiceLargestAntenna = (int16_t)min((AntennaReduction) -
605 twiceLargestAntenna, 0);
606
607 /*
608 * scaledPower is the minimum of the user input power level
609 * and the regulatory allowed power level.
610 */
611 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
612
613 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX)
614 maxRegAllowedPower -=
615 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
616
617 scaledPower = min(powerLimit, maxRegAllowedPower);
618 597
619 /* 598 /*
620 * Reduce scaled Power by number of chains active 599 * Reduce scaled Power by number of chains active
@@ -815,7 +794,6 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
815static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, 794static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
816 struct ath9k_channel *chan, u16 cfgCtl, 795 struct ath9k_channel *chan, u16 cfgCtl,
817 u8 twiceAntennaReduction, 796 u8 twiceAntennaReduction,
818 u8 twiceMaxRegulatoryPower,
819 u8 powerLimit, bool test) 797 u8 powerLimit, bool test)
820{ 798{
821 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 799 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
@@ -834,7 +812,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
834 ath9k_hw_set_ar9287_power_per_rate_table(ah, chan, 812 ath9k_hw_set_ar9287_power_per_rate_table(ah, chan,
835 &ratesArray[0], cfgCtl, 813 &ratesArray[0], cfgCtl,
836 twiceAntennaReduction, 814 twiceAntennaReduction,
837 twiceMaxRegulatoryPower,
838 powerLimit); 815 powerLimit);
839 816
840 ath9k_hw_set_ar9287_power_cal_table(ah, chan); 817 ath9k_hw_set_ar9287_power_cal_table(ah, chan);
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index eda681fc7ba6..81e629671679 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -400,6 +400,7 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
400 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 400 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
401 struct modal_eep_header *pModal = eep->modalHeader; 401 struct modal_eep_header *pModal = eep->modalHeader;
402 struct base_eep_header *pBase = &eep->baseEepHeader; 402 struct base_eep_header *pBase = &eep->baseEepHeader;
403 int band = 0;
403 404
404 switch (param) { 405 switch (param) {
405 case EEP_NFTHRESH_5: 406 case EEP_NFTHRESH_5:
@@ -414,8 +415,6 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
414 return get_unaligned_be16(pBase->macAddr + 4); 415 return get_unaligned_be16(pBase->macAddr + 4);
415 case EEP_REG_0: 416 case EEP_REG_0:
416 return pBase->regDmn[0]; 417 return pBase->regDmn[0];
417 case EEP_REG_1:
418 return pBase->regDmn[1];
419 case EEP_OP_CAP: 418 case EEP_OP_CAP:
420 return pBase->deviceCap; 419 return pBase->deviceCap;
421 case EEP_OP_MODE: 420 case EEP_OP_MODE:
@@ -467,6 +466,14 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
467 return pBase->pwr_table_offset; 466 return pBase->pwr_table_offset;
468 else 467 else
469 return AR5416_PWR_TABLE_OFFSET_DB; 468 return AR5416_PWR_TABLE_OFFSET_DB;
469 case EEP_ANTENNA_GAIN_2G:
470 band = 1;
471 /* fall through */
472 case EEP_ANTENNA_GAIN_5G:
473 return max_t(u8, max_t(u8,
474 pModal[band].antennaGainCh[0],
475 pModal[band].antennaGainCh[1]),
476 pModal[band].antennaGainCh[2]);
470 default: 477 default:
471 return 0; 478 return 0;
472 } 479 }
@@ -986,21 +993,15 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
986 struct ath9k_channel *chan, 993 struct ath9k_channel *chan,
987 int16_t *ratesArray, 994 int16_t *ratesArray,
988 u16 cfgCtl, 995 u16 cfgCtl,
989 u16 AntennaReduction, 996 u16 antenna_reduction,
990 u16 twiceMaxRegulatoryPower,
991 u16 powerLimit) 997 u16 powerLimit)
992{ 998{
993#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ 999#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
994#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */ 1000#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
995 1001
996 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
997 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 1002 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
998 u16 twiceMaxEdgePower = MAX_RATE_POWER; 1003 u16 twiceMaxEdgePower = MAX_RATE_POWER;
999 static const u16 tpScaleReductionTable[5] =
1000 { 0, 3, 6, 9, MAX_RATE_POWER };
1001
1002 int i; 1004 int i;
1003 int16_t twiceLargestAntenna;
1004 struct cal_ctl_data *rep; 1005 struct cal_ctl_data *rep;
1005 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { 1006 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
1006 0, { 0, 0, 0, 0} 1007 0, { 0, 0, 0, 0}
@@ -1012,7 +1013,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
1012 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { 1013 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
1013 0, {0, 0, 0, 0} 1014 0, {0, 0, 0, 0}
1014 }; 1015 };
1015 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 1016 u16 scaledPower = 0, minCtlPower;
1016 static const u16 ctlModesFor11a[] = { 1017 static const u16 ctlModesFor11a[] = {
1017 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 1018 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
1018 }; 1019 };
@@ -1031,27 +1032,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
1031 1032
1032 ath9k_hw_get_channel_centers(ah, chan, &centers); 1033 ath9k_hw_get_channel_centers(ah, chan, &centers);
1033 1034
1034 twiceLargestAntenna = max( 1035 scaledPower = powerLimit - antenna_reduction;
1035 pEepData->modalHeader
1036 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
1037 pEepData->modalHeader
1038 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
1039
1040 twiceLargestAntenna = max((u8)twiceLargestAntenna,
1041 pEepData->modalHeader
1042 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
1043
1044 twiceLargestAntenna = (int16_t)min(AntennaReduction -
1045 twiceLargestAntenna, 0);
1046
1047 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
1048
1049 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
1050 maxRegAllowedPower -=
1051 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
1052 }
1053
1054 scaledPower = min(powerLimit, maxRegAllowedPower);
1055 1036
1056 switch (ar5416_get_ntxchains(tx_chainmask)) { 1037 switch (ar5416_get_ntxchains(tx_chainmask)) {
1057 case 1: 1038 case 1:
@@ -1256,7 +1237,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1256 struct ath9k_channel *chan, 1237 struct ath9k_channel *chan,
1257 u16 cfgCtl, 1238 u16 cfgCtl,
1258 u8 twiceAntennaReduction, 1239 u8 twiceAntennaReduction,
1259 u8 twiceMaxRegulatoryPower,
1260 u8 powerLimit, bool test) 1240 u8 powerLimit, bool test)
1261{ 1241{
1262#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta) 1242#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
@@ -1278,7 +1258,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1278 ath9k_hw_set_def_power_per_rate_table(ah, chan, 1258 ath9k_hw_set_def_power_per_rate_table(ah, chan,
1279 &ratesArray[0], cfgCtl, 1259 &ratesArray[0], cfgCtl,
1280 twiceAntennaReduction, 1260 twiceAntennaReduction,
1281 twiceMaxRegulatoryPower,
1282 powerLimit); 1261 powerLimit);
1283 1262
1284 ath9k_hw_set_def_power_cal_table(ah, chan); 1263 ath9k_hw_set_def_power_cal_table(ah, chan);
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index fd0f84ebdb51..655576c8fdab 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -48,8 +48,8 @@ void ath_init_leds(struct ath_softc *sc)
48 sc->sc_ah->led_pin = ATH_LED_PIN_9485; 48 sc->sc_ah->led_pin = ATH_LED_PIN_9485;
49 else if (AR_SREV_9300(sc->sc_ah)) 49 else if (AR_SREV_9300(sc->sc_ah))
50 sc->sc_ah->led_pin = ATH_LED_PIN_9300; 50 sc->sc_ah->led_pin = ATH_LED_PIN_9300;
51 else if (AR_SREV_9480(sc->sc_ah)) 51 else if (AR_SREV_9462(sc->sc_ah))
52 sc->sc_ah->led_pin = ATH_LED_PIN_9480; 52 sc->sc_ah->led_pin = ATH_LED_PIN_9462;
53 else 53 else
54 sc->sc_ah->led_pin = ATH_LED_PIN_DEF; 54 sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
55 } 55 }
@@ -155,7 +155,7 @@ static void ath9k_gen_timer_start(struct ath_hw *ah,
155 if ((ah->imask & ATH9K_INT_GENTIMER) == 0) { 155 if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
156 ath9k_hw_disable_interrupts(ah); 156 ath9k_hw_disable_interrupts(ah);
157 ah->imask |= ATH9K_INT_GENTIMER; 157 ah->imask |= ATH9K_INT_GENTIMER;
158 ath9k_hw_set_interrupts(ah, ah->imask); 158 ath9k_hw_set_interrupts(ah);
159 ath9k_hw_enable_interrupts(ah); 159 ath9k_hw_enable_interrupts(ah);
160 } 160 }
161} 161}
@@ -170,7 +170,7 @@ static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
170 if (timer_table->timer_mask.val == 0) { 170 if (timer_table->timer_mask.val == 0) {
171 ath9k_hw_disable_interrupts(ah); 171 ath9k_hw_disable_interrupts(ah);
172 ah->imask &= ~ATH9K_INT_GENTIMER; 172 ah->imask &= ~ATH9K_INT_GENTIMER;
173 ath9k_hw_set_interrupts(ah, ah->imask); 173 ath9k_hw_set_interrupts(ah);
174 ath9k_hw_enable_interrupts(ah); 174 ath9k_hw_enable_interrupts(ah);
175 } 175 }
176} 176}
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index e9782d164962..e74c233757a2 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -205,4 +205,11 @@ static inline void ath9k_hw_setup_calibration(struct ath_hw *ah,
205 ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal); 205 ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal);
206} 206}
207 207
208static inline int ath9k_hw_fast_chan_change(struct ath_hw *ah,
209 struct ath9k_channel *chan,
210 u8 *ini_reloaded)
211{
212 return ath9k_hw_private_ops(ah)->fast_chan_change(ah, chan,
213 ini_reloaded);
214}
208#endif /* ATH9K_HW_OPS_H */ 215#endif /* ATH9K_HW_OPS_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 42ebe8fb053a..f16d2033081f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -285,7 +285,7 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
285 (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S; 285 (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
286 ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); 286 ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
287 287
288 if (AR_SREV_9480(ah)) 288 if (AR_SREV_9462(ah))
289 ah->is_pciexpress = true; 289 ah->is_pciexpress = true;
290 else 290 else
291 ah->is_pciexpress = (val & 291 ah->is_pciexpress = (val &
@@ -433,7 +433,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
433 433
434 regulatory->country_code = CTRY_DEFAULT; 434 regulatory->country_code = CTRY_DEFAULT;
435 regulatory->power_limit = MAX_RATE_POWER; 435 regulatory->power_limit = MAX_RATE_POWER;
436 regulatory->tp_scale = ATH9K_TP_SCALE_MAX;
437 436
438 ah->hw_version.magic = AR5416_MAGIC; 437 ah->hw_version.magic = AR5416_MAGIC;
439 ah->hw_version.subvendorid = 0; 438 ah->hw_version.subvendorid = 0;
@@ -542,6 +541,9 @@ static int __ath9k_hw_init(struct ath_hw *ah)
542 return -EIO; 541 return -EIO;
543 } 542 }
544 543
544 if (AR_SREV_9462(ah))
545 ah->WARegVal &= ~AR_WA_D3_L1_DISABLE;
546
545 ath9k_hw_init_defaults(ah); 547 ath9k_hw_init_defaults(ah);
546 ath9k_hw_init_config(ah); 548 ath9k_hw_init_config(ah);
547 549
@@ -585,7 +587,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
585 case AR_SREV_VERSION_9330: 587 case AR_SREV_VERSION_9330:
586 case AR_SREV_VERSION_9485: 588 case AR_SREV_VERSION_9485:
587 case AR_SREV_VERSION_9340: 589 case AR_SREV_VERSION_9340:
588 case AR_SREV_VERSION_9480: 590 case AR_SREV_VERSION_9462:
589 break; 591 break;
590 default: 592 default:
591 ath_err(common, 593 ath_err(common,
@@ -670,7 +672,7 @@ int ath9k_hw_init(struct ath_hw *ah)
670 case AR9300_DEVID_AR9330: 672 case AR9300_DEVID_AR9330:
671 case AR9300_DEVID_AR9340: 673 case AR9300_DEVID_AR9340:
672 case AR9300_DEVID_AR9580: 674 case AR9300_DEVID_AR9580:
673 case AR9300_DEVID_AR9480: 675 case AR9300_DEVID_AR9462:
674 break; 676 break;
675 default: 677 default:
676 if (common->bus_ops->ath_bus_type == ATH_USB) 678 if (common->bus_ops->ath_bus_type == ATH_USB)
@@ -1389,11 +1391,17 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
1389static bool ath9k_hw_channel_change(struct ath_hw *ah, 1391static bool ath9k_hw_channel_change(struct ath_hw *ah,
1390 struct ath9k_channel *chan) 1392 struct ath9k_channel *chan)
1391{ 1393{
1392 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1393 struct ath_common *common = ath9k_hw_common(ah); 1394 struct ath_common *common = ath9k_hw_common(ah);
1394 struct ieee80211_channel *channel = chan->chan;
1395 u32 qnum; 1395 u32 qnum;
1396 int r; 1396 int r;
1397 bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
1398 bool band_switch, mode_diff;
1399 u8 ini_reloaded;
1400
1401 band_switch = (chan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ)) !=
1402 (ah->curchan->channelFlags & (CHANNEL_2GHZ |
1403 CHANNEL_5GHZ));
1404 mode_diff = (chan->chanmode != ah->curchan->chanmode);
1397 1405
1398 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { 1406 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
1399 if (ath9k_hw_numtxpending(ah, qnum)) { 1407 if (ath9k_hw_numtxpending(ah, qnum)) {
@@ -1408,6 +1416,18 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1408 return false; 1416 return false;
1409 } 1417 }
1410 1418
1419 if (edma && (band_switch || mode_diff)) {
1420 ath9k_hw_mark_phy_inactive(ah);
1421 udelay(5);
1422
1423 ath9k_hw_init_pll(ah, NULL);
1424
1425 if (ath9k_hw_fast_chan_change(ah, chan, &ini_reloaded)) {
1426 ath_err(common, "Failed to do fast channel change\n");
1427 return false;
1428 }
1429 }
1430
1411 ath9k_hw_set_channel_regs(ah, chan); 1431 ath9k_hw_set_channel_regs(ah, chan);
1412 1432
1413 r = ath9k_hw_rf_set_freq(ah, chan); 1433 r = ath9k_hw_rf_set_freq(ah, chan);
@@ -1416,14 +1436,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1416 return false; 1436 return false;
1417 } 1437 }
1418 ath9k_hw_set_clockrate(ah); 1438 ath9k_hw_set_clockrate(ah);
1419 1439 ath9k_hw_apply_txpower(ah, chan);
1420 ah->eep_ops->set_txpower(ah, chan,
1421 ath9k_regd_get_ctl(regulatory, chan),
1422 channel->max_antenna_gain * 2,
1423 channel->max_power * 2,
1424 min((u32) MAX_RATE_POWER,
1425 (u32) regulatory->power_limit), false);
1426
1427 ath9k_hw_rfbus_done(ah); 1440 ath9k_hw_rfbus_done(ah);
1428 1441
1429 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) 1442 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
@@ -1431,6 +1444,18 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1431 1444
1432 ath9k_hw_spur_mitigate_freq(ah, chan); 1445 ath9k_hw_spur_mitigate_freq(ah, chan);
1433 1446
1447 if (edma && (band_switch || mode_diff)) {
1448 ah->ah_flags |= AH_FASTCC;
1449 if (band_switch || ini_reloaded)
1450 ah->eep_ops->set_board_values(ah, chan);
1451
1452 ath9k_hw_init_bb(ah, chan);
1453
1454 if (band_switch || ini_reloaded)
1455 ath9k_hw_init_cal(ah, chan);
1456 ah->ah_flags &= ~AH_FASTCC;
1457 }
1458
1434 return true; 1459 return true;
1435} 1460}
1436 1461
@@ -1486,6 +1511,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1486 u32 macStaId1; 1511 u32 macStaId1;
1487 u64 tsf = 0; 1512 u64 tsf = 0;
1488 int i, r; 1513 int i, r;
1514 bool allow_fbs = false;
1489 1515
1490 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) 1516 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
1491 return -EIO; 1517 return -EIO;
@@ -1504,16 +1530,22 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1504 } 1530 }
1505 ah->noise = ath9k_hw_getchan_noise(ah, chan); 1531 ah->noise = ath9k_hw_getchan_noise(ah, chan);
1506 1532
1507 if ((AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) || 1533 if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI)
1508 (AR_SREV_9300_20_OR_LATER(ah) && IS_CHAN_5GHZ(chan)))
1509 bChannelChange = false; 1534 bChannelChange = false;
1510 1535
1536 if (caldata &&
1537 caldata->done_txiqcal_once &&
1538 caldata->done_txclcal_once &&
1539 caldata->rtt_hist.num_readings)
1540 allow_fbs = true;
1541
1511 if (bChannelChange && 1542 if (bChannelChange &&
1512 (ah->chip_fullsleep != true) && 1543 (ah->chip_fullsleep != true) &&
1513 (ah->curchan != NULL) && 1544 (ah->curchan != NULL) &&
1514 (chan->channel != ah->curchan->channel) && 1545 (chan->channel != ah->curchan->channel) &&
1515 ((chan->channelFlags & CHANNEL_ALL) == 1546 (allow_fbs ||
1516 (ah->curchan->channelFlags & CHANNEL_ALL))) { 1547 ((chan->channelFlags & CHANNEL_ALL) ==
1548 (ah->curchan->channelFlags & CHANNEL_ALL)))) {
1517 if (ath9k_hw_channel_change(ah, chan)) { 1549 if (ath9k_hw_channel_change(ah, chan)) {
1518 ath9k_hw_loadnf(ah, ah->curchan); 1550 ath9k_hw_loadnf(ah, ah->curchan);
1519 ath9k_hw_start_nfcal(ah, true); 1551 ath9k_hw_start_nfcal(ah, true);
@@ -1684,6 +1716,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1684 1716
1685 ath9k_hw_init_bb(ah, chan); 1717 ath9k_hw_init_bb(ah, chan);
1686 1718
1719 if (caldata) {
1720 caldata->done_txiqcal_once = false;
1721 caldata->done_txclcal_once = false;
1722 caldata->rtt_hist.num_readings = 0;
1723 }
1687 if (!ath9k_hw_init_cal(ah, chan)) 1724 if (!ath9k_hw_init_cal(ah, chan))
1688 return -EIO; 1725 return -EIO;
1689 1726
@@ -1753,7 +1790,7 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
1753{ 1790{
1754 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 1791 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
1755 if (setChip) { 1792 if (setChip) {
1756 if (AR_SREV_9480(ah)) { 1793 if (AR_SREV_9462(ah)) {
1757 REG_WRITE(ah, AR_TIMER_MODE, 1794 REG_WRITE(ah, AR_TIMER_MODE,
1758 REG_READ(ah, AR_TIMER_MODE) & 0xFFFFFF00); 1795 REG_READ(ah, AR_TIMER_MODE) & 0xFFFFFF00);
1759 REG_WRITE(ah, AR_NDP2_TIMER_MODE, REG_READ(ah, 1796 REG_WRITE(ah, AR_NDP2_TIMER_MODE, REG_READ(ah,
@@ -1771,7 +1808,7 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
1771 */ 1808 */
1772 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); 1809 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN);
1773 1810
1774 if (AR_SREV_9480(ah)) 1811 if (AR_SREV_9462(ah))
1775 udelay(100); 1812 udelay(100);
1776 1813
1777 if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) 1814 if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
@@ -1779,15 +1816,14 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
1779 1816
1780 /* Shutdown chip. Active low */ 1817 /* Shutdown chip. Active low */
1781 if (!AR_SREV_5416(ah) && 1818 if (!AR_SREV_5416(ah) &&
1782 !AR_SREV_9271(ah) && !AR_SREV_9480_10(ah)) { 1819 !AR_SREV_9271(ah) && !AR_SREV_9462_10(ah)) {
1783 REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN); 1820 REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN);
1784 udelay(2); 1821 udelay(2);
1785 } 1822 }
1786 } 1823 }
1787 1824
1788 /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ 1825 /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */
1789 if (!AR_SREV_9480(ah)) 1826 REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
1790 REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
1791} 1827}
1792 1828
1793/* 1829/*
@@ -1818,7 +1854,7 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
1818 * SYS_WAKING and SYS_SLEEPING messages which will make 1854 * SYS_WAKING and SYS_SLEEPING messages which will make
1819 * BT CPU to busy to process. 1855 * BT CPU to busy to process.
1820 */ 1856 */
1821 if (AR_SREV_9480(ah)) { 1857 if (AR_SREV_9462(ah)) {
1822 val = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_EN) & 1858 val = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_EN) &
1823 ~AR_MCI_INTERRUPT_RX_HW_MSG_MASK; 1859 ~AR_MCI_INTERRUPT_RX_HW_MSG_MASK;
1824 REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, val); 1860 REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, val);
@@ -1830,7 +1866,7 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
1830 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, 1866 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
1831 AR_RTC_FORCE_WAKE_EN); 1867 AR_RTC_FORCE_WAKE_EN);
1832 1868
1833 if (AR_SREV_9480(ah)) 1869 if (AR_SREV_9462(ah))
1834 udelay(30); 1870 udelay(30);
1835 } 1871 }
1836 } 1872 }
@@ -2082,11 +2118,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2082 eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); 2118 eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
2083 regulatory->current_rd = eeval; 2119 regulatory->current_rd = eeval;
2084 2120
2085 eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
2086 if (AR_SREV_9285_12_OR_LATER(ah))
2087 eeval |= AR9285_RDEXT_DEFAULT;
2088 regulatory->current_rd_ext = eeval;
2089
2090 if (ah->opmode != NL80211_IFTYPE_AP && 2121 if (ah->opmode != NL80211_IFTYPE_AP &&
2091 ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) { 2122 ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
2092 if (regulatory->current_rd == 0x64 || 2123 if (regulatory->current_rd == 0x64 ||
@@ -2294,6 +2325,14 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2294 rx_chainmask >>= 1; 2325 rx_chainmask >>= 1;
2295 } 2326 }
2296 2327
2328 if (AR_SREV_9300_20_OR_LATER(ah)) {
2329 ah->enabled_cals |= TX_IQ_CAL;
2330 if (!AR_SREV_9330(ah))
2331 ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
2332 }
2333 if (AR_SREV_9462(ah))
2334 pCap->hw_caps |= ATH9K_HW_CAP_RTT;
2335
2297 return 0; 2336 return 0;
2298} 2337}
2299 2338
@@ -2454,7 +2493,7 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
2454 2493
2455 ENABLE_REGWRITE_BUFFER(ah); 2494 ENABLE_REGWRITE_BUFFER(ah);
2456 2495
2457 if (AR_SREV_9480(ah)) 2496 if (AR_SREV_9462(ah))
2458 bits |= ATH9K_RX_FILTER_CONTROL_WRAPPER; 2497 bits |= ATH9K_RX_FILTER_CONTROL_WRAPPER;
2459 2498
2460 REG_WRITE(ah, AR_RX_FILTER, bits); 2499 REG_WRITE(ah, AR_RX_FILTER, bits);
@@ -2498,23 +2537,56 @@ bool ath9k_hw_disable(struct ath_hw *ah)
2498} 2537}
2499EXPORT_SYMBOL(ath9k_hw_disable); 2538EXPORT_SYMBOL(ath9k_hw_disable);
2500 2539
2540static int get_antenna_gain(struct ath_hw *ah, struct ath9k_channel *chan)
2541{
2542 enum eeprom_param gain_param;
2543
2544 if (IS_CHAN_2GHZ(chan))
2545 gain_param = EEP_ANTENNA_GAIN_2G;
2546 else
2547 gain_param = EEP_ANTENNA_GAIN_5G;
2548
2549 return ah->eep_ops->get_eeprom(ah, gain_param);
2550}
2551
2552void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan)
2553{
2554 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
2555 struct ieee80211_channel *channel;
2556 int chan_pwr, new_pwr, max_gain;
2557 int ant_gain, ant_reduction = 0;
2558
2559 if (!chan)
2560 return;
2561
2562 channel = chan->chan;
2563 chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
2564 new_pwr = min_t(int, chan_pwr, reg->power_limit);
2565 max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2;
2566
2567 ant_gain = get_antenna_gain(ah, chan);
2568 if (ant_gain > max_gain)
2569 ant_reduction = ant_gain - max_gain;
2570
2571 ah->eep_ops->set_txpower(ah, chan,
2572 ath9k_regd_get_ctl(reg, chan),
2573 ant_reduction, new_pwr, false);
2574}
2575
2501void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) 2576void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
2502{ 2577{
2503 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 2578 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
2504 struct ath9k_channel *chan = ah->curchan; 2579 struct ath9k_channel *chan = ah->curchan;
2505 struct ieee80211_channel *channel = chan->chan; 2580 struct ieee80211_channel *channel = chan->chan;
2506 int reg_pwr = min_t(int, MAX_RATE_POWER, limit);
2507 int chan_pwr = channel->max_power * 2;
2508 2581
2582 reg->power_limit = min_t(int, limit, MAX_RATE_POWER);
2509 if (test) 2583 if (test)
2510 reg_pwr = chan_pwr = MAX_RATE_POWER; 2584 channel->max_power = MAX_RATE_POWER / 2;
2511 2585
2512 regulatory->power_limit = reg_pwr; 2586 ath9k_hw_apply_txpower(ah, chan);
2513 2587
2514 ah->eep_ops->set_txpower(ah, chan, 2588 if (test)
2515 ath9k_regd_get_ctl(regulatory, chan), 2589 channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2);
2516 channel->max_antenna_gain * 2,
2517 chan_pwr, reg_pwr, test);
2518} 2590}
2519EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit); 2591EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
2520 2592
@@ -2713,9 +2785,9 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah,
2713 REG_SET_BIT(ah, gen_tmr_configuration[timer->index].mode_addr, 2785 REG_SET_BIT(ah, gen_tmr_configuration[timer->index].mode_addr,
2714 gen_tmr_configuration[timer->index].mode_mask); 2786 gen_tmr_configuration[timer->index].mode_mask);
2715 2787
2716 if (AR_SREV_9480(ah)) { 2788 if (AR_SREV_9462(ah)) {
2717 /* 2789 /*
2718 * Starting from AR9480, each generic timer can select which tsf 2790 * Starting from AR9462, each generic timer can select which tsf
2719 * to use. But we still follow the old rule, 0 - 7 use tsf and 2791 * to use. But we still follow the old rule, 0 - 7 use tsf and
2720 * 8 - 15 use tsf2. 2792 * 8 - 15 use tsf2.
2721 */ 2793 */
@@ -2832,7 +2904,7 @@ static struct {
2832 { AR_SREV_VERSION_9330, "9330" }, 2904 { AR_SREV_VERSION_9330, "9330" },
2833 { AR_SREV_VERSION_9340, "9340" }, 2905 { AR_SREV_VERSION_9340, "9340" },
2834 { AR_SREV_VERSION_9485, "9485" }, 2906 { AR_SREV_VERSION_9485, "9485" },
2835 { AR_SREV_VERSION_9480, "9480" }, 2907 { AR_SREV_VERSION_9462, "9462" },
2836}; 2908};
2837 2909
2838/* For devices with external radios */ 2910/* For devices with external radios */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 24889f78a053..f389b3c93cf3 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -46,7 +46,7 @@
46#define AR9300_DEVID_AR9340 0x0031 46#define AR9300_DEVID_AR9340 0x0031
47#define AR9300_DEVID_AR9485_PCIE 0x0032 47#define AR9300_DEVID_AR9485_PCIE 0x0032
48#define AR9300_DEVID_AR9580 0x0033 48#define AR9300_DEVID_AR9580 0x0033
49#define AR9300_DEVID_AR9480 0x0034 49#define AR9300_DEVID_AR9462 0x0034
50#define AR9300_DEVID_AR9330 0x0035 50#define AR9300_DEVID_AR9330 0x0035
51 51
52#define AR5416_AR9100_DEVID 0x000b 52#define AR5416_AR9100_DEVID 0x000b
@@ -202,6 +202,7 @@ enum ath9k_hw_caps {
202 ATH9K_HW_CAP_2GHZ = BIT(13), 202 ATH9K_HW_CAP_2GHZ = BIT(13),
203 ATH9K_HW_CAP_5GHZ = BIT(14), 203 ATH9K_HW_CAP_5GHZ = BIT(14),
204 ATH9K_HW_CAP_APM = BIT(15), 204 ATH9K_HW_CAP_APM = BIT(15),
205 ATH9K_HW_CAP_RTT = BIT(16),
205}; 206};
206 207
207struct ath9k_hw_capabilities { 208struct ath9k_hw_capabilities {
@@ -337,6 +338,16 @@ enum ath9k_int {
337 CHANNEL_HT40PLUS | \ 338 CHANNEL_HT40PLUS | \
338 CHANNEL_HT40MINUS) 339 CHANNEL_HT40MINUS)
339 340
341#define MAX_RTT_TABLE_ENTRY 6
342#define RTT_HIST_MAX 3
343struct ath9k_rtt_hist {
344 u32 table[AR9300_MAX_CHAINS][RTT_HIST_MAX][MAX_RTT_TABLE_ENTRY];
345 u8 num_readings;
346};
347
348#define MAX_IQCAL_MEASUREMENT 8
349#define MAX_CL_TAB_ENTRY 16
350
340struct ath9k_hw_cal_data { 351struct ath9k_hw_cal_data {
341 u16 channel; 352 u16 channel;
342 u32 channelFlags; 353 u32 channelFlags;
@@ -346,9 +357,15 @@ struct ath9k_hw_cal_data {
346 bool paprd_done; 357 bool paprd_done;
347 bool nfcal_pending; 358 bool nfcal_pending;
348 bool nfcal_interference; 359 bool nfcal_interference;
360 bool done_txiqcal_once;
361 bool done_txclcal_once;
349 u16 small_signal_gain[AR9300_MAX_CHAINS]; 362 u16 small_signal_gain[AR9300_MAX_CHAINS];
350 u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ]; 363 u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ];
364 u32 num_measures[AR9300_MAX_CHAINS];
365 int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS];
366 u32 tx_clcal[AR9300_MAX_CHAINS][MAX_CL_TAB_ENTRY];
351 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; 367 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
368 struct ath9k_rtt_hist rtt_hist;
352}; 369};
353 370
354struct ath9k_channel { 371struct ath9k_channel {
@@ -390,14 +407,6 @@ enum ath9k_power_mode {
390 ATH9K_PM_UNDEFINED 407 ATH9K_PM_UNDEFINED
391}; 408};
392 409
393enum ath9k_tp_scale {
394 ATH9K_TP_SCALE_MAX = 0,
395 ATH9K_TP_SCALE_50,
396 ATH9K_TP_SCALE_25,
397 ATH9K_TP_SCALE_12,
398 ATH9K_TP_SCALE_MIN
399};
400
401enum ser_reg_mode { 410enum ser_reg_mode {
402 SER_REG_MODE_OFF = 0, 411 SER_REG_MODE_OFF = 0,
403 SER_REG_MODE_ON = 1, 412 SER_REG_MODE_ON = 1,
@@ -591,6 +600,8 @@ struct ath_hw_private_ops {
591 void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]); 600 void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
592 void (*set_radar_params)(struct ath_hw *ah, 601 void (*set_radar_params)(struct ath_hw *ah,
593 struct ath_hw_radar_conf *conf); 602 struct ath_hw_radar_conf *conf);
603 int (*fast_chan_change)(struct ath_hw *ah, struct ath9k_channel *chan,
604 u8 *ini_reloaded);
594 605
595 /* ANI */ 606 /* ANI */
596 void (*ani_cache_ini_regs)(struct ath_hw *ah); 607 void (*ani_cache_ini_regs)(struct ath_hw *ah);
@@ -632,9 +643,16 @@ struct ath_nf_limits {
632 s16 nominal; 643 s16 nominal;
633}; 644};
634 645
646enum ath_cal_list {
647 TX_IQ_CAL = BIT(0),
648 TX_IQ_ON_AGC_CAL = BIT(1),
649 TX_CL_CAL = BIT(2),
650};
651
635/* ah_flags */ 652/* ah_flags */
636#define AH_USE_EEPROM 0x1 653#define AH_USE_EEPROM 0x1
637#define AH_UNPLUGGED 0x2 /* The card has been physically removed. */ 654#define AH_UNPLUGGED 0x2 /* The card has been physically removed. */
655#define AH_FASTCC 0x4
638 656
639struct ath_hw { 657struct ath_hw {
640 struct ath_ops reg_ops; 658 struct ath_ops reg_ops;
@@ -692,6 +710,7 @@ struct ath_hw {
692 atomic_t intr_ref_cnt; 710 atomic_t intr_ref_cnt;
693 bool chip_fullsleep; 711 bool chip_fullsleep;
694 u32 atim_window; 712 u32 atim_window;
713 u32 modes_index;
695 714
696 /* Calibration */ 715 /* Calibration */
697 u32 supp_cals; 716 u32 supp_cals;
@@ -730,6 +749,7 @@ struct ath_hw {
730 int32_t sign[AR5416_MAX_CHAINS]; 749 int32_t sign[AR5416_MAX_CHAINS];
731 } meas3; 750 } meas3;
732 u16 cal_samples; 751 u16 cal_samples;
752 u8 enabled_cals;
733 753
734 u32 sta_id1_defaults; 754 u32 sta_id1_defaults;
735 u32 misc_mode; 755 u32 misc_mode;
@@ -968,6 +988,7 @@ void ath9k_hw_htc_resetinit(struct ath_hw *ah);
968/* PHY */ 988/* PHY */
969void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, 989void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
970 u32 *coef_mantissa, u32 *coef_exponent); 990 u32 *coef_mantissa, u32 *coef_exponent);
991void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan);
971 992
972/* 993/*
973 * Code Specific to AR5008, AR9001 or AR9002, 994 * Code Specific to AR5008, AR9001 or AR9002,
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 39514de044ef..af1b32549531 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -626,7 +626,6 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
626 struct ieee80211_supported_band *sband; 626 struct ieee80211_supported_band *sband;
627 struct ieee80211_channel *chan; 627 struct ieee80211_channel *chan;
628 struct ath_hw *ah = sc->sc_ah; 628 struct ath_hw *ah = sc->sc_ah;
629 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
630 int i; 629 int i;
631 630
632 sband = &sc->sbands[band]; 631 sband = &sc->sbands[band];
@@ -635,7 +634,6 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
635 ah->curchan = &ah->channels[chan->hw_value]; 634 ah->curchan = &ah->channels[chan->hw_value];
636 ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20); 635 ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
637 ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true); 636 ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
638 chan->max_power = reg->max_power_level / 2;
639 } 637 }
640} 638}
641 639
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 22f23eafe8ba..6a8fdf33a527 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -620,8 +620,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
620 rs->rs_status |= ATH9K_RXERR_DECRYPT; 620 rs->rs_status |= ATH9K_RXERR_DECRYPT;
621 else if (ads.ds_rxstatus8 & AR_MichaelErr) 621 else if (ads.ds_rxstatus8 & AR_MichaelErr)
622 rs->rs_status |= ATH9K_RXERR_MIC; 622 rs->rs_status |= ATH9K_RXERR_MIC;
623 else if (ads.ds_rxstatus8 & AR_KeyMiss) 623 if (ads.ds_rxstatus8 & AR_KeyMiss)
624 rs->rs_status |= ATH9K_RXERR_DECRYPT; 624 rs->rs_status |= ATH9K_RXERR_KEYMISS;
625 } 625 }
626 626
627 return 0; 627 return 0;
@@ -827,9 +827,9 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
827} 827}
828EXPORT_SYMBOL(ath9k_hw_enable_interrupts); 828EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
829 829
830void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) 830void ath9k_hw_set_interrupts(struct ath_hw *ah)
831{ 831{
832 enum ath9k_int omask = ah->imask; 832 enum ath9k_int ints = ah->imask;
833 u32 mask, mask2; 833 u32 mask, mask2;
834 struct ath9k_hw_capabilities *pCap = &ah->caps; 834 struct ath9k_hw_capabilities *pCap = &ah->caps;
835 struct ath_common *common = ath9k_hw_common(ah); 835 struct ath_common *common = ath9k_hw_common(ah);
@@ -837,7 +837,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
837 if (!(ints & ATH9K_INT_GLOBAL)) 837 if (!(ints & ATH9K_INT_GLOBAL))
838 ath9k_hw_disable_interrupts(ah); 838 ath9k_hw_disable_interrupts(ah);
839 839
840 ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); 840 ath_dbg(common, ATH_DBG_INTERRUPT, "New interrupt mask 0x%x\n", ints);
841 841
842 mask = ints & ATH9K_INT_COMMON; 842 mask = ints & ATH9K_INT_COMMON;
843 mask2 = 0; 843 mask2 = 0;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 91c96546c0cd..11dbd1473a13 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -75,9 +75,10 @@
75#define ATH9K_TXERR_XTXOP 0x08 75#define ATH9K_TXERR_XTXOP 0x08
76#define ATH9K_TXERR_TIMER_EXPIRED 0x10 76#define ATH9K_TXERR_TIMER_EXPIRED 0x10
77#define ATH9K_TX_ACKED 0x20 77#define ATH9K_TX_ACKED 0x20
78#define ATH9K_TX_FLUSH 0x40
78#define ATH9K_TXERR_MASK \ 79#define ATH9K_TXERR_MASK \
79 (ATH9K_TXERR_XRETRY | ATH9K_TXERR_FILT | ATH9K_TXERR_FIFO | \ 80 (ATH9K_TXERR_XRETRY | ATH9K_TXERR_FILT | ATH9K_TXERR_FIFO | \
80 ATH9K_TXERR_XTXOP | ATH9K_TXERR_TIMER_EXPIRED) 81 ATH9K_TXERR_XTXOP | ATH9K_TXERR_TIMER_EXPIRED | ATH9K_TX_FLUSH)
81 82
82#define ATH9K_TX_BA 0x01 83#define ATH9K_TX_BA 0x01
83#define ATH9K_TX_PWRMGMT 0x02 84#define ATH9K_TX_PWRMGMT 0x02
@@ -181,6 +182,7 @@ struct ath_htc_rx_status {
181#define ATH9K_RXERR_FIFO 0x04 182#define ATH9K_RXERR_FIFO 0x04
182#define ATH9K_RXERR_DECRYPT 0x08 183#define ATH9K_RXERR_DECRYPT 0x08
183#define ATH9K_RXERR_MIC 0x10 184#define ATH9K_RXERR_MIC 0x10
185#define ATH9K_RXERR_KEYMISS 0x20
184 186
185#define ATH9K_RX_MORE 0x01 187#define ATH9K_RX_MORE 0x01
186#define ATH9K_RX_MORE_AGGR 0x02 188#define ATH9K_RX_MORE_AGGR 0x02
@@ -734,7 +736,7 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah);
734 736
735/* Interrupt Handling */ 737/* Interrupt Handling */
736bool ath9k_hw_intrpend(struct ath_hw *ah); 738bool ath9k_hw_intrpend(struct ath_hw *ah);
737void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints); 739void ath9k_hw_set_interrupts(struct ath_hw *ah);
738void ath9k_hw_enable_interrupts(struct ath_hw *ah); 740void ath9k_hw_enable_interrupts(struct ath_hw *ah);
739void ath9k_hw_disable_interrupts(struct ath_hw *ah); 741void ath9k_hw_disable_interrupts(struct ath_hw *ah);
740 742
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 988318665758..93fbe6f40898 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -273,7 +273,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
273 273
274 ath9k_cmn_update_txpow(ah, sc->curtxpow, 274 ath9k_cmn_update_txpow(ah, sc->curtxpow,
275 sc->config.txpowlimit, &sc->curtxpow); 275 sc->config.txpowlimit, &sc->curtxpow);
276 ath9k_hw_set_interrupts(ah, ah->imask); 276 ath9k_hw_set_interrupts(ah);
277 ath9k_hw_enable_interrupts(ah); 277 ath9k_hw_enable_interrupts(ah);
278 278
279 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && start) { 279 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && start) {
@@ -679,6 +679,16 @@ void ath9k_tasklet(unsigned long data)
679 679
680 if ((status & ATH9K_INT_FATAL) || 680 if ((status & ATH9K_INT_FATAL) ||
681 (status & ATH9K_INT_BB_WATCHDOG)) { 681 (status & ATH9K_INT_BB_WATCHDOG)) {
682#ifdef CONFIG_ATH9K_DEBUGFS
683 enum ath_reset_type type;
684
685 if (status & ATH9K_INT_FATAL)
686 type = RESET_TYPE_FATAL_INT;
687 else
688 type = RESET_TYPE_BB_WATCHDOG;
689
690 RESET_STAT_INC(sc, type);
691#endif
682 ieee80211_queue_work(sc->hw, &sc->hw_reset_work); 692 ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
683 goto out; 693 goto out;
684 } 694 }
@@ -823,7 +833,7 @@ irqreturn_t ath_isr(int irq, void *dev)
823 833
824 if (status & ATH9K_INT_RXEOL) { 834 if (status & ATH9K_INT_RXEOL) {
825 ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN); 835 ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
826 ath9k_hw_set_interrupts(ah, ah->imask); 836 ath9k_hw_set_interrupts(ah);
827 } 837 }
828 838
829 if (status & ATH9K_INT_MIB) { 839 if (status & ATH9K_INT_MIB) {
@@ -995,8 +1005,10 @@ void ath_hw_check(struct work_struct *work)
995 ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, " 1005 ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, "
996 "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1); 1006 "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
997 if (busy >= 99) { 1007 if (busy >= 99) {
998 if (++sc->hw_busy_count >= 3) 1008 if (++sc->hw_busy_count >= 3) {
1009 RESET_STAT_INC(sc, RESET_TYPE_BB_HANG);
999 ieee80211_queue_work(sc->hw, &sc->hw_reset_work); 1010 ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
1011 }
1000 1012
1001 } else if (busy >= 0) 1013 } else if (busy >= 0)
1002 sc->hw_busy_count = 0; 1014 sc->hw_busy_count = 0;
@@ -1016,6 +1028,7 @@ static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
1016 /* Rx is hung for more than 500ms. Reset it */ 1028 /* Rx is hung for more than 500ms. Reset it */
1017 ath_dbg(common, ATH_DBG_RESET, 1029 ath_dbg(common, ATH_DBG_RESET,
1018 "Possible RX hang, resetting"); 1030 "Possible RX hang, resetting");
1031 RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG);
1019 ieee80211_queue_work(sc->hw, &sc->hw_reset_work); 1032 ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
1020 count = 0; 1033 count = 0;
1021 } 1034 }
@@ -1396,7 +1409,7 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
1396 ah->imask &= ~ATH9K_INT_TSFOOR; 1409 ah->imask &= ~ATH9K_INT_TSFOOR;
1397 } 1410 }
1398 1411
1399 ath9k_hw_set_interrupts(ah, ah->imask); 1412 ath9k_hw_set_interrupts(ah);
1400 1413
1401 /* Set up ANI */ 1414 /* Set up ANI */
1402 if (iter_data.naps > 0) { 1415 if (iter_data.naps > 0) {
@@ -1571,7 +1584,7 @@ static void ath9k_enable_ps(struct ath_softc *sc)
1571 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { 1584 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
1572 if ((ah->imask & ATH9K_INT_TIM_TIMER) == 0) { 1585 if ((ah->imask & ATH9K_INT_TIM_TIMER) == 0) {
1573 ah->imask |= ATH9K_INT_TIM_TIMER; 1586 ah->imask |= ATH9K_INT_TIM_TIMER;
1574 ath9k_hw_set_interrupts(ah, ah->imask); 1587 ath9k_hw_set_interrupts(ah);
1575 } 1588 }
1576 ath9k_hw_setrxabort(ah, 1); 1589 ath9k_hw_setrxabort(ah, 1);
1577 } 1590 }
@@ -1591,7 +1604,7 @@ static void ath9k_disable_ps(struct ath_softc *sc)
1591 PS_WAIT_FOR_TX_ACK); 1604 PS_WAIT_FOR_TX_ACK);
1592 if (ah->imask & ATH9K_INT_TIM_TIMER) { 1605 if (ah->imask & ATH9K_INT_TIM_TIMER) {
1593 ah->imask &= ~ATH9K_INT_TIM_TIMER; 1606 ah->imask &= ~ATH9K_INT_TIM_TIMER;
1594 ath9k_hw_set_interrupts(ah, ah->imask); 1607 ath9k_hw_set_interrupts(ah);
1595 } 1608 }
1596 } 1609 }
1597 1610
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index d67d6eee3954..edb0b4b3da3a 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -33,7 +33,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
33 { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */ 33 { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
34 { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */ 34 { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */
35 { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */ 35 { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */
36 { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9480 */ 36 { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */
37 { 0 } 37 { 0 }
38}; 38};
39 39
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index f658ec60b510..67b862cdae6d 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -433,12 +433,9 @@ void ath_rx_cleanup(struct ath_softc *sc)
433 433
434u32 ath_calcrxfilter(struct ath_softc *sc) 434u32 ath_calcrxfilter(struct ath_softc *sc)
435{ 435{
436#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
437
438 u32 rfilt; 436 u32 rfilt;
439 437
440 rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE) 438 rfilt = ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
441 | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
442 | ATH9K_RX_FILTER_MCAST; 439 | ATH9K_RX_FILTER_MCAST;
443 440
444 if (sc->rx.rxfilter & FIF_PROBE_REQ) 441 if (sc->rx.rxfilter & FIF_PROBE_REQ)
@@ -811,6 +808,7 @@ static bool ath9k_rx_accept(struct ath_common *common,
811 struct ath_rx_status *rx_stats, 808 struct ath_rx_status *rx_stats,
812 bool *decrypt_error) 809 bool *decrypt_error)
813{ 810{
811 struct ath_softc *sc = (struct ath_softc *) common->priv;
814 bool is_mc, is_valid_tkip, strip_mic, mic_error; 812 bool is_mc, is_valid_tkip, strip_mic, mic_error;
815 struct ath_hw *ah = common->ah; 813 struct ath_hw *ah = common->ah;
816 __le16 fc; 814 __le16 fc;
@@ -823,7 +821,8 @@ static bool ath9k_rx_accept(struct ath_common *common,
823 test_bit(rx_stats->rs_keyix, common->tkip_keymap); 821 test_bit(rx_stats->rs_keyix, common->tkip_keymap);
824 strip_mic = is_valid_tkip && ieee80211_is_data(fc) && 822 strip_mic = is_valid_tkip && ieee80211_is_data(fc) &&
825 !(rx_stats->rs_status & 823 !(rx_stats->rs_status &
826 (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC)); 824 (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC |
825 ATH9K_RXERR_KEYMISS));
827 826
828 if (!rx_stats->rs_datalen) 827 if (!rx_stats->rs_datalen)
829 return false; 828 return false;
@@ -851,6 +850,8 @@ static bool ath9k_rx_accept(struct ath_common *common,
851 * descriptors. 850 * descriptors.
852 */ 851 */
853 if (rx_stats->rs_status != 0) { 852 if (rx_stats->rs_status != 0) {
853 u8 status_mask;
854
854 if (rx_stats->rs_status & ATH9K_RXERR_CRC) { 855 if (rx_stats->rs_status & ATH9K_RXERR_CRC) {
855 rxs->flag |= RX_FLAG_FAILED_FCS_CRC; 856 rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
856 mic_error = false; 857 mic_error = false;
@@ -858,7 +859,8 @@ static bool ath9k_rx_accept(struct ath_common *common,
858 if (rx_stats->rs_status & ATH9K_RXERR_PHY) 859 if (rx_stats->rs_status & ATH9K_RXERR_PHY)
859 return false; 860 return false;
860 861
861 if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { 862 if ((rx_stats->rs_status & ATH9K_RXERR_DECRYPT) ||
863 (!is_mc && (rx_stats->rs_status & ATH9K_RXERR_KEYMISS))) {
862 *decrypt_error = true; 864 *decrypt_error = true;
863 mic_error = false; 865 mic_error = false;
864 } 866 }
@@ -868,17 +870,14 @@ static bool ath9k_rx_accept(struct ath_common *common,
868 * decryption and MIC failures. For monitor mode, 870 * decryption and MIC failures. For monitor mode,
869 * we also ignore the CRC error. 871 * we also ignore the CRC error.
870 */ 872 */
871 if (ah->is_monitoring) { 873 status_mask = ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
872 if (rx_stats->rs_status & 874 ATH9K_RXERR_KEYMISS;
873 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | 875
874 ATH9K_RXERR_CRC)) 876 if (ah->is_monitoring && (sc->rx.rxfilter & FIF_FCSFAIL))
875 return false; 877 status_mask |= ATH9K_RXERR_CRC;
876 } else { 878
877 if (rx_stats->rs_status & 879 if (rx_stats->rs_status & ~status_mask)
878 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) { 880 return false;
879 return false;
880 }
881 }
882 } 881 }
883 882
884 /* 883 /*
@@ -1973,7 +1972,7 @@ requeue:
1973 1972
1974 if (!(ah->imask & ATH9K_INT_RXEOL)) { 1973 if (!(ah->imask & ATH9K_INT_RXEOL)) {
1975 ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN); 1974 ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
1976 ath9k_hw_set_interrupts(ah, ah->imask); 1975 ath9k_hw_set_interrupts(ah);
1977 } 1976 }
1978 1977
1979 return 0; 1978 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index b76c49d9c503..8fcb7e9e8399 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -796,9 +796,9 @@
796#define AR_SREV_VERSION_9340 0x300 796#define AR_SREV_VERSION_9340 0x300
797#define AR_SREV_VERSION_9580 0x1C0 797#define AR_SREV_VERSION_9580 0x1C0
798#define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */ 798#define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */
799#define AR_SREV_VERSION_9480 0x280 799#define AR_SREV_VERSION_9462 0x280
800#define AR_SREV_REVISION_9480_10 0 800#define AR_SREV_REVISION_9462_10 0
801#define AR_SREV_REVISION_9480_20 2 801#define AR_SREV_REVISION_9462_20 2
802 802
803#define AR_SREV_5416(_ah) \ 803#define AR_SREV_5416(_ah) \
804 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ 804 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -895,20 +895,20 @@
895 (AR_SREV_9285_12_OR_LATER(_ah) && \ 895 (AR_SREV_9285_12_OR_LATER(_ah) && \
896 ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1)) 896 ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
897 897
898#define AR_SREV_9480(_ah) \ 898#define AR_SREV_9462(_ah) \
899 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480)) 899 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462))
900 900
901#define AR_SREV_9480_10(_ah) \ 901#define AR_SREV_9462_10(_ah) \
902 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480) && \ 902 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
903 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9480_10)) 903 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_10))
904 904
905#define AR_SREV_9480_20(_ah) \ 905#define AR_SREV_9462_20(_ah) \
906 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480) && \ 906 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
907 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9480_20)) 907 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20))
908 908
909#define AR_SREV_9480_20_OR_LATER(_ah) \ 909#define AR_SREV_9462_20_OR_LATER(_ah) \
910 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480) && \ 910 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
911 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9480_20)) 911 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_20))
912 912
913#define AR_SREV_9580(_ah) \ 913#define AR_SREV_9580(_ah) \
914 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \ 914 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \
@@ -1933,6 +1933,7 @@ enum {
1933#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 /* don't update noise floor automatically */ 1933#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 /* don't update noise floor automatically */
1934#define AR_PHY_AGC_CONTROL_EXT_NF_PWR_MEAS 0x00040000 /* extend noise floor power measurement */ 1934#define AR_PHY_AGC_CONTROL_EXT_NF_PWR_MEAS 0x00040000 /* extend noise floor power measurement */
1935#define AR_PHY_AGC_CONTROL_CLC_SUCCESS 0x00080000 /* carrier leak calibration done */ 1935#define AR_PHY_AGC_CONTROL_CLC_SUCCESS 0x00080000 /* carrier leak calibration done */
1936#define AR_PHY_AGC_CONTROL_PKDET_CAL 0x00100000
1936#define AR_PHY_AGC_CONTROL_YCOK_MAX 0x000003c0 1937#define AR_PHY_AGC_CONTROL_YCOK_MAX 0x000003c0
1937#define AR_PHY_AGC_CONTROL_YCOK_MAX_S 6 1938#define AR_PHY_AGC_CONTROL_YCOK_MAX_S 6
1938 1939
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index c2bfc57958d8..03b0a651a591 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -373,7 +373,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
373 struct ath_frame_info *fi; 373 struct ath_frame_info *fi;
374 int nframes; 374 int nframes;
375 u8 tidno; 375 u8 tidno;
376 bool clear_filter; 376 bool flush = !!(ts->ts_status & ATH9K_TX_FLUSH);
377 377
378 skb = bf->bf_mpdu; 378 skb = bf->bf_mpdu;
379 hdr = (struct ieee80211_hdr *)skb->data; 379 hdr = (struct ieee80211_hdr *)skb->data;
@@ -462,12 +462,12 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
462 * the un-acked sub-frames 462 * the un-acked sub-frames
463 */ 463 */
464 txfail = 1; 464 txfail = 1;
465 } else if (flush) {
466 txpending = 1;
465 } else if (fi->retries < ATH_MAX_SW_RETRIES) { 467 } else if (fi->retries < ATH_MAX_SW_RETRIES) {
466 if (!(ts->ts_status & ATH9K_TXERR_FILT) || 468 if (txok || !an->sleeping)
467 !an->sleeping)
468 ath_tx_set_retry(sc, txq, bf->bf_mpdu); 469 ath_tx_set_retry(sc, txq, bf->bf_mpdu);
469 470
470 clear_filter = true;
471 txpending = 1; 471 txpending = 1;
472 } else { 472 } else {
473 txfail = 1; 473 txfail = 1;
@@ -521,7 +521,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
521 521
522 ath_tx_complete_buf(sc, bf, txq, 522 ath_tx_complete_buf(sc, bf, txq,
523 &bf_head, 523 &bf_head,
524 ts, 0, 1); 524 ts, 0,
525 !flush);
525 break; 526 break;
526 } 527 }
527 528
@@ -545,11 +546,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
545 ieee80211_sta_set_buffered(sta, tid->tidno, true); 546 ieee80211_sta_set_buffered(sta, tid->tidno, true);
546 547
547 spin_lock_bh(&txq->axq_lock); 548 spin_lock_bh(&txq->axq_lock);
548 if (clear_filter)
549 tid->ac->clear_ps_filter = true;
550 skb_queue_splice(&bf_pending, &tid->buf_q); 549 skb_queue_splice(&bf_pending, &tid->buf_q);
551 if (!an->sleeping) 550 if (!an->sleeping) {
552 ath_tx_queue_tid(txq, tid); 551 ath_tx_queue_tid(txq, tid);
552
553 if (ts->ts_status & ATH9K_TXERR_FILT)
554 tid->ac->clear_ps_filter = true;
555 }
553 spin_unlock_bh(&txq->axq_lock); 556 spin_unlock_bh(&txq->axq_lock);
554 } 557 }
555 558
@@ -564,8 +567,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
564 567
565 rcu_read_unlock(); 568 rcu_read_unlock();
566 569
567 if (needreset) 570 if (needreset) {
571 RESET_STAT_INC(sc, RESET_TYPE_TX_ERROR);
568 ieee80211_queue_work(sc->hw, &sc->hw_reset_work); 572 ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
573 }
569} 574}
570 575
571static bool ath_lookup_legacy(struct ath_buf *bf) 576static bool ath_lookup_legacy(struct ath_buf *bf)
@@ -1255,7 +1260,6 @@ static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
1255struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) 1260struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
1256{ 1261{
1257 struct ath_hw *ah = sc->sc_ah; 1262 struct ath_hw *ah = sc->sc_ah;
1258 struct ath_common *common = ath9k_hw_common(ah);
1259 struct ath9k_tx_queue_info qi; 1263 struct ath9k_tx_queue_info qi;
1260 static const int subtype_txq_to_hwq[] = { 1264 static const int subtype_txq_to_hwq[] = {
1261 [WME_AC_BE] = ATH_TXQ_AC_BE, 1265 [WME_AC_BE] = ATH_TXQ_AC_BE,
@@ -1305,12 +1309,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
1305 */ 1309 */
1306 return NULL; 1310 return NULL;
1307 } 1311 }
1308 if (axq_qnum >= ARRAY_SIZE(sc->tx.txq)) {
1309 ath_err(common, "qnum %u out of range, max %zu!\n",
1310 axq_qnum, ARRAY_SIZE(sc->tx.txq));
1311 ath9k_hw_releasetxqueue(ah, axq_qnum);
1312 return NULL;
1313 }
1314 if (!ATH_TXQ_SETUP(sc, axq_qnum)) { 1312 if (!ATH_TXQ_SETUP(sc, axq_qnum)) {
1315 struct ath_txq *txq = &sc->tx.txq[axq_qnum]; 1313 struct ath_txq *txq = &sc->tx.txq[axq_qnum];
1316 1314
@@ -1407,6 +1405,7 @@ static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq,
1407 struct ath_tx_status ts; 1405 struct ath_tx_status ts;
1408 1406
1409 memset(&ts, 0, sizeof(ts)); 1407 memset(&ts, 0, sizeof(ts));
1408 ts.ts_status = ATH9K_TX_FLUSH;
1410 INIT_LIST_HEAD(&bf_head); 1409 INIT_LIST_HEAD(&bf_head);
1411 1410
1412 while (!list_empty(list)) { 1411 while (!list_empty(list)) {
@@ -1473,7 +1472,8 @@ bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
1473 struct ath_hw *ah = sc->sc_ah; 1472 struct ath_hw *ah = sc->sc_ah;
1474 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1473 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1475 struct ath_txq *txq; 1474 struct ath_txq *txq;
1476 int i, npend = 0; 1475 int i;
1476 u32 npend = 0;
1477 1477
1478 if (sc->sc_flags & SC_OP_INVALID) 1478 if (sc->sc_flags & SC_OP_INVALID)
1479 return true; 1479 return true;
@@ -1485,11 +1485,12 @@ bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
1485 if (!ATH_TXQ_SETUP(sc, i)) 1485 if (!ATH_TXQ_SETUP(sc, i))
1486 continue; 1486 continue;
1487 1487
1488 npend += ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum); 1488 if (ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum))
1489 npend |= BIT(i);
1489 } 1490 }
1490 1491
1491 if (npend) 1492 if (npend)
1492 ath_err(common, "Failed to stop TX DMA!\n"); 1493 ath_err(common, "Failed to stop TX DMA, queues=0x%03x!\n", npend);
1493 1494
1494 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { 1495 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
1495 if (!ATH_TXQ_SETUP(sc, i)) 1496 if (!ATH_TXQ_SETUP(sc, i))
@@ -2211,6 +2212,7 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
2211 if (needreset) { 2212 if (needreset) {
2212 ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET, 2213 ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
2213 "tx hung, resetting the chip\n"); 2214 "tx hung, resetting the chip\n");
2215 RESET_STAT_INC(sc, RESET_TYPE_TX_HANG);
2214 ieee80211_queue_work(sc->hw, &sc->hw_reset_work); 2216 ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
2215 } 2217 }
2216 2218
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index beca71073e9b..f06e0695d412 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -1896,7 +1896,6 @@ static int carl9170_parse_eeprom(struct ar9170 *ar)
1896 ar->hw->channel_change_time = 80 * 1000; 1896 ar->hw->channel_change_time = 80 * 1000;
1897 1897
1898 regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]); 1898 regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
1899 regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
1900 1899
1901 /* second part of wiphy init */ 1900 /* second part of wiphy init */
1902 SET_IEEE80211_PERM_ADDR(ar->hw, ar->eeprom.mac_address); 1901 SET_IEEE80211_PERM_ADDR(ar->hw, ar->eeprom.mac_address);
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index b8de62c22479..c73e8600d218 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -735,16 +735,22 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
735 } 735 }
736 736
737 /* Link quality statistics */ 737 /* Link quality statistics */
738 if ((chanstat & B43_RX_CHAN_PHYTYPE) == B43_PHYTYPE_N) { 738 switch (chanstat & B43_RX_CHAN_PHYTYPE) {
739// s8 rssi = max(rxhdr->power0, rxhdr->power1); 739 case B43_PHYTYPE_N:
740 //TODO: Find out what the rssi value is (dBm or percentage?) 740 if (rxhdr->power0 == 16 || rxhdr->power0 == 32)
741 // and also find out what the maximum possible value is. 741 status.signal = max(rxhdr->power1, rxhdr->power2);
742 // Fill status.ssi and status.signal fields. 742 else
743 } else { 743 status.signal = max(rxhdr->power0, rxhdr->power1);
744 break;
745 case B43_PHYTYPE_A:
746 case B43_PHYTYPE_B:
747 case B43_PHYTYPE_G:
748 case B43_PHYTYPE_LP:
744 status.signal = b43_rssi_postprocess(dev, rxhdr->jssi, 749 status.signal = b43_rssi_postprocess(dev, rxhdr->jssi,
745 (phystat0 & B43_RX_PHYST0_OFDM), 750 (phystat0 & B43_RX_PHYST0_OFDM),
746 (phystat0 & B43_RX_PHYST0_GAINCTL), 751 (phystat0 & B43_RX_PHYST0_GAINCTL),
747 (phystat3 & B43_RX_PHYST3_TRSTATE)); 752 (phystat3 & B43_RX_PHYST3_TRSTATE));
753 break;
748 } 754 }
749 755
750 if (phystat0 & B43_RX_PHYST0_OFDM) 756 if (phystat0 & B43_RX_PHYST0_OFDM)
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index f6e8bc436d5a..16c514d54afa 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -248,7 +248,15 @@ struct b43_rxhdr_fw4 {
248 __s8 power1; /* PHY RX Status 1: Power 1 */ 248 __s8 power1; /* PHY RX Status 1: Power 1 */
249 } __packed; 249 } __packed;
250 } __packed; 250 } __packed;
251 __le16 phy_status2; /* PHY RX Status 2 */ 251 union {
252 /* RSSI for N-PHYs */
253 struct {
254 __s8 power2;
255 PAD_BYTES(1);
256 } __packed;
257
258 __le16 phy_status2; /* PHY RX Status 2 */
259 } __packed;
252 __le16 phy_status3; /* PHY RX Status 3 */ 260 __le16 phy_status3; /* PHY RX Status 3 */
253 union { 261 union {
254 /* Tested with 598.314, 644.1001 and 666.2 */ 262 /* Tested with 598.314, 644.1001 and 666.2 */
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
new file mode 100644
index 000000000000..2069fc8f7ad1
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -0,0 +1,35 @@
1config BRCMUTIL
2 tristate
3
4config BRCMSMAC
5 tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
6 depends on PCI
7 depends on MAC80211
8 depends on BCMA=n
9 select BRCMUTIL
10 select FW_LOADER
11 select CRC_CCITT
12 select CRC8
13 select CORDIC
14 ---help---
15 This module adds support for PCIe wireless adapters based on Broadcom
16 IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll
17 be called brcmsmac.ko.
18
19config BRCMFMAC
20 tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
21 depends on MMC
22 depends on CFG80211
23 select BRCMUTIL
24 select FW_LOADER
25 ---help---
26 This module adds support for embedded wireless adapters based on
27 Broadcom IEEE802.11n FullMAC chipsets. This driver uses the kernel's
28 wireless extensions subsystem. If you choose to build a module,
29 it'll be called brcmfmac.ko.
30
31config BRCMDBG
32 bool "Broadcom driver debug functions"
33 depends on BRCMSMAC || BRCMFMAC
34 ---help---
35 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 000000000000..f41c047eca82
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/Makefile
@@ -0,0 +1,23 @@
1#
2# Makefile fragment for Broadcom 802.11n Networking Device Driver
3#
4# Copyright (c) 2010 Broadcom Corporation
5#
6# Permission to use, copy, modify, and/or distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18# common flags
19subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG
20
21obj-$(CONFIG_BRCMUTIL) += brcmutil/
22obj-$(CONFIG_BRCMFMAC) += brcmfmac/
23obj-$(CONFIG_BRCMSMAC) += brcmsmac/
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
new file mode 100644
index 000000000000..b44e3094588a
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -0,0 +1,33 @@
1#
2# Makefile fragment for Broadcom 802.11n Networking Device Driver
3#
4# Copyright (c) 2010 Broadcom Corporation
5#
6# Permission to use, copy, modify, and/or distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18ccflags-y += \
19 -Idrivers/net/wireless/brcm80211/brcmfmac \
20 -Idrivers/net/wireless/brcm80211/include
21
22DHDOFILES = \
23 wl_cfg80211.o \
24 dhd_cdc.o \
25 dhd_common.o \
26 dhd_sdio.o \
27 dhd_linux.o \
28 bcmsdh.o \
29 bcmsdh_sdmmc.o
30
31obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
32brcmfmac-objs += $(DHDOFILES)
33ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h b/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h
new file mode 100644
index 000000000000..d7d3afd5a10f
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) 2011 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _bcmchip_h_
18#define _bcmchip_h_
19
20/* bcm4329 */
21/* SDIO device core, ID 0x829 */
22#define BCM4329_CORE_BUS_BASE 0x18011000
23/* internal memory core, ID 0x80e */
24#define BCM4329_CORE_SOCRAM_BASE 0x18003000
25/* ARM Cortex M3 core, ID 0x82a */
26#define BCM4329_CORE_ARM_BASE 0x18002000
27#define BCM4329_RAMSIZE 0x48000
28/* firmware name */
29#define BCM4329_FW_NAME "brcm/bcm4329-fullmac-4.bin"
30#define BCM4329_NV_NAME "brcm/bcm4329-fullmac-4.txt"
31
32#endif /* _bcmchip_h_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
new file mode 100644
index 000000000000..bff9dcd6fadc
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -0,0 +1,371 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16/* ****************** SDIO CARD Interface Functions **************************/
17
18#include <linux/types.h>
19#include <linux/netdevice.h>
20#include <linux/pci.h>
21#include <linux/pci_ids.h>
22#include <linux/sched.h>
23#include <linux/completion.h>
24#include <linux/mmc/sdio.h>
25#include <linux/mmc/sdio_func.h>
26#include <linux/mmc/card.h>
27
28#include <defs.h>
29#include <brcm_hw_ids.h>
30#include <brcmu_utils.h>
31#include <brcmu_wifi.h>
32#include <soc.h>
33#include "dhd.h"
34#include "dhd_bus.h"
35#include "dhd_dbg.h"
36#include "sdio_host.h"
37
38#define SDIOH_API_ACCESS_RETRY_LIMIT 2
39
40static void brcmf_sdioh_irqhandler(struct sdio_func *func)
41{
42 struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
43
44 brcmf_dbg(TRACE, "***IRQHandler\n");
45
46 sdio_release_host(func);
47
48 brcmf_sdbrcm_isr(sdiodev->bus);
49
50 sdio_claim_host(func);
51}
52
53int brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev)
54{
55 brcmf_dbg(TRACE, "Entering\n");
56
57 sdio_claim_host(sdiodev->func[1]);
58 sdio_claim_irq(sdiodev->func[1], brcmf_sdioh_irqhandler);
59 sdio_release_host(sdiodev->func[1]);
60
61 return 0;
62}
63
64int brcmf_sdcard_intr_dereg(struct brcmf_sdio_dev *sdiodev)
65{
66 brcmf_dbg(TRACE, "Entering\n");
67
68 sdio_claim_host(sdiodev->func[1]);
69 sdio_release_irq(sdiodev->func[1]);
70 sdio_release_host(sdiodev->func[1]);
71
72 return 0;
73}
74
75u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr,
76 int *err)
77{
78 int status;
79 s32 retry = 0;
80 u8 data = 0;
81
82 do {
83 if (retry) /* wait for 1 ms till bus get settled down */
84 udelay(1000);
85 status = brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, fnc_num,
86 addr, (u8 *) &data);
87 } while (status != 0
88 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
89 if (err)
90 *err = status;
91
92 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n",
93 fnc_num, addr, data);
94
95 return data;
96}
97
98void
99brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr,
100 u8 data, int *err)
101{
102 int status;
103 s32 retry = 0;
104
105 do {
106 if (retry) /* wait for 1 ms till bus get settled down */
107 udelay(1000);
108 status = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, fnc_num,
109 addr, (u8 *) &data);
110 } while (status != 0
111 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
112 if (err)
113 *err = status;
114
115 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n",
116 fnc_num, addr, data);
117}
118
119int
120brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
121{
122 int err = 0;
123 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
124 (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
125 if (!err)
126 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
127 SBSDIO_FUNC1_SBADDRMID,
128 (address >> 16) & SBSDIO_SBADDRMID_MASK,
129 &err);
130 if (!err)
131 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
132 SBSDIO_FUNC1_SBADDRHIGH,
133 (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
134 &err);
135
136 return err;
137}
138
139u32 brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size)
140{
141 int status;
142 u32 word = 0;
143 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
144
145 brcmf_dbg(INFO, "fun = 1, addr = 0x%x\n", addr);
146
147 if (bar0 != sdiodev->sbwad) {
148 if (brcmf_sdcard_set_sbaddr_window(sdiodev, bar0))
149 return 0xFFFFFFFF;
150
151 sdiodev->sbwad = bar0;
152 }
153
154 addr &= SBSDIO_SB_OFT_ADDR_MASK;
155 if (size == 4)
156 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
157
158 status = brcmf_sdioh_request_word(sdiodev, SDIOH_READ, SDIO_FUNC_1,
159 addr, &word, size);
160
161 sdiodev->regfail = (status != 0);
162
163 brcmf_dbg(INFO, "u32data = 0x%x\n", word);
164
165 /* if ok, return appropriately masked word */
166 if (status == 0) {
167 switch (size) {
168 case sizeof(u8):
169 return word & 0xff;
170 case sizeof(u16):
171 return word & 0xffff;
172 case sizeof(u32):
173 return word;
174 default:
175 sdiodev->regfail = true;
176
177 }
178 }
179
180 /* otherwise, bad sdio access or invalid size */
181 brcmf_dbg(ERROR, "error reading addr 0x%04x size %d\n", addr, size);
182 return 0xFFFFFFFF;
183}
184
185u32 brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size,
186 u32 data)
187{
188 int status;
189 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
190 int err = 0;
191
192 brcmf_dbg(INFO, "fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
193 addr, size * 8, data);
194
195 if (bar0 != sdiodev->sbwad) {
196 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
197 if (err)
198 return err;
199
200 sdiodev->sbwad = bar0;
201 }
202
203 addr &= SBSDIO_SB_OFT_ADDR_MASK;
204 if (size == 4)
205 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
206 status =
207 brcmf_sdioh_request_word(sdiodev, SDIOH_WRITE, SDIO_FUNC_1,
208 addr, &data, size);
209 sdiodev->regfail = (status != 0);
210
211 if (status == 0)
212 return 0;
213
214 brcmf_dbg(ERROR, "error writing 0x%08x to addr 0x%04x size %d\n",
215 data, addr, size);
216 return 0xFFFFFFFF;
217}
218
219bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev)
220{
221 return sdiodev->regfail;
222}
223
224int
225brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
226 uint flags,
227 u8 *buf, uint nbytes, struct sk_buff *pkt)
228{
229 int status;
230 uint incr_fix;
231 uint width;
232 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
233 int err = 0;
234
235 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, nbytes);
236
237 /* Async not implemented yet */
238 if (flags & SDIO_REQ_ASYNC)
239 return -ENOTSUPP;
240
241 if (bar0 != sdiodev->sbwad) {
242 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
243 if (err)
244 return err;
245
246 sdiodev->sbwad = bar0;
247 }
248
249 addr &= SBSDIO_SB_OFT_ADDR_MASK;
250
251 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
252 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
253 if (width == 4)
254 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
255
256 status = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_READ,
257 fn, addr, width, nbytes, buf, pkt);
258
259 return status;
260}
261
262int
263brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
264 uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt)
265{
266 uint incr_fix;
267 uint width;
268 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
269 int err = 0;
270
271 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, nbytes);
272
273 /* Async not implemented yet */
274 if (flags & SDIO_REQ_ASYNC)
275 return -ENOTSUPP;
276
277 if (bar0 != sdiodev->sbwad) {
278 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
279 if (err)
280 return err;
281
282 sdiodev->sbwad = bar0;
283 }
284
285 addr &= SBSDIO_SB_OFT_ADDR_MASK;
286
287 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
288 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
289 if (width == 4)
290 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
291
292 return brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_WRITE, fn,
293 addr, width, nbytes, buf, pkt);
294}
295
296int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr,
297 u8 *buf, uint nbytes)
298{
299 addr &= SBSDIO_SB_OFT_ADDR_MASK;
300 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
301
302 return brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC,
303 (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
304 addr, 4, nbytes, buf, NULL);
305}
306
307int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
308{
309 char t_func = (char)fn;
310 brcmf_dbg(TRACE, "Enter\n");
311
312 /* issue abort cmd52 command through F0 */
313 brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0,
314 SDIO_CCCR_ABORT, &t_func);
315
316 brcmf_dbg(TRACE, "Exit\n");
317 return 0;
318}
319
320int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
321{
322 u32 regs = 0;
323 int ret = 0;
324
325 ret = brcmf_sdioh_attach(sdiodev);
326 if (ret)
327 goto out;
328
329 regs = SI_ENUM_BASE;
330
331 /* Report the BAR, to fix if needed */
332 sdiodev->sbwad = SI_ENUM_BASE;
333
334 /* try to attach to the target device */
335 sdiodev->bus = brcmf_sdbrcm_probe(0, 0, 0, 0, regs, sdiodev);
336 if (!sdiodev->bus) {
337 brcmf_dbg(ERROR, "device attach failed\n");
338 ret = -ENODEV;
339 goto out;
340 }
341
342out:
343 if (ret)
344 brcmf_sdio_remove(sdiodev);
345
346 return ret;
347}
348EXPORT_SYMBOL(brcmf_sdio_probe);
349
350int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev)
351{
352 if (sdiodev->bus) {
353 brcmf_sdbrcm_disconnect(sdiodev->bus);
354 sdiodev->bus = NULL;
355 }
356
357 brcmf_sdioh_detach(sdiodev);
358
359 sdiodev->sbwad = 0;
360
361 return 0;
362}
363EXPORT_SYMBOL(brcmf_sdio_remove);
364
365void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable)
366{
367 if (enable)
368 brcmf_sdbrcm_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
369 else
370 brcmf_sdbrcm_wd_timer(sdiodev->bus, 0);
371}
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 000000000000..bbaeb2d5c93a
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -0,0 +1,626 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/types.h>
17#include <linux/netdevice.h>
18#include <linux/mmc/sdio.h>
19#include <linux/mmc/core.h>
20#include <linux/mmc/sdio_func.h>
21#include <linux/mmc/sdio_ids.h>
22#include <linux/mmc/card.h>
23#include <linux/suspend.h>
24#include <linux/errno.h>
25#include <linux/sched.h> /* request_irq() */
26#include <linux/module.h>
27#include <net/cfg80211.h>
28
29#include <defs.h>
30#include <brcm_hw_ids.h>
31#include <brcmu_utils.h>
32#include <brcmu_wifi.h>
33#include "sdio_host.h"
34#include "dhd.h"
35#include "dhd_dbg.h"
36#include "wl_cfg80211.h"
37
38#define SDIO_VENDOR_ID_BROADCOM 0x02d0
39
40#define DMA_ALIGN_MASK 0x03
41
42#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
43
44#define SDIO_FUNC1_BLOCKSIZE 64
45#define SDIO_FUNC2_BLOCKSIZE 512
46
47/* devices we support, null terminated */
48static const struct sdio_device_id brcmf_sdmmc_ids[] = {
49 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
50 { /* end: all zeroes */ },
51};
52MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
53
54static bool
55brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
56{
57 bool is_err = false;
58#ifdef CONFIG_PM_SLEEP
59 is_err = atomic_read(&sdiodev->suspend);
60#endif
61 return is_err;
62}
63
64static void
65brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq)
66{
67#ifdef CONFIG_PM_SLEEP
68 int retry = 0;
69 while (atomic_read(&sdiodev->suspend) && retry++ != 30)
70 wait_event_timeout(*wq, false, HZ/100);
71#endif
72}
73
74static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
75 uint regaddr, u8 *byte)
76{
77 struct sdio_func *sdfunc = sdiodev->func[0];
78 int err_ret;
79
80 /*
81 * Can only directly write to some F0 registers.
82 * Handle F2 enable/disable and Abort command
83 * as a special case.
84 */
85 if (regaddr == SDIO_CCCR_IOEx) {
86 sdfunc = sdiodev->func[2];
87 if (sdfunc) {
88 sdio_claim_host(sdfunc);
89 if (*byte & SDIO_FUNC_ENABLE_2) {
90 /* Enable Function 2 */
91 err_ret = sdio_enable_func(sdfunc);
92 if (err_ret)
93 brcmf_dbg(ERROR,
94 "enable F2 failed:%d\n",
95 err_ret);
96 } else {
97 /* Disable Function 2 */
98 err_ret = sdio_disable_func(sdfunc);
99 if (err_ret)
100 brcmf_dbg(ERROR,
101 "Disable F2 failed:%d\n",
102 err_ret);
103 }
104 sdio_release_host(sdfunc);
105 }
106 } else if (regaddr == SDIO_CCCR_ABORT) {
107 sdio_claim_host(sdfunc);
108 sdio_writeb(sdfunc, *byte, regaddr, &err_ret);
109 sdio_release_host(sdfunc);
110 } else if (regaddr < 0xF0) {
111 brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr);
112 err_ret = -EPERM;
113 } else {
114 sdio_claim_host(sdfunc);
115 sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret);
116 sdio_release_host(sdfunc);
117 }
118
119 return err_ret;
120}
121
122int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
123 uint regaddr, u8 *byte)
124{
125 int err_ret;
126
127 brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr);
128
129 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait);
130 if (brcmf_pm_resume_error(sdiodev))
131 return -EIO;
132
133 if (rw && func == 0) {
134 /* handle F0 separately */
135 err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte);
136 } else {
137 sdio_claim_host(sdiodev->func[func]);
138 if (rw) /* CMD52 Write */
139 sdio_writeb(sdiodev->func[func], *byte, regaddr,
140 &err_ret);
141 else if (func == 0) {
142 *byte = sdio_f0_readb(sdiodev->func[func], regaddr,
143 &err_ret);
144 } else {
145 *byte = sdio_readb(sdiodev->func[func], regaddr,
146 &err_ret);
147 }
148 sdio_release_host(sdiodev->func[func]);
149 }
150
151 if (err_ret)
152 brcmf_dbg(ERROR, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
153 rw ? "write" : "read", func, regaddr, *byte, err_ret);
154
155 return err_ret;
156}
157
158int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
159 uint rw, uint func, uint addr, u32 *word,
160 uint nbytes)
161{
162 int err_ret = -EIO;
163
164 if (func == 0) {
165 brcmf_dbg(ERROR, "Only CMD52 allowed to F0\n");
166 return -EINVAL;
167 }
168
169 brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
170 rw, func, addr, nbytes);
171
172 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait);
173 if (brcmf_pm_resume_error(sdiodev))
174 return -EIO;
175 /* Claim host controller */
176 sdio_claim_host(sdiodev->func[func]);
177
178 if (rw) { /* CMD52 Write */
179 if (nbytes == 4)
180 sdio_writel(sdiodev->func[func], *word, addr,
181 &err_ret);
182 else if (nbytes == 2)
183 sdio_writew(sdiodev->func[func], (*word & 0xFFFF),
184 addr, &err_ret);
185 else
186 brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
187 } else { /* CMD52 Read */
188 if (nbytes == 4)
189 *word = sdio_readl(sdiodev->func[func], addr, &err_ret);
190 else if (nbytes == 2)
191 *word = sdio_readw(sdiodev->func[func], addr,
192 &err_ret) & 0xFFFF;
193 else
194 brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
195 }
196
197 /* Release host controller */
198 sdio_release_host(sdiodev->func[func]);
199
200 if (err_ret)
201 brcmf_dbg(ERROR, "Failed to %s word, Err: 0x%08x\n",
202 rw ? "write" : "read", err_ret);
203
204 return err_ret;
205}
206
207static int
208brcmf_sdioh_request_packet(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
209 uint write, uint func, uint addr,
210 struct sk_buff *pkt)
211{
212 bool fifo = (fix_inc == SDIOH_DATA_FIX);
213 u32 SGCount = 0;
214 int err_ret = 0;
215
216 struct sk_buff *pnext;
217
218 brcmf_dbg(TRACE, "Enter\n");
219
220 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_packet_wait);
221 if (brcmf_pm_resume_error(sdiodev))
222 return -EIO;
223
224 /* Claim host controller */
225 sdio_claim_host(sdiodev->func[func]);
226 for (pnext = pkt; pnext; pnext = pnext->next) {
227 uint pkt_len = pnext->len;
228 pkt_len += 3;
229 pkt_len &= 0xFFFFFFFC;
230
231 if ((write) && (!fifo)) {
232 err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
233 ((u8 *) (pnext->data)),
234 pkt_len);
235 } else if (write) {
236 err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
237 ((u8 *) (pnext->data)),
238 pkt_len);
239 } else if (fifo) {
240 err_ret = sdio_readsb(sdiodev->func[func],
241 ((u8 *) (pnext->data)),
242 addr, pkt_len);
243 } else {
244 err_ret = sdio_memcpy_fromio(sdiodev->func[func],
245 ((u8 *) (pnext->data)),
246 addr, pkt_len);
247 }
248
249 if (err_ret) {
250 brcmf_dbg(ERROR, "%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
251 write ? "TX" : "RX", pnext, SGCount, addr,
252 pkt_len, err_ret);
253 } else {
254 brcmf_dbg(TRACE, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n",
255 write ? "TX" : "RX", pnext, SGCount, addr,
256 pkt_len);
257 }
258
259 if (!fifo)
260 addr += pkt_len;
261 SGCount++;
262
263 }
264
265 /* Release host controller */
266 sdio_release_host(sdiodev->func[func]);
267
268 brcmf_dbg(TRACE, "Exit\n");
269 return err_ret;
270}
271
272/*
273 * This function takes a buffer or packet, and fixes everything up
274 * so that in the end, a DMA-able packet is created.
275 *
276 * A buffer does not have an associated packet pointer,
277 * and may or may not be aligned.
278 * A packet may consist of a single packet, or a packet chain.
279 * If it is a packet chain, then all the packets in the chain
280 * must be properly aligned.
281 *
282 * If the packet data is not aligned, then there may only be
283 * one packet, and in this case, it is copied to a new
284 * aligned packet.
285 *
286 */
287int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
288 uint fix_inc, uint write, uint func, uint addr,
289 uint reg_width, uint buflen_u, u8 *buffer,
290 struct sk_buff *pkt)
291{
292 int Status;
293 struct sk_buff *mypkt = NULL;
294
295 brcmf_dbg(TRACE, "Enter\n");
296
297 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
298 if (brcmf_pm_resume_error(sdiodev))
299 return -EIO;
300 /* Case 1: we don't have a packet. */
301 if (pkt == NULL) {
302 brcmf_dbg(DATA, "Creating new %s Packet, len=%d\n",
303 write ? "TX" : "RX", buflen_u);
304 mypkt = brcmu_pkt_buf_get_skb(buflen_u);
305 if (!mypkt) {
306 brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
307 buflen_u);
308 return -EIO;
309 }
310
311 /* For a write, copy the buffer data into the packet. */
312 if (write)
313 memcpy(mypkt->data, buffer, buflen_u);
314
315 Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write,
316 func, addr, mypkt);
317
318 /* For a read, copy the packet data back to the buffer. */
319 if (!write)
320 memcpy(buffer, mypkt->data, buflen_u);
321
322 brcmu_pkt_buf_free_skb(mypkt);
323 } else if (((ulong) (pkt->data) & DMA_ALIGN_MASK) != 0) {
324 /*
325 * Case 2: We have a packet, but it is unaligned.
326 * In this case, we cannot have a chain (pkt->next == NULL)
327 */
328 brcmf_dbg(DATA, "Creating aligned %s Packet, len=%d\n",
329 write ? "TX" : "RX", pkt->len);
330 mypkt = brcmu_pkt_buf_get_skb(pkt->len);
331 if (!mypkt) {
332 brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
333 pkt->len);
334 return -EIO;
335 }
336
337 /* For a write, copy the buffer data into the packet. */
338 if (write)
339 memcpy(mypkt->data, pkt->data, pkt->len);
340
341 Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write,
342 func, addr, mypkt);
343
344 /* For a read, copy the packet data back to the buffer. */
345 if (!write)
346 memcpy(pkt->data, mypkt->data, mypkt->len);
347
348 brcmu_pkt_buf_free_skb(mypkt);
349 } else { /* case 3: We have a packet and
350 it is aligned. */
351 brcmf_dbg(DATA, "Aligned %s Packet, direct DMA\n",
352 write ? "Tx" : "Rx");
353 Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write,
354 func, addr, pkt);
355 }
356
357 return Status;
358}
359
360/* Read client card reg */
361static int
362brcmf_sdioh_card_regread(struct brcmf_sdio_dev *sdiodev, int func, u32 regaddr,
363 int regsize, u32 *data)
364{
365
366 if ((func == 0) || (regsize == 1)) {
367 u8 temp = 0;
368
369 brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, func, regaddr,
370 &temp);
371 *data = temp;
372 *data &= 0xff;
373 brcmf_dbg(DATA, "byte read data=0x%02x\n", *data);
374 } else {
375 brcmf_sdioh_request_word(sdiodev, SDIOH_READ, func, regaddr,
376 data, regsize);
377 if (regsize == 2)
378 *data &= 0xffff;
379
380 brcmf_dbg(DATA, "word read data=0x%08x\n", *data);
381 }
382
383 return SUCCESS;
384}
385
386static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
387{
388 /* read 24 bits and return valid 17 bit addr */
389 int i;
390 u32 scratch, regdata;
391 __le32 scratch_le;
392 u8 *ptr = (u8 *)&scratch_le;
393
394 for (i = 0; i < 3; i++) {
395 if ((brcmf_sdioh_card_regread(sdiodev, 0, regaddr, 1,
396 &regdata)) != SUCCESS)
397 brcmf_dbg(ERROR, "Can't read!\n");
398
399 *ptr++ = (u8) regdata;
400 regaddr++;
401 }
402
403 /* Only the lower 17-bits are valid */
404 scratch = le32_to_cpu(scratch_le);
405 scratch &= 0x0001FFFF;
406 return scratch;
407}
408
409static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
410{
411 int err_ret;
412 u32 fbraddr;
413 u8 func;
414
415 brcmf_dbg(TRACE, "\n");
416
417 /* Get the Card's common CIS address */
418 sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev,
419 SDIO_CCCR_CIS);
420 brcmf_dbg(INFO, "Card's Common CIS Ptr = 0x%x\n",
421 sdiodev->func_cis_ptr[0]);
422
423 /* Get the Card's function CIS (for each function) */
424 for (fbraddr = SDIO_FBR_BASE(1), func = 1;
425 func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
426 sdiodev->func_cis_ptr[func] =
427 brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr);
428 brcmf_dbg(INFO, "Function %d CIS Ptr = 0x%x\n",
429 func, sdiodev->func_cis_ptr[func]);
430 }
431
432 /* Enable Function 1 */
433 sdio_claim_host(sdiodev->func[1]);
434 err_ret = sdio_enable_func(sdiodev->func[1]);
435 sdio_release_host(sdiodev->func[1]);
436 if (err_ret)
437 brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret);
438
439 return false;
440}
441
442/*
443 * Public entry points & extern's
444 */
445int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
446{
447 int err_ret = 0;
448
449 brcmf_dbg(TRACE, "\n");
450
451 sdiodev->num_funcs = 2;
452
453 sdio_claim_host(sdiodev->func[1]);
454 err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
455 sdio_release_host(sdiodev->func[1]);
456 if (err_ret) {
457 brcmf_dbg(ERROR, "Failed to set F1 blocksize\n");
458 goto out;
459 }
460
461 sdio_claim_host(sdiodev->func[2]);
462 err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
463 sdio_release_host(sdiodev->func[2]);
464 if (err_ret) {
465 brcmf_dbg(ERROR, "Failed to set F2 blocksize\n");
466 goto out;
467 }
468
469 brcmf_sdioh_enablefuncs(sdiodev);
470
471out:
472 brcmf_dbg(TRACE, "Done\n");
473 return err_ret;
474}
475
476void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev)
477{
478 brcmf_dbg(TRACE, "\n");
479
480 /* Disable Function 2 */
481 sdio_claim_host(sdiodev->func[2]);
482 sdio_disable_func(sdiodev->func[2]);
483 sdio_release_host(sdiodev->func[2]);
484
485 /* Disable Function 1 */
486 sdio_claim_host(sdiodev->func[1]);
487 sdio_disable_func(sdiodev->func[1]);
488 sdio_release_host(sdiodev->func[1]);
489
490}
491
492static int brcmf_ops_sdio_probe(struct sdio_func *func,
493 const struct sdio_device_id *id)
494{
495 int ret = 0;
496 struct brcmf_sdio_dev *sdiodev;
497 brcmf_dbg(TRACE, "Enter\n");
498 brcmf_dbg(TRACE, "func->class=%x\n", func->class);
499 brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor);
500 brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device);
501 brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num);
502
503 if (func->num == 1) {
504 if (dev_get_drvdata(&func->card->dev)) {
505 brcmf_dbg(ERROR, "card private drvdata occupied\n");
506 return -ENXIO;
507 }
508 sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
509 if (!sdiodev)
510 return -ENOMEM;
511 sdiodev->func[0] = func->card->sdio_func[0];
512 sdiodev->func[1] = func;
513 dev_set_drvdata(&func->card->dev, sdiodev);
514
515 atomic_set(&sdiodev->suspend, false);
516 init_waitqueue_head(&sdiodev->request_byte_wait);
517 init_waitqueue_head(&sdiodev->request_word_wait);
518 init_waitqueue_head(&sdiodev->request_packet_wait);
519 init_waitqueue_head(&sdiodev->request_buffer_wait);
520 }
521
522 if (func->num == 2) {
523 sdiodev = dev_get_drvdata(&func->card->dev);
524 if ((!sdiodev) || (sdiodev->func[1]->card != func->card))
525 return -ENODEV;
526 sdiodev->func[2] = func;
527
528 brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
529 ret = brcmf_sdio_probe(sdiodev);
530 }
531
532 return ret;
533}
534
535static void brcmf_ops_sdio_remove(struct sdio_func *func)
536{
537 struct brcmf_sdio_dev *sdiodev;
538 brcmf_dbg(TRACE, "Enter\n");
539 brcmf_dbg(INFO, "func->class=%x\n", func->class);
540 brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor);
541 brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device);
542 brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num);
543
544 if (func->num == 2) {
545 sdiodev = dev_get_drvdata(&func->card->dev);
546 brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n");
547 brcmf_sdio_remove(sdiodev);
548 dev_set_drvdata(&func->card->dev, NULL);
549 kfree(sdiodev);
550 }
551}
552
553#ifdef CONFIG_PM_SLEEP
554static int brcmf_sdio_suspend(struct device *dev)
555{
556 mmc_pm_flag_t sdio_flags;
557 struct brcmf_sdio_dev *sdiodev;
558 struct sdio_func *func = dev_to_sdio_func(dev);
559 int ret = 0;
560
561 brcmf_dbg(TRACE, "\n");
562
563 sdiodev = dev_get_drvdata(&func->card->dev);
564
565 atomic_set(&sdiodev->suspend, true);
566
567 sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
568 if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
569 brcmf_dbg(ERROR, "Host can't keep power while suspended\n");
570 return -EINVAL;
571 }
572
573 ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
574 if (ret) {
575 brcmf_dbg(ERROR, "Failed to set pm_flags\n");
576 return ret;
577 }
578
579 brcmf_sdio_wdtmr_enable(sdiodev, false);
580
581 return ret;
582}
583
584static int brcmf_sdio_resume(struct device *dev)
585{
586 struct brcmf_sdio_dev *sdiodev;
587 struct sdio_func *func = dev_to_sdio_func(dev);
588
589 sdiodev = dev_get_drvdata(&func->card->dev);
590 brcmf_sdio_wdtmr_enable(sdiodev, true);
591 atomic_set(&sdiodev->suspend, false);
592 return 0;
593}
594
595static const struct dev_pm_ops brcmf_sdio_pm_ops = {
596 .suspend = brcmf_sdio_suspend,
597 .resume = brcmf_sdio_resume,
598};
599#endif /* CONFIG_PM_SLEEP */
600
601static struct sdio_driver brcmf_sdmmc_driver = {
602 .probe = brcmf_ops_sdio_probe,
603 .remove = brcmf_ops_sdio_remove,
604 .name = "brcmfmac",
605 .id_table = brcmf_sdmmc_ids,
606#ifdef CONFIG_PM_SLEEP
607 .drv = {
608 .pm = &brcmf_sdio_pm_ops,
609 },
610#endif /* CONFIG_PM_SLEEP */
611};
612
613/* bus register interface */
614int brcmf_bus_register(void)
615{
616 brcmf_dbg(TRACE, "Enter\n");
617
618 return sdio_register_driver(&brcmf_sdmmc_driver);
619}
620
621void brcmf_bus_unregister(void)
622{
623 brcmf_dbg(TRACE, "Enter\n");
624
625 sdio_unregister_driver(&brcmf_sdmmc_driver);
626}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
new file mode 100644
index 000000000000..4645766b4070
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -0,0 +1,776 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/****************
18 * Common types *
19 */
20
21#ifndef _BRCMF_H_
22#define _BRCMF_H_
23
24#define BRCMF_VERSION_STR "4.218.248.5"
25
26/*******************************************************************************
27 * IO codes that are interpreted by dongle firmware
28 ******************************************************************************/
29#define BRCMF_C_UP 2
30#define BRCMF_C_SET_PROMISC 10
31#define BRCMF_C_GET_RATE 12
32#define BRCMF_C_GET_INFRA 19
33#define BRCMF_C_SET_INFRA 20
34#define BRCMF_C_GET_AUTH 21
35#define BRCMF_C_SET_AUTH 22
36#define BRCMF_C_GET_BSSID 23
37#define BRCMF_C_GET_SSID 25
38#define BRCMF_C_SET_SSID 26
39#define BRCMF_C_GET_CHANNEL 29
40#define BRCMF_C_GET_SRL 31
41#define BRCMF_C_GET_LRL 33
42#define BRCMF_C_GET_RADIO 37
43#define BRCMF_C_SET_RADIO 38
44#define BRCMF_C_GET_PHYTYPE 39
45#define BRCMF_C_SET_KEY 45
46#define BRCMF_C_SET_PASSIVE_SCAN 49
47#define BRCMF_C_SCAN 50
48#define BRCMF_C_SCAN_RESULTS 51
49#define BRCMF_C_DISASSOC 52
50#define BRCMF_C_REASSOC 53
51#define BRCMF_C_SET_ROAM_TRIGGER 55
52#define BRCMF_C_SET_ROAM_DELTA 57
53#define BRCMF_C_GET_DTIMPRD 77
54#define BRCMF_C_SET_COUNTRY 84
55#define BRCMF_C_GET_PM 85
56#define BRCMF_C_SET_PM 86
57#define BRCMF_C_GET_AP 117
58#define BRCMF_C_SET_AP 118
59#define BRCMF_C_GET_RSSI 127
60#define BRCMF_C_GET_WSEC 133
61#define BRCMF_C_SET_WSEC 134
62#define BRCMF_C_GET_PHY_NOISE 135
63#define BRCMF_C_GET_BSS_INFO 136
64#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
65#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
66#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
67#define BRCMF_C_GET_VALID_CHANNELS 217
68#define BRCMF_C_GET_KEY_PRIMARY 235
69#define BRCMF_C_SET_KEY_PRIMARY 236
70#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258
71#define BRCMF_C_GET_VAR 262
72#define BRCMF_C_SET_VAR 263
73
74/* phy types (returned by WLC_GET_PHYTPE) */
75#define WLC_PHY_TYPE_A 0
76#define WLC_PHY_TYPE_B 1
77#define WLC_PHY_TYPE_G 2
78#define WLC_PHY_TYPE_N 4
79#define WLC_PHY_TYPE_LP 5
80#define WLC_PHY_TYPE_SSN 6
81#define WLC_PHY_TYPE_HT 7
82#define WLC_PHY_TYPE_LCN 8
83#define WLC_PHY_TYPE_NULL 0xf
84
85#define BRCMF_EVENTING_MASK_LEN 16
86
87#define TOE_TX_CSUM_OL 0x00000001
88#define TOE_RX_CSUM_OL 0x00000002
89
90#define BRCMF_BSS_INFO_VERSION 108 /* current ver of brcmf_bss_info struct */
91
92/* size of brcmf_scan_params not including variable length array */
93#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
94
95/* masks for channel and ssid count */
96#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
97#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
98
99#define BRCMF_SCAN_ACTION_START 1
100#define BRCMF_SCAN_ACTION_CONTINUE 2
101#define WL_SCAN_ACTION_ABORT 3
102
103#define BRCMF_ISCAN_REQ_VERSION 1
104
105/* brcmf_iscan_results status values */
106#define BRCMF_SCAN_RESULTS_SUCCESS 0
107#define BRCMF_SCAN_RESULTS_PARTIAL 1
108#define BRCMF_SCAN_RESULTS_PENDING 2
109#define BRCMF_SCAN_RESULTS_ABORTED 3
110#define BRCMF_SCAN_RESULTS_NO_MEM 4
111
112/* Indicates this key is using soft encrypt */
113#define WL_SOFT_KEY (1 << 0)
114/* primary (ie tx) key */
115#define BRCMF_PRIMARY_KEY (1 << 1)
116/* Reserved for backward compat */
117#define WL_KF_RES_4 (1 << 4)
118/* Reserved for backward compat */
119#define WL_KF_RES_5 (1 << 5)
120/* Indicates a group key for a IBSS PEER */
121#define WL_IBSS_PEER_GROUP_KEY (1 << 6)
122
123/* For supporting multiple interfaces */
124#define BRCMF_MAX_IFS 16
125#define BRCMF_DEL_IF -0xe
126#define BRCMF_BAD_IF -0xf
127
128#define DOT11_BSSTYPE_ANY 2
129#define DOT11_MAX_DEFAULT_KEYS 4
130
131#define BRCMF_EVENT_MSG_LINK 0x01
132#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02
133#define BRCMF_EVENT_MSG_GROUP 0x04
134
135struct brcmf_event_msg {
136 __be16 version;
137 __be16 flags;
138 __be32 event_type;
139 __be32 status;
140 __be32 reason;
141 __be32 auth_type;
142 __be32 datalen;
143 u8 addr[ETH_ALEN];
144 char ifname[IFNAMSIZ];
145} __packed;
146
147struct brcm_ethhdr {
148 u16 subtype;
149 u16 length;
150 u8 version;
151 u8 oui[3];
152 u16 usr_subtype;
153} __packed;
154
155struct brcmf_event {
156 struct ethhdr eth;
157 struct brcm_ethhdr hdr;
158 struct brcmf_event_msg msg;
159} __packed;
160
161struct dngl_stats {
162 unsigned long rx_packets; /* total packets received */
163 unsigned long tx_packets; /* total packets transmitted */
164 unsigned long rx_bytes; /* total bytes received */
165 unsigned long tx_bytes; /* total bytes transmitted */
166 unsigned long rx_errors; /* bad packets received */
167 unsigned long tx_errors; /* packet transmit problems */
168 unsigned long rx_dropped; /* packets dropped by dongle */
169 unsigned long tx_dropped; /* packets dropped by dongle */
170 unsigned long multicast; /* multicast packets received */
171};
172
173/* event codes sent by the dongle to this driver */
174#define BRCMF_E_SET_SSID 0
175#define BRCMF_E_JOIN 1
176#define BRCMF_E_START 2
177#define BRCMF_E_AUTH 3
178#define BRCMF_E_AUTH_IND 4
179#define BRCMF_E_DEAUTH 5
180#define BRCMF_E_DEAUTH_IND 6
181#define BRCMF_E_ASSOC 7
182#define BRCMF_E_ASSOC_IND 8
183#define BRCMF_E_REASSOC 9
184#define BRCMF_E_REASSOC_IND 10
185#define BRCMF_E_DISASSOC 11
186#define BRCMF_E_DISASSOC_IND 12
187#define BRCMF_E_QUIET_START 13
188#define BRCMF_E_QUIET_END 14
189#define BRCMF_E_BEACON_RX 15
190#define BRCMF_E_LINK 16
191#define BRCMF_E_MIC_ERROR 17
192#define BRCMF_E_NDIS_LINK 18
193#define BRCMF_E_ROAM 19
194#define BRCMF_E_TXFAIL 20
195#define BRCMF_E_PMKID_CACHE 21
196#define BRCMF_E_RETROGRADE_TSF 22
197#define BRCMF_E_PRUNE 23
198#define BRCMF_E_AUTOAUTH 24
199#define BRCMF_E_EAPOL_MSG 25
200#define BRCMF_E_SCAN_COMPLETE 26
201#define BRCMF_E_ADDTS_IND 27
202#define BRCMF_E_DELTS_IND 28
203#define BRCMF_E_BCNSENT_IND 29
204#define BRCMF_E_BCNRX_MSG 30
205#define BRCMF_E_BCNLOST_MSG 31
206#define BRCMF_E_ROAM_PREP 32
207#define BRCMF_E_PFN_NET_FOUND 33
208#define BRCMF_E_PFN_NET_LOST 34
209#define BRCMF_E_RESET_COMPLETE 35
210#define BRCMF_E_JOIN_START 36
211#define BRCMF_E_ROAM_START 37
212#define BRCMF_E_ASSOC_START 38
213#define BRCMF_E_IBSS_ASSOC 39
214#define BRCMF_E_RADIO 40
215#define BRCMF_E_PSM_WATCHDOG 41
216#define BRCMF_E_PROBREQ_MSG 44
217#define BRCMF_E_SCAN_CONFIRM_IND 45
218#define BRCMF_E_PSK_SUP 46
219#define BRCMF_E_COUNTRY_CODE_CHANGED 47
220#define BRCMF_E_EXCEEDED_MEDIUM_TIME 48
221#define BRCMF_E_ICV_ERROR 49
222#define BRCMF_E_UNICAST_DECODE_ERROR 50
223#define BRCMF_E_MULTICAST_DECODE_ERROR 51
224#define BRCMF_E_TRACE 52
225#define BRCMF_E_IF 54
226#define BRCMF_E_RSSI 56
227#define BRCMF_E_PFN_SCAN_COMPLETE 57
228#define BRCMF_E_EXTLOG_MSG 58
229#define BRCMF_E_ACTION_FRAME 59
230#define BRCMF_E_ACTION_FRAME_COMPLETE 60
231#define BRCMF_E_PRE_ASSOC_IND 61
232#define BRCMF_E_PRE_REASSOC_IND 62
233#define BRCMF_E_CHANNEL_ADOPTED 63
234#define BRCMF_E_AP_STARTED 64
235#define BRCMF_E_DFS_AP_STOP 65
236#define BRCMF_E_DFS_AP_RESUME 66
237#define BRCMF_E_RESERVED1 67
238#define BRCMF_E_RESERVED2 68
239#define BRCMF_E_ESCAN_RESULT 69
240#define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70
241#define BRCMF_E_DCS_REQUEST 73
242
243#define BRCMF_E_FIFO_CREDIT_MAP 74
244
245#define BRCMF_E_LAST 75
246
247#define BRCMF_E_STATUS_SUCCESS 0
248#define BRCMF_E_STATUS_FAIL 1
249#define BRCMF_E_STATUS_TIMEOUT 2
250#define BRCMF_E_STATUS_NO_NETWORKS 3
251#define BRCMF_E_STATUS_ABORT 4
252#define BRCMF_E_STATUS_NO_ACK 5
253#define BRCMF_E_STATUS_UNSOLICITED 6
254#define BRCMF_E_STATUS_ATTEMPT 7
255#define BRCMF_E_STATUS_PARTIAL 8
256#define BRCMF_E_STATUS_NEWSCAN 9
257#define BRCMF_E_STATUS_NEWASSOC 10
258#define BRCMF_E_STATUS_11HQUIET 11
259#define BRCMF_E_STATUS_SUPPRESS 12
260#define BRCMF_E_STATUS_NOCHANS 13
261#define BRCMF_E_STATUS_CS_ABORT 15
262#define BRCMF_E_STATUS_ERROR 16
263
264#define BRCMF_E_REASON_INITIAL_ASSOC 0
265#define BRCMF_E_REASON_LOW_RSSI 1
266#define BRCMF_E_REASON_DEAUTH 2
267#define BRCMF_E_REASON_DISASSOC 3
268#define BRCMF_E_REASON_BCNS_LOST 4
269#define BRCMF_E_REASON_MINTXRATE 9
270#define BRCMF_E_REASON_TXFAIL 10
271
272#define BRCMF_E_REASON_FAST_ROAM_FAILED 5
273#define BRCMF_E_REASON_DIRECTED_ROAM 6
274#define BRCMF_E_REASON_TSPEC_REJECTED 7
275#define BRCMF_E_REASON_BETTER_AP 8
276
277#define BRCMF_E_PRUNE_ENCR_MISMATCH 1
278#define BRCMF_E_PRUNE_BCAST_BSSID 2
279#define BRCMF_E_PRUNE_MAC_DENY 3
280#define BRCMF_E_PRUNE_MAC_NA 4
281#define BRCMF_E_PRUNE_REG_PASSV 5
282#define BRCMF_E_PRUNE_SPCT_MGMT 6
283#define BRCMF_E_PRUNE_RADAR 7
284#define BRCMF_E_RSN_MISMATCH 8
285#define BRCMF_E_PRUNE_NO_COMMON_RATES 9
286#define BRCMF_E_PRUNE_BASIC_RATES 10
287#define BRCMF_E_PRUNE_CIPHER_NA 12
288#define BRCMF_E_PRUNE_KNOWN_STA 13
289#define BRCMF_E_PRUNE_WDS_PEER 15
290#define BRCMF_E_PRUNE_QBSS_LOAD 16
291#define BRCMF_E_PRUNE_HOME_AP 17
292
293#define BRCMF_E_SUP_OTHER 0
294#define BRCMF_E_SUP_DECRYPT_KEY_DATA 1
295#define BRCMF_E_SUP_BAD_UCAST_WEP128 2
296#define BRCMF_E_SUP_BAD_UCAST_WEP40 3
297#define BRCMF_E_SUP_UNSUP_KEY_LEN 4
298#define BRCMF_E_SUP_PW_KEY_CIPHER 5
299#define BRCMF_E_SUP_MSG3_TOO_MANY_IE 6
300#define BRCMF_E_SUP_MSG3_IE_MISMATCH 7
301#define BRCMF_E_SUP_NO_INSTALL_FLAG 8
302#define BRCMF_E_SUP_MSG3_NO_GTK 9
303#define BRCMF_E_SUP_GRP_KEY_CIPHER 10
304#define BRCMF_E_SUP_GRP_MSG1_NO_GTK 11
305#define BRCMF_E_SUP_GTK_DECRYPT_FAIL 12
306#define BRCMF_E_SUP_SEND_FAIL 13
307#define BRCMF_E_SUP_DEAUTH 14
308
309#define BRCMF_E_IF_ADD 1
310#define BRCMF_E_IF_DEL 2
311#define BRCMF_E_IF_CHANGE 3
312
313#define BRCMF_E_IF_ROLE_STA 0
314#define BRCMF_E_IF_ROLE_AP 1
315#define BRCMF_E_IF_ROLE_WDS 2
316
317#define BRCMF_E_LINK_BCN_LOSS 1
318#define BRCMF_E_LINK_DISASSOC 2
319#define BRCMF_E_LINK_ASSOC_REC 3
320#define BRCMF_E_LINK_BSSCFG_DIS 4
321
322/* The level of bus communication with the dongle */
323enum brcmf_bus_state {
324 BRCMF_BUS_DOWN, /* Not ready for frame transfers */
325 BRCMF_BUS_LOAD, /* Download access only (CPU reset) */
326 BRCMF_BUS_DATA /* Ready for frame transfers */
327};
328
329/* Pattern matching filter. Specifies an offset within received packets to
330 * start matching, the pattern to match, the size of the pattern, and a bitmask
331 * that indicates which bits within the pattern should be matched.
332 */
333struct brcmf_pkt_filter_pattern_le {
334 /*
335 * Offset within received packet to start pattern matching.
336 * Offset '0' is the first byte of the ethernet header.
337 */
338 __le32 offset;
339 /* Size of the pattern. Bitmask must be the same size.*/
340 __le32 size_bytes;
341 /*
342 * Variable length mask and pattern data. mask starts at offset 0.
343 * Pattern immediately follows mask.
344 */
345 u8 mask_and_pattern[1];
346};
347
348/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
349struct brcmf_pkt_filter_le {
350 __le32 id; /* Unique filter id, specified by app. */
351 __le32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
352 __le32 negate_match; /* Negate the result of filter matches */
353 union { /* Filter definitions */
354 struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */
355 } u;
356};
357
358/* IOVAR "pkt_filter_enable" parameter. */
359struct brcmf_pkt_filter_enable_le {
360 __le32 id; /* Unique filter id */
361 __le32 enable; /* Enable/disable bool */
362};
363
364/* BSS info structure
365 * Applications MUST CHECK ie_offset field and length field to access IEs and
366 * next bss_info structure in a vector (in struct brcmf_scan_results)
367 */
368struct brcmf_bss_info {
369 __le32 version; /* version field */
370 __le32 length; /* byte length of data in this record,
371 * starting at version and including IEs
372 */
373 u8 BSSID[ETH_ALEN];
374 __le16 beacon_period; /* units are Kusec */
375 __le16 capability; /* Capability information */
376 u8 SSID_len;
377 u8 SSID[32];
378 struct {
379 __le32 count; /* # rates in this set */
380 u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
381 } rateset; /* supported rates */
382 __le16 chanspec; /* chanspec for bss */
383 __le16 atim_window; /* units are Kusec */
384 u8 dtim_period; /* DTIM period */
385 __le16 RSSI; /* receive signal strength (in dBm) */
386 s8 phy_noise; /* noise (in dBm) */
387
388 u8 n_cap; /* BSS is 802.11N Capable */
389 /* 802.11N BSS Capabilities (based on HT_CAP_*): */
390 __le32 nbss_cap;
391 u8 ctl_ch; /* 802.11N BSS control channel number */
392 __le32 reserved32[1]; /* Reserved for expansion of BSS properties */
393 u8 flags; /* flags */
394 u8 reserved[3]; /* Reserved for expansion of BSS properties */
395 u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
396
397 __le16 ie_offset; /* offset at which IEs start, from beginning */
398 __le32 ie_length; /* byte length of Information Elements */
399 __le16 SNR; /* average SNR of during frame reception */
400 /* Add new fields here */
401 /* variable length Information Elements */
402};
403
404struct brcm_rateset_le {
405 /* # rates in this set */
406 __le32 count;
407 /* rates in 500kbps units w/hi bit set if basic */
408 u8 rates[WL_NUMRATES];
409};
410
411struct brcmf_ssid {
412 u32 SSID_len;
413 unsigned char SSID[32];
414};
415
416struct brcmf_ssid_le {
417 __le32 SSID_len;
418 unsigned char SSID[32];
419};
420
421struct brcmf_scan_params_le {
422 struct brcmf_ssid_le ssid_le; /* default: {0, ""} */
423 u8 bssid[ETH_ALEN]; /* default: bcast */
424 s8 bss_type; /* default: any,
425 * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
426 */
427 u8 scan_type; /* flags, 0 use default */
428 __le32 nprobes; /* -1 use default, number of probes per channel */
429 __le32 active_time; /* -1 use default, dwell time per channel for
430 * active scanning
431 */
432 __le32 passive_time; /* -1 use default, dwell time per channel
433 * for passive scanning
434 */
435 __le32 home_time; /* -1 use default, dwell time for the
436 * home channel between channel scans
437 */
438 __le32 channel_num; /* count of channels and ssids that follow
439 *
440 * low half is count of channels in
441 * channel_list, 0 means default (use all
442 * available channels)
443 *
444 * high half is entries in struct brcmf_ssid
445 * array that follows channel_list, aligned for
446 * s32 (4 bytes) meaning an odd channel count
447 * implies a 2-byte pad between end of
448 * channel_list and first ssid
449 *
450 * if ssid count is zero, single ssid in the
451 * fixed parameter portion is assumed, otherwise
452 * ssid in the fixed portion is ignored
453 */
454 __le16 channel_list[1]; /* list of chanspecs */
455};
456
457/* incremental scan struct */
458struct brcmf_iscan_params_le {
459 __le32 version;
460 __le16 action;
461 __le16 scan_duration;
462 struct brcmf_scan_params_le params_le;
463};
464
465struct brcmf_scan_results {
466 u32 buflen;
467 u32 version;
468 u32 count;
469 struct brcmf_bss_info bss_info[1];
470};
471
472struct brcmf_scan_results_le {
473 __le32 buflen;
474 __le32 version;
475 __le32 count;
476 struct brcmf_bss_info bss_info[1];
477};
478
479/* used for association with a specific BSSID and chanspec list */
480struct brcmf_assoc_params_le {
481 /* 00:00:00:00:00:00: broadcast scan */
482 u8 bssid[ETH_ALEN];
483 /* 0: all available channels, otherwise count of chanspecs in
484 * chanspec_list */
485 __le32 chanspec_num;
486 /* list of chanspecs */
487 __le16 chanspec_list[1];
488};
489
490/* used for join with or without a specific bssid and channel list */
491struct brcmf_join_params {
492 struct brcmf_ssid_le ssid_le;
493 struct brcmf_assoc_params_le params_le;
494};
495
496/* size of brcmf_scan_results not including variable length array */
497#define BRCMF_SCAN_RESULTS_FIXED_SIZE \
498 (sizeof(struct brcmf_scan_results) - sizeof(struct brcmf_bss_info))
499
500/* incremental scan results struct */
501struct brcmf_iscan_results {
502 union {
503 u32 status;
504 __le32 status_le;
505 };
506 union {
507 struct brcmf_scan_results results;
508 struct brcmf_scan_results_le results_le;
509 };
510};
511
512/* size of brcmf_iscan_results not including variable length array */
513#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \
514 (BRCMF_SCAN_RESULTS_FIXED_SIZE + \
515 offsetof(struct brcmf_iscan_results, results))
516
517struct brcmf_wsec_key {
518 u32 index; /* key index */
519 u32 len; /* key length */
520 u8 data[WLAN_MAX_KEY_LEN]; /* key data */
521 u32 pad_1[18];
522 u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
523 u32 flags; /* misc flags */
524 u32 pad_2[3];
525 u32 iv_initialized; /* has IV been initialized already? */
526 u32 pad_3;
527 /* Rx IV */
528 struct {
529 u32 hi; /* upper 32 bits of IV */
530 u16 lo; /* lower 16 bits of IV */
531 } rxiv;
532 u32 pad_4[2];
533 u8 ea[ETH_ALEN]; /* per station */
534};
535
536/*
537 * dongle requires same struct as above but with fields in little endian order
538 */
539struct brcmf_wsec_key_le {
540 __le32 index; /* key index */
541 __le32 len; /* key length */
542 u8 data[WLAN_MAX_KEY_LEN]; /* key data */
543 __le32 pad_1[18];
544 __le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
545 __le32 flags; /* misc flags */
546 __le32 pad_2[3];
547 __le32 iv_initialized; /* has IV been initialized already? */
548 __le32 pad_3;
549 /* Rx IV */
550 struct {
551 __le32 hi; /* upper 32 bits of IV */
552 __le16 lo; /* lower 16 bits of IV */
553 } rxiv;
554 __le32 pad_4[2];
555 u8 ea[ETH_ALEN]; /* per station */
556};
557
558/* Used to get specific STA parameters */
559struct brcmf_scb_val_le {
560 __le32 val;
561 u8 ea[ETH_ALEN];
562};
563
564/* channel encoding */
565struct brcmf_channel_info_le {
566 __le32 hw_channel;
567 __le32 target_channel;
568 __le32 scan_channel;
569};
570
571/* Bus independent dongle command */
572struct brcmf_dcmd {
573 uint cmd; /* common dongle cmd definition */
574 void *buf; /* pointer to user buffer */
575 uint len; /* length of user buffer */
576 u8 set; /* get or set request (optional) */
577 uint used; /* bytes read or written (optional) */
578 uint needed; /* bytes needed (optional) */
579};
580
581/* Forward decls for struct brcmf_pub (see below) */
582struct brcmf_bus; /* device bus info */
583struct brcmf_proto; /* device communication protocol info */
584struct brcmf_info; /* device driver info */
585struct brcmf_cfg80211_dev; /* cfg80211 device info */
586
587/* Common structure for module and instance linkage */
588struct brcmf_pub {
589 /* Linkage ponters */
590 struct brcmf_bus *bus;
591 struct brcmf_proto *prot;
592 struct brcmf_info *info;
593 struct brcmf_cfg80211_dev *config;
594
595 /* Internal brcmf items */
596 bool up; /* Driver up/down (to OS) */
597 bool txoff; /* Transmit flow-controlled */
598 enum brcmf_bus_state busstate;
599 uint hdrlen; /* Total BRCMF header length (proto + bus) */
600 uint maxctl; /* Max size rxctl request from proto to bus */
601 uint rxsz; /* Rx buffer size bus module should use */
602 u8 wme_dp; /* wme discard priority */
603
604 /* Dongle media info */
605 bool iswl; /* Dongle-resident driver is wl */
606 unsigned long drv_version; /* Version of dongle-resident driver */
607 u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */
608 struct dngl_stats dstats; /* Stats for dongle-based data */
609
610 /* Additional stats for the bus level */
611
612 /* Data packets sent to dongle */
613 unsigned long tx_packets;
614 /* Multicast data packets sent to dongle */
615 unsigned long tx_multicast;
616 /* Errors in sending data to dongle */
617 unsigned long tx_errors;
618 /* Control packets sent to dongle */
619 unsigned long tx_ctlpkts;
620 /* Errors sending control frames to dongle */
621 unsigned long tx_ctlerrs;
622 /* Packets sent up the network interface */
623 unsigned long rx_packets;
624 /* Multicast packets sent up the network interface */
625 unsigned long rx_multicast;
626 /* Errors processing rx data packets */
627 unsigned long rx_errors;
628 /* Control frames processed from dongle */
629 unsigned long rx_ctlpkts;
630
631 /* Errors in processing rx control frames */
632 unsigned long rx_ctlerrs;
633 /* Packets dropped locally (no memory) */
634 unsigned long rx_dropped;
635 /* Packets flushed due to unscheduled sendup thread */
636 unsigned long rx_flushed;
637 /* Number of times dpc scheduled by watchdog timer */
638 unsigned long wd_dpc_sched;
639
640 /* Number of packets where header read-ahead was used. */
641 unsigned long rx_readahead_cnt;
642 /* Number of tx packets we had to realloc for headroom */
643 unsigned long tx_realloc;
644 /* Number of flow control pkts recvd */
645 unsigned long fc_packets;
646
647 /* Last error return */
648 int bcmerror;
649 uint tickcnt;
650
651 /* Last error from dongle */
652 int dongle_error;
653
654 /* Suspend disable flag flag */
655 int suspend_disable_flag; /* "1" to disable all extra powersaving
656 during suspend */
657 int in_suspend; /* flag set to 1 when early suspend called */
658 int dtim_skip; /* dtim skip , default 0 means wake each dtim */
659
660 /* Pkt filter defination */
661 char *pktfilter[100];
662 int pktfilter_count;
663
664 u8 country_code[BRCM_CNTRY_BUF_SZ];
665 char eventmask[BRCMF_EVENTING_MASK_LEN];
666
667};
668
669struct brcmf_if_event {
670 u8 ifidx;
671 u8 action;
672 u8 flags;
673 u8 bssidx;
674};
675
676struct bcmevent_name {
677 uint event;
678 const char *name;
679};
680
681extern const struct bcmevent_name bcmevent_names[];
682
683extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
684 char *buf, uint len);
685
686/* Indication from bus module regarding presence/insertion of dongle.
687 * Return struct brcmf_pub pointer, used as handle to OS module in later calls.
688 * Returned structure should have bus and prot pointers filled in.
689 * bus_hdrlen specifies required headroom for bus module header.
690 */
691extern struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus,
692 uint bus_hdrlen);
693extern int brcmf_net_attach(struct brcmf_pub *drvr, int idx);
694extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
695
696extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len);
697
698/* Indication from bus module regarding removal/absence of dongle */
699extern void brcmf_detach(struct brcmf_pub *drvr);
700
701/* Indication from bus module to change flow-control state */
702extern void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool on);
703
704extern bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q,
705 struct sk_buff *pkt, int prec);
706
707/* Receive frame for delivery to OS. Callee disposes of rxp. */
708extern void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx,
709 struct sk_buff *rxp, int numpkt);
710
711/* Return pointer to interface name */
712extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
713
714/* Notify tx completion */
715extern void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp,
716 bool success);
717
718/* Query dongle */
719extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx,
720 uint cmd, void *buf, uint len);
721
722/* OS independent layer functions */
723extern int brcmf_os_proto_block(struct brcmf_pub *drvr);
724extern int brcmf_os_proto_unblock(struct brcmf_pub *drvr);
725#ifdef BCMDBG
726extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size);
727#endif /* BCMDBG */
728
729extern int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name);
730extern int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *idx,
731 void *pktdata, struct brcmf_event_msg *,
732 void **data_ptr);
733
734extern void brcmf_c_init(void);
735
736extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx,
737 struct net_device *ndev, char *name, u8 *mac_addr,
738 u32 flags, u8 bssidx);
739extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx);
740
741/* Send packet to dongle via data channel */
742extern int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx,\
743 struct sk_buff *pkt);
744
745extern int brcmf_bus_start(struct brcmf_pub *drvr);
746
747extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg);
748extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg,
749 int enable, int master_mode);
750
751#define BRCMF_DCMD_SMLEN 256 /* "small" cmd buffer required */
752#define BRCMF_DCMD_MEDLEN 1536 /* "med" cmd buffer required */
753#define BRCMF_DCMD_MAXLEN 8192 /* max length cmd buffer required */
754
755/* message levels */
756#define BRCMF_ERROR_VAL 0x0001
757#define BRCMF_TRACE_VAL 0x0002
758#define BRCMF_INFO_VAL 0x0004
759#define BRCMF_DATA_VAL 0x0008
760#define BRCMF_CTL_VAL 0x0010
761#define BRCMF_TIMER_VAL 0x0020
762#define BRCMF_HDRS_VAL 0x0040
763#define BRCMF_BYTES_VAL 0x0080
764#define BRCMF_INTR_VAL 0x0100
765#define BRCMF_GLOM_VAL 0x0400
766#define BRCMF_EVENT_VAL 0x0800
767#define BRCMF_BTA_VAL 0x1000
768#define BRCMF_ISCAN_VAL 0x2000
769
770/* Enter idle immediately (no timeout) */
771#define BRCMF_IDLE_IMMEDIATE (-1)
772#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change
773 when idle */
774#define BRCMF_IDLE_INTERVAL 1
775
776#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 000000000000..a249407c9a1b
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCMF_BUS_H_
18#define _BRCMF_BUS_H_
19
20/* Packet alignment for most efficient SDIO (can change based on platform) */
21#define BRCMF_SDALIGN (1 << 6)
22
23/* watchdog polling interval in ms */
24#define BRCMF_WD_POLL_MS 10
25
26/*
27 * Exported from brcmf bus module (brcmf_usb, brcmf_sdio)
28 */
29
30/* Indicate (dis)interest in finding dongles. */
31extern int brcmf_bus_register(void);
32extern void brcmf_bus_unregister(void);
33
34/* obtain linux device object providing bus function */
35extern struct device *brcmf_bus_get_device(struct brcmf_bus *bus);
36
37/* Stop bus module: clear pending frames, disable data flow */
38extern void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus);
39
40/* Initialize bus module: prepare for communication w/dongle */
41extern int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr);
42
43/* Send a data frame to the dongle. Callee disposes of txp. */
44extern int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *txp);
45
46/* Send/receive a control message to/from the dongle.
47 * Expects caller to enforce a single outstanding transaction.
48 */
49extern int
50brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
51
52extern int
53brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
54
55extern void brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick);
56
57#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 000000000000..e34c5c3d1d55
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
@@ -0,0 +1,498 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/*******************************************************************************
18 * Communicates with the dongle by using dcmd codes.
19 * For certain dcmd codes, the dongle interprets string data from the host.
20 ******************************************************************************/
21
22#include <linux/types.h>
23#include <linux/netdevice.h>
24#include <linux/sched.h>
25#include <defs.h>
26
27#include <brcmu_utils.h>
28#include <brcmu_wifi.h>
29
30#include "dhd.h"
31#include "dhd_proto.h"
32#include "dhd_bus.h"
33#include "dhd_dbg.h"
34
35struct brcmf_proto_cdc_dcmd {
36 __le32 cmd; /* dongle command value */
37 __le32 len; /* lower 16: output buflen;
38 * upper 16: input buflen (excludes header) */
39 __le32 flags; /* flag defns given below */
40 __le32 status; /* status code returned from the device */
41};
42
43/* Max valid buffer size that can be sent to the dongle */
44#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)
45
46/* CDC flag definitions */
47#define CDC_DCMD_ERROR 0x01 /* 1=cmd failed */
48#define CDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */
49#define CDC_DCMD_IF_MASK 0xF000 /* I/F index */
50#define CDC_DCMD_IF_SHIFT 12
51#define CDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */
52#define CDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */
53#define CDC_DCMD_ID(flags) \
54 (((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT)
55
56/*
57 * BDC header - Broadcom specific extension of CDC.
58 * Used on data packets to convey priority across USB.
59 */
60#define BDC_HEADER_LEN 4
61#define BDC_PROTO_VER 1 /* Protocol version */
62#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
63#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
64#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */
65#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */
66#define BDC_PRIORITY_MASK 0x7
67#define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */
68#define BDC_FLAG2_IF_SHIFT 0
69
70#define BDC_GET_IF_IDX(hdr) \
71 ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
72#define BDC_SET_IF_IDX(hdr, idx) \
73 ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
74 ((idx) << BDC_FLAG2_IF_SHIFT)))
75
76struct brcmf_proto_bdc_header {
77 u8 flags;
78 u8 priority; /* 802.1d Priority, 4:7 flow control info for usb */
79 u8 flags2;
80 u8 rssi;
81};
82
83
84#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
85#define BUS_HEADER_LEN (16+BRCMF_SDALIGN) /* Must be atleast SDPCM_RESERVE
86 * (amount of header tha might be added)
87 * plus any space that might be needed
88 * for alignment padding.
89 */
90#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for
91 * round off at the end of buffer
92 */
93
94struct brcmf_proto {
95 u16 reqid;
96 u8 pending;
97 u32 lastcmd;
98 u8 bus_header[BUS_HEADER_LEN];
99 struct brcmf_proto_cdc_dcmd msg;
100 unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
101};
102
103static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
104{
105 struct brcmf_proto *prot = drvr->prot;
106 int len = le32_to_cpu(prot->msg.len) +
107 sizeof(struct brcmf_proto_cdc_dcmd);
108
109 brcmf_dbg(TRACE, "Enter\n");
110
111 /* NOTE : cdc->msg.len holds the desired length of the buffer to be
112 * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
113 * is actually sent to the dongle
114 */
115 if (len > CDC_MAX_MSG_SIZE)
116 len = CDC_MAX_MSG_SIZE;
117
118 /* Send request */
119 return brcmf_sdbrcm_bus_txctl(drvr->bus, (unsigned char *)&prot->msg,
120 len);
121}
122
123static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
124{
125 int ret;
126 struct brcmf_proto *prot = drvr->prot;
127
128 brcmf_dbg(TRACE, "Enter\n");
129
130 do {
131 ret = brcmf_sdbrcm_bus_rxctl(drvr->bus,
132 (unsigned char *)&prot->msg,
133 len + sizeof(struct brcmf_proto_cdc_dcmd));
134 if (ret < 0)
135 break;
136 } while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id);
137
138 return ret;
139}
140
141int
142brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
143 void *buf, uint len)
144{
145 struct brcmf_proto *prot = drvr->prot;
146 struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
147 void *info;
148 int ret = 0, retries = 0;
149 u32 id, flags;
150
151 brcmf_dbg(TRACE, "Enter\n");
152 brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
153
154 /* Respond "bcmerror" and "bcmerrorstr" with local cache */
155 if (cmd == BRCMF_C_GET_VAR && buf) {
156 if (!strcmp((char *)buf, "bcmerrorstr")) {
157 strncpy((char *)buf, "bcm_error",
158 BCME_STRLEN);
159 goto done;
160 } else if (!strcmp((char *)buf, "bcmerror")) {
161 *(int *)buf = drvr->dongle_error;
162 goto done;
163 }
164 }
165
166 memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
167
168 msg->cmd = cpu_to_le32(cmd);
169 msg->len = cpu_to_le32(len);
170 flags = (++prot->reqid << CDC_DCMD_ID_SHIFT);
171 flags = (flags & ~CDC_DCMD_IF_MASK) |
172 (ifidx << CDC_DCMD_IF_SHIFT);
173 msg->flags = cpu_to_le32(flags);
174
175 if (buf)
176 memcpy(prot->buf, buf, len);
177
178 ret = brcmf_proto_cdc_msg(drvr);
179 if (ret < 0) {
180 brcmf_dbg(ERROR, "brcmf_proto_cdc_msg failed w/status %d\n",
181 ret);
182 goto done;
183 }
184
185retry:
186 /* wait for interrupt and get first fragment */
187 ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
188 if (ret < 0)
189 goto done;
190
191 flags = le32_to_cpu(msg->flags);
192 id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
193
194 if ((id < prot->reqid) && (++retries < RETRIES))
195 goto retry;
196 if (id != prot->reqid) {
197 brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
198 brcmf_ifname(drvr, ifidx), id, prot->reqid);
199 ret = -EINVAL;
200 goto done;
201 }
202
203 /* Check info buffer */
204 info = (void *)&msg[1];
205
206 /* Copy info buffer */
207 if (buf) {
208 if (ret < (int)len)
209 len = ret;
210 memcpy(buf, info, len);
211 }
212
213 /* Check the ERROR flag */
214 if (flags & CDC_DCMD_ERROR) {
215 ret = le32_to_cpu(msg->status);
216 /* Cache error from dongle */
217 drvr->dongle_error = ret;
218 }
219
220done:
221 return ret;
222}
223
224int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
225 void *buf, uint len)
226{
227 struct brcmf_proto *prot = drvr->prot;
228 struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
229 int ret = 0;
230 u32 flags, id;
231
232 brcmf_dbg(TRACE, "Enter\n");
233 brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
234
235 memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
236
237 msg->cmd = cpu_to_le32(cmd);
238 msg->len = cpu_to_le32(len);
239 flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET;
240 flags = (flags & ~CDC_DCMD_IF_MASK) |
241 (ifidx << CDC_DCMD_IF_SHIFT);
242 msg->flags = cpu_to_le32(flags);
243
244 if (buf)
245 memcpy(prot->buf, buf, len);
246
247 ret = brcmf_proto_cdc_msg(drvr);
248 if (ret < 0)
249 goto done;
250
251 ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
252 if (ret < 0)
253 goto done;
254
255 flags = le32_to_cpu(msg->flags);
256 id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
257
258 if (id != prot->reqid) {
259 brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
260 brcmf_ifname(drvr, ifidx), id, prot->reqid);
261 ret = -EINVAL;
262 goto done;
263 }
264
265 /* Check the ERROR flag */
266 if (flags & CDC_DCMD_ERROR) {
267 ret = le32_to_cpu(msg->status);
268 /* Cache error from dongle */
269 drvr->dongle_error = ret;
270 }
271
272done:
273 return ret;
274}
275
276int
277brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd,
278 int len)
279{
280 struct brcmf_proto *prot = drvr->prot;
281 int ret = -1;
282
283 if (drvr->busstate == BRCMF_BUS_DOWN) {
284 brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n");
285 return ret;
286 }
287 brcmf_os_proto_block(drvr);
288
289 brcmf_dbg(TRACE, "Enter\n");
290
291 if (len > BRCMF_DCMD_MAXLEN)
292 goto done;
293
294 if (prot->pending == true) {
295 brcmf_dbg(TRACE, "CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n",
296 dcmd->cmd, (unsigned long)dcmd->cmd, prot->lastcmd,
297 (unsigned long)prot->lastcmd);
298 if (dcmd->cmd == BRCMF_C_SET_VAR ||
299 dcmd->cmd == BRCMF_C_GET_VAR)
300 brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)dcmd->buf);
301
302 goto done;
303 }
304
305 prot->pending = true;
306 prot->lastcmd = dcmd->cmd;
307 if (dcmd->set)
308 ret = brcmf_proto_cdc_set_dcmd(drvr, ifidx, dcmd->cmd,
309 dcmd->buf, len);
310 else {
311 ret = brcmf_proto_cdc_query_dcmd(drvr, ifidx, dcmd->cmd,
312 dcmd->buf, len);
313 if (ret > 0)
314 dcmd->used = ret -
315 sizeof(struct brcmf_proto_cdc_dcmd);
316 }
317
318 if (ret >= 0)
319 ret = 0;
320 else {
321 struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
322 /* len == needed when set/query fails from dongle */
323 dcmd->needed = le32_to_cpu(msg->len);
324 }
325
326 /* Intercept the wme_dp dongle cmd here */
327 if (!ret && dcmd->cmd == BRCMF_C_SET_VAR &&
328 !strcmp(dcmd->buf, "wme_dp")) {
329 int slen;
330 __le32 val = 0;
331
332 slen = strlen("wme_dp") + 1;
333 if (len >= (int)(slen + sizeof(int)))
334 memcpy(&val, (char *)dcmd->buf + slen, sizeof(int));
335 drvr->wme_dp = (u8) le32_to_cpu(val);
336 }
337
338 prot->pending = false;
339
340done:
341 brcmf_os_proto_unblock(drvr);
342
343 return ret;
344}
345
346static bool pkt_sum_needed(struct sk_buff *skb)
347{
348 return skb->ip_summed == CHECKSUM_PARTIAL;
349}
350
351static void pkt_set_sum_good(struct sk_buff *skb, bool x)
352{
353 skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
354}
355
356void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
357 struct sk_buff *pktbuf)
358{
359 struct brcmf_proto_bdc_header *h;
360
361 brcmf_dbg(TRACE, "Enter\n");
362
363 /* Push BDC header used to convey priority for buses that don't */
364
365 skb_push(pktbuf, BDC_HEADER_LEN);
366
367 h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
368
369 h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
370 if (pkt_sum_needed(pktbuf))
371 h->flags |= BDC_FLAG_SUM_NEEDED;
372
373 h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
374 h->flags2 = 0;
375 h->rssi = 0;
376 BDC_SET_IF_IDX(h, ifidx);
377}
378
379int brcmf_proto_hdrpull(struct brcmf_pub *drvr, int *ifidx,
380 struct sk_buff *pktbuf)
381{
382 struct brcmf_proto_bdc_header *h;
383
384 brcmf_dbg(TRACE, "Enter\n");
385
386 /* Pop BDC header used to convey priority for buses that don't */
387
388 if (pktbuf->len < BDC_HEADER_LEN) {
389 brcmf_dbg(ERROR, "rx data too short (%d < %d)\n",
390 pktbuf->len, BDC_HEADER_LEN);
391 return -EBADE;
392 }
393
394 h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
395
396 *ifidx = BDC_GET_IF_IDX(h);
397 if (*ifidx >= BRCMF_MAX_IFS) {
398 brcmf_dbg(ERROR, "rx data ifnum out of range (%d)\n", *ifidx);
399 return -EBADE;
400 }
401
402 if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
403 BDC_PROTO_VER) {
404 brcmf_dbg(ERROR, "%s: non-BDC packet received, flags 0x%x\n",
405 brcmf_ifname(drvr, *ifidx), h->flags);
406 return -EBADE;
407 }
408
409 if (h->flags & BDC_FLAG_SUM_GOOD) {
410 brcmf_dbg(INFO, "%s: BDC packet received with good rx-csum, flags 0x%x\n",
411 brcmf_ifname(drvr, *ifidx), h->flags);
412 pkt_set_sum_good(pktbuf, true);
413 }
414
415 pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
416
417 skb_pull(pktbuf, BDC_HEADER_LEN);
418
419 return 0;
420}
421
422int brcmf_proto_attach(struct brcmf_pub *drvr)
423{
424 struct brcmf_proto *cdc;
425
426 cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
427 if (!cdc)
428 goto fail;
429
430 /* ensure that the msg buf directly follows the cdc msg struct */
431 if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
432 brcmf_dbg(ERROR, "struct brcmf_proto is not correctly defined\n");
433 goto fail;
434 }
435
436 drvr->prot = cdc;
437 drvr->hdrlen += BDC_HEADER_LEN;
438 drvr->maxctl = BRCMF_DCMD_MAXLEN +
439 sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;
440 return 0;
441
442fail:
443 kfree(cdc);
444 return -ENOMEM;
445}
446
447/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */
448void brcmf_proto_detach(struct brcmf_pub *drvr)
449{
450 kfree(drvr->prot);
451 drvr->prot = NULL;
452}
453
454void brcmf_proto_dstats(struct brcmf_pub *drvr)
455{
456 /* No stats from dongle added yet, copy bus stats */
457 drvr->dstats.tx_packets = drvr->tx_packets;
458 drvr->dstats.tx_errors = drvr->tx_errors;
459 drvr->dstats.rx_packets = drvr->rx_packets;
460 drvr->dstats.rx_errors = drvr->rx_errors;
461 drvr->dstats.rx_dropped = drvr->rx_dropped;
462 drvr->dstats.multicast = drvr->rx_multicast;
463 return;
464}
465
466int brcmf_proto_init(struct brcmf_pub *drvr)
467{
468 int ret = 0;
469 char buf[128];
470
471 brcmf_dbg(TRACE, "Enter\n");
472
473 brcmf_os_proto_block(drvr);
474
475 /* Get the device MAC address */
476 strcpy(buf, "cur_etheraddr");
477 ret = brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR,
478 buf, sizeof(buf));
479 if (ret < 0) {
480 brcmf_os_proto_unblock(drvr);
481 return ret;
482 }
483 memcpy(drvr->mac, buf, ETH_ALEN);
484
485 brcmf_os_proto_unblock(drvr);
486
487 ret = brcmf_c_preinit_dcmds(drvr);
488
489 /* Always assumes wl for now */
490 drvr->iswl = true;
491
492 return ret;
493}
494
495void brcmf_proto_stop(struct brcmf_pub *drvr)
496{
497 /* Nothing to do for CDC */
498}
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 000000000000..891826197f96
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -0,0 +1,895 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/kernel.h>
17#include <linux/string.h>
18#include <linux/sched.h>
19#include <linux/netdevice.h>
20#include <asm/unaligned.h>
21#include <defs.h>
22#include <brcmu_wifi.h>
23#include <brcmu_utils.h>
24#include "dhd.h"
25#include "dhd_bus.h"
26#include "dhd_proto.h"
27#include "dhd_dbg.h"
28
29#define BRCM_OUI "\x00\x10\x18"
30#define DOT11_OUI_LEN 3
31#define BCMILCP_BCM_SUBTYPE_EVENT 1
32#define PKTFILTER_BUF_SIZE 2048
33#define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */
34
35int brcmf_msg_level;
36
37#define MSGTRACE_VERSION 1
38
39#define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter_le, u)
40#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \
41 offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern)
42
43#ifdef BCMDBG
44static const char brcmf_version[] =
45 "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on "
46 __DATE__ " at " __TIME__;
47#else
48static const char brcmf_version[] =
49 "Dongle Host Driver, version " BRCMF_VERSION_STR;
50#endif
51
52/* Message trace header */
53struct msgtrace_hdr {
54 u8 version;
55 u8 spare;
56 __be16 len; /* Len of the trace */
57 __be32 seqnum; /* Sequence number of message. Useful
58 * if the messsage has been lost
59 * because of DMA error or a bus reset
60 * (ex: SDIO Func2)
61 */
62 __be32 discarded_bytes; /* Number of discarded bytes because of
63 trace overflow */
64 __be32 discarded_printf; /* Number of discarded printf
65 because of trace overflow */
66} __packed;
67
68
69uint
70brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
71{
72 uint len;
73
74 len = strlen(name) + 1;
75
76 if ((len + datalen) > buflen)
77 return 0;
78
79 strncpy(buf, name, buflen);
80
81 /* append data onto the end of the name string */
82 memcpy(&buf[len], data, datalen);
83 len += datalen;
84
85 return len;
86}
87
88void brcmf_c_init(void)
89{
90 /* Init global variables at run-time, not as part of the declaration.
91 * This is required to support init/de-init of the driver.
92 * Initialization
93 * of globals as part of the declaration results in non-deterministic
94 * behaviour since the value of the globals may be different on the
95 * first time that the driver is initialized vs subsequent
96 * initializations.
97 */
98 brcmf_msg_level = BRCMF_ERROR_VAL;
99}
100
101bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q,
102 struct sk_buff *pkt, int prec)
103{
104 struct sk_buff *p;
105 int eprec = -1; /* precedence to evict from */
106 bool discard_oldest;
107
108 /* Fast case, precedence queue is not full and we are also not
109 * exceeding total queue length
110 */
111 if (!pktq_pfull(q, prec) && !pktq_full(q)) {
112 brcmu_pktq_penq(q, prec, pkt);
113 return true;
114 }
115
116 /* Determine precedence from which to evict packet, if any */
117 if (pktq_pfull(q, prec))
118 eprec = prec;
119 else if (pktq_full(q)) {
120 p = brcmu_pktq_peek_tail(q, &eprec);
121 if (eprec > prec)
122 return false;
123 }
124
125 /* Evict if needed */
126 if (eprec >= 0) {
127 /* Detect queueing to unconfigured precedence */
128 discard_oldest = ac_bitmap_tst(drvr->wme_dp, eprec);
129 if (eprec == prec && !discard_oldest)
130 return false; /* refuse newer (incoming) packet */
131 /* Evict packet according to discard policy */
132 p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
133 brcmu_pktq_pdeq_tail(q, eprec);
134 if (p == NULL)
135 brcmf_dbg(ERROR, "brcmu_pktq_penq() failed, oldest %d\n",
136 discard_oldest);
137
138 brcmu_pkt_buf_free_skb(p);
139 }
140
141 /* Enqueue */
142 p = brcmu_pktq_penq(q, prec, pkt);
143 if (p == NULL)
144 brcmf_dbg(ERROR, "brcmu_pktq_penq() failed\n");
145
146 return p != NULL;
147}
148
149#ifdef BCMDBG
150static void
151brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
152{
153 uint i, status, reason;
154 bool group = false, flush_txq = false, link = false;
155 char *auth_str, *event_name;
156 unsigned char *buf;
157 char err_msg[256], eabuf[ETHER_ADDR_STR_LEN];
158 static struct {
159 uint event;
160 char *event_name;
161 } event_names[] = {
162 {
163 BRCMF_E_SET_SSID, "SET_SSID"}, {
164 BRCMF_E_JOIN, "JOIN"}, {
165 BRCMF_E_START, "START"}, {
166 BRCMF_E_AUTH, "AUTH"}, {
167 BRCMF_E_AUTH_IND, "AUTH_IND"}, {
168 BRCMF_E_DEAUTH, "DEAUTH"}, {
169 BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, {
170 BRCMF_E_ASSOC, "ASSOC"}, {
171 BRCMF_E_ASSOC_IND, "ASSOC_IND"}, {
172 BRCMF_E_REASSOC, "REASSOC"}, {
173 BRCMF_E_REASSOC_IND, "REASSOC_IND"}, {
174 BRCMF_E_DISASSOC, "DISASSOC"}, {
175 BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, {
176 BRCMF_E_QUIET_START, "START_QUIET"}, {
177 BRCMF_E_QUIET_END, "END_QUIET"}, {
178 BRCMF_E_BEACON_RX, "BEACON_RX"}, {
179 BRCMF_E_LINK, "LINK"}, {
180 BRCMF_E_MIC_ERROR, "MIC_ERROR"}, {
181 BRCMF_E_NDIS_LINK, "NDIS_LINK"}, {
182 BRCMF_E_ROAM, "ROAM"}, {
183 BRCMF_E_TXFAIL, "TXFAIL"}, {
184 BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, {
185 BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, {
186 BRCMF_E_PRUNE, "PRUNE"}, {
187 BRCMF_E_AUTOAUTH, "AUTOAUTH"}, {
188 BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, {
189 BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
190 BRCMF_E_ADDTS_IND, "ADDTS_IND"}, {
191 BRCMF_E_DELTS_IND, "DELTS_IND"}, {
192 BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, {
193 BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, {
194 BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, {
195 BRCMF_E_ROAM_PREP, "ROAM_PREP"}, {
196 BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, {
197 BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, {
198 BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, {
199 BRCMF_E_JOIN_START, "JOIN_START"}, {
200 BRCMF_E_ROAM_START, "ROAM_START"}, {
201 BRCMF_E_ASSOC_START, "ASSOC_START"}, {
202 BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, {
203 BRCMF_E_RADIO, "RADIO"}, {
204 BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, {
205 BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, {
206 BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, {
207 BRCMF_E_PSK_SUP, "PSK_SUP"}, {
208 BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, {
209 BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, {
210 BRCMF_E_ICV_ERROR, "ICV_ERROR"}, {
211 BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, {
212 BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, {
213 BRCMF_E_TRACE, "TRACE"}, {
214 BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, {
215 BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {
216 BRCMF_E_IF, "IF"}, {
217 BRCMF_E_RSSI, "RSSI"}, {
218 BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}
219 };
220 uint event_type, flags, auth_type, datalen;
221 static u32 seqnum_prev;
222 struct msgtrace_hdr hdr;
223 u32 nblost;
224 char *s, *p;
225
226 event_type = be32_to_cpu(event->event_type);
227 flags = be16_to_cpu(event->flags);
228 status = be32_to_cpu(event->status);
229 reason = be32_to_cpu(event->reason);
230 auth_type = be32_to_cpu(event->auth_type);
231 datalen = be32_to_cpu(event->datalen);
232 /* debug dump of event messages */
233 sprintf(eabuf, "%pM", event->addr);
234
235 event_name = "UNKNOWN";
236 for (i = 0; i < ARRAY_SIZE(event_names); i++) {
237 if (event_names[i].event == event_type)
238 event_name = event_names[i].event_name;
239 }
240
241 brcmf_dbg(EVENT, "EVENT: %s, event ID = %d\n", event_name, event_type);
242 brcmf_dbg(EVENT, "flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n",
243 flags, status, reason, auth_type, eabuf);
244
245 if (flags & BRCMF_EVENT_MSG_LINK)
246 link = true;
247 if (flags & BRCMF_EVENT_MSG_GROUP)
248 group = true;
249 if (flags & BRCMF_EVENT_MSG_FLUSHTXQ)
250 flush_txq = true;
251
252 switch (event_type) {
253 case BRCMF_E_START:
254 case BRCMF_E_DEAUTH:
255 case BRCMF_E_DISASSOC:
256 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
257 break;
258
259 case BRCMF_E_ASSOC_IND:
260 case BRCMF_E_REASSOC_IND:
261 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
262 break;
263
264 case BRCMF_E_ASSOC:
265 case BRCMF_E_REASSOC:
266 if (status == BRCMF_E_STATUS_SUCCESS)
267 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, SUCCESS\n",
268 event_name, eabuf);
269 else if (status == BRCMF_E_STATUS_TIMEOUT)
270 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, TIMEOUT\n",
271 event_name, eabuf);
272 else if (status == BRCMF_E_STATUS_FAIL)
273 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, FAILURE, reason %d\n",
274 event_name, eabuf, (int)reason);
275 else
276 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, unexpected status %d\n",
277 event_name, eabuf, (int)status);
278 break;
279
280 case BRCMF_E_DEAUTH_IND:
281 case BRCMF_E_DISASSOC_IND:
282 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, reason %d\n",
283 event_name, eabuf, (int)reason);
284 break;
285
286 case BRCMF_E_AUTH:
287 case BRCMF_E_AUTH_IND:
288 if (auth_type == WLAN_AUTH_OPEN)
289 auth_str = "Open System";
290 else if (auth_type == WLAN_AUTH_SHARED_KEY)
291 auth_str = "Shared Key";
292 else {
293 sprintf(err_msg, "AUTH unknown: %d", (int)auth_type);
294 auth_str = err_msg;
295 }
296 if (event_type == BRCMF_E_AUTH_IND)
297 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s\n",
298 event_name, eabuf, auth_str);
299 else if (status == BRCMF_E_STATUS_SUCCESS)
300 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, SUCCESS\n",
301 event_name, eabuf, auth_str);
302 else if (status == BRCMF_E_STATUS_TIMEOUT)
303 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, TIMEOUT\n",
304 event_name, eabuf, auth_str);
305 else if (status == BRCMF_E_STATUS_FAIL) {
306 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n",
307 event_name, eabuf, auth_str, (int)reason);
308 }
309
310 break;
311
312 case BRCMF_E_JOIN:
313 case BRCMF_E_ROAM:
314 case BRCMF_E_SET_SSID:
315 if (status == BRCMF_E_STATUS_SUCCESS)
316 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n",
317 event_name, eabuf);
318 else if (status == BRCMF_E_STATUS_FAIL)
319 brcmf_dbg(EVENT, "MACEVENT: %s, failed\n", event_name);
320 else if (status == BRCMF_E_STATUS_NO_NETWORKS)
321 brcmf_dbg(EVENT, "MACEVENT: %s, no networks found\n",
322 event_name);
323 else
324 brcmf_dbg(EVENT, "MACEVENT: %s, unexpected status %d\n",
325 event_name, (int)status);
326 break;
327
328 case BRCMF_E_BEACON_RX:
329 if (status == BRCMF_E_STATUS_SUCCESS)
330 brcmf_dbg(EVENT, "MACEVENT: %s, SUCCESS\n", event_name);
331 else if (status == BRCMF_E_STATUS_FAIL)
332 brcmf_dbg(EVENT, "MACEVENT: %s, FAIL\n", event_name);
333 else
334 brcmf_dbg(EVENT, "MACEVENT: %s, status %d\n",
335 event_name, status);
336 break;
337
338 case BRCMF_E_LINK:
339 brcmf_dbg(EVENT, "MACEVENT: %s %s\n",
340 event_name, link ? "UP" : "DOWN");
341 break;
342
343 case BRCMF_E_MIC_ERROR:
344 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, Group %d, Flush %d\n",
345 event_name, eabuf, group, flush_txq);
346 break;
347
348 case BRCMF_E_ICV_ERROR:
349 case BRCMF_E_UNICAST_DECODE_ERROR:
350 case BRCMF_E_MULTICAST_DECODE_ERROR:
351 brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
352 break;
353
354 case BRCMF_E_TXFAIL:
355 brcmf_dbg(EVENT, "MACEVENT: %s, RA %s\n", event_name, eabuf);
356 break;
357
358 case BRCMF_E_SCAN_COMPLETE:
359 case BRCMF_E_PMKID_CACHE:
360 brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name);
361 break;
362
363 case BRCMF_E_PFN_NET_FOUND:
364 case BRCMF_E_PFN_NET_LOST:
365 case BRCMF_E_PFN_SCAN_COMPLETE:
366 brcmf_dbg(EVENT, "PNOEVENT: %s\n", event_name);
367 break;
368
369 case BRCMF_E_PSK_SUP:
370 case BRCMF_E_PRUNE:
371 brcmf_dbg(EVENT, "MACEVENT: %s, status %d, reason %d\n",
372 event_name, (int)status, (int)reason);
373 break;
374
375 case BRCMF_E_TRACE:
376 buf = (unsigned char *) event_data;
377 memcpy(&hdr, buf, sizeof(struct msgtrace_hdr));
378
379 if (hdr.version != MSGTRACE_VERSION) {
380 brcmf_dbg(ERROR,
381 "MACEVENT: %s [unsupported version --> brcmf"
382 " version:%d dongle version:%d]\n",
383 event_name, MSGTRACE_VERSION, hdr.version);
384 /* Reset datalen to avoid display below */
385 datalen = 0;
386 break;
387 }
388
389 /* There are 2 bytes available at the end of data */
390 *(buf + sizeof(struct msgtrace_hdr)
391 + be16_to_cpu(hdr.len)) = '\0';
392
393 if (be32_to_cpu(hdr.discarded_bytes)
394 || be32_to_cpu(hdr.discarded_printf))
395 brcmf_dbg(ERROR,
396 "WLC_E_TRACE: [Discarded traces in dongle -->"
397 " discarded_bytes %d discarded_printf %d]\n",
398 be32_to_cpu(hdr.discarded_bytes),
399 be32_to_cpu(hdr.discarded_printf));
400
401 nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1;
402 if (nblost > 0)
403 brcmf_dbg(ERROR, "WLC_E_TRACE: [Event lost --> seqnum "
404 " %d nblost %d\n", be32_to_cpu(hdr.seqnum),
405 nblost);
406 seqnum_prev = be32_to_cpu(hdr.seqnum);
407
408 /* Display the trace buffer. Advance from \n to \n to
409 * avoid display big
410 * printf (issue with Linux printk )
411 */
412 p = (char *)&buf[sizeof(struct msgtrace_hdr)];
413 while ((s = strstr(p, "\n")) != NULL) {
414 *s = '\0';
415 printk(KERN_DEBUG"%s\n", p);
416 p = s + 1;
417 }
418 printk(KERN_DEBUG "%s\n", p);
419
420 /* Reset datalen to avoid display below */
421 datalen = 0;
422 break;
423
424 case BRCMF_E_RSSI:
425 brcmf_dbg(EVENT, "MACEVENT: %s %d\n",
426 event_name, be32_to_cpu(*((__be32 *)event_data)));
427 break;
428
429 default:
430 brcmf_dbg(EVENT,
431 "MACEVENT: %s %d, MAC %s, status %d, reason %d, "
432 "auth %d\n", event_name, event_type, eabuf,
433 (int)status, (int)reason, (int)auth_type);
434 break;
435 }
436
437 /* show any appended data */
438 if (datalen) {
439 buf = (unsigned char *) event_data;
440 brcmf_dbg(EVENT, " data (%d) : ", datalen);
441 for (i = 0; i < datalen; i++)
442 brcmf_dbg(EVENT, " 0x%02x ", *buf++);
443 brcmf_dbg(EVENT, "\n");
444 }
445}
446#endif /* BCMDBG */
447
448int
449brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata,
450 struct brcmf_event_msg *event, void **data_ptr)
451{
452 /* check whether packet is a BRCM event pkt */
453 struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata;
454 struct brcmf_if_event *ifevent;
455 char *event_data;
456 u32 type, status;
457 u16 flags;
458 int evlen;
459
460 if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) {
461 brcmf_dbg(ERROR, "mismatched OUI, bailing\n");
462 return -EBADE;
463 }
464
465 /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */
466 if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) !=
467 BCMILCP_BCM_SUBTYPE_EVENT) {
468 brcmf_dbg(ERROR, "mismatched subtype, bailing\n");
469 return -EBADE;
470 }
471
472 *data_ptr = &pvt_data[1];
473 event_data = *data_ptr;
474
475 /* memcpy since BRCM event pkt may be unaligned. */
476 memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg));
477
478 type = get_unaligned_be32(&event->event_type);
479 flags = get_unaligned_be16(&event->flags);
480 status = get_unaligned_be32(&event->status);
481 evlen = get_unaligned_be32(&event->datalen) +
482 sizeof(struct brcmf_event);
483
484 switch (type) {
485 case BRCMF_E_IF:
486 ifevent = (struct brcmf_if_event *) event_data;
487 brcmf_dbg(TRACE, "if event\n");
488
489 if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) {
490 if (ifevent->action == BRCMF_E_IF_ADD)
491 brcmf_add_if(drvr_priv, ifevent->ifidx, NULL,
492 event->ifname,
493 pvt_data->eth.h_dest,
494 ifevent->flags, ifevent->bssidx);
495 else
496 brcmf_del_if(drvr_priv, ifevent->ifidx);
497 } else {
498 brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n",
499 ifevent->ifidx, event->ifname);
500 }
501
502 /* send up the if event: btamp user needs it */
503 *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname);
504 break;
505
506 /* These are what external supplicant/authenticator wants */
507 case BRCMF_E_LINK:
508 case BRCMF_E_ASSOC_IND:
509 case BRCMF_E_REASSOC_IND:
510 case BRCMF_E_DISASSOC_IND:
511 case BRCMF_E_MIC_ERROR:
512 default:
513 /* Fall through: this should get _everything_ */
514
515 *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname);
516 brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n",
517 type, flags, status);
518
519 /* put it back to BRCMF_E_NDIS_LINK */
520 if (type == BRCMF_E_NDIS_LINK) {
521 u32 temp1;
522 __be32 temp2;
523
524 temp1 = get_unaligned_be32(&event->event_type);
525 brcmf_dbg(TRACE, "Converted to WLC_E_LINK type %d\n",
526 temp1);
527
528 temp2 = cpu_to_be32(BRCMF_E_NDIS_LINK);
529 memcpy((void *)(&pvt_data->msg.event_type), &temp2,
530 sizeof(pvt_data->msg.event_type));
531 }
532 break;
533 }
534
535#ifdef BCMDBG
536 brcmf_c_show_host_event(event, event_data);
537#endif /* BCMDBG */
538
539 return 0;
540}
541
542/* Convert user's input in hex pattern to byte-size mask */
543static int brcmf_c_pattern_atoh(char *src, char *dst)
544{
545 int i;
546 if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
547 brcmf_dbg(ERROR, "Mask invalid format. Needs to start with 0x\n");
548 return -EINVAL;
549 }
550 src = src + 2; /* Skip past 0x */
551 if (strlen(src) % 2 != 0) {
552 brcmf_dbg(ERROR, "Mask invalid format. Length must be even.\n");
553 return -EINVAL;
554 }
555 for (i = 0; *src != '\0'; i++) {
556 unsigned long res;
557 char num[3];
558 strncpy(num, src, 2);
559 num[2] = '\0';
560 if (kstrtoul(num, 16, &res))
561 return -EINVAL;
562 dst[i] = (u8)res;
563 src += 2;
564 }
565 return i;
566}
567
568void
569brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable,
570 int master_mode)
571{
572 unsigned long res;
573 char *argv[8];
574 int i = 0;
575 const char *str;
576 int buf_len;
577 int str_len;
578 char *arg_save = NULL, *arg_org = NULL;
579 int rc;
580 char buf[128];
581 struct brcmf_pkt_filter_enable_le enable_parm;
582 struct brcmf_pkt_filter_enable_le *pkt_filterp;
583 __le32 mmode_le;
584
585 arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
586 if (!arg_save)
587 goto fail;
588
589 arg_org = arg_save;
590 memcpy(arg_save, arg, strlen(arg) + 1);
591
592 argv[i] = strsep(&arg_save, " ");
593
594 i = 0;
595 if (NULL == argv[i]) {
596 brcmf_dbg(ERROR, "No args provided\n");
597 goto fail;
598 }
599
600 str = "pkt_filter_enable";
601 str_len = strlen(str);
602 strncpy(buf, str, str_len);
603 buf[str_len] = '\0';
604 buf_len = str_len + 1;
605
606 pkt_filterp = (struct brcmf_pkt_filter_enable_le *) (buf + str_len + 1);
607
608 /* Parse packet filter id. */
609 enable_parm.id = 0;
610 if (!kstrtoul(argv[i], 0, &res))
611 enable_parm.id = cpu_to_le32((u32)res);
612
613 /* Parse enable/disable value. */
614 enable_parm.enable = cpu_to_le32(enable);
615
616 buf_len += sizeof(enable_parm);
617 memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm));
618
619 /* Enable/disable the specified filter. */
620 rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
621 rc = rc >= 0 ? 0 : rc;
622 if (rc)
623 brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
624 arg, rc);
625 else
626 brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);
627
628 /* Contorl the master mode */
629 mmode_le = cpu_to_le32(master_mode);
630 brcmf_c_mkiovar("pkt_filter_mode", (char *)&mmode_le, 4, buf,
631 sizeof(buf));
632 rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf,
633 sizeof(buf));
634 rc = rc >= 0 ? 0 : rc;
635 if (rc)
636 brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
637 arg, rc);
638
639fail:
640 kfree(arg_org);
641}
642
643void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
644{
645 const char *str;
646 struct brcmf_pkt_filter_le pkt_filter;
647 struct brcmf_pkt_filter_le *pkt_filterp;
648 unsigned long res;
649 int buf_len;
650 int str_len;
651 int rc;
652 u32 mask_size;
653 u32 pattern_size;
654 char *argv[8], *buf = NULL;
655 int i = 0;
656 char *arg_save = NULL, *arg_org = NULL;
657
658 arg_save = kstrdup(arg, GFP_ATOMIC);
659 if (!arg_save)
660 goto fail;
661
662 arg_org = arg_save;
663
664 buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC);
665 if (!buf)
666 goto fail;
667
668 argv[i] = strsep(&arg_save, " ");
669 while (argv[i++])
670 argv[i] = strsep(&arg_save, " ");
671
672 i = 0;
673 if (NULL == argv[i]) {
674 brcmf_dbg(ERROR, "No args provided\n");
675 goto fail;
676 }
677
678 str = "pkt_filter_add";
679 strcpy(buf, str);
680 str_len = strlen(str);
681 buf_len = str_len + 1;
682
683 pkt_filterp = (struct brcmf_pkt_filter_le *) (buf + str_len + 1);
684
685 /* Parse packet filter id. */
686 pkt_filter.id = 0;
687 if (!kstrtoul(argv[i], 0, &res))
688 pkt_filter.id = cpu_to_le32((u32)res);
689
690 if (NULL == argv[++i]) {
691 brcmf_dbg(ERROR, "Polarity not provided\n");
692 goto fail;
693 }
694
695 /* Parse filter polarity. */
696 pkt_filter.negate_match = 0;
697 if (!kstrtoul(argv[i], 0, &res))
698 pkt_filter.negate_match = cpu_to_le32((u32)res);
699
700 if (NULL == argv[++i]) {
701 brcmf_dbg(ERROR, "Filter type not provided\n");
702 goto fail;
703 }
704
705 /* Parse filter type. */
706 pkt_filter.type = 0;
707 if (!kstrtoul(argv[i], 0, &res))
708 pkt_filter.type = cpu_to_le32((u32)res);
709
710 if (NULL == argv[++i]) {
711 brcmf_dbg(ERROR, "Offset not provided\n");
712 goto fail;
713 }
714
715 /* Parse pattern filter offset. */
716 pkt_filter.u.pattern.offset = 0;
717 if (!kstrtoul(argv[i], 0, &res))
718 pkt_filter.u.pattern.offset = cpu_to_le32((u32)res);
719
720 if (NULL == argv[++i]) {
721 brcmf_dbg(ERROR, "Bitmask not provided\n");
722 goto fail;
723 }
724
725 /* Parse pattern filter mask. */
726 mask_size =
727 brcmf_c_pattern_atoh
728 (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern);
729
730 if (NULL == argv[++i]) {
731 brcmf_dbg(ERROR, "Pattern not provided\n");
732 goto fail;
733 }
734
735 /* Parse pattern filter pattern. */
736 pattern_size =
737 brcmf_c_pattern_atoh(argv[i],
738 (char *)&pkt_filterp->u.pattern.
739 mask_and_pattern[mask_size]);
740
741 if (mask_size != pattern_size) {
742 brcmf_dbg(ERROR, "Mask and pattern not the same size\n");
743 goto fail;
744 }
745
746 pkt_filter.u.pattern.size_bytes = cpu_to_le32(mask_size);
747 buf_len += BRCMF_PKT_FILTER_FIXED_LEN;
748 buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
749
750 /* Keep-alive attributes are set in local
751 * variable (keep_alive_pkt), and
752 ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
753 ** guarantee that the buffer is properly aligned.
754 */
755 memcpy((char *)pkt_filterp,
756 &pkt_filter,
757 BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN);
758
759 rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
760 rc = rc >= 0 ? 0 : rc;
761
762 if (rc)
763 brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
764 arg, rc);
765 else
766 brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);
767
768fail:
769 kfree(arg_org);
770
771 kfree(buf);
772}
773
774static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode)
775{
776 char iovbuf[32];
777 int retcode;
778
779 brcmf_c_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
780 retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
781 iovbuf, sizeof(iovbuf));
782 retcode = retcode >= 0 ? 0 : retcode;
783 if (retcode)
784 brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, retcode = %d\n",
785 arp_mode, retcode);
786 else
787 brcmf_dbg(TRACE, "successfully set ARP offload mode to 0x%x\n",
788 arp_mode);
789}
790
791static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable)
792{
793 char iovbuf[32];
794 int retcode;
795
796 brcmf_c_mkiovar("arpoe", (char *)&arp_enable, 4,
797 iovbuf, sizeof(iovbuf));
798 retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
799 iovbuf, sizeof(iovbuf));
800 retcode = retcode >= 0 ? 0 : retcode;
801 if (retcode)
802 brcmf_dbg(TRACE, "failed to enable ARP offload to %d, retcode = %d\n",
803 arp_enable, retcode);
804 else
805 brcmf_dbg(TRACE, "successfully enabled ARP offload to %d\n",
806 arp_enable);
807}
808
809int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
810{
811 char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for
812 "event_msgs" + '\0' + bitvec */
813 uint up = 0;
814 char buf[128], *ptr;
815 u32 dongle_align = BRCMF_SDALIGN;
816 u32 glom = 0;
817 u32 roaming = 1;
818 uint bcn_timeout = 3;
819 int scan_assoc_time = 40;
820 int scan_unassoc_time = 40;
821 int i;
822
823 brcmf_os_proto_block(drvr);
824
825 /* Set Country code */
826 if (drvr->country_code[0] != 0) {
827 if (brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_COUNTRY,
828 drvr->country_code,
829 sizeof(drvr->country_code)) < 0)
830 brcmf_dbg(ERROR, "country code setting failed\n");
831 }
832
833 /* query for 'ver' to get version info from firmware */
834 memset(buf, 0, sizeof(buf));
835 ptr = buf;
836 brcmf_c_mkiovar("ver", NULL, 0, buf, sizeof(buf));
837 brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf));
838 strsep(&ptr, "\n");
839 /* Print fw version info */
840 brcmf_dbg(ERROR, "Firmware version = %s\n", buf);
841
842 /* Match Host and Dongle rx alignment */
843 brcmf_c_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
844 sizeof(iovbuf));
845 brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
846 sizeof(iovbuf));
847
848 /* disable glom option per default */
849 brcmf_c_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
850 brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
851 sizeof(iovbuf));
852
853 /* Setup timeout if Beacons are lost and roam is off to report
854 link down */
855 brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
856 sizeof(iovbuf));
857 brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
858 sizeof(iovbuf));
859
860 /* Enable/Disable build-in roaming to allowed ext supplicant to take
861 of romaing */
862 brcmf_c_mkiovar("roam_off", (char *)&roaming, 4,
863 iovbuf, sizeof(iovbuf));
864 brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
865 sizeof(iovbuf));
866
867 /* Force STA UP */
868 brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up));
869
870 /* Setup event_msgs */
871 brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
872 iovbuf, sizeof(iovbuf));
873 brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
874 sizeof(iovbuf));
875
876 brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME,
877 (char *)&scan_assoc_time, sizeof(scan_assoc_time));
878 brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME,
879 (char *)&scan_unassoc_time, sizeof(scan_unassoc_time));
880
881 /* Set and enable ARP offload feature */
882 brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE);
883 brcmf_c_arp_offload_enable(drvr, true);
884
885 /* Set up pkt filter */
886 for (i = 0; i < drvr->pktfilter_count; i++) {
887 brcmf_c_pktfilter_offload_set(drvr, drvr->pktfilter[i]);
888 brcmf_c_pktfilter_offload_enable(drvr, drvr->pktfilter[i],
889 0, true);
890 }
891
892 brcmf_os_proto_unblock(drvr);
893
894 return 0;
895}
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 000000000000..7467922f0536
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCMF_DBG_H_
18#define _BRCMF_DBG_H_
19
20#if defined(BCMDBG)
21
22#define brcmf_dbg(level, fmt, ...) \
23do { \
24 if (BRCMF_ERROR_VAL == BRCMF_##level##_VAL) { \
25 if (brcmf_msg_level & BRCMF_##level##_VAL) { \
26 if (net_ratelimit()) \
27 printk(KERN_DEBUG "%s: " fmt, \
28 __func__, ##__VA_ARGS__); \
29 } \
30 } else { \
31 if (brcmf_msg_level & BRCMF_##level##_VAL) { \
32 printk(KERN_DEBUG "%s: " fmt, \
33 __func__, ##__VA_ARGS__); \
34 } \
35 } \
36} while (0)
37
38#define BRCMF_DATA_ON() (brcmf_msg_level & BRCMF_DATA_VAL)
39#define BRCMF_CTL_ON() (brcmf_msg_level & BRCMF_CTL_VAL)
40#define BRCMF_HDRS_ON() (brcmf_msg_level & BRCMF_HDRS_VAL)
41#define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL)
42#define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL)
43
44#else /* (defined BCMDBG) || (defined BCMDBG) */
45
46#define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
47
48#define BRCMF_DATA_ON() 0
49#define BRCMF_CTL_ON() 0
50#define BRCMF_HDRS_ON() 0
51#define BRCMF_BYTES_ON() 0
52#define BRCMF_GLOM_ON() 0
53
54#endif /* defined(BCMDBG) */
55
56extern int brcmf_msg_level;
57
58#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 000000000000..4acbac5a74c6
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -0,0 +1,1356 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/kthread.h>
20#include <linux/slab.h>
21#include <linux/skbuff.h>
22#include <linux/netdevice.h>
23#include <linux/etherdevice.h>
24#include <linux/mmc/sdio_func.h>
25#include <linux/random.h>
26#include <linux/spinlock.h>
27#include <linux/ethtool.h>
28#include <linux/fcntl.h>
29#include <linux/fs.h>
30#include <linux/uaccess.h>
31#include <linux/hardirq.h>
32#include <linux/mutex.h>
33#include <linux/wait.h>
34#include <linux/module.h>
35#include <net/cfg80211.h>
36#include <net/rtnetlink.h>
37#include <defs.h>
38#include <brcmu_utils.h>
39#include <brcmu_wifi.h>
40
41#include "dhd.h"
42#include "dhd_bus.h"
43#include "dhd_proto.h"
44#include "dhd_dbg.h"
45#include "wl_cfg80211.h"
46#include "bcmchip.h"
47
48MODULE_AUTHOR("Broadcom Corporation");
49MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver.");
50MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards");
51MODULE_LICENSE("Dual BSD/GPL");
52
53
54/* Interface control information */
55struct brcmf_if {
56 struct brcmf_info *info; /* back pointer to brcmf_info */
57 /* OS/stack specifics */
58 struct net_device *ndev;
59 struct net_device_stats stats;
60 int idx; /* iface idx in dongle */
61 int state; /* interface state */
62 u8 mac_addr[ETH_ALEN]; /* assigned MAC address */
63};
64
65/* Local private structure (extension of pub) */
66struct brcmf_info {
67 struct brcmf_pub pub;
68
69 /* OS/stack specifics */
70 struct brcmf_if *iflist[BRCMF_MAX_IFS];
71
72 struct mutex proto_block;
73
74 struct work_struct setmacaddr_work;
75 struct work_struct multicast_work;
76 u8 macvalue[ETH_ALEN];
77 atomic_t pend_8021x_cnt;
78};
79
80/* Error bits */
81module_param(brcmf_msg_level, int, 0);
82
83
84static int brcmf_net2idx(struct brcmf_info *drvr_priv, struct net_device *ndev)
85{
86 int i = 0;
87
88 while (i < BRCMF_MAX_IFS) {
89 if (drvr_priv->iflist[i] && drvr_priv->iflist[i]->ndev == ndev)
90 return i;
91 i++;
92 }
93
94 return BRCMF_BAD_IF;
95}
96
97int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name)
98{
99 int i = BRCMF_MAX_IFS;
100 struct brcmf_if *ifp;
101
102 if (name == NULL || *name == '\0')
103 return 0;
104
105 while (--i > 0) {
106 ifp = drvr_priv->iflist[i];
107 if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ))
108 break;
109 }
110
111 brcmf_dbg(TRACE, "return idx %d for \"%s\"\n", i, name);
112
113 return i; /* default - the primary interface */
114}
115
116char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
117{
118 struct brcmf_info *drvr_priv = drvr->info;
119
120 if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
121 brcmf_dbg(ERROR, "ifidx %d out of range\n", ifidx);
122 return "<if_bad>";
123 }
124
125 if (drvr_priv->iflist[ifidx] == NULL) {
126 brcmf_dbg(ERROR, "null i/f %d\n", ifidx);
127 return "<if_null>";
128 }
129
130 if (drvr_priv->iflist[ifidx]->ndev)
131 return drvr_priv->iflist[ifidx]->ndev->name;
132
133 return "<if_none>";
134}
135
136static void _brcmf_set_multicast_list(struct work_struct *work)
137{
138 struct net_device *ndev;
139 struct netdev_hw_addr *ha;
140 u32 dcmd_value, cnt;
141 __le32 cnt_le;
142 __le32 dcmd_le_value;
143
144 struct brcmf_dcmd dcmd;
145 char *buf, *bufp;
146 uint buflen;
147 int ret;
148
149 struct brcmf_info *drvr_priv = container_of(work, struct brcmf_info,
150 multicast_work);
151
152 ndev = drvr_priv->iflist[0]->ndev;
153 cnt = netdev_mc_count(ndev);
154
155 /* Determine initial value of allmulti flag */
156 dcmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false;
157
158 /* Send down the multicast list first. */
159
160 buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN);
161 bufp = buf = kmalloc(buflen, GFP_ATOMIC);
162 if (!bufp)
163 return;
164
165 strcpy(bufp, "mcast_list");
166 bufp += strlen("mcast_list") + 1;
167
168 cnt_le = cpu_to_le32(cnt);
169 memcpy(bufp, &cnt_le, sizeof(cnt));
170 bufp += sizeof(cnt_le);
171
172 netdev_for_each_mc_addr(ha, ndev) {
173 if (!cnt)
174 break;
175 memcpy(bufp, ha->addr, ETH_ALEN);
176 bufp += ETH_ALEN;
177 cnt--;
178 }
179
180 memset(&dcmd, 0, sizeof(dcmd));
181 dcmd.cmd = BRCMF_C_SET_VAR;
182 dcmd.buf = buf;
183 dcmd.len = buflen;
184 dcmd.set = true;
185
186 ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len);
187 if (ret < 0) {
188 brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n",
189 brcmf_ifname(&drvr_priv->pub, 0), cnt);
190 dcmd_value = cnt ? true : dcmd_value;
191 }
192
193 kfree(buf);
194
195 /* Now send the allmulti setting. This is based on the setting in the
196 * net_device flags, but might be modified above to be turned on if we
197 * were trying to set some addresses and dongle rejected it...
198 */
199
200 buflen = sizeof("allmulti") + sizeof(dcmd_value);
201 buf = kmalloc(buflen, GFP_ATOMIC);
202 if (!buf)
203 return;
204
205 dcmd_le_value = cpu_to_le32(dcmd_value);
206
207 if (!brcmf_c_mkiovar
208 ("allmulti", (void *)&dcmd_le_value,
209 sizeof(dcmd_le_value), buf, buflen)) {
210 brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n",
211 brcmf_ifname(&drvr_priv->pub, 0),
212 (int)sizeof(dcmd_value), buflen);
213 kfree(buf);
214 return;
215 }
216
217 memset(&dcmd, 0, sizeof(dcmd));
218 dcmd.cmd = BRCMF_C_SET_VAR;
219 dcmd.buf = buf;
220 dcmd.len = buflen;
221 dcmd.set = true;
222
223 ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len);
224 if (ret < 0) {
225 brcmf_dbg(ERROR, "%s: set allmulti %d failed\n",
226 brcmf_ifname(&drvr_priv->pub, 0),
227 le32_to_cpu(dcmd_le_value));
228 }
229
230 kfree(buf);
231
232 /* Finally, pick up the PROMISC flag as well, like the NIC
233 driver does */
234
235 dcmd_value = (ndev->flags & IFF_PROMISC) ? true : false;
236 dcmd_le_value = cpu_to_le32(dcmd_value);
237
238 memset(&dcmd, 0, sizeof(dcmd));
239 dcmd.cmd = BRCMF_C_SET_PROMISC;
240 dcmd.buf = &dcmd_le_value;
241 dcmd.len = sizeof(dcmd_le_value);
242 dcmd.set = true;
243
244 ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len);
245 if (ret < 0) {
246 brcmf_dbg(ERROR, "%s: set promisc %d failed\n",
247 brcmf_ifname(&drvr_priv->pub, 0),
248 le32_to_cpu(dcmd_le_value));
249 }
250}
251
252static void
253_brcmf_set_mac_address(struct work_struct *work)
254{
255 char buf[32];
256 struct brcmf_dcmd dcmd;
257 int ret;
258
259 struct brcmf_info *drvr_priv = container_of(work, struct brcmf_info,
260 setmacaddr_work);
261
262 brcmf_dbg(TRACE, "enter\n");
263 if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr_priv->macvalue,
264 ETH_ALEN, buf, 32)) {
265 brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n",
266 brcmf_ifname(&drvr_priv->pub, 0));
267 return;
268 }
269 memset(&dcmd, 0, sizeof(dcmd));
270 dcmd.cmd = BRCMF_C_SET_VAR;
271 dcmd.buf = buf;
272 dcmd.len = 32;
273 dcmd.set = true;
274
275 ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len);
276 if (ret < 0)
277 brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n",
278 brcmf_ifname(&drvr_priv->pub, 0));
279 else
280 memcpy(drvr_priv->iflist[0]->ndev->dev_addr,
281 drvr_priv->macvalue, ETH_ALEN);
282
283 return;
284}
285
286static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
287{
288 struct brcmf_info *drvr_priv = *(struct brcmf_info **)
289 netdev_priv(ndev);
290 struct sockaddr *sa = (struct sockaddr *)addr;
291 int ifidx;
292
293 ifidx = brcmf_net2idx(drvr_priv, ndev);
294 if (ifidx == BRCMF_BAD_IF)
295 return -1;
296
297 memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN);
298 schedule_work(&drvr_priv->setmacaddr_work);
299 return 0;
300}
301
302static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
303{
304 struct brcmf_info *drvr_priv = *(struct brcmf_info **)
305 netdev_priv(ndev);
306 int ifidx;
307
308 ifidx = brcmf_net2idx(drvr_priv, ndev);
309 if (ifidx == BRCMF_BAD_IF)
310 return;
311
312 schedule_work(&drvr_priv->multicast_work);
313}
314
315int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf)
316{
317 struct brcmf_info *drvr_priv = drvr->info;
318
319 /* Reject if down */
320 if (!drvr->up || (drvr->busstate == BRCMF_BUS_DOWN))
321 return -ENODEV;
322
323 /* Update multicast statistic */
324 if (pktbuf->len >= ETH_ALEN) {
325 u8 *pktdata = (u8 *) (pktbuf->data);
326 struct ethhdr *eh = (struct ethhdr *)pktdata;
327
328 if (is_multicast_ether_addr(eh->h_dest))
329 drvr->tx_multicast++;
330 if (ntohs(eh->h_proto) == ETH_P_PAE)
331 atomic_inc(&drvr_priv->pend_8021x_cnt);
332 }
333
334 /* If the protocol uses a data header, apply it */
335 brcmf_proto_hdrpush(drvr, ifidx, pktbuf);
336
337 /* Use bus module to send data frame */
338 return brcmf_sdbrcm_bus_txdata(drvr->bus, pktbuf);
339}
340
341static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
342{
343 int ret;
344 struct brcmf_info *drvr_priv = *(struct brcmf_info **)
345 netdev_priv(ndev);
346 int ifidx;
347
348 brcmf_dbg(TRACE, "Enter\n");
349
350 /* Reject if down */
351 if (!drvr_priv->pub.up || (drvr_priv->pub.busstate == BRCMF_BUS_DOWN)) {
352 brcmf_dbg(ERROR, "xmit rejected pub.up=%d busstate=%d\n",
353 drvr_priv->pub.up, drvr_priv->pub.busstate);
354 netif_stop_queue(ndev);
355 return -ENODEV;
356 }
357
358 ifidx = brcmf_net2idx(drvr_priv, ndev);
359 if (ifidx == BRCMF_BAD_IF) {
360 brcmf_dbg(ERROR, "bad ifidx %d\n", ifidx);
361 netif_stop_queue(ndev);
362 return -ENODEV;
363 }
364
365 /* Make sure there's enough room for any header */
366 if (skb_headroom(skb) < drvr_priv->pub.hdrlen) {
367 struct sk_buff *skb2;
368
369 brcmf_dbg(INFO, "%s: insufficient headroom\n",
370 brcmf_ifname(&drvr_priv->pub, ifidx));
371 drvr_priv->pub.tx_realloc++;
372 skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen);
373 dev_kfree_skb(skb);
374 skb = skb2;
375 if (skb == NULL) {
376 brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n",
377 brcmf_ifname(&drvr_priv->pub, ifidx));
378 ret = -ENOMEM;
379 goto done;
380 }
381 }
382
383 ret = brcmf_sendpkt(&drvr_priv->pub, ifidx, skb);
384
385done:
386 if (ret)
387 drvr_priv->pub.dstats.tx_dropped++;
388 else
389 drvr_priv->pub.tx_packets++;
390
391 /* Return ok: we always eat the packet */
392 return 0;
393}
394
395void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool state)
396{
397 struct net_device *ndev;
398 struct brcmf_info *drvr_priv = drvr->info;
399
400 brcmf_dbg(TRACE, "Enter\n");
401
402 drvr->txoff = state;
403 ndev = drvr_priv->iflist[ifidx]->ndev;
404 if (state == ON)
405 netif_stop_queue(ndev);
406 else
407 netif_wake_queue(ndev);
408}
409
410static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx,
411 void *pktdata, struct brcmf_event_msg *event,
412 void **data)
413{
414 int bcmerror = 0;
415
416 bcmerror = brcmf_c_host_event(drvr_priv, ifidx, pktdata, event, data);
417 if (bcmerror != 0)
418 return bcmerror;
419
420 if (drvr_priv->iflist[*ifidx]->ndev)
421 brcmf_cfg80211_event(drvr_priv->iflist[*ifidx]->ndev,
422 event, *data);
423
424 return bcmerror;
425}
426
427void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *skb,
428 int numpkt)
429{
430 struct brcmf_info *drvr_priv = drvr->info;
431 unsigned char *eth;
432 uint len;
433 void *data;
434 struct sk_buff *pnext, *save_pktbuf;
435 int i;
436 struct brcmf_if *ifp;
437 struct brcmf_event_msg event;
438
439 brcmf_dbg(TRACE, "Enter\n");
440
441 save_pktbuf = skb;
442
443 for (i = 0; skb && i < numpkt; i++, skb = pnext) {
444
445 pnext = skb->next;
446 skb->next = NULL;
447
448 /* Get the protocol, maintain skb around eth_type_trans()
449 * The main reason for this hack is for the limitation of
450 * Linux 2.4 where 'eth_type_trans' uses the
451 * 'net->hard_header_len'
452 * to perform skb_pull inside vs ETH_HLEN. Since to avoid
453 * coping of the packet coming from the network stack to add
454 * BDC, Hardware header etc, during network interface
455 * registration
456 * we set the 'net->hard_header_len' to ETH_HLEN + extra space
457 * required
458 * for BDC, Hardware header etc. and not just the ETH_HLEN
459 */
460 eth = skb->data;
461 len = skb->len;
462
463 ifp = drvr_priv->iflist[ifidx];
464 if (ifp == NULL)
465 ifp = drvr_priv->iflist[0];
466
467 skb->dev = ifp->ndev;
468 skb->protocol = eth_type_trans(skb, skb->dev);
469
470 if (skb->pkt_type == PACKET_MULTICAST)
471 drvr_priv->pub.rx_multicast++;
472
473 skb->data = eth;
474 skb->len = len;
475
476 /* Strip header, count, deliver upward */
477 skb_pull(skb, ETH_HLEN);
478
479 /* Process special event packets and then discard them */
480 if (ntohs(skb->protocol) == ETH_P_LINK_CTL)
481 brcmf_host_event(drvr_priv, &ifidx,
482 skb_mac_header(skb),
483 &event, &data);
484
485 if (drvr_priv->iflist[ifidx] &&
486 !drvr_priv->iflist[ifidx]->state)
487 ifp = drvr_priv->iflist[ifidx];
488
489 if (ifp->ndev)
490 ifp->ndev->last_rx = jiffies;
491
492 drvr->dstats.rx_bytes += skb->len;
493 drvr->rx_packets++; /* Local count */
494
495 if (in_interrupt())
496 netif_rx(skb);
497 else
498 /* If the receive is not processed inside an ISR,
499 * the softirqd must be woken explicitly to service
500 * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled
501 * by netif_rx_ni(), but in earlier kernels, we need
502 * to do it manually.
503 */
504 netif_rx_ni(skb);
505 }
506}
507
508void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, bool success)
509{
510 uint ifidx;
511 struct brcmf_info *drvr_priv = drvr->info;
512 struct ethhdr *eh;
513 u16 type;
514
515 brcmf_proto_hdrpull(drvr, &ifidx, txp);
516
517 eh = (struct ethhdr *)(txp->data);
518 type = ntohs(eh->h_proto);
519
520 if (type == ETH_P_PAE)
521 atomic_dec(&drvr_priv->pend_8021x_cnt);
522
523}
524
525static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
526{
527 struct brcmf_info *drvr_priv = *(struct brcmf_info **)
528 netdev_priv(ndev);
529 struct brcmf_if *ifp;
530 int ifidx;
531
532 brcmf_dbg(TRACE, "Enter\n");
533
534 ifidx = brcmf_net2idx(drvr_priv, ndev);
535 if (ifidx == BRCMF_BAD_IF)
536 return NULL;
537
538 ifp = drvr_priv->iflist[ifidx];
539
540 if (drvr_priv->pub.up)
541 /* Use the protocol to get dongle stats */
542 brcmf_proto_dstats(&drvr_priv->pub);
543
544 /* Copy dongle stats to net device stats */
545 ifp->stats.rx_packets = drvr_priv->pub.dstats.rx_packets;
546 ifp->stats.tx_packets = drvr_priv->pub.dstats.tx_packets;
547 ifp->stats.rx_bytes = drvr_priv->pub.dstats.rx_bytes;
548 ifp->stats.tx_bytes = drvr_priv->pub.dstats.tx_bytes;
549 ifp->stats.rx_errors = drvr_priv->pub.dstats.rx_errors;
550 ifp->stats.tx_errors = drvr_priv->pub.dstats.tx_errors;
551 ifp->stats.rx_dropped = drvr_priv->pub.dstats.rx_dropped;
552 ifp->stats.tx_dropped = drvr_priv->pub.dstats.tx_dropped;
553 ifp->stats.multicast = drvr_priv->pub.dstats.multicast;
554
555 return &ifp->stats;
556}
557
558/* Retrieve current toe component enables, which are kept
559 as a bitmap in toe_ol iovar */
560static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol)
561{
562 struct brcmf_dcmd dcmd;
563 __le32 toe_le;
564 char buf[32];
565 int ret;
566
567 memset(&dcmd, 0, sizeof(dcmd));
568
569 dcmd.cmd = BRCMF_C_GET_VAR;
570 dcmd.buf = buf;
571 dcmd.len = (uint) sizeof(buf);
572 dcmd.set = false;
573
574 strcpy(buf, "toe_ol");
575 ret = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, dcmd.len);
576 if (ret < 0) {
577 /* Check for older dongle image that doesn't support toe_ol */
578 if (ret == -EIO) {
579 brcmf_dbg(ERROR, "%s: toe not supported by device\n",
580 brcmf_ifname(&drvr_priv->pub, ifidx));
581 return -EOPNOTSUPP;
582 }
583
584 brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n",
585 brcmf_ifname(&drvr_priv->pub, ifidx), ret);
586 return ret;
587 }
588
589 memcpy(&toe_le, buf, sizeof(u32));
590 *toe_ol = le32_to_cpu(toe_le);
591 return 0;
592}
593
594/* Set current toe component enables in toe_ol iovar,
595 and set toe global enable iovar */
596static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol)
597{
598 struct brcmf_dcmd dcmd;
599 char buf[32];
600 int ret;
601 __le32 toe_le = cpu_to_le32(toe_ol);
602
603 memset(&dcmd, 0, sizeof(dcmd));
604
605 dcmd.cmd = BRCMF_C_SET_VAR;
606 dcmd.buf = buf;
607 dcmd.len = (uint) sizeof(buf);
608 dcmd.set = true;
609
610 /* Set toe_ol as requested */
611 strcpy(buf, "toe_ol");
612 memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32));
613
614 ret = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, dcmd.len);
615 if (ret < 0) {
616 brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n",
617 brcmf_ifname(&drvr_priv->pub, ifidx), ret);
618 return ret;
619 }
620
621 /* Enable toe globally only if any components are enabled. */
622 toe_le = cpu_to_le32(toe_ol != 0);
623
624 strcpy(buf, "toe");
625 memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32));
626
627 ret = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, dcmd.len);
628 if (ret < 0) {
629 brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n",
630 brcmf_ifname(&drvr_priv->pub, ifidx), ret);
631 return ret;
632 }
633
634 return 0;
635}
636
637static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
638 struct ethtool_drvinfo *info)
639{
640 struct brcmf_info *drvr_priv = *(struct brcmf_info **)
641 netdev_priv(ndev);
642
643 sprintf(info->driver, KBUILD_MODNAME);
644 sprintf(info->version, "%lu", drvr_priv->pub.drv_version);
645 sprintf(info->fw_version, "%s", BCM4329_FW_NAME);
646 sprintf(info->bus_info, "%s",
647 dev_name(brcmf_bus_get_device(drvr_priv->pub.bus)));
648}
649
650static struct ethtool_ops brcmf_ethtool_ops = {
651 .get_drvinfo = brcmf_ethtool_get_drvinfo
652};
653
654static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr)
655{
656 struct ethtool_drvinfo info;
657 char drvname[sizeof(info.driver)];
658 u32 cmd;
659 struct ethtool_value edata;
660 u32 toe_cmpnt, csum_dir;
661 int ret;
662
663 brcmf_dbg(TRACE, "Enter\n");
664
665 /* all ethtool calls start with a cmd word */
666 if (copy_from_user(&cmd, uaddr, sizeof(u32)))
667 return -EFAULT;
668
669 switch (cmd) {
670 case ETHTOOL_GDRVINFO:
671 /* Copy out any request driver name */
672 if (copy_from_user(&info, uaddr, sizeof(info)))
673 return -EFAULT;
674 strncpy(drvname, info.driver, sizeof(info.driver));
675 drvname[sizeof(info.driver) - 1] = '\0';
676
677 /* clear struct for return */
678 memset(&info, 0, sizeof(info));
679 info.cmd = cmd;
680
681 /* if requested, identify ourselves */
682 if (strcmp(drvname, "?dhd") == 0) {
683 sprintf(info.driver, "dhd");
684 strcpy(info.version, BRCMF_VERSION_STR);
685 }
686
687 /* otherwise, require dongle to be up */
688 else if (!drvr_priv->pub.up) {
689 brcmf_dbg(ERROR, "dongle is not up\n");
690 return -ENODEV;
691 }
692
693 /* finally, report dongle driver type */
694 else if (drvr_priv->pub.iswl)
695 sprintf(info.driver, "wl");
696 else
697 sprintf(info.driver, "xx");
698
699 sprintf(info.version, "%lu", drvr_priv->pub.drv_version);
700 if (copy_to_user(uaddr, &info, sizeof(info)))
701 return -EFAULT;
702 brcmf_dbg(CTL, "given %*s, returning %s\n",
703 (int)sizeof(drvname), drvname, info.driver);
704 break;
705
706 /* Get toe offload components from dongle */
707 case ETHTOOL_GRXCSUM:
708 case ETHTOOL_GTXCSUM:
709 ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt);
710 if (ret < 0)
711 return ret;
712
713 csum_dir =
714 (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
715
716 edata.cmd = cmd;
717 edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
718
719 if (copy_to_user(uaddr, &edata, sizeof(edata)))
720 return -EFAULT;
721 break;
722
723 /* Set toe offload components in dongle */
724 case ETHTOOL_SRXCSUM:
725 case ETHTOOL_STXCSUM:
726 if (copy_from_user(&edata, uaddr, sizeof(edata)))
727 return -EFAULT;
728
729 /* Read the current settings, update and write back */
730 ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt);
731 if (ret < 0)
732 return ret;
733
734 csum_dir =
735 (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
736
737 if (edata.data != 0)
738 toe_cmpnt |= csum_dir;
739 else
740 toe_cmpnt &= ~csum_dir;
741
742 ret = brcmf_toe_set(drvr_priv, 0, toe_cmpnt);
743 if (ret < 0)
744 return ret;
745
746 /* If setting TX checksum mode, tell Linux the new mode */
747 if (cmd == ETHTOOL_STXCSUM) {
748 if (edata.data)
749 drvr_priv->iflist[0]->ndev->features |=
750 NETIF_F_IP_CSUM;
751 else
752 drvr_priv->iflist[0]->ndev->features &=
753 ~NETIF_F_IP_CSUM;
754 }
755
756 break;
757
758 default:
759 return -EOPNOTSUPP;
760 }
761
762 return 0;
763}
764
765static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
766 int cmd)
767{
768 struct brcmf_info *drvr_priv = *(struct brcmf_info **)
769 netdev_priv(ndev);
770 int ifidx;
771
772 ifidx = brcmf_net2idx(drvr_priv, ndev);
773 brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifidx, cmd);
774
775 if (ifidx == BRCMF_BAD_IF)
776 return -1;
777
778 if (cmd == SIOCETHTOOL)
779 return brcmf_ethtool(drvr_priv, ifr->ifr_data);
780
781 return -EOPNOTSUPP;
782}
783
784/* called only from within this driver. Sends a command to the dongle. */
785s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len)
786{
787 struct brcmf_dcmd dcmd;
788 s32 err = 0;
789 int buflen = 0;
790 bool is_set_key_cmd;
791 struct brcmf_info *drvr_priv = *(struct brcmf_info **)
792 netdev_priv(ndev);
793 int ifidx;
794
795 memset(&dcmd, 0, sizeof(dcmd));
796 dcmd.cmd = cmd;
797 dcmd.buf = arg;
798 dcmd.len = len;
799
800 ifidx = brcmf_net2idx(drvr_priv, ndev);
801
802 if (dcmd.buf != NULL)
803 buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN);
804
805 /* send to dongle (must be up, and wl) */
806 if ((drvr_priv->pub.busstate != BRCMF_BUS_DATA)) {
807 brcmf_dbg(ERROR, "DONGLE_DOWN\n");
808 err = -EIO;
809 goto done;
810 }
811
812 if (!drvr_priv->pub.iswl) {
813 err = -EIO;
814 goto done;
815 }
816
817 /*
818 * Intercept BRCMF_C_SET_KEY CMD - serialize M4 send and
819 * set key CMD to prevent M4 encryption.
820 */
821 is_set_key_cmd = ((dcmd.cmd == BRCMF_C_SET_KEY) ||
822 ((dcmd.cmd == BRCMF_C_SET_VAR) &&
823 !(strncmp("wsec_key", dcmd.buf, 9))) ||
824 ((dcmd.cmd == BRCMF_C_SET_VAR) &&
825 !(strncmp("bsscfg:wsec_key", dcmd.buf, 15))));
826 if (is_set_key_cmd)
827 brcmf_netdev_wait_pend8021x(ndev);
828
829 err = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, buflen);
830
831done:
832 if (err > 0)
833 err = 0;
834
835 return err;
836}
837
838static int brcmf_netdev_stop(struct net_device *ndev)
839{
840 struct brcmf_pub *drvr = *(struct brcmf_pub **) netdev_priv(ndev);
841
842 brcmf_dbg(TRACE, "Enter\n");
843 brcmf_cfg80211_down(drvr->config);
844 if (drvr->up == 0)
845 return 0;
846
847 /* Set state and stop OS transmissions */
848 drvr->up = 0;
849 netif_stop_queue(ndev);
850
851 return 0;
852}
853
854static int brcmf_netdev_open(struct net_device *ndev)
855{
856 struct brcmf_info *drvr_priv = *(struct brcmf_info **)
857 netdev_priv(ndev);
858 u32 toe_ol;
859 int ifidx = brcmf_net2idx(drvr_priv, ndev);
860 s32 ret = 0;
861
862 brcmf_dbg(TRACE, "ifidx %d\n", ifidx);
863
864 if (ifidx == 0) { /* do it only for primary eth0 */
865
866 /* try to bring up bus */
867 ret = brcmf_bus_start(&drvr_priv->pub);
868 if (ret != 0) {
869 brcmf_dbg(ERROR, "failed with code %d\n", ret);
870 return -1;
871 }
872 atomic_set(&drvr_priv->pend_8021x_cnt, 0);
873
874 memcpy(ndev->dev_addr, drvr_priv->pub.mac, ETH_ALEN);
875
876 /* Get current TOE mode from dongle */
877 if (brcmf_toe_get(drvr_priv, ifidx, &toe_ol) >= 0
878 && (toe_ol & TOE_TX_CSUM_OL) != 0)
879 drvr_priv->iflist[ifidx]->ndev->features |=
880 NETIF_F_IP_CSUM;
881 else
882 drvr_priv->iflist[ifidx]->ndev->features &=
883 ~NETIF_F_IP_CSUM;
884 }
885 /* Allow transmit calls */
886 netif_start_queue(ndev);
887 drvr_priv->pub.up = 1;
888 if (brcmf_cfg80211_up(drvr_priv->pub.config)) {
889 brcmf_dbg(ERROR, "failed to bring up cfg80211\n");
890 return -1;
891 }
892
893 return ret;
894}
895
896int
897brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, struct net_device *ndev,
898 char *name, u8 *mac_addr, u32 flags, u8 bssidx)
899{
900 struct brcmf_if *ifp;
901 int ret = 0, err = 0;
902
903 brcmf_dbg(TRACE, "idx %d, handle->%p\n", ifidx, ndev);
904
905 ifp = drvr_priv->iflist[ifidx];
906 if (!ifp) {
907 ifp = kmalloc(sizeof(struct brcmf_if), GFP_ATOMIC);
908 if (!ifp)
909 return -ENOMEM;
910 }
911
912 memset(ifp, 0, sizeof(struct brcmf_if));
913 ifp->info = drvr_priv;
914 drvr_priv->iflist[ifidx] = ifp;
915 if (mac_addr != NULL)
916 memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
917
918 if (ndev == NULL) {
919 ifp->state = BRCMF_E_IF_ADD;
920 ifp->idx = ifidx;
921 /*
922 * Delete the existing interface before overwriting it
923 * in case we missed the BRCMF_E_IF_DEL event.
924 */
925 if (ifp->ndev != NULL) {
926 brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n",
927 ifp->ndev->name);
928 netif_stop_queue(ifp->ndev);
929 unregister_netdev(ifp->ndev);
930 free_netdev(ifp->ndev);
931 }
932
933 /* Allocate netdev, including space for private structure */
934 ifp->ndev = alloc_netdev(sizeof(drvr_priv), "wlan%d",
935 ether_setup);
936 if (!ifp->ndev) {
937 brcmf_dbg(ERROR, "OOM - alloc_netdev\n");
938 ret = -ENOMEM;
939 }
940
941 if (ret == 0) {
942 memcpy(netdev_priv(ifp->ndev), &drvr_priv,
943 sizeof(drvr_priv));
944 err = brcmf_net_attach(&drvr_priv->pub, ifp->idx);
945 if (err != 0) {
946 brcmf_dbg(ERROR, "brcmf_net_attach failed, err %d\n",
947 err);
948 ret = -EOPNOTSUPP;
949 } else {
950 brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n",
951 current->pid, ifp->ndev->name);
952 ifp->state = 0;
953 }
954 }
955
956 if (ret < 0) {
957 if (ifp->ndev)
958 free_netdev(ifp->ndev);
959
960 drvr_priv->iflist[ifp->idx] = NULL;
961 kfree(ifp);
962 }
963 } else
964 ifp->ndev = ndev;
965
966 return 0;
967}
968
969void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx)
970{
971 struct brcmf_if *ifp;
972
973 brcmf_dbg(TRACE, "idx %d\n", ifidx);
974
975 ifp = drvr_priv->iflist[ifidx];
976 if (!ifp) {
977 brcmf_dbg(ERROR, "Null interface\n");
978 return;
979 }
980
981 ifp->state = BRCMF_E_IF_DEL;
982 ifp->idx = ifidx;
983 if (ifp->ndev != NULL) {
984 netif_stop_queue(ifp->ndev);
985 unregister_netdev(ifp->ndev);
986 free_netdev(ifp->ndev);
987 drvr_priv->iflist[ifidx] = NULL;
988 kfree(ifp);
989 }
990}
991
992struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen)
993{
994 struct brcmf_info *drvr_priv = NULL;
995 struct net_device *ndev;
996
997 brcmf_dbg(TRACE, "Enter\n");
998
999 /* Allocate netdev, including space for private structure */
1000 ndev = alloc_netdev(sizeof(drvr_priv), "wlan%d", ether_setup);
1001 if (!ndev) {
1002 brcmf_dbg(ERROR, "OOM - alloc_netdev\n");
1003 goto fail;
1004 }
1005
1006 /* Allocate primary brcmf_info */
1007 drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC);
1008 if (!drvr_priv)
1009 goto fail;
1010
1011 /*
1012 * Save the brcmf_info into the priv
1013 */
1014 memcpy(netdev_priv(ndev), &drvr_priv, sizeof(drvr_priv));
1015
1016 if (brcmf_add_if(drvr_priv, 0, ndev, ndev->name, NULL, 0, 0) ==
1017 BRCMF_BAD_IF)
1018 goto fail;
1019
1020 ndev->netdev_ops = NULL;
1021 mutex_init(&drvr_priv->proto_block);
1022
1023 /* Link to info module */
1024 drvr_priv->pub.info = drvr_priv;
1025
1026 /* Link to bus module */
1027 drvr_priv->pub.bus = bus;
1028 drvr_priv->pub.hdrlen = bus_hdrlen;
1029
1030 /* Attach and link in the protocol */
1031 if (brcmf_proto_attach(&drvr_priv->pub) != 0) {
1032 brcmf_dbg(ERROR, "brcmf_prot_attach failed\n");
1033 goto fail;
1034 }
1035
1036 /* Attach and link in the cfg80211 */
1037 drvr_priv->pub.config =
1038 brcmf_cfg80211_attach(ndev,
1039 brcmf_bus_get_device(bus),
1040 &drvr_priv->pub);
1041 if (drvr_priv->pub.config == NULL) {
1042 brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n");
1043 goto fail;
1044 }
1045
1046 INIT_WORK(&drvr_priv->setmacaddr_work, _brcmf_set_mac_address);
1047 INIT_WORK(&drvr_priv->multicast_work, _brcmf_set_multicast_list);
1048
1049 /*
1050 * Save the brcmf_info into the priv
1051 */
1052 memcpy(netdev_priv(ndev), &drvr_priv, sizeof(drvr_priv));
1053
1054 return &drvr_priv->pub;
1055
1056fail:
1057 if (ndev)
1058 free_netdev(ndev);
1059 if (drvr_priv)
1060 brcmf_detach(&drvr_priv->pub);
1061
1062 return NULL;
1063}
1064
1065int brcmf_bus_start(struct brcmf_pub *drvr)
1066{
1067 int ret = -1;
1068 struct brcmf_info *drvr_priv = drvr->info;
1069 /* Room for "event_msgs" + '\0' + bitvec */
1070 char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
1071
1072 brcmf_dbg(TRACE, "\n");
1073
1074 /* Bring up the bus */
1075 ret = brcmf_sdbrcm_bus_init(&drvr_priv->pub);
1076 if (ret != 0) {
1077 brcmf_dbg(ERROR, "brcmf_sdbrcm_bus_init failed %d\n", ret);
1078 return ret;
1079 }
1080
1081 /* If bus is not ready, can't come up */
1082 if (drvr_priv->pub.busstate != BRCMF_BUS_DATA) {
1083 brcmf_dbg(ERROR, "failed bus is not ready\n");
1084 return -ENODEV;
1085 }
1086
1087 brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
1088 iovbuf, sizeof(iovbuf));
1089 brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, iovbuf,
1090 sizeof(iovbuf));
1091 memcpy(drvr->eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
1092
1093 setbit(drvr->eventmask, BRCMF_E_SET_SSID);
1094 setbit(drvr->eventmask, BRCMF_E_PRUNE);
1095 setbit(drvr->eventmask, BRCMF_E_AUTH);
1096 setbit(drvr->eventmask, BRCMF_E_REASSOC);
1097 setbit(drvr->eventmask, BRCMF_E_REASSOC_IND);
1098 setbit(drvr->eventmask, BRCMF_E_DEAUTH_IND);
1099 setbit(drvr->eventmask, BRCMF_E_DISASSOC_IND);
1100 setbit(drvr->eventmask, BRCMF_E_DISASSOC);
1101 setbit(drvr->eventmask, BRCMF_E_JOIN);
1102 setbit(drvr->eventmask, BRCMF_E_ASSOC_IND);
1103 setbit(drvr->eventmask, BRCMF_E_PSK_SUP);
1104 setbit(drvr->eventmask, BRCMF_E_LINK);
1105 setbit(drvr->eventmask, BRCMF_E_NDIS_LINK);
1106 setbit(drvr->eventmask, BRCMF_E_MIC_ERROR);
1107 setbit(drvr->eventmask, BRCMF_E_PMKID_CACHE);
1108 setbit(drvr->eventmask, BRCMF_E_TXFAIL);
1109 setbit(drvr->eventmask, BRCMF_E_JOIN_START);
1110 setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE);
1111
1112/* enable dongle roaming event */
1113
1114 drvr->pktfilter_count = 1;
1115 /* Setup filter to allow only unicast */
1116 drvr->pktfilter[0] = "100 0 0 0 0x01 0x00";
1117
1118 /* Bus is ready, do any protocol initialization */
1119 ret = brcmf_proto_init(&drvr_priv->pub);
1120 if (ret < 0)
1121 return ret;
1122
1123 return 0;
1124}
1125
1126static struct net_device_ops brcmf_netdev_ops_pri = {
1127 .ndo_open = brcmf_netdev_open,
1128 .ndo_stop = brcmf_netdev_stop,
1129 .ndo_get_stats = brcmf_netdev_get_stats,
1130 .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
1131 .ndo_start_xmit = brcmf_netdev_start_xmit,
1132 .ndo_set_mac_address = brcmf_netdev_set_mac_address,
1133 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
1134};
1135
1136int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx)
1137{
1138 struct brcmf_info *drvr_priv = drvr->info;
1139 struct net_device *ndev;
1140 u8 temp_addr[ETH_ALEN] = {
1141 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33};
1142
1143 brcmf_dbg(TRACE, "ifidx %d\n", ifidx);
1144
1145 ndev = drvr_priv->iflist[ifidx]->ndev;
1146 ndev->netdev_ops = &brcmf_netdev_ops_pri;
1147
1148 /*
1149 * We have to use the primary MAC for virtual interfaces
1150 */
1151 if (ifidx != 0) {
1152 /* for virtual interfaces use the primary MAC */
1153 memcpy(temp_addr, drvr_priv->pub.mac, ETH_ALEN);
1154
1155 }
1156
1157 if (ifidx == 1) {
1158 brcmf_dbg(TRACE, "ACCESS POINT MAC:\n");
1159 /* ACCESSPOINT INTERFACE CASE */
1160 temp_addr[0] |= 0X02; /* set bit 2 ,
1161 - Locally Administered address */
1162
1163 }
1164 ndev->hard_header_len = ETH_HLEN + drvr_priv->pub.hdrlen;
1165 ndev->ethtool_ops = &brcmf_ethtool_ops;
1166
1167 drvr_priv->pub.rxsz = ndev->mtu + ndev->hard_header_len +
1168 drvr_priv->pub.hdrlen;
1169
1170 memcpy(ndev->dev_addr, temp_addr, ETH_ALEN);
1171
1172 if (register_netdev(ndev) != 0) {
1173 brcmf_dbg(ERROR, "couldn't register the net device\n");
1174 goto fail;
1175 }
1176
1177 brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
1178
1179 return 0;
1180
1181fail:
1182 ndev->netdev_ops = NULL;
1183 return -EBADE;
1184}
1185
1186static void brcmf_bus_detach(struct brcmf_pub *drvr)
1187{
1188 struct brcmf_info *drvr_priv;
1189
1190 brcmf_dbg(TRACE, "Enter\n");
1191
1192 if (drvr) {
1193 drvr_priv = drvr->info;
1194 if (drvr_priv) {
1195 /* Stop the protocol module */
1196 brcmf_proto_stop(&drvr_priv->pub);
1197
1198 /* Stop the bus module */
1199 brcmf_sdbrcm_bus_stop(drvr_priv->pub.bus);
1200 }
1201 }
1202}
1203
1204void brcmf_detach(struct brcmf_pub *drvr)
1205{
1206 struct brcmf_info *drvr_priv;
1207
1208 brcmf_dbg(TRACE, "Enter\n");
1209
1210 if (drvr) {
1211 drvr_priv = drvr->info;
1212 if (drvr_priv) {
1213 struct brcmf_if *ifp;
1214 int i;
1215
1216 for (i = 1; i < BRCMF_MAX_IFS; i++)
1217 if (drvr_priv->iflist[i])
1218 brcmf_del_if(drvr_priv, i);
1219
1220 ifp = drvr_priv->iflist[0];
1221 if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
1222 rtnl_lock();
1223 brcmf_netdev_stop(ifp->ndev);
1224 rtnl_unlock();
1225 unregister_netdev(ifp->ndev);
1226 }
1227
1228 cancel_work_sync(&drvr_priv->setmacaddr_work);
1229 cancel_work_sync(&drvr_priv->multicast_work);
1230
1231 brcmf_bus_detach(drvr);
1232
1233 if (drvr->prot)
1234 brcmf_proto_detach(drvr);
1235
1236 brcmf_cfg80211_detach(drvr->config);
1237
1238 free_netdev(ifp->ndev);
1239 kfree(ifp);
1240 kfree(drvr_priv);
1241 }
1242 }
1243}
1244
1245static void __exit brcmf_module_cleanup(void)
1246{
1247 brcmf_dbg(TRACE, "Enter\n");
1248
1249 brcmf_bus_unregister();
1250}
1251
1252static int __init brcmf_module_init(void)
1253{
1254 int error;
1255
1256 brcmf_dbg(TRACE, "Enter\n");
1257
1258 error = brcmf_bus_register();
1259
1260 if (error) {
1261 brcmf_dbg(ERROR, "brcmf_bus_register failed\n");
1262 goto failed;
1263 }
1264 return 0;
1265
1266failed:
1267 return -EINVAL;
1268}
1269
1270module_init(brcmf_module_init);
1271module_exit(brcmf_module_cleanup);
1272
1273int brcmf_os_proto_block(struct brcmf_pub *drvr)
1274{
1275 struct brcmf_info *drvr_priv = drvr->info;
1276
1277 if (drvr_priv) {
1278 mutex_lock(&drvr_priv->proto_block);
1279 return 1;
1280 }
1281 return 0;
1282}
1283
1284int brcmf_os_proto_unblock(struct brcmf_pub *drvr)
1285{
1286 struct brcmf_info *drvr_priv = drvr->info;
1287
1288 if (drvr_priv) {
1289 mutex_unlock(&drvr_priv->proto_block);
1290 return 1;
1291 }
1292
1293 return 0;
1294}
1295
1296static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv)
1297{
1298 return atomic_read(&drvr_priv->pend_8021x_cnt);
1299}
1300
1301#define MAX_WAIT_FOR_8021X_TX 10
1302
1303int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
1304{
1305 struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(ndev);
1306 int timeout = 10 * HZ / 1000;
1307 int ntimes = MAX_WAIT_FOR_8021X_TX;
1308 int pend = brcmf_get_pend_8021x_cnt(drvr_priv);
1309
1310 while (ntimes && pend) {
1311 if (pend) {
1312 set_current_state(TASK_INTERRUPTIBLE);
1313 schedule_timeout(timeout);
1314 set_current_state(TASK_RUNNING);
1315 ntimes--;
1316 }
1317 pend = brcmf_get_pend_8021x_cnt(drvr_priv);
1318 }
1319 return pend;
1320}
1321
1322#ifdef BCMDBG
1323int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size)
1324{
1325 int ret = 0;
1326 struct file *fp;
1327 mm_segment_t old_fs;
1328 loff_t pos = 0;
1329
1330 /* change to KERNEL_DS address limit */
1331 old_fs = get_fs();
1332 set_fs(KERNEL_DS);
1333
1334 /* open file to write */
1335 fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640);
1336 if (!fp) {
1337 brcmf_dbg(ERROR, "open file error\n");
1338 ret = -1;
1339 goto exit;
1340 }
1341
1342 /* Write buf to file */
1343 fp->f_op->write(fp, (char __user *)buf, size, &pos);
1344
1345exit:
1346 /* free buf before return */
1347 kfree(buf);
1348 /* close file before return */
1349 if (fp)
1350 filp_close(fp, current->files);
1351 /* restore previous address limit */
1352 set_fs(old_fs);
1353
1354 return ret;
1355}
1356#endif /* BCMDBG */
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 000000000000..4ee1ea846f6d
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
@@ -0,0 +1,60 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCMF_PROTO_H_
18#define _BRCMF_PROTO_H_
19
20/*
21 * Exported from the brcmf protocol module (brcmf_cdc)
22 */
23
24/* Linkage, sets prot link and updates hdrlen in pub */
25extern int brcmf_proto_attach(struct brcmf_pub *drvr);
26
27/* Unlink, frees allocated protocol memory (including brcmf_proto) */
28extern void brcmf_proto_detach(struct brcmf_pub *drvr);
29
30/* Initialize protocol: sync w/dongle state.
31 * Sets dongle media info (iswl, drv_version, mac address).
32 */
33extern int brcmf_proto_init(struct brcmf_pub *drvr);
34
35/* Stop protocol: sync w/dongle state. */
36extern void brcmf_proto_stop(struct brcmf_pub *drvr);
37
38/* Add any protocol-specific data header.
39 * Caller must reserve prot_hdrlen prepend space.
40 */
41extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx,
42 struct sk_buff *txp);
43
44/* Remove any protocol-specific data header. */
45extern int brcmf_proto_hdrpull(struct brcmf_pub *, int *ifidx,
46 struct sk_buff *rxp);
47
48/* Use protocol to issue command to dongle */
49extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx,
50 struct brcmf_dcmd *dcmd, int len);
51
52/* Update local copy of dongle statistics */
53extern void brcmf_proto_dstats(struct brcmf_pub *drvr);
54
55extern int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr);
56
57extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx,
58 uint cmd, void *buf, uint len);
59
60#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 000000000000..313b8bf592d1
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -0,0 +1,4591 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/types.h>
18#include <linux/kernel.h>
19#include <linux/kthread.h>
20#include <linux/printk.h>
21#include <linux/pci_ids.h>
22#include <linux/netdevice.h>
23#include <linux/interrupt.h>
24#include <linux/sched.h>
25#include <linux/mmc/sdio.h>
26#include <linux/mmc/sdio_func.h>
27#include <linux/mmc/card.h>
28#include <linux/semaphore.h>
29#include <linux/firmware.h>
30#include <linux/module.h>
31#include <asm/unaligned.h>
32#include <defs.h>
33#include <brcmu_wifi.h>
34#include <brcmu_utils.h>
35#include <brcm_hw_ids.h>
36#include <soc.h>
37#include "sdio_host.h"
38
39#define DCMD_RESP_TIMEOUT 2000 /* In milli second */
40
41#ifdef BCMDBG
42
43#define BRCMF_TRAP_INFO_SIZE 80
44
45#define CBUF_LEN (128)
46
47struct rte_log_le {
48 __le32 buf; /* Can't be pointer on (64-bit) hosts */
49 __le32 buf_size;
50 __le32 idx;
51 char *_buf_compat; /* Redundant pointer for backward compat. */
52};
53
54struct rte_console {
55 /* Virtual UART
56 * When there is no UART (e.g. Quickturn),
57 * the host should write a complete
58 * input line directly into cbuf and then write
59 * the length into vcons_in.
60 * This may also be used when there is a real UART
61 * (at risk of conflicting with
62 * the real UART). vcons_out is currently unused.
63 */
64 uint vcons_in;
65 uint vcons_out;
66
67 /* Output (logging) buffer
68 * Console output is written to a ring buffer log_buf at index log_idx.
69 * The host may read the output when it sees log_idx advance.
70 * Output will be lost if the output wraps around faster than the host
71 * polls.
72 */
73 struct rte_log_le log_le;
74
75 /* Console input line buffer
76 * Characters are read one at a time into cbuf
77 * until <CR> is received, then
78 * the buffer is processed as a command line.
79 * Also used for virtual UART.
80 */
81 uint cbuf_idx;
82 char cbuf[CBUF_LEN];
83};
84
85#endif /* BCMDBG */
86#include <chipcommon.h>
87
88#include "dhd.h"
89#include "dhd_bus.h"
90#include "dhd_proto.h"
91#include "dhd_dbg.h"
92#include <bcmchip.h>
93
94#define TXQLEN 2048 /* bulk tx queue length */
95#define TXHI (TXQLEN - 256) /* turn on flow control above TXHI */
96#define TXLOW (TXHI - 256) /* turn off flow control below TXLOW */
97#define PRIOMASK 7
98
99#define TXRETRIES 2 /* # of retries for tx frames */
100
101#define BRCMF_RXBOUND 50 /* Default for max rx frames in
102 one scheduling */
103
104#define BRCMF_TXBOUND 20 /* Default for max tx frames in
105 one scheduling */
106
107#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */
108
109#define MEMBLOCK 2048 /* Block size used for downloading
110 of dongle image */
111#define MAX_DATA_BUF (32 * 1024) /* Must be large enough to hold
112 biggest possible glom */
113
114#define BRCMF_FIRSTREAD (1 << 6)
115
116
117/* SBSDIO_DEVICE_CTL */
118
119/* 1: device will assert busy signal when receiving CMD53 */
120#define SBSDIO_DEVCTL_SETBUSY 0x01
121/* 1: assertion of sdio interrupt is synchronous to the sdio clock */
122#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02
123/* 1: mask all interrupts to host except the chipActive (rev 8) */
124#define SBSDIO_DEVCTL_CA_INT_ONLY 0x04
125/* 1: isolate internal sdio signals, put external pads in tri-state; requires
126 * sdio bus power cycle to clear (rev 9) */
127#define SBSDIO_DEVCTL_PADS_ISO 0x08
128/* Force SD->SB reset mapping (rev 11) */
129#define SBSDIO_DEVCTL_SB_RST_CTL 0x30
130/* Determined by CoreControl bit */
131#define SBSDIO_DEVCTL_RST_CORECTL 0x00
132/* Force backplane reset */
133#define SBSDIO_DEVCTL_RST_BPRESET 0x10
134/* Force no backplane reset */
135#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20
136
137/* SBSDIO_FUNC1_CHIPCLKCSR */
138
139/* Force ALP request to backplane */
140#define SBSDIO_FORCE_ALP 0x01
141/* Force HT request to backplane */
142#define SBSDIO_FORCE_HT 0x02
143/* Force ILP request to backplane */
144#define SBSDIO_FORCE_ILP 0x04
145/* Make ALP ready (power up xtal) */
146#define SBSDIO_ALP_AVAIL_REQ 0x08
147/* Make HT ready (power up PLL) */
148#define SBSDIO_HT_AVAIL_REQ 0x10
149/* Squelch clock requests from HW */
150#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20
151/* Status: ALP is ready */
152#define SBSDIO_ALP_AVAIL 0x40
153/* Status: HT is ready */
154#define SBSDIO_HT_AVAIL 0x80
155
156#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
157#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS)
158#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
159#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
160
161#define SBSDIO_CLKAV(regval, alponly) \
162 (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))
163
164/* direct(mapped) cis space */
165
166/* MAPPED common CIS address */
167#define SBSDIO_CIS_BASE_COMMON 0x1000
168/* maximum bytes in one CIS */
169#define SBSDIO_CIS_SIZE_LIMIT 0x200
170/* cis offset addr is < 17 bits */
171#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF
172
173/* manfid tuple length, include tuple, link bytes */
174#define SBSDIO_CIS_MANFID_TUPLE_LEN 6
175
176/* intstatus */
177#define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */
178#define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */
179#define I_SMB_SW2 (1 << 2) /* To SB Mail S/W interrupt 2 */
180#define I_SMB_SW3 (1 << 3) /* To SB Mail S/W interrupt 3 */
181#define I_SMB_SW_MASK 0x0000000f /* To SB Mail S/W interrupts mask */
182#define I_SMB_SW_SHIFT 0 /* To SB Mail S/W interrupts shift */
183#define I_HMB_SW0 (1 << 4) /* To Host Mail S/W interrupt 0 */
184#define I_HMB_SW1 (1 << 5) /* To Host Mail S/W interrupt 1 */
185#define I_HMB_SW2 (1 << 6) /* To Host Mail S/W interrupt 2 */
186#define I_HMB_SW3 (1 << 7) /* To Host Mail S/W interrupt 3 */
187#define I_HMB_SW_MASK 0x000000f0 /* To Host Mail S/W interrupts mask */
188#define I_HMB_SW_SHIFT 4 /* To Host Mail S/W interrupts shift */
189#define I_WR_OOSYNC (1 << 8) /* Write Frame Out Of Sync */
190#define I_RD_OOSYNC (1 << 9) /* Read Frame Out Of Sync */
191#define I_PC (1 << 10) /* descriptor error */
192#define I_PD (1 << 11) /* data error */
193#define I_DE (1 << 12) /* Descriptor protocol Error */
194#define I_RU (1 << 13) /* Receive descriptor Underflow */
195#define I_RO (1 << 14) /* Receive fifo Overflow */
196#define I_XU (1 << 15) /* Transmit fifo Underflow */
197#define I_RI (1 << 16) /* Receive Interrupt */
198#define I_BUSPWR (1 << 17) /* SDIO Bus Power Change (rev 9) */
199#define I_XMTDATA_AVAIL (1 << 23) /* bits in fifo */
200#define I_XI (1 << 24) /* Transmit Interrupt */
201#define I_RF_TERM (1 << 25) /* Read Frame Terminate */
202#define I_WF_TERM (1 << 26) /* Write Frame Terminate */
203#define I_PCMCIA_XU (1 << 27) /* PCMCIA Transmit FIFO Underflow */
204#define I_SBINT (1 << 28) /* sbintstatus Interrupt */
205#define I_CHIPACTIVE (1 << 29) /* chip from doze to active state */
206#define I_SRESET (1 << 30) /* CCCR RES interrupt */
207#define I_IOE2 (1U << 31) /* CCCR IOE2 Bit Changed */
208#define I_ERRORS (I_PC | I_PD | I_DE | I_RU | I_RO | I_XU)
209#define I_DMA (I_RI | I_XI | I_ERRORS)
210
211/* corecontrol */
212#define CC_CISRDY (1 << 0) /* CIS Ready */
213#define CC_BPRESEN (1 << 1) /* CCCR RES signal */
214#define CC_F2RDY (1 << 2) /* set CCCR IOR2 bit */
215#define CC_CLRPADSISO (1 << 3) /* clear SDIO pads isolation */
216#define CC_XMTDATAAVAIL_MODE (1 << 4)
217#define CC_XMTDATAAVAIL_CTRL (1 << 5)
218
219/* SDA_FRAMECTRL */
220#define SFC_RF_TERM (1 << 0) /* Read Frame Terminate */
221#define SFC_WF_TERM (1 << 1) /* Write Frame Terminate */
222#define SFC_CRC4WOOS (1 << 2) /* CRC error for write out of sync */
223#define SFC_ABORTALL (1 << 3) /* Abort all in-progress frames */
224
225/* HW frame tag */
226#define SDPCM_FRAMETAG_LEN 4 /* 2 bytes len, 2 bytes check val */
227
228/* Total length of frame header for dongle protocol */
229#define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN)
230#define SDPCM_RESERVE (SDPCM_HDRLEN + BRCMF_SDALIGN)
231
232/*
233 * Software allocation of To SB Mailbox resources
234 */
235
236/* tosbmailbox bits corresponding to intstatus bits */
237#define SMB_NAK (1 << 0) /* Frame NAK */
238#define SMB_INT_ACK (1 << 1) /* Host Interrupt ACK */
239#define SMB_USE_OOB (1 << 2) /* Use OOB Wakeup */
240#define SMB_DEV_INT (1 << 3) /* Miscellaneous Interrupt */
241
242/* tosbmailboxdata */
243#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version */
244
245/*
246 * Software allocation of To Host Mailbox resources
247 */
248
249/* intstatus bits */
250#define I_HMB_FC_STATE I_HMB_SW0 /* Flow Control State */
251#define I_HMB_FC_CHANGE I_HMB_SW1 /* Flow Control State Changed */
252#define I_HMB_FRAME_IND I_HMB_SW2 /* Frame Indication */
253#define I_HMB_HOST_INT I_HMB_SW3 /* Miscellaneous Interrupt */
254
255/* tohostmailboxdata */
256#define HMB_DATA_NAKHANDLED 1 /* retransmit NAK'd frame */
257#define HMB_DATA_DEVREADY 2 /* talk to host after enable */
258#define HMB_DATA_FC 4 /* per prio flowcontrol update flag */
259#define HMB_DATA_FWREADY 8 /* fw ready for protocol activity */
260
261#define HMB_DATA_FCDATA_MASK 0xff000000
262#define HMB_DATA_FCDATA_SHIFT 24
263
264#define HMB_DATA_VERSION_MASK 0x00ff0000
265#define HMB_DATA_VERSION_SHIFT 16
266
267/*
268 * Software-defined protocol header
269 */
270
271/* Current protocol version */
272#define SDPCM_PROT_VERSION 4
273
274/* SW frame header */
275#define SDPCM_PACKET_SEQUENCE(p) (((u8 *)p)[0] & 0xff)
276
277#define SDPCM_CHANNEL_MASK 0x00000f00
278#define SDPCM_CHANNEL_SHIFT 8
279#define SDPCM_PACKET_CHANNEL(p) (((u8 *)p)[1] & 0x0f)
280
281#define SDPCM_NEXTLEN_OFFSET 2
282
283/* Data Offset from SOF (HW Tag, SW Tag, Pad) */
284#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */
285#define SDPCM_DOFFSET_VALUE(p) (((u8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff)
286#define SDPCM_DOFFSET_MASK 0xff000000
287#define SDPCM_DOFFSET_SHIFT 24
288#define SDPCM_FCMASK_OFFSET 4 /* Flow control */
289#define SDPCM_FCMASK_VALUE(p) (((u8 *)p)[SDPCM_FCMASK_OFFSET] & 0xff)
290#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */
291#define SDPCM_WINDOW_VALUE(p) (((u8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff)
292
293#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */
294
295/* logical channel numbers */
296#define SDPCM_CONTROL_CHANNEL 0 /* Control channel Id */
297#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */
298#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */
299#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets */
300#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */
301
302#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for 8bit frame seq */
303
304#define SDPCM_GLOMDESC(p) (((u8 *)p)[1] & 0x80)
305
306/*
307 * Shared structure between dongle and the host.
308 * The structure contains pointers to trap or assert information.
309 */
310#define SDPCM_SHARED_VERSION 0x0002
311#define SDPCM_SHARED_VERSION_MASK 0x00FF
312#define SDPCM_SHARED_ASSERT_BUILT 0x0100
313#define SDPCM_SHARED_ASSERT 0x0200
314#define SDPCM_SHARED_TRAP 0x0400
315
316/* Space for header read, limit for data packets */
317#define MAX_HDR_READ (1 << 6)
318#define MAX_RX_DATASZ 2048
319
320/* Maximum milliseconds to wait for F2 to come up */
321#define BRCMF_WAIT_F2RDY 3000
322
323/* Bump up limit on waiting for HT to account for first startup;
324 * if the image is doing a CRC calculation before programming the PMU
325 * for HT availability, it could take a couple hundred ms more, so
326 * max out at a 1 second (1000000us).
327 */
328#undef PMU_MAX_TRANSITION_DLY
329#define PMU_MAX_TRANSITION_DLY 1000000
330
331/* Value for ChipClockCSR during initial setup */
332#define BRCMF_INIT_CLKCTL1 (SBSDIO_FORCE_HW_CLKREQ_OFF | \
333 SBSDIO_ALP_AVAIL_REQ)
334
335/* Flags for SDH calls */
336#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
337
338/* sbimstate */
339#define SBIM_IBE 0x20000 /* inbanderror */
340#define SBIM_TO 0x40000 /* timeout */
341#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */
342#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */
343
344/* sbtmstatelow */
345
346/* reset */
347#define SBTML_RESET 0x0001
348/* reject field */
349#define SBTML_REJ_MASK 0x0006
350/* reject */
351#define SBTML_REJ 0x0002
352/* temporary reject, for error recovery */
353#define SBTML_TMPREJ 0x0004
354
355/* Shift to locate the SI control flags in sbtml */
356#define SBTML_SICF_SHIFT 16
357
358/* sbtmstatehigh */
359#define SBTMH_SERR 0x0001 /* serror */
360#define SBTMH_INT 0x0002 /* interrupt */
361#define SBTMH_BUSY 0x0004 /* busy */
362#define SBTMH_TO 0x0020 /* timeout (sonics >= 2.3) */
363
364/* Shift to locate the SI status flags in sbtmh */
365#define SBTMH_SISF_SHIFT 16
366
367/* sbidlow */
368#define SBIDL_INIT 0x80 /* initiator */
369
370/* sbidhigh */
371#define SBIDH_RC_MASK 0x000f /* revision code */
372#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */
373#define SBIDH_RCE_SHIFT 8
374#define SBCOREREV(sbidh) \
375 ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | \
376 ((sbidh) & SBIDH_RC_MASK))
377#define SBIDH_CC_MASK 0x8ff0 /* core code */
378#define SBIDH_CC_SHIFT 4
379#define SBIDH_VC_MASK 0xffff0000 /* vendor code */
380#define SBIDH_VC_SHIFT 16
381
382/*
383 * Conversion of 802.1D priority to precedence level
384 */
385static uint prio2prec(u32 prio)
386{
387 return (prio == PRIO_8021D_NONE || prio == PRIO_8021D_BE) ?
388 (prio^2) : prio;
389}
390
391/*
392 * Core reg address translation.
393 * Both macro's returns a 32 bits byte address on the backplane bus.
394 */
395#define CORE_CC_REG(base, field) \
396 (base + offsetof(struct chipcregs, field))
397#define CORE_BUS_REG(base, field) \
398 (base + offsetof(struct sdpcmd_regs, field))
399#define CORE_SB(base, field) \
400 (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
401
402/* core registers */
403struct sdpcmd_regs {
404 u32 corecontrol; /* 0x00, rev8 */
405 u32 corestatus; /* rev8 */
406 u32 PAD[1];
407 u32 biststatus; /* rev8 */
408
409 /* PCMCIA access */
410 u16 pcmciamesportaladdr; /* 0x010, rev8 */
411 u16 PAD[1];
412 u16 pcmciamesportalmask; /* rev8 */
413 u16 PAD[1];
414 u16 pcmciawrframebc; /* rev8 */
415 u16 PAD[1];
416 u16 pcmciaunderflowtimer; /* rev8 */
417 u16 PAD[1];
418
419 /* interrupt */
420 u32 intstatus; /* 0x020, rev8 */
421 u32 hostintmask; /* rev8 */
422 u32 intmask; /* rev8 */
423 u32 sbintstatus; /* rev8 */
424 u32 sbintmask; /* rev8 */
425 u32 funcintmask; /* rev4 */
426 u32 PAD[2];
427 u32 tosbmailbox; /* 0x040, rev8 */
428 u32 tohostmailbox; /* rev8 */
429 u32 tosbmailboxdata; /* rev8 */
430 u32 tohostmailboxdata; /* rev8 */
431
432 /* synchronized access to registers in SDIO clock domain */
433 u32 sdioaccess; /* 0x050, rev8 */
434 u32 PAD[3];
435
436 /* PCMCIA frame control */
437 u8 pcmciaframectrl; /* 0x060, rev8 */
438 u8 PAD[3];
439 u8 pcmciawatermark; /* rev8 */
440 u8 PAD[155];
441
442 /* interrupt batching control */
443 u32 intrcvlazy; /* 0x100, rev8 */
444 u32 PAD[3];
445
446 /* counters */
447 u32 cmd52rd; /* 0x110, rev8 */
448 u32 cmd52wr; /* rev8 */
449 u32 cmd53rd; /* rev8 */
450 u32 cmd53wr; /* rev8 */
451 u32 abort; /* rev8 */
452 u32 datacrcerror; /* rev8 */
453 u32 rdoutofsync; /* rev8 */
454 u32 wroutofsync; /* rev8 */
455 u32 writebusy; /* rev8 */
456 u32 readwait; /* rev8 */
457 u32 readterm; /* rev8 */
458 u32 writeterm; /* rev8 */
459 u32 PAD[40];
460 u32 clockctlstatus; /* rev8 */
461 u32 PAD[7];
462
463 u32 PAD[128]; /* DMA engines */
464
465 /* SDIO/PCMCIA CIS region */
466 char cis[512]; /* 0x400-0x5ff, rev6 */
467
468 /* PCMCIA function control registers */
469 char pcmciafcr[256]; /* 0x600-6ff, rev6 */
470 u16 PAD[55];
471
472 /* PCMCIA backplane access */
473 u16 backplanecsr; /* 0x76E, rev6 */
474 u16 backplaneaddr0; /* rev6 */
475 u16 backplaneaddr1; /* rev6 */
476 u16 backplaneaddr2; /* rev6 */
477 u16 backplaneaddr3; /* rev6 */
478 u16 backplanedata0; /* rev6 */
479 u16 backplanedata1; /* rev6 */
480 u16 backplanedata2; /* rev6 */
481 u16 backplanedata3; /* rev6 */
482 u16 PAD[31];
483
484 /* sprom "size" & "blank" info */
485 u16 spromstatus; /* 0x7BE, rev2 */
486 u32 PAD[464];
487
488 u16 PAD[0x80];
489};
490
491#ifdef BCMDBG
492/* Device console log buffer state */
493struct brcmf_console {
494 uint count; /* Poll interval msec counter */
495 uint log_addr; /* Log struct address (fixed) */
496 struct rte_log_le log_le; /* Log struct (host copy) */
497 uint bufsize; /* Size of log buffer */
498 u8 *buf; /* Log buffer (host copy) */
499 uint last; /* Last buffer read index */
500};
501#endif /* BCMDBG */
502
503struct sdpcm_shared {
504 u32 flags;
505 u32 trap_addr;
506 u32 assert_exp_addr;
507 u32 assert_file_addr;
508 u32 assert_line;
509 u32 console_addr; /* Address of struct rte_console */
510 u32 msgtrace_addr;
511 u8 tag[32];
512};
513
514struct sdpcm_shared_le {
515 __le32 flags;
516 __le32 trap_addr;
517 __le32 assert_exp_addr;
518 __le32 assert_file_addr;
519 __le32 assert_line;
520 __le32 console_addr; /* Address of struct rte_console */
521 __le32 msgtrace_addr;
522 u8 tag[32];
523};
524
525
526/* misc chip info needed by some of the routines */
527struct chip_info {
528 u32 chip;
529 u32 chiprev;
530 u32 cccorebase;
531 u32 ccrev;
532 u32 cccaps;
533 u32 buscorebase; /* 32 bits backplane bus address */
534 u32 buscorerev;
535 u32 buscoretype;
536 u32 ramcorebase;
537 u32 armcorebase;
538 u32 pmurev;
539 u32 ramsize;
540};
541
542/* Private data for SDIO bus interaction */
543struct brcmf_bus {
544 struct brcmf_pub *drvr;
545
546 struct brcmf_sdio_dev *sdiodev; /* sdio device handler */
547 struct chip_info *ci; /* Chip info struct */
548 char *vars; /* Variables (from CIS and/or other) */
549 uint varsz; /* Size of variables buffer */
550
551 u32 ramsize; /* Size of RAM in SOCRAM (bytes) */
552
553 u32 hostintmask; /* Copy of Host Interrupt Mask */
554 u32 intstatus; /* Intstatus bits (events) pending */
555 bool dpc_sched; /* Indicates DPC schedule (intrpt rcvd) */
556 bool fcstate; /* State of dongle flow-control */
557
558 uint blocksize; /* Block size of SDIO transfers */
559 uint roundup; /* Max roundup limit */
560
561 struct pktq txq; /* Queue length used for flow-control */
562 u8 flowcontrol; /* per prio flow control bitmask */
563 u8 tx_seq; /* Transmit sequence number (next) */
564 u8 tx_max; /* Maximum transmit sequence allowed */
565
566 u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN];
567 u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */
568 u16 nextlen; /* Next Read Len from last header */
569 u8 rx_seq; /* Receive sequence number (expected) */
570 bool rxskip; /* Skip receive (awaiting NAK ACK) */
571
572 uint rxbound; /* Rx frames to read before resched */
573 uint txbound; /* Tx frames to send before resched */
574 uint txminmax;
575
576 struct sk_buff *glomd; /* Packet containing glomming descriptor */
577 struct sk_buff *glom; /* Packet chain for glommed superframe */
578 uint glomerr; /* Glom packet read errors */
579
580 u8 *rxbuf; /* Buffer for receiving control packets */
581 uint rxblen; /* Allocated length of rxbuf */
582 u8 *rxctl; /* Aligned pointer into rxbuf */
583 u8 *databuf; /* Buffer for receiving big glom packet */
584 u8 *dataptr; /* Aligned pointer into databuf */
585 uint rxlen; /* Length of valid data in buffer */
586
587 u8 sdpcm_ver; /* Bus protocol reported by dongle */
588
589 bool intr; /* Use interrupts */
590 bool poll; /* Use polling */
591 bool ipend; /* Device interrupt is pending */
592 uint intrcount; /* Count of device interrupt callbacks */
593 uint lastintrs; /* Count as of last watchdog timer */
594 uint spurious; /* Count of spurious interrupts */
595 uint pollrate; /* Ticks between device polls */
596 uint polltick; /* Tick counter */
597 uint pollcnt; /* Count of active polls */
598
599#ifdef BCMDBG
600 uint console_interval;
601 struct brcmf_console console; /* Console output polling support */
602 uint console_addr; /* Console address from shared struct */
603#endif /* BCMDBG */
604
605 uint regfails; /* Count of R_REG failures */
606
607 uint clkstate; /* State of sd and backplane clock(s) */
608 bool activity; /* Activity flag for clock down */
609 s32 idletime; /* Control for activity timeout */
610 s32 idlecount; /* Activity timeout counter */
611 s32 idleclock; /* How to set bus driver when idle */
612 s32 sd_rxchain;
613 bool use_rxchain; /* If brcmf should use PKT chains */
614 bool sleeping; /* Is SDIO bus sleeping? */
615 bool rxflow_mode; /* Rx flow control mode */
616 bool rxflow; /* Is rx flow control on */
617 bool alp_only; /* Don't use HT clock (ALP only) */
618/* Field to decide if rx of control frames happen in rxbuf or lb-pool */
619 bool usebufpool;
620
621 /* Some additional counters */
622 uint tx_sderrs; /* Count of tx attempts with sd errors */
623 uint fcqueued; /* Tx packets that got queued */
624 uint rxrtx; /* Count of rtx requests (NAK to dongle) */
625 uint rx_toolong; /* Receive frames too long to receive */
626 uint rxc_errors; /* SDIO errors when reading control frames */
627 uint rx_hdrfail; /* SDIO errors on header reads */
628 uint rx_badhdr; /* Bad received headers (roosync?) */
629 uint rx_badseq; /* Mismatched rx sequence number */
630 uint fc_rcvd; /* Number of flow-control events received */
631 uint fc_xoff; /* Number which turned on flow-control */
632 uint fc_xon; /* Number which turned off flow-control */
633 uint rxglomfail; /* Failed deglom attempts */
634 uint rxglomframes; /* Number of glom frames (superframes) */
635 uint rxglompkts; /* Number of packets from glom frames */
636 uint f2rxhdrs; /* Number of header reads */
637 uint f2rxdata; /* Number of frame data reads */
638 uint f2txdata; /* Number of f2 frame writes */
639 uint f1regdata; /* Number of f1 register accesses */
640
641 u8 *ctrl_frame_buf;
642 u32 ctrl_frame_len;
643 bool ctrl_frame_stat;
644
645 spinlock_t txqlock;
646 wait_queue_head_t ctrl_wait;
647 wait_queue_head_t dcmd_resp_wait;
648
649 struct timer_list timer;
650 struct completion watchdog_wait;
651 struct task_struct *watchdog_tsk;
652 bool wd_timer_valid;
653 uint save_ms;
654
655 struct task_struct *dpc_tsk;
656 struct completion dpc_wait;
657
658 struct semaphore sdsem;
659
660 const char *fw_name;
661 const struct firmware *firmware;
662 const char *nv_name;
663 u32 fw_ptr;
664};
665
666struct sbconfig {
667 u32 PAD[2];
668 u32 sbipsflag; /* initiator port ocp slave flag */
669 u32 PAD[3];
670 u32 sbtpsflag; /* target port ocp slave flag */
671 u32 PAD[11];
672 u32 sbtmerrloga; /* (sonics >= 2.3) */
673 u32 PAD;
674 u32 sbtmerrlog; /* (sonics >= 2.3) */
675 u32 PAD[3];
676 u32 sbadmatch3; /* address match3 */
677 u32 PAD;
678 u32 sbadmatch2; /* address match2 */
679 u32 PAD;
680 u32 sbadmatch1; /* address match1 */
681 u32 PAD[7];
682 u32 sbimstate; /* initiator agent state */
683 u32 sbintvec; /* interrupt mask */
684 u32 sbtmstatelow; /* target state */
685 u32 sbtmstatehigh; /* target state */
686 u32 sbbwa0; /* bandwidth allocation table0 */
687 u32 PAD;
688 u32 sbimconfiglow; /* initiator configuration */
689 u32 sbimconfighigh; /* initiator configuration */
690 u32 sbadmatch0; /* address match0 */
691 u32 PAD;
692 u32 sbtmconfiglow; /* target configuration */
693 u32 sbtmconfighigh; /* target configuration */
694 u32 sbbconfig; /* broadcast configuration */
695 u32 PAD;
696 u32 sbbstate; /* broadcast state */
697 u32 PAD[3];
698 u32 sbactcnfg; /* activate configuration */
699 u32 PAD[3];
700 u32 sbflagst; /* current sbflags */
701 u32 PAD[3];
702 u32 sbidlow; /* identification */
703 u32 sbidhigh; /* identification */
704};
705
706/* clkstate */
707#define CLK_NONE 0
708#define CLK_SDONLY 1
709#define CLK_PENDING 2 /* Not used yet */
710#define CLK_AVAIL 3
711
712#ifdef BCMDBG
713static int qcount[NUMPRIO];
714static int tx_packets[NUMPRIO];
715#endif /* BCMDBG */
716
717#define SDIO_DRIVE_STRENGTH 6 /* in milliamps */
718
719#define RETRYCHAN(chan) ((chan) == SDPCM_EVENT_CHANNEL)
720
721/* Retry count for register access failures */
722static const uint retry_limit = 2;
723
724/* Limit on rounding up frames */
725static const uint max_roundup = 512;
726
727#define ALIGNMENT 4
728
729static void pkt_align(struct sk_buff *p, int len, int align)
730{
731 uint datalign;
732 datalign = (unsigned long)(p->data);
733 datalign = roundup(datalign, (align)) - datalign;
734 if (datalign)
735 skb_pull(p, datalign);
736 __skb_trim(p, len);
737}
738
739/* To check if there's window offered */
740static bool data_ok(struct brcmf_bus *bus)
741{
742 return (u8)(bus->tx_max - bus->tx_seq) != 0 &&
743 ((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0;
744}
745
746/*
747 * Reads a register in the SDIO hardware block. This block occupies a series of
748 * adresses on the 32 bit backplane bus.
749 */
750static void
751r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar)
752{
753 *retryvar = 0;
754 do {
755 *regvar = brcmf_sdcard_reg_read(bus->sdiodev,
756 bus->ci->buscorebase + reg_offset, sizeof(u32));
757 } while (brcmf_sdcard_regfail(bus->sdiodev) &&
758 (++(*retryvar) <= retry_limit));
759 if (*retryvar) {
760 bus->regfails += (*retryvar-1);
761 if (*retryvar > retry_limit) {
762 brcmf_dbg(ERROR, "FAILED READ %Xh\n", reg_offset);
763 *regvar = 0;
764 }
765 }
766}
767
768static void
769w_sdreg32(struct brcmf_bus *bus, u32 regval, u32 reg_offset, u32 *retryvar)
770{
771 *retryvar = 0;
772 do {
773 brcmf_sdcard_reg_write(bus->sdiodev,
774 bus->ci->buscorebase + reg_offset,
775 sizeof(u32), regval);
776 } while (brcmf_sdcard_regfail(bus->sdiodev) &&
777 (++(*retryvar) <= retry_limit));
778 if (*retryvar) {
779 bus->regfails += (*retryvar-1);
780 if (*retryvar > retry_limit)
781 brcmf_dbg(ERROR, "FAILED REGISTER WRITE %Xh\n",
782 reg_offset);
783 }
784}
785
786#define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND)
787
788#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE)
789
790/* Packet free applicable unconditionally for sdio and sdspi.
791 * Conditional if bufpool was present for gspi bus.
792 */
793static void brcmf_sdbrcm_pktfree2(struct brcmf_bus *bus, struct sk_buff *pkt)
794{
795 if (bus->usebufpool)
796 brcmu_pkt_buf_free_skb(pkt);
797}
798
799/* Turn backplane clock on or off */
800static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok)
801{
802 int err;
803 u8 clkctl, clkreq, devctl;
804 unsigned long timeout;
805
806 brcmf_dbg(TRACE, "Enter\n");
807
808 clkctl = 0;
809
810 if (on) {
811 /* Request HT Avail */
812 clkreq =
813 bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
814
815 if ((bus->ci->chip == BCM4329_CHIP_ID)
816 && (bus->ci->chiprev == 0))
817 clkreq |= SBSDIO_FORCE_ALP;
818
819 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
820 SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err);
821 if (err) {
822 brcmf_dbg(ERROR, "HT Avail request error: %d\n", err);
823 return -EBADE;
824 }
825
826 if (pendok && ((bus->ci->buscoretype == PCMCIA_CORE_ID)
827 && (bus->ci->buscorerev == 9))) {
828 u32 dummy, retries;
829 r_sdreg32(bus, &dummy,
830 offsetof(struct sdpcmd_regs, clockctlstatus),
831 &retries);
832 }
833
834 /* Check current status */
835 clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
836 SBSDIO_FUNC1_CHIPCLKCSR, &err);
837 if (err) {
838 brcmf_dbg(ERROR, "HT Avail read error: %d\n", err);
839 return -EBADE;
840 }
841
842 /* Go to pending and await interrupt if appropriate */
843 if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
844 /* Allow only clock-available interrupt */
845 devctl = brcmf_sdcard_cfg_read(bus->sdiodev,
846 SDIO_FUNC_1,
847 SBSDIO_DEVICE_CTL, &err);
848 if (err) {
849 brcmf_dbg(ERROR, "Devctl error setting CA: %d\n",
850 err);
851 return -EBADE;
852 }
853
854 devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
855 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
856 SBSDIO_DEVICE_CTL, devctl, &err);
857 brcmf_dbg(INFO, "CLKCTL: set PENDING\n");
858 bus->clkstate = CLK_PENDING;
859
860 return 0;
861 } else if (bus->clkstate == CLK_PENDING) {
862 /* Cancel CA-only interrupt filter */
863 devctl =
864 brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
865 SBSDIO_DEVICE_CTL, &err);
866 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
867 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
868 SBSDIO_DEVICE_CTL, devctl, &err);
869 }
870
871 /* Otherwise, wait here (polling) for HT Avail */
872 timeout = jiffies +
873 msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000);
874 while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
875 clkctl = brcmf_sdcard_cfg_read(bus->sdiodev,
876 SDIO_FUNC_1,
877 SBSDIO_FUNC1_CHIPCLKCSR,
878 &err);
879 if (time_after(jiffies, timeout))
880 break;
881 else
882 usleep_range(5000, 10000);
883 }
884 if (err) {
885 brcmf_dbg(ERROR, "HT Avail request error: %d\n", err);
886 return -EBADE;
887 }
888 if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
889 brcmf_dbg(ERROR, "HT Avail timeout (%d): clkctl 0x%02x\n",
890 PMU_MAX_TRANSITION_DLY, clkctl);
891 return -EBADE;
892 }
893
894 /* Mark clock available */
895 bus->clkstate = CLK_AVAIL;
896 brcmf_dbg(INFO, "CLKCTL: turned ON\n");
897
898#if defined(BCMDBG)
899 if (bus->alp_only != true) {
900 if (SBSDIO_ALPONLY(clkctl))
901 brcmf_dbg(ERROR, "HT Clock should be on\n");
902 }
903#endif /* defined (BCMDBG) */
904
905 bus->activity = true;
906 } else {
907 clkreq = 0;
908
909 if (bus->clkstate == CLK_PENDING) {
910 /* Cancel CA-only interrupt filter */
911 devctl = brcmf_sdcard_cfg_read(bus->sdiodev,
912 SDIO_FUNC_1,
913 SBSDIO_DEVICE_CTL, &err);
914 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
915 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
916 SBSDIO_DEVICE_CTL, devctl, &err);
917 }
918
919 bus->clkstate = CLK_SDONLY;
920 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
921 SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err);
922 brcmf_dbg(INFO, "CLKCTL: turned OFF\n");
923 if (err) {
924 brcmf_dbg(ERROR, "Failed access turning clock off: %d\n",
925 err);
926 return -EBADE;
927 }
928 }
929 return 0;
930}
931
932/* Change idle/active SD state */
933static int brcmf_sdbrcm_sdclk(struct brcmf_bus *bus, bool on)
934{
935 brcmf_dbg(TRACE, "Enter\n");
936
937 if (on)
938 bus->clkstate = CLK_SDONLY;
939 else
940 bus->clkstate = CLK_NONE;
941
942 return 0;
943}
944
945/* Transition SD and backplane clock readiness */
946static int brcmf_sdbrcm_clkctl(struct brcmf_bus *bus, uint target, bool pendok)
947{
948#ifdef BCMDBG
949 uint oldstate = bus->clkstate;
950#endif /* BCMDBG */
951
952 brcmf_dbg(TRACE, "Enter\n");
953
954 /* Early exit if we're already there */
955 if (bus->clkstate == target) {
956 if (target == CLK_AVAIL) {
957 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
958 bus->activity = true;
959 }
960 return 0;
961 }
962
963 switch (target) {
964 case CLK_AVAIL:
965 /* Make sure SD clock is available */
966 if (bus->clkstate == CLK_NONE)
967 brcmf_sdbrcm_sdclk(bus, true);
968 /* Now request HT Avail on the backplane */
969 brcmf_sdbrcm_htclk(bus, true, pendok);
970 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
971 bus->activity = true;
972 break;
973
974 case CLK_SDONLY:
975 /* Remove HT request, or bring up SD clock */
976 if (bus->clkstate == CLK_NONE)
977 brcmf_sdbrcm_sdclk(bus, true);
978 else if (bus->clkstate == CLK_AVAIL)
979 brcmf_sdbrcm_htclk(bus, false, false);
980 else
981 brcmf_dbg(ERROR, "request for %d -> %d\n",
982 bus->clkstate, target);
983 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
984 break;
985
986 case CLK_NONE:
987 /* Make sure to remove HT request */
988 if (bus->clkstate == CLK_AVAIL)
989 brcmf_sdbrcm_htclk(bus, false, false);
990 /* Now remove the SD clock */
991 brcmf_sdbrcm_sdclk(bus, false);
992 brcmf_sdbrcm_wd_timer(bus, 0);
993 break;
994 }
995#ifdef BCMDBG
996 brcmf_dbg(INFO, "%d -> %d\n", oldstate, bus->clkstate);
997#endif /* BCMDBG */
998
999 return 0;
1000}
1001
1002static int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep)
1003{
1004 uint retries = 0;
1005
1006 brcmf_dbg(INFO, "request %s (currently %s)\n",
1007 sleep ? "SLEEP" : "WAKE",
1008 bus->sleeping ? "SLEEP" : "WAKE");
1009
1010 /* Done if we're already in the requested state */
1011 if (sleep == bus->sleeping)
1012 return 0;
1013
1014 /* Going to sleep: set the alarm and turn off the lights... */
1015 if (sleep) {
1016 /* Don't sleep if something is pending */
1017 if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq))
1018 return -EBUSY;
1019
1020 /* Make sure the controller has the bus up */
1021 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
1022
1023 /* Tell device to start using OOB wakeup */
1024 w_sdreg32(bus, SMB_USE_OOB,
1025 offsetof(struct sdpcmd_regs, tosbmailbox), &retries);
1026 if (retries > retry_limit)
1027 brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n");
1028
1029 /* Turn off our contribution to the HT clock request */
1030 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
1031
1032 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
1033 SBSDIO_FUNC1_CHIPCLKCSR,
1034 SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
1035
1036 /* Isolate the bus */
1037 if (bus->ci->chip != BCM4329_CHIP_ID) {
1038 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
1039 SBSDIO_DEVICE_CTL,
1040 SBSDIO_DEVCTL_PADS_ISO, NULL);
1041 }
1042
1043 /* Change state */
1044 bus->sleeping = true;
1045
1046 } else {
1047 /* Waking up: bus power up is ok, set local state */
1048
1049 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
1050 SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
1051
1052 /* Force pad isolation off if possible
1053 (in case power never toggled) */
1054 if ((bus->ci->buscoretype == PCMCIA_CORE_ID)
1055 && (bus->ci->buscorerev >= 10))
1056 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
1057 SBSDIO_DEVICE_CTL, 0, NULL);
1058
1059 /* Make sure the controller has the bus up */
1060 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
1061
1062 /* Send misc interrupt to indicate OOB not needed */
1063 w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, tosbmailboxdata),
1064 &retries);
1065 if (retries <= retry_limit)
1066 w_sdreg32(bus, SMB_DEV_INT,
1067 offsetof(struct sdpcmd_regs, tosbmailbox),
1068 &retries);
1069
1070 if (retries > retry_limit)
1071 brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP TO CLEAR OOB!!\n");
1072
1073 /* Make sure we have SD bus access */
1074 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
1075
1076 /* Change state */
1077 bus->sleeping = false;
1078 }
1079
1080 return 0;
1081}
1082
1083static void bus_wake(struct brcmf_bus *bus)
1084{
1085 if (bus->sleeping)
1086 brcmf_sdbrcm_bussleep(bus, false);
1087}
1088
1089static u32 brcmf_sdbrcm_hostmail(struct brcmf_bus *bus)
1090{
1091 u32 intstatus = 0;
1092 u32 hmb_data;
1093 u8 fcbits;
1094 uint retries = 0;
1095
1096 brcmf_dbg(TRACE, "Enter\n");
1097
1098 /* Read mailbox data and ack that we did so */
1099 r_sdreg32(bus, &hmb_data,
1100 offsetof(struct sdpcmd_regs, tohostmailboxdata), &retries);
1101
1102 if (retries <= retry_limit)
1103 w_sdreg32(bus, SMB_INT_ACK,
1104 offsetof(struct sdpcmd_regs, tosbmailbox), &retries);
1105 bus->f1regdata += 2;
1106
1107 /* Dongle recomposed rx frames, accept them again */
1108 if (hmb_data & HMB_DATA_NAKHANDLED) {
1109 brcmf_dbg(INFO, "Dongle reports NAK handled, expect rtx of %d\n",
1110 bus->rx_seq);
1111 if (!bus->rxskip)
1112 brcmf_dbg(ERROR, "unexpected NAKHANDLED!\n");
1113
1114 bus->rxskip = false;
1115 intstatus |= I_HMB_FRAME_IND;
1116 }
1117
1118 /*
1119 * DEVREADY does not occur with gSPI.
1120 */
1121 if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) {
1122 bus->sdpcm_ver =
1123 (hmb_data & HMB_DATA_VERSION_MASK) >>
1124 HMB_DATA_VERSION_SHIFT;
1125 if (bus->sdpcm_ver != SDPCM_PROT_VERSION)
1126 brcmf_dbg(ERROR, "Version mismatch, dongle reports %d, "
1127 "expecting %d\n",
1128 bus->sdpcm_ver, SDPCM_PROT_VERSION);
1129 else
1130 brcmf_dbg(INFO, "Dongle ready, protocol version %d\n",
1131 bus->sdpcm_ver);
1132 }
1133
1134 /*
1135 * Flow Control has been moved into the RX headers and this out of band
1136 * method isn't used any more.
1137 * remaining backward compatible with older dongles.
1138 */
1139 if (hmb_data & HMB_DATA_FC) {
1140 fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >>
1141 HMB_DATA_FCDATA_SHIFT;
1142
1143 if (fcbits & ~bus->flowcontrol)
1144 bus->fc_xoff++;
1145
1146 if (bus->flowcontrol & ~fcbits)
1147 bus->fc_xon++;
1148
1149 bus->fc_rcvd++;
1150 bus->flowcontrol = fcbits;
1151 }
1152
1153 /* Shouldn't be any others */
1154 if (hmb_data & ~(HMB_DATA_DEVREADY |
1155 HMB_DATA_NAKHANDLED |
1156 HMB_DATA_FC |
1157 HMB_DATA_FWREADY |
1158 HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK))
1159 brcmf_dbg(ERROR, "Unknown mailbox data content: 0x%02x\n",
1160 hmb_data);
1161
1162 return intstatus;
1163}
1164
1165static void brcmf_sdbrcm_rxfail(struct brcmf_bus *bus, bool abort, bool rtx)
1166{
1167 uint retries = 0;
1168 u16 lastrbc;
1169 u8 hi, lo;
1170 int err;
1171
1172 brcmf_dbg(ERROR, "%sterminate frame%s\n",
1173 abort ? "abort command, " : "",
1174 rtx ? ", send NAK" : "");
1175
1176 if (abort)
1177 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
1178
1179 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
1180 SBSDIO_FUNC1_FRAMECTRL,
1181 SFC_RF_TERM, &err);
1182 bus->f1regdata++;
1183
1184 /* Wait until the packet has been flushed (device/FIFO stable) */
1185 for (lastrbc = retries = 0xffff; retries > 0; retries--) {
1186 hi = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
1187 SBSDIO_FUNC1_RFRAMEBCHI, NULL);
1188 lo = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
1189 SBSDIO_FUNC1_RFRAMEBCLO, NULL);
1190 bus->f1regdata += 2;
1191
1192 if ((hi == 0) && (lo == 0))
1193 break;
1194
1195 if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) {
1196 brcmf_dbg(ERROR, "count growing: last 0x%04x now 0x%04x\n",
1197 lastrbc, (hi << 8) + lo);
1198 }
1199 lastrbc = (hi << 8) + lo;
1200 }
1201
1202 if (!retries)
1203 brcmf_dbg(ERROR, "count never zeroed: last 0x%04x\n", lastrbc);
1204 else
1205 brcmf_dbg(INFO, "flush took %d iterations\n", 0xffff - retries);
1206
1207 if (rtx) {
1208 bus->rxrtx++;
1209 w_sdreg32(bus, SMB_NAK,
1210 offsetof(struct sdpcmd_regs, tosbmailbox), &retries);
1211
1212 bus->f1regdata++;
1213 if (retries <= retry_limit)
1214 bus->rxskip = true;
1215 }
1216
1217 /* Clear partial in any case */
1218 bus->nextlen = 0;
1219
1220 /* If we can't reach the device, signal failure */
1221 if (err || brcmf_sdcard_regfail(bus->sdiodev))
1222 bus->drvr->busstate = BRCMF_BUS_DOWN;
1223}
1224
1225static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq)
1226{
1227 u16 dlen, totlen;
1228 u8 *dptr, num = 0;
1229
1230 u16 sublen, check;
1231 struct sk_buff *pfirst, *plast, *pnext, *save_pfirst;
1232
1233 int errcode;
1234 u8 chan, seq, doff, sfdoff;
1235 u8 txmax;
1236
1237 int ifidx = 0;
1238 bool usechain = bus->use_rxchain;
1239
1240 /* If packets, issue read(s) and send up packet chain */
1241 /* Return sequence numbers consumed? */
1242
1243 brcmf_dbg(TRACE, "start: glomd %p glom %p\n", bus->glomd, bus->glom);
1244
1245 /* If there's a descriptor, generate the packet chain */
1246 if (bus->glomd) {
1247 pfirst = plast = pnext = NULL;
1248 dlen = (u16) (bus->glomd->len);
1249 dptr = bus->glomd->data;
1250 if (!dlen || (dlen & 1)) {
1251 brcmf_dbg(ERROR, "bad glomd len(%d), ignore descriptor\n",
1252 dlen);
1253 dlen = 0;
1254 }
1255
1256 for (totlen = num = 0; dlen; num++) {
1257 /* Get (and move past) next length */
1258 sublen = get_unaligned_le16(dptr);
1259 dlen -= sizeof(u16);
1260 dptr += sizeof(u16);
1261 if ((sublen < SDPCM_HDRLEN) ||
1262 ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) {
1263 brcmf_dbg(ERROR, "descriptor len %d bad: %d\n",
1264 num, sublen);
1265 pnext = NULL;
1266 break;
1267 }
1268 if (sublen % BRCMF_SDALIGN) {
1269 brcmf_dbg(ERROR, "sublen %d not multiple of %d\n",
1270 sublen, BRCMF_SDALIGN);
1271 usechain = false;
1272 }
1273 totlen += sublen;
1274
1275 /* For last frame, adjust read len so total
1276 is a block multiple */
1277 if (!dlen) {
1278 sublen +=
1279 (roundup(totlen, bus->blocksize) - totlen);
1280 totlen = roundup(totlen, bus->blocksize);
1281 }
1282
1283 /* Allocate/chain packet for next subframe */
1284 pnext = brcmu_pkt_buf_get_skb(sublen + BRCMF_SDALIGN);
1285 if (pnext == NULL) {
1286 brcmf_dbg(ERROR, "bcm_pkt_buf_get_skb failed, num %d len %d\n",
1287 num, sublen);
1288 break;
1289 }
1290 if (!pfirst) {
1291 pfirst = plast = pnext;
1292 } else {
1293 plast->next = pnext;
1294 plast = pnext;
1295 }
1296
1297 /* Adhere to start alignment requirements */
1298 pkt_align(pnext, sublen, BRCMF_SDALIGN);
1299 }
1300
1301 /* If all allocations succeeded, save packet chain
1302 in bus structure */
1303 if (pnext) {
1304 brcmf_dbg(GLOM, "allocated %d-byte packet chain for %d subframes\n",
1305 totlen, num);
1306 if (BRCMF_GLOM_ON() && bus->nextlen &&
1307 totlen != bus->nextlen) {
1308 brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n",
1309 bus->nextlen, totlen, rxseq);
1310 }
1311 bus->glom = pfirst;
1312 pfirst = pnext = NULL;
1313 } else {
1314 if (pfirst)
1315 brcmu_pkt_buf_free_skb(pfirst);
1316 bus->glom = NULL;
1317 num = 0;
1318 }
1319
1320 /* Done with descriptor packet */
1321 brcmu_pkt_buf_free_skb(bus->glomd);
1322 bus->glomd = NULL;
1323 bus->nextlen = 0;
1324 }
1325
1326 /* Ok -- either we just generated a packet chain,
1327 or had one from before */
1328 if (bus->glom) {
1329 if (BRCMF_GLOM_ON()) {
1330 brcmf_dbg(GLOM, "try superframe read, packet chain:\n");
1331 for (pnext = bus->glom; pnext; pnext = pnext->next) {
1332 brcmf_dbg(GLOM, " %p: %p len 0x%04x (%d)\n",
1333 pnext, (u8 *) (pnext->data),
1334 pnext->len, pnext->len);
1335 }
1336 }
1337
1338 pfirst = bus->glom;
1339 dlen = (u16) brcmu_pkttotlen(pfirst);
1340
1341 /* Do an SDIO read for the superframe. Configurable iovar to
1342 * read directly into the chained packet, or allocate a large
1343 * packet and and copy into the chain.
1344 */
1345 if (usechain) {
1346 errcode = brcmf_sdcard_recv_buf(bus->sdiodev,
1347 bus->sdiodev->sbwad,
1348 SDIO_FUNC_2,
1349 F2SYNC, (u8 *) pfirst->data, dlen,
1350 pfirst);
1351 } else if (bus->dataptr) {
1352 errcode = brcmf_sdcard_recv_buf(bus->sdiodev,
1353 bus->sdiodev->sbwad,
1354 SDIO_FUNC_2,
1355 F2SYNC, bus->dataptr, dlen,
1356 NULL);
1357 sublen = (u16) brcmu_pktfrombuf(pfirst, 0, dlen,
1358 bus->dataptr);
1359 if (sublen != dlen) {
1360 brcmf_dbg(ERROR, "FAILED TO COPY, dlen %d sublen %d\n",
1361 dlen, sublen);
1362 errcode = -1;
1363 }
1364 pnext = NULL;
1365 } else {
1366 brcmf_dbg(ERROR, "COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n",
1367 dlen);
1368 errcode = -1;
1369 }
1370 bus->f2rxdata++;
1371
1372 /* On failure, kill the superframe, allow a couple retries */
1373 if (errcode < 0) {
1374 brcmf_dbg(ERROR, "glom read of %d bytes failed: %d\n",
1375 dlen, errcode);
1376 bus->drvr->rx_errors++;
1377
1378 if (bus->glomerr++ < 3) {
1379 brcmf_sdbrcm_rxfail(bus, true, true);
1380 } else {
1381 bus->glomerr = 0;
1382 brcmf_sdbrcm_rxfail(bus, true, false);
1383 brcmu_pkt_buf_free_skb(bus->glom);
1384 bus->rxglomfail++;
1385 bus->glom = NULL;
1386 }
1387 return 0;
1388 }
1389#ifdef BCMDBG
1390 if (BRCMF_GLOM_ON()) {
1391 printk(KERN_DEBUG "SUPERFRAME:\n");
1392 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
1393 pfirst->data, min_t(int, pfirst->len, 48));
1394 }
1395#endif
1396
1397 /* Validate the superframe header */
1398 dptr = (u8 *) (pfirst->data);
1399 sublen = get_unaligned_le16(dptr);
1400 check = get_unaligned_le16(dptr + sizeof(u16));
1401
1402 chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
1403 seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
1404 bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
1405 if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
1406 brcmf_dbg(INFO, "nextlen too large (%d) seq %d\n",
1407 bus->nextlen, seq);
1408 bus->nextlen = 0;
1409 }
1410 doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
1411 txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
1412
1413 errcode = 0;
1414 if ((u16)~(sublen ^ check)) {
1415 brcmf_dbg(ERROR, "(superframe): HW hdr error: len/check 0x%04x/0x%04x\n",
1416 sublen, check);
1417 errcode = -1;
1418 } else if (roundup(sublen, bus->blocksize) != dlen) {
1419 brcmf_dbg(ERROR, "(superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n",
1420 sublen, roundup(sublen, bus->blocksize),
1421 dlen);
1422 errcode = -1;
1423 } else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) !=
1424 SDPCM_GLOM_CHANNEL) {
1425 brcmf_dbg(ERROR, "(superframe): bad channel %d\n",
1426 SDPCM_PACKET_CHANNEL(
1427 &dptr[SDPCM_FRAMETAG_LEN]));
1428 errcode = -1;
1429 } else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) {
1430 brcmf_dbg(ERROR, "(superframe): got 2nd descriptor?\n");
1431 errcode = -1;
1432 } else if ((doff < SDPCM_HDRLEN) ||
1433 (doff > (pfirst->len - SDPCM_HDRLEN))) {
1434 brcmf_dbg(ERROR, "(superframe): Bad data offset %d: HW %d pkt %d min %d\n",
1435 doff, sublen, pfirst->len, SDPCM_HDRLEN);
1436 errcode = -1;
1437 }
1438
1439 /* Check sequence number of superframe SW header */
1440 if (rxseq != seq) {
1441 brcmf_dbg(INFO, "(superframe) rx_seq %d, expected %d\n",
1442 seq, rxseq);
1443 bus->rx_badseq++;
1444 rxseq = seq;
1445 }
1446
1447 /* Check window for sanity */
1448 if ((u8) (txmax - bus->tx_seq) > 0x40) {
1449 brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n",
1450 txmax, bus->tx_seq);
1451 txmax = bus->tx_seq + 2;
1452 }
1453 bus->tx_max = txmax;
1454
1455 /* Remove superframe header, remember offset */
1456 skb_pull(pfirst, doff);
1457 sfdoff = doff;
1458
1459 /* Validate all the subframe headers */
1460 for (num = 0, pnext = pfirst; pnext && !errcode;
1461 num++, pnext = pnext->next) {
1462 dptr = (u8 *) (pnext->data);
1463 dlen = (u16) (pnext->len);
1464 sublen = get_unaligned_le16(dptr);
1465 check = get_unaligned_le16(dptr + sizeof(u16));
1466 chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
1467 doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
1468#ifdef BCMDBG
1469 if (BRCMF_GLOM_ON()) {
1470 printk(KERN_DEBUG "subframe:\n");
1471 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
1472 dptr, 32);
1473 }
1474#endif
1475
1476 if ((u16)~(sublen ^ check)) {
1477 brcmf_dbg(ERROR, "(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n",
1478 num, sublen, check);
1479 errcode = -1;
1480 } else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) {
1481 brcmf_dbg(ERROR, "(subframe %d): length mismatch: len 0x%04x, expect 0x%04x\n",
1482 num, sublen, dlen);
1483 errcode = -1;
1484 } else if ((chan != SDPCM_DATA_CHANNEL) &&
1485 (chan != SDPCM_EVENT_CHANNEL)) {
1486 brcmf_dbg(ERROR, "(subframe %d): bad channel %d\n",
1487 num, chan);
1488 errcode = -1;
1489 } else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) {
1490 brcmf_dbg(ERROR, "(subframe %d): Bad data offset %d: HW %d min %d\n",
1491 num, doff, sublen, SDPCM_HDRLEN);
1492 errcode = -1;
1493 }
1494 }
1495
1496 if (errcode) {
1497 /* Terminate frame on error, request
1498 a couple retries */
1499 if (bus->glomerr++ < 3) {
1500 /* Restore superframe header space */
1501 skb_push(pfirst, sfdoff);
1502 brcmf_sdbrcm_rxfail(bus, true, true);
1503 } else {
1504 bus->glomerr = 0;
1505 brcmf_sdbrcm_rxfail(bus, true, false);
1506 brcmu_pkt_buf_free_skb(bus->glom);
1507 bus->rxglomfail++;
1508 bus->glom = NULL;
1509 }
1510 bus->nextlen = 0;
1511 return 0;
1512 }
1513
1514 /* Basic SD framing looks ok - process each packet (header) */
1515 save_pfirst = pfirst;
1516 bus->glom = NULL;
1517 plast = NULL;
1518
1519 for (num = 0; pfirst; rxseq++, pfirst = pnext) {
1520 pnext = pfirst->next;
1521 pfirst->next = NULL;
1522
1523 dptr = (u8 *) (pfirst->data);
1524 sublen = get_unaligned_le16(dptr);
1525 chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
1526 seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
1527 doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
1528
1529 brcmf_dbg(GLOM, "Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n",
1530 num, pfirst, pfirst->data,
1531 pfirst->len, sublen, chan, seq);
1532
1533 /* precondition: chan == SDPCM_DATA_CHANNEL ||
1534 chan == SDPCM_EVENT_CHANNEL */
1535
1536 if (rxseq != seq) {
1537 brcmf_dbg(GLOM, "rx_seq %d, expected %d\n",
1538 seq, rxseq);
1539 bus->rx_badseq++;
1540 rxseq = seq;
1541 }
1542#ifdef BCMDBG
1543 if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
1544 printk(KERN_DEBUG "Rx Subframe Data:\n");
1545 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
1546 dptr, dlen);
1547 }
1548#endif
1549
1550 __skb_trim(pfirst, sublen);
1551 skb_pull(pfirst, doff);
1552
1553 if (pfirst->len == 0) {
1554 brcmu_pkt_buf_free_skb(pfirst);
1555 if (plast)
1556 plast->next = pnext;
1557 else
1558 save_pfirst = pnext;
1559
1560 continue;
1561 } else if (brcmf_proto_hdrpull(bus->drvr, &ifidx,
1562 pfirst) != 0) {
1563 brcmf_dbg(ERROR, "rx protocol error\n");
1564 bus->drvr->rx_errors++;
1565 brcmu_pkt_buf_free_skb(pfirst);
1566 if (plast)
1567 plast->next = pnext;
1568 else
1569 save_pfirst = pnext;
1570
1571 continue;
1572 }
1573
1574 /* this packet will go up, link back into
1575 chain and count it */
1576 pfirst->next = pnext;
1577 plast = pfirst;
1578 num++;
1579
1580#ifdef BCMDBG
1581 if (BRCMF_GLOM_ON()) {
1582 brcmf_dbg(GLOM, "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n",
1583 num, pfirst, pfirst->data,
1584 pfirst->len, pfirst->next,
1585 pfirst->prev);
1586 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
1587 pfirst->data,
1588 min_t(int, pfirst->len, 32));
1589 }
1590#endif /* BCMDBG */
1591 }
1592 if (num) {
1593 up(&bus->sdsem);
1594 brcmf_rx_frame(bus->drvr, ifidx, save_pfirst, num);
1595 down(&bus->sdsem);
1596 }
1597
1598 bus->rxglomframes++;
1599 bus->rxglompkts += num;
1600 }
1601 return num;
1602}
1603
1604static int brcmf_sdbrcm_dcmd_resp_wait(struct brcmf_bus *bus, uint *condition,
1605 bool *pending)
1606{
1607 DECLARE_WAITQUEUE(wait, current);
1608 int timeout = msecs_to_jiffies(DCMD_RESP_TIMEOUT);
1609
1610 /* Wait until control frame is available */
1611 add_wait_queue(&bus->dcmd_resp_wait, &wait);
1612 set_current_state(TASK_INTERRUPTIBLE);
1613
1614 while (!(*condition) && (!signal_pending(current) && timeout))
1615 timeout = schedule_timeout(timeout);
1616
1617 if (signal_pending(current))
1618 *pending = true;
1619
1620 set_current_state(TASK_RUNNING);
1621 remove_wait_queue(&bus->dcmd_resp_wait, &wait);
1622
1623 return timeout;
1624}
1625
1626static int brcmf_sdbrcm_dcmd_resp_wake(struct brcmf_bus *bus)
1627{
1628 if (waitqueue_active(&bus->dcmd_resp_wait))
1629 wake_up_interruptible(&bus->dcmd_resp_wait);
1630
1631 return 0;
1632}
1633static void
1634brcmf_sdbrcm_read_control(struct brcmf_bus *bus, u8 *hdr, uint len, uint doff)
1635{
1636 uint rdlen, pad;
1637
1638 int sdret;
1639
1640 brcmf_dbg(TRACE, "Enter\n");
1641
1642 /* Set rxctl for frame (w/optional alignment) */
1643 bus->rxctl = bus->rxbuf;
1644 bus->rxctl += BRCMF_FIRSTREAD;
1645 pad = ((unsigned long)bus->rxctl % BRCMF_SDALIGN);
1646 if (pad)
1647 bus->rxctl += (BRCMF_SDALIGN - pad);
1648 bus->rxctl -= BRCMF_FIRSTREAD;
1649
1650 /* Copy the already-read portion over */
1651 memcpy(bus->rxctl, hdr, BRCMF_FIRSTREAD);
1652 if (len <= BRCMF_FIRSTREAD)
1653 goto gotpkt;
1654
1655 /* Raise rdlen to next SDIO block to avoid tail command */
1656 rdlen = len - BRCMF_FIRSTREAD;
1657 if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) {
1658 pad = bus->blocksize - (rdlen % bus->blocksize);
1659 if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
1660 ((len + pad) < bus->drvr->maxctl))
1661 rdlen += pad;
1662 } else if (rdlen % BRCMF_SDALIGN) {
1663 rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
1664 }
1665
1666 /* Satisfy length-alignment requirements */
1667 if (rdlen & (ALIGNMENT - 1))
1668 rdlen = roundup(rdlen, ALIGNMENT);
1669
1670 /* Drop if the read is too big or it exceeds our maximum */
1671 if ((rdlen + BRCMF_FIRSTREAD) > bus->drvr->maxctl) {
1672 brcmf_dbg(ERROR, "%d-byte control read exceeds %d-byte buffer\n",
1673 rdlen, bus->drvr->maxctl);
1674 bus->drvr->rx_errors++;
1675 brcmf_sdbrcm_rxfail(bus, false, false);
1676 goto done;
1677 }
1678
1679 if ((len - doff) > bus->drvr->maxctl) {
1680 brcmf_dbg(ERROR, "%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n",
1681 len, len - doff, bus->drvr->maxctl);
1682 bus->drvr->rx_errors++;
1683 bus->rx_toolong++;
1684 brcmf_sdbrcm_rxfail(bus, false, false);
1685 goto done;
1686 }
1687
1688 /* Read remainder of frame body into the rxctl buffer */
1689 sdret = brcmf_sdcard_recv_buf(bus->sdiodev,
1690 bus->sdiodev->sbwad,
1691 SDIO_FUNC_2,
1692 F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen,
1693 NULL);
1694 bus->f2rxdata++;
1695
1696 /* Control frame failures need retransmission */
1697 if (sdret < 0) {
1698 brcmf_dbg(ERROR, "read %d control bytes failed: %d\n",
1699 rdlen, sdret);
1700 bus->rxc_errors++;
1701 brcmf_sdbrcm_rxfail(bus, true, true);
1702 goto done;
1703 }
1704
1705gotpkt:
1706
1707#ifdef BCMDBG
1708 if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) {
1709 printk(KERN_DEBUG "RxCtrl:\n");
1710 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len);
1711 }
1712#endif
1713
1714 /* Point to valid data and indicate its length */
1715 bus->rxctl += doff;
1716 bus->rxlen = len - doff;
1717
1718done:
1719 /* Awake any waiters */
1720 brcmf_sdbrcm_dcmd_resp_wake(bus);
1721}
1722
1723/* Pad read to blocksize for efficiency */
1724static void brcmf_pad(struct brcmf_bus *bus, u16 *pad, u16 *rdlen)
1725{
1726 if (bus->roundup && bus->blocksize && *rdlen > bus->blocksize) {
1727 *pad = bus->blocksize - (*rdlen % bus->blocksize);
1728 if (*pad <= bus->roundup && *pad < bus->blocksize &&
1729 *rdlen + *pad + BRCMF_FIRSTREAD < MAX_RX_DATASZ)
1730 *rdlen += *pad;
1731 } else if (*rdlen % BRCMF_SDALIGN) {
1732 *rdlen += BRCMF_SDALIGN - (*rdlen % BRCMF_SDALIGN);
1733 }
1734}
1735
1736static void
1737brcmf_alloc_pkt_and_read(struct brcmf_bus *bus, u16 rdlen,
1738 struct sk_buff **pkt, u8 **rxbuf)
1739{
1740 int sdret; /* Return code from calls */
1741
1742 *pkt = brcmu_pkt_buf_get_skb(rdlen + BRCMF_SDALIGN);
1743 if (*pkt == NULL)
1744 return;
1745
1746 pkt_align(*pkt, rdlen, BRCMF_SDALIGN);
1747 *rxbuf = (u8 *) ((*pkt)->data);
1748 /* Read the entire frame */
1749 sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad,
1750 SDIO_FUNC_2, F2SYNC,
1751 *rxbuf, rdlen, *pkt);
1752 bus->f2rxdata++;
1753
1754 if (sdret < 0) {
1755 brcmf_dbg(ERROR, "(nextlen): read %d bytes failed: %d\n",
1756 rdlen, sdret);
1757 brcmu_pkt_buf_free_skb(*pkt);
1758 bus->drvr->rx_errors++;
1759 /* Force retry w/normal header read.
1760 * Don't attempt NAK for
1761 * gSPI
1762 */
1763 brcmf_sdbrcm_rxfail(bus, true, true);
1764 *pkt = NULL;
1765 }
1766}
1767
1768/* Checks the header */
1769static int
1770brcmf_check_rxbuf(struct brcmf_bus *bus, struct sk_buff *pkt, u8 *rxbuf,
1771 u8 rxseq, u16 nextlen, u16 *len)
1772{
1773 u16 check;
1774 bool len_consistent; /* Result of comparing readahead len and
1775 len from hw-hdr */
1776
1777 memcpy(bus->rxhdr, rxbuf, SDPCM_HDRLEN);
1778
1779 /* Extract hardware header fields */
1780 *len = get_unaligned_le16(bus->rxhdr);
1781 check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
1782
1783 /* All zeros means readahead info was bad */
1784 if (!(*len | check)) {
1785 brcmf_dbg(INFO, "(nextlen): read zeros in HW header???\n");
1786 goto fail;
1787 }
1788
1789 /* Validate check bytes */
1790 if ((u16)~(*len ^ check)) {
1791 brcmf_dbg(ERROR, "(nextlen): HW hdr error: nextlen/len/check 0x%04x/0x%04x/0x%04x\n",
1792 nextlen, *len, check);
1793 bus->rx_badhdr++;
1794 brcmf_sdbrcm_rxfail(bus, false, false);
1795 goto fail;
1796 }
1797
1798 /* Validate frame length */
1799 if (*len < SDPCM_HDRLEN) {
1800 brcmf_dbg(ERROR, "(nextlen): HW hdr length invalid: %d\n",
1801 *len);
1802 goto fail;
1803 }
1804
1805 /* Check for consistency with readahead info */
1806 len_consistent = (nextlen != (roundup(*len, 16) >> 4));
1807 if (len_consistent) {
1808 /* Mismatch, force retry w/normal
1809 header (may be >4K) */
1810 brcmf_dbg(ERROR, "(nextlen): mismatch, nextlen %d len %d rnd %d; expected rxseq %d\n",
1811 nextlen, *len, roundup(*len, 16),
1812 rxseq);
1813 brcmf_sdbrcm_rxfail(bus, true, true);
1814 goto fail;
1815 }
1816
1817 return 0;
1818
1819fail:
1820 brcmf_sdbrcm_pktfree2(bus, pkt);
1821 return -EINVAL;
1822}
1823
1824/* Return true if there may be more frames to read */
1825static uint
1826brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished)
1827{
1828 u16 len, check; /* Extracted hardware header fields */
1829 u8 chan, seq, doff; /* Extracted software header fields */
1830 u8 fcbits; /* Extracted fcbits from software header */
1831
1832 struct sk_buff *pkt; /* Packet for event or data frames */
1833 u16 pad; /* Number of pad bytes to read */
1834 u16 rdlen; /* Total number of bytes to read */
1835 u8 rxseq; /* Next sequence number to expect */
1836 uint rxleft = 0; /* Remaining number of frames allowed */
1837 int sdret; /* Return code from calls */
1838 u8 txmax; /* Maximum tx sequence offered */
1839 u8 *rxbuf;
1840 int ifidx = 0;
1841 uint rxcount = 0; /* Total frames read */
1842
1843 brcmf_dbg(TRACE, "Enter\n");
1844
1845 /* Not finished unless we encounter no more frames indication */
1846 *finished = false;
1847
1848 for (rxseq = bus->rx_seq, rxleft = maxframes;
1849 !bus->rxskip && rxleft && bus->drvr->busstate != BRCMF_BUS_DOWN;
1850 rxseq++, rxleft--) {
1851
1852 /* Handle glomming separately */
1853 if (bus->glom || bus->glomd) {
1854 u8 cnt;
1855 brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n",
1856 bus->glomd, bus->glom);
1857 cnt = brcmf_sdbrcm_rxglom(bus, rxseq);
1858 brcmf_dbg(GLOM, "rxglom returned %d\n", cnt);
1859 rxseq += cnt - 1;
1860 rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1;
1861 continue;
1862 }
1863
1864 /* Try doing single read if we can */
1865 if (bus->nextlen) {
1866 u16 nextlen = bus->nextlen;
1867 bus->nextlen = 0;
1868
1869 rdlen = len = nextlen << 4;
1870 brcmf_pad(bus, &pad, &rdlen);
1871
1872 /*
1873 * After the frame is received we have to
1874 * distinguish whether it is data
1875 * or non-data frame.
1876 */
1877 brcmf_alloc_pkt_and_read(bus, rdlen, &pkt, &rxbuf);
1878 if (pkt == NULL) {
1879 /* Give up on data, request rtx of events */
1880 brcmf_dbg(ERROR, "(nextlen): brcmf_alloc_pkt_and_read failed: len %d rdlen %d expected rxseq %d\n",
1881 len, rdlen, rxseq);
1882 continue;
1883 }
1884
1885 if (brcmf_check_rxbuf(bus, pkt, rxbuf, rxseq, nextlen,
1886 &len) < 0)
1887 continue;
1888
1889 /* Extract software header fields */
1890 chan = SDPCM_PACKET_CHANNEL(
1891 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1892 seq = SDPCM_PACKET_SEQUENCE(
1893 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1894 doff = SDPCM_DOFFSET_VALUE(
1895 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1896 txmax = SDPCM_WINDOW_VALUE(
1897 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1898
1899 bus->nextlen =
1900 bus->rxhdr[SDPCM_FRAMETAG_LEN +
1901 SDPCM_NEXTLEN_OFFSET];
1902 if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
1903 brcmf_dbg(INFO, "(nextlen): got frame w/nextlen too large (%d), seq %d\n",
1904 bus->nextlen, seq);
1905 bus->nextlen = 0;
1906 }
1907
1908 bus->drvr->rx_readahead_cnt++;
1909
1910 /* Handle Flow Control */
1911 fcbits = SDPCM_FCMASK_VALUE(
1912 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1913
1914 if (bus->flowcontrol != fcbits) {
1915 if (~bus->flowcontrol & fcbits)
1916 bus->fc_xoff++;
1917
1918 if (bus->flowcontrol & ~fcbits)
1919 bus->fc_xon++;
1920
1921 bus->fc_rcvd++;
1922 bus->flowcontrol = fcbits;
1923 }
1924
1925 /* Check and update sequence number */
1926 if (rxseq != seq) {
1927 brcmf_dbg(INFO, "(nextlen): rx_seq %d, expected %d\n",
1928 seq, rxseq);
1929 bus->rx_badseq++;
1930 rxseq = seq;
1931 }
1932
1933 /* Check window for sanity */
1934 if ((u8) (txmax - bus->tx_seq) > 0x40) {
1935 brcmf_dbg(ERROR, "got unlikely tx max %d with tx_seq %d\n",
1936 txmax, bus->tx_seq);
1937 txmax = bus->tx_seq + 2;
1938 }
1939 bus->tx_max = txmax;
1940
1941#ifdef BCMDBG
1942 if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
1943 printk(KERN_DEBUG "Rx Data:\n");
1944 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
1945 rxbuf, len);
1946 } else if (BRCMF_HDRS_ON()) {
1947 printk(KERN_DEBUG "RxHdr:\n");
1948 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
1949 bus->rxhdr, SDPCM_HDRLEN);
1950 }
1951#endif
1952
1953 if (chan == SDPCM_CONTROL_CHANNEL) {
1954 brcmf_dbg(ERROR, "(nextlen): readahead on control packet %d?\n",
1955 seq);
1956 /* Force retry w/normal header read */
1957 bus->nextlen = 0;
1958 brcmf_sdbrcm_rxfail(bus, false, true);
1959 brcmf_sdbrcm_pktfree2(bus, pkt);
1960 continue;
1961 }
1962
1963 /* Validate data offset */
1964 if ((doff < SDPCM_HDRLEN) || (doff > len)) {
1965 brcmf_dbg(ERROR, "(nextlen): bad data offset %d: HW len %d min %d\n",
1966 doff, len, SDPCM_HDRLEN);
1967 brcmf_sdbrcm_rxfail(bus, false, false);
1968 brcmf_sdbrcm_pktfree2(bus, pkt);
1969 continue;
1970 }
1971
1972 /* All done with this one -- now deliver the packet */
1973 goto deliver;
1974 }
1975
1976 /* Read frame header (hardware and software) */
1977 sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad,
1978 SDIO_FUNC_2, F2SYNC, bus->rxhdr,
1979 BRCMF_FIRSTREAD, NULL);
1980 bus->f2rxhdrs++;
1981
1982 if (sdret < 0) {
1983 brcmf_dbg(ERROR, "RXHEADER FAILED: %d\n", sdret);
1984 bus->rx_hdrfail++;
1985 brcmf_sdbrcm_rxfail(bus, true, true);
1986 continue;
1987 }
1988#ifdef BCMDBG
1989 if (BRCMF_BYTES_ON() || BRCMF_HDRS_ON()) {
1990 printk(KERN_DEBUG "RxHdr:\n");
1991 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
1992 bus->rxhdr, SDPCM_HDRLEN);
1993 }
1994#endif
1995
1996 /* Extract hardware header fields */
1997 len = get_unaligned_le16(bus->rxhdr);
1998 check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
1999
2000 /* All zeros means no more frames */
2001 if (!(len | check)) {
2002 *finished = true;
2003 break;
2004 }
2005
2006 /* Validate check bytes */
2007 if ((u16) ~(len ^ check)) {
2008 brcmf_dbg(ERROR, "HW hdr err: len/check 0x%04x/0x%04x\n",
2009 len, check);
2010 bus->rx_badhdr++;
2011 brcmf_sdbrcm_rxfail(bus, false, false);
2012 continue;
2013 }
2014
2015 /* Validate frame length */
2016 if (len < SDPCM_HDRLEN) {
2017 brcmf_dbg(ERROR, "HW hdr length invalid: %d\n", len);
2018 continue;
2019 }
2020
2021 /* Extract software header fields */
2022 chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
2023 seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
2024 doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
2025 txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
2026
2027 /* Validate data offset */
2028 if ((doff < SDPCM_HDRLEN) || (doff > len)) {
2029 brcmf_dbg(ERROR, "Bad data offset %d: HW len %d, min %d seq %d\n",
2030 doff, len, SDPCM_HDRLEN, seq);
2031 bus->rx_badhdr++;
2032 brcmf_sdbrcm_rxfail(bus, false, false);
2033 continue;
2034 }
2035
2036 /* Save the readahead length if there is one */
2037 bus->nextlen =
2038 bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
2039 if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
2040 brcmf_dbg(INFO, "(nextlen): got frame w/nextlen too large (%d), seq %d\n",
2041 bus->nextlen, seq);
2042 bus->nextlen = 0;
2043 }
2044
2045 /* Handle Flow Control */
2046 fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
2047
2048 if (bus->flowcontrol != fcbits) {
2049 if (~bus->flowcontrol & fcbits)
2050 bus->fc_xoff++;
2051
2052 if (bus->flowcontrol & ~fcbits)
2053 bus->fc_xon++;
2054
2055 bus->fc_rcvd++;
2056 bus->flowcontrol = fcbits;
2057 }
2058
2059 /* Check and update sequence number */
2060 if (rxseq != seq) {
2061 brcmf_dbg(INFO, "rx_seq %d, expected %d\n", seq, rxseq);
2062 bus->rx_badseq++;
2063 rxseq = seq;
2064 }
2065
2066 /* Check window for sanity */
2067 if ((u8) (txmax - bus->tx_seq) > 0x40) {
2068 brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n",
2069 txmax, bus->tx_seq);
2070 txmax = bus->tx_seq + 2;
2071 }
2072 bus->tx_max = txmax;
2073
2074 /* Call a separate function for control frames */
2075 if (chan == SDPCM_CONTROL_CHANNEL) {
2076 brcmf_sdbrcm_read_control(bus, bus->rxhdr, len, doff);
2077 continue;
2078 }
2079
2080 /* precondition: chan is either SDPCM_DATA_CHANNEL,
2081 SDPCM_EVENT_CHANNEL, SDPCM_TEST_CHANNEL or
2082 SDPCM_GLOM_CHANNEL */
2083
2084 /* Length to read */
2085 rdlen = (len > BRCMF_FIRSTREAD) ? (len - BRCMF_FIRSTREAD) : 0;
2086
2087 /* May pad read to blocksize for efficiency */
2088 if (bus->roundup && bus->blocksize &&
2089 (rdlen > bus->blocksize)) {
2090 pad = bus->blocksize - (rdlen % bus->blocksize);
2091 if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
2092 ((rdlen + pad + BRCMF_FIRSTREAD) < MAX_RX_DATASZ))
2093 rdlen += pad;
2094 } else if (rdlen % BRCMF_SDALIGN) {
2095 rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
2096 }
2097
2098 /* Satisfy length-alignment requirements */
2099 if (rdlen & (ALIGNMENT - 1))
2100 rdlen = roundup(rdlen, ALIGNMENT);
2101
2102 if ((rdlen + BRCMF_FIRSTREAD) > MAX_RX_DATASZ) {
2103 /* Too long -- skip this frame */
2104 brcmf_dbg(ERROR, "too long: len %d rdlen %d\n",
2105 len, rdlen);
2106 bus->drvr->rx_errors++;
2107 bus->rx_toolong++;
2108 brcmf_sdbrcm_rxfail(bus, false, false);
2109 continue;
2110 }
2111
2112 pkt = brcmu_pkt_buf_get_skb(rdlen +
2113 BRCMF_FIRSTREAD + BRCMF_SDALIGN);
2114 if (!pkt) {
2115 /* Give up on data, request rtx of events */
2116 brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: rdlen %d chan %d\n",
2117 rdlen, chan);
2118 bus->drvr->rx_dropped++;
2119 brcmf_sdbrcm_rxfail(bus, false, RETRYCHAN(chan));
2120 continue;
2121 }
2122
2123 /* Leave room for what we already read, and align remainder */
2124 skb_pull(pkt, BRCMF_FIRSTREAD);
2125 pkt_align(pkt, rdlen, BRCMF_SDALIGN);
2126
2127 /* Read the remaining frame data */
2128 sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad,
2129 SDIO_FUNC_2, F2SYNC, ((u8 *) (pkt->data)),
2130 rdlen, pkt);
2131 bus->f2rxdata++;
2132
2133 if (sdret < 0) {
2134 brcmf_dbg(ERROR, "read %d %s bytes failed: %d\n", rdlen,
2135 ((chan == SDPCM_EVENT_CHANNEL) ? "event"
2136 : ((chan == SDPCM_DATA_CHANNEL) ? "data"
2137 : "test")), sdret);
2138 brcmu_pkt_buf_free_skb(pkt);
2139 bus->drvr->rx_errors++;
2140 brcmf_sdbrcm_rxfail(bus, true, RETRYCHAN(chan));
2141 continue;
2142 }
2143
2144 /* Copy the already-read portion */
2145 skb_push(pkt, BRCMF_FIRSTREAD);
2146 memcpy(pkt->data, bus->rxhdr, BRCMF_FIRSTREAD);
2147
2148#ifdef BCMDBG
2149 if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
2150 printk(KERN_DEBUG "Rx Data:\n");
2151 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
2152 pkt->data, len);
2153 }
2154#endif
2155
2156deliver:
2157 /* Save superframe descriptor and allocate packet frame */
2158 if (chan == SDPCM_GLOM_CHANNEL) {
2159 if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) {
2160 brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n",
2161 len);
2162#ifdef BCMDBG
2163 if (BRCMF_GLOM_ON()) {
2164 printk(KERN_DEBUG "Glom Data:\n");
2165 print_hex_dump_bytes("",
2166 DUMP_PREFIX_OFFSET,
2167 pkt->data, len);
2168 }
2169#endif
2170 __skb_trim(pkt, len);
2171 skb_pull(pkt, SDPCM_HDRLEN);
2172 bus->glomd = pkt;
2173 } else {
2174 brcmf_dbg(ERROR, "%s: glom superframe w/o "
2175 "descriptor!\n", __func__);
2176 brcmf_sdbrcm_rxfail(bus, false, false);
2177 }
2178 continue;
2179 }
2180
2181 /* Fill in packet len and prio, deliver upward */
2182 __skb_trim(pkt, len);
2183 skb_pull(pkt, doff);
2184
2185 if (pkt->len == 0) {
2186 brcmu_pkt_buf_free_skb(pkt);
2187 continue;
2188 } else if (brcmf_proto_hdrpull(bus->drvr, &ifidx, pkt) != 0) {
2189 brcmf_dbg(ERROR, "rx protocol error\n");
2190 brcmu_pkt_buf_free_skb(pkt);
2191 bus->drvr->rx_errors++;
2192 continue;
2193 }
2194
2195 /* Unlock during rx call */
2196 up(&bus->sdsem);
2197 brcmf_rx_frame(bus->drvr, ifidx, pkt, 1);
2198 down(&bus->sdsem);
2199 }
2200 rxcount = maxframes - rxleft;
2201#ifdef BCMDBG
2202 /* Message if we hit the limit */
2203 if (!rxleft)
2204 brcmf_dbg(DATA, "hit rx limit of %d frames\n",
2205 maxframes);
2206 else
2207#endif /* BCMDBG */
2208 brcmf_dbg(DATA, "processed %d frames\n", rxcount);
2209 /* Back off rxseq if awaiting rtx, update rx_seq */
2210 if (bus->rxskip)
2211 rxseq--;
2212 bus->rx_seq = rxseq;
2213
2214 return rxcount;
2215}
2216
2217static int
2218brcmf_sdbrcm_send_buf(struct brcmf_bus *bus, u32 addr, uint fn, uint flags,
2219 u8 *buf, uint nbytes, struct sk_buff *pkt)
2220{
2221 return brcmf_sdcard_send_buf
2222 (bus->sdiodev, addr, fn, flags, buf, nbytes, pkt);
2223}
2224
2225static void
2226brcmf_sdbrcm_wait_for_event(struct brcmf_bus *bus, bool *lockvar)
2227{
2228 up(&bus->sdsem);
2229 wait_event_interruptible_timeout(bus->ctrl_wait,
2230 (*lockvar == false), HZ * 2);
2231 down(&bus->sdsem);
2232 return;
2233}
2234
2235static void
2236brcmf_sdbrcm_wait_event_wakeup(struct brcmf_bus *bus)
2237{
2238 if (waitqueue_active(&bus->ctrl_wait))
2239 wake_up_interruptible(&bus->ctrl_wait);
2240 return;
2241}
2242
2243/* Writes a HW/SW header into the packet and sends it. */
2244/* Assumes: (a) header space already there, (b) caller holds lock */
2245static int brcmf_sdbrcm_txpkt(struct brcmf_bus *bus, struct sk_buff *pkt,
2246 uint chan, bool free_pkt)
2247{
2248 int ret;
2249 u8 *frame;
2250 u16 len, pad = 0;
2251 u32 swheader;
2252 struct sk_buff *new;
2253 int i;
2254
2255 brcmf_dbg(TRACE, "Enter\n");
2256
2257 frame = (u8 *) (pkt->data);
2258
2259 /* Add alignment padding, allocate new packet if needed */
2260 pad = ((unsigned long)frame % BRCMF_SDALIGN);
2261 if (pad) {
2262 if (skb_headroom(pkt) < pad) {
2263 brcmf_dbg(INFO, "insufficient headroom %d for %d pad\n",
2264 skb_headroom(pkt), pad);
2265 bus->drvr->tx_realloc++;
2266 new = brcmu_pkt_buf_get_skb(pkt->len + BRCMF_SDALIGN);
2267 if (!new) {
2268 brcmf_dbg(ERROR, "couldn't allocate new %d-byte packet\n",
2269 pkt->len + BRCMF_SDALIGN);
2270 ret = -ENOMEM;
2271 goto done;
2272 }
2273
2274 pkt_align(new, pkt->len, BRCMF_SDALIGN);
2275 memcpy(new->data, pkt->data, pkt->len);
2276 if (free_pkt)
2277 brcmu_pkt_buf_free_skb(pkt);
2278 /* free the pkt if canned one is not used */
2279 free_pkt = true;
2280 pkt = new;
2281 frame = (u8 *) (pkt->data);
2282 /* precondition: (frame % BRCMF_SDALIGN) == 0) */
2283 pad = 0;
2284 } else {
2285 skb_push(pkt, pad);
2286 frame = (u8 *) (pkt->data);
2287 /* precondition: pad + SDPCM_HDRLEN <= pkt->len */
2288 memset(frame, 0, pad + SDPCM_HDRLEN);
2289 }
2290 }
2291 /* precondition: pad < BRCMF_SDALIGN */
2292
2293 /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
2294 len = (u16) (pkt->len);
2295 *(__le16 *) frame = cpu_to_le16(len);
2296 *(((__le16 *) frame) + 1) = cpu_to_le16(~len);
2297
2298 /* Software tag: channel, sequence number, data offset */
2299 swheader =
2300 ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq |
2301 (((pad +
2302 SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK);
2303
2304 put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
2305 put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
2306
2307#ifdef BCMDBG
2308 tx_packets[pkt->priority]++;
2309 if (BRCMF_BYTES_ON() &&
2310 (((BRCMF_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) ||
2311 (BRCMF_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) {
2312 printk(KERN_DEBUG "Tx Frame:\n");
2313 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len);
2314 } else if (BRCMF_HDRS_ON()) {
2315 printk(KERN_DEBUG "TxHdr:\n");
2316 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
2317 frame, min_t(u16, len, 16));
2318 }
2319#endif
2320
2321 /* Raise len to next SDIO block to eliminate tail command */
2322 if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
2323 u16 pad = bus->blocksize - (len % bus->blocksize);
2324 if ((pad <= bus->roundup) && (pad < bus->blocksize))
2325 len += pad;
2326 } else if (len % BRCMF_SDALIGN) {
2327 len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN);
2328 }
2329
2330 /* Some controllers have trouble with odd bytes -- round to even */
2331 if (len & (ALIGNMENT - 1))
2332 len = roundup(len, ALIGNMENT);
2333
2334 ret = brcmf_sdbrcm_send_buf(bus, bus->sdiodev->sbwad,
2335 SDIO_FUNC_2, F2SYNC, frame,
2336 len, pkt);
2337 bus->f2txdata++;
2338
2339 if (ret < 0) {
2340 /* On failure, abort the command and terminate the frame */
2341 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
2342 ret);
2343 bus->tx_sderrs++;
2344
2345 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
2346 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
2347 SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM,
2348 NULL);
2349 bus->f1regdata++;
2350
2351 for (i = 0; i < 3; i++) {
2352 u8 hi, lo;
2353 hi = brcmf_sdcard_cfg_read(bus->sdiodev,
2354 SDIO_FUNC_1,
2355 SBSDIO_FUNC1_WFRAMEBCHI,
2356 NULL);
2357 lo = brcmf_sdcard_cfg_read(bus->sdiodev,
2358 SDIO_FUNC_1,
2359 SBSDIO_FUNC1_WFRAMEBCLO,
2360 NULL);
2361 bus->f1regdata += 2;
2362 if ((hi == 0) && (lo == 0))
2363 break;
2364 }
2365
2366 }
2367 if (ret == 0)
2368 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
2369
2370done:
2371 /* restore pkt buffer pointer before calling tx complete routine */
2372 skb_pull(pkt, SDPCM_HDRLEN + pad);
2373 up(&bus->sdsem);
2374 brcmf_txcomplete(bus->drvr, pkt, ret != 0);
2375 down(&bus->sdsem);
2376
2377 if (free_pkt)
2378 brcmu_pkt_buf_free_skb(pkt);
2379
2380 return ret;
2381}
2382
2383static uint brcmf_sdbrcm_sendfromq(struct brcmf_bus *bus, uint maxframes)
2384{
2385 struct sk_buff *pkt;
2386 u32 intstatus = 0;
2387 uint retries = 0;
2388 int ret = 0, prec_out;
2389 uint cnt = 0;
2390 uint datalen;
2391 u8 tx_prec_map;
2392
2393 struct brcmf_pub *drvr = bus->drvr;
2394
2395 brcmf_dbg(TRACE, "Enter\n");
2396
2397 tx_prec_map = ~bus->flowcontrol;
2398
2399 /* Send frames until the limit or some other event */
2400 for (cnt = 0; (cnt < maxframes) && data_ok(bus); cnt++) {
2401 spin_lock_bh(&bus->txqlock);
2402 pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
2403 if (pkt == NULL) {
2404 spin_unlock_bh(&bus->txqlock);
2405 break;
2406 }
2407 spin_unlock_bh(&bus->txqlock);
2408 datalen = pkt->len - SDPCM_HDRLEN;
2409
2410 ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
2411 if (ret)
2412 bus->drvr->tx_errors++;
2413 else
2414 bus->drvr->dstats.tx_bytes += datalen;
2415
2416 /* In poll mode, need to check for other events */
2417 if (!bus->intr && cnt) {
2418 /* Check device status, signal pending interrupt */
2419 r_sdreg32(bus, &intstatus,
2420 offsetof(struct sdpcmd_regs, intstatus),
2421 &retries);
2422 bus->f2txdata++;
2423 if (brcmf_sdcard_regfail(bus->sdiodev))
2424 break;
2425 if (intstatus & bus->hostintmask)
2426 bus->ipend = true;
2427 }
2428 }
2429
2430 /* Deflow-control stack if needed */
2431 if (drvr->up && (drvr->busstate == BRCMF_BUS_DATA) &&
2432 drvr->txoff && (pktq_len(&bus->txq) < TXLOW))
2433 brcmf_txflowcontrol(drvr, 0, OFF);
2434
2435 return cnt;
2436}
2437
2438static bool brcmf_sdbrcm_dpc(struct brcmf_bus *bus)
2439{
2440 u32 intstatus, newstatus = 0;
2441 uint retries = 0;
2442 uint rxlimit = bus->rxbound; /* Rx frames to read before resched */
2443 uint txlimit = bus->txbound; /* Tx frames to send before resched */
2444 uint framecnt = 0; /* Temporary counter of tx/rx frames */
2445 bool rxdone = true; /* Flag for no more read data */
2446 bool resched = false; /* Flag indicating resched wanted */
2447
2448 brcmf_dbg(TRACE, "Enter\n");
2449
2450 /* Start with leftover status bits */
2451 intstatus = bus->intstatus;
2452
2453 down(&bus->sdsem);
2454
2455 /* If waiting for HTAVAIL, check status */
2456 if (bus->clkstate == CLK_PENDING) {
2457 int err;
2458 u8 clkctl, devctl = 0;
2459
2460#ifdef BCMDBG
2461 /* Check for inconsistent device control */
2462 devctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
2463 SBSDIO_DEVICE_CTL, &err);
2464 if (err) {
2465 brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err);
2466 bus->drvr->busstate = BRCMF_BUS_DOWN;
2467 }
2468#endif /* BCMDBG */
2469
2470 /* Read CSR, if clock on switch to AVAIL, else ignore */
2471 clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
2472 SBSDIO_FUNC1_CHIPCLKCSR, &err);
2473 if (err) {
2474 brcmf_dbg(ERROR, "error reading CSR: %d\n",
2475 err);
2476 bus->drvr->busstate = BRCMF_BUS_DOWN;
2477 }
2478
2479 brcmf_dbg(INFO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n",
2480 devctl, clkctl);
2481
2482 if (SBSDIO_HTAV(clkctl)) {
2483 devctl = brcmf_sdcard_cfg_read(bus->sdiodev,
2484 SDIO_FUNC_1,
2485 SBSDIO_DEVICE_CTL, &err);
2486 if (err) {
2487 brcmf_dbg(ERROR, "error reading DEVCTL: %d\n",
2488 err);
2489 bus->drvr->busstate = BRCMF_BUS_DOWN;
2490 }
2491 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
2492 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
2493 SBSDIO_DEVICE_CTL, devctl, &err);
2494 if (err) {
2495 brcmf_dbg(ERROR, "error writing DEVCTL: %d\n",
2496 err);
2497 bus->drvr->busstate = BRCMF_BUS_DOWN;
2498 }
2499 bus->clkstate = CLK_AVAIL;
2500 } else {
2501 goto clkwait;
2502 }
2503 }
2504
2505 bus_wake(bus);
2506
2507 /* Make sure backplane clock is on */
2508 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true);
2509 if (bus->clkstate == CLK_PENDING)
2510 goto clkwait;
2511
2512 /* Pending interrupt indicates new device status */
2513 if (bus->ipend) {
2514 bus->ipend = false;
2515 r_sdreg32(bus, &newstatus,
2516 offsetof(struct sdpcmd_regs, intstatus), &retries);
2517 bus->f1regdata++;
2518 if (brcmf_sdcard_regfail(bus->sdiodev))
2519 newstatus = 0;
2520 newstatus &= bus->hostintmask;
2521 bus->fcstate = !!(newstatus & I_HMB_FC_STATE);
2522 if (newstatus) {
2523 w_sdreg32(bus, newstatus,
2524 offsetof(struct sdpcmd_regs, intstatus),
2525 &retries);
2526 bus->f1regdata++;
2527 }
2528 }
2529
2530 /* Merge new bits with previous */
2531 intstatus |= newstatus;
2532 bus->intstatus = 0;
2533
2534 /* Handle flow-control change: read new state in case our ack
2535 * crossed another change interrupt. If change still set, assume
2536 * FC ON for safety, let next loop through do the debounce.
2537 */
2538 if (intstatus & I_HMB_FC_CHANGE) {
2539 intstatus &= ~I_HMB_FC_CHANGE;
2540 w_sdreg32(bus, I_HMB_FC_CHANGE,
2541 offsetof(struct sdpcmd_regs, intstatus), &retries);
2542
2543 r_sdreg32(bus, &newstatus,
2544 offsetof(struct sdpcmd_regs, intstatus), &retries);
2545 bus->f1regdata += 2;
2546 bus->fcstate =
2547 !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE));
2548 intstatus |= (newstatus & bus->hostintmask);
2549 }
2550
2551 /* Handle host mailbox indication */
2552 if (intstatus & I_HMB_HOST_INT) {
2553 intstatus &= ~I_HMB_HOST_INT;
2554 intstatus |= brcmf_sdbrcm_hostmail(bus);
2555 }
2556
2557 /* Generally don't ask for these, can get CRC errors... */
2558 if (intstatus & I_WR_OOSYNC) {
2559 brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n");
2560 intstatus &= ~I_WR_OOSYNC;
2561 }
2562
2563 if (intstatus & I_RD_OOSYNC) {
2564 brcmf_dbg(ERROR, "Dongle reports RD_OOSYNC\n");
2565 intstatus &= ~I_RD_OOSYNC;
2566 }
2567
2568 if (intstatus & I_SBINT) {
2569 brcmf_dbg(ERROR, "Dongle reports SBINT\n");
2570 intstatus &= ~I_SBINT;
2571 }
2572
2573 /* Would be active due to wake-wlan in gSPI */
2574 if (intstatus & I_CHIPACTIVE) {
2575 brcmf_dbg(INFO, "Dongle reports CHIPACTIVE\n");
2576 intstatus &= ~I_CHIPACTIVE;
2577 }
2578
2579 /* Ignore frame indications if rxskip is set */
2580 if (bus->rxskip)
2581 intstatus &= ~I_HMB_FRAME_IND;
2582
2583 /* On frame indication, read available frames */
2584 if (PKT_AVAILABLE()) {
2585 framecnt = brcmf_sdbrcm_readframes(bus, rxlimit, &rxdone);
2586 if (rxdone || bus->rxskip)
2587 intstatus &= ~I_HMB_FRAME_IND;
2588 rxlimit -= min(framecnt, rxlimit);
2589 }
2590
2591 /* Keep still-pending events for next scheduling */
2592 bus->intstatus = intstatus;
2593
2594clkwait:
2595 if (data_ok(bus) && bus->ctrl_frame_stat &&
2596 (bus->clkstate == CLK_AVAIL)) {
2597 int ret, i;
2598
2599 ret = brcmf_sdbrcm_send_buf(bus, bus->sdiodev->sbwad,
2600 SDIO_FUNC_2, F2SYNC, (u8 *) bus->ctrl_frame_buf,
2601 (u32) bus->ctrl_frame_len, NULL);
2602
2603 if (ret < 0) {
2604 /* On failure, abort the command and
2605 terminate the frame */
2606 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
2607 ret);
2608 bus->tx_sderrs++;
2609
2610 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
2611
2612 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
2613 SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM,
2614 NULL);
2615 bus->f1regdata++;
2616
2617 for (i = 0; i < 3; i++) {
2618 u8 hi, lo;
2619 hi = brcmf_sdcard_cfg_read(bus->sdiodev,
2620 SDIO_FUNC_1,
2621 SBSDIO_FUNC1_WFRAMEBCHI,
2622 NULL);
2623 lo = brcmf_sdcard_cfg_read(bus->sdiodev,
2624 SDIO_FUNC_1,
2625 SBSDIO_FUNC1_WFRAMEBCLO,
2626 NULL);
2627 bus->f1regdata += 2;
2628 if ((hi == 0) && (lo == 0))
2629 break;
2630 }
2631
2632 }
2633 if (ret == 0)
2634 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
2635
2636 brcmf_dbg(INFO, "Return_dpc value is : %d\n", ret);
2637 bus->ctrl_frame_stat = false;
2638 brcmf_sdbrcm_wait_event_wakeup(bus);
2639 }
2640 /* Send queued frames (limit 1 if rx may still be pending) */
2641 else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate &&
2642 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
2643 && data_ok(bus)) {
2644 framecnt = rxdone ? txlimit : min(txlimit, bus->txminmax);
2645 framecnt = brcmf_sdbrcm_sendfromq(bus, framecnt);
2646 txlimit -= framecnt;
2647 }
2648
2649 /* Resched if events or tx frames are pending,
2650 else await next interrupt */
2651 /* On failed register access, all bets are off:
2652 no resched or interrupts */
2653 if ((bus->drvr->busstate == BRCMF_BUS_DOWN) ||
2654 brcmf_sdcard_regfail(bus->sdiodev)) {
2655 brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation %d\n",
2656 brcmf_sdcard_regfail(bus->sdiodev));
2657 bus->drvr->busstate = BRCMF_BUS_DOWN;
2658 bus->intstatus = 0;
2659 } else if (bus->clkstate == CLK_PENDING) {
2660 brcmf_dbg(INFO, "rescheduled due to CLK_PENDING awaiting I_CHIPACTIVE interrupt\n");
2661 resched = true;
2662 } else if (bus->intstatus || bus->ipend ||
2663 (!bus->fcstate && brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol)
2664 && data_ok(bus)) || PKT_AVAILABLE()) {
2665 resched = true;
2666 }
2667
2668 bus->dpc_sched = resched;
2669
2670 /* If we're done for now, turn off clock request. */
2671 if ((bus->clkstate != CLK_PENDING)
2672 && bus->idletime == BRCMF_IDLE_IMMEDIATE) {
2673 bus->activity = false;
2674 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
2675 }
2676
2677 up(&bus->sdsem);
2678
2679 return resched;
2680}
2681
2682static int brcmf_sdbrcm_dpc_thread(void *data)
2683{
2684 struct brcmf_bus *bus = (struct brcmf_bus *) data;
2685
2686 allow_signal(SIGTERM);
2687 /* Run until signal received */
2688 while (1) {
2689 if (kthread_should_stop())
2690 break;
2691 if (!wait_for_completion_interruptible(&bus->dpc_wait)) {
2692 /* Call bus dpc unless it indicated down
2693 (then clean stop) */
2694 if (bus->drvr->busstate != BRCMF_BUS_DOWN) {
2695 if (brcmf_sdbrcm_dpc(bus))
2696 complete(&bus->dpc_wait);
2697 } else {
2698 /* after stopping the bus, exit thread */
2699 brcmf_sdbrcm_bus_stop(bus);
2700 bus->dpc_tsk = NULL;
2701 break;
2702 }
2703 } else
2704 break;
2705 }
2706 return 0;
2707}
2708
2709int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *pkt)
2710{
2711 int ret = -EBADE;
2712 uint datalen, prec;
2713
2714 brcmf_dbg(TRACE, "Enter\n");
2715
2716 datalen = pkt->len;
2717
2718 /* Add space for the header */
2719 skb_push(pkt, SDPCM_HDRLEN);
2720 /* precondition: IS_ALIGNED((unsigned long)(pkt->data), 2) */
2721
2722 prec = prio2prec((pkt->priority & PRIOMASK));
2723
2724 /* Check for existing queue, current flow-control,
2725 pending event, or pending clock */
2726 brcmf_dbg(TRACE, "deferring pktq len %d\n", pktq_len(&bus->txq));
2727 bus->fcqueued++;
2728
2729 /* Priority based enq */
2730 spin_lock_bh(&bus->txqlock);
2731 if (brcmf_c_prec_enq(bus->drvr, &bus->txq, pkt, prec) == false) {
2732 skb_pull(pkt, SDPCM_HDRLEN);
2733 brcmf_txcomplete(bus->drvr, pkt, false);
2734 brcmu_pkt_buf_free_skb(pkt);
2735 brcmf_dbg(ERROR, "out of bus->txq !!!\n");
2736 ret = -ENOSR;
2737 } else {
2738 ret = 0;
2739 }
2740 spin_unlock_bh(&bus->txqlock);
2741
2742 if (pktq_len(&bus->txq) >= TXHI)
2743 brcmf_txflowcontrol(bus->drvr, 0, ON);
2744
2745#ifdef BCMDBG
2746 if (pktq_plen(&bus->txq, prec) > qcount[prec])
2747 qcount[prec] = pktq_plen(&bus->txq, prec);
2748#endif
2749 /* Schedule DPC if needed to send queued packet(s) */
2750 if (!bus->dpc_sched) {
2751 bus->dpc_sched = true;
2752 if (bus->dpc_tsk)
2753 complete(&bus->dpc_wait);
2754 }
2755
2756 return ret;
2757}
2758
2759static int
2760brcmf_sdbrcm_membytes(struct brcmf_bus *bus, bool write, u32 address, u8 *data,
2761 uint size)
2762{
2763 int bcmerror = 0;
2764 u32 sdaddr;
2765 uint dsize;
2766
2767 /* Determine initial transfer parameters */
2768 sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
2769 if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
2770 dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
2771 else
2772 dsize = size;
2773
2774 /* Set the backplane window to include the start address */
2775 bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev, address);
2776 if (bcmerror) {
2777 brcmf_dbg(ERROR, "window change failed\n");
2778 goto xfer_done;
2779 }
2780
2781 /* Do the transfer(s) */
2782 while (size) {
2783 brcmf_dbg(INFO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",
2784 write ? "write" : "read", dsize,
2785 sdaddr, address & SBSDIO_SBWINDOW_MASK);
2786 bcmerror = brcmf_sdcard_rwdata(bus->sdiodev, write,
2787 sdaddr, data, dsize);
2788 if (bcmerror) {
2789 brcmf_dbg(ERROR, "membytes transfer failed\n");
2790 break;
2791 }
2792
2793 /* Adjust for next transfer (if any) */
2794 size -= dsize;
2795 if (size) {
2796 data += dsize;
2797 address += dsize;
2798 bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev,
2799 address);
2800 if (bcmerror) {
2801 brcmf_dbg(ERROR, "window change failed\n");
2802 break;
2803 }
2804 sdaddr = 0;
2805 dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
2806 }
2807 }
2808
2809xfer_done:
2810 /* Return the window to backplane enumeration space for core access */
2811 if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, bus->sdiodev->sbwad))
2812 brcmf_dbg(ERROR, "FAILED to set window back to 0x%x\n",
2813 bus->sdiodev->sbwad);
2814
2815 return bcmerror;
2816}
2817
2818#ifdef BCMDBG
2819#define CONSOLE_LINE_MAX 192
2820
2821static int brcmf_sdbrcm_readconsole(struct brcmf_bus *bus)
2822{
2823 struct brcmf_console *c = &bus->console;
2824 u8 line[CONSOLE_LINE_MAX], ch;
2825 u32 n, idx, addr;
2826 int rv;
2827
2828 /* Don't do anything until FWREADY updates console address */
2829 if (bus->console_addr == 0)
2830 return 0;
2831
2832 /* Read console log struct */
2833 addr = bus->console_addr + offsetof(struct rte_console, log_le);
2834 rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&c->log_le,
2835 sizeof(c->log_le));
2836 if (rv < 0)
2837 return rv;
2838
2839 /* Allocate console buffer (one time only) */
2840 if (c->buf == NULL) {
2841 c->bufsize = le32_to_cpu(c->log_le.buf_size);
2842 c->buf = kmalloc(c->bufsize, GFP_ATOMIC);
2843 if (c->buf == NULL)
2844 return -ENOMEM;
2845 }
2846
2847 idx = le32_to_cpu(c->log_le.idx);
2848
2849 /* Protect against corrupt value */
2850 if (idx > c->bufsize)
2851 return -EBADE;
2852
2853 /* Skip reading the console buffer if the index pointer
2854 has not moved */
2855 if (idx == c->last)
2856 return 0;
2857
2858 /* Read the console buffer */
2859 addr = le32_to_cpu(c->log_le.buf);
2860 rv = brcmf_sdbrcm_membytes(bus, false, addr, c->buf, c->bufsize);
2861 if (rv < 0)
2862 return rv;
2863
2864 while (c->last != idx) {
2865 for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) {
2866 if (c->last == idx) {
2867 /* This would output a partial line.
2868 * Instead, back up
2869 * the buffer pointer and output this
2870 * line next time around.
2871 */
2872 if (c->last >= n)
2873 c->last -= n;
2874 else
2875 c->last = c->bufsize - n;
2876 goto break2;
2877 }
2878 ch = c->buf[c->last];
2879 c->last = (c->last + 1) % c->bufsize;
2880 if (ch == '\n')
2881 break;
2882 line[n] = ch;
2883 }
2884
2885 if (n > 0) {
2886 if (line[n - 1] == '\r')
2887 n--;
2888 line[n] = 0;
2889 printk(KERN_DEBUG "CONSOLE: %s\n", line);
2890 }
2891 }
2892break2:
2893
2894 return 0;
2895}
2896#endif /* BCMDBG */
2897
2898static int brcmf_tx_frame(struct brcmf_bus *bus, u8 *frame, u16 len)
2899{
2900 int i;
2901 int ret;
2902
2903 bus->ctrl_frame_stat = false;
2904 ret = brcmf_sdbrcm_send_buf(bus, bus->sdiodev->sbwad,
2905 SDIO_FUNC_2, F2SYNC, frame, len, NULL);
2906
2907 if (ret < 0) {
2908 /* On failure, abort the command and terminate the frame */
2909 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
2910 ret);
2911 bus->tx_sderrs++;
2912
2913 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
2914
2915 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
2916 SBSDIO_FUNC1_FRAMECTRL,
2917 SFC_WF_TERM, NULL);
2918 bus->f1regdata++;
2919
2920 for (i = 0; i < 3; i++) {
2921 u8 hi, lo;
2922 hi = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
2923 SBSDIO_FUNC1_WFRAMEBCHI,
2924 NULL);
2925 lo = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
2926 SBSDIO_FUNC1_WFRAMEBCLO,
2927 NULL);
2928 bus->f1regdata += 2;
2929 if (hi == 0 && lo == 0)
2930 break;
2931 }
2932 return ret;
2933 }
2934
2935 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
2936
2937 return ret;
2938}
2939
2940int
2941brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen)
2942{
2943 u8 *frame;
2944 u16 len;
2945 u32 swheader;
2946 uint retries = 0;
2947 u8 doff = 0;
2948 int ret = -1;
2949
2950 brcmf_dbg(TRACE, "Enter\n");
2951
2952 /* Back the pointer to make a room for bus header */
2953 frame = msg - SDPCM_HDRLEN;
2954 len = (msglen += SDPCM_HDRLEN);
2955
2956 /* Add alignment padding (optional for ctl frames) */
2957 doff = ((unsigned long)frame % BRCMF_SDALIGN);
2958 if (doff) {
2959 frame -= doff;
2960 len += doff;
2961 msglen += doff;
2962 memset(frame, 0, doff + SDPCM_HDRLEN);
2963 }
2964 /* precondition: doff < BRCMF_SDALIGN */
2965 doff += SDPCM_HDRLEN;
2966
2967 /* Round send length to next SDIO block */
2968 if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
2969 u16 pad = bus->blocksize - (len % bus->blocksize);
2970 if ((pad <= bus->roundup) && (pad < bus->blocksize))
2971 len += pad;
2972 } else if (len % BRCMF_SDALIGN) {
2973 len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN);
2974 }
2975
2976 /* Satisfy length-alignment requirements */
2977 if (len & (ALIGNMENT - 1))
2978 len = roundup(len, ALIGNMENT);
2979
2980 /* precondition: IS_ALIGNED((unsigned long)frame, 2) */
2981
2982 /* Need to lock here to protect txseq and SDIO tx calls */
2983 down(&bus->sdsem);
2984
2985 bus_wake(bus);
2986
2987 /* Make sure backplane clock is on */
2988 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
2989
2990 /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
2991 *(__le16 *) frame = cpu_to_le16((u16) msglen);
2992 *(((__le16 *) frame) + 1) = cpu_to_le16(~msglen);
2993
2994 /* Software tag: channel, sequence number, data offset */
2995 swheader =
2996 ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) &
2997 SDPCM_CHANNEL_MASK)
2998 | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) &
2999 SDPCM_DOFFSET_MASK);
3000 put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
3001 put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
3002
3003 if (!data_ok(bus)) {
3004 brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
3005 bus->tx_max, bus->tx_seq);
3006 bus->ctrl_frame_stat = true;
3007 /* Send from dpc */
3008 bus->ctrl_frame_buf = frame;
3009 bus->ctrl_frame_len = len;
3010
3011 brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat);
3012
3013 if (bus->ctrl_frame_stat == false) {
3014 brcmf_dbg(INFO, "ctrl_frame_stat == false\n");
3015 ret = 0;
3016 } else {
3017 brcmf_dbg(INFO, "ctrl_frame_stat == true\n");
3018 ret = -1;
3019 }
3020 }
3021
3022 if (ret == -1) {
3023#ifdef BCMDBG
3024 if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) {
3025 printk(KERN_DEBUG "Tx Frame:\n");
3026 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
3027 frame, len);
3028 } else if (BRCMF_HDRS_ON()) {
3029 printk(KERN_DEBUG "TxHdr:\n");
3030 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
3031 frame, min_t(u16, len, 16));
3032 }
3033#endif
3034
3035 do {
3036 ret = brcmf_tx_frame(bus, frame, len);
3037 } while (ret < 0 && retries++ < TXRETRIES);
3038 }
3039
3040 if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) {
3041 bus->activity = false;
3042 brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
3043 }
3044
3045 up(&bus->sdsem);
3046
3047 if (ret)
3048 bus->drvr->tx_ctlerrs++;
3049 else
3050 bus->drvr->tx_ctlpkts++;
3051
3052 return ret ? -EIO : 0;
3053}
3054
3055int
3056brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen)
3057{
3058 int timeleft;
3059 uint rxlen = 0;
3060 bool pending;
3061
3062 brcmf_dbg(TRACE, "Enter\n");
3063
3064 /* Wait until control frame is available */
3065 timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending);
3066
3067 down(&bus->sdsem);
3068 rxlen = bus->rxlen;
3069 memcpy(msg, bus->rxctl, min(msglen, rxlen));
3070 bus->rxlen = 0;
3071 up(&bus->sdsem);
3072
3073 if (rxlen) {
3074 brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n",
3075 rxlen, msglen);
3076 } else if (timeleft == 0) {
3077 brcmf_dbg(ERROR, "resumed on timeout\n");
3078 } else if (pending == true) {
3079 brcmf_dbg(CTL, "cancelled\n");
3080 return -ERESTARTSYS;
3081 } else {
3082 brcmf_dbg(CTL, "resumed for unknown reason?\n");
3083 }
3084
3085 if (rxlen)
3086 bus->drvr->rx_ctlpkts++;
3087 else
3088 bus->drvr->rx_ctlerrs++;
3089
3090 return rxlen ? (int)rxlen : -ETIMEDOUT;
3091}
3092
3093static int brcmf_sdbrcm_downloadvars(struct brcmf_bus *bus, void *arg, int len)
3094{
3095 int bcmerror = 0;
3096
3097 brcmf_dbg(TRACE, "Enter\n");
3098
3099 /* Basic sanity checks */
3100 if (bus->drvr->up) {
3101 bcmerror = -EISCONN;
3102 goto err;
3103 }
3104 if (!len) {
3105 bcmerror = -EOVERFLOW;
3106 goto err;
3107 }
3108
3109 /* Free the old ones and replace with passed variables */
3110 kfree(bus->vars);
3111
3112 bus->vars = kmalloc(len, GFP_ATOMIC);
3113 bus->varsz = bus->vars ? len : 0;
3114 if (bus->vars == NULL) {
3115 bcmerror = -ENOMEM;
3116 goto err;
3117 }
3118
3119 /* Copy the passed variables, which should include the
3120 terminating double-null */
3121 memcpy(bus->vars, arg, bus->varsz);
3122err:
3123 return bcmerror;
3124}
3125
3126static int brcmf_sdbrcm_write_vars(struct brcmf_bus *bus)
3127{
3128 int bcmerror = 0;
3129 u32 varsize;
3130 u32 varaddr;
3131 u8 *vbuffer;
3132 u32 varsizew;
3133 __le32 varsizew_le;
3134#ifdef BCMDBG
3135 char *nvram_ularray;
3136#endif /* BCMDBG */
3137
3138 /* Even if there are no vars are to be written, we still
3139 need to set the ramsize. */
3140 varsize = bus->varsz ? roundup(bus->varsz, 4) : 0;
3141 varaddr = (bus->ramsize - 4) - varsize;
3142
3143 if (bus->vars) {
3144 vbuffer = kzalloc(varsize, GFP_ATOMIC);
3145 if (!vbuffer)
3146 return -ENOMEM;
3147
3148 memcpy(vbuffer, bus->vars, bus->varsz);
3149
3150 /* Write the vars list */
3151 bcmerror =
3152 brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize);
3153#ifdef BCMDBG
3154 /* Verify NVRAM bytes */
3155 brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize);
3156 nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
3157 if (!nvram_ularray)
3158 return -ENOMEM;
3159
3160 /* Upload image to verify downloaded contents. */
3161 memset(nvram_ularray, 0xaa, varsize);
3162
3163 /* Read the vars list to temp buffer for comparison */
3164 bcmerror =
3165 brcmf_sdbrcm_membytes(bus, false, varaddr, nvram_ularray,
3166 varsize);
3167 if (bcmerror) {
3168 brcmf_dbg(ERROR, "error %d on reading %d nvram bytes at 0x%08x\n",
3169 bcmerror, varsize, varaddr);
3170 }
3171 /* Compare the org NVRAM with the one read from RAM */
3172 if (memcmp(vbuffer, nvram_ularray, varsize))
3173 brcmf_dbg(ERROR, "Downloaded NVRAM image is corrupted\n");
3174 else
3175 brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n");
3176
3177 kfree(nvram_ularray);
3178#endif /* BCMDBG */
3179
3180 kfree(vbuffer);
3181 }
3182
3183 /* adjust to the user specified RAM */
3184 brcmf_dbg(INFO, "Physical memory size: %d\n", bus->ramsize);
3185 brcmf_dbg(INFO, "Vars are at %d, orig varsize is %d\n",
3186 varaddr, varsize);
3187 varsize = ((bus->ramsize - 4) - varaddr);
3188
3189 /*
3190 * Determine the length token:
3191 * Varsize, converted to words, in lower 16-bits, checksum
3192 * in upper 16-bits.
3193 */
3194 if (bcmerror) {
3195 varsizew = 0;
3196 varsizew_le = cpu_to_le32(0);
3197 } else {
3198 varsizew = varsize / 4;
3199 varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
3200 varsizew_le = cpu_to_le32(varsizew);
3201 }
3202
3203 brcmf_dbg(INFO, "New varsize is %d, length token=0x%08x\n",
3204 varsize, varsizew);
3205
3206 /* Write the length token to the last word */
3207 bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4),
3208 (u8 *)&varsizew_le, 4);
3209
3210 return bcmerror;
3211}
3212
3213static void
3214brcmf_sdbrcm_chip_disablecore(struct brcmf_sdio_dev *sdiodev, u32 corebase)
3215{
3216 u32 regdata;
3217
3218 regdata = brcmf_sdcard_reg_read(sdiodev,
3219 CORE_SB(corebase, sbtmstatelow), 4);
3220 if (regdata & SBTML_RESET)
3221 return;
3222
3223 regdata = brcmf_sdcard_reg_read(sdiodev,
3224 CORE_SB(corebase, sbtmstatelow), 4);
3225 if ((regdata & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) != 0) {
3226 /*
3227 * set target reject and spin until busy is clear
3228 * (preserve core-specific bits)
3229 */
3230 regdata = brcmf_sdcard_reg_read(sdiodev,
3231 CORE_SB(corebase, sbtmstatelow), 4);
3232 brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow),
3233 4, regdata | SBTML_REJ);
3234
3235 regdata = brcmf_sdcard_reg_read(sdiodev,
3236 CORE_SB(corebase, sbtmstatelow), 4);
3237 udelay(1);
3238 SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
3239 CORE_SB(corebase, sbtmstatehigh), 4) &
3240 SBTMH_BUSY), 100000);
3241
3242 regdata = brcmf_sdcard_reg_read(sdiodev,
3243 CORE_SB(corebase, sbtmstatehigh), 4);
3244 if (regdata & SBTMH_BUSY)
3245 brcmf_dbg(ERROR, "ARM core still busy\n");
3246
3247 regdata = brcmf_sdcard_reg_read(sdiodev,
3248 CORE_SB(corebase, sbidlow), 4);
3249 if (regdata & SBIDL_INIT) {
3250 regdata = brcmf_sdcard_reg_read(sdiodev,
3251 CORE_SB(corebase, sbimstate), 4) |
3252 SBIM_RJ;
3253 brcmf_sdcard_reg_write(sdiodev,
3254 CORE_SB(corebase, sbimstate), 4,
3255 regdata);
3256 regdata = brcmf_sdcard_reg_read(sdiodev,
3257 CORE_SB(corebase, sbimstate), 4);
3258 udelay(1);
3259 SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
3260 CORE_SB(corebase, sbimstate), 4) &
3261 SBIM_BY), 100000);
3262 }
3263
3264 /* set reset and reject while enabling the clocks */
3265 brcmf_sdcard_reg_write(sdiodev,
3266 CORE_SB(corebase, sbtmstatelow), 4,
3267 (((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
3268 SBTML_REJ | SBTML_RESET));
3269 regdata = brcmf_sdcard_reg_read(sdiodev,
3270 CORE_SB(corebase, sbtmstatelow), 4);
3271 udelay(10);
3272
3273 /* clear the initiator reject bit */
3274 regdata = brcmf_sdcard_reg_read(sdiodev,
3275 CORE_SB(corebase, sbidlow), 4);
3276 if (regdata & SBIDL_INIT) {
3277 regdata = brcmf_sdcard_reg_read(sdiodev,
3278 CORE_SB(corebase, sbimstate), 4) &
3279 ~SBIM_RJ;
3280 brcmf_sdcard_reg_write(sdiodev,
3281 CORE_SB(corebase, sbimstate), 4,
3282 regdata);
3283 }
3284 }
3285
3286 /* leave reset and reject asserted */
3287 brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
3288 (SBTML_REJ | SBTML_RESET));
3289 udelay(1);
3290}
3291
3292static void
3293brcmf_sdbrcm_chip_resetcore(struct brcmf_sdio_dev *sdiodev, u32 corebase)
3294{
3295 u32 regdata;
3296
3297 /*
3298 * Must do the disable sequence first to work for
3299 * arbitrary current core state.
3300 */
3301 brcmf_sdbrcm_chip_disablecore(sdiodev, corebase);
3302
3303 /*
3304 * Now do the initialization sequence.
3305 * set reset while enabling the clock and
3306 * forcing them on throughout the core
3307 */
3308 brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
3309 ((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
3310 SBTML_RESET);
3311 udelay(1);
3312
3313 regdata = brcmf_sdcard_reg_read(sdiodev,
3314 CORE_SB(corebase, sbtmstatehigh), 4);
3315 if (regdata & SBTMH_SERR)
3316 brcmf_sdcard_reg_write(sdiodev,
3317 CORE_SB(corebase, sbtmstatehigh), 4, 0);
3318
3319 regdata = brcmf_sdcard_reg_read(sdiodev,
3320 CORE_SB(corebase, sbimstate), 4);
3321 if (regdata & (SBIM_IBE | SBIM_TO))
3322 brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbimstate), 4,
3323 regdata & ~(SBIM_IBE | SBIM_TO));
3324
3325 /* clear reset and allow it to propagate throughout the core */
3326 brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
3327 (SICF_FGC << SBTML_SICF_SHIFT) |
3328 (SICF_CLOCK_EN << SBTML_SICF_SHIFT));
3329 udelay(1);
3330
3331 /* leave clock enabled */
3332 brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
3333 (SICF_CLOCK_EN << SBTML_SICF_SHIFT));
3334 udelay(1);
3335}
3336
3337static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter)
3338{
3339 uint retries;
3340 u32 regdata;
3341 int bcmerror = 0;
3342
3343 /* To enter download state, disable ARM and reset SOCRAM.
3344 * To exit download state, simply reset ARM (default is RAM boot).
3345 */
3346 if (enter) {
3347 bus->alp_only = true;
3348
3349 brcmf_sdbrcm_chip_disablecore(bus->sdiodev,
3350 bus->ci->armcorebase);
3351
3352 brcmf_sdbrcm_chip_resetcore(bus->sdiodev, bus->ci->ramcorebase);
3353
3354 /* Clear the top bit of memory */
3355 if (bus->ramsize) {
3356 u32 zeros = 0;
3357 brcmf_sdbrcm_membytes(bus, true, bus->ramsize - 4,
3358 (u8 *)&zeros, 4);
3359 }
3360 } else {
3361 regdata = brcmf_sdcard_reg_read(bus->sdiodev,
3362 CORE_SB(bus->ci->ramcorebase, sbtmstatelow), 4);
3363 regdata &= (SBTML_RESET | SBTML_REJ_MASK |
3364 (SICF_CLOCK_EN << SBTML_SICF_SHIFT));
3365 if ((SICF_CLOCK_EN << SBTML_SICF_SHIFT) != regdata) {
3366 brcmf_dbg(ERROR, "SOCRAM core is down after reset?\n");
3367 bcmerror = -EBADE;
3368 goto fail;
3369 }
3370
3371 bcmerror = brcmf_sdbrcm_write_vars(bus);
3372 if (bcmerror) {
3373 brcmf_dbg(ERROR, "no vars written to RAM\n");
3374 bcmerror = 0;
3375 }
3376
3377 w_sdreg32(bus, 0xFFFFFFFF,
3378 offsetof(struct sdpcmd_regs, intstatus), &retries);
3379
3380 brcmf_sdbrcm_chip_resetcore(bus->sdiodev, bus->ci->armcorebase);
3381
3382 /* Allow HT Clock now that the ARM is running. */
3383 bus->alp_only = false;
3384
3385 bus->drvr->busstate = BRCMF_BUS_LOAD;
3386 }
3387fail:
3388 return bcmerror;
3389}
3390
3391static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_bus *bus)
3392{
3393 if (bus->firmware->size < bus->fw_ptr + len)
3394 len = bus->firmware->size - bus->fw_ptr;
3395
3396 memcpy(buf, &bus->firmware->data[bus->fw_ptr], len);
3397 bus->fw_ptr += len;
3398 return len;
3399}
3400
3401MODULE_FIRMWARE(BCM4329_FW_NAME);
3402MODULE_FIRMWARE(BCM4329_NV_NAME);
3403
3404static int brcmf_sdbrcm_download_code_file(struct brcmf_bus *bus)
3405{
3406 int offset = 0;
3407 uint len;
3408 u8 *memblock = NULL, *memptr;
3409 int ret;
3410
3411 brcmf_dbg(INFO, "Enter\n");
3412
3413 bus->fw_name = BCM4329_FW_NAME;
3414 ret = request_firmware(&bus->firmware, bus->fw_name,
3415 &bus->sdiodev->func[2]->dev);
3416 if (ret) {
3417 brcmf_dbg(ERROR, "Fail to request firmware %d\n", ret);
3418 return ret;
3419 }
3420 bus->fw_ptr = 0;
3421
3422 memptr = memblock = kmalloc(MEMBLOCK + BRCMF_SDALIGN, GFP_ATOMIC);
3423 if (memblock == NULL) {
3424 ret = -ENOMEM;
3425 goto err;
3426 }
3427 if ((u32)(unsigned long)memblock % BRCMF_SDALIGN)
3428 memptr += (BRCMF_SDALIGN -
3429 ((u32)(unsigned long)memblock % BRCMF_SDALIGN));
3430
3431 /* Download image */
3432 while ((len =
3433 brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) {
3434 ret = brcmf_sdbrcm_membytes(bus, true, offset, memptr, len);
3435 if (ret) {
3436 brcmf_dbg(ERROR, "error %d on writing %d membytes at 0x%08x\n",
3437 ret, MEMBLOCK, offset);
3438 goto err;
3439 }
3440
3441 offset += MEMBLOCK;
3442 }
3443
3444err:
3445 kfree(memblock);
3446
3447 release_firmware(bus->firmware);
3448 bus->fw_ptr = 0;
3449
3450 return ret;
3451}
3452
3453/*
3454 * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file
3455 * and ending in a NUL.
3456 * Removes carriage returns, empty lines, comment lines, and converts
3457 * newlines to NULs.
3458 * Shortens buffer as needed and pads with NULs. End of buffer is marked
3459 * by two NULs.
3460*/
3461
3462static uint brcmf_process_nvram_vars(char *varbuf, uint len)
3463{
3464 char *dp;
3465 bool findNewline;
3466 int column;
3467 uint buf_len, n;
3468
3469 dp = varbuf;
3470
3471 findNewline = false;
3472 column = 0;
3473
3474 for (n = 0; n < len; n++) {
3475 if (varbuf[n] == 0)
3476 break;
3477 if (varbuf[n] == '\r')
3478 continue;
3479 if (findNewline && varbuf[n] != '\n')
3480 continue;
3481 findNewline = false;
3482 if (varbuf[n] == '#') {
3483 findNewline = true;
3484 continue;
3485 }
3486 if (varbuf[n] == '\n') {
3487 if (column == 0)
3488 continue;
3489 *dp++ = 0;
3490 column = 0;
3491 continue;
3492 }
3493 *dp++ = varbuf[n];
3494 column++;
3495 }
3496 buf_len = dp - varbuf;
3497
3498 while (dp < varbuf + n)
3499 *dp++ = 0;
3500
3501 return buf_len;
3502}
3503
3504static int brcmf_sdbrcm_download_nvram(struct brcmf_bus *bus)
3505{
3506 uint len;
3507 char *memblock = NULL;
3508 char *bufp;
3509 int ret;
3510
3511 bus->nv_name = BCM4329_NV_NAME;
3512 ret = request_firmware(&bus->firmware, bus->nv_name,
3513 &bus->sdiodev->func[2]->dev);
3514 if (ret) {
3515 brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret);
3516 return ret;
3517 }
3518 bus->fw_ptr = 0;
3519
3520 memblock = kmalloc(MEMBLOCK, GFP_ATOMIC);
3521 if (memblock == NULL) {
3522 ret = -ENOMEM;
3523 goto err;
3524 }
3525
3526 len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus);
3527
3528 if (len > 0 && len < MEMBLOCK) {
3529 bufp = (char *)memblock;
3530 bufp[len] = 0;
3531 len = brcmf_process_nvram_vars(bufp, len);
3532 bufp += len;
3533 *bufp++ = 0;
3534 if (len)
3535 ret = brcmf_sdbrcm_downloadvars(bus, memblock, len + 1);
3536 if (ret)
3537 brcmf_dbg(ERROR, "error downloading vars: %d\n", ret);
3538 } else {
3539 brcmf_dbg(ERROR, "error reading nvram file: %d\n", len);
3540 ret = -EIO;
3541 }
3542
3543err:
3544 kfree(memblock);
3545
3546 release_firmware(bus->firmware);
3547 bus->fw_ptr = 0;
3548
3549 return ret;
3550}
3551
3552static int _brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus)
3553{
3554 int bcmerror = -1;
3555
3556 /* Keep arm in reset */
3557 if (brcmf_sdbrcm_download_state(bus, true)) {
3558 brcmf_dbg(ERROR, "error placing ARM core in reset\n");
3559 goto err;
3560 }
3561
3562 /* External image takes precedence if specified */
3563 if (brcmf_sdbrcm_download_code_file(bus)) {
3564 brcmf_dbg(ERROR, "dongle image file download failed\n");
3565 goto err;
3566 }
3567
3568 /* External nvram takes precedence if specified */
3569 if (brcmf_sdbrcm_download_nvram(bus))
3570 brcmf_dbg(ERROR, "dongle nvram file download failed\n");
3571
3572 /* Take arm out of reset */
3573 if (brcmf_sdbrcm_download_state(bus, false)) {
3574 brcmf_dbg(ERROR, "error getting out of ARM core reset\n");
3575 goto err;
3576 }
3577
3578 bcmerror = 0;
3579
3580err:
3581 return bcmerror;
3582}
3583
3584static bool
3585brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus)
3586{
3587 bool ret;
3588
3589 /* Download the firmware */
3590 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
3591
3592 ret = _brcmf_sdbrcm_download_firmware(bus) == 0;
3593
3594 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
3595
3596 return ret;
3597}
3598
3599void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus)
3600{
3601 u32 local_hostintmask;
3602 u8 saveclk;
3603 uint retries;
3604 int err;
3605
3606 brcmf_dbg(TRACE, "Enter\n");
3607
3608 if (bus->watchdog_tsk) {
3609 send_sig(SIGTERM, bus->watchdog_tsk, 1);
3610 kthread_stop(bus->watchdog_tsk);
3611 bus->watchdog_tsk = NULL;
3612 }
3613
3614 if (bus->dpc_tsk && bus->dpc_tsk != current) {
3615 send_sig(SIGTERM, bus->dpc_tsk, 1);
3616 kthread_stop(bus->dpc_tsk);
3617 bus->dpc_tsk = NULL;
3618 }
3619
3620 down(&bus->sdsem);
3621
3622 bus_wake(bus);
3623
3624 /* Enable clock for device interrupts */
3625 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
3626
3627 /* Disable and clear interrupts at the chip level also */
3628 w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask), &retries);
3629 local_hostintmask = bus->hostintmask;
3630 bus->hostintmask = 0;
3631
3632 /* Change our idea of bus state */
3633 bus->drvr->busstate = BRCMF_BUS_DOWN;
3634
3635 /* Force clocks on backplane to be sure F2 interrupt propagates */
3636 saveclk = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
3637 SBSDIO_FUNC1_CHIPCLKCSR, &err);
3638 if (!err) {
3639 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
3640 SBSDIO_FUNC1_CHIPCLKCSR,
3641 (saveclk | SBSDIO_FORCE_HT), &err);
3642 }
3643 if (err)
3644 brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err);
3645
3646 /* Turn off the bus (F2), free any pending packets */
3647 brcmf_dbg(INTR, "disable SDIO interrupts\n");
3648 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx,
3649 SDIO_FUNC_ENABLE_1, NULL);
3650
3651 /* Clear any pending interrupts now that F2 is disabled */
3652 w_sdreg32(bus, local_hostintmask,
3653 offsetof(struct sdpcmd_regs, intstatus), &retries);
3654
3655 /* Turn off the backplane clock (only) */
3656 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
3657
3658 /* Clear the data packet queues */
3659 brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
3660
3661 /* Clear any held glomming stuff */
3662 if (bus->glomd)
3663 brcmu_pkt_buf_free_skb(bus->glomd);
3664
3665 if (bus->glom)
3666 brcmu_pkt_buf_free_skb(bus->glom);
3667
3668 bus->glom = bus->glomd = NULL;
3669
3670 /* Clear rx control and wake any waiters */
3671 bus->rxlen = 0;
3672 brcmf_sdbrcm_dcmd_resp_wake(bus);
3673
3674 /* Reset some F2 state stuff */
3675 bus->rxskip = false;
3676 bus->tx_seq = bus->rx_seq = 0;
3677
3678 up(&bus->sdsem);
3679}
3680
3681int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr)
3682{
3683 struct brcmf_bus *bus = drvr->bus;
3684 unsigned long timeout;
3685 uint retries = 0;
3686 u8 ready, enable;
3687 int err, ret = 0;
3688 u8 saveclk;
3689
3690 brcmf_dbg(TRACE, "Enter\n");
3691
3692 /* try to download image and nvram to the dongle */
3693 if (drvr->busstate == BRCMF_BUS_DOWN) {
3694 if (!(brcmf_sdbrcm_download_firmware(bus)))
3695 return -1;
3696 }
3697
3698 if (!bus->drvr)
3699 return 0;
3700
3701 /* Start the watchdog timer */
3702 bus->drvr->tickcnt = 0;
3703 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
3704
3705 down(&bus->sdsem);
3706
3707 /* Make sure backplane clock is on, needed to generate F2 interrupt */
3708 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
3709 if (bus->clkstate != CLK_AVAIL)
3710 goto exit;
3711
3712 /* Force clocks on backplane to be sure F2 interrupt propagates */
3713 saveclk =
3714 brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
3715 SBSDIO_FUNC1_CHIPCLKCSR, &err);
3716 if (!err) {
3717 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
3718 SBSDIO_FUNC1_CHIPCLKCSR,
3719 (saveclk | SBSDIO_FORCE_HT), &err);
3720 }
3721 if (err) {
3722 brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err);
3723 goto exit;
3724 }
3725
3726 /* Enable function 2 (frame transfers) */
3727 w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
3728 offsetof(struct sdpcmd_regs, tosbmailboxdata), &retries);
3729 enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2);
3730
3731 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx,
3732 enable, NULL);
3733
3734 timeout = jiffies + msecs_to_jiffies(BRCMF_WAIT_F2RDY);
3735 ready = 0;
3736 while (enable != ready) {
3737 ready = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_0,
3738 SDIO_CCCR_IORx, NULL);
3739 if (time_after(jiffies, timeout))
3740 break;
3741 else if (time_after(jiffies, timeout - BRCMF_WAIT_F2RDY + 50))
3742 /* prevent busy waiting if it takes too long */
3743 msleep_interruptible(20);
3744 }
3745
3746 brcmf_dbg(INFO, "enable 0x%02x, ready 0x%02x\n", enable, ready);
3747
3748 /* If F2 successfully enabled, set core and enable interrupts */
3749 if (ready == enable) {
3750 /* Set up the interrupt mask and enable interrupts */
3751 bus->hostintmask = HOSTINTMASK;
3752 w_sdreg32(bus, bus->hostintmask,
3753 offsetof(struct sdpcmd_regs, hostintmask), &retries);
3754
3755 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
3756 SBSDIO_WATERMARK, 8, &err);
3757
3758 /* Set bus state according to enable result */
3759 drvr->busstate = BRCMF_BUS_DATA;
3760 }
3761
3762 else {
3763 /* Disable F2 again */
3764 enable = SDIO_FUNC_ENABLE_1;
3765 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0,
3766 SDIO_CCCR_IOEx, enable, NULL);
3767 }
3768
3769 /* Restore previous clock setting */
3770 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
3771 SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
3772
3773 /* If we didn't come up, turn off backplane clock */
3774 if (drvr->busstate != BRCMF_BUS_DATA)
3775 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
3776
3777exit:
3778 up(&bus->sdsem);
3779
3780 return ret;
3781}
3782
3783void brcmf_sdbrcm_isr(void *arg)
3784{
3785 struct brcmf_bus *bus = (struct brcmf_bus *) arg;
3786
3787 brcmf_dbg(TRACE, "Enter\n");
3788
3789 if (!bus) {
3790 brcmf_dbg(ERROR, "bus is null pointer, exiting\n");
3791 return;
3792 }
3793
3794 if (bus->drvr->busstate == BRCMF_BUS_DOWN) {
3795 brcmf_dbg(ERROR, "bus is down. we have nothing to do\n");
3796 return;
3797 }
3798 /* Count the interrupt call */
3799 bus->intrcount++;
3800 bus->ipend = true;
3801
3802 /* Shouldn't get this interrupt if we're sleeping? */
3803 if (bus->sleeping) {
3804 brcmf_dbg(ERROR, "INTERRUPT WHILE SLEEPING??\n");
3805 return;
3806 }
3807
3808 /* Disable additional interrupts (is this needed now)? */
3809 if (!bus->intr)
3810 brcmf_dbg(ERROR, "isr w/o interrupt configured!\n");
3811
3812 bus->dpc_sched = true;
3813 if (bus->dpc_tsk)
3814 complete(&bus->dpc_wait);
3815}
3816
3817static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_pub *drvr)
3818{
3819 struct brcmf_bus *bus;
3820
3821 brcmf_dbg(TIMER, "Enter\n");
3822
3823 bus = drvr->bus;
3824
3825 /* Ignore the timer if simulating bus down */
3826 if (bus->sleeping)
3827 return false;
3828
3829 down(&bus->sdsem);
3830
3831 /* Poll period: check device if appropriate. */
3832 if (bus->poll && (++bus->polltick >= bus->pollrate)) {
3833 u32 intstatus = 0;
3834
3835 /* Reset poll tick */
3836 bus->polltick = 0;
3837
3838 /* Check device if no interrupts */
3839 if (!bus->intr || (bus->intrcount == bus->lastintrs)) {
3840
3841 if (!bus->dpc_sched) {
3842 u8 devpend;
3843 devpend = brcmf_sdcard_cfg_read(bus->sdiodev,
3844 SDIO_FUNC_0, SDIO_CCCR_INTx,
3845 NULL);
3846 intstatus =
3847 devpend & (INTR_STATUS_FUNC1 |
3848 INTR_STATUS_FUNC2);
3849 }
3850
3851 /* If there is something, make like the ISR and
3852 schedule the DPC */
3853 if (intstatus) {
3854 bus->pollcnt++;
3855 bus->ipend = true;
3856
3857 bus->dpc_sched = true;
3858 if (bus->dpc_tsk)
3859 complete(&bus->dpc_wait);
3860 }
3861 }
3862
3863 /* Update interrupt tracking */
3864 bus->lastintrs = bus->intrcount;
3865 }
3866#ifdef BCMDBG
3867 /* Poll for console output periodically */
3868 if (drvr->busstate == BRCMF_BUS_DATA && bus->console_interval != 0) {
3869 bus->console.count += BRCMF_WD_POLL_MS;
3870 if (bus->console.count >= bus->console_interval) {
3871 bus->console.count -= bus->console_interval;
3872 /* Make sure backplane clock is on */
3873 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
3874 if (brcmf_sdbrcm_readconsole(bus) < 0)
3875 /* stop on error */
3876 bus->console_interval = 0;
3877 }
3878 }
3879#endif /* BCMDBG */
3880
3881 /* On idle timeout clear activity flag and/or turn off clock */
3882 if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
3883 if (++bus->idlecount >= bus->idletime) {
3884 bus->idlecount = 0;
3885 if (bus->activity) {
3886 bus->activity = false;
3887 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
3888 } else {
3889 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
3890 }
3891 }
3892 }
3893
3894 up(&bus->sdsem);
3895
3896 return bus->ipend;
3897}
3898
3899static bool brcmf_sdbrcm_chipmatch(u16 chipid)
3900{
3901 if (chipid == BCM4329_CHIP_ID)
3902 return true;
3903 return false;
3904}
3905
3906static void brcmf_sdbrcm_release_malloc(struct brcmf_bus *bus)
3907{
3908 brcmf_dbg(TRACE, "Enter\n");
3909
3910 kfree(bus->rxbuf);
3911 bus->rxctl = bus->rxbuf = NULL;
3912 bus->rxlen = 0;
3913
3914 kfree(bus->databuf);
3915 bus->databuf = NULL;
3916}
3917
3918static bool brcmf_sdbrcm_probe_malloc(struct brcmf_bus *bus)
3919{
3920 brcmf_dbg(TRACE, "Enter\n");
3921
3922 if (bus->drvr->maxctl) {
3923 bus->rxblen =
3924 roundup((bus->drvr->maxctl + SDPCM_HDRLEN),
3925 ALIGNMENT) + BRCMF_SDALIGN;
3926 bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
3927 if (!(bus->rxbuf))
3928 goto fail;
3929 }
3930
3931 /* Allocate buffer to receive glomed packet */
3932 bus->databuf = kmalloc(MAX_DATA_BUF, GFP_ATOMIC);
3933 if (!(bus->databuf)) {
3934 /* release rxbuf which was already located as above */
3935 if (!bus->rxblen)
3936 kfree(bus->rxbuf);
3937 goto fail;
3938 }
3939
3940 /* Align the buffer */
3941 if ((unsigned long)bus->databuf % BRCMF_SDALIGN)
3942 bus->dataptr = bus->databuf + (BRCMF_SDALIGN -
3943 ((unsigned long)bus->databuf % BRCMF_SDALIGN));
3944 else
3945 bus->dataptr = bus->databuf;
3946
3947 return true;
3948
3949fail:
3950 return false;
3951}
3952
3953/* SDIO Pad drive strength to select value mappings */
3954struct sdiod_drive_str {
3955 u8 strength; /* Pad Drive Strength in mA */
3956 u8 sel; /* Chip-specific select value */
3957};
3958
3959/* SDIO Drive Strength to sel value table for PMU Rev 1 */
3960static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = {
3961 {
3962 4, 0x2}, {
3963 2, 0x3}, {
3964 1, 0x0}, {
3965 0, 0x0}
3966 };
3967
3968/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
3969static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = {
3970 {
3971 12, 0x7}, {
3972 10, 0x6}, {
3973 8, 0x5}, {
3974 6, 0x4}, {
3975 4, 0x2}, {
3976 2, 0x1}, {
3977 0, 0x0}
3978 };
3979
3980/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
3981static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = {
3982 {
3983 32, 0x7}, {
3984 26, 0x6}, {
3985 22, 0x5}, {
3986 16, 0x4}, {
3987 12, 0x3}, {
3988 8, 0x2}, {
3989 4, 0x1}, {
3990 0, 0x0}
3991 };
3992
3993#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
3994
3995static char *brcmf_chipname(uint chipid, char *buf, uint len)
3996{
3997 const char *fmt;
3998
3999 fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
4000 snprintf(buf, len, fmt, chipid);
4001 return buf;
4002}
4003
4004static void brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus,
4005 u32 drivestrength) {
4006 struct sdiod_drive_str *str_tab = NULL;
4007 u32 str_mask = 0;
4008 u32 str_shift = 0;
4009 char chn[8];
4010
4011 if (!(bus->ci->cccaps & CC_CAP_PMU))
4012 return;
4013
4014 switch (SDIOD_DRVSTR_KEY(bus->ci->chip, bus->ci->pmurev)) {
4015 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
4016 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1;
4017 str_mask = 0x30000000;
4018 str_shift = 28;
4019 break;
4020 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
4021 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
4022 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2;
4023 str_mask = 0x00003800;
4024 str_shift = 11;
4025 break;
4026 case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
4027 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3;
4028 str_mask = 0x00003800;
4029 str_shift = 11;
4030 break;
4031 default:
4032 brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
4033 brcmf_chipname(bus->ci->chip, chn, 8),
4034 bus->ci->chiprev, bus->ci->pmurev);
4035 break;
4036 }
4037
4038 if (str_tab != NULL) {
4039 u32 drivestrength_sel = 0;
4040 u32 cc_data_temp;
4041 int i;
4042
4043 for (i = 0; str_tab[i].strength != 0; i++) {
4044 if (drivestrength >= str_tab[i].strength) {
4045 drivestrength_sel = str_tab[i].sel;
4046 break;
4047 }
4048 }
4049
4050 brcmf_sdcard_reg_write(bus->sdiodev,
4051 CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr),
4052 4, 1);
4053 cc_data_temp = brcmf_sdcard_reg_read(bus->sdiodev,
4054 CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4);
4055 cc_data_temp &= ~str_mask;
4056 drivestrength_sel <<= str_shift;
4057 cc_data_temp |= drivestrength_sel;
4058 brcmf_sdcard_reg_write(bus->sdiodev,
4059 CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr),
4060 4, cc_data_temp);
4061
4062 brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n",
4063 drivestrength, cc_data_temp);
4064 }
4065}
4066
4067static int
4068brcmf_sdbrcm_chip_recognition(struct brcmf_sdio_dev *sdiodev,
4069 struct chip_info *ci, u32 regs)
4070{
4071 u32 regdata;
4072
4073 /*
4074 * Get CC core rev
4075 * Chipid is assume to be at offset 0 from regs arg
4076 * For different chiptypes or old sdio hosts w/o chipcommon,
4077 * other ways of recognition should be added here.
4078 */
4079 ci->cccorebase = regs;
4080 regdata = brcmf_sdcard_reg_read(sdiodev,
4081 CORE_CC_REG(ci->cccorebase, chipid), 4);
4082 ci->chip = regdata & CID_ID_MASK;
4083 ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
4084
4085 brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev);
4086
4087 /* Address of cores for new chips should be added here */
4088 switch (ci->chip) {
4089 case BCM4329_CHIP_ID:
4090 ci->buscorebase = BCM4329_CORE_BUS_BASE;
4091 ci->ramcorebase = BCM4329_CORE_SOCRAM_BASE;
4092 ci->armcorebase = BCM4329_CORE_ARM_BASE;
4093 ci->ramsize = BCM4329_RAMSIZE;
4094 break;
4095 default:
4096 brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip);
4097 return -ENODEV;
4098 }
4099
4100 regdata = brcmf_sdcard_reg_read(sdiodev,
4101 CORE_SB(ci->cccorebase, sbidhigh), 4);
4102 ci->ccrev = SBCOREREV(regdata);
4103
4104 regdata = brcmf_sdcard_reg_read(sdiodev,
4105 CORE_CC_REG(ci->cccorebase, pmucapabilities), 4);
4106 ci->pmurev = regdata & PCAP_REV_MASK;
4107
4108 regdata = brcmf_sdcard_reg_read(sdiodev,
4109 CORE_SB(ci->buscorebase, sbidhigh), 4);
4110 ci->buscorerev = SBCOREREV(regdata);
4111 ci->buscoretype = (regdata & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT;
4112
4113 brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
4114 ci->ccrev, ci->pmurev, ci->buscorerev, ci->buscoretype);
4115
4116 /* get chipcommon capabilites */
4117 ci->cccaps = brcmf_sdcard_reg_read(sdiodev,
4118 CORE_CC_REG(ci->cccorebase, capabilities), 4);
4119
4120 return 0;
4121}
4122
4123static int
4124brcmf_sdbrcm_chip_attach(struct brcmf_bus *bus, u32 regs)
4125{
4126 struct chip_info *ci;
4127 int err;
4128 u8 clkval, clkset;
4129
4130 brcmf_dbg(TRACE, "Enter\n");
4131
4132 /* alloc chip_info_t */
4133 ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC);
4134 if (NULL == ci)
4135 return -ENOMEM;
4136
4137 /* bus/core/clk setup for register access */
4138 /* Try forcing SDIO core to do ALPAvail request only */
4139 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
4140 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
4141 SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
4142 if (err) {
4143 brcmf_dbg(ERROR, "error writing for HT off\n");
4144 goto fail;
4145 }
4146
4147 /* If register supported, wait for ALPAvail and then force ALP */
4148 /* This may take up to 15 milliseconds */
4149 clkval = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
4150 SBSDIO_FUNC1_CHIPCLKCSR, NULL);
4151 if ((clkval & ~SBSDIO_AVBITS) == clkset) {
4152 SPINWAIT(((clkval =
4153 brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
4154 SBSDIO_FUNC1_CHIPCLKCSR,
4155 NULL)),
4156 !SBSDIO_ALPAV(clkval)),
4157 PMU_MAX_TRANSITION_DLY);
4158 if (!SBSDIO_ALPAV(clkval)) {
4159 brcmf_dbg(ERROR, "timeout on ALPAV wait, clkval 0x%02x\n",
4160 clkval);
4161 err = -EBUSY;
4162 goto fail;
4163 }
4164 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF |
4165 SBSDIO_FORCE_ALP;
4166 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
4167 SBSDIO_FUNC1_CHIPCLKCSR,
4168 clkset, &err);
4169 udelay(65);
4170 } else {
4171 brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
4172 clkset, clkval);
4173 err = -EACCES;
4174 goto fail;
4175 }
4176
4177 /* Also, disable the extra SDIO pull-ups */
4178 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
4179 SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
4180
4181 err = brcmf_sdbrcm_chip_recognition(bus->sdiodev, ci, regs);
4182 if (err)
4183 goto fail;
4184
4185 /*
4186 * Make sure any on-chip ARM is off (in case strapping is wrong),
4187 * or downloaded code was already running.
4188 */
4189 brcmf_sdbrcm_chip_disablecore(bus->sdiodev, ci->armcorebase);
4190
4191 brcmf_sdcard_reg_write(bus->sdiodev,
4192 CORE_CC_REG(ci->cccorebase, gpiopullup), 4, 0);
4193 brcmf_sdcard_reg_write(bus->sdiodev,
4194 CORE_CC_REG(ci->cccorebase, gpiopulldown), 4, 0);
4195
4196 /* Disable F2 to clear any intermediate frame state on the dongle */
4197 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx,
4198 SDIO_FUNC_ENABLE_1, NULL);
4199
4200 /* WAR: cmd52 backplane read so core HW will drop ALPReq */
4201 clkval = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
4202 0, NULL);
4203
4204 /* Done with backplane-dependent accesses, can drop clock... */
4205 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
4206 SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
4207
4208 bus->ci = ci;
4209 return 0;
4210fail:
4211 bus->ci = NULL;
4212 kfree(ci);
4213 return err;
4214}
4215
4216static bool
4217brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva)
4218{
4219 u8 clkctl = 0;
4220 int err = 0;
4221 int reg_addr;
4222 u32 reg_val;
4223
4224 bus->alp_only = true;
4225
4226 /* Return the window to backplane enumeration space for core access */
4227 if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, SI_ENUM_BASE))
4228 brcmf_dbg(ERROR, "FAILED to return to SI_ENUM_BASE\n");
4229
4230#ifdef BCMDBG
4231 printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n",
4232 brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4));
4233
4234#endif /* BCMDBG */
4235
4236 /*
4237 * Force PLL off until brcmf_sdbrcm_chip_attach()
4238 * programs PLL control regs
4239 */
4240
4241 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
4242 SBSDIO_FUNC1_CHIPCLKCSR,
4243 BRCMF_INIT_CLKCTL1, &err);
4244 if (!err)
4245 clkctl =
4246 brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
4247 SBSDIO_FUNC1_CHIPCLKCSR, &err);
4248
4249 if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
4250 brcmf_dbg(ERROR, "ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n",
4251 err, BRCMF_INIT_CLKCTL1, clkctl);
4252 goto fail;
4253 }
4254
4255 if (brcmf_sdbrcm_chip_attach(bus, regsva)) {
4256 brcmf_dbg(ERROR, "brcmf_sdbrcm_chip_attach failed!\n");
4257 goto fail;
4258 }
4259
4260 if (!brcmf_sdbrcm_chipmatch((u16) bus->ci->chip)) {
4261 brcmf_dbg(ERROR, "unsupported chip: 0x%04x\n", bus->ci->chip);
4262 goto fail;
4263 }
4264
4265 brcmf_sdbrcm_sdiod_drive_strength_init(bus, SDIO_DRIVE_STRENGTH);
4266
4267 /* Get info on the ARM and SOCRAM cores... */
4268 brcmf_sdcard_reg_read(bus->sdiodev,
4269 CORE_SB(bus->ci->armcorebase, sbidhigh), 4);
4270 bus->ramsize = bus->ci->ramsize;
4271 if (!(bus->ramsize)) {
4272 brcmf_dbg(ERROR, "failed to find SOCRAM memory!\n");
4273 goto fail;
4274 }
4275
4276 /* Set core control so an SDIO reset does a backplane reset */
4277 reg_addr = bus->ci->buscorebase +
4278 offsetof(struct sdpcmd_regs, corecontrol);
4279 reg_val = brcmf_sdcard_reg_read(bus->sdiodev, reg_addr, sizeof(u32));
4280 brcmf_sdcard_reg_write(bus->sdiodev, reg_addr, sizeof(u32),
4281 reg_val | CC_BPRESEN);
4282
4283 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
4284
4285 /* Locate an appropriately-aligned portion of hdrbuf */
4286 bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0],
4287 BRCMF_SDALIGN);
4288
4289 /* Set the poll and/or interrupt flags */
4290 bus->intr = true;
4291 bus->poll = false;
4292 if (bus->poll)
4293 bus->pollrate = 1;
4294
4295 return true;
4296
4297fail:
4298 return false;
4299}
4300
4301static bool brcmf_sdbrcm_probe_init(struct brcmf_bus *bus)
4302{
4303 brcmf_dbg(TRACE, "Enter\n");
4304
4305 /* Disable F2 to clear any intermediate frame state on the dongle */
4306 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx,
4307 SDIO_FUNC_ENABLE_1, NULL);
4308
4309 bus->drvr->busstate = BRCMF_BUS_DOWN;
4310 bus->sleeping = false;
4311 bus->rxflow = false;
4312
4313 /* Done with backplane-dependent accesses, can drop clock... */
4314 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
4315 SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
4316
4317 /* ...and initialize clock/power states */
4318 bus->clkstate = CLK_SDONLY;
4319 bus->idletime = BRCMF_IDLE_INTERVAL;
4320 bus->idleclock = BRCMF_IDLE_ACTIVE;
4321
4322 /* Query the F2 block size, set roundup accordingly */
4323 bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
4324 bus->roundup = min(max_roundup, bus->blocksize);
4325
4326 /* bus module does not support packet chaining */
4327 bus->use_rxchain = false;
4328 bus->sd_rxchain = false;
4329
4330 return true;
4331}
4332
4333static int
4334brcmf_sdbrcm_watchdog_thread(void *data)
4335{
4336 struct brcmf_bus *bus = (struct brcmf_bus *)data;
4337
4338 allow_signal(SIGTERM);
4339 /* Run until signal received */
4340 while (1) {
4341 if (kthread_should_stop())
4342 break;
4343 if (!wait_for_completion_interruptible(&bus->watchdog_wait)) {
4344 brcmf_sdbrcm_bus_watchdog(bus->drvr);
4345 /* Count the tick for reference */
4346 bus->drvr->tickcnt++;
4347 } else
4348 break;
4349 }
4350 return 0;
4351}
4352
4353static void
4354brcmf_sdbrcm_watchdog(unsigned long data)
4355{
4356 struct brcmf_bus *bus = (struct brcmf_bus *)data;
4357
4358 if (bus->watchdog_tsk) {
4359 complete(&bus->watchdog_wait);
4360 /* Reschedule the watchdog */
4361 if (bus->wd_timer_valid)
4362 mod_timer(&bus->timer,
4363 jiffies + BRCMF_WD_POLL_MS * HZ / 1000);
4364 }
4365}
4366
4367static void
4368brcmf_sdbrcm_chip_detach(struct brcmf_bus *bus)
4369{
4370 brcmf_dbg(TRACE, "Enter\n");
4371
4372 kfree(bus->ci);
4373 bus->ci = NULL;
4374}
4375
4376static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus)
4377{
4378 brcmf_dbg(TRACE, "Enter\n");
4379
4380 if (bus->ci) {
4381 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
4382 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
4383 brcmf_sdbrcm_chip_detach(bus);
4384 if (bus->vars && bus->varsz)
4385 kfree(bus->vars);
4386 bus->vars = NULL;
4387 }
4388
4389 brcmf_dbg(TRACE, "Disconnected\n");
4390}
4391
4392/* Detach and free everything */
4393static void brcmf_sdbrcm_release(struct brcmf_bus *bus)
4394{
4395 brcmf_dbg(TRACE, "Enter\n");
4396
4397 if (bus) {
4398 /* De-register interrupt handler */
4399 brcmf_sdcard_intr_dereg(bus->sdiodev);
4400
4401 if (bus->drvr) {
4402 brcmf_detach(bus->drvr);
4403 brcmf_sdbrcm_release_dongle(bus);
4404 bus->drvr = NULL;
4405 }
4406
4407 brcmf_sdbrcm_release_malloc(bus);
4408
4409 kfree(bus);
4410 }
4411
4412 brcmf_dbg(TRACE, "Disconnected\n");
4413}
4414
4415void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype,
4416 u32 regsva, struct brcmf_sdio_dev *sdiodev)
4417{
4418 int ret;
4419 struct brcmf_bus *bus;
4420
4421 /* Init global variables at run-time, not as part of the declaration.
4422 * This is required to support init/de-init of the driver.
4423 * Initialization
4424 * of globals as part of the declaration results in non-deterministic
4425 * behavior since the value of the globals may be different on the
4426 * first time that the driver is initialized vs subsequent
4427 * initializations.
4428 */
4429 brcmf_c_init();
4430
4431 brcmf_dbg(TRACE, "Enter\n");
4432
4433 /* We make an assumption about address window mappings:
4434 * regsva == SI_ENUM_BASE*/
4435
4436 /* Allocate private bus interface state */
4437 bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC);
4438 if (!bus)
4439 goto fail;
4440
4441 bus->sdiodev = sdiodev;
4442 sdiodev->bus = bus;
4443 bus->txbound = BRCMF_TXBOUND;
4444 bus->rxbound = BRCMF_RXBOUND;
4445 bus->txminmax = BRCMF_TXMINMAX;
4446 bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1;
4447 bus->usebufpool = false; /* Use bufpool if allocated,
4448 else use locally malloced rxbuf */
4449
4450 /* attempt to attach to the dongle */
4451 if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) {
4452 brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n");
4453 goto fail;
4454 }
4455
4456 spin_lock_init(&bus->txqlock);
4457 init_waitqueue_head(&bus->ctrl_wait);
4458 init_waitqueue_head(&bus->dcmd_resp_wait);
4459
4460 /* Set up the watchdog timer */
4461 init_timer(&bus->timer);
4462 bus->timer.data = (unsigned long)bus;
4463 bus->timer.function = brcmf_sdbrcm_watchdog;
4464
4465 /* Initialize thread based operation and lock */
4466 sema_init(&bus->sdsem, 1);
4467
4468 /* Initialize watchdog thread */
4469 init_completion(&bus->watchdog_wait);
4470 bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread,
4471 bus, "brcmf_watchdog");
4472 if (IS_ERR(bus->watchdog_tsk)) {
4473 printk(KERN_WARNING
4474 "brcmf_watchdog thread failed to start\n");
4475 bus->watchdog_tsk = NULL;
4476 }
4477 /* Initialize DPC thread */
4478 init_completion(&bus->dpc_wait);
4479 bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread,
4480 bus, "brcmf_dpc");
4481 if (IS_ERR(bus->dpc_tsk)) {
4482 printk(KERN_WARNING
4483 "brcmf_dpc thread failed to start\n");
4484 bus->dpc_tsk = NULL;
4485 }
4486
4487 /* Attach to the brcmf/OS/network interface */
4488 bus->drvr = brcmf_attach(bus, SDPCM_RESERVE);
4489 if (!bus->drvr) {
4490 brcmf_dbg(ERROR, "brcmf_attach failed\n");
4491 goto fail;
4492 }
4493
4494 /* Allocate buffers */
4495 if (!(brcmf_sdbrcm_probe_malloc(bus))) {
4496 brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_malloc failed\n");
4497 goto fail;
4498 }
4499
4500 if (!(brcmf_sdbrcm_probe_init(bus))) {
4501 brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_init failed\n");
4502 goto fail;
4503 }
4504
4505 /* Register interrupt callback, but mask it (not operational yet). */
4506 brcmf_dbg(INTR, "disable SDIO interrupts (not interested yet)\n");
4507 ret = brcmf_sdcard_intr_reg(bus->sdiodev);
4508 if (ret != 0) {
4509 brcmf_dbg(ERROR, "FAILED: sdcard_intr_reg returned %d\n", ret);
4510 goto fail;
4511 }
4512 brcmf_dbg(INTR, "registered SDIO interrupt function ok\n");
4513
4514 brcmf_dbg(INFO, "completed!!\n");
4515
4516 /* if firmware path present try to download and bring up bus */
4517 ret = brcmf_bus_start(bus->drvr);
4518 if (ret != 0) {
4519 if (ret == -ENOLINK) {
4520 brcmf_dbg(ERROR, "dongle is not responding\n");
4521 goto fail;
4522 }
4523 }
4524 /* Ok, have the per-port tell the stack we're open for business */
4525 if (brcmf_net_attach(bus->drvr, 0) != 0) {
4526 brcmf_dbg(ERROR, "Net attach failed!!\n");
4527 goto fail;
4528 }
4529
4530 return bus;
4531
4532fail:
4533 brcmf_sdbrcm_release(bus);
4534 return NULL;
4535}
4536
4537void brcmf_sdbrcm_disconnect(void *ptr)
4538{
4539 struct brcmf_bus *bus = (struct brcmf_bus *)ptr;
4540
4541 brcmf_dbg(TRACE, "Enter\n");
4542
4543 if (bus)
4544 brcmf_sdbrcm_release(bus);
4545
4546 brcmf_dbg(TRACE, "Disconnected\n");
4547}
4548
4549struct device *brcmf_bus_get_device(struct brcmf_bus *bus)
4550{
4551 return &bus->sdiodev->func[2]->dev;
4552}
4553
4554void
4555brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick)
4556{
4557 /* don't start the wd until fw is loaded */
4558 if (bus->drvr->busstate == BRCMF_BUS_DOWN)
4559 return;
4560
4561 /* Totally stop the timer */
4562 if (!wdtick && bus->wd_timer_valid == true) {
4563 del_timer_sync(&bus->timer);
4564 bus->wd_timer_valid = false;
4565 bus->save_ms = wdtick;
4566 return;
4567 }
4568
4569 if (wdtick) {
4570 if (bus->save_ms != BRCMF_WD_POLL_MS) {
4571 if (bus->wd_timer_valid == true)
4572 /* Stop timer and restart at new value */
4573 del_timer_sync(&bus->timer);
4574
4575 /* Create timer again when watchdog period is
4576 dynamically changed or in the first instance
4577 */
4578 bus->timer.expires =
4579 jiffies + BRCMF_WD_POLL_MS * HZ / 1000;
4580 add_timer(&bus->timer);
4581
4582 } else {
4583 /* Re arm the timer, at last watchdog period */
4584 mod_timer(&bus->timer,
4585 jiffies + BRCMF_WD_POLL_MS * HZ / 1000);
4586 }
4587
4588 bus->wd_timer_valid = true;
4589 bus->save_ms = wdtick;
4590 }
4591}
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 000000000000..726fa8981113
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -0,0 +1,252 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_SDH_H_
18#define _BRCM_SDH_H_
19
20#include <linux/skbuff.h>
21
22#define SDIO_FUNC_0 0
23#define SDIO_FUNC_1 1
24#define SDIO_FUNC_2 2
25
26#define SDIOD_FBR_SIZE 0x100
27
28/* io_en */
29#define SDIO_FUNC_ENABLE_1 0x02
30#define SDIO_FUNC_ENABLE_2 0x04
31
32/* io_rdys */
33#define SDIO_FUNC_READY_1 0x02
34#define SDIO_FUNC_READY_2 0x04
35
36/* intr_status */
37#define INTR_STATUS_FUNC1 0x2
38#define INTR_STATUS_FUNC2 0x4
39
40/* Maximum number of I/O funcs */
41#define SDIOD_MAX_IOFUNCS 7
42
43/* as of sdiod rev 0, supports 3 functions */
44#define SBSDIO_NUM_FUNCTION 3
45
46/* function 1 miscellaneous registers */
47
48/* sprom command and status */
49#define SBSDIO_SPROM_CS 0x10000
50/* sprom info register */
51#define SBSDIO_SPROM_INFO 0x10001
52/* sprom indirect access data byte 0 */
53#define SBSDIO_SPROM_DATA_LOW 0x10002
54/* sprom indirect access data byte 1 */
55#define SBSDIO_SPROM_DATA_HIGH 0x10003
56/* sprom indirect access addr byte 0 */
57#define SBSDIO_SPROM_ADDR_LOW 0x10004
58/* sprom indirect access addr byte 0 */
59#define SBSDIO_SPROM_ADDR_HIGH 0x10005
60/* xtal_pu (gpio) output */
61#define SBSDIO_CHIP_CTRL_DATA 0x10006
62/* xtal_pu (gpio) enable */
63#define SBSDIO_CHIP_CTRL_EN 0x10007
64/* rev < 7, watermark for sdio device */
65#define SBSDIO_WATERMARK 0x10008
66/* control busy signal generation */
67#define SBSDIO_DEVICE_CTL 0x10009
68
69/* SB Address Window Low (b15) */
70#define SBSDIO_FUNC1_SBADDRLOW 0x1000A
71/* SB Address Window Mid (b23:b16) */
72#define SBSDIO_FUNC1_SBADDRMID 0x1000B
73/* SB Address Window High (b31:b24) */
74#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C
75/* Frame Control (frame term/abort) */
76#define SBSDIO_FUNC1_FRAMECTRL 0x1000D
77/* ChipClockCSR (ALP/HT ctl/status) */
78#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E
79/* SdioPullUp (on cmd, d0-d2) */
80#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F
81/* Write Frame Byte Count Low */
82#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019
83/* Write Frame Byte Count High */
84#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A
85/* Read Frame Byte Count Low */
86#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B
87/* Read Frame Byte Count High */
88#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C
89
90#define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */
91#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */
92
93/* function 1 OCP space */
94
95/* sb offset addr is <= 15 bits, 32k */
96#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF
97#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000
98/* with b15, maps to 32-bit SB access */
99#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000
100
101/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
102
103#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */
104#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */
105#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */
106/* Address bits from SBADDR regs */
107#define SBSDIO_SBWINDOW_MASK 0xffff8000
108
109#define SDIOH_READ 0 /* Read request */
110#define SDIOH_WRITE 1 /* Write request */
111
112#define SDIOH_DATA_FIX 0 /* Fixed addressing */
113#define SDIOH_DATA_INC 1 /* Incremental addressing */
114
115/* internal return code */
116#define SUCCESS 0
117#define ERROR 1
118
119struct brcmf_sdreg {
120 int func;
121 int offset;
122 int value;
123};
124
125struct brcmf_sdio_dev {
126 struct sdio_func *func[SDIO_MAX_FUNCS];
127 u8 num_funcs; /* Supported funcs on client */
128 u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
129 u32 sbwad; /* Save backplane window address */
130 bool regfail; /* status of last reg_r/w call */
131 void *bus;
132 atomic_t suspend; /* suspend flag */
133 wait_queue_head_t request_byte_wait;
134 wait_queue_head_t request_word_wait;
135 wait_queue_head_t request_packet_wait;
136 wait_queue_head_t request_buffer_wait;
137
138};
139
140/* Register/deregister device interrupt handler. */
141extern int
142brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev);
143
144extern int brcmf_sdcard_intr_dereg(struct brcmf_sdio_dev *sdiodev);
145
146/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface).
147 * fn: function number
148 * addr: unmodified SDIO-space address
149 * data: data byte to write
150 * err: pointer to error code (or NULL)
151 */
152extern u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint func,
153 u32 addr, int *err);
154extern void brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, uint func,
155 u32 addr, u8 data, int *err);
156
157/* Synchronous access to device (client) core registers via CMD53 to F1.
158 * addr: backplane address (i.e. >= regsva from attach)
159 * size: register width in bytes (2 or 4)
160 * data: data for register write
161 */
162extern u32
163brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size);
164
165extern u32
166brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size,
167 u32 data);
168
169/* Indicate if last reg read/write failed */
170extern bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev);
171
172/* Buffer transfer to/from device (client) core via cmd53.
173 * fn: function number
174 * addr: backplane address (i.e. >= regsva from attach)
175 * flags: backplane width, address increment, sync/async
176 * buf: pointer to memory data buffer
177 * nbytes: number of bytes to transfer to/from buf
178 * pkt: pointer to packet associated with buf (if any)
179 * complete: callback function for command completion (async only)
180 * handle: handle for completion callback (first arg in callback)
181 * Returns 0 or error code.
182 * NOTE: Async operation is not currently supported.
183 */
184extern int
185brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
186 uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt);
187extern int
188brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
189 uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt);
190
191/* Flags bits */
192
193/* Four-byte target (backplane) width (vs. two-byte) */
194#define SDIO_REQ_4BYTE 0x1
195/* Fixed address (FIFO) (vs. incrementing address) */
196#define SDIO_REQ_FIXED 0x2
197/* Async request (vs. sync request) */
198#define SDIO_REQ_ASYNC 0x4
199
200/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
201 * rw: read or write (0/1)
202 * addr: direct SDIO address
203 * buf: pointer to memory data buffer
204 * nbytes: number of bytes to transfer to/from buf
205 * Returns 0 or error code.
206 */
207extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw,
208 u32 addr, u8 *buf, uint nbytes);
209
210/* Issue an abort to the specified function */
211extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
212
213/* platform specific/high level functions */
214extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
215extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev);
216
217extern int brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
218 u32 address);
219
220/* attach, return handler on success, NULL if failed.
221 * The handler shall be provided by all subsequent calls. No local cache
222 * cfghdl points to the starting address of pci device mapped memory
223 */
224extern int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev);
225extern void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev);
226
227/* read or write one byte using cmd52 */
228extern int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw,
229 uint fnc, uint addr, u8 *byte);
230
231/* read or write 2/4 bytes using cmd53 */
232extern int
233brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
234 uint rw, uint fnc, uint addr,
235 u32 *word, uint nbyte);
236
237/* read or write any buffer using cmd53 */
238extern int
239brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
240 uint fix_inc, uint rw, uint fnc_num,
241 u32 addr, uint regwidth,
242 u32 buflen, u8 *buffer, struct sk_buff *pkt);
243
244/* Watchdog timer interface for pm ops */
245extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev,
246 bool enable);
247
248extern void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype,
249 u32 regsva, struct brcmf_sdio_dev *sdiodev);
250extern void brcmf_sdbrcm_disconnect(void *ptr);
251extern void brcmf_sdbrcm_isr(void *arg);
252#endif /* _BRCM_SDH_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 000000000000..5eddabe5228a
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -0,0 +1,3868 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
18
19#include <linux/kernel.h>
20#include <linux/if_arp.h>
21#include <linux/sched.h>
22#include <linux/kthread.h>
23#include <linux/netdevice.h>
24#include <linux/bitops.h>
25#include <linux/etherdevice.h>
26#include <linux/ieee80211.h>
27#include <linux/uaccess.h>
28#include <net/cfg80211.h>
29
30#include <brcmu_utils.h>
31#include <defs.h>
32#include <brcmu_wifi.h>
33#include "dhd.h"
34#include "wl_cfg80211.h"
35
36#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
37 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
38
39static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
40
41static u32 brcmf_dbg_level = WL_DBG_ERR;
42
43static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
44{
45 dev->driver_data = data;
46}
47
48static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
49{
50 void *data = NULL;
51
52 if (dev)
53 data = dev->driver_data;
54 return data;
55}
56
57static
58struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
59{
60 struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
61 return ci->cfg_priv;
62}
63
64static bool check_sys_up(struct wiphy *wiphy)
65{
66 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
67 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
68 WL_INFO("device is not ready : status (%d)\n",
69 (int)cfg_priv->status);
70 return false;
71 }
72 return true;
73}
74
75#define CHAN2G(_channel, _freq, _flags) { \
76 .band = IEEE80211_BAND_2GHZ, \
77 .center_freq = (_freq), \
78 .hw_value = (_channel), \
79 .flags = (_flags), \
80 .max_antenna_gain = 0, \
81 .max_power = 30, \
82}
83
84#define CHAN5G(_channel, _flags) { \
85 .band = IEEE80211_BAND_5GHZ, \
86 .center_freq = 5000 + (5 * (_channel)), \
87 .hw_value = (_channel), \
88 .flags = (_flags), \
89 .max_antenna_gain = 0, \
90 .max_power = 30, \
91}
92
93#define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
94#define RATETAB_ENT(_rateid, _flags) \
95 { \
96 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
97 .hw_value = (_rateid), \
98 .flags = (_flags), \
99 }
100
101static struct ieee80211_rate __wl_rates[] = {
102 RATETAB_ENT(BRCM_RATE_1M, 0),
103 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
104 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
105 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
106 RATETAB_ENT(BRCM_RATE_6M, 0),
107 RATETAB_ENT(BRCM_RATE_9M, 0),
108 RATETAB_ENT(BRCM_RATE_12M, 0),
109 RATETAB_ENT(BRCM_RATE_18M, 0),
110 RATETAB_ENT(BRCM_RATE_24M, 0),
111 RATETAB_ENT(BRCM_RATE_36M, 0),
112 RATETAB_ENT(BRCM_RATE_48M, 0),
113 RATETAB_ENT(BRCM_RATE_54M, 0),
114};
115
116#define wl_a_rates (__wl_rates + 4)
117#define wl_a_rates_size 8
118#define wl_g_rates (__wl_rates + 0)
119#define wl_g_rates_size 12
120
121static struct ieee80211_channel __wl_2ghz_channels[] = {
122 CHAN2G(1, 2412, 0),
123 CHAN2G(2, 2417, 0),
124 CHAN2G(3, 2422, 0),
125 CHAN2G(4, 2427, 0),
126 CHAN2G(5, 2432, 0),
127 CHAN2G(6, 2437, 0),
128 CHAN2G(7, 2442, 0),
129 CHAN2G(8, 2447, 0),
130 CHAN2G(9, 2452, 0),
131 CHAN2G(10, 2457, 0),
132 CHAN2G(11, 2462, 0),
133 CHAN2G(12, 2467, 0),
134 CHAN2G(13, 2472, 0),
135 CHAN2G(14, 2484, 0),
136};
137
138static struct ieee80211_channel __wl_5ghz_a_channels[] = {
139 CHAN5G(34, 0), CHAN5G(36, 0),
140 CHAN5G(38, 0), CHAN5G(40, 0),
141 CHAN5G(42, 0), CHAN5G(44, 0),
142 CHAN5G(46, 0), CHAN5G(48, 0),
143 CHAN5G(52, 0), CHAN5G(56, 0),
144 CHAN5G(60, 0), CHAN5G(64, 0),
145 CHAN5G(100, 0), CHAN5G(104, 0),
146 CHAN5G(108, 0), CHAN5G(112, 0),
147 CHAN5G(116, 0), CHAN5G(120, 0),
148 CHAN5G(124, 0), CHAN5G(128, 0),
149 CHAN5G(132, 0), CHAN5G(136, 0),
150 CHAN5G(140, 0), CHAN5G(149, 0),
151 CHAN5G(153, 0), CHAN5G(157, 0),
152 CHAN5G(161, 0), CHAN5G(165, 0),
153 CHAN5G(184, 0), CHAN5G(188, 0),
154 CHAN5G(192, 0), CHAN5G(196, 0),
155 CHAN5G(200, 0), CHAN5G(204, 0),
156 CHAN5G(208, 0), CHAN5G(212, 0),
157 CHAN5G(216, 0),
158};
159
160static struct ieee80211_channel __wl_5ghz_n_channels[] = {
161 CHAN5G(32, 0), CHAN5G(34, 0),
162 CHAN5G(36, 0), CHAN5G(38, 0),
163 CHAN5G(40, 0), CHAN5G(42, 0),
164 CHAN5G(44, 0), CHAN5G(46, 0),
165 CHAN5G(48, 0), CHAN5G(50, 0),
166 CHAN5G(52, 0), CHAN5G(54, 0),
167 CHAN5G(56, 0), CHAN5G(58, 0),
168 CHAN5G(60, 0), CHAN5G(62, 0),
169 CHAN5G(64, 0), CHAN5G(66, 0),
170 CHAN5G(68, 0), CHAN5G(70, 0),
171 CHAN5G(72, 0), CHAN5G(74, 0),
172 CHAN5G(76, 0), CHAN5G(78, 0),
173 CHAN5G(80, 0), CHAN5G(82, 0),
174 CHAN5G(84, 0), CHAN5G(86, 0),
175 CHAN5G(88, 0), CHAN5G(90, 0),
176 CHAN5G(92, 0), CHAN5G(94, 0),
177 CHAN5G(96, 0), CHAN5G(98, 0),
178 CHAN5G(100, 0), CHAN5G(102, 0),
179 CHAN5G(104, 0), CHAN5G(106, 0),
180 CHAN5G(108, 0), CHAN5G(110, 0),
181 CHAN5G(112, 0), CHAN5G(114, 0),
182 CHAN5G(116, 0), CHAN5G(118, 0),
183 CHAN5G(120, 0), CHAN5G(122, 0),
184 CHAN5G(124, 0), CHAN5G(126, 0),
185 CHAN5G(128, 0), CHAN5G(130, 0),
186 CHAN5G(132, 0), CHAN5G(134, 0),
187 CHAN5G(136, 0), CHAN5G(138, 0),
188 CHAN5G(140, 0), CHAN5G(142, 0),
189 CHAN5G(144, 0), CHAN5G(145, 0),
190 CHAN5G(146, 0), CHAN5G(147, 0),
191 CHAN5G(148, 0), CHAN5G(149, 0),
192 CHAN5G(150, 0), CHAN5G(151, 0),
193 CHAN5G(152, 0), CHAN5G(153, 0),
194 CHAN5G(154, 0), CHAN5G(155, 0),
195 CHAN5G(156, 0), CHAN5G(157, 0),
196 CHAN5G(158, 0), CHAN5G(159, 0),
197 CHAN5G(160, 0), CHAN5G(161, 0),
198 CHAN5G(162, 0), CHAN5G(163, 0),
199 CHAN5G(164, 0), CHAN5G(165, 0),
200 CHAN5G(166, 0), CHAN5G(168, 0),
201 CHAN5G(170, 0), CHAN5G(172, 0),
202 CHAN5G(174, 0), CHAN5G(176, 0),
203 CHAN5G(178, 0), CHAN5G(180, 0),
204 CHAN5G(182, 0), CHAN5G(184, 0),
205 CHAN5G(186, 0), CHAN5G(188, 0),
206 CHAN5G(190, 0), CHAN5G(192, 0),
207 CHAN5G(194, 0), CHAN5G(196, 0),
208 CHAN5G(198, 0), CHAN5G(200, 0),
209 CHAN5G(202, 0), CHAN5G(204, 0),
210 CHAN5G(206, 0), CHAN5G(208, 0),
211 CHAN5G(210, 0), CHAN5G(212, 0),
212 CHAN5G(214, 0), CHAN5G(216, 0),
213 CHAN5G(218, 0), CHAN5G(220, 0),
214 CHAN5G(222, 0), CHAN5G(224, 0),
215 CHAN5G(226, 0), CHAN5G(228, 0),
216};
217
218static struct ieee80211_supported_band __wl_band_2ghz = {
219 .band = IEEE80211_BAND_2GHZ,
220 .channels = __wl_2ghz_channels,
221 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
222 .bitrates = wl_g_rates,
223 .n_bitrates = wl_g_rates_size,
224};
225
226static struct ieee80211_supported_band __wl_band_5ghz_a = {
227 .band = IEEE80211_BAND_5GHZ,
228 .channels = __wl_5ghz_a_channels,
229 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
230 .bitrates = wl_a_rates,
231 .n_bitrates = wl_a_rates_size,
232};
233
234static struct ieee80211_supported_band __wl_band_5ghz_n = {
235 .band = IEEE80211_BAND_5GHZ,
236 .channels = __wl_5ghz_n_channels,
237 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
238 .bitrates = wl_a_rates,
239 .n_bitrates = wl_a_rates_size,
240};
241
242static const u32 __wl_cipher_suites[] = {
243 WLAN_CIPHER_SUITE_WEP40,
244 WLAN_CIPHER_SUITE_WEP104,
245 WLAN_CIPHER_SUITE_TKIP,
246 WLAN_CIPHER_SUITE_CCMP,
247 WLAN_CIPHER_SUITE_AES_CMAC,
248};
249
250/* tag_ID/length/value_buffer tuple */
251struct brcmf_tlv {
252 u8 id;
253 u8 len;
254 u8 data[1];
255};
256
257/* Quarter dBm units to mW
258 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
259 * Table is offset so the last entry is largest mW value that fits in
260 * a u16.
261 */
262
263#define QDBM_OFFSET 153 /* Offset for first entry */
264#define QDBM_TABLE_LEN 40 /* Table size */
265
266/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
267 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
268 */
269#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
270
271/* Largest mW value that will round down to the last table entry,
272 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
273 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
274 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
275 */
276#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
277
278static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
279/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
280/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
281/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
282/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
283/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
284/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
285};
286
287static u16 brcmf_qdbm_to_mw(u8 qdbm)
288{
289 uint factor = 1;
290 int idx = qdbm - QDBM_OFFSET;
291
292 if (idx >= QDBM_TABLE_LEN)
293 /* clamp to max u16 mW value */
294 return 0xFFFF;
295
296 /* scale the qdBm index up to the range of the table 0-40
297 * where an offset of 40 qdBm equals a factor of 10 mW.
298 */
299 while (idx < 0) {
300 idx += 40;
301 factor *= 10;
302 }
303
304 /* return the mW value scaled down to the correct factor of 10,
305 * adding in factor/2 to get proper rounding.
306 */
307 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
308}
309
310static u8 brcmf_mw_to_qdbm(u16 mw)
311{
312 u8 qdbm;
313 int offset;
314 uint mw_uint = mw;
315 uint boundary;
316
317 /* handle boundary case */
318 if (mw_uint <= 1)
319 return 0;
320
321 offset = QDBM_OFFSET;
322
323 /* move mw into the range of the table */
324 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
325 mw_uint *= 10;
326 offset -= 40;
327 }
328
329 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
330 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
331 nqdBm_to_mW_map[qdbm]) / 2;
332 if (mw_uint < boundary)
333 break;
334 }
335
336 qdbm += (u8) offset;
337
338 return qdbm;
339}
340
341/* function for reading/writing a single u32 from/to the dongle */
342static int
343brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
344{
345 int err;
346 __le32 par_le = cpu_to_le32(*par);
347
348 err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
349 *par = le32_to_cpu(par_le);
350
351 return err;
352}
353
354static void convert_key_from_CPU(struct brcmf_wsec_key *key,
355 struct brcmf_wsec_key_le *key_le)
356{
357 key_le->index = cpu_to_le32(key->index);
358 key_le->len = cpu_to_le32(key->len);
359 key_le->algo = cpu_to_le32(key->algo);
360 key_le->flags = cpu_to_le32(key->flags);
361 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
362 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
363 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
364 memcpy(key_le->data, key->data, sizeof(key->data));
365 memcpy(key_le->ea, key->ea, sizeof(key->ea));
366}
367
368static int send_key_to_dongle(struct net_device *ndev,
369 struct brcmf_wsec_key *key)
370{
371 int err;
372 struct brcmf_wsec_key_le key_le;
373
374 convert_key_from_CPU(key, &key_le);
375 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
376 if (err)
377 WL_ERR("WLC_SET_KEY error (%d)\n", err);
378 return err;
379}
380
381static s32
382brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
383 enum nl80211_iftype type, u32 *flags,
384 struct vif_params *params)
385{
386 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
387 struct wireless_dev *wdev;
388 s32 infra = 0;
389 s32 err = 0;
390
391 WL_TRACE("Enter\n");
392 if (!check_sys_up(wiphy))
393 return -EIO;
394
395 switch (type) {
396 case NL80211_IFTYPE_MONITOR:
397 case NL80211_IFTYPE_WDS:
398 WL_ERR("type (%d) : currently we do not support this type\n",
399 type);
400 return -EOPNOTSUPP;
401 case NL80211_IFTYPE_ADHOC:
402 cfg_priv->conf->mode = WL_MODE_IBSS;
403 infra = 0;
404 break;
405 case NL80211_IFTYPE_STATION:
406 cfg_priv->conf->mode = WL_MODE_BSS;
407 infra = 1;
408 break;
409 default:
410 err = -EINVAL;
411 goto done;
412 }
413
414 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
415 if (err) {
416 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
417 err = -EAGAIN;
418 } else {
419 wdev = ndev->ieee80211_ptr;
420 wdev->iftype = type;
421 }
422
423 WL_INFO("IF Type = %s\n",
424 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
425
426done:
427 WL_TRACE("Exit\n");
428
429 return err;
430}
431
432static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
433{
434 s8 buf[BRCMF_DCMD_SMLEN];
435 u32 len;
436 s32 err = 0;
437 __le32 val_le;
438
439 val_le = cpu_to_le32(val);
440 len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
441 sizeof(buf));
442 BUG_ON(!len);
443
444 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
445 if (err)
446 WL_ERR("error (%d)\n", err);
447
448 return err;
449}
450
451static s32
452brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
453{
454 union {
455 s8 buf[BRCMF_DCMD_SMLEN];
456 __le32 val;
457 } var;
458 u32 len;
459 u32 data_null;
460 s32 err = 0;
461
462 len =
463 brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
464 sizeof(var.buf));
465 BUG_ON(!len);
466 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
467 if (err)
468 WL_ERR("error (%d)\n", err);
469
470 *retval = le32_to_cpu(var.val);
471
472 return err;
473}
474
475static void brcmf_set_mpc(struct net_device *ndev, int mpc)
476{
477 s32 err = 0;
478 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
479
480 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
481 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
482 if (err) {
483 WL_ERR("fail to set mpc\n");
484 return;
485 }
486 WL_INFO("MPC : %d\n", mpc);
487 }
488}
489
490static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
491 struct brcmf_ssid *ssid)
492{
493 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
494 params_le->bss_type = DOT11_BSSTYPE_ANY;
495 params_le->scan_type = 0;
496 params_le->channel_num = 0;
497 params_le->nprobes = cpu_to_le32(-1);
498 params_le->active_time = cpu_to_le32(-1);
499 params_le->passive_time = cpu_to_le32(-1);
500 params_le->home_time = cpu_to_le32(-1);
501 if (ssid && ssid->SSID_len)
502 memcpy(&params_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
503}
504
505static s32
506brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
507 s32 paramlen, void *bufptr, s32 buflen)
508{
509 s32 iolen;
510
511 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
512 BUG_ON(!iolen);
513
514 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
515}
516
517static s32
518brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
519 s32 paramlen, void *bufptr, s32 buflen)
520{
521 s32 iolen;
522
523 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
524 BUG_ON(!iolen);
525
526 return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
527}
528
529static s32
530brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
531 struct brcmf_ssid *ssid, u16 action)
532{
533 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
534 offsetof(struct brcmf_iscan_params_le, params_le);
535 struct brcmf_iscan_params_le *params;
536 s32 err = 0;
537
538 if (ssid && ssid->SSID_len)
539 params_size += sizeof(struct brcmf_ssid);
540 params = kzalloc(params_size, GFP_KERNEL);
541 if (!params)
542 return -ENOMEM;
543 BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
544
545 wl_iscan_prep(&params->params_le, ssid);
546
547 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
548 params->action = cpu_to_le16(action);
549 params->scan_duration = cpu_to_le16(0);
550
551 err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
552 iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
553 if (err) {
554 if (err == -EBUSY)
555 WL_INFO("system busy : iscan canceled\n");
556 else
557 WL_ERR("error (%d)\n", err);
558 }
559
560 kfree(params);
561 return err;
562}
563
564static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
565{
566 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
567 struct net_device *ndev = cfg_to_ndev(cfg_priv);
568 struct brcmf_ssid ssid;
569 __le32 passive_scan;
570 s32 err = 0;
571
572 /* Broadcast scan by default */
573 memset(&ssid, 0, sizeof(ssid));
574
575 iscan->state = WL_ISCAN_STATE_SCANING;
576
577 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
578 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
579 &passive_scan, sizeof(passive_scan));
580 if (err) {
581 WL_ERR("error (%d)\n", err);
582 return err;
583 }
584 brcmf_set_mpc(ndev, 0);
585 cfg_priv->iscan_kickstart = true;
586 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
587 if (err) {
588 brcmf_set_mpc(ndev, 1);
589 cfg_priv->iscan_kickstart = false;
590 return err;
591 }
592 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
593 iscan->timer_on = 1;
594 return err;
595}
596
597static s32
598__brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
599 struct cfg80211_scan_request *request,
600 struct cfg80211_ssid *this_ssid)
601{
602 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
603 struct cfg80211_ssid *ssids;
604 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
605 __le32 passive_scan;
606 bool iscan_req;
607 bool spec_scan;
608 s32 err = 0;
609 u32 SSID_len;
610
611 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
612 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
613 return -EAGAIN;
614 }
615 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
616 WL_ERR("Scanning being aborted : status (%lu)\n",
617 cfg_priv->status);
618 return -EAGAIN;
619 }
620 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
621 WL_ERR("Connecting : status (%lu)\n",
622 cfg_priv->status);
623 return -EAGAIN;
624 }
625
626 iscan_req = false;
627 spec_scan = false;
628 if (request) {
629 /* scan bss */
630 ssids = request->ssids;
631 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
632 iscan_req = true;
633 } else {
634 /* scan in ibss */
635 /* we don't do iscan in ibss */
636 ssids = this_ssid;
637 }
638
639 cfg_priv->scan_request = request;
640 set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
641 if (iscan_req) {
642 err = brcmf_do_iscan(cfg_priv);
643 if (!err)
644 return err;
645 else
646 goto scan_out;
647 } else {
648 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
649 ssids->ssid, ssids->ssid_len);
650 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
651 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
652 sr->ssid_le.SSID_len = cpu_to_le32(0);
653 if (SSID_len) {
654 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
655 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
656 spec_scan = true;
657 } else {
658 WL_SCAN("Broadcast scan\n");
659 }
660
661 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
662 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
663 &passive_scan, sizeof(passive_scan));
664 if (err) {
665 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
666 goto scan_out;
667 }
668 brcmf_set_mpc(ndev, 0);
669 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
670 sizeof(sr->ssid_le));
671 if (err) {
672 if (err == -EBUSY)
673 WL_INFO("system busy : scan for \"%s\" "
674 "canceled\n", sr->ssid_le.SSID);
675 else
676 WL_ERR("WLC_SCAN error (%d)\n", err);
677
678 brcmf_set_mpc(ndev, 1);
679 goto scan_out;
680 }
681 }
682
683 return 0;
684
685scan_out:
686 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
687 cfg_priv->scan_request = NULL;
688 return err;
689}
690
691static s32
692brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
693 struct cfg80211_scan_request *request)
694{
695 s32 err = 0;
696
697 WL_TRACE("Enter\n");
698
699 if (!check_sys_up(wiphy))
700 return -EIO;
701
702 err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
703 if (err)
704 WL_ERR("scan error (%d)\n", err);
705
706 WL_TRACE("Exit\n");
707 return err;
708}
709
710static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
711{
712 s32 err = 0;
713
714 err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
715 if (err)
716 WL_ERR("Error (%d)\n", err);
717
718 return err;
719}
720
721static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
722{
723 s32 err = 0;
724
725 err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
726 if (err)
727 WL_ERR("Error (%d)\n", err);
728
729 return err;
730}
731
732static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
733{
734 s32 err = 0;
735 u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
736
737 err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
738 if (err) {
739 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
740 return err;
741 }
742 return err;
743}
744
745static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
746{
747 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
748 struct net_device *ndev = cfg_to_ndev(cfg_priv);
749 s32 err = 0;
750
751 WL_TRACE("Enter\n");
752 if (!check_sys_up(wiphy))
753 return -EIO;
754
755 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
756 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
757 cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
758 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
759 if (!err)
760 goto done;
761 }
762 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
763 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
764 cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
765 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
766 if (!err)
767 goto done;
768 }
769 if (changed & WIPHY_PARAM_RETRY_LONG
770 && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
771 cfg_priv->conf->retry_long = wiphy->retry_long;
772 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
773 if (!err)
774 goto done;
775 }
776 if (changed & WIPHY_PARAM_RETRY_SHORT
777 && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
778 cfg_priv->conf->retry_short = wiphy->retry_short;
779 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
780 if (!err)
781 goto done;
782 }
783
784done:
785 WL_TRACE("Exit\n");
786 return err;
787}
788
789static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
790{
791 switch (item) {
792 case WL_PROF_SEC:
793 return &cfg_priv->profile->sec;
794 case WL_PROF_BSSID:
795 return &cfg_priv->profile->bssid;
796 case WL_PROF_SSID:
797 return &cfg_priv->profile->ssid;
798 }
799 WL_ERR("invalid item (%d)\n", item);
800 return NULL;
801}
802
803static s32
804brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
805 const struct brcmf_event_msg *e, void *data, s32 item)
806{
807 s32 err = 0;
808 struct brcmf_ssid *ssid;
809
810 switch (item) {
811 case WL_PROF_SSID:
812 ssid = (struct brcmf_ssid *) data;
813 memset(cfg_priv->profile->ssid.SSID, 0,
814 sizeof(cfg_priv->profile->ssid.SSID));
815 memcpy(cfg_priv->profile->ssid.SSID,
816 ssid->SSID, ssid->SSID_len);
817 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
818 break;
819 case WL_PROF_BSSID:
820 if (data)
821 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
822 else
823 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
824 break;
825 case WL_PROF_SEC:
826 memcpy(&cfg_priv->profile->sec, data,
827 sizeof(cfg_priv->profile->sec));
828 break;
829 case WL_PROF_BEACONINT:
830 cfg_priv->profile->beacon_interval = *(u16 *)data;
831 break;
832 case WL_PROF_DTIMPERIOD:
833 cfg_priv->profile->dtim_period = *(u8 *)data;
834 break;
835 default:
836 WL_ERR("unsupported item (%d)\n", item);
837 err = -EOPNOTSUPP;
838 break;
839 }
840
841 return err;
842}
843
844static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
845{
846 memset(prof, 0, sizeof(*prof));
847}
848
849static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
850 size_t *join_params_size)
851{
852 u16 chanspec = 0;
853
854 if (ch != 0) {
855 if (ch <= CH_MAX_2G_CHANNEL)
856 chanspec |= WL_CHANSPEC_BAND_2G;
857 else
858 chanspec |= WL_CHANSPEC_BAND_5G;
859
860 chanspec |= WL_CHANSPEC_BW_20;
861 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
862
863 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
864 sizeof(u16);
865
866 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
867 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
868 join_params->params_le.chanspec_num = cpu_to_le32(1);
869
870 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
871 "channel %d, chanspec %#X\n",
872 chanspec, ch, chanspec);
873 }
874}
875
876static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
877{
878 struct net_device *ndev = NULL;
879 s32 err = 0;
880
881 WL_TRACE("Enter\n");
882
883 if (cfg_priv->link_up) {
884 ndev = cfg_to_ndev(cfg_priv);
885 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
886 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
887 if (err)
888 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
889 cfg_priv->link_up = false;
890 }
891 WL_TRACE("Exit\n");
892}
893
894static s32
895brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
896 struct cfg80211_ibss_params *params)
897{
898 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
899 struct brcmf_join_params join_params;
900 size_t join_params_size = 0;
901 s32 err = 0;
902 s32 wsec = 0;
903 s32 bcnprd;
904 struct brcmf_ssid ssid;
905
906 WL_TRACE("Enter\n");
907 if (!check_sys_up(wiphy))
908 return -EIO;
909
910 if (params->ssid)
911 WL_CONN("SSID: %s\n", params->ssid);
912 else {
913 WL_CONN("SSID: NULL, Not supported\n");
914 return -EOPNOTSUPP;
915 }
916
917 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
918
919 if (params->bssid)
920 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
921 params->bssid[0], params->bssid[1], params->bssid[2],
922 params->bssid[3], params->bssid[4], params->bssid[5]);
923 else
924 WL_CONN("No BSSID specified\n");
925
926 if (params->channel)
927 WL_CONN("channel: %d\n", params->channel->center_freq);
928 else
929 WL_CONN("no channel specified\n");
930
931 if (params->channel_fixed)
932 WL_CONN("fixed channel required\n");
933 else
934 WL_CONN("no fixed channel required\n");
935
936 if (params->ie && params->ie_len)
937 WL_CONN("ie len: %d\n", params->ie_len);
938 else
939 WL_CONN("no ie specified\n");
940
941 if (params->beacon_interval)
942 WL_CONN("beacon interval: %d\n", params->beacon_interval);
943 else
944 WL_CONN("no beacon interval specified\n");
945
946 if (params->basic_rates)
947 WL_CONN("basic rates: %08X\n", params->basic_rates);
948 else
949 WL_CONN("no basic rates specified\n");
950
951 if (params->privacy)
952 WL_CONN("privacy required\n");
953 else
954 WL_CONN("no privacy required\n");
955
956 /* Configure Privacy for starter */
957 if (params->privacy)
958 wsec |= WEP_ENABLED;
959
960 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
961 if (err) {
962 WL_ERR("wsec failed (%d)\n", err);
963 goto done;
964 }
965
966 /* Configure Beacon Interval for starter */
967 if (params->beacon_interval)
968 bcnprd = params->beacon_interval;
969 else
970 bcnprd = 100;
971
972 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
973 if (err) {
974 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
975 goto done;
976 }
977
978 /* Configure required join parameter */
979 memset(&join_params, 0, sizeof(struct brcmf_join_params));
980
981 /* SSID */
982 ssid.SSID_len = min_t(u32, params->ssid_len, 32);
983 memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
984 memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
985 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
986 join_params_size = sizeof(join_params.ssid_le);
987 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
988
989 /* BSSID */
990 if (params->bssid) {
991 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
992 join_params_size = sizeof(join_params.ssid_le) +
993 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
994 } else {
995 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
996 }
997
998 brcmf_update_prof(cfg_priv, NULL,
999 &join_params.params_le.bssid, WL_PROF_BSSID);
1000
1001 /* Channel */
1002 if (params->channel) {
1003 u32 target_channel;
1004
1005 cfg_priv->channel =
1006 ieee80211_frequency_to_channel(
1007 params->channel->center_freq);
1008 if (params->channel_fixed) {
1009 /* adding chanspec */
1010 brcmf_ch_to_chanspec(cfg_priv->channel,
1011 &join_params, &join_params_size);
1012 }
1013
1014 /* set channel for starter */
1015 target_channel = cfg_priv->channel;
1016 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1017 &target_channel);
1018 if (err) {
1019 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1020 goto done;
1021 }
1022 } else
1023 cfg_priv->channel = 0;
1024
1025 cfg_priv->ibss_starter = false;
1026
1027
1028 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1029 &join_params, join_params_size);
1030 if (err) {
1031 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1032 goto done;
1033 }
1034
1035done:
1036 if (err)
1037 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1038 WL_TRACE("Exit\n");
1039 return err;
1040}
1041
1042static s32
1043brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1044{
1045 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1046 s32 err = 0;
1047
1048 WL_TRACE("Enter\n");
1049 if (!check_sys_up(wiphy))
1050 return -EIO;
1051
1052 brcmf_link_down(cfg_priv);
1053
1054 WL_TRACE("Exit\n");
1055
1056 return err;
1057}
1058
1059static s32 brcmf_set_wpa_version(struct net_device *ndev,
1060 struct cfg80211_connect_params *sme)
1061{
1062 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1063 struct brcmf_cfg80211_security *sec;
1064 s32 val = 0;
1065 s32 err = 0;
1066
1067 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1068 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1069 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1070 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1071 else
1072 val = WPA_AUTH_DISABLED;
1073 WL_CONN("setting wpa_auth to 0x%0x\n", val);
1074 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1075 if (err) {
1076 WL_ERR("set wpa_auth failed (%d)\n", err);
1077 return err;
1078 }
1079 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1080 sec->wpa_versions = sme->crypto.wpa_versions;
1081 return err;
1082}
1083
1084static s32 brcmf_set_auth_type(struct net_device *ndev,
1085 struct cfg80211_connect_params *sme)
1086{
1087 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1088 struct brcmf_cfg80211_security *sec;
1089 s32 val = 0;
1090 s32 err = 0;
1091
1092 switch (sme->auth_type) {
1093 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1094 val = 0;
1095 WL_CONN("open system\n");
1096 break;
1097 case NL80211_AUTHTYPE_SHARED_KEY:
1098 val = 1;
1099 WL_CONN("shared key\n");
1100 break;
1101 case NL80211_AUTHTYPE_AUTOMATIC:
1102 val = 2;
1103 WL_CONN("automatic\n");
1104 break;
1105 case NL80211_AUTHTYPE_NETWORK_EAP:
1106 WL_CONN("network eap\n");
1107 default:
1108 val = 2;
1109 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1110 break;
1111 }
1112
1113 err = brcmf_dev_intvar_set(ndev, "auth", val);
1114 if (err) {
1115 WL_ERR("set auth failed (%d)\n", err);
1116 return err;
1117 }
1118 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1119 sec->auth_type = sme->auth_type;
1120 return err;
1121}
1122
1123static s32
1124brcmf_set_set_cipher(struct net_device *ndev,
1125 struct cfg80211_connect_params *sme)
1126{
1127 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1128 struct brcmf_cfg80211_security *sec;
1129 s32 pval = 0;
1130 s32 gval = 0;
1131 s32 err = 0;
1132
1133 if (sme->crypto.n_ciphers_pairwise) {
1134 switch (sme->crypto.ciphers_pairwise[0]) {
1135 case WLAN_CIPHER_SUITE_WEP40:
1136 case WLAN_CIPHER_SUITE_WEP104:
1137 pval = WEP_ENABLED;
1138 break;
1139 case WLAN_CIPHER_SUITE_TKIP:
1140 pval = TKIP_ENABLED;
1141 break;
1142 case WLAN_CIPHER_SUITE_CCMP:
1143 pval = AES_ENABLED;
1144 break;
1145 case WLAN_CIPHER_SUITE_AES_CMAC:
1146 pval = AES_ENABLED;
1147 break;
1148 default:
1149 WL_ERR("invalid cipher pairwise (%d)\n",
1150 sme->crypto.ciphers_pairwise[0]);
1151 return -EINVAL;
1152 }
1153 }
1154 if (sme->crypto.cipher_group) {
1155 switch (sme->crypto.cipher_group) {
1156 case WLAN_CIPHER_SUITE_WEP40:
1157 case WLAN_CIPHER_SUITE_WEP104:
1158 gval = WEP_ENABLED;
1159 break;
1160 case WLAN_CIPHER_SUITE_TKIP:
1161 gval = TKIP_ENABLED;
1162 break;
1163 case WLAN_CIPHER_SUITE_CCMP:
1164 gval = AES_ENABLED;
1165 break;
1166 case WLAN_CIPHER_SUITE_AES_CMAC:
1167 gval = AES_ENABLED;
1168 break;
1169 default:
1170 WL_ERR("invalid cipher group (%d)\n",
1171 sme->crypto.cipher_group);
1172 return -EINVAL;
1173 }
1174 }
1175
1176 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1177 err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
1178 if (err) {
1179 WL_ERR("error (%d)\n", err);
1180 return err;
1181 }
1182
1183 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1184 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1185 sec->cipher_group = sme->crypto.cipher_group;
1186
1187 return err;
1188}
1189
1190static s32
1191brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1192{
1193 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1194 struct brcmf_cfg80211_security *sec;
1195 s32 val = 0;
1196 s32 err = 0;
1197
1198 if (sme->crypto.n_akm_suites) {
1199 err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
1200 if (err) {
1201 WL_ERR("could not get wpa_auth (%d)\n", err);
1202 return err;
1203 }
1204 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1205 switch (sme->crypto.akm_suites[0]) {
1206 case WLAN_AKM_SUITE_8021X:
1207 val = WPA_AUTH_UNSPECIFIED;
1208 break;
1209 case WLAN_AKM_SUITE_PSK:
1210 val = WPA_AUTH_PSK;
1211 break;
1212 default:
1213 WL_ERR("invalid cipher group (%d)\n",
1214 sme->crypto.cipher_group);
1215 return -EINVAL;
1216 }
1217 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1218 switch (sme->crypto.akm_suites[0]) {
1219 case WLAN_AKM_SUITE_8021X:
1220 val = WPA2_AUTH_UNSPECIFIED;
1221 break;
1222 case WLAN_AKM_SUITE_PSK:
1223 val = WPA2_AUTH_PSK;
1224 break;
1225 default:
1226 WL_ERR("invalid cipher group (%d)\n",
1227 sme->crypto.cipher_group);
1228 return -EINVAL;
1229 }
1230 }
1231
1232 WL_CONN("setting wpa_auth to %d\n", val);
1233 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1234 if (err) {
1235 WL_ERR("could not set wpa_auth (%d)\n", err);
1236 return err;
1237 }
1238 }
1239 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1240 sec->wpa_auth = sme->crypto.akm_suites[0];
1241
1242 return err;
1243}
1244
1245static s32
1246brcmf_set_wep_sharedkey(struct net_device *ndev,
1247 struct cfg80211_connect_params *sme)
1248{
1249 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1250 struct brcmf_cfg80211_security *sec;
1251 struct brcmf_wsec_key key;
1252 s32 val;
1253 s32 err = 0;
1254
1255 WL_CONN("key len (%d)\n", sme->key_len);
1256
1257 if (sme->key_len == 0)
1258 return 0;
1259
1260 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1261 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1262 sec->wpa_versions, sec->cipher_pairwise);
1263
1264 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1265 return 0;
1266
1267 if (sec->cipher_pairwise &
1268 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) {
1269 memset(&key, 0, sizeof(key));
1270 key.len = (u32) sme->key_len;
1271 key.index = (u32) sme->key_idx;
1272 if (key.len > sizeof(key.data)) {
1273 WL_ERR("Too long key length (%u)\n", key.len);
1274 return -EINVAL;
1275 }
1276 memcpy(key.data, sme->key, key.len);
1277 key.flags = BRCMF_PRIMARY_KEY;
1278 switch (sec->cipher_pairwise) {
1279 case WLAN_CIPHER_SUITE_WEP40:
1280 key.algo = CRYPTO_ALGO_WEP1;
1281 break;
1282 case WLAN_CIPHER_SUITE_WEP104:
1283 key.algo = CRYPTO_ALGO_WEP128;
1284 break;
1285 default:
1286 WL_ERR("Invalid algorithm (%d)\n",
1287 sme->crypto.ciphers_pairwise[0]);
1288 return -EINVAL;
1289 }
1290 /* Set the new key/index */
1291 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1292 key.len, key.index, key.algo);
1293 WL_CONN("key \"%s\"\n", key.data);
1294 err = send_key_to_dongle(ndev, &key);
1295 if (err)
1296 return err;
1297
1298 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1299 WL_CONN("set auth_type to shared key\n");
1300 val = 1; /* shared key */
1301 err = brcmf_dev_intvar_set(ndev, "auth", val);
1302 if (err) {
1303 WL_ERR("set auth failed (%d)\n", err);
1304 return err;
1305 }
1306 }
1307 }
1308 return err;
1309}
1310
1311static s32
1312brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1313 struct cfg80211_connect_params *sme)
1314{
1315 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1316 struct ieee80211_channel *chan = sme->channel;
1317 struct brcmf_join_params join_params;
1318 size_t join_params_size;
1319 struct brcmf_ssid ssid;
1320
1321 s32 err = 0;
1322
1323 WL_TRACE("Enter\n");
1324 if (!check_sys_up(wiphy))
1325 return -EIO;
1326
1327 if (!sme->ssid) {
1328 WL_ERR("Invalid ssid\n");
1329 return -EOPNOTSUPP;
1330 }
1331
1332 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1333
1334 if (chan) {
1335 cfg_priv->channel =
1336 ieee80211_frequency_to_channel(chan->center_freq);
1337 WL_CONN("channel (%d), center_req (%d)\n",
1338 cfg_priv->channel, chan->center_freq);
1339 } else
1340 cfg_priv->channel = 0;
1341
1342 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1343
1344 err = brcmf_set_wpa_version(ndev, sme);
1345 if (err) {
1346 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1347 goto done;
1348 }
1349
1350 err = brcmf_set_auth_type(ndev, sme);
1351 if (err) {
1352 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1353 goto done;
1354 }
1355
1356 err = brcmf_set_set_cipher(ndev, sme);
1357 if (err) {
1358 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1359 goto done;
1360 }
1361
1362 err = brcmf_set_key_mgmt(ndev, sme);
1363 if (err) {
1364 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1365 goto done;
1366 }
1367
1368 err = brcmf_set_wep_sharedkey(ndev, sme);
1369 if (err) {
1370 WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err);
1371 goto done;
1372 }
1373
1374 memset(&join_params, 0, sizeof(join_params));
1375 join_params_size = sizeof(join_params.ssid_le);
1376
1377 ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), sme->ssid_len);
1378 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
1379 memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
1380 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
1381 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
1382
1383 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1384
1385 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1386 WL_CONN("ssid \"%s\", len (%d)\n",
1387 ssid.SSID, ssid.SSID_len);
1388
1389 brcmf_ch_to_chanspec(cfg_priv->channel,
1390 &join_params, &join_params_size);
1391 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1392 &join_params, join_params_size);
1393 if (err)
1394 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1395
1396done:
1397 if (err)
1398 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1399 WL_TRACE("Exit\n");
1400 return err;
1401}
1402
1403static s32
1404brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1405 u16 reason_code)
1406{
1407 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1408 struct brcmf_scb_val_le scbval;
1409 s32 err = 0;
1410
1411 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1412 if (!check_sys_up(wiphy))
1413 return -EIO;
1414
1415 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1416
1417 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1418 scbval.val = cpu_to_le32(reason_code);
1419 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1420 sizeof(struct brcmf_scb_val_le));
1421 if (err)
1422 WL_ERR("error (%d)\n", err);
1423
1424 cfg_priv->link_up = false;
1425
1426 WL_TRACE("Exit\n");
1427 return err;
1428}
1429
1430static s32
1431brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1432 enum nl80211_tx_power_setting type, s32 dbm)
1433{
1434
1435 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1436 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1437 u16 txpwrmw;
1438 s32 err = 0;
1439 s32 disable = 0;
1440
1441 WL_TRACE("Enter\n");
1442 if (!check_sys_up(wiphy))
1443 return -EIO;
1444
1445 switch (type) {
1446 case NL80211_TX_POWER_AUTOMATIC:
1447 break;
1448 case NL80211_TX_POWER_LIMITED:
1449 if (dbm < 0) {
1450 WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1451 err = -EINVAL;
1452 goto done;
1453 }
1454 break;
1455 case NL80211_TX_POWER_FIXED:
1456 if (dbm < 0) {
1457 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1458 err = -EINVAL;
1459 goto done;
1460 }
1461 break;
1462 }
1463 /* Make sure radio is off or on as far as software is concerned */
1464 disable = WL_RADIO_SW_DISABLE << 16;
1465 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1466 if (err)
1467 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1468
1469 if (dbm > 0xffff)
1470 txpwrmw = 0xffff;
1471 else
1472 txpwrmw = (u16) dbm;
1473 err = brcmf_dev_intvar_set(ndev, "qtxpower",
1474 (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1475 if (err)
1476 WL_ERR("qtxpower error (%d)\n", err);
1477 cfg_priv->conf->tx_power = dbm;
1478
1479done:
1480 WL_TRACE("Exit\n");
1481 return err;
1482}
1483
1484static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1485{
1486 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1487 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1488 s32 txpwrdbm;
1489 u8 result;
1490 s32 err = 0;
1491
1492 WL_TRACE("Enter\n");
1493 if (!check_sys_up(wiphy))
1494 return -EIO;
1495
1496 err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1497 if (err) {
1498 WL_ERR("error (%d)\n", err);
1499 goto done;
1500 }
1501
1502 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1503 *dbm = (s32) brcmf_qdbm_to_mw(result);
1504
1505done:
1506 WL_TRACE("Exit\n");
1507 return err;
1508}
1509
1510static s32
1511brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1512 u8 key_idx, bool unicast, bool multicast)
1513{
1514 u32 index;
1515 u32 wsec;
1516 s32 err = 0;
1517
1518 WL_TRACE("Enter\n");
1519 WL_CONN("key index (%d)\n", key_idx);
1520 if (!check_sys_up(wiphy))
1521 return -EIO;
1522
1523 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1524 if (err) {
1525 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1526 goto done;
1527 }
1528
1529 if (wsec & WEP_ENABLED) {
1530 /* Just select a new current key */
1531 index = key_idx;
1532 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
1533 &index);
1534 if (err)
1535 WL_ERR("error (%d)\n", err);
1536 }
1537done:
1538 WL_TRACE("Exit\n");
1539 return err;
1540}
1541
1542static s32
1543brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1544 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1545{
1546 struct brcmf_wsec_key key;
1547 struct brcmf_wsec_key_le key_le;
1548 s32 err = 0;
1549
1550 memset(&key, 0, sizeof(key));
1551 key.index = (u32) key_idx;
1552 /* Instead of bcast for ea address for default wep keys,
1553 driver needs it to be Null */
1554 if (!is_multicast_ether_addr(mac_addr))
1555 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1556 key.len = (u32) params->key_len;
1557 /* check for key index change */
1558 if (key.len == 0) {
1559 /* key delete */
1560 err = send_key_to_dongle(ndev, &key);
1561 if (err)
1562 return err;
1563 } else {
1564 if (key.len > sizeof(key.data)) {
1565 WL_ERR("Invalid key length (%d)\n", key.len);
1566 return -EINVAL;
1567 }
1568
1569 WL_CONN("Setting the key index %d\n", key.index);
1570 memcpy(key.data, params->key, key.len);
1571
1572 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1573 u8 keybuf[8];
1574 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1575 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1576 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1577 }
1578
1579 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1580 if (params->seq && params->seq_len == 6) {
1581 /* rx iv */
1582 u8 *ivptr;
1583 ivptr = (u8 *) params->seq;
1584 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1585 (ivptr[3] << 8) | ivptr[2];
1586 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1587 key.iv_initialized = true;
1588 }
1589
1590 switch (params->cipher) {
1591 case WLAN_CIPHER_SUITE_WEP40:
1592 key.algo = CRYPTO_ALGO_WEP1;
1593 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1594 break;
1595 case WLAN_CIPHER_SUITE_WEP104:
1596 key.algo = CRYPTO_ALGO_WEP128;
1597 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1598 break;
1599 case WLAN_CIPHER_SUITE_TKIP:
1600 key.algo = CRYPTO_ALGO_TKIP;
1601 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1602 break;
1603 case WLAN_CIPHER_SUITE_AES_CMAC:
1604 key.algo = CRYPTO_ALGO_AES_CCM;
1605 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1606 break;
1607 case WLAN_CIPHER_SUITE_CCMP:
1608 key.algo = CRYPTO_ALGO_AES_CCM;
1609 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1610 break;
1611 default:
1612 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1613 return -EINVAL;
1614 }
1615 convert_key_from_CPU(&key, &key_le);
1616
1617 brcmf_netdev_wait_pend8021x(ndev);
1618 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
1619 sizeof(key_le));
1620 if (err) {
1621 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1622 return err;
1623 }
1624 }
1625 return err;
1626}
1627
1628static s32
1629brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1630 u8 key_idx, bool pairwise, const u8 *mac_addr,
1631 struct key_params *params)
1632{
1633 struct brcmf_wsec_key key;
1634 s32 val;
1635 s32 wsec;
1636 s32 err = 0;
1637 u8 keybuf[8];
1638
1639 WL_TRACE("Enter\n");
1640 WL_CONN("key index (%d)\n", key_idx);
1641 if (!check_sys_up(wiphy))
1642 return -EIO;
1643
1644 if (mac_addr) {
1645 WL_TRACE("Exit");
1646 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1647 }
1648 memset(&key, 0, sizeof(key));
1649
1650 key.len = (u32) params->key_len;
1651 key.index = (u32) key_idx;
1652
1653 if (key.len > sizeof(key.data)) {
1654 WL_ERR("Too long key length (%u)\n", key.len);
1655 err = -EINVAL;
1656 goto done;
1657 }
1658 memcpy(key.data, params->key, key.len);
1659
1660 key.flags = BRCMF_PRIMARY_KEY;
1661 switch (params->cipher) {
1662 case WLAN_CIPHER_SUITE_WEP40:
1663 key.algo = CRYPTO_ALGO_WEP1;
1664 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1665 break;
1666 case WLAN_CIPHER_SUITE_WEP104:
1667 key.algo = CRYPTO_ALGO_WEP128;
1668 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1669 break;
1670 case WLAN_CIPHER_SUITE_TKIP:
1671 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1672 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1673 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1674 key.algo = CRYPTO_ALGO_TKIP;
1675 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1676 break;
1677 case WLAN_CIPHER_SUITE_AES_CMAC:
1678 key.algo = CRYPTO_ALGO_AES_CCM;
1679 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1680 break;
1681 case WLAN_CIPHER_SUITE_CCMP:
1682 key.algo = CRYPTO_ALGO_AES_CCM;
1683 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1684 break;
1685 default:
1686 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1687 err = -EINVAL;
1688 goto done;
1689 }
1690
1691 err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
1692 if (err)
1693 goto done;
1694
1695 val = WEP_ENABLED;
1696 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1697 if (err) {
1698 WL_ERR("get wsec error (%d)\n", err);
1699 goto done;
1700 }
1701 wsec &= ~(WEP_ENABLED);
1702 wsec |= val;
1703 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1704 if (err) {
1705 WL_ERR("set wsec error (%d)\n", err);
1706 goto done;
1707 }
1708
1709 val = 1; /* assume shared key. otherwise 0 */
1710 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1711 if (err)
1712 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1713done:
1714 WL_TRACE("Exit\n");
1715 return err;
1716}
1717
1718static s32
1719brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1720 u8 key_idx, bool pairwise, const u8 *mac_addr)
1721{
1722 struct brcmf_wsec_key key;
1723 s32 err = 0;
1724 s32 val;
1725 s32 wsec;
1726
1727 WL_TRACE("Enter\n");
1728 if (!check_sys_up(wiphy))
1729 return -EIO;
1730
1731 memset(&key, 0, sizeof(key));
1732
1733 key.index = (u32) key_idx;
1734 key.flags = BRCMF_PRIMARY_KEY;
1735 key.algo = CRYPTO_ALGO_OFF;
1736
1737 WL_CONN("key index (%d)\n", key_idx);
1738
1739 /* Set the new key/index */
1740 err = send_key_to_dongle(ndev, &key);
1741 if (err) {
1742 if (err == -EINVAL) {
1743 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1744 /* we ignore this key index in this case */
1745 WL_ERR("invalid key index (%d)\n", key_idx);
1746 }
1747 /* Ignore this error, may happen during DISASSOC */
1748 err = -EAGAIN;
1749 goto done;
1750 }
1751
1752 val = 0;
1753 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1754 if (err) {
1755 WL_ERR("get wsec error (%d)\n", err);
1756 /* Ignore this error, may happen during DISASSOC */
1757 err = -EAGAIN;
1758 goto done;
1759 }
1760 wsec &= ~(WEP_ENABLED);
1761 wsec |= val;
1762 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1763 if (err) {
1764 WL_ERR("set wsec error (%d)\n", err);
1765 /* Ignore this error, may happen during DISASSOC */
1766 err = -EAGAIN;
1767 goto done;
1768 }
1769
1770 val = 0; /* assume open key. otherwise 1 */
1771 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1772 if (err) {
1773 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1774 /* Ignore this error, may happen during DISASSOC */
1775 err = -EAGAIN;
1776 }
1777done:
1778 WL_TRACE("Exit\n");
1779 return err;
1780}
1781
1782static s32
1783brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1784 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1785 void (*callback) (void *cookie, struct key_params * params))
1786{
1787 struct key_params params;
1788 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1789 struct brcmf_cfg80211_security *sec;
1790 s32 wsec;
1791 s32 err = 0;
1792
1793 WL_TRACE("Enter\n");
1794 WL_CONN("key index (%d)\n", key_idx);
1795 if (!check_sys_up(wiphy))
1796 return -EIO;
1797
1798 memset(&params, 0, sizeof(params));
1799
1800 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1801 if (err) {
1802 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1803 /* Ignore this error, may happen during DISASSOC */
1804 err = -EAGAIN;
1805 goto done;
1806 }
1807 switch (wsec) {
1808 case WEP_ENABLED:
1809 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1810 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1811 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1812 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1813 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1814 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1815 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1816 }
1817 break;
1818 case TKIP_ENABLED:
1819 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1820 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1821 break;
1822 case AES_ENABLED:
1823 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1824 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1825 break;
1826 default:
1827 WL_ERR("Invalid algo (0x%x)\n", wsec);
1828 err = -EINVAL;
1829 goto done;
1830 }
1831 callback(cookie, &params);
1832
1833done:
1834 WL_TRACE("Exit\n");
1835 return err;
1836}
1837
1838static s32
1839brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1840 struct net_device *ndev, u8 key_idx)
1841{
1842 WL_INFO("Not supported\n");
1843
1844 return -EOPNOTSUPP;
1845}
1846
1847static s32
1848brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1849 u8 *mac, struct station_info *sinfo)
1850{
1851 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1852 struct brcmf_scb_val_le scb_val;
1853 int rssi;
1854 s32 rate;
1855 s32 err = 0;
1856 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1857
1858 WL_TRACE("Enter\n");
1859 if (!check_sys_up(wiphy))
1860 return -EIO;
1861
1862 if (memcmp(mac, bssid, ETH_ALEN)) {
1863 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1864 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1865 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1866 bssid[0], bssid[1], bssid[2], bssid[3],
1867 bssid[4], bssid[5]);
1868 err = -ENOENT;
1869 goto done;
1870 }
1871
1872 /* Report the current tx rate */
1873 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1874 if (err) {
1875 WL_ERR("Could not get rate (%d)\n", err);
1876 } else {
1877 sinfo->filled |= STATION_INFO_TX_BITRATE;
1878 sinfo->txrate.legacy = rate * 5;
1879 WL_CONN("Rate %d Mbps\n", rate / 2);
1880 }
1881
1882 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1883 scb_val.val = cpu_to_le32(0);
1884 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
1885 sizeof(struct brcmf_scb_val_le));
1886 if (err)
1887 WL_ERR("Could not get rssi (%d)\n", err);
1888
1889 rssi = le32_to_cpu(scb_val.val);
1890 sinfo->filled |= STATION_INFO_SIGNAL;
1891 sinfo->signal = rssi;
1892 WL_CONN("RSSI %d dBm\n", rssi);
1893 }
1894
1895done:
1896 WL_TRACE("Exit\n");
1897 return err;
1898}
1899
1900static s32
1901brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1902 bool enabled, s32 timeout)
1903{
1904 s32 pm;
1905 s32 err = 0;
1906 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1907
1908 WL_TRACE("Enter\n");
1909
1910 /*
1911 * Powersave enable/disable request is coming from the
1912 * cfg80211 even before the interface is up. In that
1913 * scenario, driver will be storing the power save
1914 * preference in cfg_priv struct to apply this to
1915 * FW later while initializing the dongle
1916 */
1917 cfg_priv->pwr_save = enabled;
1918 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
1919
1920 WL_INFO("Device is not ready,"
1921 "storing the value in cfg_priv struct\n");
1922 goto done;
1923 }
1924
1925 pm = enabled ? PM_FAST : PM_OFF;
1926 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1927
1928 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
1929 if (err) {
1930 if (err == -ENODEV)
1931 WL_ERR("net_device is not ready yet\n");
1932 else
1933 WL_ERR("error (%d)\n", err);
1934 }
1935done:
1936 WL_TRACE("Exit\n");
1937 return err;
1938}
1939
1940static s32
1941brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
1942 const u8 *addr,
1943 const struct cfg80211_bitrate_mask *mask)
1944{
1945 struct brcm_rateset_le rateset_le;
1946 s32 rate;
1947 s32 val;
1948 s32 err_bg;
1949 s32 err_a;
1950 u32 legacy;
1951 s32 err = 0;
1952
1953 WL_TRACE("Enter\n");
1954 if (!check_sys_up(wiphy))
1955 return -EIO;
1956
1957 /* addr param is always NULL. ignore it */
1958 /* Get current rateset */
1959 err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
1960 sizeof(rateset_le));
1961 if (err) {
1962 WL_ERR("could not get current rateset (%d)\n", err);
1963 goto done;
1964 }
1965
1966 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
1967 if (!legacy)
1968 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
1969 0xFFFF);
1970
1971 val = wl_g_rates[legacy - 1].bitrate * 100000;
1972
1973 if (val < le32_to_cpu(rateset_le.count))
1974 /* Select rate by rateset index */
1975 rate = rateset_le.rates[val] & 0x7f;
1976 else
1977 /* Specified rate in bps */
1978 rate = val / 500000;
1979
1980 WL_CONN("rate %d mbps\n", rate / 2);
1981
1982 /*
1983 *
1984 * Set rate override,
1985 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1986 */
1987 err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
1988 err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
1989 if (err_bg && err_a) {
1990 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
1991 err = err_bg | err_a;
1992 }
1993
1994done:
1995 WL_TRACE("Exit\n");
1996 return err;
1997}
1998
1999static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
2000 struct brcmf_bss_info *bi)
2001{
2002 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2003 struct ieee80211_channel *notify_channel;
2004 struct cfg80211_bss *bss;
2005 struct ieee80211_supported_band *band;
2006 s32 err = 0;
2007 u16 channel;
2008 u32 freq;
2009 u64 notify_timestamp;
2010 u16 notify_capability;
2011 u16 notify_interval;
2012 u8 *notify_ie;
2013 size_t notify_ielen;
2014 s32 notify_signal;
2015
2016 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2017 WL_ERR("Bss info is larger than buffer. Discarding\n");
2018 return 0;
2019 }
2020
2021 channel = bi->ctl_ch ? bi->ctl_ch :
2022 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2023
2024 if (channel <= CH_MAX_2G_CHANNEL)
2025 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2026 else
2027 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2028
2029 freq = ieee80211_channel_to_frequency(channel, band->band);
2030 notify_channel = ieee80211_get_channel(wiphy, freq);
2031
2032 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2033 notify_capability = le16_to_cpu(bi->capability);
2034 notify_interval = le16_to_cpu(bi->beacon_period);
2035 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2036 notify_ielen = le32_to_cpu(bi->ie_length);
2037 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2038
2039 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2040 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2041 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2042 WL_CONN("Channel: %d(%d)\n", channel, freq);
2043 WL_CONN("Capability: %X\n", notify_capability);
2044 WL_CONN("Beacon interval: %d\n", notify_interval);
2045 WL_CONN("Signal: %d\n", notify_signal);
2046 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2047
2048 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2049 notify_timestamp, notify_capability, notify_interval, notify_ie,
2050 notify_ielen, notify_signal, GFP_KERNEL);
2051
2052 if (!bss) {
2053 WL_ERR("cfg80211_inform_bss_frame error\n");
2054 return -EINVAL;
2055 }
2056
2057 return err;
2058}
2059
2060static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2061{
2062 struct brcmf_scan_results *bss_list;
2063 struct brcmf_bss_info *bi = NULL; /* must be initialized */
2064 s32 err = 0;
2065 int i;
2066
2067 bss_list = cfg_priv->bss_list;
2068 if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2069 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2070 bss_list->version);
2071 return -EOPNOTSUPP;
2072 }
2073 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2074 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2075 bi = next_bss(bss_list, bi);
2076 err = brcmf_inform_single_bss(cfg_priv, bi);
2077 if (err)
2078 break;
2079 }
2080 return err;
2081}
2082
2083static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2084 struct net_device *ndev, const u8 *bssid)
2085{
2086 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2087 struct ieee80211_channel *notify_channel;
2088 struct brcmf_bss_info *bi = NULL;
2089 struct ieee80211_supported_band *band;
2090 u8 *buf = NULL;
2091 s32 err = 0;
2092 u16 channel;
2093 u32 freq;
2094 u64 notify_timestamp;
2095 u16 notify_capability;
2096 u16 notify_interval;
2097 u8 *notify_ie;
2098 size_t notify_ielen;
2099 s32 notify_signal;
2100
2101 WL_TRACE("Enter\n");
2102
2103 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2104 if (buf == NULL) {
2105 err = -ENOMEM;
2106 goto CleanUp;
2107 }
2108
2109 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2110
2111 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2112 if (err) {
2113 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2114 goto CleanUp;
2115 }
2116
2117 bi = (struct brcmf_bss_info *)(buf + 4);
2118
2119 channel = bi->ctl_ch ? bi->ctl_ch :
2120 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2121
2122 if (channel <= CH_MAX_2G_CHANNEL)
2123 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2124 else
2125 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2126
2127 freq = ieee80211_channel_to_frequency(channel, band->band);
2128 notify_channel = ieee80211_get_channel(wiphy, freq);
2129
2130 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2131 notify_capability = le16_to_cpu(bi->capability);
2132 notify_interval = le16_to_cpu(bi->beacon_period);
2133 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2134 notify_ielen = le32_to_cpu(bi->ie_length);
2135 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2136
2137 WL_CONN("channel: %d(%d)\n", channel, freq);
2138 WL_CONN("capability: %X\n", notify_capability);
2139 WL_CONN("beacon interval: %d\n", notify_interval);
2140 WL_CONN("signal: %d\n", notify_signal);
2141 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2142
2143 cfg80211_inform_bss(wiphy, notify_channel, bssid,
2144 notify_timestamp, notify_capability, notify_interval,
2145 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2146
2147CleanUp:
2148
2149 kfree(buf);
2150
2151 WL_TRACE("Exit\n");
2152
2153 return err;
2154}
2155
2156static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
2157{
2158 return cfg_priv->conf->mode == WL_MODE_IBSS;
2159}
2160
2161/*
2162 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2163 * triples, returning a pointer to the substring whose first element
2164 * matches tag
2165 */
2166static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2167{
2168 struct brcmf_tlv *elt;
2169 int totlen;
2170
2171 elt = (struct brcmf_tlv *) buf;
2172 totlen = buflen;
2173
2174 /* find tagged parameter */
2175 while (totlen >= 2) {
2176 int len = elt->len;
2177
2178 /* validate remaining totlen */
2179 if ((elt->id == key) && (totlen >= (len + 2)))
2180 return elt;
2181
2182 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2));
2183 totlen -= (len + 2);
2184 }
2185
2186 return NULL;
2187}
2188
2189static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2190{
2191 struct brcmf_bss_info *bi;
2192 struct brcmf_ssid *ssid;
2193 struct brcmf_tlv *tim;
2194 u16 beacon_interval;
2195 u8 dtim_period;
2196 size_t ie_len;
2197 u8 *ie;
2198 s32 err = 0;
2199
2200 WL_TRACE("Enter\n");
2201 if (brcmf_is_ibssmode(cfg_priv))
2202 return err;
2203
2204 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2205
2206 *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2207 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2208 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2209 if (err) {
2210 WL_ERR("Could not get bss info %d\n", err);
2211 goto update_bss_info_out;
2212 }
2213
2214 bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4);
2215 err = brcmf_inform_single_bss(cfg_priv, bi);
2216 if (err)
2217 goto update_bss_info_out;
2218
2219 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2220 ie_len = le32_to_cpu(bi->ie_length);
2221 beacon_interval = le16_to_cpu(bi->beacon_period);
2222
2223 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2224 if (tim)
2225 dtim_period = tim->data[1];
2226 else {
2227 /*
2228 * active scan was done so we could not get dtim
2229 * information out of probe response.
2230 * so we speficially query dtim information to dongle.
2231 */
2232 u32 var;
2233 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2234 "dtim_assoc", &var);
2235 if (err) {
2236 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2237 goto update_bss_info_out;
2238 }
2239 dtim_period = (u8)var;
2240 }
2241
2242 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2243 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2244
2245update_bss_info_out:
2246 WL_TRACE("Exit");
2247 return err;
2248}
2249
2250static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2251{
2252 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2253 struct brcmf_ssid ssid;
2254
2255 if (cfg_priv->iscan_on) {
2256 iscan->state = WL_ISCAN_STATE_IDLE;
2257
2258 if (iscan->timer_on) {
2259 del_timer_sync(&iscan->timer);
2260 iscan->timer_on = 0;
2261 }
2262
2263 cancel_work_sync(&iscan->work);
2264
2265 /* Abort iscan running in FW */
2266 memset(&ssid, 0, sizeof(ssid));
2267 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2268 }
2269}
2270
2271static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2272 bool aborted)
2273{
2274 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2275 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2276
2277 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
2278 WL_ERR("Scan complete while device not scanning\n");
2279 return;
2280 }
2281 if (cfg_priv->scan_request) {
2282 WL_SCAN("ISCAN Completed scan: %s\n",
2283 aborted ? "Aborted" : "Done");
2284 cfg80211_scan_done(cfg_priv->scan_request, aborted);
2285 brcmf_set_mpc(ndev, 1);
2286 cfg_priv->scan_request = NULL;
2287 }
2288 cfg_priv->iscan_kickstart = false;
2289}
2290
2291static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2292{
2293 if (iscan->state != WL_ISCAN_STATE_IDLE) {
2294 WL_SCAN("wake up iscan\n");
2295 schedule_work(&iscan->work);
2296 return 0;
2297 }
2298
2299 return -EIO;
2300}
2301
2302static s32
2303brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2304 struct brcmf_scan_results **bss_list)
2305{
2306 struct brcmf_iscan_results list;
2307 struct brcmf_scan_results *results;
2308 struct brcmf_scan_results_le *results_le;
2309 struct brcmf_iscan_results *list_buf;
2310 s32 err = 0;
2311
2312 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2313 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2314 results = &list_buf->results;
2315 results_le = &list_buf->results_le;
2316 results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2317 results->version = 0;
2318 results->count = 0;
2319
2320 memset(&list, 0, sizeof(list));
2321 list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2322 err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2323 BRCMF_ISCAN_RESULTS_FIXED_SIZE,
2324 iscan->scan_buf, WL_ISCAN_BUF_MAX);
2325 if (err) {
2326 WL_ERR("error (%d)\n", err);
2327 return err;
2328 }
2329 results->buflen = le32_to_cpu(results_le->buflen);
2330 results->version = le32_to_cpu(results_le->version);
2331 results->count = le32_to_cpu(results_le->count);
2332 WL_SCAN("results->count = %d\n", results_le->count);
2333 WL_SCAN("results->buflen = %d\n", results_le->buflen);
2334 *status = le32_to_cpu(list_buf->status_le);
2335 WL_SCAN("status = %d\n", *status);
2336 *bss_list = results;
2337
2338 return err;
2339}
2340
2341static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2342{
2343 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2344 s32 err = 0;
2345
2346 iscan->state = WL_ISCAN_STATE_IDLE;
2347 brcmf_inform_bss(cfg_priv);
2348 brcmf_notify_iscan_complete(iscan, false);
2349
2350 return err;
2351}
2352
2353static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2354{
2355 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2356 s32 err = 0;
2357
2358 /* Reschedule the timer */
2359 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2360 iscan->timer_on = 1;
2361
2362 return err;
2363}
2364
2365static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2366{
2367 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2368 s32 err = 0;
2369
2370 brcmf_inform_bss(cfg_priv);
2371 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2372 /* Reschedule the timer */
2373 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2374 iscan->timer_on = 1;
2375
2376 return err;
2377}
2378
2379static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2380{
2381 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2382 s32 err = 0;
2383
2384 iscan->state = WL_ISCAN_STATE_IDLE;
2385 brcmf_notify_iscan_complete(iscan, true);
2386
2387 return err;
2388}
2389
2390static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2391{
2392 struct brcmf_cfg80211_iscan_ctrl *iscan =
2393 container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2394 work);
2395 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2396 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2397 u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2398
2399 if (iscan->timer_on) {
2400 del_timer_sync(&iscan->timer);
2401 iscan->timer_on = 0;
2402 }
2403
2404 if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2405 status = BRCMF_SCAN_RESULTS_ABORTED;
2406 WL_ERR("Abort iscan\n");
2407 }
2408
2409 el->handler[status](cfg_priv);
2410}
2411
2412static void brcmf_iscan_timer(unsigned long data)
2413{
2414 struct brcmf_cfg80211_iscan_ctrl *iscan =
2415 (struct brcmf_cfg80211_iscan_ctrl *)data;
2416
2417 if (iscan) {
2418 iscan->timer_on = 0;
2419 WL_SCAN("timer expired\n");
2420 brcmf_wakeup_iscan(iscan);
2421 }
2422}
2423
2424static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2425{
2426 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2427
2428 if (cfg_priv->iscan_on) {
2429 iscan->state = WL_ISCAN_STATE_IDLE;
2430 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2431 }
2432
2433 return 0;
2434}
2435
2436static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2437{
2438 memset(el, 0, sizeof(*el));
2439 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2440 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2441 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2442 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2443 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2444}
2445
2446static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2447{
2448 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2449 int err = 0;
2450
2451 if (cfg_priv->iscan_on) {
2452 iscan->ndev = cfg_to_ndev(cfg_priv);
2453 brcmf_init_iscan_eloop(&iscan->el);
2454 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2455 init_timer(&iscan->timer);
2456 iscan->timer.data = (unsigned long) iscan;
2457 iscan->timer.function = brcmf_iscan_timer;
2458 err = brcmf_invoke_iscan(cfg_priv);
2459 if (!err)
2460 iscan->data = cfg_priv;
2461 }
2462
2463 return err;
2464}
2465
2466static void brcmf_delay(u32 ms)
2467{
2468 if (ms < 1000 / HZ) {
2469 cond_resched();
2470 mdelay(ms);
2471 } else {
2472 msleep(ms);
2473 }
2474}
2475
2476static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2477{
2478 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2479
2480 /*
2481 * Check for WL_STATUS_READY before any function call which
2482 * could result is bus access. Don't block the resume for
2483 * any driver error conditions
2484 */
2485 WL_TRACE("Enter\n");
2486
2487 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2488 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2489
2490 WL_TRACE("Exit\n");
2491 return 0;
2492}
2493
2494static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2495 struct cfg80211_wowlan *wow)
2496{
2497 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2498 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2499
2500 WL_TRACE("Enter\n");
2501
2502 /*
2503 * Check for WL_STATUS_READY before any function call which
2504 * could result is bus access. Don't block the suspend for
2505 * any driver error conditions
2506 */
2507
2508 /*
2509 * While going to suspend if associated with AP disassociate
2510 * from AP to save power while system is in suspended state
2511 */
2512 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2513 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2514 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2515 WL_INFO("Disassociating from AP"
2516 " while entering suspend state\n");
2517 brcmf_link_down(cfg_priv);
2518
2519 /*
2520 * Make sure WPA_Supplicant receives all the event
2521 * generated due to DISASSOC call to the fw to keep
2522 * the state fw and WPA_Supplicant state consistent
2523 */
2524 brcmf_delay(500);
2525 }
2526
2527 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2528 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2529 brcmf_term_iscan(cfg_priv);
2530
2531 if (cfg_priv->scan_request) {
2532 /* Indidate scan abort to cfg80211 layer */
2533 WL_INFO("Terminating scan in progress\n");
2534 cfg80211_scan_done(cfg_priv->scan_request, true);
2535 cfg_priv->scan_request = NULL;
2536 }
2537 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2538 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2539
2540 /* Turn off watchdog timer */
2541 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2542 WL_INFO("Enable MPC\n");
2543 brcmf_set_mpc(ndev, 1);
2544 }
2545
2546 WL_TRACE("Exit\n");
2547
2548 return 0;
2549}
2550
2551static __used s32
2552brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
2553{
2554 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2555 u32 buflen;
2556
2557 buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
2558 WL_DCMD_LEN_MAX);
2559 BUG_ON(!buflen);
2560
2561 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
2562 buflen);
2563}
2564
2565static s32
2566brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
2567 s32 buf_len)
2568{
2569 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2570 u32 len;
2571 s32 err = 0;
2572
2573 len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
2574 WL_DCMD_LEN_MAX);
2575 BUG_ON(!len);
2576 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
2577 WL_DCMD_LEN_MAX);
2578 if (err) {
2579 WL_ERR("error (%d)\n", err);
2580 return err;
2581 }
2582 memcpy(buf, cfg_priv->dcmd_buf, buf_len);
2583
2584 return err;
2585}
2586
2587static __used s32
2588brcmf_update_pmklist(struct net_device *ndev,
2589 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2590{
2591 int i, j;
2592 int pmkid_len;
2593
2594 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2595
2596 WL_CONN("No of elements %d\n", pmkid_len);
2597 for (i = 0; i < pmkid_len; i++) {
2598 WL_CONN("PMKID[%d]: %pM =\n", i,
2599 &pmk_list->pmkids.pmkid[i].BSSID);
2600 for (j = 0; j < WLAN_PMKID_LEN; j++)
2601 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2602 }
2603
2604 if (!err)
2605 brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
2606 sizeof(*pmk_list));
2607
2608 return err;
2609}
2610
2611static s32
2612brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2613 struct cfg80211_pmksa *pmksa)
2614{
2615 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2616 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2617 s32 err = 0;
2618 int i;
2619 int pmkid_len;
2620
2621 WL_TRACE("Enter\n");
2622 if (!check_sys_up(wiphy))
2623 return -EIO;
2624
2625 pmkid_len = le32_to_cpu(pmkids->npmkid);
2626 for (i = 0; i < pmkid_len; i++)
2627 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2628 break;
2629 if (i < WL_NUM_PMKIDS_MAX) {
2630 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2631 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2632 if (i == pmkid_len) {
2633 pmkid_len++;
2634 pmkids->npmkid = cpu_to_le32(pmkid_len);
2635 }
2636 } else
2637 err = -EINVAL;
2638
2639 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2640 pmkids->pmkid[pmkid_len].BSSID);
2641 for (i = 0; i < WLAN_PMKID_LEN; i++)
2642 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2643
2644 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2645
2646 WL_TRACE("Exit\n");
2647 return err;
2648}
2649
2650static s32
2651brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2652 struct cfg80211_pmksa *pmksa)
2653{
2654 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2655 struct pmkid_list pmkid;
2656 s32 err = 0;
2657 int i, pmkid_len;
2658
2659 WL_TRACE("Enter\n");
2660 if (!check_sys_up(wiphy))
2661 return -EIO;
2662
2663 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2664 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2665
2666 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2667 &pmkid.pmkid[0].BSSID);
2668 for (i = 0; i < WLAN_PMKID_LEN; i++)
2669 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2670
2671 pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
2672 for (i = 0; i < pmkid_len; i++)
2673 if (!memcmp
2674 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2675 ETH_ALEN))
2676 break;
2677
2678 if ((pmkid_len > 0)
2679 && (i < pmkid_len)) {
2680 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2681 sizeof(struct pmkid));
2682 for (; i < (pmkid_len - 1); i++) {
2683 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2684 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2685 ETH_ALEN);
2686 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2687 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2688 WLAN_PMKID_LEN);
2689 }
2690 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2691 } else
2692 err = -EINVAL;
2693
2694 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2695
2696 WL_TRACE("Exit\n");
2697 return err;
2698
2699}
2700
2701static s32
2702brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2703{
2704 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2705 s32 err = 0;
2706
2707 WL_TRACE("Enter\n");
2708 if (!check_sys_up(wiphy))
2709 return -EIO;
2710
2711 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2712 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2713
2714 WL_TRACE("Exit\n");
2715 return err;
2716
2717}
2718
2719static struct cfg80211_ops wl_cfg80211_ops = {
2720 .change_virtual_intf = brcmf_cfg80211_change_iface,
2721 .scan = brcmf_cfg80211_scan,
2722 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2723 .join_ibss = brcmf_cfg80211_join_ibss,
2724 .leave_ibss = brcmf_cfg80211_leave_ibss,
2725 .get_station = brcmf_cfg80211_get_station,
2726 .set_tx_power = brcmf_cfg80211_set_tx_power,
2727 .get_tx_power = brcmf_cfg80211_get_tx_power,
2728 .add_key = brcmf_cfg80211_add_key,
2729 .del_key = brcmf_cfg80211_del_key,
2730 .get_key = brcmf_cfg80211_get_key,
2731 .set_default_key = brcmf_cfg80211_config_default_key,
2732 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2733 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2734 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2735 .connect = brcmf_cfg80211_connect,
2736 .disconnect = brcmf_cfg80211_disconnect,
2737 .suspend = brcmf_cfg80211_suspend,
2738 .resume = brcmf_cfg80211_resume,
2739 .set_pmksa = brcmf_cfg80211_set_pmksa,
2740 .del_pmksa = brcmf_cfg80211_del_pmksa,
2741 .flush_pmksa = brcmf_cfg80211_flush_pmksa
2742};
2743
2744static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2745{
2746 s32 err = 0;
2747
2748 switch (mode) {
2749 case WL_MODE_BSS:
2750 return NL80211_IFTYPE_STATION;
2751 case WL_MODE_IBSS:
2752 return NL80211_IFTYPE_ADHOC;
2753 default:
2754 return NL80211_IFTYPE_UNSPECIFIED;
2755 }
2756
2757 return err;
2758}
2759
2760static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2761 struct device *ndev)
2762{
2763 struct wireless_dev *wdev;
2764 s32 err = 0;
2765
2766 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2767 if (!wdev)
2768 return ERR_PTR(-ENOMEM);
2769
2770 wdev->wiphy =
2771 wiphy_new(&wl_cfg80211_ops,
2772 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2773 if (!wdev->wiphy) {
2774 WL_ERR("Couldn not allocate wiphy device\n");
2775 err = -ENOMEM;
2776 goto wiphy_new_out;
2777 }
2778 set_wiphy_dev(wdev->wiphy, ndev);
2779 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2780 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2781 wdev->wiphy->interface_modes =
2782 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2783 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2784 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2785 * it as 11a by default.
2786 * This will be updated with
2787 * 11n phy tables in
2788 * "ifconfig up"
2789 * if phy has 11n capability
2790 */
2791 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2792 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2793 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2794 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2795 * save mode
2796 * by default
2797 */
2798 err = wiphy_register(wdev->wiphy);
2799 if (err < 0) {
2800 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2801 goto wiphy_register_out;
2802 }
2803 return wdev;
2804
2805wiphy_register_out:
2806 wiphy_free(wdev->wiphy);
2807
2808wiphy_new_out:
2809 kfree(wdev);
2810
2811 return ERR_PTR(err);
2812}
2813
2814static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2815{
2816 struct wireless_dev *wdev = cfg_priv->wdev;
2817
2818 if (!wdev) {
2819 WL_ERR("wdev is invalid\n");
2820 return;
2821 }
2822 wiphy_unregister(wdev->wiphy);
2823 wiphy_free(wdev->wiphy);
2824 kfree(wdev);
2825 cfg_priv->wdev = NULL;
2826}
2827
2828static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2829 const struct brcmf_event_msg *e)
2830{
2831 u32 event = be32_to_cpu(e->event_type);
2832 u32 status = be32_to_cpu(e->status);
2833
2834 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2835 WL_CONN("Processing set ssid\n");
2836 cfg_priv->link_up = true;
2837 return true;
2838 }
2839
2840 return false;
2841}
2842
2843static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2844 const struct brcmf_event_msg *e)
2845{
2846 u32 event = be32_to_cpu(e->event_type);
2847 u16 flags = be16_to_cpu(e->flags);
2848
2849 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2850 WL_CONN("Processing link down\n");
2851 return true;
2852 }
2853 return false;
2854}
2855
2856static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2857 const struct brcmf_event_msg *e)
2858{
2859 u32 event = be32_to_cpu(e->event_type);
2860 u32 status = be32_to_cpu(e->status);
2861
2862 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2863 WL_CONN("Processing Link %s & no network found\n",
2864 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2865 "up" : "down");
2866 return true;
2867 }
2868
2869 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2870 WL_CONN("Processing connecting & no network found\n");
2871 return true;
2872 }
2873
2874 return false;
2875}
2876
2877static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2878{
2879 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2880
2881 kfree(conn_info->req_ie);
2882 conn_info->req_ie = NULL;
2883 conn_info->req_ie_len = 0;
2884 kfree(conn_info->resp_ie);
2885 conn_info->resp_ie = NULL;
2886 conn_info->resp_ie_len = 0;
2887}
2888
2889static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2890{
2891 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2892 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
2893 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2894 u32 req_len;
2895 u32 resp_len;
2896 s32 err = 0;
2897
2898 brcmf_clear_assoc_ies(cfg_priv);
2899
2900 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2901 WL_ASSOC_INFO_MAX);
2902 if (err) {
2903 WL_ERR("could not get assoc info (%d)\n", err);
2904 return err;
2905 }
2906 assoc_info =
2907 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
2908 req_len = le32_to_cpu(assoc_info->req_len);
2909 resp_len = le32_to_cpu(assoc_info->resp_len);
2910 if (req_len) {
2911 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2912 cfg_priv->extra_buf,
2913 WL_ASSOC_INFO_MAX);
2914 if (err) {
2915 WL_ERR("could not get assoc req (%d)\n", err);
2916 return err;
2917 }
2918 conn_info->req_ie_len = req_len;
2919 conn_info->req_ie =
2920 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2921 GFP_KERNEL);
2922 } else {
2923 conn_info->req_ie_len = 0;
2924 conn_info->req_ie = NULL;
2925 }
2926 if (resp_len) {
2927 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2928 cfg_priv->extra_buf,
2929 WL_ASSOC_INFO_MAX);
2930 if (err) {
2931 WL_ERR("could not get assoc resp (%d)\n", err);
2932 return err;
2933 }
2934 conn_info->resp_ie_len = resp_len;
2935 conn_info->resp_ie =
2936 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2937 GFP_KERNEL);
2938 } else {
2939 conn_info->resp_ie_len = 0;
2940 conn_info->resp_ie = NULL;
2941 }
2942 WL_CONN("req len (%d) resp len (%d)\n",
2943 conn_info->req_ie_len, conn_info->resp_ie_len);
2944
2945 return err;
2946}
2947
2948static s32
2949brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2950 struct net_device *ndev,
2951 const struct brcmf_event_msg *e)
2952{
2953 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2954 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2955 struct brcmf_channel_info_le channel_le;
2956 struct ieee80211_channel *notify_channel;
2957 struct ieee80211_supported_band *band;
2958 u32 freq;
2959 s32 err = 0;
2960 u32 target_channel;
2961
2962 WL_TRACE("Enter\n");
2963
2964 brcmf_get_assoc_ies(cfg_priv);
2965 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2966 brcmf_update_bss_info(cfg_priv);
2967
2968 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2969 sizeof(channel_le));
2970
2971 target_channel = le32_to_cpu(channel_le.target_channel);
2972 WL_CONN("Roamed to channel %d\n", target_channel);
2973
2974 if (target_channel <= CH_MAX_2G_CHANNEL)
2975 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2976 else
2977 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2978
2979 freq = ieee80211_channel_to_frequency(target_channel, band->band);
2980 notify_channel = ieee80211_get_channel(wiphy, freq);
2981
2982 cfg80211_roamed(ndev, notify_channel,
2983 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2984 conn_info->req_ie, conn_info->req_ie_len,
2985 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2986 WL_CONN("Report roaming result\n");
2987
2988 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2989 WL_TRACE("Exit\n");
2990 return err;
2991}
2992
2993static s32
2994brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
2995 struct net_device *ndev, const struct brcmf_event_msg *e,
2996 bool completed)
2997{
2998 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2999 s32 err = 0;
3000
3001 WL_TRACE("Enter\n");
3002
3003 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
3004 if (completed) {
3005 brcmf_get_assoc_ies(cfg_priv);
3006 brcmf_update_prof(cfg_priv, NULL, &e->addr,
3007 WL_PROF_BSSID);
3008 brcmf_update_bss_info(cfg_priv);
3009 }
3010 cfg80211_connect_result(ndev,
3011 (u8 *)brcmf_read_prof(cfg_priv,
3012 WL_PROF_BSSID),
3013 conn_info->req_ie,
3014 conn_info->req_ie_len,
3015 conn_info->resp_ie,
3016 conn_info->resp_ie_len,
3017 completed ? WLAN_STATUS_SUCCESS :
3018 WLAN_STATUS_AUTH_TIMEOUT,
3019 GFP_KERNEL);
3020 if (completed)
3021 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3022 WL_CONN("Report connect result - connection %s\n",
3023 completed ? "succeeded" : "failed");
3024 }
3025 WL_TRACE("Exit\n");
3026 return err;
3027}
3028
3029static s32
3030brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
3031 struct net_device *ndev,
3032 const struct brcmf_event_msg *e, void *data)
3033{
3034 s32 err = 0;
3035
3036 if (brcmf_is_linkup(cfg_priv, e)) {
3037 WL_CONN("Linkup\n");
3038 if (brcmf_is_ibssmode(cfg_priv)) {
3039 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
3040 WL_PROF_BSSID);
3041 wl_inform_ibss(cfg_priv, ndev, e->addr);
3042 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3043 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3044 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3045 } else
3046 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3047 } else if (brcmf_is_linkdown(cfg_priv, e)) {
3048 WL_CONN("Linkdown\n");
3049 if (brcmf_is_ibssmode(cfg_priv)) {
3050 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3051 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3052 &cfg_priv->status))
3053 brcmf_link_down(cfg_priv);
3054 } else {
3055 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3056 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3057 &cfg_priv->status)) {
3058 cfg80211_disconnected(ndev, 0, NULL, 0,
3059 GFP_KERNEL);
3060 brcmf_link_down(cfg_priv);
3061 }
3062 }
3063 brcmf_init_prof(cfg_priv->profile);
3064 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
3065 if (brcmf_is_ibssmode(cfg_priv))
3066 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3067 else
3068 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3069 }
3070
3071 return err;
3072}
3073
3074static s32
3075brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3076 struct net_device *ndev,
3077 const struct brcmf_event_msg *e, void *data)
3078{
3079 s32 err = 0;
3080 u32 event = be32_to_cpu(e->event_type);
3081 u32 status = be32_to_cpu(e->status);
3082
3083 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3084 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
3085 brcmf_bss_roaming_done(cfg_priv, ndev, e);
3086 else
3087 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3088 }
3089
3090 return err;
3091}
3092
3093static s32
3094brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3095 struct net_device *ndev,
3096 const struct brcmf_event_msg *e, void *data)
3097{
3098 u16 flags = be16_to_cpu(e->flags);
3099 enum nl80211_key_type key_type;
3100
3101 if (flags & BRCMF_EVENT_MSG_GROUP)
3102 key_type = NL80211_KEYTYPE_GROUP;
3103 else
3104 key_type = NL80211_KEYTYPE_PAIRWISE;
3105
3106 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
3107 NULL, GFP_KERNEL);
3108
3109 return 0;
3110}
3111
3112static s32
3113brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3114 struct net_device *ndev,
3115 const struct brcmf_event_msg *e, void *data)
3116{
3117 struct brcmf_channel_info_le channel_inform_le;
3118 struct brcmf_scan_results_le *bss_list_le;
3119 u32 len = WL_SCAN_BUF_MAX;
3120 s32 err = 0;
3121 bool scan_abort = false;
3122 u32 scan_channel;
3123
3124 WL_TRACE("Enter\n");
3125
3126 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3127 WL_TRACE("Exit\n");
3128 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3129 }
3130
3131 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3132 WL_ERR("Scan complete while device not scanning\n");
3133 scan_abort = true;
3134 err = -EINVAL;
3135 goto scan_done_out;
3136 }
3137
3138 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3139 sizeof(channel_inform_le));
3140 if (err) {
3141 WL_ERR("scan busy (%d)\n", err);
3142 scan_abort = true;
3143 goto scan_done_out;
3144 }
3145 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3146 if (scan_channel)
3147 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3148 cfg_priv->bss_list = cfg_priv->scan_results;
3149 bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3150
3151 memset(cfg_priv->scan_results, 0, len);
3152 bss_list_le->buflen = cpu_to_le32(len);
3153 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3154 cfg_priv->scan_results, len);
3155 if (err) {
3156 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3157 err = -EINVAL;
3158 scan_abort = true;
3159 goto scan_done_out;
3160 }
3161 cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3162 cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3163 cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3164
3165 err = brcmf_inform_bss(cfg_priv);
3166 if (err) {
3167 scan_abort = true;
3168 goto scan_done_out;
3169 }
3170
3171scan_done_out:
3172 if (cfg_priv->scan_request) {
3173 WL_SCAN("calling cfg80211_scan_done\n");
3174 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3175 brcmf_set_mpc(ndev, 1);
3176 cfg_priv->scan_request = NULL;
3177 }
3178
3179 WL_TRACE("Exit\n");
3180
3181 return err;
3182}
3183
3184static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3185{
3186 conf->mode = (u32)-1;
3187 conf->frag_threshold = (u32)-1;
3188 conf->rts_threshold = (u32)-1;
3189 conf->retry_short = (u32)-1;
3190 conf->retry_long = (u32)-1;
3191 conf->tx_power = -1;
3192}
3193
3194static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3195{
3196 memset(el, 0, sizeof(*el));
3197 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3198 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3199 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3200 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3201 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3202}
3203
3204static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3205{
3206 kfree(cfg_priv->scan_results);
3207 cfg_priv->scan_results = NULL;
3208 kfree(cfg_priv->bss_info);
3209 cfg_priv->bss_info = NULL;
3210 kfree(cfg_priv->conf);
3211 cfg_priv->conf = NULL;
3212 kfree(cfg_priv->profile);
3213 cfg_priv->profile = NULL;
3214 kfree(cfg_priv->scan_req_int);
3215 cfg_priv->scan_req_int = NULL;
3216 kfree(cfg_priv->dcmd_buf);
3217 cfg_priv->dcmd_buf = NULL;
3218 kfree(cfg_priv->extra_buf);
3219 cfg_priv->extra_buf = NULL;
3220 kfree(cfg_priv->iscan);
3221 cfg_priv->iscan = NULL;
3222 kfree(cfg_priv->pmk_list);
3223 cfg_priv->pmk_list = NULL;
3224}
3225
3226static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3227{
3228 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3229 if (!cfg_priv->scan_results)
3230 goto init_priv_mem_out;
3231 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3232 if (!cfg_priv->conf)
3233 goto init_priv_mem_out;
3234 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3235 if (!cfg_priv->profile)
3236 goto init_priv_mem_out;
3237 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3238 if (!cfg_priv->bss_info)
3239 goto init_priv_mem_out;
3240 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3241 GFP_KERNEL);
3242 if (!cfg_priv->scan_req_int)
3243 goto init_priv_mem_out;
3244 cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3245 if (!cfg_priv->dcmd_buf)
3246 goto init_priv_mem_out;
3247 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3248 if (!cfg_priv->extra_buf)
3249 goto init_priv_mem_out;
3250 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3251 if (!cfg_priv->iscan)
3252 goto init_priv_mem_out;
3253 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3254 if (!cfg_priv->pmk_list)
3255 goto init_priv_mem_out;
3256
3257 return 0;
3258
3259init_priv_mem_out:
3260 brcmf_deinit_priv_mem(cfg_priv);
3261
3262 return -ENOMEM;
3263}
3264
3265/*
3266* retrieve first queued event from head
3267*/
3268
3269static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3270 struct brcmf_cfg80211_priv *cfg_priv)
3271{
3272 struct brcmf_cfg80211_event_q *e = NULL;
3273
3274 spin_lock_irq(&cfg_priv->evt_q_lock);
3275 if (!list_empty(&cfg_priv->evt_q_list)) {
3276 e = list_first_entry(&cfg_priv->evt_q_list,
3277 struct brcmf_cfg80211_event_q, evt_q_list);
3278 list_del(&e->evt_q_list);
3279 }
3280 spin_unlock_irq(&cfg_priv->evt_q_lock);
3281
3282 return e;
3283}
3284
3285/*
3286** push event to tail of the queue
3287*/
3288
3289static s32
3290brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3291 const struct brcmf_event_msg *msg)
3292{
3293 struct brcmf_cfg80211_event_q *e;
3294 s32 err = 0;
3295
3296 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3297 if (!e)
3298 return -ENOMEM;
3299
3300 e->etype = event;
3301 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3302
3303 spin_lock_irq(&cfg_priv->evt_q_lock);
3304 list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3305 spin_unlock_irq(&cfg_priv->evt_q_lock);
3306
3307 return err;
3308}
3309
3310static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3311{
3312 kfree(e);
3313}
3314
3315static void brcmf_cfg80211_event_handler(struct work_struct *work)
3316{
3317 struct brcmf_cfg80211_priv *cfg_priv =
3318 container_of(work, struct brcmf_cfg80211_priv,
3319 event_work);
3320 struct brcmf_cfg80211_event_q *e;
3321
3322 e = brcmf_deq_event(cfg_priv);
3323 if (unlikely(!e)) {
3324 WL_ERR("event queue empty...\n");
3325 return;
3326 }
3327
3328 do {
3329 WL_INFO("event type (%d)\n", e->etype);
3330 if (cfg_priv->el.handler[e->etype])
3331 cfg_priv->el.handler[e->etype](cfg_priv,
3332 cfg_to_ndev(cfg_priv),
3333 &e->emsg, e->edata);
3334 else
3335 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3336 brcmf_put_event(e);
3337 } while ((e = brcmf_deq_event(cfg_priv)));
3338
3339}
3340
3341static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3342{
3343 spin_lock_init(&cfg_priv->evt_q_lock);
3344 INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3345}
3346
3347static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3348{
3349 struct brcmf_cfg80211_event_q *e;
3350
3351 spin_lock_irq(&cfg_priv->evt_q_lock);
3352 while (!list_empty(&cfg_priv->evt_q_list)) {
3353 e = list_first_entry(&cfg_priv->evt_q_list,
3354 struct brcmf_cfg80211_event_q, evt_q_list);
3355 list_del(&e->evt_q_list);
3356 kfree(e);
3357 }
3358 spin_unlock_irq(&cfg_priv->evt_q_lock);
3359}
3360
3361static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3362{
3363 s32 err = 0;
3364
3365 cfg_priv->scan_request = NULL;
3366 cfg_priv->pwr_save = true;
3367 cfg_priv->iscan_on = true; /* iscan on & off switch.
3368 we enable iscan per default */
3369 cfg_priv->roam_on = true; /* roam on & off switch.
3370 we enable roam per default */
3371
3372 cfg_priv->iscan_kickstart = false;
3373 cfg_priv->active_scan = true; /* we do active scan for
3374 specific scan per default */
3375 cfg_priv->dongle_up = false; /* dongle is not up yet */
3376 brcmf_init_eq(cfg_priv);
3377 err = brcmf_init_priv_mem(cfg_priv);
3378 if (err)
3379 return err;
3380 INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3381 brcmf_init_eloop_handler(&cfg_priv->el);
3382 mutex_init(&cfg_priv->usr_sync);
3383 err = brcmf_init_iscan(cfg_priv);
3384 if (err)
3385 return err;
3386 brcmf_init_conf(cfg_priv->conf);
3387 brcmf_init_prof(cfg_priv->profile);
3388 brcmf_link_down(cfg_priv);
3389
3390 return err;
3391}
3392
3393static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3394{
3395 cancel_work_sync(&cfg_priv->event_work);
3396 cfg_priv->dongle_up = false; /* dongle down */
3397 brcmf_flush_eq(cfg_priv);
3398 brcmf_link_down(cfg_priv);
3399 brcmf_term_iscan(cfg_priv);
3400 brcmf_deinit_priv_mem(cfg_priv);
3401}
3402
3403struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3404 struct device *busdev,
3405 void *data)
3406{
3407 struct wireless_dev *wdev;
3408 struct brcmf_cfg80211_priv *cfg_priv;
3409 struct brcmf_cfg80211_iface *ci;
3410 struct brcmf_cfg80211_dev *cfg_dev;
3411 s32 err = 0;
3412
3413 if (!ndev) {
3414 WL_ERR("ndev is invalid\n");
3415 return NULL;
3416 }
3417 cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3418 if (!cfg_dev)
3419 return NULL;
3420
3421 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3422 if (IS_ERR(wdev)) {
3423 kfree(cfg_dev);
3424 return NULL;
3425 }
3426
3427 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3428 cfg_priv = wdev_to_cfg(wdev);
3429 cfg_priv->wdev = wdev;
3430 cfg_priv->pub = data;
3431 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3432 ci->cfg_priv = cfg_priv;
3433 ndev->ieee80211_ptr = wdev;
3434 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3435 wdev->netdev = ndev;
3436 err = wl_init_priv(cfg_priv);
3437 if (err) {
3438 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3439 goto cfg80211_attach_out;
3440 }
3441 brcmf_set_drvdata(cfg_dev, ci);
3442
3443 return cfg_dev;
3444
3445cfg80211_attach_out:
3446 brcmf_free_wdev(cfg_priv);
3447 kfree(cfg_dev);
3448 return NULL;
3449}
3450
3451void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3452{
3453 struct brcmf_cfg80211_priv *cfg_priv;
3454
3455 cfg_priv = brcmf_priv_get(cfg_dev);
3456
3457 wl_deinit_priv(cfg_priv);
3458 brcmf_free_wdev(cfg_priv);
3459 brcmf_set_drvdata(cfg_dev, NULL);
3460 kfree(cfg_dev);
3461}
3462
3463void
3464brcmf_cfg80211_event(struct net_device *ndev,
3465 const struct brcmf_event_msg *e, void *data)
3466{
3467 u32 event_type = be32_to_cpu(e->event_type);
3468 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3469
3470 if (!brcmf_enq_event(cfg_priv, event_type, e))
3471 schedule_work(&cfg_priv->event_work);
3472}
3473
3474static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3475{
3476 s32 infra = 0;
3477 s32 err = 0;
3478
3479 switch (iftype) {
3480 case NL80211_IFTYPE_MONITOR:
3481 case NL80211_IFTYPE_WDS:
3482 WL_ERR("type (%d) : currently we do not support this mode\n",
3483 iftype);
3484 err = -EINVAL;
3485 return err;
3486 case NL80211_IFTYPE_ADHOC:
3487 infra = 0;
3488 break;
3489 case NL80211_IFTYPE_STATION:
3490 infra = 1;
3491 break;
3492 default:
3493 err = -EINVAL;
3494 WL_ERR("invalid type (%d)\n", iftype);
3495 return err;
3496 }
3497 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3498 if (err) {
3499 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3500 return err;
3501 }
3502
3503 return 0;
3504}
3505
3506static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3507{
3508 /* Room for "event_msgs" + '\0' + bitvec */
3509 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3510 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3511 s32 err = 0;
3512
3513 WL_TRACE("Enter\n");
3514
3515 /* Setup event_msgs */
3516 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3517 iovbuf, sizeof(iovbuf));
3518 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3519 if (err) {
3520 WL_ERR("Get event_msgs error (%d)\n", err);
3521 goto dongle_eventmsg_out;
3522 }
3523 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3524
3525 setbit(eventmask, BRCMF_E_SET_SSID);
3526 setbit(eventmask, BRCMF_E_ROAM);
3527 setbit(eventmask, BRCMF_E_PRUNE);
3528 setbit(eventmask, BRCMF_E_AUTH);
3529 setbit(eventmask, BRCMF_E_REASSOC);
3530 setbit(eventmask, BRCMF_E_REASSOC_IND);
3531 setbit(eventmask, BRCMF_E_DEAUTH_IND);
3532 setbit(eventmask, BRCMF_E_DISASSOC_IND);
3533 setbit(eventmask, BRCMF_E_DISASSOC);
3534 setbit(eventmask, BRCMF_E_JOIN);
3535 setbit(eventmask, BRCMF_E_ASSOC_IND);
3536 setbit(eventmask, BRCMF_E_PSK_SUP);
3537 setbit(eventmask, BRCMF_E_LINK);
3538 setbit(eventmask, BRCMF_E_NDIS_LINK);
3539 setbit(eventmask, BRCMF_E_MIC_ERROR);
3540 setbit(eventmask, BRCMF_E_PMKID_CACHE);
3541 setbit(eventmask, BRCMF_E_TXFAIL);
3542 setbit(eventmask, BRCMF_E_JOIN_START);
3543 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3544
3545 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3546 iovbuf, sizeof(iovbuf));
3547 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3548 if (err) {
3549 WL_ERR("Set event_msgs error (%d)\n", err);
3550 goto dongle_eventmsg_out;
3551 }
3552
3553dongle_eventmsg_out:
3554 WL_TRACE("Exit\n");
3555 return err;
3556}
3557
3558static s32
3559brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3560{
3561 s8 iovbuf[32];
3562 s32 err = 0;
3563 __le32 roamtrigger[2];
3564 __le32 roam_delta[2];
3565 __le32 bcn_to_le;
3566 __le32 roamvar_le;
3567
3568 /*
3569 * Setup timeout if Beacons are lost and roam is
3570 * off to report link down
3571 */
3572 if (roamvar) {
3573 bcn_to_le = cpu_to_le32(bcn_timeout);
3574 brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
3575 sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
3576 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3577 iovbuf, sizeof(iovbuf));
3578 if (err) {
3579 WL_ERR("bcn_timeout error (%d)\n", err);
3580 goto dongle_rom_out;
3581 }
3582 }
3583
3584 /*
3585 * Enable/Disable built-in roaming to allow supplicant
3586 * to take care of roaming
3587 */
3588 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3589 roamvar_le = cpu_to_le32(roamvar);
3590 brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
3591 sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
3592 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3593 if (err) {
3594 WL_ERR("roam_off error (%d)\n", err);
3595 goto dongle_rom_out;
3596 }
3597
3598 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
3599 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
3600 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3601 (void *)roamtrigger, sizeof(roamtrigger));
3602 if (err) {
3603 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3604 goto dongle_rom_out;
3605 }
3606
3607 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
3608 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
3609 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3610 (void *)roam_delta, sizeof(roam_delta));
3611 if (err) {
3612 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3613 goto dongle_rom_out;
3614 }
3615
3616dongle_rom_out:
3617 return err;
3618}
3619
3620static s32
3621brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3622 s32 scan_unassoc_time, s32 scan_passive_time)
3623{
3624 s32 err = 0;
3625 __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
3626 __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
3627 __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
3628
3629 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3630 &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
3631 if (err) {
3632 if (err == -EOPNOTSUPP)
3633 WL_INFO("Scan assoc time is not supported\n");
3634 else
3635 WL_ERR("Scan assoc time error (%d)\n", err);
3636 goto dongle_scantime_out;
3637 }
3638 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3639 &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
3640 if (err) {
3641 if (err == -EOPNOTSUPP)
3642 WL_INFO("Scan unassoc time is not supported\n");
3643 else
3644 WL_ERR("Scan unassoc time error (%d)\n", err);
3645 goto dongle_scantime_out;
3646 }
3647
3648 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3649 &scan_passive_tm_le, sizeof(scan_passive_tm_le));
3650 if (err) {
3651 if (err == -EOPNOTSUPP)
3652 WL_INFO("Scan passive time is not supported\n");
3653 else
3654 WL_ERR("Scan passive time error (%d)\n", err);
3655 goto dongle_scantime_out;
3656 }
3657
3658dongle_scantime_out:
3659 return err;
3660}
3661
3662static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3663{
3664 struct wiphy *wiphy;
3665 s32 phy_list;
3666 s8 phy;
3667 s32 err = 0;
3668
3669 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3670 &phy_list, sizeof(phy_list));
3671 if (err) {
3672 WL_ERR("error (%d)\n", err);
3673 return err;
3674 }
3675
3676 phy = ((char *)&phy_list)[1];
3677 WL_INFO("%c phy\n", phy);
3678 if (phy == 'n' || phy == 'a') {
3679 wiphy = cfg_to_wiphy(cfg_priv);
3680 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3681 }
3682
3683 return err;
3684}
3685
3686static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3687{
3688 return wl_update_wiphybands(cfg_priv);
3689}
3690
3691static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3692{
3693 struct net_device *ndev;
3694 struct wireless_dev *wdev;
3695 s32 power_mode;
3696 s32 err = 0;
3697
3698 if (cfg_priv->dongle_up)
3699 return err;
3700
3701 ndev = cfg_to_ndev(cfg_priv);
3702 wdev = ndev->ieee80211_ptr;
3703
3704 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3705 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3706
3707 err = brcmf_dongle_eventmsg(ndev);
3708 if (err)
3709 goto default_conf_out;
3710
3711 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3712 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3713 if (err)
3714 goto default_conf_out;
3715 WL_INFO("power save set to %s\n",
3716 (power_mode ? "enabled" : "disabled"));
3717
3718 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3719 WL_BEACON_TIMEOUT);
3720 if (err)
3721 goto default_conf_out;
3722 err = brcmf_dongle_mode(ndev, wdev->iftype);
3723 if (err && err != -EINPROGRESS)
3724 goto default_conf_out;
3725 err = brcmf_dongle_probecap(cfg_priv);
3726 if (err)
3727 goto default_conf_out;
3728
3729 /* -EINPROGRESS: Call commit handler */
3730
3731default_conf_out:
3732
3733 cfg_priv->dongle_up = true;
3734
3735 return err;
3736
3737}
3738
3739static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3740{
3741 char buf[10+IFNAMSIZ];
3742 struct dentry *fd;
3743 s32 err = 0;
3744
3745 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3746 cfg_priv->debugfsdir = debugfs_create_dir(buf,
3747 cfg_to_wiphy(cfg_priv)->debugfsdir);
3748
3749 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3750 (u16 *)&cfg_priv->profile->beacon_interval);
3751 if (!fd) {
3752 err = -ENOMEM;
3753 goto err_out;
3754 }
3755
3756 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3757 (u8 *)&cfg_priv->profile->dtim_period);
3758 if (!fd) {
3759 err = -ENOMEM;
3760 goto err_out;
3761 }
3762
3763err_out:
3764 return err;
3765}
3766
3767static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3768{
3769 debugfs_remove_recursive(cfg_priv->debugfsdir);
3770 cfg_priv->debugfsdir = NULL;
3771}
3772
3773static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3774{
3775 s32 err = 0;
3776
3777 set_bit(WL_STATUS_READY, &cfg_priv->status);
3778
3779 brcmf_debugfs_add_netdev_params(cfg_priv);
3780
3781 err = brcmf_config_dongle(cfg_priv);
3782 if (err)
3783 return err;
3784
3785 brcmf_invoke_iscan(cfg_priv);
3786
3787 return err;
3788}
3789
3790static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3791{
3792 /*
3793 * While going down, if associated with AP disassociate
3794 * from AP to save power
3795 */
3796 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3797 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3798 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3799 WL_INFO("Disassociating from AP");
3800 brcmf_link_down(cfg_priv);
3801
3802 /* Make sure WPA_Supplicant receives all the event
3803 generated due to DISASSOC call to the fw to keep
3804 the state fw and WPA_Supplicant state consistent
3805 */
3806 brcmf_delay(500);
3807 }
3808
3809 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3810 brcmf_term_iscan(cfg_priv);
3811 if (cfg_priv->scan_request) {
3812 cfg80211_scan_done(cfg_priv->scan_request, true);
3813 /* May need to perform this to cover rmmod */
3814 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3815 cfg_priv->scan_request = NULL;
3816 }
3817 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3818 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3819 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3820
3821 brcmf_debugfs_remove_netdev(cfg_priv);
3822
3823 return 0;
3824}
3825
3826s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3827{
3828 struct brcmf_cfg80211_priv *cfg_priv;
3829 s32 err = 0;
3830
3831 cfg_priv = brcmf_priv_get(cfg_dev);
3832 mutex_lock(&cfg_priv->usr_sync);
3833 err = __brcmf_cfg80211_up(cfg_priv);
3834 mutex_unlock(&cfg_priv->usr_sync);
3835
3836 return err;
3837}
3838
3839s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3840{
3841 struct brcmf_cfg80211_priv *cfg_priv;
3842 s32 err = 0;
3843
3844 cfg_priv = brcmf_priv_get(cfg_dev);
3845 mutex_lock(&cfg_priv->usr_sync);
3846 err = __brcmf_cfg80211_down(cfg_priv);
3847 mutex_unlock(&cfg_priv->usr_sync);
3848
3849 return err;
3850}
3851
3852static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3853 u8 t, u8 l, u8 *v)
3854{
3855 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3856 s32 err = 0;
3857
3858 if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3859 WL_ERR("ei crosses buffer boundary\n");
3860 return -ENOSPC;
3861 }
3862 ie->buf[ie->offset] = t;
3863 ie->buf[ie->offset + 1] = l;
3864 memcpy(&ie->buf[ie->offset + 2], v, l);
3865 ie->offset += l + 2;
3866
3867 return err;
3868}
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 000000000000..62dc46144ede
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -0,0 +1,375 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _wl_cfg80211_h_
18#define _wl_cfg80211_h_
19
20struct brcmf_cfg80211_conf;
21struct brcmf_cfg80211_iface;
22struct brcmf_cfg80211_priv;
23struct brcmf_cfg80211_security;
24struct brcmf_cfg80211_ibss;
25
26#define WL_DBG_NONE 0
27#define WL_DBG_CONN (1 << 5)
28#define WL_DBG_SCAN (1 << 4)
29#define WL_DBG_TRACE (1 << 3)
30#define WL_DBG_INFO (1 << 1)
31#define WL_DBG_ERR (1 << 0)
32#define WL_DBG_MASK ((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \
33 (WL_DBG_SCAN) | (WL_DBG_CONN))
34
35#define WL_ERR(fmt, args...) \
36do { \
37 if (brcmf_dbg_level & WL_DBG_ERR) { \
38 if (net_ratelimit()) { \
39 printk(KERN_ERR "ERROR @%s : " fmt, \
40 __func__, ##args); \
41 } \
42 } \
43} while (0)
44
45#if (defined BCMDBG)
46#define WL_INFO(fmt, args...) \
47do { \
48 if (brcmf_dbg_level & WL_DBG_INFO) { \
49 if (net_ratelimit()) { \
50 printk(KERN_ERR "INFO @%s : " fmt, \
51 __func__, ##args); \
52 } \
53 } \
54} while (0)
55
56#define WL_TRACE(fmt, args...) \
57do { \
58 if (brcmf_dbg_level & WL_DBG_TRACE) { \
59 if (net_ratelimit()) { \
60 printk(KERN_ERR "TRACE @%s : " fmt, \
61 __func__, ##args); \
62 } \
63 } \
64} while (0)
65
66#define WL_SCAN(fmt, args...) \
67do { \
68 if (brcmf_dbg_level & WL_DBG_SCAN) { \
69 if (net_ratelimit()) { \
70 printk(KERN_ERR "SCAN @%s : " fmt, \
71 __func__, ##args); \
72 } \
73 } \
74} while (0)
75
76#define WL_CONN(fmt, args...) \
77do { \
78 if (brcmf_dbg_level & WL_DBG_CONN) { \
79 if (net_ratelimit()) { \
80 printk(KERN_ERR "CONN @%s : " fmt, \
81 __func__, ##args); \
82 } \
83 } \
84} while (0)
85
86#else /* (defined BCMDBG) */
87#define WL_INFO(fmt, args...)
88#define WL_TRACE(fmt, args...)
89#define WL_SCAN(fmt, args...)
90#define WL_CONN(fmt, args...)
91#endif /* (defined BCMDBG) */
92
93#define WL_NUM_SCAN_MAX 1
94#define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used
95 * for 2.6.33 kernel
96 * or later
97 */
98#define WL_SCAN_BUF_MAX (1024 * 8)
99#define WL_TLV_INFO_MAX 1024
100#define WL_BSS_INFO_MAX 2048
101#define WL_ASSOC_INFO_MAX 512 /*
102 * needs to grab assoc info from dongle to
103 * report it to cfg80211 through "connect"
104 * event
105 */
106#define WL_DCMD_LEN_MAX 1024
107#define WL_EXTRA_BUF_MAX 2048
108#define WL_ISCAN_BUF_MAX 2048 /*
109 * the buf length can be BRCMF_DCMD_MAXLEN
110 * to reduce iteration
111 */
112#define WL_ISCAN_TIMER_INTERVAL_MS 3000
113#define WL_SCAN_ERSULTS_LAST (BRCMF_SCAN_RESULTS_NO_MEM+1)
114#define WL_AP_MAX 256 /* virtually unlimitted as long
115 * as kernel memory allows
116 */
117
118#define WL_ROAM_TRIGGER_LEVEL -75
119#define WL_ROAM_DELTA 20
120#define WL_BEACON_TIMEOUT 3
121
122#define WL_SCAN_CHANNEL_TIME 40
123#define WL_SCAN_UNASSOC_TIME 40
124#define WL_SCAN_PASSIVE_TIME 120
125
126/* dongle status */
127enum wl_status {
128 WL_STATUS_READY,
129 WL_STATUS_SCANNING,
130 WL_STATUS_SCAN_ABORTING,
131 WL_STATUS_CONNECTING,
132 WL_STATUS_CONNECTED
133};
134
135/* wi-fi mode */
136enum wl_mode {
137 WL_MODE_BSS,
138 WL_MODE_IBSS,
139 WL_MODE_AP
140};
141
142/* dongle profile list */
143enum wl_prof_list {
144 WL_PROF_MODE,
145 WL_PROF_SSID,
146 WL_PROF_SEC,
147 WL_PROF_IBSS,
148 WL_PROF_BAND,
149 WL_PROF_BSSID,
150 WL_PROF_ACT,
151 WL_PROF_BEACONINT,
152 WL_PROF_DTIMPERIOD
153};
154
155/* dongle iscan state */
156enum wl_iscan_state {
157 WL_ISCAN_STATE_IDLE,
158 WL_ISCAN_STATE_SCANING
159};
160
161/* dongle configuration */
162struct brcmf_cfg80211_conf {
163 u32 mode; /* adhoc , infrastructure or ap */
164 u32 frag_threshold;
165 u32 rts_threshold;
166 u32 retry_short;
167 u32 retry_long;
168 s32 tx_power;
169 struct ieee80211_channel channel;
170};
171
172/* cfg80211 main event loop */
173struct brcmf_cfg80211_event_loop {
174 s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_priv *cfg_priv,
175 struct net_device *ndev,
176 const struct brcmf_event_msg *e,
177 void *data);
178};
179
180/* representing interface of cfg80211 plane */
181struct brcmf_cfg80211_iface {
182 struct brcmf_cfg80211_priv *cfg_priv;
183};
184
185struct brcmf_cfg80211_dev {
186 void *driver_data; /* to store cfg80211 object information */
187};
188
189/* basic structure of scan request */
190struct brcmf_cfg80211_scan_req {
191 struct brcmf_ssid_le ssid_le;
192};
193
194/* basic structure of information element */
195struct brcmf_cfg80211_ie {
196 u16 offset;
197 u8 buf[WL_TLV_INFO_MAX];
198};
199
200/* event queue for cfg80211 main event */
201struct brcmf_cfg80211_event_q {
202 struct list_head evt_q_list;
203 u32 etype;
204 struct brcmf_event_msg emsg;
205 s8 edata[1];
206};
207
208/* security information with currently associated ap */
209struct brcmf_cfg80211_security {
210 u32 wpa_versions;
211 u32 auth_type;
212 u32 cipher_pairwise;
213 u32 cipher_group;
214 u32 wpa_auth;
215};
216
217/* ibss information for currently joined ibss network */
218struct brcmf_cfg80211_ibss {
219 u8 beacon_interval; /* in millisecond */
220 u8 atim; /* in millisecond */
221 s8 join_only;
222 u8 band;
223 u8 channel;
224};
225
226/* dongle profile */
227struct brcmf_cfg80211_profile {
228 u32 mode;
229 struct brcmf_ssid ssid;
230 u8 bssid[ETH_ALEN];
231 u16 beacon_interval;
232 u8 dtim_period;
233 struct brcmf_cfg80211_security sec;
234 struct brcmf_cfg80211_ibss ibss;
235 s32 band;
236};
237
238/* dongle iscan event loop */
239struct brcmf_cfg80211_iscan_eloop {
240 s32 (*handler[WL_SCAN_ERSULTS_LAST])
241 (struct brcmf_cfg80211_priv *cfg_priv);
242};
243
244/* dongle iscan controller */
245struct brcmf_cfg80211_iscan_ctrl {
246 struct net_device *ndev;
247 struct timer_list timer;
248 u32 timer_ms;
249 u32 timer_on;
250 s32 state;
251 struct work_struct work;
252 struct brcmf_cfg80211_iscan_eloop el;
253 void *data;
254 s8 dcmd_buf[BRCMF_DCMD_SMLEN];
255 s8 scan_buf[WL_ISCAN_BUF_MAX];
256};
257
258/* association inform */
259struct brcmf_cfg80211_connect_info {
260 u8 *req_ie;
261 s32 req_ie_len;
262 u8 *resp_ie;
263 s32 resp_ie_len;
264};
265
266/* assoc ie length */
267struct brcmf_cfg80211_assoc_ielen_le {
268 __le32 req_len;
269 __le32 resp_len;
270};
271
272/* wpa2 pmk list */
273struct brcmf_cfg80211_pmk_list {
274 struct pmkid_list pmkids;
275 struct pmkid foo[MAXPMKID - 1];
276};
277
278/* dongle private data of cfg80211 interface */
279struct brcmf_cfg80211_priv {
280 struct wireless_dev *wdev; /* representing wl cfg80211 device */
281 struct brcmf_cfg80211_conf *conf; /* dongle configuration */
282 struct cfg80211_scan_request *scan_request; /* scan request
283 object */
284 struct brcmf_cfg80211_event_loop el; /* main event loop */
285 struct list_head evt_q_list; /* used for event queue */
286 spinlock_t evt_q_lock; /* for event queue synchronization */
287 struct mutex usr_sync; /* maily for dongle up/down synchronization */
288 struct brcmf_scan_results *bss_list; /* bss_list holding scanned
289 ap information */
290 struct brcmf_scan_results *scan_results;
291 struct brcmf_cfg80211_scan_req *scan_req_int; /* scan request object
292 for internal purpose */
293 struct wl_cfg80211_bss_info *bss_info; /* bss information for
294 cfg80211 layer */
295 struct brcmf_cfg80211_ie ie; /* information element object for
296 internal purpose */
297 struct brcmf_cfg80211_profile *profile; /* holding dongle profile */
298 struct brcmf_cfg80211_iscan_ctrl *iscan; /* iscan controller */
299 struct brcmf_cfg80211_connect_info conn_info; /* association info */
300 struct brcmf_cfg80211_pmk_list *pmk_list; /* wpa2 pmk list */
301 struct work_struct event_work; /* event handler work struct */
302 unsigned long status; /* current dongle status */
303 void *pub;
304 u32 channel; /* current channel */
305 bool iscan_on; /* iscan on/off switch */
306 bool iscan_kickstart; /* indicate iscan already started */
307 bool active_scan; /* current scan mode */
308 bool ibss_starter; /* indicates this sta is ibss starter */
309 bool link_up; /* link/connection up flag */
310 bool pwr_save; /* indicate whether dongle to support
311 power save mode */
312 bool dongle_up; /* indicate whether dongle up or not */
313 bool roam_on; /* on/off switch for dongle self-roaming */
314 bool scan_tried; /* indicates if first scan attempted */
315 u8 *dcmd_buf; /* dcmd buffer */
316 u8 *extra_buf; /* maily to grab assoc information */
317 struct dentry *debugfsdir;
318 u8 ci[0] __aligned(NETDEV_ALIGN);
319};
320
321static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_priv *w)
322{
323 return w->wdev->wiphy;
324}
325
326static inline struct brcmf_cfg80211_priv *wiphy_to_cfg(struct wiphy *w)
327{
328 return (struct brcmf_cfg80211_priv *)(wiphy_priv(w));
329}
330
331static inline struct brcmf_cfg80211_priv *wdev_to_cfg(struct wireless_dev *wd)
332{
333 return (struct brcmf_cfg80211_priv *)(wdev_priv(wd));
334}
335
336static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_priv *cfg)
337{
338 return cfg->wdev->netdev;
339}
340
341static inline struct brcmf_cfg80211_priv *ndev_to_cfg(struct net_device *ndev)
342{
343 return wdev_to_cfg(ndev->ieee80211_ptr);
344}
345
346#define iscan_to_cfg(i) ((struct brcmf_cfg80211_priv *)(i->data))
347#define cfg_to_iscan(w) (w->iscan)
348
349static inline struct
350brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_priv *cfg)
351{
352 return &cfg->conn_info;
353}
354
355static inline struct brcmf_bss_info *next_bss(struct brcmf_scan_results *list,
356 struct brcmf_bss_info *bss)
357{
358 return bss = bss ?
359 (struct brcmf_bss_info *)((unsigned long)bss +
360 le32_to_cpu(bss->length)) :
361 list->bss_info;
362}
363
364extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
365 struct device *busdev,
366 void *data);
367extern void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg);
368
369/* event handler from dongle */
370extern void brcmf_cfg80211_event(struct net_device *ndev,
371 const struct brcmf_event_msg *e, void *data);
372extern s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev);
373extern s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev);
374
375#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 000000000000..c2eb2d0af386
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
@@ -0,0 +1,51 @@
1#
2# Makefile fragment for Broadcom 802.11n Networking Device Driver
3#
4# Copyright (c) 2010 Broadcom Corporation
5#
6# Permission to use, copy, modify, and/or distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18ccflags-y := \
19 -D__CHECK_ENDIAN__ \
20 -Idrivers/net/wireless/brcm80211/brcmsmac \
21 -Idrivers/net/wireless/brcm80211/brcmsmac/phy \
22 -Idrivers/net/wireless/brcm80211/include
23
24BRCMSMAC_OFILES := \
25 mac80211_if.o \
26 ucode_loader.o \
27 ampdu.o \
28 antsel.o \
29 channel.o \
30 main.o \
31 phy_shim.o \
32 pmu.o \
33 rate.o \
34 stf.o \
35 aiutils.o \
36 phy/phy_cmn.o \
37 phy/phy_lcn.o \
38 phy/phy_n.o \
39 phy/phytbl_lcn.o \
40 phy/phytbl_n.o \
41 phy/phy_qmath.o \
42 otp.o \
43 srom.o \
44 dma.o \
45 nicpci.o \
46 brcms_trace_events.o
47
48MODULEPFX := brcmsmac
49
50obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o
51$(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 000000000000..025fa0eb6f47
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
@@ -0,0 +1,2079 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 *
16 * File contents: support functions for PCI/PCIe
17 */
18
19#include <linux/delay.h>
20#include <linux/pci.h>
21
22#include <defs.h>
23#include <chipcommon.h>
24#include <brcmu_utils.h>
25#include <brcm_hw_ids.h>
26#include <soc.h>
27#include "types.h"
28#include "pub.h"
29#include "pmu.h"
30#include "srom.h"
31#include "nicpci.h"
32#include "aiutils.h"
33
34/* slow_clk_ctl */
35 /* slow clock source mask */
36#define SCC_SS_MASK 0x00000007
37 /* source of slow clock is LPO */
38#define SCC_SS_LPO 0x00000000
39 /* source of slow clock is crystal */
40#define SCC_SS_XTAL 0x00000001
41 /* source of slow clock is PCI */
42#define SCC_SS_PCI 0x00000002
43 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
44#define SCC_LF 0x00000200
45 /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
46#define SCC_LP 0x00000400
47 /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
48#define SCC_FS 0x00000800
49 /* IgnorePllOffReq, 1/0:
50 * power logic ignores/honors PLL clock disable requests from core
51 */
52#define SCC_IP 0x00001000
53 /* XtalControlEn, 1/0:
54 * power logic does/doesn't disable crystal when appropriate
55 */
56#define SCC_XC 0x00002000
57 /* XtalPU (RO), 1/0: crystal running/disabled */
58#define SCC_XP 0x00004000
59 /* ClockDivider (SlowClk = 1/(4+divisor)) */
60#define SCC_CD_MASK 0xffff0000
61#define SCC_CD_SHIFT 16
62
63/* system_clk_ctl */
64 /* ILPen: Enable Idle Low Power */
65#define SYCC_IE 0x00000001
66 /* ALPen: Enable Active Low Power */
67#define SYCC_AE 0x00000002
68 /* ForcePLLOn */
69#define SYCC_FP 0x00000004
70 /* Force ALP (or HT if ALPen is not set */
71#define SYCC_AR 0x00000008
72 /* Force HT */
73#define SYCC_HR 0x00000010
74 /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */
75#define SYCC_CD_MASK 0xffff0000
76#define SYCC_CD_SHIFT 16
77
78#define CST4329_SPROM_OTP_SEL_MASK 0x00000003
79 /* OTP is powered up, use def. CIS, no SPROM */
80#define CST4329_DEFCIS_SEL 0
81 /* OTP is powered up, SPROM is present */
82#define CST4329_SPROM_SEL 1
83 /* OTP is powered up, no SPROM */
84#define CST4329_OTP_SEL 2
85 /* OTP is powered down, SPROM is present */
86#define CST4329_OTP_PWRDN 3
87
88#define CST4329_SPI_SDIO_MODE_MASK 0x00000004
89#define CST4329_SPI_SDIO_MODE_SHIFT 2
90
91/* 43224 chip-specific ChipControl register bits */
92#define CCTRL43224_GPIO_TOGGLE 0x8000
93 /* 12 mA drive strength */
94#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0
95 /* 12 mA drive strength for later 43224s */
96#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0
97
98/* 43236 Chip specific ChipStatus register bits */
99#define CST43236_SFLASH_MASK 0x00000040
100#define CST43236_OTP_MASK 0x00000080
101#define CST43236_HSIC_MASK 0x00000100 /* USB/HSIC */
102#define CST43236_BP_CLK 0x00000200 /* 120/96Mbps */
103#define CST43236_BOOT_MASK 0x00001800
104#define CST43236_BOOT_SHIFT 11
105#define CST43236_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */
106#define CST43236_BOOT_FROM_ROM 1 /* boot from ROM */
107#define CST43236_BOOT_FROM_FLASH 2 /* boot from FLASH */
108#define CST43236_BOOT_FROM_INVALID 3
109
110/* 4331 chip-specific ChipControl register bits */
111 /* 0 disable */
112#define CCTRL4331_BT_COEXIST (1<<0)
113 /* 0 SECI is disabled (JTAG functional) */
114#define CCTRL4331_SECI (1<<1)
115 /* 0 disable */
116#define CCTRL4331_EXT_LNA (1<<2)
117 /* sprom/gpio13-15 mux */
118#define CCTRL4331_SPROM_GPIO13_15 (1<<3)
119 /* 0 ext pa disable, 1 ext pa enabled */
120#define CCTRL4331_EXTPA_EN (1<<4)
121 /* set drive out GPIO_CLK on sprom_cs pin */
122#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5)
123 /* use sprom_cs pin as PCIE mdio interface */
124#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6)
125 /* aband extpa will be at gpio2/5 and sprom_dout */
126#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7)
127 /* override core control on pipe_AuxClkEnable */
128#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8)
129 /* override core control on pipe_AuxPowerDown */
130#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9)
131 /* pcie_auxclkenable */
132#define CCTRL4331_PCIE_AUXCLKEN (1<<10)
133 /* pcie_pipe_pllpowerdown */
134#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11)
135 /* enable bt_shd0 at gpio4 */
136#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16)
137 /* enable bt_shd1 at gpio5 */
138#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17)
139
140/* 4331 Chip specific ChipStatus register bits */
141 /* crystal frequency 20/40Mhz */
142#define CST4331_XTAL_FREQ 0x00000001
143#define CST4331_SPROM_PRESENT 0x00000002
144#define CST4331_OTP_PRESENT 0x00000004
145#define CST4331_LDO_RF 0x00000008
146#define CST4331_LDO_PAR 0x00000010
147
148/* 4319 chip-specific ChipStatus register bits */
149#define CST4319_SPI_CPULESSUSB 0x00000001
150#define CST4319_SPI_CLK_POL 0x00000002
151#define CST4319_SPI_CLK_PH 0x00000008
152 /* gpio [7:6], SDIO CIS selection */
153#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0
154#define CST4319_SPROM_OTP_SEL_SHIFT 6
155 /* use default CIS, OTP is powered up */
156#define CST4319_DEFCIS_SEL 0x00000000
157 /* use SPROM, OTP is powered up */
158#define CST4319_SPROM_SEL 0x00000040
159 /* use OTP, OTP is powered up */
160#define CST4319_OTP_SEL 0x00000080
161 /* use SPROM, OTP is powered down */
162#define CST4319_OTP_PWRDN 0x000000c0
163 /* gpio [8], sdio/usb mode */
164#define CST4319_SDIO_USB_MODE 0x00000100
165#define CST4319_REMAP_SEL_MASK 0x00000600
166#define CST4319_ILPDIV_EN 0x00000800
167#define CST4319_XTAL_PD_POL 0x00001000
168#define CST4319_LPO_SEL 0x00002000
169#define CST4319_RES_INIT_MODE 0x0000c000
170 /* PALDO is configured with external PNP */
171#define CST4319_PALDO_EXTPNP 0x00010000
172#define CST4319_CBUCK_MODE_MASK 0x00060000
173#define CST4319_CBUCK_MODE_BURST 0x00020000
174#define CST4319_CBUCK_MODE_LPBURST 0x00060000
175#define CST4319_RCAL_VALID 0x01000000
176#define CST4319_RCAL_VALUE_MASK 0x3e000000
177#define CST4319_RCAL_VALUE_SHIFT 25
178
179/* 4336 chip-specific ChipStatus register bits */
180#define CST4336_SPI_MODE_MASK 0x00000001
181#define CST4336_SPROM_PRESENT 0x00000002
182#define CST4336_OTP_PRESENT 0x00000004
183#define CST4336_ARMREMAP_0 0x00000008
184#define CST4336_ILPDIV_EN_MASK 0x00000010
185#define CST4336_ILPDIV_EN_SHIFT 4
186#define CST4336_XTAL_PD_POL_MASK 0x00000020
187#define CST4336_XTAL_PD_POL_SHIFT 5
188#define CST4336_LPO_SEL_MASK 0x00000040
189#define CST4336_LPO_SEL_SHIFT 6
190#define CST4336_RES_INIT_MODE_MASK 0x00000180
191#define CST4336_RES_INIT_MODE_SHIFT 7
192#define CST4336_CBUCK_MODE_MASK 0x00000600
193#define CST4336_CBUCK_MODE_SHIFT 9
194
195/* 4313 chip-specific ChipStatus register bits */
196#define CST4313_SPROM_PRESENT 1
197#define CST4313_OTP_PRESENT 2
198#define CST4313_SPROM_OTP_SEL_MASK 0x00000002
199#define CST4313_SPROM_OTP_SEL_SHIFT 0
200
201/* 4313 Chip specific ChipControl register bits */
202 /* 12 mA drive strengh for later 4313 */
203#define CCTRL_4313_12MA_LED_DRIVE 0x00000007
204
205/* Manufacturer Ids */
206#define MFGID_ARM 0x43b
207#define MFGID_BRCM 0x4bf
208#define MFGID_MIPS 0x4a7
209
210/* Enumeration ROM registers */
211#define ER_EROMENTRY 0x000
212#define ER_REMAPCONTROL 0xe00
213#define ER_REMAPSELECT 0xe04
214#define ER_MASTERSELECT 0xe10
215#define ER_ITCR 0xf00
216#define ER_ITIP 0xf04
217
218/* Erom entries */
219#define ER_TAG 0xe
220#define ER_TAG1 0x6
221#define ER_VALID 1
222#define ER_CI 0
223#define ER_MP 2
224#define ER_ADD 4
225#define ER_END 0xe
226#define ER_BAD 0xffffffff
227
228/* EROM CompIdentA */
229#define CIA_MFG_MASK 0xfff00000
230#define CIA_MFG_SHIFT 20
231#define CIA_CID_MASK 0x000fff00
232#define CIA_CID_SHIFT 8
233#define CIA_CCL_MASK 0x000000f0
234#define CIA_CCL_SHIFT 4
235
236/* EROM CompIdentB */
237#define CIB_REV_MASK 0xff000000
238#define CIB_REV_SHIFT 24
239#define CIB_NSW_MASK 0x00f80000
240#define CIB_NSW_SHIFT 19
241#define CIB_NMW_MASK 0x0007c000
242#define CIB_NMW_SHIFT 14
243#define CIB_NSP_MASK 0x00003e00
244#define CIB_NSP_SHIFT 9
245#define CIB_NMP_MASK 0x000001f0
246#define CIB_NMP_SHIFT 4
247
248/* EROM AddrDesc */
249#define AD_ADDR_MASK 0xfffff000
250#define AD_SP_MASK 0x00000f00
251#define AD_SP_SHIFT 8
252#define AD_ST_MASK 0x000000c0
253#define AD_ST_SHIFT 6
254#define AD_ST_SLAVE 0x00000000
255#define AD_ST_BRIDGE 0x00000040
256#define AD_ST_SWRAP 0x00000080
257#define AD_ST_MWRAP 0x000000c0
258#define AD_SZ_MASK 0x00000030
259#define AD_SZ_SHIFT 4
260#define AD_SZ_4K 0x00000000
261#define AD_SZ_8K 0x00000010
262#define AD_SZ_16K 0x00000020
263#define AD_SZ_SZD 0x00000030
264#define AD_AG32 0x00000008
265#define AD_ADDR_ALIGN 0x00000fff
266#define AD_SZ_BASE 0x00001000 /* 4KB */
267
268/* EROM SizeDesc */
269#define SD_SZ_MASK 0xfffff000
270#define SD_SG32 0x00000008
271#define SD_SZ_ALIGN 0x00000fff
272
273/* PCI config space bit 4 for 4306c0 slow clock source */
274#define PCI_CFG_GPIO_SCS 0x10
275/* PCI config space GPIO 14 for Xtal power-up */
276#define PCI_CFG_GPIO_XTAL 0x40
277/* PCI config space GPIO 15 for PLL power-down */
278#define PCI_CFG_GPIO_PLL 0x80
279
280/* power control defines */
281#define PLL_DELAY 150 /* us pll on delay */
282#define FREF_DELAY 200 /* us fref change delay */
283#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */
284
285/* resetctrl */
286#define AIRC_RESET 1
287
288#define NOREV -1 /* Invalid rev */
289
290/* GPIO Based LED powersave defines */
291#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */
292#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */
293
294/* When Srom support present, fields in sromcontrol */
295#define SRC_START 0x80000000
296#define SRC_BUSY 0x80000000
297#define SRC_OPCODE 0x60000000
298#define SRC_OP_READ 0x00000000
299#define SRC_OP_WRITE 0x20000000
300#define SRC_OP_WRDIS 0x40000000
301#define SRC_OP_WREN 0x60000000
302#define SRC_OTPSEL 0x00000010
303#define SRC_LOCK 0x00000008
304#define SRC_SIZE_MASK 0x00000006
305#define SRC_SIZE_1K 0x00000000
306#define SRC_SIZE_4K 0x00000002
307#define SRC_SIZE_16K 0x00000004
308#define SRC_SIZE_SHIFT 1
309#define SRC_PRESENT 0x00000001
310
311/* External PA enable mask */
312#define GPIO_CTRL_EPA_EN_MASK 0x40
313
314#define DEFAULT_GPIOTIMERVAL \
315 ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
316
317#define BADIDX (SI_MAXCORES + 1)
318
319/* Newer chips can access PCI/PCIE and CC core without requiring to change
320 * PCI BAR0 WIN
321 */
322#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) || \
323 (((si)->pub.buscoretype == PCI_CORE_ID) && \
324 (si)->pub.buscorerev >= 13))
325
326#define CCREGS_FAST(si) (((char __iomem *)((si)->curmap) + \
327 PCI_16KB0_CCREGS_OFFSET))
328
329#define IS_SIM(chippkg) \
330 ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
331
332/*
333 * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts
334 * before after core switching to avoid invalid register accesss inside ISR.
335 */
336#define INTR_OFF(si, intr_val) \
337 if ((si)->intrsoff_fn && \
338 (si)->coreid[(si)->curidx] == (si)->dev_coreid) \
339 intr_val = (*(si)->intrsoff_fn)((si)->intr_arg)
340
341#define INTR_RESTORE(si, intr_val) \
342 if ((si)->intrsrestore_fn && \
343 (si)->coreid[(si)->curidx] == (si)->dev_coreid) \
344 (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val)
345
346#define PCI(si) ((si)->pub.buscoretype == PCI_CORE_ID)
347#define PCIE(si) ((si)->pub.buscoretype == PCIE_CORE_ID)
348
349#define PCI_FORCEHT(si) (PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID))
350
351#ifdef BCMDBG
352#define SI_MSG(args) printk args
353#else
354#define SI_MSG(args)
355#endif /* BCMDBG */
356
357#define GOODCOREADDR(x, b) \
358 (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
359 IS_ALIGNED((x), SI_CORE_SIZE))
360
361#define PCIEREGS(si) ((__iomem char *)((si)->curmap) + \
362 PCI_16KB0_PCIREGS_OFFSET)
363
364struct aidmp {
365 u32 oobselina30; /* 0x000 */
366 u32 oobselina74; /* 0x004 */
367 u32 PAD[6];
368 u32 oobselinb30; /* 0x020 */
369 u32 oobselinb74; /* 0x024 */
370 u32 PAD[6];
371 u32 oobselinc30; /* 0x040 */
372 u32 oobselinc74; /* 0x044 */
373 u32 PAD[6];
374 u32 oobselind30; /* 0x060 */
375 u32 oobselind74; /* 0x064 */
376 u32 PAD[38];
377 u32 oobselouta30; /* 0x100 */
378 u32 oobselouta74; /* 0x104 */
379 u32 PAD[6];
380 u32 oobseloutb30; /* 0x120 */
381 u32 oobseloutb74; /* 0x124 */
382 u32 PAD[6];
383 u32 oobseloutc30; /* 0x140 */
384 u32 oobseloutc74; /* 0x144 */
385 u32 PAD[6];
386 u32 oobseloutd30; /* 0x160 */
387 u32 oobseloutd74; /* 0x164 */
388 u32 PAD[38];
389 u32 oobsynca; /* 0x200 */
390 u32 oobseloutaen; /* 0x204 */
391 u32 PAD[6];
392 u32 oobsyncb; /* 0x220 */
393 u32 oobseloutben; /* 0x224 */
394 u32 PAD[6];
395 u32 oobsyncc; /* 0x240 */
396 u32 oobseloutcen; /* 0x244 */
397 u32 PAD[6];
398 u32 oobsyncd; /* 0x260 */
399 u32 oobseloutden; /* 0x264 */
400 u32 PAD[38];
401 u32 oobaextwidth; /* 0x300 */
402 u32 oobainwidth; /* 0x304 */
403 u32 oobaoutwidth; /* 0x308 */
404 u32 PAD[5];
405 u32 oobbextwidth; /* 0x320 */
406 u32 oobbinwidth; /* 0x324 */
407 u32 oobboutwidth; /* 0x328 */
408 u32 PAD[5];
409 u32 oobcextwidth; /* 0x340 */
410 u32 oobcinwidth; /* 0x344 */
411 u32 oobcoutwidth; /* 0x348 */
412 u32 PAD[5];
413 u32 oobdextwidth; /* 0x360 */
414 u32 oobdinwidth; /* 0x364 */
415 u32 oobdoutwidth; /* 0x368 */
416 u32 PAD[37];
417 u32 ioctrlset; /* 0x400 */
418 u32 ioctrlclear; /* 0x404 */
419 u32 ioctrl; /* 0x408 */
420 u32 PAD[61];
421 u32 iostatus; /* 0x500 */
422 u32 PAD[127];
423 u32 ioctrlwidth; /* 0x700 */
424 u32 iostatuswidth; /* 0x704 */
425 u32 PAD[62];
426 u32 resetctrl; /* 0x800 */
427 u32 resetstatus; /* 0x804 */
428 u32 resetreadid; /* 0x808 */
429 u32 resetwriteid; /* 0x80c */
430 u32 PAD[60];
431 u32 errlogctrl; /* 0x900 */
432 u32 errlogdone; /* 0x904 */
433 u32 errlogstatus; /* 0x908 */
434 u32 errlogaddrlo; /* 0x90c */
435 u32 errlogaddrhi; /* 0x910 */
436 u32 errlogid; /* 0x914 */
437 u32 errloguser; /* 0x918 */
438 u32 errlogflags; /* 0x91c */
439 u32 PAD[56];
440 u32 intstatus; /* 0xa00 */
441 u32 PAD[127];
442 u32 config; /* 0xe00 */
443 u32 PAD[63];
444 u32 itcr; /* 0xf00 */
445 u32 PAD[3];
446 u32 itipooba; /* 0xf10 */
447 u32 itipoobb; /* 0xf14 */
448 u32 itipoobc; /* 0xf18 */
449 u32 itipoobd; /* 0xf1c */
450 u32 PAD[4];
451 u32 itipoobaout; /* 0xf30 */
452 u32 itipoobbout; /* 0xf34 */
453 u32 itipoobcout; /* 0xf38 */
454 u32 itipoobdout; /* 0xf3c */
455 u32 PAD[4];
456 u32 itopooba; /* 0xf50 */
457 u32 itopoobb; /* 0xf54 */
458 u32 itopoobc; /* 0xf58 */
459 u32 itopoobd; /* 0xf5c */
460 u32 PAD[4];
461 u32 itopoobain; /* 0xf70 */
462 u32 itopoobbin; /* 0xf74 */
463 u32 itopoobcin; /* 0xf78 */
464 u32 itopoobdin; /* 0xf7c */
465 u32 PAD[4];
466 u32 itopreset; /* 0xf90 */
467 u32 PAD[15];
468 u32 peripherialid4; /* 0xfd0 */
469 u32 peripherialid5; /* 0xfd4 */
470 u32 peripherialid6; /* 0xfd8 */
471 u32 peripherialid7; /* 0xfdc */
472 u32 peripherialid0; /* 0xfe0 */
473 u32 peripherialid1; /* 0xfe4 */
474 u32 peripherialid2; /* 0xfe8 */
475 u32 peripherialid3; /* 0xfec */
476 u32 componentid0; /* 0xff0 */
477 u32 componentid1; /* 0xff4 */
478 u32 componentid2; /* 0xff8 */
479 u32 componentid3; /* 0xffc */
480};
481
482/* EROM parsing */
483
484static u32
485get_erom_ent(struct si_pub *sih, u32 __iomem **eromptr, u32 mask, u32 match)
486{
487 u32 ent;
488 uint inv = 0, nom = 0;
489
490 while (true) {
491 ent = R_REG(*eromptr);
492 (*eromptr)++;
493
494 if (mask == 0)
495 break;
496
497 if ((ent & ER_VALID) == 0) {
498 inv++;
499 continue;
500 }
501
502 if (ent == (ER_END | ER_VALID))
503 break;
504
505 if ((ent & mask) == match)
506 break;
507
508 nom++;
509 }
510
511 return ent;
512}
513
514static u32
515get_asd(struct si_pub *sih, u32 __iomem **eromptr, uint sp, uint ad, uint st,
516 u32 *addrl, u32 *addrh, u32 *sizel, u32 *sizeh)
517{
518 u32 asd, sz, szd;
519
520 asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID);
521 if (((asd & ER_TAG1) != ER_ADD) ||
522 (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) ||
523 ((asd & AD_ST_MASK) != st)) {
524 /* This is not what we want, "push" it back */
525 (*eromptr)--;
526 return 0;
527 }
528 *addrl = asd & AD_ADDR_MASK;
529 if (asd & AD_AG32)
530 *addrh = get_erom_ent(sih, eromptr, 0, 0);
531 else
532 *addrh = 0;
533 *sizeh = 0;
534 sz = asd & AD_SZ_MASK;
535 if (sz == AD_SZ_SZD) {
536 szd = get_erom_ent(sih, eromptr, 0, 0);
537 *sizel = szd & SD_SZ_MASK;
538 if (szd & SD_SG32)
539 *sizeh = get_erom_ent(sih, eromptr, 0, 0);
540 } else
541 *sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT);
542
543 return asd;
544}
545
546static void ai_hwfixup(struct si_info *sii)
547{
548}
549
550/* parse the enumeration rom to identify all cores */
551static void ai_scan(struct si_pub *sih, struct chipcregs __iomem *cc)
552{
553 struct si_info *sii = (struct si_info *)sih;
554
555 u32 erombase;
556 u32 __iomem *eromptr, *eromlim;
557 void __iomem *regs = cc;
558
559 erombase = R_REG(&cc->eromptr);
560
561 /* Set wrappers address */
562 sii->curwrap = (void *)((unsigned long)cc + SI_CORE_SIZE);
563
564 /* Now point the window at the erom */
565 pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, erombase);
566 eromptr = regs;
567 eromlim = eromptr + (ER_REMAPCONTROL / sizeof(u32));
568
569 while (eromptr < eromlim) {
570 u32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp;
571 u32 mpd, asd, addrl, addrh, sizel, sizeh;
572 u32 __iomem *base;
573 uint i, j, idx;
574 bool br;
575
576 br = false;
577
578 /* Grok a component */
579 cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI);
580 if (cia == (ER_END | ER_VALID)) {
581 /* Found END of erom */
582 ai_hwfixup(sii);
583 return;
584 }
585 base = eromptr - 1;
586 cib = get_erom_ent(sih, &eromptr, 0, 0);
587
588 if ((cib & ER_TAG) != ER_CI) {
589 /* CIA not followed by CIB */
590 goto error;
591 }
592
593 cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT;
594 mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
595 crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
596 nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT;
597 nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT;
598 nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT;
599 nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT;
600
601 if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0))
602 continue;
603 if ((nmw + nsw == 0)) {
604 /* A component which is not a core */
605 if (cid == OOB_ROUTER_CORE_ID) {
606 asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE,
607 &addrl, &addrh, &sizel, &sizeh);
608 if (asd != 0)
609 sii->oob_router = addrl;
610 }
611 continue;
612 }
613
614 idx = sii->numcores;
615/* sii->eromptr[idx] = base; */
616 sii->cia[idx] = cia;
617 sii->cib[idx] = cib;
618 sii->coreid[idx] = cid;
619
620 for (i = 0; i < nmp; i++) {
621 mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID);
622 if ((mpd & ER_TAG) != ER_MP) {
623 /* Not enough MP entries for component */
624 goto error;
625 }
626 }
627
628 /* First Slave Address Descriptor should be port 0:
629 * the main register space for the core
630 */
631 asd =
632 get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh,
633 &sizel, &sizeh);
634 if (asd == 0) {
635 /* Try again to see if it is a bridge */
636 asd =
637 get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl,
638 &addrh, &sizel, &sizeh);
639 if (asd != 0)
640 br = true;
641 else if ((addrh != 0) || (sizeh != 0)
642 || (sizel != SI_CORE_SIZE)) {
643 /* First Slave ASD for core malformed */
644 goto error;
645 }
646 }
647 sii->coresba[idx] = addrl;
648 sii->coresba_size[idx] = sizel;
649 /* Get any more ASDs in port 0 */
650 j = 1;
651 do {
652 asd =
653 get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl,
654 &addrh, &sizel, &sizeh);
655 if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) {
656 sii->coresba2[idx] = addrl;
657 sii->coresba2_size[idx] = sizel;
658 }
659 j++;
660 } while (asd != 0);
661
662 /* Go through the ASDs for other slave ports */
663 for (i = 1; i < nsp; i++) {
664 j = 0;
665 do {
666 asd =
667 get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE,
668 &addrl, &addrh, &sizel, &sizeh);
669 } while (asd != 0);
670 if (j == 0) {
671 /* SP has no address descriptors */
672 goto error;
673 }
674 }
675
676 /* Now get master wrappers */
677 for (i = 0; i < nmw; i++) {
678 asd =
679 get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl,
680 &addrh, &sizel, &sizeh);
681 if (asd == 0) {
682 /* Missing descriptor for MW */
683 goto error;
684 }
685 if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
686 /* Master wrapper %d is not 4KB */
687 goto error;
688 }
689 if (i == 0)
690 sii->wrapba[idx] = addrl;
691 }
692
693 /* And finally slave wrappers */
694 for (i = 0; i < nsw; i++) {
695 uint fwp = (nsp == 1) ? 0 : 1;
696 asd =
697 get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP,
698 &addrl, &addrh, &sizel, &sizeh);
699 if (asd == 0) {
700 /* Missing descriptor for SW */
701 goto error;
702 }
703 if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
704 /* Slave wrapper is not 4KB */
705 goto error;
706 }
707 if ((nmw == 0) && (i == 0))
708 sii->wrapba[idx] = addrl;
709 }
710
711 /* Don't record bridges */
712 if (br)
713 continue;
714
715 /* Done with core */
716 sii->numcores++;
717 }
718
719 error:
720 /* Reached end of erom without finding END */
721 sii->numcores = 0;
722 return;
723}
724
725/*
726 * This function changes the logical "focus" to the indicated core.
727 * Return the current core's virtual address. Since each core starts with the
728 * same set of registers (BIST, clock control, etc), the returned address
729 * contains the first register of this 'common' register block (not to be
730 * confused with 'common core').
731 */
732void __iomem *ai_setcoreidx(struct si_pub *sih, uint coreidx)
733{
734 struct si_info *sii = (struct si_info *)sih;
735 u32 addr = sii->coresba[coreidx];
736 u32 wrap = sii->wrapba[coreidx];
737
738 if (coreidx >= sii->numcores)
739 return NULL;
740
741 /* point bar0 window */
742 pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, addr);
743 /* point bar0 2nd 4KB window */
744 pci_write_config_dword(sii->pbus, PCI_BAR0_WIN2, wrap);
745 sii->curidx = coreidx;
746
747 return sii->curmap;
748}
749
750/* Return the number of address spaces in current core */
751int ai_numaddrspaces(struct si_pub *sih)
752{
753 return 2;
754}
755
756/* Return the address of the nth address space in the current core */
757u32 ai_addrspace(struct si_pub *sih, uint asidx)
758{
759 struct si_info *sii;
760 uint cidx;
761
762 sii = (struct si_info *)sih;
763 cidx = sii->curidx;
764
765 if (asidx == 0)
766 return sii->coresba[cidx];
767 else if (asidx == 1)
768 return sii->coresba2[cidx];
769 else {
770 /* Need to parse the erom again to find addr space */
771 return 0;
772 }
773}
774
775/* Return the size of the nth address space in the current core */
776u32 ai_addrspacesize(struct si_pub *sih, uint asidx)
777{
778 struct si_info *sii;
779 uint cidx;
780
781 sii = (struct si_info *)sih;
782 cidx = sii->curidx;
783
784 if (asidx == 0)
785 return sii->coresba_size[cidx];
786 else if (asidx == 1)
787 return sii->coresba2_size[cidx];
788 else {
789 /* Need to parse the erom again to find addr */
790 return 0;
791 }
792}
793
794uint ai_flag(struct si_pub *sih)
795{
796 struct si_info *sii;
797 struct aidmp *ai;
798
799 sii = (struct si_info *)sih;
800 ai = sii->curwrap;
801
802 return R_REG(&ai->oobselouta30) & 0x1f;
803}
804
805void ai_setint(struct si_pub *sih, int siflag)
806{
807}
808
809uint ai_corevendor(struct si_pub *sih)
810{
811 struct si_info *sii;
812 u32 cia;
813
814 sii = (struct si_info *)sih;
815 cia = sii->cia[sii->curidx];
816 return (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
817}
818
819uint ai_corerev(struct si_pub *sih)
820{
821 struct si_info *sii;
822 u32 cib;
823
824 sii = (struct si_info *)sih;
825 cib = sii->cib[sii->curidx];
826 return (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
827}
828
829bool ai_iscoreup(struct si_pub *sih)
830{
831 struct si_info *sii;
832 struct aidmp *ai;
833
834 sii = (struct si_info *)sih;
835 ai = sii->curwrap;
836
837 return (((R_REG(&ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) ==
838 SICF_CLOCK_EN)
839 && ((R_REG(&ai->resetctrl) & AIRC_RESET) == 0));
840}
841
842void ai_core_cflags_wo(struct si_pub *sih, u32 mask, u32 val)
843{
844 struct si_info *sii;
845 struct aidmp *ai;
846 u32 w;
847
848 sii = (struct si_info *)sih;
849
850 ai = sii->curwrap;
851
852 if (mask || val) {
853 w = ((R_REG(&ai->ioctrl) & ~mask) | val);
854 W_REG(&ai->ioctrl, w);
855 }
856}
857
858u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val)
859{
860 struct si_info *sii;
861 struct aidmp *ai;
862 u32 w;
863
864 sii = (struct si_info *)sih;
865 ai = sii->curwrap;
866
867 if (mask || val) {
868 w = ((R_REG(&ai->ioctrl) & ~mask) | val);
869 W_REG(&ai->ioctrl, w);
870 }
871
872 return R_REG(&ai->ioctrl);
873}
874
875/* return true if PCIE capability exists in the pci config space */
876static bool ai_ispcie(struct si_info *sii)
877{
878 u8 cap_ptr;
879
880 cap_ptr =
881 pcicore_find_pci_capability(sii->pbus, PCI_CAP_ID_EXP, NULL,
882 NULL);
883 if (!cap_ptr)
884 return false;
885
886 return true;
887}
888
889static bool ai_buscore_prep(struct si_info *sii)
890{
891 /* kludge to enable the clock on the 4306 which lacks a slowclock */
892 if (!ai_ispcie(sii))
893 ai_clkctl_xtal(&sii->pub, XTAL | PLL, ON);
894 return true;
895}
896
897u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val)
898{
899 struct si_info *sii;
900 struct aidmp *ai;
901 u32 w;
902
903 sii = (struct si_info *)sih;
904 ai = sii->curwrap;
905
906 if (mask || val) {
907 w = ((R_REG(&ai->iostatus) & ~mask) | val);
908 W_REG(&ai->iostatus, w);
909 }
910
911 return R_REG(&ai->iostatus);
912}
913
914static bool
915ai_buscore_setup(struct si_info *sii, u32 savewin, uint *origidx)
916{
917 bool pci, pcie;
918 uint i;
919 uint pciidx, pcieidx, pcirev, pcierev;
920 struct chipcregs __iomem *cc;
921
922 cc = ai_setcoreidx(&sii->pub, SI_CC_IDX);
923
924 /* get chipcommon rev */
925 sii->pub.ccrev = (int)ai_corerev(&sii->pub);
926
927 /* get chipcommon chipstatus */
928 if (sii->pub.ccrev >= 11)
929 sii->pub.chipst = R_REG(&cc->chipstatus);
930
931 /* get chipcommon capabilites */
932 sii->pub.cccaps = R_REG(&cc->capabilities);
933 /* get chipcommon extended capabilities */
934
935 if (sii->pub.ccrev >= 35)
936 sii->pub.cccaps_ext = R_REG(&cc->capabilities_ext);
937
938 /* get pmu rev and caps */
939 if (sii->pub.cccaps & CC_CAP_PMU) {
940 sii->pub.pmucaps = R_REG(&cc->pmucapabilities);
941 sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
942 }
943
944 /* figure out bus/orignal core idx */
945 sii->pub.buscoretype = NODEV_CORE_ID;
946 sii->pub.buscorerev = NOREV;
947 sii->pub.buscoreidx = BADIDX;
948
949 pci = pcie = false;
950 pcirev = pcierev = NOREV;
951 pciidx = pcieidx = BADIDX;
952
953 for (i = 0; i < sii->numcores; i++) {
954 uint cid, crev;
955
956 ai_setcoreidx(&sii->pub, i);
957 cid = ai_coreid(&sii->pub);
958 crev = ai_corerev(&sii->pub);
959
960 if (cid == PCI_CORE_ID) {
961 pciidx = i;
962 pcirev = crev;
963 pci = true;
964 } else if (cid == PCIE_CORE_ID) {
965 pcieidx = i;
966 pcierev = crev;
967 pcie = true;
968 }
969
970 /* find the core idx before entering this func. */
971 if ((savewin && (savewin == sii->coresba[i])) ||
972 (cc == sii->regs[i]))
973 *origidx = i;
974 }
975
976 if (pci && pcie) {
977 if (ai_ispcie(sii))
978 pci = false;
979 else
980 pcie = false;
981 }
982 if (pci) {
983 sii->pub.buscoretype = PCI_CORE_ID;
984 sii->pub.buscorerev = pcirev;
985 sii->pub.buscoreidx = pciidx;
986 } else if (pcie) {
987 sii->pub.buscoretype = PCIE_CORE_ID;
988 sii->pub.buscorerev = pcierev;
989 sii->pub.buscoreidx = pcieidx;
990 }
991
992 /* fixup necessary chip/core configurations */
993 if (SI_FAST(sii)) {
994 if (!sii->pch) {
995 sii->pch = pcicore_init(&sii->pub, sii->pbus,
996 (__iomem void *)PCIEREGS(sii));
997 if (sii->pch == NULL)
998 return false;
999 }
1000 }
1001 if (ai_pci_fixcfg(&sii->pub)) {
1002 /* si_doattach: si_pci_fixcfg failed */
1003 return false;
1004 }
1005
1006 /* return to the original core */
1007 ai_setcoreidx(&sii->pub, *origidx);
1008
1009 return true;
1010}
1011
1012/*
1013 * get boardtype and boardrev
1014 */
1015static __used void ai_nvram_process(struct si_info *sii)
1016{
1017 uint w = 0;
1018
1019 /* do a pci config read to get subsystem id and subvendor id */
1020 pci_read_config_dword(sii->pbus, PCI_SUBSYSTEM_VENDOR_ID, &w);
1021
1022 sii->pub.boardvendor = w & 0xffff;
1023 sii->pub.boardtype = (w >> 16) & 0xffff;
1024 sii->pub.boardflags = getintvar(&sii->pub, BRCMS_SROM_BOARDFLAGS);
1025}
1026
1027static struct si_info *ai_doattach(struct si_info *sii,
1028 void __iomem *regs, struct pci_dev *pbus)
1029{
1030 struct si_pub *sih = &sii->pub;
1031 u32 w, savewin;
1032 struct chipcregs __iomem *cc;
1033 uint socitype;
1034 uint origidx;
1035
1036 memset((unsigned char *) sii, 0, sizeof(struct si_info));
1037
1038 savewin = 0;
1039
1040 sih->buscoreidx = BADIDX;
1041
1042 sii->curmap = regs;
1043 sii->pbus = pbus;
1044
1045 /* find Chipcommon address */
1046 pci_read_config_dword(sii->pbus, PCI_BAR0_WIN, &savewin);
1047 if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
1048 savewin = SI_ENUM_BASE;
1049
1050 pci_write_config_dword(sii->pbus, PCI_BAR0_WIN,
1051 SI_ENUM_BASE);
1052 cc = (struct chipcregs __iomem *) regs;
1053
1054 /* bus/core/clk setup for register access */
1055 if (!ai_buscore_prep(sii))
1056 return NULL;
1057
1058 /*
1059 * ChipID recognition.
1060 * We assume we can read chipid at offset 0 from the regs arg.
1061 * If we add other chiptypes (or if we need to support old sdio
1062 * hosts w/o chipcommon), some way of recognizing them needs to
1063 * be added here.
1064 */
1065 w = R_REG(&cc->chipid);
1066 socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
1067 /* Might as wll fill in chip id rev & pkg */
1068 sih->chip = w & CID_ID_MASK;
1069 sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
1070 sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
1071
1072 sih->issim = false;
1073
1074 /* scan for cores */
1075 if (socitype == SOCI_AI) {
1076 SI_MSG(("Found chip type AI (0x%08x)\n", w));
1077 /* pass chipc address instead of original core base */
1078 ai_scan(&sii->pub, cc);
1079 } else {
1080 /* Found chip of unknown type */
1081 return NULL;
1082 }
1083 /* no cores found, bail out */
1084 if (sii->numcores == 0)
1085 return NULL;
1086
1087 /* bus/core/clk setup */
1088 origidx = SI_CC_IDX;
1089 if (!ai_buscore_setup(sii, savewin, &origidx))
1090 goto exit;
1091
1092 /* Init nvram from sprom/otp if they exist */
1093 if (srom_var_init(&sii->pub, cc))
1094 goto exit;
1095
1096 ai_nvram_process(sii);
1097
1098 /* === NVRAM, clock is ready === */
1099 cc = (struct chipcregs __iomem *) ai_setcore(sih, CC_CORE_ID, 0);
1100 W_REG(&cc->gpiopullup, 0);
1101 W_REG(&cc->gpiopulldown, 0);
1102 ai_setcoreidx(sih, origidx);
1103
1104 /* PMU specific initializations */
1105 if (sih->cccaps & CC_CAP_PMU) {
1106 u32 xtalfreq;
1107 si_pmu_init(sih);
1108 si_pmu_chip_init(sih);
1109
1110 xtalfreq = si_pmu_measure_alpclk(sih);
1111 si_pmu_pll_init(sih, xtalfreq);
1112 si_pmu_res_init(sih);
1113 si_pmu_swreg_init(sih);
1114 }
1115
1116 /* setup the GPIO based LED powersave register */
1117 w = getintvar(sih, BRCMS_SROM_LEDDC);
1118 if (w == 0)
1119 w = DEFAULT_GPIOTIMERVAL;
1120 ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, gpiotimerval),
1121 ~0, w);
1122
1123 if (PCIE(sii))
1124 pcicore_attach(sii->pch, SI_DOATTACH);
1125
1126 if (sih->chip == BCM43224_CHIP_ID) {
1127 /*
1128 * enable 12 mA drive strenth for 43224 and
1129 * set chipControl register bit 15
1130 */
1131 if (sih->chiprev == 0) {
1132 SI_MSG(("Applying 43224A0 WARs\n"));
1133 ai_corereg(sih, SI_CC_IDX,
1134 offsetof(struct chipcregs, chipcontrol),
1135 CCTRL43224_GPIO_TOGGLE,
1136 CCTRL43224_GPIO_TOGGLE);
1137 si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
1138 CCTRL_43224A0_12MA_LED_DRIVE);
1139 }
1140 if (sih->chiprev >= 1) {
1141 SI_MSG(("Applying 43224B0+ WARs\n"));
1142 si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
1143 CCTRL_43224B0_12MA_LED_DRIVE);
1144 }
1145 }
1146
1147 if (sih->chip == BCM4313_CHIP_ID) {
1148 /*
1149 * enable 12 mA drive strenth for 4313 and
1150 * set chipControl register bit 1
1151 */
1152 SI_MSG(("Applying 4313 WARs\n"));
1153 si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
1154 CCTRL_4313_12MA_LED_DRIVE);
1155 }
1156
1157 return sii;
1158
1159 exit:
1160 if (sii->pch)
1161 pcicore_deinit(sii->pch);
1162 sii->pch = NULL;
1163
1164 return NULL;
1165}
1166
1167/*
1168 * Allocate a si handle.
1169 * devid - pci device id (used to determine chip#)
1170 * osh - opaque OS handle
1171 * regs - virtual address of initial core registers
1172 */
1173struct si_pub *
1174ai_attach(void __iomem *regs, struct pci_dev *sdh)
1175{
1176 struct si_info *sii;
1177
1178 /* alloc struct si_info */
1179 sii = kmalloc(sizeof(struct si_info), GFP_ATOMIC);
1180 if (sii == NULL)
1181 return NULL;
1182
1183 if (ai_doattach(sii, regs, sdh) == NULL) {
1184 kfree(sii);
1185 return NULL;
1186 }
1187
1188 return (struct si_pub *) sii;
1189}
1190
1191/* may be called with core in reset */
1192void ai_detach(struct si_pub *sih)
1193{
1194 struct si_info *sii;
1195
1196 struct si_pub *si_local = NULL;
1197 memcpy(&si_local, &sih, sizeof(struct si_pub **));
1198
1199 sii = (struct si_info *)sih;
1200
1201 if (sii == NULL)
1202 return;
1203
1204 if (sii->pch)
1205 pcicore_deinit(sii->pch);
1206 sii->pch = NULL;
1207
1208 srom_free_vars(sih);
1209 kfree(sii);
1210}
1211
1212/* register driver interrupt disabling and restoring callback functions */
1213void
1214ai_register_intr_callback(struct si_pub *sih, void *intrsoff_fn,
1215 void *intrsrestore_fn,
1216 void *intrsenabled_fn, void *intr_arg)
1217{
1218 struct si_info *sii;
1219
1220 sii = (struct si_info *)sih;
1221 sii->intr_arg = intr_arg;
1222 sii->intrsoff_fn = (u32 (*)(void *)) intrsoff_fn;
1223 sii->intrsrestore_fn = (void (*) (void *, u32)) intrsrestore_fn;
1224 sii->intrsenabled_fn = (bool (*)(void *)) intrsenabled_fn;
1225 /* save current core id. when this function called, the current core
1226 * must be the core which provides driver functions(il, et, wl, etc.)
1227 */
1228 sii->dev_coreid = sii->coreid[sii->curidx];
1229}
1230
1231void ai_deregister_intr_callback(struct si_pub *sih)
1232{
1233 struct si_info *sii;
1234
1235 sii = (struct si_info *)sih;
1236 sii->intrsoff_fn = NULL;
1237}
1238
1239uint ai_coreid(struct si_pub *sih)
1240{
1241 struct si_info *sii;
1242
1243 sii = (struct si_info *)sih;
1244 return sii->coreid[sii->curidx];
1245}
1246
1247uint ai_coreidx(struct si_pub *sih)
1248{
1249 struct si_info *sii;
1250
1251 sii = (struct si_info *)sih;
1252 return sii->curidx;
1253}
1254
1255bool ai_backplane64(struct si_pub *sih)
1256{
1257 return (sih->cccaps & CC_CAP_BKPLN64) != 0;
1258}
1259
1260/* return index of coreid or BADIDX if not found */
1261uint ai_findcoreidx(struct si_pub *sih, uint coreid, uint coreunit)
1262{
1263 struct si_info *sii;
1264 uint found;
1265 uint i;
1266
1267 sii = (struct si_info *)sih;
1268
1269 found = 0;
1270
1271 for (i = 0; i < sii->numcores; i++)
1272 if (sii->coreid[i] == coreid) {
1273 if (found == coreunit)
1274 return i;
1275 found++;
1276 }
1277
1278 return BADIDX;
1279}
1280
1281/*
1282 * This function changes logical "focus" to the indicated core;
1283 * must be called with interrupts off.
1284 * Moreover, callers should keep interrupts off during switching
1285 * out of and back to d11 core.
1286 */
1287void __iomem *ai_setcore(struct si_pub *sih, uint coreid, uint coreunit)
1288{
1289 uint idx;
1290
1291 idx = ai_findcoreidx(sih, coreid, coreunit);
1292 if (idx >= SI_MAXCORES)
1293 return NULL;
1294
1295 return ai_setcoreidx(sih, idx);
1296}
1297
1298/* Turn off interrupt as required by ai_setcore, before switch core */
1299void __iomem *ai_switch_core(struct si_pub *sih, uint coreid, uint *origidx,
1300 uint *intr_val)
1301{
1302 void __iomem *cc;
1303 struct si_info *sii;
1304
1305 sii = (struct si_info *)sih;
1306
1307 if (SI_FAST(sii)) {
1308 /* Overloading the origidx variable to remember the coreid,
1309 * this works because the core ids cannot be confused with
1310 * core indices.
1311 */
1312 *origidx = coreid;
1313 if (coreid == CC_CORE_ID)
1314 return CCREGS_FAST(sii);
1315 else if (coreid == sih->buscoretype)
1316 return PCIEREGS(sii);
1317 }
1318 INTR_OFF(sii, *intr_val);
1319 *origidx = sii->curidx;
1320 cc = ai_setcore(sih, coreid, 0);
1321 return cc;
1322}
1323
1324/* restore coreidx and restore interrupt */
1325void ai_restore_core(struct si_pub *sih, uint coreid, uint intr_val)
1326{
1327 struct si_info *sii;
1328
1329 sii = (struct si_info *)sih;
1330 if (SI_FAST(sii)
1331 && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
1332 return;
1333
1334 ai_setcoreidx(sih, coreid);
1335 INTR_RESTORE(sii, intr_val);
1336}
1337
1338void ai_write_wrapperreg(struct si_pub *sih, u32 offset, u32 val)
1339{
1340 struct si_info *sii = (struct si_info *)sih;
1341 u32 *w = (u32 *) sii->curwrap;
1342 W_REG(w + (offset / 4), val);
1343 return;
1344}
1345
1346/*
1347 * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set
1348 * operation, switch back to the original core, and return the new value.
1349 *
1350 * When using the silicon backplane, no fiddling with interrupts or core
1351 * switches is needed.
1352 *
1353 * Also, when using pci/pcie, we can optimize away the core switching for pci
1354 * registers and (on newer pci cores) chipcommon registers.
1355 */
1356uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
1357 uint val)
1358{
1359 uint origidx = 0;
1360 u32 __iomem *r = NULL;
1361 uint w;
1362 uint intr_val = 0;
1363 bool fast = false;
1364 struct si_info *sii;
1365
1366 sii = (struct si_info *)sih;
1367
1368 if (coreidx >= SI_MAXCORES)
1369 return 0;
1370
1371 /*
1372 * If pci/pcie, we can get at pci/pcie regs
1373 * and on newer cores to chipc
1374 */
1375 if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
1376 /* Chipc registers are mapped at 12KB */
1377 fast = true;
1378 r = (u32 __iomem *)((__iomem char *)sii->curmap +
1379 PCI_16KB0_CCREGS_OFFSET + regoff);
1380 } else if (sii->pub.buscoreidx == coreidx) {
1381 /*
1382 * pci registers are at either in the last 2KB of
1383 * an 8KB window or, in pcie and pci rev 13 at 8KB
1384 */
1385 fast = true;
1386 if (SI_FAST(sii))
1387 r = (u32 __iomem *)((__iomem char *)sii->curmap +
1388 PCI_16KB0_PCIREGS_OFFSET + regoff);
1389 else
1390 r = (u32 __iomem *)((__iomem char *)sii->curmap +
1391 ((regoff >= SBCONFIGOFF) ?
1392 PCI_BAR0_PCISBR_OFFSET :
1393 PCI_BAR0_PCIREGS_OFFSET) + regoff);
1394 }
1395
1396 if (!fast) {
1397 INTR_OFF(sii, intr_val);
1398
1399 /* save current core index */
1400 origidx = ai_coreidx(&sii->pub);
1401
1402 /* switch core */
1403 r = (u32 __iomem *) ((unsigned char __iomem *)
1404 ai_setcoreidx(&sii->pub, coreidx) + regoff);
1405 }
1406
1407 /* mask and set */
1408 if (mask || val) {
1409 w = (R_REG(r) & ~mask) | val;
1410 W_REG(r, w);
1411 }
1412
1413 /* readback */
1414 w = R_REG(r);
1415
1416 if (!fast) {
1417 /* restore core index */
1418 if (origidx != coreidx)
1419 ai_setcoreidx(&sii->pub, origidx);
1420
1421 INTR_RESTORE(sii, intr_val);
1422 }
1423
1424 return w;
1425}
1426
1427void ai_core_disable(struct si_pub *sih, u32 bits)
1428{
1429 struct si_info *sii;
1430 u32 dummy;
1431 struct aidmp *ai;
1432
1433 sii = (struct si_info *)sih;
1434
1435 ai = sii->curwrap;
1436
1437 /* if core is already in reset, just return */
1438 if (R_REG(&ai->resetctrl) & AIRC_RESET)
1439 return;
1440
1441 W_REG(&ai->ioctrl, bits);
1442 dummy = R_REG(&ai->ioctrl);
1443 udelay(10);
1444
1445 W_REG(&ai->resetctrl, AIRC_RESET);
1446 udelay(1);
1447}
1448
1449/* reset and re-enable a core
1450 * inputs:
1451 * bits - core specific bits that are set during and after reset sequence
1452 * resetbits - core specific bits that are set only during reset sequence
1453 */
1454void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits)
1455{
1456 struct si_info *sii;
1457 struct aidmp *ai;
1458 u32 dummy;
1459
1460 sii = (struct si_info *)sih;
1461 ai = sii->curwrap;
1462
1463 /*
1464 * Must do the disable sequence first to work
1465 * for arbitrary current core state.
1466 */
1467 ai_core_disable(sih, (bits | resetbits));
1468
1469 /*
1470 * Now do the initialization sequence.
1471 */
1472 W_REG(&ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN));
1473 dummy = R_REG(&ai->ioctrl);
1474 W_REG(&ai->resetctrl, 0);
1475 udelay(1);
1476
1477 W_REG(&ai->ioctrl, (bits | SICF_CLOCK_EN));
1478 dummy = R_REG(&ai->ioctrl);
1479 udelay(1);
1480}
1481
1482/* return the slow clock source - LPO, XTAL, or PCI */
1483static uint ai_slowclk_src(struct si_info *sii)
1484{
1485 struct chipcregs __iomem *cc;
1486 u32 val;
1487
1488 if (sii->pub.ccrev < 6) {
1489 pci_read_config_dword(sii->pbus, PCI_GPIO_OUT,
1490 &val);
1491 if (val & PCI_CFG_GPIO_SCS)
1492 return SCC_SS_PCI;
1493 return SCC_SS_XTAL;
1494 } else if (sii->pub.ccrev < 10) {
1495 cc = (struct chipcregs __iomem *)
1496 ai_setcoreidx(&sii->pub, sii->curidx);
1497 return R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK;
1498 } else /* Insta-clock */
1499 return SCC_SS_XTAL;
1500}
1501
1502/*
1503* return the ILP (slowclock) min or max frequency
1504* precondition: we've established the chip has dynamic clk control
1505*/
1506static uint ai_slowclk_freq(struct si_info *sii, bool max_freq,
1507 struct chipcregs __iomem *cc)
1508{
1509 u32 slowclk;
1510 uint div;
1511
1512 slowclk = ai_slowclk_src(sii);
1513 if (sii->pub.ccrev < 6) {
1514 if (slowclk == SCC_SS_PCI)
1515 return max_freq ? (PCIMAXFREQ / 64)
1516 : (PCIMINFREQ / 64);
1517 else
1518 return max_freq ? (XTALMAXFREQ / 32)
1519 : (XTALMINFREQ / 32);
1520 } else if (sii->pub.ccrev < 10) {
1521 div = 4 *
1522 (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >>
1523 SCC_CD_SHIFT) + 1);
1524 if (slowclk == SCC_SS_LPO)
1525 return max_freq ? LPOMAXFREQ : LPOMINFREQ;
1526 else if (slowclk == SCC_SS_XTAL)
1527 return max_freq ? (XTALMAXFREQ / div)
1528 : (XTALMINFREQ / div);
1529 else if (slowclk == SCC_SS_PCI)
1530 return max_freq ? (PCIMAXFREQ / div)
1531 : (PCIMINFREQ / div);
1532 } else {
1533 /* Chipc rev 10 is InstaClock */
1534 div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT;
1535 div = 4 * (div + 1);
1536 return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
1537 }
1538 return 0;
1539}
1540
1541static void
1542ai_clkctl_setdelay(struct si_info *sii, struct chipcregs __iomem *cc)
1543{
1544 uint slowmaxfreq, pll_delay, slowclk;
1545 uint pll_on_delay, fref_sel_delay;
1546
1547 pll_delay = PLL_DELAY;
1548
1549 /*
1550 * If the slow clock is not sourced by the xtal then
1551 * add the xtal_on_delay since the xtal will also be
1552 * powered down by dynamic clk control logic.
1553 */
1554
1555 slowclk = ai_slowclk_src(sii);
1556 if (slowclk != SCC_SS_XTAL)
1557 pll_delay += XTAL_ON_DELAY;
1558
1559 /* Starting with 4318 it is ILP that is used for the delays */
1560 slowmaxfreq =
1561 ai_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? false : true, cc);
1562
1563 pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
1564 fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
1565
1566 W_REG(&cc->pll_on_delay, pll_on_delay);
1567 W_REG(&cc->fref_sel_delay, fref_sel_delay);
1568}
1569
1570/* initialize power control delay registers */
1571void ai_clkctl_init(struct si_pub *sih)
1572{
1573 struct si_info *sii;
1574 uint origidx = 0;
1575 struct chipcregs __iomem *cc;
1576 bool fast;
1577
1578 if (!(sih->cccaps & CC_CAP_PWR_CTL))
1579 return;
1580
1581 sii = (struct si_info *)sih;
1582 fast = SI_FAST(sii);
1583 if (!fast) {
1584 origidx = sii->curidx;
1585 cc = (struct chipcregs __iomem *)
1586 ai_setcore(sih, CC_CORE_ID, 0);
1587 if (cc == NULL)
1588 return;
1589 } else {
1590 cc = (struct chipcregs __iomem *) CCREGS_FAST(sii);
1591 if (cc == NULL)
1592 return;
1593 }
1594
1595 /* set all Instaclk chip ILP to 1 MHz */
1596 if (sih->ccrev >= 10)
1597 SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK,
1598 (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
1599
1600 ai_clkctl_setdelay(sii, cc);
1601
1602 if (!fast)
1603 ai_setcoreidx(sih, origidx);
1604}
1605
1606/*
1607 * return the value suitable for writing to the
1608 * dot11 core FAST_PWRUP_DELAY register
1609 */
1610u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih)
1611{
1612 struct si_info *sii;
1613 uint origidx = 0;
1614 struct chipcregs __iomem *cc;
1615 uint slowminfreq;
1616 u16 fpdelay;
1617 uint intr_val = 0;
1618 bool fast;
1619
1620 sii = (struct si_info *)sih;
1621 if (sih->cccaps & CC_CAP_PMU) {
1622 INTR_OFF(sii, intr_val);
1623 fpdelay = si_pmu_fast_pwrup_delay(sih);
1624 INTR_RESTORE(sii, intr_val);
1625 return fpdelay;
1626 }
1627
1628 if (!(sih->cccaps & CC_CAP_PWR_CTL))
1629 return 0;
1630
1631 fast = SI_FAST(sii);
1632 fpdelay = 0;
1633 if (!fast) {
1634 origidx = sii->curidx;
1635 INTR_OFF(sii, intr_val);
1636 cc = (struct chipcregs __iomem *)
1637 ai_setcore(sih, CC_CORE_ID, 0);
1638 if (cc == NULL)
1639 goto done;
1640 } else {
1641 cc = (struct chipcregs __iomem *) CCREGS_FAST(sii);
1642 if (cc == NULL)
1643 goto done;
1644 }
1645
1646 slowminfreq = ai_slowclk_freq(sii, false, cc);
1647 fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) +
1648 (slowminfreq - 1)) / slowminfreq;
1649
1650 done:
1651 if (!fast) {
1652 ai_setcoreidx(sih, origidx);
1653 INTR_RESTORE(sii, intr_val);
1654 }
1655 return fpdelay;
1656}
1657
1658/* turn primary xtal and/or pll off/on */
1659int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on)
1660{
1661 struct si_info *sii;
1662 u32 in, out, outen;
1663
1664 sii = (struct si_info *)sih;
1665
1666 /* pcie core doesn't have any mapping to control the xtal pu */
1667 if (PCIE(sii))
1668 return -1;
1669
1670 pci_read_config_dword(sii->pbus, PCI_GPIO_IN, &in);
1671 pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, &out);
1672 pci_read_config_dword(sii->pbus, PCI_GPIO_OUTEN, &outen);
1673
1674 /*
1675 * Avoid glitching the clock if GPRS is already using it.
1676 * We can't actually read the state of the PLLPD so we infer it
1677 * by the value of XTAL_PU which *is* readable via gpioin.
1678 */
1679 if (on && (in & PCI_CFG_GPIO_XTAL))
1680 return 0;
1681
1682 if (what & XTAL)
1683 outen |= PCI_CFG_GPIO_XTAL;
1684 if (what & PLL)
1685 outen |= PCI_CFG_GPIO_PLL;
1686
1687 if (on) {
1688 /* turn primary xtal on */
1689 if (what & XTAL) {
1690 out |= PCI_CFG_GPIO_XTAL;
1691 if (what & PLL)
1692 out |= PCI_CFG_GPIO_PLL;
1693 pci_write_config_dword(sii->pbus,
1694 PCI_GPIO_OUT, out);
1695 pci_write_config_dword(sii->pbus,
1696 PCI_GPIO_OUTEN, outen);
1697 udelay(XTAL_ON_DELAY);
1698 }
1699
1700 /* turn pll on */
1701 if (what & PLL) {
1702 out &= ~PCI_CFG_GPIO_PLL;
1703 pci_write_config_dword(sii->pbus,
1704 PCI_GPIO_OUT, out);
1705 mdelay(2);
1706 }
1707 } else {
1708 if (what & XTAL)
1709 out &= ~PCI_CFG_GPIO_XTAL;
1710 if (what & PLL)
1711 out |= PCI_CFG_GPIO_PLL;
1712 pci_write_config_dword(sii->pbus,
1713 PCI_GPIO_OUT, out);
1714 pci_write_config_dword(sii->pbus,
1715 PCI_GPIO_OUTEN, outen);
1716 }
1717
1718 return 0;
1719}
1720
1721/* clk control mechanism through chipcommon, no policy checking */
1722static bool _ai_clkctl_cc(struct si_info *sii, uint mode)
1723{
1724 uint origidx = 0;
1725 struct chipcregs __iomem *cc;
1726 u32 scc;
1727 uint intr_val = 0;
1728 bool fast = SI_FAST(sii);
1729
1730 /* chipcommon cores prior to rev6 don't support dynamic clock control */
1731 if (sii->pub.ccrev < 6)
1732 return false;
1733
1734 if (!fast) {
1735 INTR_OFF(sii, intr_val);
1736 origidx = sii->curidx;
1737 cc = (struct chipcregs __iomem *)
1738 ai_setcore(&sii->pub, CC_CORE_ID, 0);
1739 } else {
1740 cc = (struct chipcregs __iomem *) CCREGS_FAST(sii);
1741 if (cc == NULL)
1742 goto done;
1743 }
1744
1745 if (!(sii->pub.cccaps & CC_CAP_PWR_CTL) && (sii->pub.ccrev < 20))
1746 goto done;
1747
1748 switch (mode) {
1749 case CLK_FAST: /* FORCEHT, fast (pll) clock */
1750 if (sii->pub.ccrev < 10) {
1751 /*
1752 * don't forget to force xtal back
1753 * on before we clear SCC_DYN_XTAL..
1754 */
1755 ai_clkctl_xtal(&sii->pub, XTAL, ON);
1756 SET_REG(&cc->slow_clk_ctl,
1757 (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
1758 } else if (sii->pub.ccrev < 20) {
1759 OR_REG(&cc->system_clk_ctl, SYCC_HR);
1760 } else {
1761 OR_REG(&cc->clk_ctl_st, CCS_FORCEHT);
1762 }
1763
1764 /* wait for the PLL */
1765 if (sii->pub.cccaps & CC_CAP_PMU) {
1766 u32 htavail = CCS_HTAVAIL;
1767 SPINWAIT(((R_REG(&cc->clk_ctl_st) & htavail)
1768 == 0), PMU_MAX_TRANSITION_DLY);
1769 } else {
1770 udelay(PLL_DELAY);
1771 }
1772 break;
1773
1774 case CLK_DYNAMIC: /* enable dynamic clock control */
1775 if (sii->pub.ccrev < 10) {
1776 scc = R_REG(&cc->slow_clk_ctl);
1777 scc &= ~(SCC_FS | SCC_IP | SCC_XC);
1778 if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
1779 scc |= SCC_XC;
1780 W_REG(&cc->slow_clk_ctl, scc);
1781
1782 /*
1783 * for dynamic control, we have to
1784 * release our xtal_pu "force on"
1785 */
1786 if (scc & SCC_XC)
1787 ai_clkctl_xtal(&sii->pub, XTAL, OFF);
1788 } else if (sii->pub.ccrev < 20) {
1789 /* Instaclock */
1790 AND_REG(&cc->system_clk_ctl, ~SYCC_HR);
1791 } else {
1792 AND_REG(&cc->clk_ctl_st, ~CCS_FORCEHT);
1793 }
1794 break;
1795
1796 default:
1797 break;
1798 }
1799
1800 done:
1801 if (!fast) {
1802 ai_setcoreidx(&sii->pub, origidx);
1803 INTR_RESTORE(sii, intr_val);
1804 }
1805 return mode == CLK_FAST;
1806}
1807
1808/*
1809 * clock control policy function throught chipcommon
1810 *
1811 * set dynamic clk control mode (forceslow, forcefast, dynamic)
1812 * returns true if we are forcing fast clock
1813 * this is a wrapper over the next internal function
1814 * to allow flexible policy settings for outside caller
1815 */
1816bool ai_clkctl_cc(struct si_pub *sih, uint mode)
1817{
1818 struct si_info *sii;
1819
1820 sii = (struct si_info *)sih;
1821
1822 /* chipcommon cores prior to rev6 don't support dynamic clock control */
1823 if (sih->ccrev < 6)
1824 return false;
1825
1826 if (PCI_FORCEHT(sii))
1827 return mode == CLK_FAST;
1828
1829 return _ai_clkctl_cc(sii, mode);
1830}
1831
1832/* Build device path */
1833int ai_devpath(struct si_pub *sih, char *path, int size)
1834{
1835 int slen;
1836
1837 if (!path || size <= 0)
1838 return -1;
1839
1840 slen = snprintf(path, (size_t) size, "pci/%u/%u/",
1841 ((struct si_info *)sih)->pbus->bus->number,
1842 PCI_SLOT(((struct pci_dev *)
1843 (((struct si_info *)(sih))->pbus))->devfn));
1844
1845 if (slen < 0 || slen >= size) {
1846 path[0] = '\0';
1847 return -1;
1848 }
1849
1850 return 0;
1851}
1852
1853void ai_pci_up(struct si_pub *sih)
1854{
1855 struct si_info *sii;
1856
1857 sii = (struct si_info *)sih;
1858
1859 if (PCI_FORCEHT(sii))
1860 _ai_clkctl_cc(sii, CLK_FAST);
1861
1862 if (PCIE(sii))
1863 pcicore_up(sii->pch, SI_PCIUP);
1864
1865}
1866
1867/* Unconfigure and/or apply various WARs when system is going to sleep mode */
1868void ai_pci_sleep(struct si_pub *sih)
1869{
1870 struct si_info *sii;
1871
1872 sii = (struct si_info *)sih;
1873
1874 pcicore_sleep(sii->pch);
1875}
1876
1877/* Unconfigure and/or apply various WARs when going down */
1878void ai_pci_down(struct si_pub *sih)
1879{
1880 struct si_info *sii;
1881
1882 sii = (struct si_info *)sih;
1883
1884 /* release FORCEHT since chip is going to "down" state */
1885 if (PCI_FORCEHT(sii))
1886 _ai_clkctl_cc(sii, CLK_DYNAMIC);
1887
1888 pcicore_down(sii->pch, SI_PCIDOWN);
1889}
1890
1891/*
1892 * Configure the pci core for pci client (NIC) action
1893 * coremask is the bitvec of cores by index to be enabled.
1894 */
1895void ai_pci_setup(struct si_pub *sih, uint coremask)
1896{
1897 struct si_info *sii;
1898 struct sbpciregs __iomem *regs = NULL;
1899 u32 siflag = 0, w;
1900 uint idx = 0;
1901
1902 sii = (struct si_info *)sih;
1903
1904 if (PCI(sii)) {
1905 /* get current core index */
1906 idx = sii->curidx;
1907
1908 /* we interrupt on this backplane flag number */
1909 siflag = ai_flag(sih);
1910
1911 /* switch over to pci core */
1912 regs = ai_setcoreidx(sih, sii->pub.buscoreidx);
1913 }
1914
1915 /*
1916 * Enable sb->pci interrupts. Assume
1917 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
1918 */
1919 if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) {
1920 /* pci config write to set this core bit in PCIIntMask */
1921 pci_read_config_dword(sii->pbus, PCI_INT_MASK, &w);
1922 w |= (coremask << PCI_SBIM_SHIFT);
1923 pci_write_config_dword(sii->pbus, PCI_INT_MASK, w);
1924 } else {
1925 /* set sbintvec bit for our flag number */
1926 ai_setint(sih, siflag);
1927 }
1928
1929 if (PCI(sii)) {
1930 pcicore_pci_setup(sii->pch, regs);
1931
1932 /* switch back to previous core */
1933 ai_setcoreidx(sih, idx);
1934 }
1935}
1936
1937/*
1938 * Fixup SROMless PCI device's configuration.
1939 * The current core may be changed upon return.
1940 */
1941int ai_pci_fixcfg(struct si_pub *sih)
1942{
1943 uint origidx;
1944 void __iomem *regs = NULL;
1945 struct si_info *sii = (struct si_info *)sih;
1946
1947 /* Fixup PI in SROM shadow area to enable the correct PCI core access */
1948 /* save the current index */
1949 origidx = ai_coreidx(&sii->pub);
1950
1951 /* check 'pi' is correct and fix it if not */
1952 regs = ai_setcore(&sii->pub, sii->pub.buscoretype, 0);
1953 if (sii->pub.buscoretype == PCIE_CORE_ID)
1954 pcicore_fixcfg_pcie(sii->pch,
1955 (struct sbpcieregs __iomem *)regs);
1956 else if (sii->pub.buscoretype == PCI_CORE_ID)
1957 pcicore_fixcfg_pci(sii->pch, (struct sbpciregs __iomem *)regs);
1958
1959 /* restore the original index */
1960 ai_setcoreidx(&sii->pub, origidx);
1961
1962 pcicore_hwup(sii->pch);
1963 return 0;
1964}
1965
1966/* mask&set gpiocontrol bits */
1967u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val, u8 priority)
1968{
1969 uint regoff;
1970
1971 regoff = offsetof(struct chipcregs, gpiocontrol);
1972 return ai_corereg(sih, SI_CC_IDX, regoff, mask, val);
1973}
1974
1975void ai_chipcontrl_epa4331(struct si_pub *sih, bool on)
1976{
1977 struct si_info *sii;
1978 struct chipcregs __iomem *cc;
1979 uint origidx;
1980 u32 val;
1981
1982 sii = (struct si_info *)sih;
1983 origidx = ai_coreidx(sih);
1984
1985 cc = (struct chipcregs __iomem *) ai_setcore(sih, CC_CORE_ID, 0);
1986
1987 val = R_REG(&cc->chipcontrol);
1988
1989 if (on) {
1990 if (sih->chippkg == 9 || sih->chippkg == 0xb)
1991 /* Ext PA Controls for 4331 12x9 Package */
1992 W_REG(&cc->chipcontrol, val |
1993 CCTRL4331_EXTPA_EN |
1994 CCTRL4331_EXTPA_ON_GPIO2_5);
1995 else
1996 /* Ext PA Controls for 4331 12x12 Package */
1997 W_REG(&cc->chipcontrol,
1998 val | CCTRL4331_EXTPA_EN);
1999 } else {
2000 val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
2001 W_REG(&cc->chipcontrol, val);
2002 }
2003
2004 ai_setcoreidx(sih, origidx);
2005}
2006
2007/* Enable BT-COEX & Ex-PA for 4313 */
2008void ai_epa_4313war(struct si_pub *sih)
2009{
2010 struct si_info *sii;
2011 struct chipcregs __iomem *cc;
2012 uint origidx;
2013
2014 sii = (struct si_info *)sih;
2015 origidx = ai_coreidx(sih);
2016
2017 cc = ai_setcore(sih, CC_CORE_ID, 0);
2018
2019 /* EPA Fix */
2020 W_REG(&cc->gpiocontrol,
2021 R_REG(&cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
2022
2023 ai_setcoreidx(sih, origidx);
2024}
2025
2026/* check if the device is removed */
2027bool ai_deviceremoved(struct si_pub *sih)
2028{
2029 u32 w;
2030 struct si_info *sii;
2031
2032 sii = (struct si_info *)sih;
2033
2034 pci_read_config_dword(sii->pbus, PCI_VENDOR_ID, &w);
2035 if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
2036 return true;
2037
2038 return false;
2039}
2040
2041bool ai_is_sprom_available(struct si_pub *sih)
2042{
2043 if (sih->ccrev >= 31) {
2044 struct si_info *sii;
2045 uint origidx;
2046 struct chipcregs __iomem *cc;
2047 u32 sromctrl;
2048
2049 if ((sih->cccaps & CC_CAP_SROM) == 0)
2050 return false;
2051
2052 sii = (struct si_info *)sih;
2053 origidx = sii->curidx;
2054 cc = ai_setcoreidx(sih, SI_CC_IDX);
2055 sromctrl = R_REG(&cc->sromcontrol);
2056 ai_setcoreidx(sih, origidx);
2057 return sromctrl & SRC_PRESENT;
2058 }
2059
2060 switch (sih->chip) {
2061 case BCM4313_CHIP_ID:
2062 return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
2063 default:
2064 return true;
2065 }
2066}
2067
2068bool ai_is_otp_disabled(struct si_pub *sih)
2069{
2070 switch (sih->chip) {
2071 case BCM4313_CHIP_ID:
2072 return (sih->chipst & CST4313_OTP_PRESENT) == 0;
2073 /* These chips always have their OTP on */
2074 case BCM43224_CHIP_ID:
2075 case BCM43225_CHIP_ID:
2076 default:
2077 return false;
2078 }
2079}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
new file mode 100644
index 000000000000..106a7424a7cd
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
@@ -0,0 +1,378 @@
1/*
2 * Copyright (c) 2011 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_AIUTILS_H_
18#define _BRCM_AIUTILS_H_
19
20#include "types.h"
21
22/*
23 * SOC Interconnect Address Map.
24 * All regions may not exist on all chips.
25 */
26/* each core gets 4Kbytes for registers */
27#define SI_CORE_SIZE 0x1000
28/*
29 * Max cores (this is arbitrary, for software
30 * convenience and could be changed if we
31 * make any larger chips
32 */
33#define SI_MAXCORES 16
34
35/* Client Mode sb2pcitranslation2 size in bytes */
36#define SI_PCI_DMA_SZ 0x40000000
37
38/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
39#define SI_PCIE_DMA_H32 0x80000000
40
41/* core codes */
42#define NODEV_CORE_ID 0x700 /* Invalid coreid */
43#define CC_CORE_ID 0x800 /* chipcommon core */
44#define ILINE20_CORE_ID 0x801 /* iline20 core */
45#define SRAM_CORE_ID 0x802 /* sram core */
46#define SDRAM_CORE_ID 0x803 /* sdram core */
47#define PCI_CORE_ID 0x804 /* pci core */
48#define MIPS_CORE_ID 0x805 /* mips core */
49#define ENET_CORE_ID 0x806 /* enet mac core */
50#define CODEC_CORE_ID 0x807 /* v90 codec core */
51#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */
52#define ADSL_CORE_ID 0x809 /* ADSL core */
53#define ILINE100_CORE_ID 0x80a /* iline100 core */
54#define IPSEC_CORE_ID 0x80b /* ipsec core */
55#define UTOPIA_CORE_ID 0x80c /* utopia core */
56#define PCMCIA_CORE_ID 0x80d /* pcmcia core */
57#define SOCRAM_CORE_ID 0x80e /* internal memory core */
58#define MEMC_CORE_ID 0x80f /* memc sdram core */
59#define OFDM_CORE_ID 0x810 /* OFDM phy core */
60#define EXTIF_CORE_ID 0x811 /* external interface core */
61#define D11_CORE_ID 0x812 /* 802.11 MAC core */
62#define APHY_CORE_ID 0x813 /* 802.11a phy core */
63#define BPHY_CORE_ID 0x814 /* 802.11b phy core */
64#define GPHY_CORE_ID 0x815 /* 802.11g phy core */
65#define MIPS33_CORE_ID 0x816 /* mips3302 core */
66#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */
67#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */
68#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */
69#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */
70#define SDIOH_CORE_ID 0x81b /* sdio host core */
71#define ROBO_CORE_ID 0x81c /* roboswitch core */
72#define ATA100_CORE_ID 0x81d /* parallel ATA core */
73#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */
74#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */
75#define PCIE_CORE_ID 0x820 /* pci express core */
76#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */
77#define SRAMC_CORE_ID 0x822 /* SRAM controller core */
78#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */
79#define ARM11_CORE_ID 0x824 /* ARM 1176 core */
80#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */
81#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */
82#define PMU_CORE_ID 0x827 /* PMU core */
83#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */
84#define SDIOD_CORE_ID 0x829 /* SDIO device core */
85#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */
86#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */
87#define MIPS74K_CORE_ID 0x82c /* mips 74k core */
88#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */
89#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */
90#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */
91#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */
92#define SC_CORE_ID 0x831 /* shared common core */
93#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */
94#define SPIH_CORE_ID 0x833 /* SPI host core */
95#define I2S_CORE_ID 0x834 /* I2S core */
96#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */
97#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */
98#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */
99#define DEF_AI_COMP 0xfff /* Default component, in ai chips it
100 * maps all unused address ranges
101 */
102
103/* chipcommon being the first core: */
104#define SI_CC_IDX 0
105
106/* SOC Interconnect types (aka chip types) */
107#define SOCI_AI 1
108
109/* Common core control flags */
110#define SICF_BIST_EN 0x8000
111#define SICF_PME_EN 0x4000
112#define SICF_CORE_BITS 0x3ffc
113#define SICF_FGC 0x0002
114#define SICF_CLOCK_EN 0x0001
115
116/* Common core status flags */
117#define SISF_BIST_DONE 0x8000
118#define SISF_BIST_ERROR 0x4000
119#define SISF_GATED_CLK 0x2000
120#define SISF_DMA64 0x1000
121#define SISF_CORE_BITS 0x0fff
122
123/* A register that is common to all cores to
124 * communicate w/PMU regarding clock control.
125 */
126#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */
127
128/* clk_ctl_st register */
129#define CCS_FORCEALP 0x00000001 /* force ALP request */
130#define CCS_FORCEHT 0x00000002 /* force HT request */
131#define CCS_FORCEILP 0x00000004 /* force ILP request */
132#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */
133#define CCS_HTAREQ 0x00000010 /* HT Avail Request */
134#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */
135#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */
136#define CCS_ERSRC_REQ_SHIFT 8
137#define CCS_ALPAVAIL 0x00010000 /* ALP is available */
138#define CCS_HTAVAIL 0x00020000 /* HT is available */
139#define CCS_BP_ON_APL 0x00040000 /* RO: running on ALP clock */
140#define CCS_BP_ON_HT 0x00080000 /* RO: running on HT clock */
141#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */
142#define CCS_ERSRC_STS_SHIFT 24
143
144/* HT avail in chipc and pcmcia on 4328a0 */
145#define CCS0_HTAVAIL 0x00010000
146/* ALP avail in chipc and pcmcia on 4328a0 */
147#define CCS0_ALPAVAIL 0x00020000
148
149/* Not really related to SOC Interconnect, but a couple of software
150 * conventions for the use the flash space:
151 */
152
153/* Minumum amount of flash we support */
154#define FLASH_MIN 0x00020000 /* Minimum flash size */
155
156#define CC_SROM_OTP 0x800 /* SROM/OTP address space */
157
158/* gpiotimerval */
159#define GPIO_ONTIME_SHIFT 16
160
161/* Fields in clkdiv */
162#define CLKD_OTP 0x000f0000
163#define CLKD_OTP_SHIFT 16
164
165/* Package IDs */
166#define BCM4717_PKG_ID 9 /* 4717 package id */
167#define BCM4718_PKG_ID 10 /* 4718 package id */
168#define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */
169
170/* these are router chips */
171#define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */
172#define BCM47162_CHIP_ID 47162 /* 47162 chipcommon chipid */
173#define BCM4748_CHIP_ID 0x4748 /* 4716 chipcommon chipid (OTP, RBBU) */
174
175/* dynamic clock control defines */
176#define LPOMINFREQ 25000 /* low power oscillator min */
177#define LPOMAXFREQ 43000 /* low power oscillator max */
178#define XTALMINFREQ 19800000 /* 20 MHz - 1% */
179#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */
180#define PCIMINFREQ 25000000 /* 25 MHz */
181#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */
182
183#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */
184#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */
185
186/* clkctl xtal what flags */
187#define XTAL 0x1 /* primary crystal oscillator (2050) */
188#define PLL 0x2 /* main chip pll */
189
190/* clkctl clk mode */
191#define CLK_FAST 0 /* force fast (pll) clock */
192#define CLK_DYNAMIC 2 /* enable dynamic clock control */
193
194/* GPIO usage priorities */
195#define GPIO_DRV_PRIORITY 0 /* Driver */
196#define GPIO_APP_PRIORITY 1 /* Application */
197#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO
198 * reservation
199 */
200
201/* GPIO pull up/down */
202#define GPIO_PULLUP 0
203#define GPIO_PULLDN 1
204
205/* GPIO event regtype */
206#define GPIO_REGEVT 0 /* GPIO register event */
207#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */
208#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */
209
210/* device path */
211#define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */
212
213/* SI routine enumeration: to be used by update function with multiple hooks */
214#define SI_DOATTACH 1
215#define SI_PCIDOWN 2
216#define SI_PCIUP 3
217
218/*
219 * Data structure to export all chip specific common variables
220 * public (read-only) portion of aiutils handle returned by si_attach()
221 */
222struct si_pub {
223 uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */
224 uint buscorerev; /* buscore rev */
225 uint buscoreidx; /* buscore index */
226 int ccrev; /* chip common core rev */
227 u32 cccaps; /* chip common capabilities */
228 u32 cccaps_ext; /* chip common capabilities extension */
229 int pmurev; /* pmu core rev */
230 u32 pmucaps; /* pmu capabilities */
231 uint boardtype; /* board type */
232 uint boardvendor; /* board vendor */
233 uint boardflags; /* board flags */
234 uint boardflags2; /* board flags2 */
235 uint chip; /* chip number */
236 uint chiprev; /* chip revision */
237 uint chippkg; /* chip package option */
238 u32 chipst; /* chip status */
239 bool issim; /* chip is in simulation or emulation */
240 uint socirev; /* SOC interconnect rev */
241 bool pci_pr32414;
242
243};
244
245struct pci_dev;
246
247struct gpioh_item {
248 void *arg;
249 bool level;
250 void (*handler) (u32 stat, void *arg);
251 u32 event;
252 struct gpioh_item *next;
253};
254
255/* misc si info needed by some of the routines */
256struct si_info {
257 struct si_pub pub; /* back plane public state (must be first) */
258 struct pci_dev *pbus; /* handle to pci bus */
259 uint dev_coreid; /* the core provides driver functions */
260 void *intr_arg; /* interrupt callback function arg */
261 u32 (*intrsoff_fn) (void *intr_arg); /* turns chip interrupts off */
262 /* restore chip interrupts */
263 void (*intrsrestore_fn) (void *intr_arg, u32 arg);
264 /* check if interrupts are enabled */
265 bool (*intrsenabled_fn) (void *intr_arg);
266
267 struct pcicore_info *pch; /* PCI/E core handle */
268
269 struct list_head var_list; /* list of srom variables */
270
271 void __iomem *curmap; /* current regs va */
272 void __iomem *regs[SI_MAXCORES]; /* other regs va */
273
274 uint curidx; /* current core index */
275 uint numcores; /* # discovered cores */
276 uint coreid[SI_MAXCORES]; /* id of each core */
277 u32 coresba[SI_MAXCORES]; /* backplane address of each core */
278 void *regs2[SI_MAXCORES]; /* 2nd virtual address per core (usbh20) */
279 u32 coresba2[SI_MAXCORES]; /* 2nd phys address per core (usbh20) */
280 u32 coresba_size[SI_MAXCORES]; /* backplane address space size */
281 u32 coresba2_size[SI_MAXCORES]; /* second address space size */
282
283 void *curwrap; /* current wrapper va */
284 void *wrappers[SI_MAXCORES]; /* other cores wrapper va */
285 u32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */
286
287 u32 cia[SI_MAXCORES]; /* erom cia entry for each core */
288 u32 cib[SI_MAXCORES]; /* erom cia entry for each core */
289 u32 oob_router; /* oob router registers for axi */
290};
291
292/*
293 * Many of the routines below take an 'sih' handle as their first arg.
294 * Allocate this by calling si_attach(). Free it by calling si_detach().
295 * At any one time, the sih is logically focused on one particular si core
296 * (the "current core").
297 * Use si_setcore() or si_setcoreidx() to change the association to another core
298 */
299
300
301/* AMBA Interconnect exported externs */
302extern uint ai_flag(struct si_pub *sih);
303extern void ai_setint(struct si_pub *sih, int siflag);
304extern uint ai_coreidx(struct si_pub *sih);
305extern uint ai_corevendor(struct si_pub *sih);
306extern uint ai_corerev(struct si_pub *sih);
307extern bool ai_iscoreup(struct si_pub *sih);
308extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val);
309extern void ai_core_cflags_wo(struct si_pub *sih, u32 mask, u32 val);
310extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val);
311extern uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
312 uint val);
313extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits);
314extern void ai_core_disable(struct si_pub *sih, u32 bits);
315extern int ai_numaddrspaces(struct si_pub *sih);
316extern u32 ai_addrspace(struct si_pub *sih, uint asidx);
317extern u32 ai_addrspacesize(struct si_pub *sih, uint asidx);
318extern void ai_write_wrap_reg(struct si_pub *sih, u32 offset, u32 val);
319
320/* === exported functions === */
321extern struct si_pub *ai_attach(void __iomem *regs, struct pci_dev *sdh);
322extern void ai_detach(struct si_pub *sih);
323extern uint ai_coreid(struct si_pub *sih);
324extern uint ai_corerev(struct si_pub *sih);
325extern uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
326 uint val);
327extern void ai_write_wrapperreg(struct si_pub *sih, u32 offset, u32 val);
328extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val);
329extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val);
330extern bool ai_iscoreup(struct si_pub *sih);
331extern uint ai_findcoreidx(struct si_pub *sih, uint coreid, uint coreunit);
332extern void __iomem *ai_setcoreidx(struct si_pub *sih, uint coreidx);
333extern void __iomem *ai_setcore(struct si_pub *sih, uint coreid, uint coreunit);
334extern void __iomem *ai_switch_core(struct si_pub *sih, uint coreid,
335 uint *origidx, uint *intr_val);
336extern void ai_restore_core(struct si_pub *sih, uint coreid, uint intr_val);
337extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits);
338extern void ai_core_disable(struct si_pub *sih, u32 bits);
339extern u32 ai_alp_clock(struct si_pub *sih);
340extern u32 ai_ilp_clock(struct si_pub *sih);
341extern void ai_pci_setup(struct si_pub *sih, uint coremask);
342extern void ai_setint(struct si_pub *sih, int siflag);
343extern bool ai_backplane64(struct si_pub *sih);
344extern void ai_register_intr_callback(struct si_pub *sih, void *intrsoff_fn,
345 void *intrsrestore_fn,
346 void *intrsenabled_fn, void *intr_arg);
347extern void ai_deregister_intr_callback(struct si_pub *sih);
348extern void ai_clkctl_init(struct si_pub *sih);
349extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih);
350extern bool ai_clkctl_cc(struct si_pub *sih, uint mode);
351extern int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on);
352extern bool ai_deviceremoved(struct si_pub *sih);
353extern u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val,
354 u8 priority);
355
356/* OTP status */
357extern bool ai_is_otp_disabled(struct si_pub *sih);
358
359/* SPROM availability */
360extern bool ai_is_sprom_available(struct si_pub *sih);
361
362/*
363 * Build device path. Path size must be >= SI_DEVPATH_BUFSZ.
364 * The returned path is NULL terminated and has trailing '/'.
365 * Return 0 on success, nonzero otherwise.
366 */
367extern int ai_devpath(struct si_pub *sih, char *path, int size);
368
369extern void ai_pci_sleep(struct si_pub *sih);
370extern void ai_pci_down(struct si_pub *sih);
371extern void ai_pci_up(struct si_pub *sih);
372extern int ai_pci_fixcfg(struct si_pub *sih);
373
374extern void ai_chipcontrl_epa4331(struct si_pub *sih, bool on);
375/* Enable Ex-PA for 4313 */
376extern void ai_epa_4313war(struct si_pub *sih);
377
378#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 000000000000..7f27dbdb6b60
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -0,0 +1,1241 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <net/mac80211.h>
17
18#include "rate.h"
19#include "scb.h"
20#include "phy/phy_hal.h"
21#include "antsel.h"
22#include "main.h"
23#include "ampdu.h"
24
25/* max number of mpdus in an ampdu */
26#define AMPDU_MAX_MPDU 32
27/* max number of mpdus in an ampdu to a legacy */
28#define AMPDU_NUM_MPDU_LEGACY 16
29/* max Tx ba window size (in pdu) */
30#define AMPDU_TX_BA_MAX_WSIZE 64
31/* default Tx ba window size (in pdu) */
32#define AMPDU_TX_BA_DEF_WSIZE 64
33/* default Rx ba window size (in pdu) */
34#define AMPDU_RX_BA_DEF_WSIZE 64
35/* max Rx ba window size (in pdu) */
36#define AMPDU_RX_BA_MAX_WSIZE 64
37/* max dur of tx ampdu (in msec) */
38#define AMPDU_MAX_DUR 5
39/* default tx retry limit */
40#define AMPDU_DEF_RETRY_LIMIT 5
41/* default tx retry limit at reg rate */
42#define AMPDU_DEF_RR_RETRY_LIMIT 2
43/* default weight of ampdu in txfifo */
44#define AMPDU_DEF_TXPKT_WEIGHT 2
45/* default ffpld reserved bytes */
46#define AMPDU_DEF_FFPLD_RSVD 2048
47/* # of inis to be freed on detach */
48#define AMPDU_INI_FREE 10
49/* max # of mpdus released at a time */
50#define AMPDU_SCB_MAX_RELEASE 20
51
52#define NUM_FFPLD_FIFO 4 /* number of fifo concerned by pre-loading */
53#define FFPLD_TX_MAX_UNFL 200 /* default value of the average number of ampdu
54 * without underflows
55 */
56#define FFPLD_MPDU_SIZE 1800 /* estimate of maximum mpdu size */
57#define FFPLD_MAX_MCS 23 /* we don't deal with mcs 32 */
58#define FFPLD_PLD_INCR 1000 /* increments in bytes */
59#define FFPLD_MAX_AMPDU_CNT 5000 /* maximum number of ampdu we
60 * accumulate between resets.
61 */
62
63#define AMPDU_DELIMITER_LEN 4
64
65/* max allowed number of mpdus in an ampdu (2 streams) */
66#define AMPDU_NUM_MPDU 16
67
68#define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE)
69
70/* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */
71#define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\
72 AMPDU_DELIMITER_LEN + 3\
73 + DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN)
74
75/* modulo add/sub, bound = 2^k */
76#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
77#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
78
79/* structure to hold tx fifo information and pre-loading state
80 * counters specific to tx underflows of ampdus
81 * some counters might be redundant with the ones in wlc or ampdu structures.
82 * This allows to maintain a specific state independently of
83 * how often and/or when the wlc counters are updated.
84 *
85 * ampdu_pld_size: number of bytes to be pre-loaded
86 * mcs2ampdu_table: per-mcs max # of mpdus in an ampdu
87 * prev_txfunfl: num of underflows last read from the HW macstats counter
88 * accum_txfunfl: num of underflows since we modified pld params
89 * accum_txampdu: num of tx ampdu since we modified pld params
90 * prev_txampdu: previous reading of tx ampdu
91 * dmaxferrate: estimated dma avg xfer rate in kbits/sec
92 */
93struct brcms_fifo_info {
94 u16 ampdu_pld_size;
95 u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1];
96 u16 prev_txfunfl;
97 u32 accum_txfunfl;
98 u32 accum_txampdu;
99 u32 prev_txampdu;
100 u32 dmaxferrate;
101};
102
103/* AMPDU module specific state
104 *
105 * wlc: pointer to main wlc structure
106 * scb_handle: scb cubby handle to retrieve data from scb
107 * ini_enable: per-tid initiator enable/disable of ampdu
108 * ba_tx_wsize: Tx ba window size (in pdu)
109 * ba_rx_wsize: Rx ba window size (in pdu)
110 * retry_limit: mpdu transmit retry limit
111 * rr_retry_limit: mpdu transmit retry limit at regular rate
112 * retry_limit_tid: per-tid mpdu transmit retry limit
113 * rr_retry_limit_tid: per-tid mpdu transmit retry limit at regular rate
114 * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec
115 * max_pdu: max pdus allowed in ampdu
116 * dur: max duration of an ampdu (in msec)
117 * txpkt_weight: weight of ampdu in txfifo; reduces rate lag
118 * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes
119 * ffpld_rsvd: number of bytes to reserve for preload
120 * max_txlen: max size of ampdu per mcs, bw and sgi
121 * mfbr: enable multiple fallback rate
122 * tx_max_funl: underflows should be kept such that
123 * (tx_max_funfl*underflows) < tx frames
124 * fifo_tb: table of fifo infos
125 */
126struct ampdu_info {
127 struct brcms_c_info *wlc;
128 int scb_handle;
129 u8 ini_enable[AMPDU_MAX_SCB_TID];
130 u8 ba_tx_wsize;
131 u8 ba_rx_wsize;
132 u8 retry_limit;
133 u8 rr_retry_limit;
134 u8 retry_limit_tid[AMPDU_MAX_SCB_TID];
135 u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID];
136 u8 mpdu_density;
137 s8 max_pdu;
138 u8 dur;
139 u8 txpkt_weight;
140 u8 rx_factor;
141 u32 ffpld_rsvd;
142 u32 max_txlen[MCS_TABLE_SIZE][2][2];
143 bool mfbr;
144 u32 tx_max_funl;
145 struct brcms_fifo_info fifo_tb[NUM_FFPLD_FIFO];
146};
147
148/* used for flushing ampdu packets */
149struct cb_del_ampdu_pars {
150 struct ieee80211_sta *sta;
151 u16 tid;
152};
153
154static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur)
155{
156 u32 rate, mcs;
157
158 for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) {
159 /* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */
160 /* 20MHz, No SGI */
161 rate = mcs_2_rate(mcs, false, false);
162 ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3;
163 /* 40 MHz, No SGI */
164 rate = mcs_2_rate(mcs, true, false);
165 ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3;
166 /* 20MHz, SGI */
167 rate = mcs_2_rate(mcs, false, true);
168 ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3;
169 /* 40 MHz, SGI */
170 rate = mcs_2_rate(mcs, true, true);
171 ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3;
172 }
173}
174
175static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu)
176{
177 if (BRCMS_PHY_11N_CAP(ampdu->wlc->band))
178 return true;
179 else
180 return false;
181}
182
183static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on)
184{
185 struct brcms_c_info *wlc = ampdu->wlc;
186
187 wlc->pub->_ampdu = false;
188
189 if (on) {
190 if (!(wlc->pub->_n_enab & SUPPORT_11N)) {
191 wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not "
192 "nmode enabled\n", wlc->pub->unit);
193 return -ENOTSUPP;
194 }
195 if (!brcms_c_ampdu_cap(ampdu)) {
196 wiphy_err(ampdu->wlc->wiphy, "wl%d: device not "
197 "ampdu capable\n", wlc->pub->unit);
198 return -ENOTSUPP;
199 }
200 wlc->pub->_ampdu = on;
201 }
202
203 return 0;
204}
205
206static void brcms_c_ffpld_init(struct ampdu_info *ampdu)
207{
208 int i, j;
209 struct brcms_fifo_info *fifo;
210
211 for (j = 0; j < NUM_FFPLD_FIFO; j++) {
212 fifo = (ampdu->fifo_tb + j);
213 fifo->ampdu_pld_size = 0;
214 for (i = 0; i <= FFPLD_MAX_MCS; i++)
215 fifo->mcs2ampdu_table[i] = 255;
216 fifo->dmaxferrate = 0;
217 fifo->accum_txampdu = 0;
218 fifo->prev_txfunfl = 0;
219 fifo->accum_txfunfl = 0;
220
221 }
222}
223
224struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc)
225{
226 struct ampdu_info *ampdu;
227 int i;
228
229 ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC);
230 if (!ampdu)
231 return NULL;
232
233 ampdu->wlc = wlc;
234
235 for (i = 0; i < AMPDU_MAX_SCB_TID; i++)
236 ampdu->ini_enable[i] = true;
237 /* Disable ampdu for VO by default */
238 ampdu->ini_enable[PRIO_8021D_VO] = false;
239 ampdu->ini_enable[PRIO_8021D_NC] = false;
240
241 /* Disable ampdu for BK by default since not enough fifo space */
242 ampdu->ini_enable[PRIO_8021D_NONE] = false;
243 ampdu->ini_enable[PRIO_8021D_BK] = false;
244
245 ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE;
246 ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE;
247 ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY;
248 ampdu->max_pdu = AUTO;
249 ampdu->dur = AMPDU_MAX_DUR;
250 ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT;
251
252 ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD;
253 /*
254 * bump max ampdu rcv size to 64k for all 11n
255 * devices except 4321A0 and 4321A1
256 */
257 if (BRCMS_ISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2))
258 ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_32K;
259 else
260 ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_64K;
261 ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT;
262 ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT;
263
264 for (i = 0; i < AMPDU_MAX_SCB_TID; i++) {
265 ampdu->retry_limit_tid[i] = ampdu->retry_limit;
266 ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit;
267 }
268
269 brcms_c_scb_ampdu_update_max_txlen(ampdu, ampdu->dur);
270 ampdu->mfbr = false;
271 /* try to set ampdu to the default value */
272 brcms_c_ampdu_set(ampdu, wlc->pub->_ampdu);
273
274 ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL;
275 brcms_c_ffpld_init(ampdu);
276
277 return ampdu;
278}
279
280void brcms_c_ampdu_detach(struct ampdu_info *ampdu)
281{
282 kfree(ampdu);
283}
284
285static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
286 struct scb *scb)
287{
288 struct scb_ampdu *scb_ampdu = &scb->scb_ampdu;
289 int i;
290
291 scb_ampdu->max_pdu = AMPDU_NUM_MPDU;
292
293 /* go back to legacy size if some preloading is occurring */
294 for (i = 0; i < NUM_FFPLD_FIFO; i++) {
295 if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR)
296 scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY;
297 }
298
299 /* apply user override */
300 if (ampdu->max_pdu != AUTO)
301 scb_ampdu->max_pdu = (u8) ampdu->max_pdu;
302
303 scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu,
304 AMPDU_SCB_MAX_RELEASE);
305
306 if (scb_ampdu->max_rx_ampdu_bytes)
307 scb_ampdu->release = min_t(u8, scb_ampdu->release,
308 scb_ampdu->max_rx_ampdu_bytes / 1600);
309
310 scb_ampdu->release = min(scb_ampdu->release,
311 ampdu->fifo_tb[TX_AC_BE_FIFO].
312 mcs2ampdu_table[FFPLD_MAX_MCS]);
313}
314
315static void brcms_c_scb_ampdu_update_config_all(struct ampdu_info *ampdu)
316{
317 brcms_c_scb_ampdu_update_config(ampdu, &ampdu->wlc->pri_scb);
318}
319
320static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
321{
322 int i;
323 u32 phy_rate, dma_rate, tmp;
324 u8 max_mpdu;
325 struct brcms_fifo_info *fifo = (ampdu->fifo_tb + f);
326
327 /* recompute the dma rate */
328 /* note : we divide/multiply by 100 to avoid integer overflows */
329 max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
330 AMPDU_NUM_MPDU_LEGACY);
331 phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
332 dma_rate =
333 (((phy_rate / 100) *
334 (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
335 / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
336 fifo->dmaxferrate = dma_rate;
337
338 /* fill up the mcs2ampdu table; do not recalc the last mcs */
339 dma_rate = dma_rate >> 7;
340 for (i = 0; i < FFPLD_MAX_MCS; i++) {
341 /* shifting to keep it within integer range */
342 phy_rate = mcs_2_rate(i, true, false) >> 7;
343 if (phy_rate > dma_rate) {
344 tmp = ((fifo->ampdu_pld_size * phy_rate) /
345 ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1;
346 tmp = min_t(u32, tmp, 255);
347 fifo->mcs2ampdu_table[i] = (u8) tmp;
348 }
349 }
350}
351
352/* evaluate the dma transfer rate using the tx underflows as feedback.
353 * If necessary, increase tx fifo preloading. If not enough,
354 * decrease maximum ampdu size for each mcs till underflows stop
355 * Return 1 if pre-loading not active, -1 if not an underflow event,
356 * 0 if pre-loading module took care of the event.
357 */
358static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
359{
360 struct ampdu_info *ampdu = wlc->ampdu;
361 u32 phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
362 u32 txunfl_ratio;
363 u8 max_mpdu;
364 u32 current_ampdu_cnt = 0;
365 u16 max_pld_size;
366 u32 new_txunfl;
367 struct brcms_fifo_info *fifo = (ampdu->fifo_tb + fid);
368 uint xmtfifo_sz;
369 u16 cur_txunfl;
370
371 /* return if we got here for a different reason than underflows */
372 cur_txunfl = brcms_b_read_shm(wlc->hw,
373 M_UCODE_MACSTAT +
374 offsetof(struct macstat, txfunfl[fid]));
375 new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl);
376 if (new_txunfl == 0) {
377 BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n");
378 return -1;
379 }
380 fifo->prev_txfunfl = cur_txunfl;
381
382 if (!ampdu->tx_max_funl)
383 return 1;
384
385 /* check if fifo is big enough */
386 if (brcms_b_xmtfifo_sz_get(wlc->hw, fid, &xmtfifo_sz))
387 return -1;
388
389 if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd)
390 return 1;
391
392 max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd;
393 fifo->accum_txfunfl += new_txunfl;
394
395 /* we need to wait for at least 10 underflows */
396 if (fifo->accum_txfunfl < 10)
397 return 0;
398
399 BCMMSG(wlc->wiphy, "ampdu_count %d tx_underflows %d\n",
400 current_ampdu_cnt, fifo->accum_txfunfl);
401
402 /*
403 compute the current ratio of tx unfl per ampdu.
404 When the current ampdu count becomes too
405 big while the ratio remains small, we reset
406 the current count in order to not
407 introduce too big of a latency in detecting a
408 large amount of tx underflows later.
409 */
410
411 txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl;
412
413 if (txunfl_ratio > ampdu->tx_max_funl) {
414 if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT)
415 fifo->accum_txfunfl = 0;
416
417 return 0;
418 }
419 max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
420 AMPDU_NUM_MPDU_LEGACY);
421
422 /* In case max value max_pdu is already lower than
423 the fifo depth, there is nothing more we can do.
424 */
425
426 if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) {
427 fifo->accum_txfunfl = 0;
428 return 0;
429 }
430
431 if (fifo->ampdu_pld_size < max_pld_size) {
432
433 /* increment by TX_FIFO_PLD_INC bytes */
434 fifo->ampdu_pld_size += FFPLD_PLD_INCR;
435 if (fifo->ampdu_pld_size > max_pld_size)
436 fifo->ampdu_pld_size = max_pld_size;
437
438 /* update scb release size */
439 brcms_c_scb_ampdu_update_config_all(ampdu);
440
441 /*
442 * compute a new dma xfer rate for max_mpdu @ max mcs.
443 * This is the minimum dma rate that can achieve no
444 * underflow condition for the current mpdu size.
445 *
446 * note : we divide/multiply by 100 to avoid integer overflows
447 */
448 fifo->dmaxferrate =
449 (((phy_rate / 100) *
450 (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
451 / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
452
453 BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; "
454 "pre-load size %d\n",
455 fifo->dmaxferrate, fifo->ampdu_pld_size);
456 } else {
457
458 /* decrease ampdu size */
459 if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] > 1) {
460 if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] == 255)
461 fifo->mcs2ampdu_table[FFPLD_MAX_MCS] =
462 AMPDU_NUM_MPDU_LEGACY - 1;
463 else
464 fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1;
465
466 /* recompute the table */
467 brcms_c_ffpld_calc_mcs2ampdu_table(ampdu, fid);
468
469 /* update scb release size */
470 brcms_c_scb_ampdu_update_config_all(ampdu);
471 }
472 }
473 fifo->accum_txfunfl = 0;
474 return 0;
475}
476
477void
478brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
479 u8 ba_wsize, /* negotiated ba window size (in pdu) */
480 uint max_rx_ampdu_bytes) /* from ht_cap in beacon */
481{
482 struct scb_ampdu *scb_ampdu;
483 struct scb_ampdu_tid_ini *ini;
484 struct ampdu_info *ampdu = wlc->ampdu;
485 struct scb *scb = &wlc->pri_scb;
486 scb_ampdu = &scb->scb_ampdu;
487
488 if (!ampdu->ini_enable[tid]) {
489 wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
490 __func__, tid);
491 return;
492 }
493
494 ini = &scb_ampdu->ini[tid];
495 ini->tid = tid;
496 ini->scb = scb_ampdu->scb;
497 ini->ba_wsize = ba_wsize;
498 scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes;
499}
500
501int
502brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
503 struct sk_buff **pdu, int prec)
504{
505 struct brcms_c_info *wlc;
506 struct sk_buff *p, *pkt[AMPDU_MAX_MPDU];
507 u8 tid, ndelim;
508 int err = 0;
509 u8 preamble_type = BRCMS_GF_PREAMBLE;
510 u8 fbr_preamble_type = BRCMS_GF_PREAMBLE;
511 u8 rts_preamble_type = BRCMS_LONG_PREAMBLE;
512 u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE;
513
514 bool rr = true, fbr = false;
515 uint i, count = 0, fifo, seg_cnt = 0;
516 u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0;
517 u32 ampdu_len, max_ampdu_bytes = 0;
518 struct d11txh *txh = NULL;
519 u8 *plcp;
520 struct ieee80211_hdr *h;
521 struct scb *scb;
522 struct scb_ampdu *scb_ampdu;
523 struct scb_ampdu_tid_ini *ini;
524 u8 mcs = 0;
525 bool use_rts = false, use_cts = false;
526 u32 rspec = 0, rspec_fallback = 0;
527 u32 rts_rspec = 0, rts_rspec_fallback = 0;
528 u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
529 struct ieee80211_rts *rts;
530 u8 rr_retry_limit;
531 struct brcms_fifo_info *f;
532 bool fbr_iscck;
533 struct ieee80211_tx_info *tx_info;
534 u16 qlen;
535 struct wiphy *wiphy;
536
537 wlc = ampdu->wlc;
538 wiphy = wlc->wiphy;
539 p = *pdu;
540
541 tid = (u8) (p->priority);
542
543 f = ampdu->fifo_tb + prio2fifo[tid];
544
545 scb = &wlc->pri_scb;
546 scb_ampdu = &scb->scb_ampdu;
547 ini = &scb_ampdu->ini[tid];
548
549 /* Let pressure continue to build ... */
550 qlen = pktq_plen(&qi->q, prec);
551 if (ini->tx_in_transit > 0 &&
552 qlen < min(scb_ampdu->max_pdu, ini->ba_wsize))
553 /* Collect multiple MPDU's to be sent in the next AMPDU */
554 return -EBUSY;
555
556 /* at this point we intend to transmit an AMPDU */
557 rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
558 ampdu_len = 0;
559 dma_len = 0;
560 while (p) {
561 struct ieee80211_tx_rate *txrate;
562
563 tx_info = IEEE80211_SKB_CB(p);
564 txrate = tx_info->status.rates;
565
566 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
567 err = brcms_c_prep_pdu(wlc, p, &fifo);
568 } else {
569 wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__);
570 *pdu = NULL;
571 err = 0;
572 break;
573 }
574
575 if (err) {
576 if (err == -EBUSY) {
577 wiphy_err(wiphy, "wl%d: sendampdu: "
578 "prep_xdu retry; seq 0x%x\n",
579 wlc->pub->unit, seq);
580 *pdu = p;
581 break;
582 }
583
584 /* error in the packet; reject it */
585 wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu "
586 "rejected; seq 0x%x\n", wlc->pub->unit, seq);
587 *pdu = NULL;
588 break;
589 }
590
591 /* pkt is good to be aggregated */
592 txh = (struct d11txh *) p->data;
593 plcp = (u8 *) (txh + 1);
594 h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
595 seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
596 index = TX_SEQ_TO_INDEX(seq);
597
598 /* check mcl fields and test whether it can be agg'd */
599 mcl = le16_to_cpu(txh->MacTxControlLow);
600 mcl &= ~TXC_AMPDU_MASK;
601 fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3);
602 txh->PreloadSize = 0; /* always default to 0 */
603
604 /* Handle retry limits */
605 if (txrate[0].count <= rr_retry_limit) {
606 txrate[0].count++;
607 rr = true;
608 fbr = false;
609 } else {
610 fbr = true;
611 rr = false;
612 txrate[1].count++;
613 }
614
615 /* extract the length info */
616 len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
617 : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
618
619 /* retrieve null delimiter count */
620 ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
621 seg_cnt += 1;
622
623 BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n",
624 wlc->pub->unit, count, len);
625
626 /*
627 * aggregateable mpdu. For ucode/hw agg,
628 * test whether need to break or change the epoch
629 */
630 if (count == 0) {
631 mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
632 /* refill the bits since might be a retx mpdu */
633 mcl |= TXC_STARTMSDU;
634 rts = (struct ieee80211_rts *)&txh->rts_frame;
635
636 if (ieee80211_is_rts(rts->frame_control)) {
637 mcl |= TXC_SENDRTS;
638 use_rts = true;
639 }
640 if (ieee80211_is_cts(rts->frame_control)) {
641 mcl |= TXC_SENDCTS;
642 use_cts = true;
643 }
644 } else {
645 mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
646 mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
647 }
648
649 len = roundup(len, 4);
650 ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN);
651
652 dma_len += (u16) brcmu_pkttotlen(p);
653
654 BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d"
655 " seg_cnt %d null delim %d\n",
656 wlc->pub->unit, ampdu_len, seg_cnt, ndelim);
657
658 txh->MacTxControlLow = cpu_to_le16(mcl);
659
660 /* this packet is added */
661 pkt[count++] = p;
662
663 /* patch the first MPDU */
664 if (count == 1) {
665 u8 plcp0, plcp3, is40, sgi;
666 struct ieee80211_sta *sta;
667
668 sta = tx_info->control.sta;
669
670 if (rr) {
671 plcp0 = plcp[0];
672 plcp3 = plcp[3];
673 } else {
674 plcp0 = txh->FragPLCPFallback[0];
675 plcp3 = txh->FragPLCPFallback[3];
676
677 }
678 is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
679 sgi = plcp3_issgi(plcp3) ? 1 : 0;
680 mcs = plcp0 & ~MIMO_PLCP_40MHZ;
681 max_ampdu_bytes =
682 min(scb_ampdu->max_rx_ampdu_bytes,
683 ampdu->max_txlen[mcs][is40][sgi]);
684
685 if (is40)
686 mimo_ctlchbw =
687 CHSPEC_SB_UPPER(wlc_phy_chanspec_get(
688 wlc->band->pi))
689 ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
690
691 /* rebuild the rspec and rspec_fallback */
692 rspec = RSPEC_MIMORATE;
693 rspec |= plcp[0] & ~MIMO_PLCP_40MHZ;
694 if (plcp[0] & MIMO_PLCP_40MHZ)
695 rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
696
697 if (fbr_iscck) /* CCK */
698 rspec_fallback = cck_rspec(cck_phy2mac_rate
699 (txh->FragPLCPFallback[0]));
700 else { /* MIMO */
701 rspec_fallback = RSPEC_MIMORATE;
702 rspec_fallback |=
703 txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ;
704 if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ)
705 rspec_fallback |=
706 (PHY_TXC1_BW_40MHZ <<
707 RSPEC_BW_SHIFT);
708 }
709
710 if (use_rts || use_cts) {
711 rts_rspec =
712 brcms_c_rspec_to_rts_rspec(wlc,
713 rspec, false, mimo_ctlchbw);
714 rts_rspec_fallback =
715 brcms_c_rspec_to_rts_rspec(wlc,
716 rspec_fallback, false, mimo_ctlchbw);
717 }
718 }
719
720 /* if (first mpdu for host agg) */
721 /* test whether to add more */
722 if ((mcs_2_rate(mcs, true, false) >= f->dmaxferrate) &&
723 (count == f->mcs2ampdu_table[mcs])) {
724 BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping"
725 " ampdu at %d for mcs %d\n",
726 wlc->pub->unit, count, mcs);
727 break;
728 }
729
730 if (count == scb_ampdu->max_pdu)
731 break;
732
733 /*
734 * check to see if the next pkt is
735 * a candidate for aggregation
736 */
737 p = pktq_ppeek(&qi->q, prec);
738 /* tx_info must be checked with current p */
739 tx_info = IEEE80211_SKB_CB(p);
740
741 if (p) {
742 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
743 ((u8) (p->priority) == tid)) {
744
745 plen = brcmu_pkttotlen(p) +
746 AMPDU_MAX_MPDU_OVERHEAD;
747 plen = max(scb_ampdu->min_len, plen);
748
749 if ((plen + ampdu_len) > max_ampdu_bytes) {
750 p = NULL;
751 continue;
752 }
753
754 /*
755 * check if there are enough
756 * descriptors available
757 */
758 if (*wlc->core->txavail[fifo] <= seg_cnt + 1) {
759 wiphy_err(wiphy, "%s: No fifo space "
760 "!!\n", __func__);
761 p = NULL;
762 continue;
763 }
764 p = brcmu_pktq_pdeq(&qi->q, prec);
765 } else {
766 p = NULL;
767 }
768 }
769 } /* end while(p) */
770
771 ini->tx_in_transit += count;
772
773 if (count) {
774 /* patch up the last txh */
775 txh = (struct d11txh *) pkt[count - 1]->data;
776 mcl = le16_to_cpu(txh->MacTxControlLow);
777 mcl &= ~TXC_AMPDU_MASK;
778 mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
779 txh->MacTxControlLow = cpu_to_le16(mcl);
780
781 /* remove the null delimiter after last mpdu */
782 ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
783 txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
784 ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
785
786 /* remove the pad len from last mpdu */
787 fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
788 len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
789 : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
790 ampdu_len -= roundup(len, 4) - len;
791
792 /* patch up the first txh & plcp */
793 txh = (struct d11txh *) pkt[0]->data;
794 plcp = (u8 *) (txh + 1);
795
796 BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len);
797 /* mark plcp to indicate ampdu */
798 BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
799
800 /* reset the mixed mode header durations */
801 if (txh->MModeLen) {
802 u16 mmodelen =
803 brcms_c_calc_lsig_len(wlc, rspec, ampdu_len);
804 txh->MModeLen = cpu_to_le16(mmodelen);
805 preamble_type = BRCMS_MM_PREAMBLE;
806 }
807 if (txh->MModeFbrLen) {
808 u16 mmfbrlen =
809 brcms_c_calc_lsig_len(wlc, rspec_fallback,
810 ampdu_len);
811 txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
812 fbr_preamble_type = BRCMS_MM_PREAMBLE;
813 }
814
815 /* set the preload length */
816 if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
817 dma_len = min(dma_len, f->ampdu_pld_size);
818 txh->PreloadSize = cpu_to_le16(dma_len);
819 } else
820 txh->PreloadSize = 0;
821
822 mch = le16_to_cpu(txh->MacTxControlHigh);
823
824 /* update RTS dur fields */
825 if (use_rts || use_cts) {
826 u16 durid;
827 rts = (struct ieee80211_rts *)&txh->rts_frame;
828 if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
829 TXC_PREAMBLE_RTS_MAIN_SHORT)
830 rts_preamble_type = BRCMS_SHORT_PREAMBLE;
831
832 if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
833 TXC_PREAMBLE_RTS_FB_SHORT)
834 rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE;
835
836 durid =
837 brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec,
838 rspec, rts_preamble_type,
839 preamble_type, ampdu_len,
840 true);
841 rts->duration = cpu_to_le16(durid);
842 durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
843 rts_rspec_fallback,
844 rspec_fallback,
845 rts_fbr_preamble_type,
846 fbr_preamble_type,
847 ampdu_len, true);
848 txh->RTSDurFallback = cpu_to_le16(durid);
849 /* set TxFesTimeNormal */
850 txh->TxFesTimeNormal = rts->duration;
851 /* set fallback rate version of TxFesTimeNormal */
852 txh->TxFesTimeFallback = txh->RTSDurFallback;
853 }
854
855 /* set flag and plcp for fallback rate */
856 if (fbr) {
857 mch |= TXC_AMPDU_FBR;
858 txh->MacTxControlHigh = cpu_to_le16(mch);
859 BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
860 BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
861 }
862
863 BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
864 wlc->pub->unit, count, ampdu_len);
865
866 /* inform rate_sel if it this is a rate probe pkt */
867 frameid = le16_to_cpu(txh->TxFrameID);
868 if (frameid & TXFID_RATE_PROBE_MASK)
869 wiphy_err(wiphy, "%s: XXX what to do with "
870 "TXFID_RATE_PROBE_MASK!?\n", __func__);
871
872 for (i = 0; i < count; i++)
873 brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1),
874 ampdu->txpkt_weight);
875
876 }
877 /* endif (count) */
878 return err;
879}
880
881static void
882brcms_c_ampdu_rate_status(struct brcms_c_info *wlc,
883 struct ieee80211_tx_info *tx_info,
884 struct tx_status *txs, u8 mcs)
885{
886 struct ieee80211_tx_rate *txrate = tx_info->status.rates;
887 int i;
888
889 /* clear the rest of the rates */
890 for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
891 txrate[i].idx = -1;
892 txrate[i].count = 0;
893 }
894}
895
896static void
897brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
898 struct sk_buff *p, struct tx_status *txs,
899 u32 s1, u32 s2)
900{
901 struct scb_ampdu *scb_ampdu;
902 struct brcms_c_info *wlc = ampdu->wlc;
903 struct scb_ampdu_tid_ini *ini;
904 u8 bitmap[8], queue, tid;
905 struct d11txh *txh;
906 u8 *plcp;
907 struct ieee80211_hdr *h;
908 u16 seq, start_seq = 0, bindex, index, mcl;
909 u8 mcs = 0;
910 bool ba_recd = false, ack_recd = false;
911 u8 suc_mpdu = 0, tot_mpdu = 0;
912 uint supr_status;
913 bool update_rate = true, retry = true, tx_error = false;
914 u16 mimoantsel = 0;
915 u8 antselid = 0;
916 u8 retry_limit, rr_retry_limit;
917 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
918 struct wiphy *wiphy = wlc->wiphy;
919
920#ifdef BCMDBG
921 u8 hole[AMPDU_MAX_MPDU];
922 memset(hole, 0, sizeof(hole));
923#endif
924
925 scb_ampdu = &scb->scb_ampdu;
926 tid = (u8) (p->priority);
927
928 ini = &scb_ampdu->ini[tid];
929 retry_limit = ampdu->retry_limit_tid[tid];
930 rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
931 memset(bitmap, 0, sizeof(bitmap));
932 queue = txs->frameid & TXFID_QUEUE_MASK;
933 supr_status = txs->status & TX_STATUS_SUPR_MASK;
934
935 if (txs->status & TX_STATUS_ACK_RCV) {
936 if (TX_STATUS_SUPR_UF == supr_status)
937 update_rate = false;
938
939 WARN_ON(!(txs->status & TX_STATUS_INTERMEDIATE));
940 start_seq = txs->sequence >> SEQNUM_SHIFT;
941 bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >>
942 TX_STATUS_BA_BMAP03_SHIFT;
943
944 WARN_ON(s1 & TX_STATUS_INTERMEDIATE);
945 WARN_ON(!(s1 & TX_STATUS_AMPDU));
946
947 bitmap[0] |=
948 (s1 & TX_STATUS_BA_BMAP47_MASK) <<
949 TX_STATUS_BA_BMAP47_SHIFT;
950 bitmap[1] = (s1 >> 8) & 0xff;
951 bitmap[2] = (s1 >> 16) & 0xff;
952 bitmap[3] = (s1 >> 24) & 0xff;
953
954 bitmap[4] = s2 & 0xff;
955 bitmap[5] = (s2 >> 8) & 0xff;
956 bitmap[6] = (s2 >> 16) & 0xff;
957 bitmap[7] = (s2 >> 24) & 0xff;
958
959 ba_recd = true;
960 } else {
961 if (supr_status) {
962 update_rate = false;
963 if (supr_status == TX_STATUS_SUPR_BADCH) {
964 wiphy_err(wiphy, "%s: Pkt tx suppressed, "
965 "illegal channel possibly %d\n",
966 __func__, CHSPEC_CHANNEL(
967 wlc->default_bss->chanspec));
968 } else {
969 if (supr_status != TX_STATUS_SUPR_FRAG)
970 wiphy_err(wiphy, "%s:"
971 "supr_status 0x%x\n",
972 __func__, supr_status);
973 }
974 /* no need to retry for badch; will fail again */
975 if (supr_status == TX_STATUS_SUPR_BADCH ||
976 supr_status == TX_STATUS_SUPR_EXPTIME) {
977 retry = false;
978 } else if (supr_status == TX_STATUS_SUPR_EXPTIME) {
979 /* TX underflow:
980 * try tuning pre-loading or ampdu size
981 */
982 } else if (supr_status == TX_STATUS_SUPR_FRAG) {
983 /*
984 * if there were underflows, but pre-loading
985 * is not active, notify rate adaptation.
986 */
987 if (brcms_c_ffpld_check_txfunfl(wlc,
988 prio2fifo[tid]) > 0)
989 tx_error = true;
990 }
991 } else if (txs->phyerr) {
992 update_rate = false;
993 wiphy_err(wiphy, "wl%d: ampdu tx phy "
994 "error (0x%x)\n", wlc->pub->unit,
995 txs->phyerr);
996
997 if (brcm_msg_level & LOG_ERROR_VAL) {
998 brcmu_prpkt("txpkt (AMPDU)", p);
999 brcms_c_print_txdesc((struct d11txh *) p->data);
1000 }
1001 brcms_c_print_txstatus(txs);
1002 }
1003 }
1004
1005 /* loop through all pkts and retry if not acked */
1006 while (p) {
1007 tx_info = IEEE80211_SKB_CB(p);
1008 txh = (struct d11txh *) p->data;
1009 mcl = le16_to_cpu(txh->MacTxControlLow);
1010 plcp = (u8 *) (txh + 1);
1011 h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
1012 seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
1013
1014 if (tot_mpdu == 0) {
1015 mcs = plcp[0] & MIMO_PLCP_MCS_MASK;
1016 mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel);
1017 }
1018
1019 index = TX_SEQ_TO_INDEX(seq);
1020 ack_recd = false;
1021 if (ba_recd) {
1022 bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
1023 BCMMSG(wlc->wiphy, "tid %d seq %d,"
1024 " start_seq %d, bindex %d set %d, index %d\n",
1025 tid, seq, start_seq, bindex,
1026 isset(bitmap, bindex), index);
1027 /* if acked then clear bit and free packet */
1028 if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
1029 && isset(bitmap, bindex)) {
1030 ini->tx_in_transit--;
1031 ini->txretry[index] = 0;
1032
1033 /*
1034 * ampdu_ack_len:
1035 * number of acked aggregated frames
1036 */
1037 /* ampdu_len: number of aggregated frames */
1038 brcms_c_ampdu_rate_status(wlc, tx_info, txs,
1039 mcs);
1040 tx_info->flags |= IEEE80211_TX_STAT_ACK;
1041 tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
1042 tx_info->status.ampdu_ack_len =
1043 tx_info->status.ampdu_len = 1;
1044
1045 skb_pull(p, D11_PHY_HDR_LEN);
1046 skb_pull(p, D11_TXH_LEN);
1047
1048 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
1049 p);
1050 ack_recd = true;
1051 suc_mpdu++;
1052 }
1053 }
1054 /* either retransmit or send bar if ack not recd */
1055 if (!ack_recd) {
1056 struct ieee80211_tx_rate *txrate =
1057 tx_info->status.rates;
1058 if (retry && (txrate[0].count < (int)retry_limit)) {
1059 ini->txretry[index]++;
1060 ini->tx_in_transit--;
1061 /*
1062 * Use high prededence for retransmit to
1063 * give some punch
1064 */
1065 /* brcms_c_txq_enq(wlc, scb, p,
1066 * BRCMS_PRIO_TO_PREC(tid)); */
1067 brcms_c_txq_enq(wlc, scb, p,
1068 BRCMS_PRIO_TO_HI_PREC(tid));
1069 } else {
1070 /* Retry timeout */
1071 ini->tx_in_transit--;
1072 ieee80211_tx_info_clear_status(tx_info);
1073 tx_info->status.ampdu_ack_len = 0;
1074 tx_info->status.ampdu_len = 1;
1075 tx_info->flags |=
1076 IEEE80211_TX_STAT_AMPDU_NO_BACK;
1077 skb_pull(p, D11_PHY_HDR_LEN);
1078 skb_pull(p, D11_TXH_LEN);
1079 wiphy_err(wiphy, "%s: BA Timeout, seq %d, in_"
1080 "transit %d\n", "AMPDU status", seq,
1081 ini->tx_in_transit);
1082 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
1083 p);
1084 }
1085 }
1086 tot_mpdu++;
1087
1088 /* break out if last packet of ampdu */
1089 if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
1090 TXC_AMPDU_LAST)
1091 break;
1092
1093 p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
1094 }
1095 brcms_c_send_q(wlc);
1096
1097 /* update rate state */
1098 antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel);
1099
1100 brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
1101}
1102
1103void
1104brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
1105 struct sk_buff *p, struct tx_status *txs)
1106{
1107 struct scb_ampdu *scb_ampdu;
1108 struct brcms_c_info *wlc = ampdu->wlc;
1109 struct scb_ampdu_tid_ini *ini;
1110 u32 s1 = 0, s2 = 0;
1111 struct ieee80211_tx_info *tx_info;
1112
1113 tx_info = IEEE80211_SKB_CB(p);
1114
1115 /* BMAC_NOTE: For the split driver, second level txstatus comes later
1116 * So if the ACK was received then wait for the second level else just
1117 * call the first one
1118 */
1119 if (txs->status & TX_STATUS_ACK_RCV) {
1120 u8 status_delay = 0;
1121
1122 /* wait till the next 8 bytes of txstatus is available */
1123 while (((s1 = R_REG(&wlc->regs->frmtxstatus)) & TXS_V) == 0) {
1124 udelay(1);
1125 status_delay++;
1126 if (status_delay > 10)
1127 return; /* error condition */
1128 }
1129
1130 s2 = R_REG(&wlc->regs->frmtxstatus2);
1131 }
1132
1133 if (scb) {
1134 scb_ampdu = &scb->scb_ampdu;
1135 ini = &scb_ampdu->ini[p->priority];
1136 brcms_c_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
1137 } else {
1138 /* loop through all pkts and free */
1139 u8 queue = txs->frameid & TXFID_QUEUE_MASK;
1140 struct d11txh *txh;
1141 u16 mcl;
1142 while (p) {
1143 tx_info = IEEE80211_SKB_CB(p);
1144 txh = (struct d11txh *) p->data;
1145 mcl = le16_to_cpu(txh->MacTxControlLow);
1146 brcmu_pkt_buf_free_skb(p);
1147 /* break out if last packet of ampdu */
1148 if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
1149 TXC_AMPDU_LAST)
1150 break;
1151 p = dma_getnexttxp(wlc->hw->di[queue],
1152 DMA_RANGE_TRANSMITTED);
1153 }
1154 brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
1155 }
1156}
1157
1158void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc)
1159{
1160 char template[T_RAM_ACCESS_SZ * 2];
1161
1162 /* driver needs to write the ta in the template; ta is at offset 16 */
1163 memset(template, 0, sizeof(template));
1164 memcpy(template, wlc->pub->cur_etheraddr, ETH_ALEN);
1165 brcms_b_write_template_ram(wlc->hw, (T_BA_TPL_BASE + 16),
1166 (T_RAM_ACCESS_SZ * 2),
1167 template);
1168}
1169
1170bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid)
1171{
1172 return wlc->ampdu->ini_enable[tid];
1173}
1174
1175void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu)
1176{
1177 struct brcms_c_info *wlc = ampdu->wlc;
1178
1179 /*
1180 * Extend ucode internal watchdog timer to
1181 * match larger received frames
1182 */
1183 if ((ampdu->rx_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) ==
1184 IEEE80211_HT_MAX_AMPDU_64K) {
1185 brcms_b_write_shm(wlc->hw, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX);
1186 brcms_b_write_shm(wlc->hw, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX);
1187 } else {
1188 brcms_b_write_shm(wlc->hw, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF);
1189 brcms_b_write_shm(wlc->hw, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF);
1190 }
1191}
1192
1193/*
1194 * callback function that helps flushing ampdu packets from a priority queue
1195 */
1196static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a)
1197{
1198 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu);
1199 struct cb_del_ampdu_pars *ampdu_pars =
1200 (struct cb_del_ampdu_pars *)arg_a;
1201 bool rc;
1202
1203 rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false;
1204 rc = rc && (tx_info->control.sta == NULL || ampdu_pars->sta == NULL ||
1205 tx_info->control.sta == ampdu_pars->sta);
1206 rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid);
1207 return rc;
1208}
1209
1210/*
1211 * callback function that helps invalidating ampdu packets in a DMA queue
1212 */
1213static void dma_cb_fn_ampdu(void *txi, void *arg_a)
1214{
1215 struct ieee80211_sta *sta = arg_a;
1216 struct ieee80211_tx_info *tx_info = (struct ieee80211_tx_info *)txi;
1217
1218 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
1219 (tx_info->control.sta == sta || sta == NULL))
1220 tx_info->control.sta = NULL;
1221}
1222
1223/*
1224 * When a remote party is no longer available for ampdu communication, any
1225 * pending tx ampdu packets in the driver have to be flushed.
1226 */
1227void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
1228 struct ieee80211_sta *sta, u16 tid)
1229{
1230 struct brcms_txq_info *qi = wlc->pkt_queue;
1231 struct pktq *pq = &qi->q;
1232 int prec;
1233 struct cb_del_ampdu_pars ampdu_pars;
1234
1235 ampdu_pars.sta = sta;
1236 ampdu_pars.tid = tid;
1237 for (prec = 0; prec < pq->num_prec; prec++)
1238 brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
1239 (void *)&ampdu_pars);
1240 brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);
1241}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
new file mode 100644
index 000000000000..421f4ba7c63c
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_AMPDU_H_
18#define _BRCM_AMPDU_H_
19
20extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc);
21extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu);
22extern int brcms_c_sendampdu(struct ampdu_info *ampdu,
23 struct brcms_txq_info *qi,
24 struct sk_buff **aggp, int prec);
25extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
26 struct sk_buff *p, struct tx_status *txs);
27extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc);
28extern void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu);
29
30#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 000000000000..a47ce25cb9a2
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
@@ -0,0 +1,307 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/slab.h>
18#include <net/mac80211.h>
19
20#include "types.h"
21#include "main.h"
22#include "phy_shim.h"
23#include "antsel.h"
24
25#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */
26#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */
27#define ANT_SELCFG_TX_UNICAST 0 /* unicast tx antenna configuration */
28#define ANT_SELCFG_RX_UNICAST 1 /* unicast rx antenna configuration */
29#define ANT_SELCFG_TX_DEF 2 /* default tx antenna configuration */
30#define ANT_SELCFG_RX_DEF 3 /* default rx antenna configuration */
31
32/* useful macros */
33#define BRCMS_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf)
34#define BRCMS_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf)
35#define BRCMS_ANTIDX_11N(ant) (((BRCMS_ANTSEL_11N_0(ant)) << 2) +\
36 (BRCMS_ANTSEL_11N_1(ant)))
37#define BRCMS_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO)
38#define BRCMS_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK)
39
40/* antenna switch */
41/* defines for no boardlevel antenna diversity */
42#define ANT_SELCFG_DEF_2x2 0x01 /* default antenna configuration */
43
44/* 2x3 antdiv defines and tables for GPIO communication */
45#define ANT_SELCFG_NUM_2x3 3
46#define ANT_SELCFG_DEF_2x3 0x01 /* default antenna configuration */
47
48/* 2x4 antdiv rev4 defines and tables for GPIO communication */
49#define ANT_SELCFG_NUM_2x4 4
50#define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */
51
52static const u16 mimo_2x4_div_antselpat_tbl[] = {
53 0, 0, 0x9, 0xa, /* ant0: 0 ant1: 2,3 */
54 0, 0, 0x5, 0x6, /* ant0: 1 ant1: 2,3 */
55 0, 0, 0, 0, /* n.a. */
56 0, 0, 0, 0 /* n.a. */
57};
58
59static const u8 mimo_2x4_div_antselid_tbl[16] = {
60 0, 0, 0, 0, 0, 2, 3, 0,
61 0, 0, 1, 0, 0, 0, 0, 0 /* pat to antselid */
62};
63
64static const u16 mimo_2x3_div_antselpat_tbl[] = {
65 16, 0, 1, 16, /* ant0: 0 ant1: 1,2 */
66 16, 16, 16, 16, /* n.a. */
67 16, 2, 16, 16, /* ant0: 2 ant1: 1 */
68 16, 16, 16, 16 /* n.a. */
69};
70
71static const u8 mimo_2x3_div_antselid_tbl[16] = {
72 0, 1, 2, 0, 0, 0, 0, 0,
73 0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */
74};
75
76/* boardlevel antenna selection: init antenna selection structure */
77static void
78brcms_c_antsel_init_cfg(struct antsel_info *asi, struct brcms_antselcfg *antsel,
79 bool auto_sel)
80{
81 if (asi->antsel_type == ANTSEL_2x3) {
82 u8 antcfg_def = ANT_SELCFG_DEF_2x3 |
83 ((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0);
84 antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def;
85 antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def;
86 antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def;
87 antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def;
88 antsel->num_antcfg = ANT_SELCFG_NUM_2x3;
89
90 } else if (asi->antsel_type == ANTSEL_2x4) {
91
92 antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4;
93 antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4;
94 antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4;
95 antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4;
96 antsel->num_antcfg = ANT_SELCFG_NUM_2x4;
97
98 } else { /* no antenna selection available */
99
100 antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2;
101 antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2;
102 antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2;
103 antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2;
104 antsel->num_antcfg = 0;
105 }
106}
107
108struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
109{
110 struct antsel_info *asi;
111 struct si_pub *sih = wlc->hw->sih;
112
113 asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
114 if (!asi)
115 return NULL;
116
117 asi->wlc = wlc;
118 asi->pub = wlc->pub;
119 asi->antsel_type = ANTSEL_NA;
120 asi->antsel_avail = false;
121 asi->antsel_antswitch = (u8) getintvar(sih, BRCMS_SROM_ANTSWITCH);
122
123 if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
124 switch (asi->antsel_antswitch) {
125 case ANTSWITCH_TYPE_1:
126 case ANTSWITCH_TYPE_2:
127 case ANTSWITCH_TYPE_3:
128 /* 4321/2 board with 2x3 switch logic */
129 asi->antsel_type = ANTSEL_2x3;
130 /* Antenna selection availability */
131 if (((u16) getintvar(sih, BRCMS_SROM_AA2G) == 7) ||
132 ((u16) getintvar(sih, BRCMS_SROM_AA5G) == 7)) {
133 asi->antsel_avail = true;
134 } else if (
135 (u16) getintvar(sih, BRCMS_SROM_AA2G) == 3 ||
136 (u16) getintvar(sih, BRCMS_SROM_AA5G) == 3) {
137 asi->antsel_avail = false;
138 } else {
139 asi->antsel_avail = false;
140 wiphy_err(wlc->wiphy, "antsel_attach: 2o3 "
141 "board cfg invalid\n");
142 }
143
144 break;
145 default:
146 break;
147 }
148 } else if ((asi->pub->sromrev == 4) &&
149 ((u16) getintvar(sih, BRCMS_SROM_AA2G) == 7) &&
150 ((u16) getintvar(sih, BRCMS_SROM_AA5G) == 0)) {
151 /* hack to match old 4321CB2 cards with 2of3 antenna switch */
152 asi->antsel_type = ANTSEL_2x3;
153 asi->antsel_avail = true;
154 } else if (asi->pub->boardflags2 & BFL2_2X4_DIV) {
155 asi->antsel_type = ANTSEL_2x4;
156 asi->antsel_avail = true;
157 }
158
159 /* Set the antenna selection type for the low driver */
160 brcms_b_antsel_type_set(wlc->hw, asi->antsel_type);
161
162 /* Init (auto/manual) antenna selection */
163 brcms_c_antsel_init_cfg(asi, &asi->antcfg_11n, true);
164 brcms_c_antsel_init_cfg(asi, &asi->antcfg_cur, true);
165
166 return asi;
167}
168
169void brcms_c_antsel_detach(struct antsel_info *asi)
170{
171 kfree(asi);
172}
173
174/*
175 * boardlevel antenna selection:
176 * convert ant_cfg to mimo_antsel (ucode interface)
177 */
178static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg)
179{
180 u8 idx = BRCMS_ANTIDX_11N(BRCMS_ANTSEL_11N(ant_cfg));
181 u16 mimo_antsel = 0;
182
183 if (asi->antsel_type == ANTSEL_2x4) {
184 /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
185 mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf);
186 return mimo_antsel;
187
188 } else if (asi->antsel_type == ANTSEL_2x3) {
189 /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
190 mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf);
191 return mimo_antsel;
192 }
193
194 return mimo_antsel;
195}
196
197/* boardlevel antenna selection: ucode interface control */
198static int brcms_c_antsel_cfgupd(struct antsel_info *asi,
199 struct brcms_antselcfg *antsel)
200{
201 struct brcms_c_info *wlc = asi->wlc;
202 u8 ant_cfg;
203 u16 mimo_antsel;
204
205 /* 1) Update TX antconfig for all frames that are not unicast data
206 * (aka default TX)
207 */
208 ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF];
209 mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
210 brcms_b_write_shm(wlc->hw, M_MIMO_ANTSEL_TXDFLT, mimo_antsel);
211 /*
212 * Update driver stats for currently selected
213 * default tx/rx antenna config
214 */
215 asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg;
216
217 /* 2) Update RX antconfig for all frames that are not unicast data
218 * (aka default RX)
219 */
220 ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF];
221 mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
222 brcms_b_write_shm(wlc->hw, M_MIMO_ANTSEL_RXDFLT, mimo_antsel);
223 /*
224 * Update driver stats for currently selected
225 * default tx/rx antenna config
226 */
227 asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg;
228
229 return 0;
230}
231
232void brcms_c_antsel_init(struct antsel_info *asi)
233{
234 if ((asi->antsel_type == ANTSEL_2x3) ||
235 (asi->antsel_type == ANTSEL_2x4))
236 brcms_c_antsel_cfgupd(asi, &asi->antcfg_11n);
237}
238
239/* boardlevel antenna selection: convert id to ant_cfg */
240static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id)
241{
242 u8 antcfg = ANT_SELCFG_DEF_2x2;
243
244 if (asi->antsel_type == ANTSEL_2x4) {
245 /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
246 antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2));
247 return antcfg;
248
249 } else if (asi->antsel_type == ANTSEL_2x3) {
250 /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
251 antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1));
252 return antcfg;
253 }
254
255 return antcfg;
256}
257
258void
259brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
260 u8 antselid, u8 fbantselid, u8 *antcfg,
261 u8 *fbantcfg)
262{
263 u8 ant;
264
265 /* if use default, assign it and return */
266 if (usedef) {
267 *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF];
268 *fbantcfg = *antcfg;
269 return;
270 }
271
272 if (!sel) {
273 *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
274 *fbantcfg = *antcfg;
275
276 } else {
277 ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
278 if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) {
279 *antcfg = brcms_c_antsel_id2antcfg(asi, antselid);
280 *fbantcfg = brcms_c_antsel_id2antcfg(asi, fbantselid);
281 } else {
282 *antcfg =
283 asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
284 *fbantcfg = *antcfg;
285 }
286 }
287 return;
288}
289
290/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */
291u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel)
292{
293 u8 antselid = 0;
294
295 if (asi->antsel_type == ANTSEL_2x4) {
296 /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
297 antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)];
298 return antselid;
299
300 } else if (asi->antsel_type == ANTSEL_2x3) {
301 /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
302 antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)];
303 return antselid;
304 }
305
306 return antselid;
307}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.h b/drivers/net/wireless/brcm80211/brcmsmac/antsel.h
new file mode 100644
index 000000000000..97ea3881a8ec
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_ANTSEL_H_
18#define _BRCM_ANTSEL_H_
19
20extern struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc);
21extern void brcms_c_antsel_detach(struct antsel_info *asi);
22extern void brcms_c_antsel_init(struct antsel_info *asi);
23extern void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef,
24 bool sel,
25 u8 id, u8 fbid, u8 *antcfg,
26 u8 *fbantcfg);
27extern u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel);
28
29#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 000000000000..52fc9eeb5fa5
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
@@ -0,0 +1,23 @@
1/*
2 * Copyright (c) 2011 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/module.h> /* bug in tracepoint.h, it should include this */
18
19#ifndef __CHECKER__
20#include "mac80211_if.h"
21#define CREATE_TRACE_POINTS
22#include "brcms_trace_events.h"
23#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 000000000000..27dd73eef56d
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
@@ -0,0 +1,92 @@
1/*
2 * Copyright (c) 2011 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#undef TRACE_SYSTEM
18#define TRACE_SYSTEM brcmsmac
19
20#if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ)
21
22#define __TRACE_BRCMSMAC_H
23
24#include <linux/tracepoint.h>
25#include "mac80211_if.h"
26
27#ifndef CONFIG_BRCMDBG
28#undef TRACE_EVENT
29#define TRACE_EVENT(name, proto, ...) \
30static inline void trace_ ## name(proto) {}
31#endif
32
33/*
34 * We define a tracepoint, its arguments, its printk format and its
35 * 'fast binary record' layout.
36 */
37TRACE_EVENT(brcms_timer,
38 /* TPPROTO is the prototype of the function called by this tracepoint */
39 TP_PROTO(struct brcms_timer *t),
40 /*
41 * TPARGS(firstarg, p) are the parameters names, same as found in the
42 * prototype.
43 */
44 TP_ARGS(t),
45 /*
46 * Fast binary tracing: define the trace record via TP_STRUCT__entry().
47 * You can think about it like a regular C structure local variable
48 * definition.
49 */
50 TP_STRUCT__entry(
51 __field(uint, ms)
52 __field(uint, set)
53 __field(uint, periodic)
54 ),
55 TP_fast_assign(
56 __entry->ms = t->ms;
57 __entry->set = t->set;
58 __entry->periodic = t->periodic;
59 ),
60 TP_printk(
61 "ms=%u set=%u periodic=%u",
62 __entry->ms, __entry->set, __entry->periodic
63 )
64);
65
66TRACE_EVENT(brcms_dpc,
67 TP_PROTO(unsigned long data),
68 TP_ARGS(data),
69 TP_STRUCT__entry(
70 __field(unsigned long, data)
71 ),
72 TP_fast_assign(
73 __entry->data = data;
74 ),
75 TP_printk(
76 "data=%p",
77 (void *)__entry->data
78 )
79);
80
81#endif /* __TRACE_BRCMSMAC_H */
82
83#ifdef CONFIG_BRCMDBG
84
85#undef TRACE_INCLUDE_PATH
86#define TRACE_INCLUDE_PATH .
87#undef TRACE_INCLUDE_FILE
88#define TRACE_INCLUDE_FILE brcms_trace_events
89
90#include <trace/define_trace.h>
91
92#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 000000000000..89ad1b7dab8f
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
@@ -0,0 +1,1591 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/types.h>
18#include <net/mac80211.h>
19
20#include <defs.h>
21#include "pub.h"
22#include "phy/phy_hal.h"
23#include "main.h"
24#include "stf.h"
25#include "channel.h"
26
27/* QDB() macro takes a dB value and converts to a quarter dB value */
28#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR)
29
30#define LOCALE_CHAN_01_11 (1<<0)
31#define LOCALE_CHAN_12_13 (1<<1)
32#define LOCALE_CHAN_14 (1<<2)
33#define LOCALE_SET_5G_LOW_JP1 (1<<3) /* 34-48, step 2 */
34#define LOCALE_SET_5G_LOW_JP2 (1<<4) /* 34-46, step 4 */
35#define LOCALE_SET_5G_LOW1 (1<<5) /* 36-48, step 4 */
36#define LOCALE_SET_5G_LOW2 (1<<6) /* 52 */
37#define LOCALE_SET_5G_LOW3 (1<<7) /* 56-64, step 4 */
38#define LOCALE_SET_5G_MID1 (1<<8) /* 100-116, step 4 */
39#define LOCALE_SET_5G_MID2 (1<<9) /* 120-124, step 4 */
40#define LOCALE_SET_5G_MID3 (1<<10) /* 128 */
41#define LOCALE_SET_5G_HIGH1 (1<<11) /* 132-140, step 4 */
42#define LOCALE_SET_5G_HIGH2 (1<<12) /* 149-161, step 4 */
43#define LOCALE_SET_5G_HIGH3 (1<<13) /* 165 */
44#define LOCALE_CHAN_52_140_ALL (1<<14)
45#define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */
46
47#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | \
48 LOCALE_SET_5G_LOW2 | \
49 LOCALE_SET_5G_LOW3)
50#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3)
51#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2)
52#define LOCALE_CHAN_100_140 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | \
53 LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1)
54#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3)
55#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4
56
57#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | \
58 LOCALE_CHAN_12_13 | \
59 LOCALE_CHAN_14)
60
61#define LOCALE_RADAR_SET_NONE 0
62#define LOCALE_RADAR_SET_1 1
63
64#define LOCALE_RESTRICTED_NONE 0
65#define LOCALE_RESTRICTED_SET_2G_SHORT 1
66#define LOCALE_RESTRICTED_CHAN_165 2
67#define LOCALE_CHAN_ALL_5G 3
68#define LOCALE_RESTRICTED_JAPAN_LEGACY 4
69#define LOCALE_RESTRICTED_11D_2G 5
70#define LOCALE_RESTRICTED_11D_5G 6
71#define LOCALE_RESTRICTED_LOW_HI 7
72#define LOCALE_RESTRICTED_12_13_14 8
73
74#define LOCALE_2G_IDX_i 0
75#define LOCALE_5G_IDX_11 0
76#define LOCALE_MIMO_IDX_bn 0
77#define LOCALE_MIMO_IDX_11n 0
78
79/* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */
80#define BRCMS_MAXPWR_TBL_SIZE 6
81/* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */
82#define BRCMS_MAXPWR_MIMO_TBL_SIZE 14
83
84/* power level in group of 2.4GHz band channels:
85 * maxpwr[0] - CCK channels [1]
86 * maxpwr[1] - CCK channels [2-10]
87 * maxpwr[2] - CCK channels [11-14]
88 * maxpwr[3] - OFDM channels [1]
89 * maxpwr[4] - OFDM channels [2-10]
90 * maxpwr[5] - OFDM channels [11-14]
91 */
92
93/* maxpwr mapping to 5GHz band channels:
94 * maxpwr[0] - channels [34-48]
95 * maxpwr[1] - channels [52-60]
96 * maxpwr[2] - channels [62-64]
97 * maxpwr[3] - channels [100-140]
98 * maxpwr[4] - channels [149-165]
99 */
100#define BAND_5G_PWR_LVLS 5 /* 5 power levels for 5G */
101
102#define LC(id) LOCALE_MIMO_IDX_ ## id
103
104#define LC_2G(id) LOCALE_2G_IDX_ ## id
105
106#define LC_5G(id) LOCALE_5G_IDX_ ## id
107
108#define LOCALES(band2, band5, mimo2, mimo5) \
109 {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)}
110
111/* macro to get 2.4 GHz channel group index for tx power */
112#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2))
113#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5))
114
115/* macro to get 5 GHz channel group index for tx power */
116#define CHANNEL_POWER_IDX_5G(c) (((c) < 52) ? 0 : \
117 (((c) < 62) ? 1 : \
118 (((c) < 100) ? 2 : \
119 (((c) < 149) ? 3 : 4))))
120
121#define ISDFS_EU(fl) (((fl) & BRCMS_DFS_EU) == BRCMS_DFS_EU)
122
123struct brcms_cm_band {
124 /* struct locale_info flags */
125 u8 locale_flags;
126 /* List of valid channels in the country */
127 struct brcms_chanvec valid_channels;
128 /* List of restricted use channels */
129 const struct brcms_chanvec *restricted_channels;
130 /* List of radar sensitive channels */
131 const struct brcms_chanvec *radar_channels;
132 u8 PAD[8];
133};
134
135 /* locale per-channel tx power limits for MIMO frames
136 * maxpwr arrays are index by channel for 2.4 GHz limits, and
137 * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel)
138 */
139struct locale_mimo_info {
140 /* tx 20 MHz power limits, qdBm units */
141 s8 maxpwr20[BRCMS_MAXPWR_MIMO_TBL_SIZE];
142 /* tx 40 MHz power limits, qdBm units */
143 s8 maxpwr40[BRCMS_MAXPWR_MIMO_TBL_SIZE];
144 u8 flags;
145};
146
147/* Country names and abbreviations with locale defined from ISO 3166 */
148struct country_info {
149 const u8 locale_2G; /* 2.4G band locale */
150 const u8 locale_5G; /* 5G band locale */
151 const u8 locale_mimo_2G; /* 2.4G mimo info */
152 const u8 locale_mimo_5G; /* 5G mimo info */
153};
154
155struct brcms_cm_info {
156 struct brcms_pub *pub;
157 struct brcms_c_info *wlc;
158 char srom_ccode[BRCM_CNTRY_BUF_SZ]; /* Country Code in SROM */
159 uint srom_regrev; /* Regulatory Rev for the SROM ccode */
160 const struct country_info *country; /* current country def */
161 char ccode[BRCM_CNTRY_BUF_SZ]; /* current internal Country Code */
162 uint regrev; /* current Regulatory Revision */
163 char country_abbrev[BRCM_CNTRY_BUF_SZ]; /* current advertised ccode */
164 /* per-band state (one per phy/radio) */
165 struct brcms_cm_band bandstate[MAXBANDS];
166 /* quiet channels currently for radar sensitivity or 11h support */
167 /* channels on which we cannot transmit */
168 struct brcms_chanvec quiet_channels;
169};
170
171/* locale channel and power info. */
172struct locale_info {
173 u32 valid_channels;
174 /* List of radar sensitive channels */
175 u8 radar_channels;
176 /* List of channels used only if APs are detected */
177 u8 restricted_channels;
178 /* Max tx pwr in qdBm for each sub-band */
179 s8 maxpwr[BRCMS_MAXPWR_TBL_SIZE];
180 /* Country IE advertised max tx pwr in dBm per sub-band */
181 s8 pub_maxpwr[BAND_5G_PWR_LVLS];
182 u8 flags;
183};
184
185/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */
186
187/*
188 * Some common channel sets
189 */
190
191/* No channels */
192static const struct brcms_chanvec chanvec_none = {
193 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 0x00, 0x00, 0x00, 0x00}
197};
198
199/* All 2.4 GHz HW channels */
200static const struct brcms_chanvec chanvec_all_2G = {
201 {0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204 0x00, 0x00, 0x00, 0x00}
205};
206
207/* All 5 GHz HW channels */
208static const struct brcms_chanvec chanvec_all_5G = {
209 {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11,
210 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,
211 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11,
212 0x11, 0x11, 0x11, 0x01}
213};
214
215/*
216 * Radar channel sets
217 */
218
219/* Channels 52 - 64, 100 - 140 */
220static const struct brcms_chanvec radar_set1 = {
221 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, /* 52 - 60 */
222 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, /* 64, 100 - 124 */
223 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 - 140 */
224 0x00, 0x00, 0x00, 0x00}
225};
226
227/*
228 * Restricted channel sets
229 */
230
231/* Channels 34, 38, 42, 46 */
232static const struct brcms_chanvec restricted_set_japan_legacy = {
233 {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
234 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236 0x00, 0x00, 0x00, 0x00}
237};
238
239/* Channels 12, 13 */
240static const struct brcms_chanvec restricted_set_2g_short = {
241 {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00}
245};
246
247/* Channel 165 */
248static const struct brcms_chanvec restricted_chan_165 = {
249 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
252 0x00, 0x00, 0x00, 0x00}
253};
254
255/* Channels 36 - 48 & 149 - 165 */
256static const struct brcms_chanvec restricted_low_hi = {
257 {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
259 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00,
260 0x00, 0x00, 0x00, 0x00}
261};
262
263/* Channels 12 - 14 */
264static const struct brcms_chanvec restricted_set_12_13_14 = {
265 {0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268 0x00, 0x00, 0x00, 0x00}
269};
270
271/* global memory to provide working buffer for expanded locale */
272
273static const struct brcms_chanvec *g_table_radar_set[] = {
274 &chanvec_none,
275 &radar_set1
276};
277
278static const struct brcms_chanvec *g_table_restricted_chan[] = {
279 &chanvec_none, /* restricted_set_none */
280 &restricted_set_2g_short,
281 &restricted_chan_165,
282 &chanvec_all_5G,
283 &restricted_set_japan_legacy,
284 &chanvec_all_2G, /* restricted_set_11d_2G */
285 &chanvec_all_5G, /* restricted_set_11d_5G */
286 &restricted_low_hi,
287 &restricted_set_12_13_14
288};
289
290static const struct brcms_chanvec locale_2g_01_11 = {
291 {0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 0x00, 0x00, 0x00, 0x00}
295};
296
297static const struct brcms_chanvec locale_2g_12_13 = {
298 {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301 0x00, 0x00, 0x00, 0x00}
302};
303
304static const struct brcms_chanvec locale_2g_14 = {
305 {0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308 0x00, 0x00, 0x00, 0x00}
309};
310
311static const struct brcms_chanvec locale_5g_LOW_JP1 = {
312 {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00,
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00}
316};
317
318static const struct brcms_chanvec locale_5g_LOW_JP2 = {
319 {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00}
323};
324
325static const struct brcms_chanvec locale_5g_LOW1 = {
326 {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0x00, 0x00, 0x00}
330};
331
332static const struct brcms_chanvec locale_5g_LOW2 = {
333 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336 0x00, 0x00, 0x00, 0x00}
337};
338
339static const struct brcms_chanvec locale_5g_LOW3 = {
340 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
341 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00}
344};
345
346static const struct brcms_chanvec locale_5g_MID1 = {
347 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00}
351};
352
353static const struct brcms_chanvec locale_5g_MID2 = {
354 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 0x00, 0x00, 0x00, 0x00}
358};
359
360static const struct brcms_chanvec locale_5g_MID3 = {
361 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364 0x00, 0x00, 0x00, 0x00}
365};
366
367static const struct brcms_chanvec locale_5g_HIGH1 = {
368 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371 0x00, 0x00, 0x00, 0x00}
372};
373
374static const struct brcms_chanvec locale_5g_HIGH2 = {
375 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00,
378 0x00, 0x00, 0x00, 0x00}
379};
380
381static const struct brcms_chanvec locale_5g_HIGH3 = {
382 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00}
386};
387
388static const struct brcms_chanvec locale_5g_52_140_ALL = {
389 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,
390 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
391 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00}
393};
394
395static const struct brcms_chanvec locale_5g_HIGH4 = {
396 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
399 0x11, 0x11, 0x11, 0x11}
400};
401
402static const struct brcms_chanvec *g_table_locale_base[] = {
403 &locale_2g_01_11,
404 &locale_2g_12_13,
405 &locale_2g_14,
406 &locale_5g_LOW_JP1,
407 &locale_5g_LOW_JP2,
408 &locale_5g_LOW1,
409 &locale_5g_LOW2,
410 &locale_5g_LOW3,
411 &locale_5g_MID1,
412 &locale_5g_MID2,
413 &locale_5g_MID3,
414 &locale_5g_HIGH1,
415 &locale_5g_HIGH2,
416 &locale_5g_HIGH3,
417 &locale_5g_52_140_ALL,
418 &locale_5g_HIGH4
419};
420
421static void brcms_c_locale_add_channels(struct brcms_chanvec *target,
422 const struct brcms_chanvec *channels)
423{
424 u8 i;
425 for (i = 0; i < sizeof(struct brcms_chanvec); i++)
426 target->vec[i] |= channels->vec[i];
427}
428
429static void brcms_c_locale_get_channels(const struct locale_info *locale,
430 struct brcms_chanvec *channels)
431{
432 u8 i;
433
434 memset(channels, 0, sizeof(struct brcms_chanvec));
435
436 for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) {
437 if (locale->valid_channels & (1 << i))
438 brcms_c_locale_add_channels(channels,
439 g_table_locale_base[i]);
440 }
441}
442
443/*
444 * Locale Definitions - 2.4 GHz
445 */
446static const struct locale_info locale_i = { /* locale i. channel 1 - 13 */
447 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
448 LOCALE_RADAR_SET_NONE,
449 LOCALE_RESTRICTED_SET_2G_SHORT,
450 {QDB(19), QDB(19), QDB(19),
451 QDB(19), QDB(19), QDB(19)},
452 {20, 20, 20, 0},
453 BRCMS_EIRP
454};
455
456/*
457 * Locale Definitions - 5 GHz
458 */
459static const struct locale_info locale_11 = {
460 /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
461 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
462 LOCALE_RADAR_SET_1,
463 LOCALE_RESTRICTED_NONE,
464 {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)},
465 {23, 23, 23, 30, 30},
466 BRCMS_EIRP | BRCMS_DFS_EU
467};
468
469static const struct locale_info *g_locale_2g_table[] = {
470 &locale_i
471};
472
473static const struct locale_info *g_locale_5g_table[] = {
474 &locale_11
475};
476
477/*
478 * MIMO Locale Definitions - 2.4 GHz
479 */
480static const struct locale_mimo_info locale_bn = {
481 {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
482 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
483 QDB(13), QDB(13), QDB(13)},
484 {0, 0, QDB(13), QDB(13), QDB(13),
485 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
486 QDB(13), 0, 0},
487 0
488};
489
490static const struct locale_mimo_info *g_mimo_2g_table[] = {
491 &locale_bn
492};
493
494/*
495 * MIMO Locale Definitions - 5 GHz
496 */
497static const struct locale_mimo_info locale_11n = {
498 { /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)},
499 {QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)},
500 0
501};
502
503static const struct locale_mimo_info *g_mimo_5g_table[] = {
504 &locale_11n
505};
506
507static const struct {
508 char abbrev[BRCM_CNTRY_BUF_SZ]; /* country abbreviation */
509 struct country_info country;
510} cntry_locales[] = {
511 {
512 "X2", LOCALES(i, 11, bn, 11n)}, /* Worldwide RoW 2 */
513};
514
515#ifdef SUPPORT_40MHZ
516/* 20MHz channel info for 40MHz pairing support */
517struct chan20_info {
518 u8 sb;
519 u8 adj_sbs;
520};
521
522/* indicates adjacent channels that are allowed for a 40 Mhz channel and
523 * those that permitted by the HT
524 */
525struct chan20_info chan20_info[] = {
526 /* 11b/11g */
527/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)},
528/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)},
529/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)},
530/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)},
531/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
532/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
533/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
534/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
535/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
536/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)},
537/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)},
538/* 11 */ {12, (CH_LOWER_SB)},
539/* 12 */ {13, (CH_LOWER_SB)},
540/* 13 */ {14, (CH_LOWER_SB)},
541
542/* 11a japan high */
543/* 14 */ {34, (CH_UPPER_SB)},
544/* 15 */ {38, (CH_LOWER_SB)},
545/* 16 */ {42, (CH_LOWER_SB)},
546/* 17 */ {46, (CH_LOWER_SB)},
547
548/* 11a usa low */
549/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)},
550/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)},
551/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)},
552/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)},
553/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)},
554/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)},
555/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)},
556/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)},
557
558/* 11a Europe */
559/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)},
560/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)},
561/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)},
562/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)},
563/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)},
564/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)},
565/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)},
566/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)},
567/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)},
568/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)},
569/* 36 */ {140, (CH_LOWER_SB)},
570
571/* 11a usa high, ref5 only */
572/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */
573/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)},
574/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)},
575/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)},
576/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)},
577/* 41 */ {165, (CH_LOWER_SB)},
578
579/* 11a japan */
580/* 42 */ {184, (CH_UPPER_SB)},
581/* 43 */ {188, (CH_LOWER_SB)},
582/* 44 */ {192, (CH_UPPER_SB)},
583/* 45 */ {196, (CH_LOWER_SB)},
584/* 46 */ {200, (CH_UPPER_SB)},
585/* 47 */ {204, (CH_LOWER_SB)},
586/* 48 */ {208, (CH_UPPER_SB)},
587/* 49 */ {212, (CH_LOWER_SB)},
588/* 50 */ {216, (CH_LOWER_SB)}
589};
590#endif /* SUPPORT_40MHZ */
591
592static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx)
593{
594 if (locale_idx >= ARRAY_SIZE(g_locale_2g_table))
595 return NULL; /* error condition */
596
597 return g_locale_2g_table[locale_idx];
598}
599
600static const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx)
601{
602 if (locale_idx >= ARRAY_SIZE(g_locale_5g_table))
603 return NULL; /* error condition */
604
605 return g_locale_5g_table[locale_idx];
606}
607
608static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx)
609{
610 if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table))
611 return NULL;
612
613 return g_mimo_2g_table[locale_idx];
614}
615
616static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx)
617{
618 if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table))
619 return NULL;
620
621 return g_mimo_5g_table[locale_idx];
622}
623
624static int
625brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm, const char *ccode,
626 char *mapped_ccode, uint *mapped_regrev)
627{
628 return false;
629}
630
631/* Lookup a country info structure from a null terminated country
632 * abbreviation and regrev directly with no translation.
633 */
634static const struct country_info *
635brcms_c_country_lookup_direct(const char *ccode, uint regrev)
636{
637 uint size, i;
638
639 /* Should just return 0 for single locale driver. */
640 /* Keep it this way in case we add more locales. (for now anyway) */
641
642 /*
643 * all other country def arrays are for regrev == 0, so if
644 * regrev is non-zero, fail
645 */
646 if (regrev > 0)
647 return NULL;
648
649 /* find matched table entry from country code */
650 size = ARRAY_SIZE(cntry_locales);
651 for (i = 0; i < size; i++) {
652 if (strcmp(ccode, cntry_locales[i].abbrev) == 0)
653 return &cntry_locales[i].country;
654 }
655 return NULL;
656}
657
658static const struct country_info *
659brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, const char *ccode,
660 char *mapped_ccode, uint *mapped_regrev)
661{
662 struct brcms_c_info *wlc = wlc_cm->wlc;
663 const struct country_info *country;
664 uint srom_regrev = wlc_cm->srom_regrev;
665 const char *srom_ccode = wlc_cm->srom_ccode;
666 int mapped;
667
668 /* check for currently supported ccode size */
669 if (strlen(ccode) > (BRCM_CNTRY_BUF_SZ - 1)) {
670 wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for "
671 "match\n", wlc->pub->unit, __func__, ccode);
672 return NULL;
673 }
674
675 /* default mapping is the given ccode and regrev 0 */
676 strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ);
677 *mapped_regrev = 0;
678
679 /* If the desired country code matches the srom country code,
680 * then the mapped country is the srom regulatory rev.
681 * Otherwise look for an aggregate mapping.
682 */
683 if (!strcmp(srom_ccode, ccode)) {
684 *mapped_regrev = srom_regrev;
685 mapped = 0;
686 wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__);
687 } else {
688 mapped =
689 brcms_c_country_aggregate_map(wlc_cm, ccode, mapped_ccode,
690 mapped_regrev);
691 }
692
693 /* find the matching built-in country definition */
694 country = brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
695
696 /* if there is not an exact rev match, default to rev zero */
697 if (country == NULL && *mapped_regrev != 0) {
698 *mapped_regrev = 0;
699 country =
700 brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
701 }
702
703 return country;
704}
705
706/* Lookup a country info structure from a null terminated country code
707 * The lookup is case sensitive.
708 */
709static const struct country_info *
710brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode)
711{
712 const struct country_info *country;
713 char mapped_ccode[BRCM_CNTRY_BUF_SZ];
714 uint mapped_regrev;
715
716 /*
717 * map the country code to a built-in country code, regrev, and
718 * country_info struct
719 */
720 country = brcms_c_countrycode_map(wlc->cmi, ccode, mapped_ccode,
721 &mapped_regrev);
722
723 return country;
724}
725
726/*
727 * reset the quiet channels vector to the union
728 * of the restricted and radar channel sets
729 */
730static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm)
731{
732 struct brcms_c_info *wlc = wlc_cm->wlc;
733 uint i, j;
734 struct brcms_band *band;
735 const struct brcms_chanvec *chanvec;
736
737 memset(&wlc_cm->quiet_channels, 0, sizeof(struct brcms_chanvec));
738
739 band = wlc->band;
740 for (i = 0; i < wlc->pub->_nbands;
741 i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
742
743 /* initialize quiet channels for restricted channels */
744 chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels;
745 for (j = 0; j < sizeof(struct brcms_chanvec); j++)
746 wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j];
747
748 }
749}
750
751/* Is the channel valid for the current locale and current band? */
752static bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val)
753{
754 struct brcms_c_info *wlc = wlc_cm->wlc;
755
756 return ((val < MAXCHANNEL) &&
757 isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec,
758 val));
759}
760
761/* Is the channel valid for the current locale and specified band? */
762static bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm,
763 uint bandunit, uint val)
764{
765 return ((val < MAXCHANNEL)
766 && isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val));
767}
768
769/* Is the channel valid for the current locale? (but don't consider channels not
770 * available due to bandlocking)
771 */
772static bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val)
773{
774 struct brcms_c_info *wlc = wlc_cm->wlc;
775
776 return brcms_c_valid_channel20(wlc->cmi, val) ||
777 (!wlc->bandlocked
778 && brcms_c_valid_channel20_in_band(wlc->cmi,
779 OTHERBANDUNIT(wlc), val));
780}
781
782/* JP, J1 - J10 are Japan ccodes */
783static bool brcms_c_japan_ccode(const char *ccode)
784{
785 return (ccode[0] == 'J' &&
786 (ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9')));
787}
788
789/* Returns true if currently set country is Japan or variant */
790static bool brcms_c_japan(struct brcms_c_info *wlc)
791{
792 return brcms_c_japan_ccode(wlc->cmi->country_abbrev);
793}
794
795static void
796brcms_c_channel_min_txpower_limits_with_local_constraint(
797 struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr,
798 u8 local_constraint_qdbm)
799{
800 int j;
801
802 /* CCK Rates */
803 for (j = 0; j < WL_TX_POWER_CCK_NUM; j++)
804 txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm);
805
806 /* 20 MHz Legacy OFDM SISO */
807 for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++)
808 txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm);
809
810 /* 20 MHz Legacy OFDM CDD */
811 for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
812 txpwr->ofdm_cdd[j] =
813 min(txpwr->ofdm_cdd[j], local_constraint_qdbm);
814
815 /* 40 MHz Legacy OFDM SISO */
816 for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
817 txpwr->ofdm_40_siso[j] =
818 min(txpwr->ofdm_40_siso[j], local_constraint_qdbm);
819
820 /* 40 MHz Legacy OFDM CDD */
821 for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
822 txpwr->ofdm_40_cdd[j] =
823 min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm);
824
825 /* 20MHz MCS 0-7 SISO */
826 for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
827 txpwr->mcs_20_siso[j] =
828 min(txpwr->mcs_20_siso[j], local_constraint_qdbm);
829
830 /* 20MHz MCS 0-7 CDD */
831 for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
832 txpwr->mcs_20_cdd[j] =
833 min(txpwr->mcs_20_cdd[j], local_constraint_qdbm);
834
835 /* 20MHz MCS 0-7 STBC */
836 for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
837 txpwr->mcs_20_stbc[j] =
838 min(txpwr->mcs_20_stbc[j], local_constraint_qdbm);
839
840 /* 20MHz MCS 8-15 MIMO */
841 for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
842 txpwr->mcs_20_mimo[j] =
843 min(txpwr->mcs_20_mimo[j], local_constraint_qdbm);
844
845 /* 40MHz MCS 0-7 SISO */
846 for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
847 txpwr->mcs_40_siso[j] =
848 min(txpwr->mcs_40_siso[j], local_constraint_qdbm);
849
850 /* 40MHz MCS 0-7 CDD */
851 for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
852 txpwr->mcs_40_cdd[j] =
853 min(txpwr->mcs_40_cdd[j], local_constraint_qdbm);
854
855 /* 40MHz MCS 0-7 STBC */
856 for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
857 txpwr->mcs_40_stbc[j] =
858 min(txpwr->mcs_40_stbc[j], local_constraint_qdbm);
859
860 /* 40MHz MCS 8-15 MIMO */
861 for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
862 txpwr->mcs_40_mimo[j] =
863 min(txpwr->mcs_40_mimo[j], local_constraint_qdbm);
864
865 /* 40MHz MCS 32 */
866 txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm);
867
868}
869
870/* Update the radio state (enable/disable) and tx power targets
871 * based on a new set of channel/regulatory information
872 */
873static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm)
874{
875 struct brcms_c_info *wlc = wlc_cm->wlc;
876 uint chan;
877 struct txpwr_limits txpwr;
878
879 /* search for the existence of any valid channel */
880 for (chan = 0; chan < MAXCHANNEL; chan++) {
881 if (brcms_c_valid_channel20_db(wlc->cmi, chan))
882 break;
883 }
884 if (chan == MAXCHANNEL)
885 chan = INVCHANNEL;
886
887 /*
888 * based on the channel search above, set or
889 * clear WL_RADIO_COUNTRY_DISABLE.
890 */
891 if (chan == INVCHANNEL) {
892 /*
893 * country/locale with no valid channels, set
894 * the radio disable bit
895 */
896 mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
897 wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" "
898 "nbands %d bandlocked %d\n", wlc->pub->unit,
899 __func__, wlc_cm->country_abbrev, wlc->pub->_nbands,
900 wlc->bandlocked);
901 } else if (mboolisset(wlc->pub->radio_disabled,
902 WL_RADIO_COUNTRY_DISABLE)) {
903 /*
904 * country/locale with valid channel, clear
905 * the radio disable bit
906 */
907 mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
908 }
909
910 /*
911 * Now that the country abbreviation is set, if the radio supports 2G,
912 * then set channel 14 restrictions based on the new locale.
913 */
914 if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G)
915 wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi,
916 brcms_c_japan(wlc) ? true :
917 false);
918
919 if (wlc->pub->up && chan != INVCHANNEL) {
920 brcms_c_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr);
921 brcms_c_channel_min_txpower_limits_with_local_constraint(wlc_cm,
922 &txpwr, BRCMS_TXPWR_MAX);
923 wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec);
924 }
925}
926
927static int
928brcms_c_channels_init(struct brcms_cm_info *wlc_cm,
929 const struct country_info *country)
930{
931 struct brcms_c_info *wlc = wlc_cm->wlc;
932 uint i, j;
933 struct brcms_band *band;
934 const struct locale_info *li;
935 struct brcms_chanvec sup_chan;
936 const struct locale_mimo_info *li_mimo;
937
938 band = wlc->band;
939 for (i = 0; i < wlc->pub->_nbands;
940 i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
941
942 li = (band->bandtype == BRCM_BAND_5G) ?
943 brcms_c_get_locale_5g(country->locale_5G) :
944 brcms_c_get_locale_2g(country->locale_2G);
945 wlc_cm->bandstate[band->bandunit].locale_flags = li->flags;
946 li_mimo = (band->bandtype == BRCM_BAND_5G) ?
947 brcms_c_get_mimo_5g(country->locale_mimo_5G) :
948 brcms_c_get_mimo_2g(country->locale_mimo_2G);
949
950 /* merge the mimo non-mimo locale flags */
951 wlc_cm->bandstate[band->bandunit].locale_flags |=
952 li_mimo->flags;
953
954 wlc_cm->bandstate[band->bandunit].restricted_channels =
955 g_table_restricted_chan[li->restricted_channels];
956 wlc_cm->bandstate[band->bandunit].radar_channels =
957 g_table_radar_set[li->radar_channels];
958
959 /*
960 * set the channel availability, masking out the channels
961 * that may not be supported on this phy.
962 */
963 wlc_phy_chanspec_band_validch(band->pi, band->bandtype,
964 &sup_chan);
965 brcms_c_locale_get_channels(li,
966 &wlc_cm->bandstate[band->bandunit].
967 valid_channels);
968 for (j = 0; j < sizeof(struct brcms_chanvec); j++)
969 wlc_cm->bandstate[band->bandunit].valid_channels.
970 vec[j] &= sup_chan.vec[j];
971 }
972
973 brcms_c_quiet_channels_reset(wlc_cm);
974 brcms_c_channels_commit(wlc_cm);
975
976 return 0;
977}
978
979/*
980 * set the driver's current country and regulatory information
981 * using a country code as the source. Look up built in country
982 * information found with the country code.
983 */
984static void
985brcms_c_set_country_common(struct brcms_cm_info *wlc_cm,
986 const char *country_abbrev,
987 const char *ccode, uint regrev,
988 const struct country_info *country)
989{
990 const struct locale_info *locale;
991 struct brcms_c_info *wlc = wlc_cm->wlc;
992 char prev_country_abbrev[BRCM_CNTRY_BUF_SZ];
993
994 /* save current country state */
995 wlc_cm->country = country;
996
997 memset(&prev_country_abbrev, 0, BRCM_CNTRY_BUF_SZ);
998 strncpy(prev_country_abbrev, wlc_cm->country_abbrev,
999 BRCM_CNTRY_BUF_SZ - 1);
1000
1001 strncpy(wlc_cm->country_abbrev, country_abbrev, BRCM_CNTRY_BUF_SZ - 1);
1002 strncpy(wlc_cm->ccode, ccode, BRCM_CNTRY_BUF_SZ - 1);
1003 wlc_cm->regrev = regrev;
1004
1005 if ((wlc->pub->_n_enab & SUPPORT_11N) !=
1006 wlc->protection->nmode_user)
1007 brcms_c_set_nmode(wlc);
1008
1009 brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
1010 brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
1011 /* set or restore gmode as required by regulatory */
1012 locale = brcms_c_get_locale_2g(country->locale_2G);
1013 if (locale && (locale->flags & BRCMS_NO_OFDM))
1014 brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false);
1015 else
1016 brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
1017
1018 brcms_c_channels_init(wlc_cm, country);
1019
1020 return;
1021}
1022
1023static int
1024brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm,
1025 const char *country_abbrev,
1026 const char *ccode, int regrev)
1027{
1028 const struct country_info *country;
1029 char mapped_ccode[BRCM_CNTRY_BUF_SZ];
1030 uint mapped_regrev;
1031
1032 /* if regrev is -1, lookup the mapped country code,
1033 * otherwise use the ccode and regrev directly
1034 */
1035 if (regrev == -1) {
1036 /*
1037 * map the country code to a built-in country
1038 * code, regrev, and country_info
1039 */
1040 country =
1041 brcms_c_countrycode_map(wlc_cm, ccode, mapped_ccode,
1042 &mapped_regrev);
1043 } else {
1044 /* find the matching built-in country definition */
1045 country = brcms_c_country_lookup_direct(ccode, regrev);
1046 strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ);
1047 mapped_regrev = regrev;
1048 }
1049
1050 if (country == NULL)
1051 return -EINVAL;
1052
1053 /* set the driver state for the country */
1054 brcms_c_set_country_common(wlc_cm, country_abbrev, mapped_ccode,
1055 mapped_regrev, country);
1056
1057 return 0;
1058}
1059
1060/*
1061 * set the driver's current country and regulatory information using
1062 * a country code as the source. Lookup built in country information
1063 * found with the country code.
1064 */
1065static int
1066brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm, const char *ccode)
1067{
1068 char country_abbrev[BRCM_CNTRY_BUF_SZ];
1069 strncpy(country_abbrev, ccode, BRCM_CNTRY_BUF_SZ);
1070 return brcms_c_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1);
1071}
1072
1073struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
1074{
1075 struct brcms_cm_info *wlc_cm;
1076 char country_abbrev[BRCM_CNTRY_BUF_SZ];
1077 const struct country_info *country;
1078 struct brcms_pub *pub = wlc->pub;
1079 char *ccode;
1080
1081 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
1082
1083 wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC);
1084 if (wlc_cm == NULL)
1085 return NULL;
1086 wlc_cm->pub = pub;
1087 wlc_cm->wlc = wlc;
1088 wlc->cmi = wlc_cm;
1089
1090 /* store the country code for passing up as a regulatory hint */
1091 ccode = getvar(wlc->hw->sih, BRCMS_SROM_CCODE);
1092 if (ccode)
1093 strncpy(wlc->pub->srom_ccode, ccode, BRCM_CNTRY_BUF_SZ - 1);
1094
1095 /*
1096 * internal country information which must match
1097 * regulatory constraints in firmware
1098 */
1099 memset(country_abbrev, 0, BRCM_CNTRY_BUF_SZ);
1100 strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1);
1101 country = brcms_c_country_lookup(wlc, country_abbrev);
1102
1103 /* save default country for exiting 11d regulatory mode */
1104 strncpy(wlc->country_default, country_abbrev, BRCM_CNTRY_BUF_SZ - 1);
1105
1106 /* initialize autocountry_default to driver default */
1107 strncpy(wlc->autocountry_default, "X2", BRCM_CNTRY_BUF_SZ - 1);
1108
1109 brcms_c_set_countrycode(wlc_cm, country_abbrev);
1110
1111 return wlc_cm;
1112}
1113
1114void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm)
1115{
1116 kfree(wlc_cm);
1117}
1118
1119u8
1120brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
1121 uint bandunit)
1122{
1123 return wlc_cm->bandstate[bandunit].locale_flags;
1124}
1125
1126static bool
1127brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, u16 chspec)
1128{
1129 return (wlc_cm->wlc->pub->_n_enab & SUPPORT_11N) &&
1130 CHSPEC_IS40(chspec) ?
1131 (isset(wlc_cm->quiet_channels.vec,
1132 lower_20_sb(CHSPEC_CHANNEL(chspec))) ||
1133 isset(wlc_cm->quiet_channels.vec,
1134 upper_20_sb(CHSPEC_CHANNEL(chspec)))) :
1135 isset(wlc_cm->quiet_channels.vec, CHSPEC_CHANNEL(chspec));
1136}
1137
1138void
1139brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
1140 u8 local_constraint_qdbm)
1141{
1142 struct brcms_c_info *wlc = wlc_cm->wlc;
1143 struct txpwr_limits txpwr;
1144
1145 brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr);
1146
1147 brcms_c_channel_min_txpower_limits_with_local_constraint(
1148 wlc_cm, &txpwr, local_constraint_qdbm
1149 );
1150
1151 brcms_b_set_chanspec(wlc->hw, chanspec,
1152 (brcms_c_quiet_chanspec(wlc_cm, chanspec) != 0),
1153 &txpwr);
1154}
1155
1156#ifdef POWER_DBG
1157static void wlc_phy_txpower_limits_dump(struct txpwr_limits *txpwr)
1158{
1159 int i;
1160 char buf[80];
1161 char fraction[4][4] = { " ", ".25", ".5 ", ".75" };
1162
1163 sprintf(buf, "CCK ");
1164 for (i = 0; i < BRCMS_NUM_RATES_CCK; i++)
1165 sprintf(buf[strlen(buf)], " %2d%s",
1166 txpwr->cck[i] / BRCMS_TXPWR_DB_FACTOR,
1167 fraction[txpwr->cck[i] % BRCMS_TXPWR_DB_FACTOR]);
1168 printk(KERN_DEBUG "%s\n", buf);
1169
1170 sprintf(buf, "20 MHz OFDM SISO ");
1171 for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++)
1172 sprintf(buf[strlen(buf)], " %2d%s",
1173 txpwr->ofdm[i] / BRCMS_TXPWR_DB_FACTOR,
1174 fraction[txpwr->ofdm[i] % BRCMS_TXPWR_DB_FACTOR]);
1175 printk(KERN_DEBUG "%s\n", buf);
1176
1177 sprintf(buf, "20 MHz OFDM CDD ");
1178 for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++)
1179 sprintf(buf[strlen(buf)], " %2d%s",
1180 txpwr->ofdm_cdd[i] / BRCMS_TXPWR_DB_FACTOR,
1181 fraction[txpwr->ofdm_cdd[i] % BRCMS_TXPWR_DB_FACTOR]);
1182 printk(KERN_DEBUG "%s\n", buf);
1183
1184 sprintf(buf, "40 MHz OFDM SISO ");
1185 for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++)
1186 sprintf(buf[strlen(buf)], " %2d%s",
1187 txpwr->ofdm_40_siso[i] / BRCMS_TXPWR_DB_FACTOR,
1188 fraction[txpwr->ofdm_40_siso[i] %
1189 BRCMS_TXPWR_DB_FACTOR]);
1190 printk(KERN_DEBUG "%s\n", buf);
1191
1192 sprintf(buf, "40 MHz OFDM CDD ");
1193 for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++)
1194 sprintf(buf[strlen(buf)], " %2d%s",
1195 txpwr->ofdm_40_cdd[i] / BRCMS_TXPWR_DB_FACTOR,
1196 fraction[txpwr->ofdm_40_cdd[i] %
1197 BRCMS_TXPWR_DB_FACTOR]);
1198 printk(KERN_DEBUG "%s\n", buf);
1199
1200 sprintf(buf, "20 MHz MCS0-7 SISO ");
1201 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++)
1202 sprintf(buf[strlen(buf)], " %2d%s",
1203 txpwr->mcs_20_siso[i] / BRCMS_TXPWR_DB_FACTOR,
1204 fraction[txpwr->mcs_20_siso[i] %
1205 BRCMS_TXPWR_DB_FACTOR]);
1206 printk(KERN_DEBUG "%s\n", buf);
1207
1208 sprintf(buf, "20 MHz MCS0-7 CDD ");
1209 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++)
1210 sprintf(buf[strlen(buf)], " %2d%s",
1211 txpwr->mcs_20_cdd[i] / BRCMS_TXPWR_DB_FACTOR,
1212 fraction[txpwr->mcs_20_cdd[i] %
1213 BRCMS_TXPWR_DB_FACTOR]);
1214 printk(KERN_DEBUG "%s\n", buf);
1215
1216 sprintf(buf, "20 MHz MCS0-7 STBC ");
1217 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++)
1218 sprintf(buf[strlen(buf)], " %2d%s",
1219 txpwr->mcs_20_stbc[i] / BRCMS_TXPWR_DB_FACTOR,
1220 fraction[txpwr->mcs_20_stbc[i] %
1221 BRCMS_TXPWR_DB_FACTOR]);
1222 printk(KERN_DEBUG "%s\n", buf);
1223
1224 sprintf(buf, "20 MHz MCS8-15 SDM ");
1225 for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++)
1226 sprintf(buf[strlen(buf)], " %2d%s",
1227 txpwr->mcs_20_mimo[i] / BRCMS_TXPWR_DB_FACTOR,
1228 fraction[txpwr->mcs_20_mimo[i] %
1229 BRCMS_TXPWR_DB_FACTOR]);
1230 printk(KERN_DEBUG "%s\n", buf);
1231
1232 sprintf(buf, "40 MHz MCS0-7 SISO ");
1233 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++)
1234 sprintf(buf[strlen(buf)], " %2d%s",
1235 txpwr->mcs_40_siso[i] / BRCMS_TXPWR_DB_FACTOR,
1236 fraction[txpwr->mcs_40_siso[i] %
1237 BRCMS_TXPWR_DB_FACTOR]);
1238 printk(KERN_DEBUG "%s\n", buf);
1239
1240 sprintf(buf, "40 MHz MCS0-7 CDD ");
1241 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++)
1242 sprintf(buf[strlen(buf)], " %2d%s",
1243 txpwr->mcs_40_cdd[i] / BRCMS_TXPWR_DB_FACTOR,
1244 fraction[txpwr->mcs_40_cdd[i] %
1245 BRCMS_TXPWR_DB_FACTOR]);
1246 printk(KERN_DEBUG "%s\n", buf);
1247
1248 sprintf(buf, "40 MHz MCS0-7 STBC ");
1249 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++)
1250 sprintf(buf[strlen(buf)], " %2d%s",
1251 txpwr->mcs_40_stbc[i] / BRCMS_TXPWR_DB_FACTOR,
1252 fraction[txpwr->mcs_40_stbc[i] %
1253 BRCMS_TXPWR_DB_FACTOR]);
1254 printk(KERN_DEBUG "%s\n", buf);
1255
1256 sprintf(buf, "40 MHz MCS8-15 SDM ");
1257 for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++)
1258 sprintf(buf[strlen(buf)], " %2d%s",
1259 txpwr->mcs_40_mimo[i] / BRCMS_TXPWR_DB_FACTOR,
1260 fraction[txpwr->mcs_40_mimo[i] %
1261 BRCMS_TXPWR_DB_FACTOR]);
1262 }
1263 printk(KERN_DEBUG "%s\n", buf);
1264
1265 printk(KERN_DEBUG "MCS32 %2d%s\n",
1266 txpwr->mcs32 / BRCMS_TXPWR_DB_FACTOR,
1267 fraction[txpwr->mcs32 % BRCMS_TXPWR_DB_FACTOR]);
1268}
1269#endif /* POWER_DBG */
1270
1271void
1272brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec,
1273 struct txpwr_limits *txpwr)
1274{
1275 struct brcms_c_info *wlc = wlc_cm->wlc;
1276 uint i;
1277 uint chan;
1278 int maxpwr;
1279 int delta;
1280 const struct country_info *country;
1281 struct brcms_band *band;
1282 const struct locale_info *li;
1283 int conducted_max = BRCMS_TXPWR_MAX;
1284 int conducted_ofdm_max = BRCMS_TXPWR_MAX;
1285 const struct locale_mimo_info *li_mimo;
1286 int maxpwr20, maxpwr40;
1287 int maxpwr_idx;
1288 uint j;
1289
1290 memset(txpwr, 0, sizeof(struct txpwr_limits));
1291
1292 if (!brcms_c_valid_chanspec_db(wlc_cm, chanspec)) {
1293 country = brcms_c_country_lookup(wlc, wlc->autocountry_default);
1294 if (country == NULL)
1295 return;
1296 } else {
1297 country = wlc_cm->country;
1298 }
1299
1300 chan = CHSPEC_CHANNEL(chanspec);
1301 band = wlc->bandstate[chspec_bandunit(chanspec)];
1302 li = (band->bandtype == BRCM_BAND_5G) ?
1303 brcms_c_get_locale_5g(country->locale_5G) :
1304 brcms_c_get_locale_2g(country->locale_2G);
1305
1306 li_mimo = (band->bandtype == BRCM_BAND_5G) ?
1307 brcms_c_get_mimo_5g(country->locale_mimo_5G) :
1308 brcms_c_get_mimo_2g(country->locale_mimo_2G);
1309
1310 if (li->flags & BRCMS_EIRP) {
1311 delta = band->antgain;
1312 } else {
1313 delta = 0;
1314 if (band->antgain > QDB(6))
1315 delta = band->antgain - QDB(6); /* Excess over 6 dB */
1316 }
1317
1318 if (li == &locale_i) {
1319 conducted_max = QDB(22);
1320 conducted_ofdm_max = QDB(22);
1321 }
1322
1323 /* CCK txpwr limits for 2.4G band */
1324 if (band->bandtype == BRCM_BAND_2G) {
1325 maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)];
1326
1327 maxpwr = maxpwr - delta;
1328 maxpwr = max(maxpwr, 0);
1329 maxpwr = min(maxpwr, conducted_max);
1330
1331 for (i = 0; i < BRCMS_NUM_RATES_CCK; i++)
1332 txpwr->cck[i] = (u8) maxpwr;
1333 }
1334
1335 /* OFDM txpwr limits for 2.4G or 5G bands */
1336 if (band->bandtype == BRCM_BAND_2G)
1337 maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)];
1338 else
1339 maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)];
1340
1341 maxpwr = maxpwr - delta;
1342 maxpwr = max(maxpwr, 0);
1343 maxpwr = min(maxpwr, conducted_ofdm_max);
1344
1345 /* Keep OFDM lmit below CCK limit */
1346 if (band->bandtype == BRCM_BAND_2G)
1347 maxpwr = min_t(int, maxpwr, txpwr->cck[0]);
1348
1349 for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++)
1350 txpwr->ofdm[i] = (u8) maxpwr;
1351
1352 for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) {
1353 /*
1354 * OFDM 40 MHz SISO has the same power as the corresponding
1355 * MCS0-7 rate unless overriden by the locale specific code.
1356 * We set this value to 0 as a flag (presumably 0 dBm isn't
1357 * a possibility) and then copy the MCS0-7 value to the 40 MHz
1358 * value if it wasn't explicitly set.
1359 */
1360 txpwr->ofdm_40_siso[i] = 0;
1361
1362 txpwr->ofdm_cdd[i] = (u8) maxpwr;
1363
1364 txpwr->ofdm_40_cdd[i] = 0;
1365 }
1366
1367 /* MIMO/HT specific limits */
1368 if (li_mimo->flags & BRCMS_EIRP) {
1369 delta = band->antgain;
1370 } else {
1371 delta = 0;
1372 if (band->antgain > QDB(6))
1373 delta = band->antgain - QDB(6); /* Excess over 6 dB */
1374 }
1375
1376 if (band->bandtype == BRCM_BAND_2G)
1377 maxpwr_idx = (chan - 1);
1378 else
1379 maxpwr_idx = CHANNEL_POWER_IDX_5G(chan);
1380
1381 maxpwr20 = li_mimo->maxpwr20[maxpwr_idx];
1382 maxpwr40 = li_mimo->maxpwr40[maxpwr_idx];
1383
1384 maxpwr20 = maxpwr20 - delta;
1385 maxpwr20 = max(maxpwr20, 0);
1386 maxpwr40 = maxpwr40 - delta;
1387 maxpwr40 = max(maxpwr40, 0);
1388
1389 /* Fill in the MCS 0-7 (SISO) rates */
1390 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1391
1392 /*
1393 * 20 MHz has the same power as the corresponding OFDM rate
1394 * unless overriden by the locale specific code.
1395 */
1396 txpwr->mcs_20_siso[i] = txpwr->ofdm[i];
1397 txpwr->mcs_40_siso[i] = 0;
1398 }
1399
1400 /* Fill in the MCS 0-7 CDD rates */
1401 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1402 txpwr->mcs_20_cdd[i] = (u8) maxpwr20;
1403 txpwr->mcs_40_cdd[i] = (u8) maxpwr40;
1404 }
1405
1406 /*
1407 * These locales have SISO expressed in the
1408 * table and override CDD later
1409 */
1410 if (li_mimo == &locale_bn) {
1411 if (li_mimo == &locale_bn) {
1412 maxpwr20 = QDB(16);
1413 maxpwr40 = 0;
1414
1415 if (chan >= 3 && chan <= 11)
1416 maxpwr40 = QDB(16);
1417 }
1418
1419 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1420 txpwr->mcs_20_siso[i] = (u8) maxpwr20;
1421 txpwr->mcs_40_siso[i] = (u8) maxpwr40;
1422 }
1423 }
1424
1425 /* Fill in the MCS 0-7 STBC rates */
1426 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1427 txpwr->mcs_20_stbc[i] = 0;
1428 txpwr->mcs_40_stbc[i] = 0;
1429 }
1430
1431 /* Fill in the MCS 8-15 SDM rates */
1432 for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) {
1433 txpwr->mcs_20_mimo[i] = (u8) maxpwr20;
1434 txpwr->mcs_40_mimo[i] = (u8) maxpwr40;
1435 }
1436
1437 /* Fill in MCS32 */
1438 txpwr->mcs32 = (u8) maxpwr40;
1439
1440 for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) {
1441 if (txpwr->ofdm_40_cdd[i] == 0)
1442 txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
1443 if (i == 0) {
1444 i = i + 1;
1445 if (txpwr->ofdm_40_cdd[i] == 0)
1446 txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
1447 }
1448 }
1449
1450 /*
1451 * Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO
1452 * value if it wasn't provided explicitly.
1453 */
1454 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1455 if (txpwr->mcs_40_siso[i] == 0)
1456 txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i];
1457 }
1458
1459 for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) {
1460 if (txpwr->ofdm_40_siso[i] == 0)
1461 txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
1462 if (i == 0) {
1463 i = i + 1;
1464 if (txpwr->ofdm_40_siso[i] == 0)
1465 txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
1466 }
1467 }
1468
1469 /*
1470 * Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding
1471 * STBC values if they weren't provided explicitly.
1472 */
1473 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1474 if (txpwr->mcs_20_stbc[i] == 0)
1475 txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i];
1476
1477 if (txpwr->mcs_40_stbc[i] == 0)
1478 txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i];
1479 }
1480
1481#ifdef POWER_DBG
1482 wlc_phy_txpower_limits_dump(txpwr);
1483#endif
1484 return;
1485}
1486
1487/*
1488 * Verify the chanspec is using a legal set of parameters, i.e. that the
1489 * chanspec specified a band, bw, ctl_sb and channel and that the
1490 * combination could be legal given any set of circumstances.
1491 * RETURNS: true is the chanspec is malformed, false if it looks good.
1492 */
1493static bool brcms_c_chspec_malformed(u16 chanspec)
1494{
1495 /* must be 2G or 5G band */
1496 if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
1497 return true;
1498 /* must be 20 or 40 bandwidth */
1499 if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
1500 return true;
1501
1502 /* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */
1503 if (CHSPEC_IS20(chanspec)) {
1504 if (!CHSPEC_SB_NONE(chanspec))
1505 return true;
1506 } else if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) {
1507 return true;
1508 }
1509
1510 return false;
1511}
1512
1513/*
1514 * Validate the chanspec for this locale, for 40MHZ we need to also
1515 * check that the sidebands are valid 20MZH channels in this locale
1516 * and they are also a legal HT combination
1517 */
1518static bool
1519brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec,
1520 bool dualband)
1521{
1522 struct brcms_c_info *wlc = wlc_cm->wlc;
1523 u8 channel = CHSPEC_CHANNEL(chspec);
1524
1525 /* check the chanspec */
1526 if (brcms_c_chspec_malformed(chspec)) {
1527 wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n",
1528 wlc->pub->unit, chspec);
1529 return false;
1530 }
1531
1532 if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) !=
1533 chspec_bandunit(chspec))
1534 return false;
1535
1536 /* Check a 20Mhz channel */
1537 if (CHSPEC_IS20(chspec)) {
1538 if (dualband)
1539 return brcms_c_valid_channel20_db(wlc_cm->wlc->cmi,
1540 channel);
1541 else
1542 return brcms_c_valid_channel20(wlc_cm->wlc->cmi,
1543 channel);
1544 }
1545#ifdef SUPPORT_40MHZ
1546 /*
1547 * We know we are now checking a 40MHZ channel, so we should
1548 * only be here for NPHYS
1549 */
1550 if (BRCMS_ISNPHY(wlc->band) || BRCMS_ISSSLPNPHY(wlc->band)) {
1551 u8 upper_sideband = 0, idx;
1552 u8 num_ch20_entries =
1553 sizeof(chan20_info) / sizeof(struct chan20_info);
1554
1555 if (!VALID_40CHANSPEC_IN_BAND(wlc, chspec_bandunit(chspec)))
1556 return false;
1557
1558 if (dualband) {
1559 if (!brcms_c_valid_channel20_db(wlc->cmi,
1560 lower_20_sb(channel)) ||
1561 !brcms_c_valid_channel20_db(wlc->cmi,
1562 upper_20_sb(channel)))
1563 return false;
1564 } else {
1565 if (!brcms_c_valid_channel20(wlc->cmi,
1566 lower_20_sb(channel)) ||
1567 !brcms_c_valid_channel20(wlc->cmi,
1568 upper_20_sb(channel)))
1569 return false;
1570 }
1571
1572 /* find the lower sideband info in the sideband array */
1573 for (idx = 0; idx < num_ch20_entries; idx++) {
1574 if (chan20_info[idx].sb == lower_20_sb(channel))
1575 upper_sideband = chan20_info[idx].adj_sbs;
1576 }
1577 /* check that the lower sideband allows an upper sideband */
1578 if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) ==
1579 (CH_UPPER_SB | CH_EWA_VALID))
1580 return true;
1581 return false;
1582 }
1583#endif /* 40 MHZ */
1584
1585 return false;
1586}
1587
1588bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec)
1589{
1590 return brcms_c_valid_chanspec_ext(wlc_cm, chspec, true);
1591}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.h b/drivers/net/wireless/brcm80211/brcmsmac/channel.h
new file mode 100644
index 000000000000..808cb4fbfbe7
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.h
@@ -0,0 +1,53 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_CHANNEL_H_
18#define _BRCM_CHANNEL_H_
19
20/* conversion for phy txpwr calculations that use .25 dB units */
21#define BRCMS_TXPWR_DB_FACTOR 4
22
23/* bits for locale_info flags */
24#define BRCMS_PEAK_CONDUCTED 0x00 /* Peak for locals */
25#define BRCMS_EIRP 0x01 /* Flag for EIRP */
26#define BRCMS_DFS_TPC 0x02 /* Flag for DFS TPC */
27#define BRCMS_NO_OFDM 0x04 /* Flag for No OFDM */
28#define BRCMS_NO_40MHZ 0x08 /* Flag for No MIMO 40MHz */
29#define BRCMS_NO_MIMO 0x10 /* Flag for No MIMO, 20 or 40 MHz */
30#define BRCMS_RADAR_TYPE_EU 0x20 /* Flag for EU */
31#define BRCMS_DFS_FCC BRCMS_DFS_TPC /* Flag for DFS FCC */
32
33#define BRCMS_DFS_EU (BRCMS_DFS_TPC | BRCMS_RADAR_TYPE_EU) /* Flag for DFS EU */
34
35extern struct brcms_cm_info *
36brcms_c_channel_mgr_attach(struct brcms_c_info *wlc);
37
38extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm);
39
40extern u8 brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
41 uint bandunit);
42
43extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm,
44 u16 chspec);
45
46extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm,
47 u16 chanspec,
48 struct txpwr_limits *txpwr);
49extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm,
50 u16 chanspec,
51 u8 local_constraint_qdbm);
52
53#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 000000000000..ed51616abc85
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/d11.h
@@ -0,0 +1,1898 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_D11_H_
18#define _BRCM_D11_H_
19
20#include <linux/ieee80211.h>
21
22#include <defs.h>
23#include "pub.h"
24#include "dma.h"
25
26/* RX FIFO numbers */
27#define RX_FIFO 0 /* data and ctl frames */
28#define RX_TXSTATUS_FIFO 3 /* RX fifo for tx status packages */
29
30/* TX FIFO numbers using WME Access Category */
31#define TX_AC_BK_FIFO 0 /* Background TX FIFO */
32#define TX_AC_BE_FIFO 1 /* Best-Effort TX FIFO */
33#define TX_AC_VI_FIFO 2 /* Video TX FIFO */
34#define TX_AC_VO_FIFO 3 /* Voice TX FIFO */
35#define TX_BCMC_FIFO 4 /* Broadcast/Multicast TX FIFO */
36#define TX_ATIM_FIFO 5 /* TX fifo for ATIM window info */
37
38/* Addr is byte address used by SW; offset is word offset used by uCode */
39
40/* Per AC TX limit settings */
41#define M_AC_TXLMT_BASE_ADDR (0x180 * 2)
42#define M_AC_TXLMT_ADDR(_ac) (M_AC_TXLMT_BASE_ADDR + (2 * (_ac)))
43
44/* Legacy TX FIFO numbers */
45#define TX_DATA_FIFO TX_AC_BE_FIFO
46#define TX_CTL_FIFO TX_AC_VO_FIFO
47
48#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */
49
50struct intctrlregs {
51 u32 intstatus;
52 u32 intmask;
53};
54
55/* PIO structure,
56 * support two PIO format: 2 bytes access and 4 bytes access
57 * basic FIFO register set is per channel(transmit or receive)
58 * a pair of channels is defined for convenience
59 */
60/* 2byte-wide pio register set per channel(xmt or rcv) */
61struct pio2regs {
62 u16 fifocontrol;
63 u16 fifodata;
64 u16 fifofree; /* only valid in xmt channel, not in rcv channel */
65 u16 PAD;
66};
67
68/* a pair of pio channels(tx and rx) */
69struct pio2regp {
70 struct pio2regs tx;
71 struct pio2regs rx;
72};
73
74/* 4byte-wide pio register set per channel(xmt or rcv) */
75struct pio4regs {
76 u32 fifocontrol;
77 u32 fifodata;
78};
79
80/* a pair of pio channels(tx and rx) */
81struct pio4regp {
82 struct pio4regs tx;
83 struct pio4regs rx;
84};
85
86/* read: 32-bit register that can be read as 32-bit or as 2 16-bit
87 * write: only low 16b-it half can be written
88 */
89union pmqreg {
90 u32 pmqhostdata; /* read only! */
91 struct {
92 u16 pmqctrlstatus; /* read/write */
93 u16 PAD;
94 } w;
95};
96
97struct fifo64 {
98 struct dma64regs dmaxmt; /* dma tx */
99 struct pio4regs piotx; /* pio tx */
100 struct dma64regs dmarcv; /* dma rx */
101 struct pio4regs piorx; /* pio rx */
102};
103
104/*
105 * Host Interface Registers
106 */
107struct d11regs {
108 /* Device Control ("semi-standard host registers") */
109 u32 PAD[3]; /* 0x0 - 0x8 */
110 u32 biststatus; /* 0xC */
111 u32 biststatus2; /* 0x10 */
112 u32 PAD; /* 0x14 */
113 u32 gptimer; /* 0x18 */
114 u32 usectimer; /* 0x1c *//* for corerev >= 26 */
115
116 /* Interrupt Control *//* 0x20 */
117 struct intctrlregs intctrlregs[8];
118
119 u32 PAD[40]; /* 0x60 - 0xFC */
120
121 u32 intrcvlazy[4]; /* 0x100 - 0x10C */
122
123 u32 PAD[4]; /* 0x110 - 0x11c */
124
125 u32 maccontrol; /* 0x120 */
126 u32 maccommand; /* 0x124 */
127 u32 macintstatus; /* 0x128 */
128 u32 macintmask; /* 0x12C */
129
130 /* Transmit Template Access */
131 u32 tplatewrptr; /* 0x130 */
132 u32 tplatewrdata; /* 0x134 */
133 u32 PAD[2]; /* 0x138 - 0x13C */
134
135 /* PMQ registers */
136 union pmqreg pmqreg; /* 0x140 */
137 u32 pmqpatl; /* 0x144 */
138 u32 pmqpath; /* 0x148 */
139 u32 PAD; /* 0x14C */
140
141 u32 chnstatus; /* 0x150 */
142 u32 psmdebug; /* 0x154 */
143 u32 phydebug; /* 0x158 */
144 u32 machwcap; /* 0x15C */
145
146 /* Extended Internal Objects */
147 u32 objaddr; /* 0x160 */
148 u32 objdata; /* 0x164 */
149 u32 PAD[2]; /* 0x168 - 0x16c */
150
151 u32 frmtxstatus; /* 0x170 */
152 u32 frmtxstatus2; /* 0x174 */
153 u32 PAD[2]; /* 0x178 - 0x17c */
154
155 /* TSF host access */
156 u32 tsf_timerlow; /* 0x180 */
157 u32 tsf_timerhigh; /* 0x184 */
158 u32 tsf_cfprep; /* 0x188 */
159 u32 tsf_cfpstart; /* 0x18c */
160 u32 tsf_cfpmaxdur32; /* 0x190 */
161 u32 PAD[3]; /* 0x194 - 0x19c */
162
163 u32 maccontrol1; /* 0x1a0 */
164 u32 machwcap1; /* 0x1a4 */
165 u32 PAD[14]; /* 0x1a8 - 0x1dc */
166
167 /* Clock control and hardware workarounds*/
168 u32 clk_ctl_st; /* 0x1e0 */
169 u32 hw_war;
170 u32 d11_phypllctl; /* the phypll request/avail bits are
171 * moved to clk_ctl_st
172 */
173 u32 PAD[5]; /* 0x1ec - 0x1fc */
174
175 /* 0x200-0x37F dma/pio registers */
176 struct fifo64 fifo64regs[6];
177
178 /* FIFO diagnostic port access */
179 struct dma32diag dmafifo; /* 0x380 - 0x38C */
180
181 u32 aggfifocnt; /* 0x390 */
182 u32 aggfifodata; /* 0x394 */
183 u32 PAD[16]; /* 0x398 - 0x3d4 */
184 u16 radioregaddr; /* 0x3d8 */
185 u16 radioregdata; /* 0x3da */
186
187 /*
188 * time delay between the change on rf disable input and
189 * radio shutdown
190 */
191 u32 rfdisabledly; /* 0x3DC */
192
193 /* PHY register access */
194 u16 phyversion; /* 0x3e0 - 0x0 */
195 u16 phybbconfig; /* 0x3e2 - 0x1 */
196 u16 phyadcbias; /* 0x3e4 - 0x2 Bphy only */
197 u16 phyanacore; /* 0x3e6 - 0x3 pwwrdwn on aphy */
198 u16 phyrxstatus0; /* 0x3e8 - 0x4 */
199 u16 phyrxstatus1; /* 0x3ea - 0x5 */
200 u16 phycrsth; /* 0x3ec - 0x6 */
201 u16 phytxerror; /* 0x3ee - 0x7 */
202 u16 phychannel; /* 0x3f0 - 0x8 */
203 u16 PAD[1]; /* 0x3f2 - 0x9 */
204 u16 phytest; /* 0x3f4 - 0xa */
205 u16 phy4waddr; /* 0x3f6 - 0xb */
206 u16 phy4wdatahi; /* 0x3f8 - 0xc */
207 u16 phy4wdatalo; /* 0x3fa - 0xd */
208 u16 phyregaddr; /* 0x3fc - 0xe */
209 u16 phyregdata; /* 0x3fe - 0xf */
210
211 /* IHR *//* 0x400 - 0x7FE */
212
213 /* RXE Block */
214 u16 PAD[3]; /* 0x400 - 0x406 */
215 u16 rcv_fifo_ctl; /* 0x406 */
216 u16 PAD; /* 0x408 - 0x40a */
217 u16 rcv_frm_cnt; /* 0x40a */
218 u16 PAD[4]; /* 0x40a - 0x414 */
219 u16 rssi; /* 0x414 */
220 u16 PAD[5]; /* 0x414 - 0x420 */
221 u16 rcm_ctl; /* 0x420 */
222 u16 rcm_mat_data; /* 0x422 */
223 u16 rcm_mat_mask; /* 0x424 */
224 u16 rcm_mat_dly; /* 0x426 */
225 u16 rcm_cond_mask_l; /* 0x428 */
226 u16 rcm_cond_mask_h; /* 0x42A */
227 u16 rcm_cond_dly; /* 0x42C */
228 u16 PAD[1]; /* 0x42E */
229 u16 ext_ihr_addr; /* 0x430 */
230 u16 ext_ihr_data; /* 0x432 */
231 u16 rxe_phyrs_2; /* 0x434 */
232 u16 rxe_phyrs_3; /* 0x436 */
233 u16 phy_mode; /* 0x438 */
234 u16 rcmta_ctl; /* 0x43a */
235 u16 rcmta_size; /* 0x43c */
236 u16 rcmta_addr0; /* 0x43e */
237 u16 rcmta_addr1; /* 0x440 */
238 u16 rcmta_addr2; /* 0x442 */
239 u16 PAD[30]; /* 0x444 - 0x480 */
240
241 /* PSM Block *//* 0x480 - 0x500 */
242
243 u16 PAD; /* 0x480 */
244 u16 psm_maccontrol_h; /* 0x482 */
245 u16 psm_macintstatus_l; /* 0x484 */
246 u16 psm_macintstatus_h; /* 0x486 */
247 u16 psm_macintmask_l; /* 0x488 */
248 u16 psm_macintmask_h; /* 0x48A */
249 u16 PAD; /* 0x48C */
250 u16 psm_maccommand; /* 0x48E */
251 u16 psm_brc; /* 0x490 */
252 u16 psm_phy_hdr_param; /* 0x492 */
253 u16 psm_postcard; /* 0x494 */
254 u16 psm_pcard_loc_l; /* 0x496 */
255 u16 psm_pcard_loc_h; /* 0x498 */
256 u16 psm_gpio_in; /* 0x49A */
257 u16 psm_gpio_out; /* 0x49C */
258 u16 psm_gpio_oe; /* 0x49E */
259
260 u16 psm_bred_0; /* 0x4A0 */
261 u16 psm_bred_1; /* 0x4A2 */
262 u16 psm_bred_2; /* 0x4A4 */
263 u16 psm_bred_3; /* 0x4A6 */
264 u16 psm_brcl_0; /* 0x4A8 */
265 u16 psm_brcl_1; /* 0x4AA */
266 u16 psm_brcl_2; /* 0x4AC */
267 u16 psm_brcl_3; /* 0x4AE */
268 u16 psm_brpo_0; /* 0x4B0 */
269 u16 psm_brpo_1; /* 0x4B2 */
270 u16 psm_brpo_2; /* 0x4B4 */
271 u16 psm_brpo_3; /* 0x4B6 */
272 u16 psm_brwk_0; /* 0x4B8 */
273 u16 psm_brwk_1; /* 0x4BA */
274 u16 psm_brwk_2; /* 0x4BC */
275 u16 psm_brwk_3; /* 0x4BE */
276
277 u16 psm_base_0; /* 0x4C0 */
278 u16 psm_base_1; /* 0x4C2 */
279 u16 psm_base_2; /* 0x4C4 */
280 u16 psm_base_3; /* 0x4C6 */
281 u16 psm_base_4; /* 0x4C8 */
282 u16 psm_base_5; /* 0x4CA */
283 u16 psm_base_6; /* 0x4CC */
284 u16 psm_pc_reg_0; /* 0x4CE */
285 u16 psm_pc_reg_1; /* 0x4D0 */
286 u16 psm_pc_reg_2; /* 0x4D2 */
287 u16 psm_pc_reg_3; /* 0x4D4 */
288 u16 PAD[0xD]; /* 0x4D6 - 0x4DE */
289 u16 psm_corectlsts; /* 0x4f0 *//* Corerev >= 13 */
290 u16 PAD[0x7]; /* 0x4f2 - 0x4fE */
291
292 /* TXE0 Block *//* 0x500 - 0x580 */
293 u16 txe_ctl; /* 0x500 */
294 u16 txe_aux; /* 0x502 */
295 u16 txe_ts_loc; /* 0x504 */
296 u16 txe_time_out; /* 0x506 */
297 u16 txe_wm_0; /* 0x508 */
298 u16 txe_wm_1; /* 0x50A */
299 u16 txe_phyctl; /* 0x50C */
300 u16 txe_status; /* 0x50E */
301 u16 txe_mmplcp0; /* 0x510 */
302 u16 txe_mmplcp1; /* 0x512 */
303 u16 txe_phyctl1; /* 0x514 */
304
305 u16 PAD[0x05]; /* 0x510 - 0x51E */
306
307 /* Transmit control */
308 u16 xmtfifodef; /* 0x520 */
309 u16 xmtfifo_frame_cnt; /* 0x522 *//* Corerev >= 16 */
310 u16 xmtfifo_byte_cnt; /* 0x524 *//* Corerev >= 16 */
311 u16 xmtfifo_head; /* 0x526 *//* Corerev >= 16 */
312 u16 xmtfifo_rd_ptr; /* 0x528 *//* Corerev >= 16 */
313 u16 xmtfifo_wr_ptr; /* 0x52A *//* Corerev >= 16 */
314 u16 xmtfifodef1; /* 0x52C *//* Corerev >= 16 */
315
316 u16 PAD[0x09]; /* 0x52E - 0x53E */
317
318 u16 xmtfifocmd; /* 0x540 */
319 u16 xmtfifoflush; /* 0x542 */
320 u16 xmtfifothresh; /* 0x544 */
321 u16 xmtfifordy; /* 0x546 */
322 u16 xmtfifoprirdy; /* 0x548 */
323 u16 xmtfiforqpri; /* 0x54A */
324 u16 xmttplatetxptr; /* 0x54C */
325 u16 PAD; /* 0x54E */
326 u16 xmttplateptr; /* 0x550 */
327 u16 smpl_clct_strptr; /* 0x552 *//* Corerev >= 22 */
328 u16 smpl_clct_stpptr; /* 0x554 *//* Corerev >= 22 */
329 u16 smpl_clct_curptr; /* 0x556 *//* Corerev >= 22 */
330 u16 PAD[0x04]; /* 0x558 - 0x55E */
331 u16 xmttplatedatalo; /* 0x560 */
332 u16 xmttplatedatahi; /* 0x562 */
333
334 u16 PAD[2]; /* 0x564 - 0x566 */
335
336 u16 xmtsel; /* 0x568 */
337 u16 xmttxcnt; /* 0x56A */
338 u16 xmttxshmaddr; /* 0x56C */
339
340 u16 PAD[0x09]; /* 0x56E - 0x57E */
341
342 /* TXE1 Block */
343 u16 PAD[0x40]; /* 0x580 - 0x5FE */
344
345 /* TSF Block */
346 u16 PAD[0X02]; /* 0x600 - 0x602 */
347 u16 tsf_cfpstrt_l; /* 0x604 */
348 u16 tsf_cfpstrt_h; /* 0x606 */
349 u16 PAD[0X05]; /* 0x608 - 0x610 */
350 u16 tsf_cfppretbtt; /* 0x612 */
351 u16 PAD[0XD]; /* 0x614 - 0x62C */
352 u16 tsf_clk_frac_l; /* 0x62E */
353 u16 tsf_clk_frac_h; /* 0x630 */
354 u16 PAD[0X14]; /* 0x632 - 0x658 */
355 u16 tsf_random; /* 0x65A */
356 u16 PAD[0x05]; /* 0x65C - 0x664 */
357 /* GPTimer 2 registers */
358 u16 tsf_gpt2_stat; /* 0x666 */
359 u16 tsf_gpt2_ctr_l; /* 0x668 */
360 u16 tsf_gpt2_ctr_h; /* 0x66A */
361 u16 tsf_gpt2_val_l; /* 0x66C */
362 u16 tsf_gpt2_val_h; /* 0x66E */
363 u16 tsf_gptall_stat; /* 0x670 */
364 u16 PAD[0x07]; /* 0x672 - 0x67E */
365
366 /* IFS Block */
367 u16 ifs_sifs_rx_tx_tx; /* 0x680 */
368 u16 ifs_sifs_nav_tx; /* 0x682 */
369 u16 ifs_slot; /* 0x684 */
370 u16 PAD; /* 0x686 */
371 u16 ifs_ctl; /* 0x688 */
372 u16 PAD[0x3]; /* 0x68a - 0x68F */
373 u16 ifsstat; /* 0x690 */
374 u16 ifsmedbusyctl; /* 0x692 */
375 u16 iftxdur; /* 0x694 */
376 u16 PAD[0x3]; /* 0x696 - 0x69b */
377 /* EDCF support in dot11macs */
378 u16 ifs_aifsn; /* 0x69c */
379 u16 ifs_ctl1; /* 0x69e */
380
381 /* slow clock registers */
382 u16 scc_ctl; /* 0x6a0 */
383 u16 scc_timer_l; /* 0x6a2 */
384 u16 scc_timer_h; /* 0x6a4 */
385 u16 scc_frac; /* 0x6a6 */
386 u16 scc_fastpwrup_dly; /* 0x6a8 */
387 u16 scc_per; /* 0x6aa */
388 u16 scc_per_frac; /* 0x6ac */
389 u16 scc_cal_timer_l; /* 0x6ae */
390 u16 scc_cal_timer_h; /* 0x6b0 */
391 u16 PAD; /* 0x6b2 */
392
393 u16 PAD[0x26];
394
395 /* NAV Block */
396 u16 nav_ctl; /* 0x700 */
397 u16 navstat; /* 0x702 */
398 u16 PAD[0x3e]; /* 0x702 - 0x77E */
399
400 /* WEP/PMQ Block *//* 0x780 - 0x7FE */
401 u16 PAD[0x20]; /* 0x780 - 0x7BE */
402
403 u16 wepctl; /* 0x7C0 */
404 u16 wepivloc; /* 0x7C2 */
405 u16 wepivkey; /* 0x7C4 */
406 u16 wepwkey; /* 0x7C6 */
407
408 u16 PAD[4]; /* 0x7C8 - 0x7CE */
409 u16 pcmctl; /* 0X7D0 */
410 u16 pcmstat; /* 0X7D2 */
411 u16 PAD[6]; /* 0x7D4 - 0x7DE */
412
413 u16 pmqctl; /* 0x7E0 */
414 u16 pmqstatus; /* 0x7E2 */
415 u16 pmqpat0; /* 0x7E4 */
416 u16 pmqpat1; /* 0x7E6 */
417 u16 pmqpat2; /* 0x7E8 */
418
419 u16 pmqdat; /* 0x7EA */
420 u16 pmqdator; /* 0x7EC */
421 u16 pmqhst; /* 0x7EE */
422 u16 pmqpath0; /* 0x7F0 */
423 u16 pmqpath1; /* 0x7F2 */
424 u16 pmqpath2; /* 0x7F4 */
425 u16 pmqdath; /* 0x7F6 */
426
427 u16 PAD[0x04]; /* 0x7F8 - 0x7FE */
428
429 /* SHM *//* 0x800 - 0xEFE */
430 u16 PAD[0x380]; /* 0x800 - 0xEFE */
431};
432
433#define PIHR_BASE 0x0400 /* byte address of packed IHR region */
434
435/* biststatus */
436#define BT_DONE (1U << 31) /* bist done */
437#define BT_B2S (1 << 30) /* bist2 ram summary bit */
438
439/* intstatus and intmask */
440#define I_PC (1 << 10) /* pci descriptor error */
441#define I_PD (1 << 11) /* pci data error */
442#define I_DE (1 << 12) /* descriptor protocol error */
443#define I_RU (1 << 13) /* receive descriptor underflow */
444#define I_RO (1 << 14) /* receive fifo overflow */
445#define I_XU (1 << 15) /* transmit fifo underflow */
446#define I_RI (1 << 16) /* receive interrupt */
447#define I_XI (1 << 24) /* transmit interrupt */
448
449/* interrupt receive lazy */
450#define IRL_TO_MASK 0x00ffffff /* timeout */
451#define IRL_FC_MASK 0xff000000 /* frame count */
452#define IRL_FC_SHIFT 24 /* frame count */
453
454/*== maccontrol register ==*/
455#define MCTL_GMODE (1U << 31)
456#define MCTL_DISCARD_PMQ (1 << 30)
457#define MCTL_WAKE (1 << 26)
458#define MCTL_HPS (1 << 25)
459#define MCTL_PROMISC (1 << 24)
460#define MCTL_KEEPBADFCS (1 << 23)
461#define MCTL_KEEPCONTROL (1 << 22)
462#define MCTL_PHYLOCK (1 << 21)
463#define MCTL_BCNS_PROMISC (1 << 20)
464#define MCTL_LOCK_RADIO (1 << 19)
465#define MCTL_AP (1 << 18)
466#define MCTL_INFRA (1 << 17)
467#define MCTL_BIGEND (1 << 16)
468#define MCTL_GPOUT_SEL_MASK (3 << 14)
469#define MCTL_GPOUT_SEL_SHIFT 14
470#define MCTL_EN_PSMDBG (1 << 13)
471#define MCTL_IHR_EN (1 << 10)
472#define MCTL_SHM_UPPER (1 << 9)
473#define MCTL_SHM_EN (1 << 8)
474#define MCTL_PSM_JMP_0 (1 << 2)
475#define MCTL_PSM_RUN (1 << 1)
476#define MCTL_EN_MAC (1 << 0)
477
478/*== maccommand register ==*/
479#define MCMD_BCN0VLD (1 << 0)
480#define MCMD_BCN1VLD (1 << 1)
481#define MCMD_DIRFRMQVAL (1 << 2)
482#define MCMD_CCA (1 << 3)
483#define MCMD_BG_NOISE (1 << 4)
484#define MCMD_SKIP_SHMINIT (1 << 5) /* only used for simulation */
485#define MCMD_SAMPLECOLL MCMD_SKIP_SHMINIT /* reuse for sample collect */
486
487/*== macintstatus/macintmask ==*/
488/* gracefully suspended */
489#define MI_MACSSPNDD (1 << 0)
490/* beacon template available */
491#define MI_BCNTPL (1 << 1)
492/* TBTT indication */
493#define MI_TBTT (1 << 2)
494/* beacon successfully tx'd */
495#define MI_BCNSUCCESS (1 << 3)
496/* beacon canceled (IBSS) */
497#define MI_BCNCANCLD (1 << 4)
498/* end of ATIM-window (IBSS) */
499#define MI_ATIMWINEND (1 << 5)
500/* PMQ entries available */
501#define MI_PMQ (1 << 6)
502/* non-specific gen-stat bits that are set by PSM */
503#define MI_NSPECGEN_0 (1 << 7)
504/* non-specific gen-stat bits that are set by PSM */
505#define MI_NSPECGEN_1 (1 << 8)
506/* MAC level Tx error */
507#define MI_MACTXERR (1 << 9)
508/* non-specific gen-stat bits that are set by PSM */
509#define MI_NSPECGEN_3 (1 << 10)
510/* PHY Tx error */
511#define MI_PHYTXERR (1 << 11)
512/* Power Management Event */
513#define MI_PME (1 << 12)
514/* General-purpose timer0 */
515#define MI_GP0 (1 << 13)
516/* General-purpose timer1 */
517#define MI_GP1 (1 << 14)
518/* (ORed) DMA-interrupts */
519#define MI_DMAINT (1 << 15)
520/* MAC has completed a TX FIFO Suspend/Flush */
521#define MI_TXSTOP (1 << 16)
522/* MAC has completed a CCA measurement */
523#define MI_CCA (1 << 17)
524/* MAC has collected background noise samples */
525#define MI_BG_NOISE (1 << 18)
526/* MBSS DTIM TBTT indication */
527#define MI_DTIM_TBTT (1 << 19)
528/* Probe response queue needs attention */
529#define MI_PRQ (1 << 20)
530/* Radio/PHY has been powered back up. */
531#define MI_PWRUP (1 << 21)
532#define MI_RESERVED3 (1 << 22)
533#define MI_RESERVED2 (1 << 23)
534#define MI_RESERVED1 (1 << 25)
535/* MAC detected change on RF Disable input*/
536#define MI_RFDISABLE (1 << 28)
537/* MAC has completed a TX */
538#define MI_TFS (1 << 29)
539/* A phy status change wrt G mode */
540#define MI_PHYCHANGED (1 << 30)
541/* general purpose timeout */
542#define MI_TO (1U << 31)
543
544/* Mac capabilities registers */
545/*== machwcap ==*/
546#define MCAP_TKIPMIC 0x80000000 /* TKIP MIC hardware present */
547
548/*== pmqhost data ==*/
549/* data entry of head pmq entry */
550#define PMQH_DATA_MASK 0xffff0000
551/* PM entry for BSS config */
552#define PMQH_BSSCFG 0x00100000
553/* PM Mode OFF: power save off */
554#define PMQH_PMOFF 0x00010000
555/* PM Mode ON: power save on */
556#define PMQH_PMON 0x00020000
557/* Dis-associated or De-authenticated */
558#define PMQH_DASAT 0x00040000
559/* ATIM not acknowledged */
560#define PMQH_ATIMFAIL 0x00080000
561/* delete head entry */
562#define PMQH_DEL_ENTRY 0x00000001
563/* delete head entry to cur read pointer -1 */
564#define PMQH_DEL_MULT 0x00000002
565/* pmq overflow indication */
566#define PMQH_OFLO 0x00000004
567/* entries are present in pmq */
568#define PMQH_NOT_EMPTY 0x00000008
569
570/*== phydebug ==*/
571/* phy is asserting carrier sense */
572#define PDBG_CRS (1 << 0)
573/* phy is taking xmit byte from mac this cycle */
574#define PDBG_TXA (1 << 1)
575/* mac is instructing the phy to transmit a frame */
576#define PDBG_TXF (1 << 2)
577/* phy is signalling a transmit Error to the mac */
578#define PDBG_TXE (1 << 3)
579/* phy detected the end of a valid frame preamble */
580#define PDBG_RXF (1 << 4)
581/* phy detected the end of a valid PLCP header */
582#define PDBG_RXS (1 << 5)
583/* rx start not asserted */
584#define PDBG_RXFRG (1 << 6)
585/* mac is taking receive byte from phy this cycle */
586#define PDBG_RXV (1 << 7)
587/* RF portion of the radio is disabled */
588#define PDBG_RFD (1 << 16)
589
590/*== objaddr register ==*/
591#define OBJADDR_SEL_MASK 0x000F0000
592#define OBJADDR_UCM_SEL 0x00000000
593#define OBJADDR_SHM_SEL 0x00010000
594#define OBJADDR_SCR_SEL 0x00020000
595#define OBJADDR_IHR_SEL 0x00030000
596#define OBJADDR_RCMTA_SEL 0x00040000
597#define OBJADDR_SRCHM_SEL 0x00060000
598#define OBJADDR_WINC 0x01000000
599#define OBJADDR_RINC 0x02000000
600#define OBJADDR_AUTO_INC 0x03000000
601
602#define WEP_PCMADDR 0x07d4
603#define WEP_PCMDATA 0x07d6
604
605/*== frmtxstatus ==*/
606#define TXS_V (1 << 0) /* valid bit */
607#define TXS_STATUS_MASK 0xffff
608#define TXS_FID_MASK 0xffff0000
609#define TXS_FID_SHIFT 16
610
611/*== frmtxstatus2 ==*/
612#define TXS_SEQ_MASK 0xffff
613#define TXS_PTX_MASK 0xff0000
614#define TXS_PTX_SHIFT 16
615#define TXS_MU_MASK 0x01000000
616#define TXS_MU_SHIFT 24
617
618/*== clk_ctl_st ==*/
619#define CCS_ERSRC_REQ_D11PLL 0x00000100 /* d11 core pll request */
620#define CCS_ERSRC_REQ_PHYPLL 0x00000200 /* PHY pll request */
621#define CCS_ERSRC_AVAIL_D11PLL 0x01000000 /* d11 core pll available */
622#define CCS_ERSRC_AVAIL_PHYPLL 0x02000000 /* PHY pll available */
623
624/* HT Cloclk Ctrl and Clock Avail for 4313 */
625#define CCS_ERSRC_REQ_HT 0x00000010 /* HT avail request */
626#define CCS_ERSRC_AVAIL_HT 0x00020000 /* HT clock available */
627
628/* tsf_cfprep register */
629#define CFPREP_CBI_MASK 0xffffffc0
630#define CFPREP_CBI_SHIFT 6
631#define CFPREP_CFPP 0x00000001
632
633/* tx fifo sizes values are in terms of 256 byte blocks */
634#define TXFIFOCMD_RESET_MASK (1 << 15) /* reset */
635#define TXFIFOCMD_FIFOSEL_SHIFT 8 /* fifo */
636#define TXFIFO_FIFOTOP_SHIFT 8 /* fifo start */
637
638#define TXFIFO_START_BLK16 65 /* Base address + 32 * 512 B/P */
639#define TXFIFO_START_BLK 6 /* Base address + 6 * 256 B */
640#define TXFIFO_SIZE_UNIT 256 /* one unit corresponds to 256 bytes */
641#define MBSS16_TEMPLMEM_MINBLKS 65 /* one unit corresponds to 256 bytes */
642
643/*== phy versions (PhyVersion:Revision field) ==*/
644/* analog block version */
645#define PV_AV_MASK 0xf000
646/* analog block version bitfield offset */
647#define PV_AV_SHIFT 12
648/* phy type */
649#define PV_PT_MASK 0x0f00
650/* phy type bitfield offset */
651#define PV_PT_SHIFT 8
652/* phy version */
653#define PV_PV_MASK 0x000f
654#define PHY_TYPE(v) ((v & PV_PT_MASK) >> PV_PT_SHIFT)
655
656/*== phy types (PhyVersion:PhyType field) ==*/
657#define PHY_TYPE_N 4 /* N-Phy value */
658#define PHY_TYPE_SSN 6 /* SSLPN-Phy value */
659#define PHY_TYPE_LCN 8 /* LCN-Phy value */
660#define PHY_TYPE_LCNXN 9 /* LCNXN-Phy value */
661#define PHY_TYPE_NULL 0xf /* Invalid Phy value */
662
663/*== analog types (PhyVersion:AnalogType field) ==*/
664#define ANA_11N_013 5
665
666/* 802.11a PLCP header def */
667struct ofdm_phy_hdr {
668 u8 rlpt[3]; /* rate, length, parity, tail */
669 u16 service;
670 u8 pad;
671} __packed;
672
673#define D11A_PHY_HDR_GRATE(phdr) ((phdr)->rlpt[0] & 0x0f)
674#define D11A_PHY_HDR_GRES(phdr) (((phdr)->rlpt[0] >> 4) & 0x01)
675#define D11A_PHY_HDR_GLENGTH(phdr) (((u32 *)((phdr)->rlpt) >> 5) & 0x0fff)
676#define D11A_PHY_HDR_GPARITY(phdr) (((phdr)->rlpt[3] >> 1) & 0x01)
677#define D11A_PHY_HDR_GTAIL(phdr) (((phdr)->rlpt[3] >> 2) & 0x3f)
678
679/* rate encoded per 802.11a-1999 sec 17.3.4.1 */
680#define D11A_PHY_HDR_SRATE(phdr, rate) \
681 ((phdr)->rlpt[0] = ((phdr)->rlpt[0] & 0xf0) | ((rate) & 0xf))
682/* set reserved field to zero */
683#define D11A_PHY_HDR_SRES(phdr) ((phdr)->rlpt[0] &= 0xef)
684/* length is number of octets in PSDU */
685#define D11A_PHY_HDR_SLENGTH(phdr, length) \
686 (*(u32 *)((phdr)->rlpt) = *(u32 *)((phdr)->rlpt) | \
687 (((length) & 0x0fff) << 5))
688/* set the tail to all zeros */
689#define D11A_PHY_HDR_STAIL(phdr) ((phdr)->rlpt[3] &= 0x03)
690
691#define D11A_PHY_HDR_LEN_L 3 /* low-rate part of PLCP header */
692#define D11A_PHY_HDR_LEN_R 2 /* high-rate part of PLCP header */
693
694#define D11A_PHY_TX_DELAY (2) /* 2.1 usec */
695
696#define D11A_PHY_HDR_TIME (4) /* low-rate part of PLCP header */
697#define D11A_PHY_PRE_TIME (16)
698#define D11A_PHY_PREHDR_TIME (D11A_PHY_PRE_TIME + D11A_PHY_HDR_TIME)
699
700/* 802.11b PLCP header def */
701struct cck_phy_hdr {
702 u8 signal;
703 u8 service;
704 u16 length;
705 u16 crc;
706} __packed;
707
708#define D11B_PHY_HDR_LEN 6
709
710#define D11B_PHY_TX_DELAY (3) /* 3.4 usec */
711
712#define D11B_PHY_LHDR_TIME (D11B_PHY_HDR_LEN << 3)
713#define D11B_PHY_LPRE_TIME (144)
714#define D11B_PHY_LPREHDR_TIME (D11B_PHY_LPRE_TIME + D11B_PHY_LHDR_TIME)
715
716#define D11B_PHY_SHDR_TIME (D11B_PHY_LHDR_TIME >> 1)
717#define D11B_PHY_SPRE_TIME (D11B_PHY_LPRE_TIME >> 1)
718#define D11B_PHY_SPREHDR_TIME (D11B_PHY_SPRE_TIME + D11B_PHY_SHDR_TIME)
719
720#define D11B_PLCP_SIGNAL_LOCKED (1 << 2)
721#define D11B_PLCP_SIGNAL_LE (1 << 7)
722
723#define MIMO_PLCP_MCS_MASK 0x7f /* mcs index */
724#define MIMO_PLCP_40MHZ 0x80 /* 40 Hz frame */
725#define MIMO_PLCP_AMPDU 0x08 /* ampdu */
726
727#define BRCMS_GET_CCK_PLCP_LEN(plcp) (plcp[4] + (plcp[5] << 8))
728#define BRCMS_GET_MIMO_PLCP_LEN(plcp) (plcp[1] + (plcp[2] << 8))
729#define BRCMS_SET_MIMO_PLCP_LEN(plcp, len) \
730 do { \
731 plcp[1] = len & 0xff; \
732 plcp[2] = ((len >> 8) & 0xff); \
733 } while (0);
734
735#define BRCMS_SET_MIMO_PLCP_AMPDU(plcp) (plcp[3] |= MIMO_PLCP_AMPDU)
736#define BRCMS_CLR_MIMO_PLCP_AMPDU(plcp) (plcp[3] &= ~MIMO_PLCP_AMPDU)
737#define BRCMS_IS_MIMO_PLCP_AMPDU(plcp) (plcp[3] & MIMO_PLCP_AMPDU)
738
739/*
740 * The dot11a PLCP header is 5 bytes. To simplify the software (so that we
741 * don't need e.g. different tx DMA headers for 11a and 11b), the PLCP header
742 * has padding added in the ucode.
743 */
744#define D11_PHY_HDR_LEN 6
745
746/* TX DMA buffer header */
747struct d11txh {
748 __le16 MacTxControlLow; /* 0x0 */
749 __le16 MacTxControlHigh; /* 0x1 */
750 __le16 MacFrameControl; /* 0x2 */
751 __le16 TxFesTimeNormal; /* 0x3 */
752 __le16 PhyTxControlWord; /* 0x4 */
753 __le16 PhyTxControlWord_1; /* 0x5 */
754 __le16 PhyTxControlWord_1_Fbr; /* 0x6 */
755 __le16 PhyTxControlWord_1_Rts; /* 0x7 */
756 __le16 PhyTxControlWord_1_FbrRts; /* 0x8 */
757 __le16 MainRates; /* 0x9 */
758 __le16 XtraFrameTypes; /* 0xa */
759 u8 IV[16]; /* 0x0b - 0x12 */
760 u8 TxFrameRA[6]; /* 0x13 - 0x15 */
761 __le16 TxFesTimeFallback; /* 0x16 */
762 u8 RTSPLCPFallback[6]; /* 0x17 - 0x19 */
763 __le16 RTSDurFallback; /* 0x1a */
764 u8 FragPLCPFallback[6]; /* 0x1b - 1d */
765 __le16 FragDurFallback; /* 0x1e */
766 __le16 MModeLen; /* 0x1f */
767 __le16 MModeFbrLen; /* 0x20 */
768 __le16 TstampLow; /* 0x21 */
769 __le16 TstampHigh; /* 0x22 */
770 __le16 ABI_MimoAntSel; /* 0x23 */
771 __le16 PreloadSize; /* 0x24 */
772 __le16 AmpduSeqCtl; /* 0x25 */
773 __le16 TxFrameID; /* 0x26 */
774 __le16 TxStatus; /* 0x27 */
775 __le16 MaxNMpdus; /* 0x28 */
776 __le16 MaxABytes_MRT; /* 0x29 */
777 __le16 MaxABytes_FBR; /* 0x2a */
778 __le16 MinMBytes; /* 0x2b */
779 u8 RTSPhyHeader[D11_PHY_HDR_LEN]; /* 0x2c - 0x2e */
780 struct ieee80211_rts rts_frame; /* 0x2f - 0x36 */
781 u16 PAD; /* 0x37 */
782} __packed;
783
784#define D11_TXH_LEN 112 /* bytes */
785
786/* Frame Types */
787#define FT_CCK 0
788#define FT_OFDM 1
789#define FT_HT 2
790#define FT_N 3
791
792/*
793 * Position of MPDU inside A-MPDU; indicated with bits 10:9
794 * of MacTxControlLow
795 */
796#define TXC_AMPDU_SHIFT 9 /* shift for ampdu settings */
797#define TXC_AMPDU_NONE 0 /* Regular MPDU, not an A-MPDU */
798#define TXC_AMPDU_FIRST 1 /* first MPDU of an A-MPDU */
799#define TXC_AMPDU_MIDDLE 2 /* intermediate MPDU of an A-MPDU */
800#define TXC_AMPDU_LAST 3 /* last (or single) MPDU of an A-MPDU */
801
802/*== MacTxControlLow ==*/
803#define TXC_AMIC 0x8000
804#define TXC_SENDCTS 0x0800
805#define TXC_AMPDU_MASK 0x0600
806#define TXC_BW_40 0x0100
807#define TXC_FREQBAND_5G 0x0080
808#define TXC_DFCS 0x0040
809#define TXC_IGNOREPMQ 0x0020
810#define TXC_HWSEQ 0x0010
811#define TXC_STARTMSDU 0x0008
812#define TXC_SENDRTS 0x0004
813#define TXC_LONGFRAME 0x0002
814#define TXC_IMMEDACK 0x0001
815
816/*== MacTxControlHigh ==*/
817/* RTS fallback preamble type 1 = SHORT 0 = LONG */
818#define TXC_PREAMBLE_RTS_FB_SHORT 0x8000
819/* RTS main rate preamble type 1 = SHORT 0 = LONG */
820#define TXC_PREAMBLE_RTS_MAIN_SHORT 0x4000
821/*
822 * Main fallback rate preamble type
823 * 1 = SHORT for OFDM/GF for MIMO
824 * 0 = LONG for CCK/MM for MIMO
825 */
826#define TXC_PREAMBLE_DATA_FB_SHORT 0x2000
827
828/* TXC_PREAMBLE_DATA_MAIN is in PhyTxControl bit 5 */
829/* use fallback rate for this AMPDU */
830#define TXC_AMPDU_FBR 0x1000
831#define TXC_SECKEY_MASK 0x0FF0
832#define TXC_SECKEY_SHIFT 4
833/* Use alternate txpwr defined at loc. M_ALT_TXPWR_IDX */
834#define TXC_ALT_TXPWR 0x0008
835#define TXC_SECTYPE_MASK 0x0007
836#define TXC_SECTYPE_SHIFT 0
837
838/* Null delimiter for Fallback rate */
839#define AMPDU_FBR_NULL_DELIM 5 /* Location of Null delimiter count for AMPDU */
840
841/* PhyTxControl for Mimophy */
842#define PHY_TXC_PWR_MASK 0xFC00
843#define PHY_TXC_PWR_SHIFT 10
844#define PHY_TXC_ANT_MASK 0x03C0 /* bit 6, 7, 8, 9 */
845#define PHY_TXC_ANT_SHIFT 6
846#define PHY_TXC_ANT_0_1 0x00C0 /* auto, last rx */
847#define PHY_TXC_LCNPHY_ANT_LAST 0x0000
848#define PHY_TXC_ANT_3 0x0200 /* virtual antenna 3 */
849#define PHY_TXC_ANT_2 0x0100 /* virtual antenna 2 */
850#define PHY_TXC_ANT_1 0x0080 /* virtual antenna 1 */
851#define PHY_TXC_ANT_0 0x0040 /* virtual antenna 0 */
852#define PHY_TXC_SHORT_HDR 0x0010
853
854#define PHY_TXC_OLD_ANT_0 0x0000
855#define PHY_TXC_OLD_ANT_1 0x0100
856#define PHY_TXC_OLD_ANT_LAST 0x0300
857
858/* PhyTxControl_1 for Mimophy */
859#define PHY_TXC1_BW_MASK 0x0007
860#define PHY_TXC1_BW_10MHZ 0
861#define PHY_TXC1_BW_10MHZ_UP 1
862#define PHY_TXC1_BW_20MHZ 2
863#define PHY_TXC1_BW_20MHZ_UP 3
864#define PHY_TXC1_BW_40MHZ 4
865#define PHY_TXC1_BW_40MHZ_DUP 5
866#define PHY_TXC1_MODE_SHIFT 3
867#define PHY_TXC1_MODE_MASK 0x0038
868#define PHY_TXC1_MODE_SISO 0
869#define PHY_TXC1_MODE_CDD 1
870#define PHY_TXC1_MODE_STBC 2
871#define PHY_TXC1_MODE_SDM 3
872
873/* PhyTxControl for HTphy that are different from Mimophy */
874#define PHY_TXC_HTANT_MASK 0x3fC0 /* bits 6-13 */
875
876/* XtraFrameTypes */
877#define XFTS_RTS_FT_SHIFT 2
878#define XFTS_FBRRTS_FT_SHIFT 4
879#define XFTS_CHANNEL_SHIFT 8
880
881/* Antenna diversity bit in ant_wr_settle */
882#define PHY_AWS_ANTDIV 0x2000
883
884/* IFS ctl */
885#define IFS_USEEDCF (1 << 2)
886
887/* IFS ctl1 */
888#define IFS_CTL1_EDCRS (1 << 3)
889#define IFS_CTL1_EDCRS_20L (1 << 4)
890#define IFS_CTL1_EDCRS_40 (1 << 5)
891
892/* ABI_MimoAntSel */
893#define ABI_MAS_ADDR_BMP_IDX_MASK 0x0f00
894#define ABI_MAS_ADDR_BMP_IDX_SHIFT 8
895#define ABI_MAS_FBR_ANT_PTN_MASK 0x00f0
896#define ABI_MAS_FBR_ANT_PTN_SHIFT 4
897#define ABI_MAS_MRT_ANT_PTN_MASK 0x000f
898
899/* tx status packet */
900struct tx_status {
901 u16 framelen;
902 u16 PAD;
903 u16 frameid;
904 u16 status;
905 u16 lasttxtime;
906 u16 sequence;
907 u16 phyerr;
908 u16 ackphyrxsh;
909} __packed;
910
911#define TXSTATUS_LEN 16
912
913/* status field bit definitions */
914#define TX_STATUS_FRM_RTX_MASK 0xF000
915#define TX_STATUS_FRM_RTX_SHIFT 12
916#define TX_STATUS_RTS_RTX_MASK 0x0F00
917#define TX_STATUS_RTS_RTX_SHIFT 8
918#define TX_STATUS_MASK 0x00FE
919#define TX_STATUS_PMINDCTD (1 << 7) /* PM mode indicated to AP */
920#define TX_STATUS_INTERMEDIATE (1 << 6) /* intermediate or 1st ampdu pkg */
921#define TX_STATUS_AMPDU (1 << 5) /* AMPDU status */
922#define TX_STATUS_SUPR_MASK 0x1C /* suppress status bits (4:2) */
923#define TX_STATUS_SUPR_SHIFT 2
924#define TX_STATUS_ACK_RCV (1 << 1) /* ACK received */
925#define TX_STATUS_VALID (1 << 0) /* Tx status valid */
926#define TX_STATUS_NO_ACK 0
927
928/* suppress status reason codes */
929#define TX_STATUS_SUPR_PMQ (1 << 2) /* PMQ entry */
930#define TX_STATUS_SUPR_FLUSH (2 << 2) /* flush request */
931#define TX_STATUS_SUPR_FRAG (3 << 2) /* previous frag failure */
932#define TX_STATUS_SUPR_TBTT (3 << 2) /* SHARED: Probe resp supr for TBTT */
933#define TX_STATUS_SUPR_BADCH (4 << 2) /* channel mismatch */
934#define TX_STATUS_SUPR_EXPTIME (5 << 2) /* lifetime expiry */
935#define TX_STATUS_SUPR_UF (6 << 2) /* underflow */
936
937/* Unexpected tx status for rate update */
938#define TX_STATUS_UNEXP(status) \
939 ((((status) & TX_STATUS_INTERMEDIATE) != 0) && \
940 TX_STATUS_UNEXP_AMPDU(status))
941
942/* Unexpected tx status for A-MPDU rate update */
943#define TX_STATUS_UNEXP_AMPDU(status) \
944 ((((status) & TX_STATUS_SUPR_MASK) != 0) && \
945 (((status) & TX_STATUS_SUPR_MASK) != TX_STATUS_SUPR_EXPTIME))
946
947#define TX_STATUS_BA_BMAP03_MASK 0xF000 /* ba bitmap 0:3 in 1st pkg */
948#define TX_STATUS_BA_BMAP03_SHIFT 12 /* ba bitmap 0:3 in 1st pkg */
949#define TX_STATUS_BA_BMAP47_MASK 0x001E /* ba bitmap 4:7 in 2nd pkg */
950#define TX_STATUS_BA_BMAP47_SHIFT 3 /* ba bitmap 4:7 in 2nd pkg */
951
952/* RXE (Receive Engine) */
953
954/* RCM_CTL */
955#define RCM_INC_MASK_H 0x0080
956#define RCM_INC_MASK_L 0x0040
957#define RCM_INC_DATA 0x0020
958#define RCM_INDEX_MASK 0x001F
959#define RCM_SIZE 15
960
961#define RCM_MAC_OFFSET 0 /* current MAC address */
962#define RCM_BSSID_OFFSET 3 /* current BSSID address */
963#define RCM_F_BSSID_0_OFFSET 6 /* foreign BSS CFP tracking */
964#define RCM_F_BSSID_1_OFFSET 9 /* foreign BSS CFP tracking */
965#define RCM_F_BSSID_2_OFFSET 12 /* foreign BSS CFP tracking */
966
967#define RCM_WEP_TA0_OFFSET 16
968#define RCM_WEP_TA1_OFFSET 19
969#define RCM_WEP_TA2_OFFSET 22
970#define RCM_WEP_TA3_OFFSET 25
971
972/* PSM Block */
973
974/* psm_phy_hdr_param bits */
975#define MAC_PHY_RESET 1
976#define MAC_PHY_CLOCK_EN 2
977#define MAC_PHY_FORCE_CLK 4
978
979/* WEP Block */
980
981/* WEP_WKEY */
982#define WKEY_START (1 << 8)
983#define WKEY_SEL_MASK 0x1F
984
985/* WEP data formats */
986
987/* the number of RCMTA entries */
988#define RCMTA_SIZE 50
989
990#define M_ADDR_BMP_BLK (0x37e * 2)
991#define M_ADDR_BMP_BLK_SZ 12
992
993#define ADDR_BMP_RA (1 << 0) /* Receiver Address (RA) */
994#define ADDR_BMP_TA (1 << 1) /* Transmitter Address (TA) */
995#define ADDR_BMP_BSSID (1 << 2) /* BSSID */
996#define ADDR_BMP_AP (1 << 3) /* Infra-BSS Access Point */
997#define ADDR_BMP_STA (1 << 4) /* Infra-BSS Station */
998#define ADDR_BMP_RESERVED1 (1 << 5)
999#define ADDR_BMP_RESERVED2 (1 << 6)
1000#define ADDR_BMP_RESERVED3 (1 << 7)
1001#define ADDR_BMP_BSS_IDX_MASK (3 << 8) /* BSS control block index */
1002#define ADDR_BMP_BSS_IDX_SHIFT 8
1003
1004#define WSEC_MAX_RCMTA_KEYS 54
1005
1006/* max keys in M_TKMICKEYS_BLK */
1007#define WSEC_MAX_TKMIC_ENGINE_KEYS 12 /* 8 + 4 default */
1008
1009/* max RXE match registers */
1010#define WSEC_MAX_RXE_KEYS 4
1011
1012/* SECKINDXALGO (Security Key Index & Algorithm Block) word format */
1013/* SKL (Security Key Lookup) */
1014#define SKL_ALGO_MASK 0x0007
1015#define SKL_ALGO_SHIFT 0
1016#define SKL_KEYID_MASK 0x0008
1017#define SKL_KEYID_SHIFT 3
1018#define SKL_INDEX_MASK 0x03F0
1019#define SKL_INDEX_SHIFT 4
1020#define SKL_GRP_ALGO_MASK 0x1c00
1021#define SKL_GRP_ALGO_SHIFT 10
1022
1023/* additional bits defined for IBSS group key support */
1024#define SKL_IBSS_INDEX_MASK 0x01F0
1025#define SKL_IBSS_INDEX_SHIFT 4
1026#define SKL_IBSS_KEYID1_MASK 0x0600
1027#define SKL_IBSS_KEYID1_SHIFT 9
1028#define SKL_IBSS_KEYID2_MASK 0x1800
1029#define SKL_IBSS_KEYID2_SHIFT 11
1030#define SKL_IBSS_KEYALGO_MASK 0xE000
1031#define SKL_IBSS_KEYALGO_SHIFT 13
1032
1033#define WSEC_MODE_OFF 0
1034#define WSEC_MODE_HW 1
1035#define WSEC_MODE_SW 2
1036
1037#define WSEC_ALGO_OFF 0
1038#define WSEC_ALGO_WEP1 1
1039#define WSEC_ALGO_TKIP 2
1040#define WSEC_ALGO_AES 3
1041#define WSEC_ALGO_WEP128 4
1042#define WSEC_ALGO_AES_LEGACY 5
1043#define WSEC_ALGO_NALG 6
1044
1045#define AES_MODE_NONE 0
1046#define AES_MODE_CCM 1
1047
1048/* WEP_CTL (Rev 0) */
1049#define WECR0_KEYREG_SHIFT 0
1050#define WECR0_KEYREG_MASK 0x7
1051#define WECR0_DECRYPT (1 << 3)
1052#define WECR0_IVINLINE (1 << 4)
1053#define WECR0_WEPALG_SHIFT 5
1054#define WECR0_WEPALG_MASK (0x7 << 5)
1055#define WECR0_WKEYSEL_SHIFT 8
1056#define WECR0_WKEYSEL_MASK (0x7 << 8)
1057#define WECR0_WKEYSTART (1 << 11)
1058#define WECR0_WEPINIT (1 << 14)
1059#define WECR0_ICVERR (1 << 15)
1060
1061/* Frame template map byte offsets */
1062#define T_ACTS_TPL_BASE (0)
1063#define T_NULL_TPL_BASE (0xc * 2)
1064#define T_QNULL_TPL_BASE (0x1c * 2)
1065#define T_RR_TPL_BASE (0x2c * 2)
1066#define T_BCN0_TPL_BASE (0x34 * 2)
1067#define T_PRS_TPL_BASE (0x134 * 2)
1068#define T_BCN1_TPL_BASE (0x234 * 2)
1069#define T_TX_FIFO_TXRAM_BASE (T_ACTS_TPL_BASE + \
1070 (TXFIFO_START_BLK * TXFIFO_SIZE_UNIT))
1071
1072#define T_BA_TPL_BASE T_QNULL_TPL_BASE /* template area for BA */
1073
1074#define T_RAM_ACCESS_SZ 4 /* template ram is 4 byte access only */
1075
1076/* Shared Mem byte offsets */
1077
1078/* Location where the ucode expects the corerev */
1079#define M_MACHW_VER (0x00b * 2)
1080
1081/* Location where the ucode expects the MAC capabilities */
1082#define M_MACHW_CAP_L (0x060 * 2)
1083#define M_MACHW_CAP_H (0x061 * 2)
1084
1085/* WME shared memory */
1086#define M_EDCF_STATUS_OFF (0x007 * 2)
1087#define M_TXF_CUR_INDEX (0x018 * 2)
1088#define M_EDCF_QINFO (0x120 * 2)
1089
1090/* PS-mode related parameters */
1091#define M_DOT11_SLOT (0x008 * 2)
1092#define M_DOT11_DTIMPERIOD (0x009 * 2)
1093#define M_NOSLPZNATDTIM (0x026 * 2)
1094
1095/* Beacon-related parameters */
1096#define M_BCN0_FRM_BYTESZ (0x00c * 2) /* Bcn 0 template length */
1097#define M_BCN1_FRM_BYTESZ (0x00d * 2) /* Bcn 1 template length */
1098#define M_BCN_TXTSF_OFFSET (0x00e * 2)
1099#define M_TIMBPOS_INBEACON (0x00f * 2)
1100#define M_SFRMTXCNTFBRTHSD (0x022 * 2)
1101#define M_LFRMTXCNTFBRTHSD (0x023 * 2)
1102#define M_BCN_PCTLWD (0x02a * 2)
1103#define M_BCN_LI (0x05b * 2) /* beacon listen interval */
1104
1105/* MAX Rx Frame len */
1106#define M_MAXRXFRM_LEN (0x010 * 2)
1107
1108/* ACK/CTS related params */
1109#define M_RSP_PCTLWD (0x011 * 2)
1110
1111/* Hardware Power Control */
1112#define M_TXPWR_N (0x012 * 2)
1113#define M_TXPWR_TARGET (0x013 * 2)
1114#define M_TXPWR_MAX (0x014 * 2)
1115#define M_TXPWR_CUR (0x019 * 2)
1116
1117/* Rx-related parameters */
1118#define M_RX_PAD_DATA_OFFSET (0x01a * 2)
1119
1120/* WEP Shared mem data */
1121#define M_SEC_DEFIVLOC (0x01e * 2)
1122#define M_SEC_VALNUMSOFTMCHTA (0x01f * 2)
1123#define M_PHYVER (0x028 * 2)
1124#define M_PHYTYPE (0x029 * 2)
1125#define M_SECRXKEYS_PTR (0x02b * 2)
1126#define M_TKMICKEYS_PTR (0x059 * 2)
1127#define M_SECKINDXALGO_BLK (0x2ea * 2)
1128#define M_SECKINDXALGO_BLK_SZ 54
1129#define M_SECPSMRXTAMCH_BLK (0x2fa * 2)
1130#define M_TKIP_TSC_TTAK (0x18c * 2)
1131#define D11_MAX_KEY_SIZE 16
1132
1133#define M_MAX_ANTCNT (0x02e * 2) /* antenna swap threshold */
1134
1135/* Probe response related parameters */
1136#define M_SSIDLEN (0x024 * 2)
1137#define M_PRB_RESP_FRM_LEN (0x025 * 2)
1138#define M_PRS_MAXTIME (0x03a * 2)
1139#define M_SSID (0xb0 * 2)
1140#define M_CTXPRS_BLK (0xc0 * 2)
1141#define C_CTX_PCTLWD_POS (0x4 * 2)
1142
1143/* Delta between OFDM and CCK power in CCK power boost mode */
1144#define M_OFDM_OFFSET (0x027 * 2)
1145
1146/* TSSI for last 4 11b/g CCK packets transmitted */
1147#define M_B_TSSI_0 (0x02c * 2)
1148#define M_B_TSSI_1 (0x02d * 2)
1149
1150/* Host flags to turn on ucode options */
1151#define M_HOST_FLAGS1 (0x02f * 2)
1152#define M_HOST_FLAGS2 (0x030 * 2)
1153#define M_HOST_FLAGS3 (0x031 * 2)
1154#define M_HOST_FLAGS4 (0x03c * 2)
1155#define M_HOST_FLAGS5 (0x06a * 2)
1156#define M_HOST_FLAGS_SZ 16
1157
1158#define M_RADAR_REG (0x033 * 2)
1159
1160/* TSSI for last 4 11a OFDM packets transmitted */
1161#define M_A_TSSI_0 (0x034 * 2)
1162#define M_A_TSSI_1 (0x035 * 2)
1163
1164/* noise interference measurement */
1165#define M_NOISE_IF_COUNT (0x034 * 2)
1166#define M_NOISE_IF_TIMEOUT (0x035 * 2)
1167
1168#define M_RF_RX_SP_REG1 (0x036 * 2)
1169
1170/* TSSI for last 4 11g OFDM packets transmitted */
1171#define M_G_TSSI_0 (0x038 * 2)
1172#define M_G_TSSI_1 (0x039 * 2)
1173
1174/* Background noise measure */
1175#define M_JSSI_0 (0x44 * 2)
1176#define M_JSSI_1 (0x45 * 2)
1177#define M_JSSI_AUX (0x46 * 2)
1178
1179#define M_CUR_2050_RADIOCODE (0x47 * 2)
1180
1181/* TX fifo sizes */
1182#define M_FIFOSIZE0 (0x4c * 2)
1183#define M_FIFOSIZE1 (0x4d * 2)
1184#define M_FIFOSIZE2 (0x4e * 2)
1185#define M_FIFOSIZE3 (0x4f * 2)
1186#define D11_MAX_TX_FRMS 32 /* max frames allowed in tx fifo */
1187
1188/* Current channel number plus upper bits */
1189#define M_CURCHANNEL (0x50 * 2)
1190#define D11_CURCHANNEL_5G 0x0100;
1191#define D11_CURCHANNEL_40 0x0200;
1192#define D11_CURCHANNEL_MAX 0x00FF;
1193
1194/* last posted frameid on the bcmc fifo */
1195#define M_BCMC_FID (0x54 * 2)
1196#define INVALIDFID 0xffff
1197
1198/* extended beacon phyctl bytes for 11N */
1199#define M_BCN_PCTL1WD (0x058 * 2)
1200
1201/* idle busy ratio to duty_cycle requirement */
1202#define M_TX_IDLE_BUSY_RATIO_X_16_CCK (0x52 * 2)
1203#define M_TX_IDLE_BUSY_RATIO_X_16_OFDM (0x5A * 2)
1204
1205/* CW RSSI for LCNPHY */
1206#define M_LCN_RSSI_0 0x1332
1207#define M_LCN_RSSI_1 0x1338
1208#define M_LCN_RSSI_2 0x133e
1209#define M_LCN_RSSI_3 0x1344
1210
1211/* SNR for LCNPHY */
1212#define M_LCN_SNR_A_0 0x1334
1213#define M_LCN_SNR_B_0 0x1336
1214
1215#define M_LCN_SNR_A_1 0x133a
1216#define M_LCN_SNR_B_1 0x133c
1217
1218#define M_LCN_SNR_A_2 0x1340
1219#define M_LCN_SNR_B_2 0x1342
1220
1221#define M_LCN_SNR_A_3 0x1346
1222#define M_LCN_SNR_B_3 0x1348
1223
1224#define M_LCN_LAST_RESET (81*2)
1225#define M_LCN_LAST_LOC (63*2)
1226#define M_LCNPHY_RESET_STATUS (4902)
1227#define M_LCNPHY_DSC_TIME (0x98d*2)
1228#define M_LCNPHY_RESET_CNT_DSC (0x98b*2)
1229#define M_LCNPHY_RESET_CNT (0x98c*2)
1230
1231/* Rate table offsets */
1232#define M_RT_DIRMAP_A (0xe0 * 2)
1233#define M_RT_BBRSMAP_A (0xf0 * 2)
1234#define M_RT_DIRMAP_B (0x100 * 2)
1235#define M_RT_BBRSMAP_B (0x110 * 2)
1236
1237/* Rate table entry offsets */
1238#define M_RT_PRS_PLCP_POS 10
1239#define M_RT_PRS_DUR_POS 16
1240#define M_RT_OFDM_PCTL1_POS 18
1241
1242#define M_20IN40_IQ (0x380 * 2)
1243
1244/* SHM locations where ucode stores the current power index */
1245#define M_CURR_IDX1 (0x384 * 2)
1246#define M_CURR_IDX2 (0x387 * 2)
1247
1248#define M_BSCALE_ANT0 (0x5e * 2)
1249#define M_BSCALE_ANT1 (0x5f * 2)
1250
1251/* Antenna Diversity Testing */
1252#define M_MIMO_ANTSEL_RXDFLT (0x63 * 2)
1253#define M_ANTSEL_CLKDIV (0x61 * 2)
1254#define M_MIMO_ANTSEL_TXDFLT (0x64 * 2)
1255
1256#define M_MIMO_MAXSYM (0x5d * 2)
1257#define MIMO_MAXSYM_DEF 0x8000 /* 32k */
1258#define MIMO_MAXSYM_MAX 0xffff /* 64k */
1259
1260#define M_WATCHDOG_8TU (0x1e * 2)
1261#define WATCHDOG_8TU_DEF 5
1262#define WATCHDOG_8TU_MAX 10
1263
1264/* Manufacturing Test Variables */
1265/* PER test mode */
1266#define M_PKTENG_CTRL (0x6c * 2)
1267/* IFS for TX mode */
1268#define M_PKTENG_IFS (0x6d * 2)
1269/* Lower word of tx frmcnt/rx lostcnt */
1270#define M_PKTENG_FRMCNT_LO (0x6e * 2)
1271/* Upper word of tx frmcnt/rx lostcnt */
1272#define M_PKTENG_FRMCNT_HI (0x6f * 2)
1273
1274/* Index variation in vbat ripple */
1275#define M_LCN_PWR_IDX_MAX (0x67 * 2) /* highest index read by ucode */
1276#define M_LCN_PWR_IDX_MIN (0x66 * 2) /* lowest index read by ucode */
1277
1278/* M_PKTENG_CTRL bit definitions */
1279#define M_PKTENG_MODE_TX 0x0001
1280#define M_PKTENG_MODE_TX_RIFS 0x0004
1281#define M_PKTENG_MODE_TX_CTS 0x0008
1282#define M_PKTENG_MODE_RX 0x0002
1283#define M_PKTENG_MODE_RX_WITH_ACK 0x0402
1284#define M_PKTENG_MODE_MASK 0x0003
1285/* TX frames indicated in the frmcnt reg */
1286#define M_PKTENG_FRMCNT_VLD 0x0100
1287
1288/* Sample Collect parameters (bitmap and type) */
1289/* Trigger bitmap for sample collect */
1290#define M_SMPL_COL_BMP (0x37d * 2)
1291/* Sample collect type */
1292#define M_SMPL_COL_CTL (0x3b2 * 2)
1293
1294#define ANTSEL_CLKDIV_4MHZ 6
1295#define MIMO_ANTSEL_BUSY 0x4000 /* bit 14 (busy) */
1296#define MIMO_ANTSEL_SEL 0x8000 /* bit 15 write the value */
1297#define MIMO_ANTSEL_WAIT 50 /* 50us wait */
1298#define MIMO_ANTSEL_OVERRIDE 0x8000 /* flag */
1299
1300struct shm_acparams {
1301 u16 txop;
1302 u16 cwmin;
1303 u16 cwmax;
1304 u16 cwcur;
1305 u16 aifs;
1306 u16 bslots;
1307 u16 reggap;
1308 u16 status;
1309 u16 rsvd[8];
1310} __packed;
1311#define M_EDCF_QLEN (16 * 2)
1312
1313#define WME_STATUS_NEWAC (1 << 8)
1314
1315/* M_HOST_FLAGS */
1316#define MHFMAX 5 /* Number of valid hostflag half-word (u16) */
1317#define MHF1 0 /* Hostflag 1 index */
1318#define MHF2 1 /* Hostflag 2 index */
1319#define MHF3 2 /* Hostflag 3 index */
1320#define MHF4 3 /* Hostflag 4 index */
1321#define MHF5 4 /* Hostflag 5 index */
1322
1323/* Flags in M_HOST_FLAGS */
1324/* Enable ucode antenna diversity help */
1325#define MHF1_ANTDIV 0x0001
1326/* Enable EDCF access control */
1327#define MHF1_EDCF 0x0100
1328#define MHF1_IQSWAP_WAR 0x0200
1329/* Disable Slow clock request, for corerev < 11 */
1330#define MHF1_FORCEFASTCLK 0x0400
1331
1332/* Flags in M_HOST_FLAGS2 */
1333
1334/* Flush BCMC FIFO immediately */
1335#define MHF2_TXBCMC_NOW 0x0040
1336/* Enable ucode/hw power control */
1337#define MHF2_HWPWRCTL 0x0080
1338#define MHF2_NPHY40MHZ_WAR 0x0800
1339
1340/* Flags in M_HOST_FLAGS3 */
1341/* enabled mimo antenna selection */
1342#define MHF3_ANTSEL_EN 0x0001
1343/* antenna selection mode: 0: 2x3, 1: 2x4 */
1344#define MHF3_ANTSEL_MODE 0x0002
1345#define MHF3_RESERVED1 0x0004
1346#define MHF3_RESERVED2 0x0008
1347#define MHF3_NPHY_MLADV_WAR 0x0010
1348
1349/* Flags in M_HOST_FLAGS4 */
1350/* force bphy Tx on core 0 (board level WAR) */
1351#define MHF4_BPHY_TXCORE0 0x0080
1352/* for 4313A0 FEM boards */
1353#define MHF4_EXTPA_ENABLE 0x4000
1354
1355/* Flags in M_HOST_FLAGS5 */
1356#define MHF5_4313_GPIOCTRL 0x0001
1357#define MHF5_RESERVED1 0x0002
1358#define MHF5_RESERVED2 0x0004
1359/* Radio power setting for ucode */
1360#define M_RADIO_PWR (0x32 * 2)
1361
1362/* phy noise recorded by ucode right after tx */
1363#define M_PHY_NOISE (0x037 * 2)
1364#define PHY_NOISE_MASK 0x00ff
1365
1366/*
1367 * Receive Frame Data Header for 802.11b DCF-only frames
1368 *
1369 * RxFrameSize: Actual byte length of the frame data received
1370 * PAD: padding (not used)
1371 * PhyRxStatus_0: PhyRxStatus 15:0
1372 * PhyRxStatus_1: PhyRxStatus 31:16
1373 * PhyRxStatus_2: PhyRxStatus 47:32
1374 * PhyRxStatus_3: PhyRxStatus 63:48
1375 * PhyRxStatus_4: PhyRxStatus 79:64
1376 * PhyRxStatus_5: PhyRxStatus 95:80
1377 * RxStatus1: MAC Rx Status
1378 * RxStatus2: extended MAC Rx status
1379 * RxTSFTime: RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY
1380 * RxChan: gain code, channel radio code, and phy type
1381 */
1382struct d11rxhdr_le {
1383 __le16 RxFrameSize;
1384 u16 PAD;
1385 __le16 PhyRxStatus_0;
1386 __le16 PhyRxStatus_1;
1387 __le16 PhyRxStatus_2;
1388 __le16 PhyRxStatus_3;
1389 __le16 PhyRxStatus_4;
1390 __le16 PhyRxStatus_5;
1391 __le16 RxStatus1;
1392 __le16 RxStatus2;
1393 __le16 RxTSFTime;
1394 __le16 RxChan;
1395} __packed;
1396
1397struct d11rxhdr {
1398 u16 RxFrameSize;
1399 u16 PAD;
1400 u16 PhyRxStatus_0;
1401 u16 PhyRxStatus_1;
1402 u16 PhyRxStatus_2;
1403 u16 PhyRxStatus_3;
1404 u16 PhyRxStatus_4;
1405 u16 PhyRxStatus_5;
1406 u16 RxStatus1;
1407 u16 RxStatus2;
1408 u16 RxTSFTime;
1409 u16 RxChan;
1410} __packed;
1411
1412/* PhyRxStatus_0: */
1413/* NPHY only: CCK, OFDM, preN, N */
1414#define PRXS0_FT_MASK 0x0003
1415/* NPHY only: clip count adjustment steps by AGC */
1416#define PRXS0_CLIP_MASK 0x000C
1417#define PRXS0_CLIP_SHIFT 2
1418/* PHY received a frame with unsupported rate */
1419#define PRXS0_UNSRATE 0x0010
1420/* GPHY: rx ant, NPHY: upper sideband */
1421#define PRXS0_RXANT_UPSUBBAND 0x0020
1422/* CCK frame only: lost crs during cck frame reception */
1423#define PRXS0_LCRS 0x0040
1424/* Short Preamble */
1425#define PRXS0_SHORTH 0x0080
1426/* PLCP violation */
1427#define PRXS0_PLCPFV 0x0100
1428/* PLCP header integrity check failed */
1429#define PRXS0_PLCPHCF 0x0200
1430/* legacy PHY gain control */
1431#define PRXS0_GAIN_CTL 0x4000
1432/* NPHY: Antennas used for received frame, bitmask */
1433#define PRXS0_ANTSEL_MASK 0xF000
1434#define PRXS0_ANTSEL_SHIFT 0x12
1435
1436/* subfield PRXS0_FT_MASK */
1437#define PRXS0_CCK 0x0000
1438/* valid only for G phy, use rxh->RxChan for A phy */
1439#define PRXS0_OFDM 0x0001
1440#define PRXS0_PREN 0x0002
1441#define PRXS0_STDN 0x0003
1442
1443/* subfield PRXS0_ANTSEL_MASK */
1444#define PRXS0_ANTSEL_0 0x0 /* antenna 0 is used */
1445#define PRXS0_ANTSEL_1 0x2 /* antenna 1 is used */
1446#define PRXS0_ANTSEL_2 0x4 /* antenna 2 is used */
1447#define PRXS0_ANTSEL_3 0x8 /* antenna 3 is used */
1448
1449/* PhyRxStatus_1: */
1450#define PRXS1_JSSI_MASK 0x00FF
1451#define PRXS1_JSSI_SHIFT 0
1452#define PRXS1_SQ_MASK 0xFF00
1453#define PRXS1_SQ_SHIFT 8
1454
1455/* nphy PhyRxStatus_1: */
1456#define PRXS1_nphy_PWR0_MASK 0x00FF
1457#define PRXS1_nphy_PWR1_MASK 0xFF00
1458
1459/* HTPHY Rx Status defines */
1460/* htphy PhyRxStatus_0: those bit are overlapped with PhyRxStatus_0 */
1461#define PRXS0_BAND 0x0400 /* 0 = 2.4G, 1 = 5G */
1462#define PRXS0_RSVD 0x0800 /* reserved; set to 0 */
1463#define PRXS0_UNUSED 0xF000 /* unused and not defined; set to 0 */
1464
1465/* htphy PhyRxStatus_1: */
1466/* core enables for {3..0}, 0=disabled, 1=enabled */
1467#define PRXS1_HTPHY_CORE_MASK 0x000F
1468/* antenna configation */
1469#define PRXS1_HTPHY_ANTCFG_MASK 0x00F0
1470/* Mixmode PLCP Length low byte mask */
1471#define PRXS1_HTPHY_MMPLCPLenL_MASK 0xFF00
1472
1473/* htphy PhyRxStatus_2: */
1474/* Mixmode PLCP Length high byte maskw */
1475#define PRXS2_HTPHY_MMPLCPLenH_MASK 0x000F
1476/* Mixmode PLCP rate mask */
1477#define PRXS2_HTPHY_MMPLCH_RATE_MASK 0x00F0
1478/* Rx power on core 0 */
1479#define PRXS2_HTPHY_RXPWR_ANT0 0xFF00
1480
1481/* htphy PhyRxStatus_3: */
1482/* Rx power on core 1 */
1483#define PRXS3_HTPHY_RXPWR_ANT1 0x00FF
1484/* Rx power on core 2 */
1485#define PRXS3_HTPHY_RXPWR_ANT2 0xFF00
1486
1487/* htphy PhyRxStatus_4: */
1488/* Rx power on core 3 */
1489#define PRXS4_HTPHY_RXPWR_ANT3 0x00FF
1490/* Coarse frequency offset */
1491#define PRXS4_HTPHY_CFO 0xFF00
1492
1493/* htphy PhyRxStatus_5: */
1494/* Fine frequency offset */
1495#define PRXS5_HTPHY_FFO 0x00FF
1496/* Advance Retard */
1497#define PRXS5_HTPHY_AR 0xFF00
1498
1499#define HTPHY_MMPLCPLen(rxs) \
1500 ((((rxs)->PhyRxStatus_1 & PRXS1_HTPHY_MMPLCPLenL_MASK) >> 8) | \
1501 (((rxs)->PhyRxStatus_2 & PRXS2_HTPHY_MMPLCPLenH_MASK) << 8))
1502/* Get Rx power on core 0 */
1503#define HTPHY_RXPWR_ANT0(rxs) \
1504 ((((rxs)->PhyRxStatus_2) & PRXS2_HTPHY_RXPWR_ANT0) >> 8)
1505/* Get Rx power on core 1 */
1506#define HTPHY_RXPWR_ANT1(rxs) \
1507 (((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT1)
1508/* Get Rx power on core 2 */
1509#define HTPHY_RXPWR_ANT2(rxs) \
1510 ((((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT2) >> 8)
1511
1512/* ucode RxStatus1: */
1513#define RXS_BCNSENT 0x8000
1514#define RXS_SECKINDX_MASK 0x07e0
1515#define RXS_SECKINDX_SHIFT 5
1516#define RXS_DECERR (1 << 4)
1517#define RXS_DECATMPT (1 << 3)
1518/* PAD bytes to make IP data 4 bytes aligned */
1519#define RXS_PBPRES (1 << 2)
1520#define RXS_RESPFRAMETX (1 << 1)
1521#define RXS_FCSERR (1 << 0)
1522
1523/* ucode RxStatus2: */
1524#define RXS_AMSDU_MASK 1
1525#define RXS_AGGTYPE_MASK 0x6
1526#define RXS_AGGTYPE_SHIFT 1
1527#define RXS_PHYRXST_VALID (1 << 8)
1528#define RXS_RXANT_MASK 0x3
1529#define RXS_RXANT_SHIFT 12
1530
1531/* RxChan */
1532#define RXS_CHAN_40 0x1000
1533#define RXS_CHAN_5G 0x0800
1534#define RXS_CHAN_ID_MASK 0x07f8
1535#define RXS_CHAN_ID_SHIFT 3
1536#define RXS_CHAN_PHYTYPE_MASK 0x0007
1537#define RXS_CHAN_PHYTYPE_SHIFT 0
1538
1539/* Index of attenuations used during ucode power control. */
1540#define M_PWRIND_BLKS (0x184 * 2)
1541#define M_PWRIND_MAP0 (M_PWRIND_BLKS + 0x0)
1542#define M_PWRIND_MAP1 (M_PWRIND_BLKS + 0x2)
1543#define M_PWRIND_MAP2 (M_PWRIND_BLKS + 0x4)
1544#define M_PWRIND_MAP3 (M_PWRIND_BLKS + 0x6)
1545/* M_PWRIND_MAP(core) macro */
1546#define M_PWRIND_MAP(core) (M_PWRIND_BLKS + ((core)<<1))
1547
1548/* PSM SHM variable offsets */
1549#define M_PSM_SOFT_REGS 0x0
1550#define M_BOM_REV_MAJOR (M_PSM_SOFT_REGS + 0x0)
1551#define M_BOM_REV_MINOR (M_PSM_SOFT_REGS + 0x2)
1552#define M_UCODE_DBGST (M_PSM_SOFT_REGS + 0x40) /* ucode debug status code */
1553#define M_UCODE_MACSTAT (M_PSM_SOFT_REGS + 0xE0) /* macstat counters */
1554
1555#define M_AGING_THRSH (0x3e * 2) /* max time waiting for medium before tx */
1556#define M_MBURST_SIZE (0x40 * 2) /* max frames in a frameburst */
1557#define M_MBURST_TXOP (0x41 * 2) /* max frameburst TXOP in unit of us */
1558#define M_SYNTHPU_DLY (0x4a * 2) /* pre-wakeup for synthpu, default: 500 */
1559#define M_PRETBTT (0x4b * 2)
1560
1561/* offset to the target txpwr */
1562#define M_ALT_TXPWR_IDX (M_PSM_SOFT_REGS + (0x3b * 2))
1563#define M_PHY_TX_FLT_PTR (M_PSM_SOFT_REGS + (0x3d * 2))
1564#define M_CTS_DURATION (M_PSM_SOFT_REGS + (0x5c * 2))
1565#define M_LP_RCCAL_OVR (M_PSM_SOFT_REGS + (0x6b * 2))
1566
1567/* PKTENG Rx Stats Block */
1568#define M_RXSTATS_BLK_PTR (M_PSM_SOFT_REGS + (0x65 * 2))
1569
1570/* ucode debug status codes */
1571/* not valid really */
1572#define DBGST_INACTIVE 0
1573/* after zeroing SHM, before suspending at init */
1574#define DBGST_INIT 1
1575/* "normal" state */
1576#define DBGST_ACTIVE 2
1577/* suspended */
1578#define DBGST_SUSPENDED 3
1579/* asleep (PS mode) */
1580#define DBGST_ASLEEP 4
1581
1582/* Scratch Reg defs */
1583enum _ePsmScratchPadRegDefinitions {
1584 S_RSV0 = 0,
1585 S_RSV1,
1586 S_RSV2,
1587
1588 /* offset 0x03: scratch registers for Dot11-contants */
1589 S_DOT11_CWMIN, /* CW-minimum */
1590 S_DOT11_CWMAX, /* CW-maximum */
1591 S_DOT11_CWCUR, /* CW-current */
1592 S_DOT11_SRC_LMT, /* short retry count limit */
1593 S_DOT11_LRC_LMT, /* long retry count limit */
1594 S_DOT11_DTIMCOUNT, /* DTIM-count */
1595
1596 /* offset 0x09: Tx-side scratch registers */
1597 S_SEQ_NUM, /* hardware sequence number reg */
1598 S_SEQ_NUM_FRAG, /* seq num for frags (at the start of MSDU) */
1599 S_FRMRETX_CNT, /* frame retx count */
1600 S_SSRC, /* Station short retry count */
1601 S_SLRC, /* Station long retry count */
1602 S_EXP_RSP, /* Expected response frame */
1603 S_OLD_BREM, /* Remaining backoff ctr */
1604 S_OLD_CWWIN, /* saved-off CW-cur */
1605 S_TXECTL, /* TXE-Ctl word constructed in scr-pad */
1606 S_CTXTST, /* frm type-subtype as read from Tx-descr */
1607
1608 /* offset 0x13: Rx-side scratch registers */
1609 S_RXTST, /* Type and subtype in Rxframe */
1610
1611 /* Global state register */
1612 S_STREG, /* state storage actual bit maps below */
1613
1614 S_TXPWR_SUM, /* Tx power control: accumulator */
1615 S_TXPWR_ITER, /* Tx power control: iteration */
1616 S_RX_FRMTYPE, /* Rate and PHY type for frames */
1617 S_THIS_AGG, /* Size of this AGG (A-MSDU) */
1618
1619 S_KEYINDX,
1620 S_RXFRMLEN, /* Receive MPDU length in bytes */
1621
1622 /* offset 0x1B: Receive TSF time stored in SCR */
1623 S_RXTSFTMRVAL_WD3, /* TSF value at the start of rx */
1624 S_RXTSFTMRVAL_WD2, /* TSF value at the start of rx */
1625 S_RXTSFTMRVAL_WD1, /* TSF value at the start of rx */
1626 S_RXTSFTMRVAL_WD0, /* TSF value at the start of rx */
1627 S_RXSSN, /* Received start seq number for A-MPDU BA */
1628 S_RXQOSFLD, /* Rx-QoS field (if present) */
1629
1630 /* offset 0x21: Scratch pad regs used in microcode as temp storage */
1631 S_TMP0, /* stmp0 */
1632 S_TMP1, /* stmp1 */
1633 S_TMP2, /* stmp2 */
1634 S_TMP3, /* stmp3 */
1635 S_TMP4, /* stmp4 */
1636 S_TMP5, /* stmp5 */
1637 S_PRQPENALTY_CTR, /* Probe response queue penalty counter */
1638 S_ANTCNT, /* unsuccessful attempts on current ant. */
1639 S_SYMBOL, /* flag for possible symbol ctl frames */
1640 S_RXTP, /* rx frame type */
1641 S_STREG2, /* extra state storage */
1642 S_STREG3, /* even more extra state storage */
1643 S_STREG4, /* ... */
1644 S_STREG5, /* remember to initialize it to zero */
1645
1646 S_ADJPWR_IDX,
1647 S_CUR_PTR, /* Temp pointer for A-MPDU re-Tx SHM table */
1648 S_REVID4, /* 0x33 */
1649 S_INDX, /* 0x34 */
1650 S_ADDR0, /* 0x35 */
1651 S_ADDR1, /* 0x36 */
1652 S_ADDR2, /* 0x37 */
1653 S_ADDR3, /* 0x38 */
1654 S_ADDR4, /* 0x39 */
1655 S_ADDR5, /* 0x3A */
1656 S_TMP6, /* 0x3B */
1657 S_KEYINDX_BU, /* Backup for Key index */
1658 S_MFGTEST_TMP0, /* Temp regs used for RX test calculations */
1659 S_RXESN, /* Received end sequence number for A-MPDU BA */
1660 S_STREG6, /* 0x3F */
1661};
1662
1663#define S_BEACON_INDX S_OLD_BREM
1664#define S_PRS_INDX S_OLD_CWWIN
1665#define S_PHYTYPE S_SSRC
1666#define S_PHYVER S_SLRC
1667
1668/* IHR SLOW_CTRL values */
1669#define SLOW_CTRL_PDE (1 << 0)
1670#define SLOW_CTRL_FD (1 << 8)
1671
1672/* ucode mac statistic counters in shared memory */
1673struct macstat {
1674 u16 txallfrm; /* 0x80 */
1675 u16 txrtsfrm; /* 0x82 */
1676 u16 txctsfrm; /* 0x84 */
1677 u16 txackfrm; /* 0x86 */
1678 u16 txdnlfrm; /* 0x88 */
1679 u16 txbcnfrm; /* 0x8a */
1680 u16 txfunfl[8]; /* 0x8c - 0x9b */
1681 u16 txtplunfl; /* 0x9c */
1682 u16 txphyerr; /* 0x9e */
1683 u16 pktengrxducast; /* 0xa0 */
1684 u16 pktengrxdmcast; /* 0xa2 */
1685 u16 rxfrmtoolong; /* 0xa4 */
1686 u16 rxfrmtooshrt; /* 0xa6 */
1687 u16 rxinvmachdr; /* 0xa8 */
1688 u16 rxbadfcs; /* 0xaa */
1689 u16 rxbadplcp; /* 0xac */
1690 u16 rxcrsglitch; /* 0xae */
1691 u16 rxstrt; /* 0xb0 */
1692 u16 rxdfrmucastmbss; /* 0xb2 */
1693 u16 rxmfrmucastmbss; /* 0xb4 */
1694 u16 rxcfrmucast; /* 0xb6 */
1695 u16 rxrtsucast; /* 0xb8 */
1696 u16 rxctsucast; /* 0xba */
1697 u16 rxackucast; /* 0xbc */
1698 u16 rxdfrmocast; /* 0xbe */
1699 u16 rxmfrmocast; /* 0xc0 */
1700 u16 rxcfrmocast; /* 0xc2 */
1701 u16 rxrtsocast; /* 0xc4 */
1702 u16 rxctsocast; /* 0xc6 */
1703 u16 rxdfrmmcast; /* 0xc8 */
1704 u16 rxmfrmmcast; /* 0xca */
1705 u16 rxcfrmmcast; /* 0xcc */
1706 u16 rxbeaconmbss; /* 0xce */
1707 u16 rxdfrmucastobss; /* 0xd0 */
1708 u16 rxbeaconobss; /* 0xd2 */
1709 u16 rxrsptmout; /* 0xd4 */
1710 u16 bcntxcancl; /* 0xd6 */
1711 u16 PAD;
1712 u16 rxf0ovfl; /* 0xda */
1713 u16 rxf1ovfl; /* 0xdc */
1714 u16 rxf2ovfl; /* 0xde */
1715 u16 txsfovfl; /* 0xe0 */
1716 u16 pmqovfl; /* 0xe2 */
1717 u16 rxcgprqfrm; /* 0xe4 */
1718 u16 rxcgprsqovfl; /* 0xe6 */
1719 u16 txcgprsfail; /* 0xe8 */
1720 u16 txcgprssuc; /* 0xea */
1721 u16 prs_timeout; /* 0xec */
1722 u16 rxnack;
1723 u16 frmscons;
1724 u16 txnack;
1725 u16 txglitch_nack;
1726 u16 txburst; /* 0xf6 # tx bursts */
1727 u16 bphy_rxcrsglitch; /* bphy rx crs glitch */
1728 u16 phywatchdog; /* 0xfa # of phy watchdog events */
1729 u16 PAD;
1730 u16 bphy_badplcp; /* bphy bad plcp */
1731};
1732
1733/* dot11 core-specific control flags */
1734#define SICF_PCLKE 0x0004 /* PHY clock enable */
1735#define SICF_PRST 0x0008 /* PHY reset */
1736#define SICF_MPCLKE 0x0010 /* MAC PHY clockcontrol enable */
1737#define SICF_FREF 0x0020 /* PLL FreqRefSelect */
1738/* NOTE: the following bw bits only apply when the core is attached
1739 * to a NPHY
1740 */
1741#define SICF_BWMASK 0x00c0 /* phy clock mask (b6 & b7) */
1742#define SICF_BW40 0x0080 /* 40MHz BW (160MHz phyclk) */
1743#define SICF_BW20 0x0040 /* 20MHz BW (80MHz phyclk) */
1744#define SICF_BW10 0x0000 /* 10MHz BW (40MHz phyclk) */
1745#define SICF_GMODE 0x2000 /* gmode enable */
1746
1747/* dot11 core-specific status flags */
1748#define SISF_2G_PHY 0x0001 /* 2.4G capable phy */
1749#define SISF_5G_PHY 0x0002 /* 5G capable phy */
1750#define SISF_FCLKA 0x0004 /* FastClkAvailable */
1751#define SISF_DB_PHY 0x0008 /* Dualband phy */
1752
1753/* === End of MAC reg, Beginning of PHY(b/a/g/n) reg === */
1754/* radio and LPPHY regs are separated */
1755
1756#define BPHY_REG_OFT_BASE 0x0
1757/* offsets for indirect access to bphy registers */
1758#define BPHY_BB_CONFIG 0x01
1759#define BPHY_ADCBIAS 0x02
1760#define BPHY_ANACORE 0x03
1761#define BPHY_PHYCRSTH 0x06
1762#define BPHY_TEST 0x0a
1763#define BPHY_PA_TX_TO 0x10
1764#define BPHY_SYNTH_DC_TO 0x11
1765#define BPHY_PA_TX_TIME_UP 0x12
1766#define BPHY_RX_FLTR_TIME_UP 0x13
1767#define BPHY_TX_POWER_OVERRIDE 0x14
1768#define BPHY_RF_OVERRIDE 0x15
1769#define BPHY_RF_TR_LOOKUP1 0x16
1770#define BPHY_RF_TR_LOOKUP2 0x17
1771#define BPHY_COEFFS 0x18
1772#define BPHY_PLL_OUT 0x19
1773#define BPHY_REFRESH_MAIN 0x1a
1774#define BPHY_REFRESH_TO0 0x1b
1775#define BPHY_REFRESH_TO1 0x1c
1776#define BPHY_RSSI_TRESH 0x20
1777#define BPHY_IQ_TRESH_HH 0x21
1778#define BPHY_IQ_TRESH_H 0x22
1779#define BPHY_IQ_TRESH_L 0x23
1780#define BPHY_IQ_TRESH_LL 0x24
1781#define BPHY_GAIN 0x25
1782#define BPHY_LNA_GAIN_RANGE 0x26
1783#define BPHY_JSSI 0x27
1784#define BPHY_TSSI_CTL 0x28
1785#define BPHY_TSSI 0x29
1786#define BPHY_TR_LOSS_CTL 0x2a
1787#define BPHY_LO_LEAKAGE 0x2b
1788#define BPHY_LO_RSSI_ACC 0x2c
1789#define BPHY_LO_IQMAG_ACC 0x2d
1790#define BPHY_TX_DC_OFF1 0x2e
1791#define BPHY_TX_DC_OFF2 0x2f
1792#define BPHY_PEAK_CNT_THRESH 0x30
1793#define BPHY_FREQ_OFFSET 0x31
1794#define BPHY_DIVERSITY_CTL 0x32
1795#define BPHY_PEAK_ENERGY_LO 0x33
1796#define BPHY_PEAK_ENERGY_HI 0x34
1797#define BPHY_SYNC_CTL 0x35
1798#define BPHY_TX_PWR_CTRL 0x36
1799#define BPHY_TX_EST_PWR 0x37
1800#define BPHY_STEP 0x38
1801#define BPHY_WARMUP 0x39
1802#define BPHY_LMS_CFF_READ 0x3a
1803#define BPHY_LMS_COEFF_I 0x3b
1804#define BPHY_LMS_COEFF_Q 0x3c
1805#define BPHY_SIG_POW 0x3d
1806#define BPHY_RFDC_CANCEL_CTL 0x3e
1807#define BPHY_HDR_TYPE 0x40
1808#define BPHY_SFD_TO 0x41
1809#define BPHY_SFD_CTL 0x42
1810#define BPHY_DEBUG 0x43
1811#define BPHY_RX_DELAY_COMP 0x44
1812#define BPHY_CRS_DROP_TO 0x45
1813#define BPHY_SHORT_SFD_NZEROS 0x46
1814#define BPHY_DSSS_COEFF1 0x48
1815#define BPHY_DSSS_COEFF2 0x49
1816#define BPHY_CCK_COEFF1 0x4a
1817#define BPHY_CCK_COEFF2 0x4b
1818#define BPHY_TR_CORR 0x4c
1819#define BPHY_ANGLE_SCALE 0x4d
1820#define BPHY_TX_PWR_BASE_IDX 0x4e
1821#define BPHY_OPTIONAL_MODES2 0x4f
1822#define BPHY_CCK_LMS_STEP 0x50
1823#define BPHY_BYPASS 0x51
1824#define BPHY_CCK_DELAY_LONG 0x52
1825#define BPHY_CCK_DELAY_SHORT 0x53
1826#define BPHY_PPROC_CHAN_DELAY 0x54
1827#define BPHY_DDFS_ENABLE 0x58
1828#define BPHY_PHASE_SCALE 0x59
1829#define BPHY_FREQ_CONTROL 0x5a
1830#define BPHY_LNA_GAIN_RANGE_10 0x5b
1831#define BPHY_LNA_GAIN_RANGE_32 0x5c
1832#define BPHY_OPTIONAL_MODES 0x5d
1833#define BPHY_RX_STATUS2 0x5e
1834#define BPHY_RX_STATUS3 0x5f
1835#define BPHY_DAC_CONTROL 0x60
1836#define BPHY_ANA11G_FILT_CTRL 0x62
1837#define BPHY_REFRESH_CTRL 0x64
1838#define BPHY_RF_OVERRIDE2 0x65
1839#define BPHY_SPUR_CANCEL_CTRL 0x66
1840#define BPHY_FINE_DIGIGAIN_CTRL 0x67
1841#define BPHY_RSSI_LUT 0x88
1842#define BPHY_RSSI_LUT_END 0xa7
1843#define BPHY_TSSI_LUT 0xa8
1844#define BPHY_TSSI_LUT_END 0xc7
1845#define BPHY_TSSI2PWR_LUT 0x380
1846#define BPHY_TSSI2PWR_LUT_END 0x39f
1847#define BPHY_LOCOMP_LUT 0x3a0
1848#define BPHY_LOCOMP_LUT_END 0x3bf
1849#define BPHY_TXGAIN_LUT 0x3c0
1850#define BPHY_TXGAIN_LUT_END 0x3ff
1851
1852/* Bits in BB_CONFIG: */
1853#define PHY_BBC_ANT_MASK 0x0180
1854#define PHY_BBC_ANT_SHIFT 7
1855#define BB_DARWIN 0x1000
1856#define BBCFG_RESETCCA 0x4000
1857#define BBCFG_RESETRX 0x8000
1858
1859/* Bits in phytest(0x0a): */
1860#define TST_DDFS 0x2000
1861#define TST_TXFILT1 0x0800
1862#define TST_UNSCRAM 0x0400
1863#define TST_CARR_SUPP 0x0200
1864#define TST_DC_COMP_LOOP 0x0100
1865#define TST_LOOPBACK 0x0080
1866#define TST_TXFILT0 0x0040
1867#define TST_TXTEST_ENABLE 0x0020
1868#define TST_TXTEST_RATE 0x0018
1869#define TST_TXTEST_PHASE 0x0007
1870
1871/* phytest txTestRate values */
1872#define TST_TXTEST_RATE_1MBPS 0
1873#define TST_TXTEST_RATE_2MBPS 1
1874#define TST_TXTEST_RATE_5_5MBPS 2
1875#define TST_TXTEST_RATE_11MBPS 3
1876#define TST_TXTEST_RATE_SHIFT 3
1877
1878#define SHM_BYT_CNT 0x2 /* IHR location */
1879#define MAX_BYT_CNT 0x600 /* Maximum frame len */
1880
1881struct d11cnt {
1882 u32 txfrag;
1883 u32 txmulti;
1884 u32 txfail;
1885 u32 txretry;
1886 u32 txretrie;
1887 u32 rxdup;
1888 u32 txrts;
1889 u32 txnocts;
1890 u32 txnoack;
1891 u32 rxfrag;
1892 u32 rxmulti;
1893 u32 rxcrc;
1894 u32 txfrmsnt;
1895 u32 rxundec;
1896};
1897
1898#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 000000000000..b56a30297c26
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -0,0 +1,1425 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/slab.h>
17#include <linux/skbuff.h>
18#include <linux/delay.h>
19#include <linux/pci.h>
20
21#include <brcmu_utils.h>
22#include <aiutils.h>
23#include "types.h"
24#include "dma.h"
25
26/*
27 * DMA hardware requires each descriptor ring to be 8kB aligned, and fit within
28 * a contiguous 8kB physical address.
29 */
30#define D64RINGALIGN_BITS 13
31#define D64MAXRINGSZ (1 << D64RINGALIGN_BITS)
32#define D64RINGALIGN (1 << D64RINGALIGN_BITS)
33
34#define D64MAXDD (D64MAXRINGSZ / sizeof(struct dma64desc))
35
36/* transmit channel control */
37#define D64_XC_XE 0x00000001 /* transmit enable */
38#define D64_XC_SE 0x00000002 /* transmit suspend request */
39#define D64_XC_LE 0x00000004 /* loopback enable */
40#define D64_XC_FL 0x00000010 /* flush request */
41#define D64_XC_PD 0x00000800 /* parity check disable */
42#define D64_XC_AE 0x00030000 /* address extension bits */
43#define D64_XC_AE_SHIFT 16
44
45/* transmit descriptor table pointer */
46#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */
47
48/* transmit channel status */
49#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */
50#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */
51#define D64_XS0_XS_SHIFT 28
52#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */
53#define D64_XS0_XS_ACTIVE 0x10000000 /* active */
54#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */
55#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */
56#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */
57
58#define D64_XS1_AD_MASK 0x00001fff /* active descriptor */
59#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */
60#define D64_XS1_XE_SHIFT 28
61#define D64_XS1_XE_NOERR 0x00000000 /* no error */
62#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */
63#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */
64#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */
65#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */
66#define D64_XS1_XE_COREE 0x50000000 /* core error */
67
68/* receive channel control */
69/* receive enable */
70#define D64_RC_RE 0x00000001
71/* receive frame offset */
72#define D64_RC_RO_MASK 0x000000fe
73#define D64_RC_RO_SHIFT 1
74/* direct fifo receive (pio) mode */
75#define D64_RC_FM 0x00000100
76/* separate rx header descriptor enable */
77#define D64_RC_SH 0x00000200
78/* overflow continue */
79#define D64_RC_OC 0x00000400
80/* parity check disable */
81#define D64_RC_PD 0x00000800
82/* address extension bits */
83#define D64_RC_AE 0x00030000
84#define D64_RC_AE_SHIFT 16
85
86/* flags for dma controller */
87/* partity enable */
88#define DMA_CTRL_PEN (1 << 0)
89/* rx overflow continue */
90#define DMA_CTRL_ROC (1 << 1)
91/* allow rx scatter to multiple descriptors */
92#define DMA_CTRL_RXMULTI (1 << 2)
93/* Unframed Rx/Tx data */
94#define DMA_CTRL_UNFRAMED (1 << 3)
95
96/* receive descriptor table pointer */
97#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */
98
99/* receive channel status */
100#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */
101#define D64_RS0_RS_MASK 0xf0000000 /* receive state */
102#define D64_RS0_RS_SHIFT 28
103#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */
104#define D64_RS0_RS_ACTIVE 0x10000000 /* active */
105#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */
106#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */
107#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */
108
109#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */
110#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */
111#define D64_RS1_RE_SHIFT 28
112#define D64_RS1_RE_NOERR 0x00000000 /* no error */
113#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */
114#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */
115#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */
116#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */
117#define D64_RS1_RE_COREE 0x50000000 /* core error */
118
119/* fifoaddr */
120#define D64_FA_OFF_MASK 0xffff /* offset */
121#define D64_FA_SEL_MASK 0xf0000 /* select */
122#define D64_FA_SEL_SHIFT 16
123#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */
124#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */
125#define D64_FA_SEL_RDD 0x40000 /* receive dma data */
126#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */
127#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */
128#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */
129#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */
130#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */
131#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */
132#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */
133
134/* descriptor control flags 1 */
135#define D64_CTRL_COREFLAGS 0x0ff00000 /* core specific flags */
136#define D64_CTRL1_EOT ((u32)1 << 28) /* end of descriptor table */
137#define D64_CTRL1_IOC ((u32)1 << 29) /* interrupt on completion */
138#define D64_CTRL1_EOF ((u32)1 << 30) /* end of frame */
139#define D64_CTRL1_SOF ((u32)1 << 31) /* start of frame */
140
141/* descriptor control flags 2 */
142/* buffer byte count. real data len must <= 16KB */
143#define D64_CTRL2_BC_MASK 0x00007fff
144/* address extension bits */
145#define D64_CTRL2_AE 0x00030000
146#define D64_CTRL2_AE_SHIFT 16
147/* parity bit */
148#define D64_CTRL2_PARITY 0x00040000
149
150/* control flags in the range [27:20] are core-specific and not defined here */
151#define D64_CTRL_CORE_MASK 0x0ff00000
152
153#define D64_RX_FRM_STS_LEN 0x0000ffff /* frame length mask */
154#define D64_RX_FRM_STS_OVFL 0x00800000 /* RxOverFlow */
155#define D64_RX_FRM_STS_DSCRCNT 0x0f000000 /* no. of descriptors used - 1 */
156#define D64_RX_FRM_STS_DATATYPE 0xf0000000 /* core-dependent data type */
157
158/*
159 * packet headroom necessary to accommodate the largest header
160 * in the system, (i.e TXOFF). By doing, we avoid the need to
161 * allocate an extra buffer for the header when bridging to WL.
162 * There is a compile time check in wlc.c which ensure that this
163 * value is at least as big as TXOFF. This value is used in
164 * dma_rxfill().
165 */
166
167#define BCMEXTRAHDROOM 172
168
169/* debug/trace */
170#ifdef BCMDBG
171#define DMA_ERROR(args) \
172 do { \
173 if (!(*di->msg_level & 1)) \
174 ; \
175 else \
176 printk args; \
177 } while (0)
178#define DMA_TRACE(args) \
179 do { \
180 if (!(*di->msg_level & 2)) \
181 ; \
182 else \
183 printk args; \
184 } while (0)
185#else
186#define DMA_ERROR(args)
187#define DMA_TRACE(args)
188#endif /* BCMDBG */
189
190#define DMA_NONE(args)
191
192#define MAXNAMEL 8 /* 8 char names */
193
194/* macros to convert between byte offsets and indexes */
195#define B2I(bytes, type) ((bytes) / sizeof(type))
196#define I2B(index, type) ((index) * sizeof(type))
197
198#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */
199#define PCI32ADDR_HIGH_SHIFT 30 /* address[31:30] */
200
201#define PCI64ADDR_HIGH 0x80000000 /* address[63] */
202#define PCI64ADDR_HIGH_SHIFT 31 /* address[63] */
203
204/*
205 * DMA Descriptor
206 * Descriptors are only read by the hardware, never written back.
207 */
208struct dma64desc {
209 __le32 ctrl1; /* misc control bits & bufcount */
210 __le32 ctrl2; /* buffer count and address extension */
211 __le32 addrlow; /* memory address of the date buffer, bits 31:0 */
212 __le32 addrhigh; /* memory address of the date buffer, bits 63:32 */
213};
214
215/* dma engine software state */
216struct dma_info {
217 struct dma_pub dma; /* exported structure */
218 uint *msg_level; /* message level pointer */
219 char name[MAXNAMEL]; /* callers name for diag msgs */
220
221 struct pci_dev *pbus; /* bus handle */
222
223 bool dma64; /* this dma engine is operating in 64-bit mode */
224 bool addrext; /* this dma engine supports DmaExtendedAddrChanges */
225
226 /* 64-bit dma tx engine registers */
227 struct dma64regs __iomem *d64txregs;
228 /* 64-bit dma rx engine registers */
229 struct dma64regs __iomem *d64rxregs;
230 /* pointer to dma64 tx descriptor ring */
231 struct dma64desc *txd64;
232 /* pointer to dma64 rx descriptor ring */
233 struct dma64desc *rxd64;
234
235 u16 dmadesc_align; /* alignment requirement for dma descriptors */
236
237 u16 ntxd; /* # tx descriptors tunable */
238 u16 txin; /* index of next descriptor to reclaim */
239 u16 txout; /* index of next descriptor to post */
240 /* pointer to parallel array of pointers to packets */
241 struct sk_buff **txp;
242 /* Aligned physical address of descriptor ring */
243 dma_addr_t txdpa;
244 /* Original physical address of descriptor ring */
245 dma_addr_t txdpaorig;
246 u16 txdalign; /* #bytes added to alloc'd mem to align txd */
247 u32 txdalloc; /* #bytes allocated for the ring */
248 u32 xmtptrbase; /* When using unaligned descriptors, the ptr register
249 * is not just an index, it needs all 13 bits to be
250 * an offset from the addr register.
251 */
252
253 u16 nrxd; /* # rx descriptors tunable */
254 u16 rxin; /* index of next descriptor to reclaim */
255 u16 rxout; /* index of next descriptor to post */
256 /* pointer to parallel array of pointers to packets */
257 struct sk_buff **rxp;
258 /* Aligned physical address of descriptor ring */
259 dma_addr_t rxdpa;
260 /* Original physical address of descriptor ring */
261 dma_addr_t rxdpaorig;
262 u16 rxdalign; /* #bytes added to alloc'd mem to align rxd */
263 u32 rxdalloc; /* #bytes allocated for the ring */
264 u32 rcvptrbase; /* Base for ptr reg when using unaligned descriptors */
265
266 /* tunables */
267 unsigned int rxbufsize; /* rx buffer size in bytes, not including
268 * the extra headroom
269 */
270 uint rxextrahdrroom; /* extra rx headroom, reverseved to assist upper
271 * stack, e.g. some rx pkt buffers will be
272 * bridged to tx side without byte copying.
273 * The extra headroom needs to be large enough
274 * to fit txheader needs. Some dongle driver may
275 * not need it.
276 */
277 uint nrxpost; /* # rx buffers to keep posted */
278 unsigned int rxoffset; /* rxcontrol offset */
279 /* add to get dma address of descriptor ring, low 32 bits */
280 uint ddoffsetlow;
281 /* high 32 bits */
282 uint ddoffsethigh;
283 /* add to get dma address of data buffer, low 32 bits */
284 uint dataoffsetlow;
285 /* high 32 bits */
286 uint dataoffsethigh;
287 /* descriptor base need to be aligned or not */
288 bool aligndesc_4k;
289};
290
291/*
292 * default dma message level (if input msg_level
293 * pointer is null in dma_attach())
294 */
295static uint dma_msg_level;
296
297/* Check for odd number of 1's */
298static u32 parity32(__le32 data)
299{
300 /* no swap needed for counting 1's */
301 u32 par_data = *(u32 *)&data;
302
303 par_data ^= par_data >> 16;
304 par_data ^= par_data >> 8;
305 par_data ^= par_data >> 4;
306 par_data ^= par_data >> 2;
307 par_data ^= par_data >> 1;
308
309 return par_data & 1;
310}
311
312static bool dma64_dd_parity(struct dma64desc *dd)
313{
314 return parity32(dd->addrlow ^ dd->addrhigh ^ dd->ctrl1 ^ dd->ctrl2);
315}
316
317/* descriptor bumping functions */
318
319static uint xxd(uint x, uint n)
320{
321 return x & (n - 1); /* faster than %, but n must be power of 2 */
322}
323
324static uint txd(struct dma_info *di, uint x)
325{
326 return xxd(x, di->ntxd);
327}
328
329static uint rxd(struct dma_info *di, uint x)
330{
331 return xxd(x, di->nrxd);
332}
333
334static uint nexttxd(struct dma_info *di, uint i)
335{
336 return txd(di, i + 1);
337}
338
339static uint prevtxd(struct dma_info *di, uint i)
340{
341 return txd(di, i - 1);
342}
343
344static uint nextrxd(struct dma_info *di, uint i)
345{
346 return txd(di, i + 1);
347}
348
349static uint ntxdactive(struct dma_info *di, uint h, uint t)
350{
351 return txd(di, t-h);
352}
353
354static uint nrxdactive(struct dma_info *di, uint h, uint t)
355{
356 return rxd(di, t-h);
357}
358
359static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
360{
361 uint dmactrlflags = di->dma.dmactrlflags;
362
363 if (di == NULL) {
364 DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
365 return 0;
366 }
367
368 dmactrlflags &= ~mask;
369 dmactrlflags |= flags;
370
371 /* If trying to enable parity, check if parity is actually supported */
372 if (dmactrlflags & DMA_CTRL_PEN) {
373 u32 control;
374
375 control = R_REG(&di->d64txregs->control);
376 W_REG(&di->d64txregs->control,
377 control | D64_XC_PD);
378 if (R_REG(&di->d64txregs->control) & D64_XC_PD)
379 /* We *can* disable it so it is supported,
380 * restore control register
381 */
382 W_REG(&di->d64txregs->control,
383 control);
384 else
385 /* Not supported, don't allow it to be enabled */
386 dmactrlflags &= ~DMA_CTRL_PEN;
387 }
388
389 di->dma.dmactrlflags = dmactrlflags;
390
391 return dmactrlflags;
392}
393
394static bool _dma64_addrext(struct dma64regs __iomem *dma64regs)
395{
396 u32 w;
397 OR_REG(&dma64regs->control, D64_XC_AE);
398 w = R_REG(&dma64regs->control);
399 AND_REG(&dma64regs->control, ~D64_XC_AE);
400 return (w & D64_XC_AE) == D64_XC_AE;
401}
402
403/*
404 * return true if this dma engine supports DmaExtendedAddrChanges,
405 * otherwise false
406 */
407static bool _dma_isaddrext(struct dma_info *di)
408{
409 /* DMA64 supports full 32- or 64-bit operation. AE is always valid */
410
411 /* not all tx or rx channel are available */
412 if (di->d64txregs != NULL) {
413 if (!_dma64_addrext(di->d64txregs))
414 DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have "
415 "AE set\n", di->name));
416 return true;
417 } else if (di->d64rxregs != NULL) {
418 if (!_dma64_addrext(di->d64rxregs))
419 DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have "
420 "AE set\n", di->name));
421 return true;
422 }
423
424 return false;
425}
426
427static bool _dma_descriptor_align(struct dma_info *di)
428{
429 u32 addrl;
430
431 /* Check to see if the descriptors need to be aligned on 4K/8K or not */
432 if (di->d64txregs != NULL) {
433 W_REG(&di->d64txregs->addrlow, 0xff0);
434 addrl = R_REG(&di->d64txregs->addrlow);
435 if (addrl != 0)
436 return false;
437 } else if (di->d64rxregs != NULL) {
438 W_REG(&di->d64rxregs->addrlow, 0xff0);
439 addrl = R_REG(&di->d64rxregs->addrlow);
440 if (addrl != 0)
441 return false;
442 }
443 return true;
444}
445
446/*
447 * Descriptor table must start at the DMA hardware dictated alignment, so
448 * allocated memory must be large enough to support this requirement.
449 */
450static void *dma_alloc_consistent(struct pci_dev *pdev, uint size,
451 u16 align_bits, uint *alloced,
452 dma_addr_t *pap)
453{
454 if (align_bits) {
455 u16 align = (1 << align_bits);
456 if (!IS_ALIGNED(PAGE_SIZE, align))
457 size += align;
458 *alloced = size;
459 }
460 return pci_alloc_consistent(pdev, size, pap);
461}
462
463static
464u8 dma_align_sizetobits(uint size)
465{
466 u8 bitpos = 0;
467 while (size >>= 1)
468 bitpos++;
469 return bitpos;
470}
471
472/* This function ensures that the DMA descriptor ring will not get allocated
473 * across Page boundary. If the allocation is done across the page boundary
474 * at the first time, then it is freed and the allocation is done at
475 * descriptor ring size aligned location. This will ensure that the ring will
476 * not cross page boundary
477 */
478static void *dma_ringalloc(struct dma_info *di, u32 boundary, uint size,
479 u16 *alignbits, uint *alloced,
480 dma_addr_t *descpa)
481{
482 void *va;
483 u32 desc_strtaddr;
484 u32 alignbytes = 1 << *alignbits;
485
486 va = dma_alloc_consistent(di->pbus, size, *alignbits, alloced, descpa);
487
488 if (NULL == va)
489 return NULL;
490
491 desc_strtaddr = (u32) roundup((unsigned long)va, alignbytes);
492 if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr
493 & boundary)) {
494 *alignbits = dma_align_sizetobits(size);
495 pci_free_consistent(di->pbus, size, va, *descpa);
496 va = dma_alloc_consistent(di->pbus, size, *alignbits,
497 alloced, descpa);
498 }
499 return va;
500}
501
502static bool dma64_alloc(struct dma_info *di, uint direction)
503{
504 u16 size;
505 uint ddlen;
506 void *va;
507 uint alloced = 0;
508 u16 align;
509 u16 align_bits;
510
511 ddlen = sizeof(struct dma64desc);
512
513 size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
514 align_bits = di->dmadesc_align;
515 align = (1 << align_bits);
516
517 if (direction == DMA_TX) {
518 va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
519 &alloced, &di->txdpaorig);
520 if (va == NULL) {
521 DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd)"
522 " failed\n", di->name));
523 return false;
524 }
525 align = (1 << align_bits);
526 di->txd64 = (struct dma64desc *)
527 roundup((unsigned long)va, align);
528 di->txdalign = (uint) ((s8 *)di->txd64 - (s8 *) va);
529 di->txdpa = di->txdpaorig + di->txdalign;
530 di->txdalloc = alloced;
531 } else {
532 va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
533 &alloced, &di->rxdpaorig);
534 if (va == NULL) {
535 DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd)"
536 " failed\n", di->name));
537 return false;
538 }
539 align = (1 << align_bits);
540 di->rxd64 = (struct dma64desc *)
541 roundup((unsigned long)va, align);
542 di->rxdalign = (uint) ((s8 *)di->rxd64 - (s8 *) va);
543 di->rxdpa = di->rxdpaorig + di->rxdalign;
544 di->rxdalloc = alloced;
545 }
546
547 return true;
548}
549
550static bool _dma_alloc(struct dma_info *di, uint direction)
551{
552 return dma64_alloc(di, direction);
553}
554
555struct dma_pub *dma_attach(char *name, struct si_pub *sih,
556 void __iomem *dmaregstx, void __iomem *dmaregsrx,
557 uint ntxd, uint nrxd,
558 uint rxbufsize, int rxextheadroom,
559 uint nrxpost, uint rxoffset, uint *msg_level)
560{
561 struct dma_info *di;
562 uint size;
563
564 /* allocate private info structure */
565 di = kzalloc(sizeof(struct dma_info), GFP_ATOMIC);
566 if (di == NULL)
567 return NULL;
568
569 di->msg_level = msg_level ? msg_level : &dma_msg_level;
570
571
572 di->dma64 = ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64);
573
574 /* init dma reg pointer */
575 di->d64txregs = (struct dma64regs __iomem *) dmaregstx;
576 di->d64rxregs = (struct dma64regs __iomem *) dmaregsrx;
577
578 /*
579 * Default flags (which can be changed by the driver calling
580 * dma_ctrlflags before enable): For backwards compatibility
581 * both Rx Overflow Continue and Parity are DISABLED.
582 */
583 _dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0);
584
585 DMA_TRACE(("%s: dma_attach: %s flags 0x%x ntxd %d nrxd %d "
586 "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
587 "dmaregstx %p dmaregsrx %p\n", name, "DMA64",
588 di->dma.dmactrlflags, ntxd, nrxd, rxbufsize,
589 rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx));
590
591 /* make a private copy of our callers name */
592 strncpy(di->name, name, MAXNAMEL);
593 di->name[MAXNAMEL - 1] = '\0';
594
595 di->pbus = ((struct si_info *)sih)->pbus;
596
597 /* save tunables */
598 di->ntxd = (u16) ntxd;
599 di->nrxd = (u16) nrxd;
600
601 /* the actual dma size doesn't include the extra headroom */
602 di->rxextrahdrroom =
603 (rxextheadroom == -1) ? BCMEXTRAHDROOM : rxextheadroom;
604 if (rxbufsize > BCMEXTRAHDROOM)
605 di->rxbufsize = (u16) (rxbufsize - di->rxextrahdrroom);
606 else
607 di->rxbufsize = (u16) rxbufsize;
608
609 di->nrxpost = (u16) nrxpost;
610 di->rxoffset = (u8) rxoffset;
611
612 /*
613 * figure out the DMA physical address offset for dd and data
614 * PCI/PCIE: they map silicon backplace address to zero
615 * based memory, need offset
616 * Other bus: use zero SI_BUS BIGENDIAN kludge: use sdram
617 * swapped region for data buffer, not descriptor
618 */
619 di->ddoffsetlow = 0;
620 di->dataoffsetlow = 0;
621 /* add offset for pcie with DMA64 bus */
622 di->ddoffsetlow = 0;
623 di->ddoffsethigh = SI_PCIE_DMA_H32;
624 di->dataoffsetlow = di->ddoffsetlow;
625 di->dataoffsethigh = di->ddoffsethigh;
626 /* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */
627 if ((ai_coreid(sih) == SDIOD_CORE_ID)
628 && ((ai_corerev(sih) > 0) && (ai_corerev(sih) <= 2)))
629 di->addrext = 0;
630 else if ((ai_coreid(sih) == I2S_CORE_ID) &&
631 ((ai_corerev(sih) == 0) || (ai_corerev(sih) == 1)))
632 di->addrext = 0;
633 else
634 di->addrext = _dma_isaddrext(di);
635
636 /* does the descriptor need to be aligned and if yes, on 4K/8K or not */
637 di->aligndesc_4k = _dma_descriptor_align(di);
638 if (di->aligndesc_4k) {
639 di->dmadesc_align = D64RINGALIGN_BITS;
640 if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2))
641 /* for smaller dd table, HW relax alignment reqmnt */
642 di->dmadesc_align = D64RINGALIGN_BITS - 1;
643 } else {
644 di->dmadesc_align = 4; /* 16 byte alignment */
645 }
646
647 DMA_NONE(("DMA descriptor align_needed %d, align %d\n",
648 di->aligndesc_4k, di->dmadesc_align));
649
650 /* allocate tx packet pointer vector */
651 if (ntxd) {
652 size = ntxd * sizeof(void *);
653 di->txp = kzalloc(size, GFP_ATOMIC);
654 if (di->txp == NULL)
655 goto fail;
656 }
657
658 /* allocate rx packet pointer vector */
659 if (nrxd) {
660 size = nrxd * sizeof(void *);
661 di->rxp = kzalloc(size, GFP_ATOMIC);
662 if (di->rxp == NULL)
663 goto fail;
664 }
665
666 /*
667 * allocate transmit descriptor ring, only need ntxd descriptors
668 * but it must be aligned
669 */
670 if (ntxd) {
671 if (!_dma_alloc(di, DMA_TX))
672 goto fail;
673 }
674
675 /*
676 * allocate receive descriptor ring, only need nrxd descriptors
677 * but it must be aligned
678 */
679 if (nrxd) {
680 if (!_dma_alloc(di, DMA_RX))
681 goto fail;
682 }
683
684 if ((di->ddoffsetlow != 0) && !di->addrext) {
685 if (di->txdpa > SI_PCI_DMA_SZ) {
686 DMA_ERROR(("%s: dma_attach: txdpa 0x%x: addrext not "
687 "supported\n", di->name, (u32)di->txdpa));
688 goto fail;
689 }
690 if (di->rxdpa > SI_PCI_DMA_SZ) {
691 DMA_ERROR(("%s: dma_attach: rxdpa 0x%x: addrext not "
692 "supported\n", di->name, (u32)di->rxdpa));
693 goto fail;
694 }
695 }
696
697 DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x "
698 "dataoffsethigh " "0x%x addrext %d\n", di->ddoffsetlow,
699 di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh,
700 di->addrext));
701
702 return (struct dma_pub *) di;
703
704 fail:
705 dma_detach((struct dma_pub *)di);
706 return NULL;
707}
708
709static inline void
710dma64_dd_upd(struct dma_info *di, struct dma64desc *ddring,
711 dma_addr_t pa, uint outidx, u32 *flags, u32 bufcount)
712{
713 u32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
714
715 /* PCI bus with big(>1G) physical address, use address extension */
716 if ((di->dataoffsetlow == 0) || !(pa & PCI32ADDR_HIGH)) {
717 ddring[outidx].addrlow = cpu_to_le32(pa + di->dataoffsetlow);
718 ddring[outidx].addrhigh = cpu_to_le32(di->dataoffsethigh);
719 ddring[outidx].ctrl1 = cpu_to_le32(*flags);
720 ddring[outidx].ctrl2 = cpu_to_le32(ctrl2);
721 } else {
722 /* address extension for 32-bit PCI */
723 u32 ae;
724
725 ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
726 pa &= ~PCI32ADDR_HIGH;
727
728 ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
729 ddring[outidx].addrlow = cpu_to_le32(pa + di->dataoffsetlow);
730 ddring[outidx].addrhigh = cpu_to_le32(di->dataoffsethigh);
731 ddring[outidx].ctrl1 = cpu_to_le32(*flags);
732 ddring[outidx].ctrl2 = cpu_to_le32(ctrl2);
733 }
734 if (di->dma.dmactrlflags & DMA_CTRL_PEN) {
735 if (dma64_dd_parity(&ddring[outidx]))
736 ddring[outidx].ctrl2 =
737 cpu_to_le32(ctrl2 | D64_CTRL2_PARITY);
738 }
739}
740
741/* !! may be called with core in reset */
742void dma_detach(struct dma_pub *pub)
743{
744 struct dma_info *di = (struct dma_info *)pub;
745
746 DMA_TRACE(("%s: dma_detach\n", di->name));
747
748 /* free dma descriptor rings */
749 if (di->txd64)
750 pci_free_consistent(di->pbus, di->txdalloc,
751 ((s8 *)di->txd64 - di->txdalign),
752 (di->txdpaorig));
753 if (di->rxd64)
754 pci_free_consistent(di->pbus, di->rxdalloc,
755 ((s8 *)di->rxd64 - di->rxdalign),
756 (di->rxdpaorig));
757
758 /* free packet pointer vectors */
759 kfree(di->txp);
760 kfree(di->rxp);
761
762 /* free our private info structure */
763 kfree(di);
764
765}
766
767/* initialize descriptor table base address */
768static void
769_dma_ddtable_init(struct dma_info *di, uint direction, dma_addr_t pa)
770{
771 if (!di->aligndesc_4k) {
772 if (direction == DMA_TX)
773 di->xmtptrbase = pa;
774 else
775 di->rcvptrbase = pa;
776 }
777
778 if ((di->ddoffsetlow == 0)
779 || !(pa & PCI32ADDR_HIGH)) {
780 if (direction == DMA_TX) {
781 W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow);
782 W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh);
783 } else {
784 W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow);
785 W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh);
786 }
787 } else {
788 /* DMA64 32bits address extension */
789 u32 ae;
790
791 /* shift the high bit(s) from pa to ae */
792 ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
793 pa &= ~PCI32ADDR_HIGH;
794
795 if (direction == DMA_TX) {
796 W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow);
797 W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh);
798 SET_REG(&di->d64txregs->control,
799 D64_XC_AE, (ae << D64_XC_AE_SHIFT));
800 } else {
801 W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow);
802 W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh);
803 SET_REG(&di->d64rxregs->control,
804 D64_RC_AE, (ae << D64_RC_AE_SHIFT));
805 }
806 }
807}
808
809static void _dma_rxenable(struct dma_info *di)
810{
811 uint dmactrlflags = di->dma.dmactrlflags;
812 u32 control;
813
814 DMA_TRACE(("%s: dma_rxenable\n", di->name));
815
816 control =
817 (R_REG(&di->d64rxregs->control) & D64_RC_AE) |
818 D64_RC_RE;
819
820 if ((dmactrlflags & DMA_CTRL_PEN) == 0)
821 control |= D64_RC_PD;
822
823 if (dmactrlflags & DMA_CTRL_ROC)
824 control |= D64_RC_OC;
825
826 W_REG(&di->d64rxregs->control,
827 ((di->rxoffset << D64_RC_RO_SHIFT) | control));
828}
829
830void dma_rxinit(struct dma_pub *pub)
831{
832 struct dma_info *di = (struct dma_info *)pub;
833
834 DMA_TRACE(("%s: dma_rxinit\n", di->name));
835
836 if (di->nrxd == 0)
837 return;
838
839 di->rxin = di->rxout = 0;
840
841 /* clear rx descriptor ring */
842 memset(di->rxd64, '\0', di->nrxd * sizeof(struct dma64desc));
843
844 /* DMA engine with out alignment requirement requires table to be inited
845 * before enabling the engine
846 */
847 if (!di->aligndesc_4k)
848 _dma_ddtable_init(di, DMA_RX, di->rxdpa);
849
850 _dma_rxenable(di);
851
852 if (di->aligndesc_4k)
853 _dma_ddtable_init(di, DMA_RX, di->rxdpa);
854}
855
856static struct sk_buff *dma64_getnextrxp(struct dma_info *di, bool forceall)
857{
858 uint i, curr;
859 struct sk_buff *rxp;
860 dma_addr_t pa;
861
862 i = di->rxin;
863
864 /* return if no packets posted */
865 if (i == di->rxout)
866 return NULL;
867
868 curr =
869 B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) -
870 di->rcvptrbase) & D64_RS0_CD_MASK, struct dma64desc);
871
872 /* ignore curr if forceall */
873 if (!forceall && (i == curr))
874 return NULL;
875
876 /* get the packet pointer that corresponds to the rx descriptor */
877 rxp = di->rxp[i];
878 di->rxp[i] = NULL;
879
880 pa = le32_to_cpu(di->rxd64[i].addrlow) - di->dataoffsetlow;
881
882 /* clear this packet from the descriptor ring */
883 pci_unmap_single(di->pbus, pa, di->rxbufsize, PCI_DMA_FROMDEVICE);
884
885 di->rxd64[i].addrlow = cpu_to_le32(0xdeadbeef);
886 di->rxd64[i].addrhigh = cpu_to_le32(0xdeadbeef);
887
888 di->rxin = nextrxd(di, i);
889
890 return rxp;
891}
892
893static struct sk_buff *_dma_getnextrxp(struct dma_info *di, bool forceall)
894{
895 if (di->nrxd == 0)
896 return NULL;
897
898 return dma64_getnextrxp(di, forceall);
899}
900
901/*
902 * !! rx entry routine
903 * returns a pointer to the next frame received, or NULL if there are no more
904 * if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is
905 * supported with pkts chain
906 * otherwise, it's treated as giant pkt and will be tossed.
907 * The DMA scattering starts with normal DMA header, followed by first
908 * buffer data. After it reaches the max size of buffer, the data continues
909 * in next DMA descriptor buffer WITHOUT DMA header
910 */
911struct sk_buff *dma_rx(struct dma_pub *pub)
912{
913 struct dma_info *di = (struct dma_info *)pub;
914 struct sk_buff *p, *head, *tail;
915 uint len;
916 uint pkt_len;
917 int resid = 0;
918
919 next_frame:
920 head = _dma_getnextrxp(di, false);
921 if (head == NULL)
922 return NULL;
923
924 len = le16_to_cpu(*(__le16 *) (head->data));
925 DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
926 dma_spin_for_len(len, head);
927
928 /* set actual length */
929 pkt_len = min((di->rxoffset + len), di->rxbufsize);
930 __skb_trim(head, pkt_len);
931 resid = len - (di->rxbufsize - di->rxoffset);
932
933 /* check for single or multi-buffer rx */
934 if (resid > 0) {
935 tail = head;
936 while ((resid > 0) && (p = _dma_getnextrxp(di, false))) {
937 tail->next = p;
938 pkt_len = min_t(uint, resid, di->rxbufsize);
939 __skb_trim(p, pkt_len);
940
941 tail = p;
942 resid -= di->rxbufsize;
943 }
944
945#ifdef BCMDBG
946 if (resid > 0) {
947 uint cur;
948 cur =
949 B2I(((R_REG(&di->d64rxregs->status0) &
950 D64_RS0_CD_MASK) -
951 di->rcvptrbase) & D64_RS0_CD_MASK,
952 struct dma64desc);
953 DMA_ERROR(("dma_rx, rxin %d rxout %d, hw_curr %d\n",
954 di->rxin, di->rxout, cur));
955 }
956#endif /* BCMDBG */
957
958 if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
959 DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n",
960 di->name, len));
961 brcmu_pkt_buf_free_skb(head);
962 di->dma.rxgiants++;
963 goto next_frame;
964 }
965 }
966
967 return head;
968}
969
970static bool dma64_rxidle(struct dma_info *di)
971{
972 DMA_TRACE(("%s: dma_rxidle\n", di->name));
973
974 if (di->nrxd == 0)
975 return true;
976
977 return ((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
978 (R_REG(&di->d64rxregs->ptr) & D64_RS0_CD_MASK));
979}
980
981/*
982 * post receive buffers
983 * return false is refill failed completely and ring is empty this will stall
984 * the rx dma and user might want to call rxfill again asap. This unlikely
985 * happens on memory-rich NIC, but often on memory-constrained dongle
986 */
987bool dma_rxfill(struct dma_pub *pub)
988{
989 struct dma_info *di = (struct dma_info *)pub;
990 struct sk_buff *p;
991 u16 rxin, rxout;
992 u32 flags = 0;
993 uint n;
994 uint i;
995 dma_addr_t pa;
996 uint extra_offset = 0;
997 bool ring_empty;
998
999 ring_empty = false;
1000
1001 /*
1002 * Determine how many receive buffers we're lacking
1003 * from the full complement, allocate, initialize,
1004 * and post them, then update the chip rx lastdscr.
1005 */
1006
1007 rxin = di->rxin;
1008 rxout = di->rxout;
1009
1010 n = di->nrxpost - nrxdactive(di, rxin, rxout);
1011
1012 DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
1013
1014 if (di->rxbufsize > BCMEXTRAHDROOM)
1015 extra_offset = di->rxextrahdrroom;
1016
1017 for (i = 0; i < n; i++) {
1018 /*
1019 * the di->rxbufsize doesn't include the extra headroom,
1020 * we need to add it to the size to be allocated
1021 */
1022 p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset);
1023
1024 if (p == NULL) {
1025 DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n",
1026 di->name));
1027 if (i == 0 && dma64_rxidle(di)) {
1028 DMA_ERROR(("%s: rxfill64: ring is empty !\n",
1029 di->name));
1030 ring_empty = true;
1031 }
1032 di->dma.rxnobuf++;
1033 break;
1034 }
1035 /* reserve an extra headroom, if applicable */
1036 if (extra_offset)
1037 skb_pull(p, extra_offset);
1038
1039 /* Do a cached write instead of uncached write since DMA_MAP
1040 * will flush the cache.
1041 */
1042 *(u32 *) (p->data) = 0;
1043
1044 pa = pci_map_single(di->pbus, p->data,
1045 di->rxbufsize, PCI_DMA_FROMDEVICE);
1046
1047 /* save the free packet pointer */
1048 di->rxp[rxout] = p;
1049
1050 /* reset flags for each descriptor */
1051 flags = 0;
1052 if (rxout == (di->nrxd - 1))
1053 flags = D64_CTRL1_EOT;
1054
1055 dma64_dd_upd(di, di->rxd64, pa, rxout, &flags,
1056 di->rxbufsize);
1057 rxout = nextrxd(di, rxout);
1058 }
1059
1060 di->rxout = rxout;
1061
1062 /* update the chip lastdscr pointer */
1063 W_REG(&di->d64rxregs->ptr,
1064 di->rcvptrbase + I2B(rxout, struct dma64desc));
1065
1066 return ring_empty;
1067}
1068
1069void dma_rxreclaim(struct dma_pub *pub)
1070{
1071 struct dma_info *di = (struct dma_info *)pub;
1072 struct sk_buff *p;
1073
1074 DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
1075
1076 while ((p = _dma_getnextrxp(di, true)))
1077 brcmu_pkt_buf_free_skb(p);
1078}
1079
1080void dma_counterreset(struct dma_pub *pub)
1081{
1082 /* reset all software counters */
1083 pub->rxgiants = 0;
1084 pub->rxnobuf = 0;
1085 pub->txnobuf = 0;
1086}
1087
1088/* get the address of the var in order to change later */
1089unsigned long dma_getvar(struct dma_pub *pub, const char *name)
1090{
1091 struct dma_info *di = (struct dma_info *)pub;
1092
1093 if (!strcmp(name, "&txavail"))
1094 return (unsigned long)&(di->dma.txavail);
1095 return 0;
1096}
1097
1098/* 64-bit DMA functions */
1099
1100void dma_txinit(struct dma_pub *pub)
1101{
1102 struct dma_info *di = (struct dma_info *)pub;
1103 u32 control = D64_XC_XE;
1104
1105 DMA_TRACE(("%s: dma_txinit\n", di->name));
1106
1107 if (di->ntxd == 0)
1108 return;
1109
1110 di->txin = di->txout = 0;
1111 di->dma.txavail = di->ntxd - 1;
1112
1113 /* clear tx descriptor ring */
1114 memset(di->txd64, '\0', (di->ntxd * sizeof(struct dma64desc)));
1115
1116 /* DMA engine with out alignment requirement requires table to be inited
1117 * before enabling the engine
1118 */
1119 if (!di->aligndesc_4k)
1120 _dma_ddtable_init(di, DMA_TX, di->txdpa);
1121
1122 if ((di->dma.dmactrlflags & DMA_CTRL_PEN) == 0)
1123 control |= D64_XC_PD;
1124 OR_REG(&di->d64txregs->control, control);
1125
1126 /* DMA engine with alignment requirement requires table to be inited
1127 * before enabling the engine
1128 */
1129 if (di->aligndesc_4k)
1130 _dma_ddtable_init(di, DMA_TX, di->txdpa);
1131}
1132
1133void dma_txsuspend(struct dma_pub *pub)
1134{
1135 struct dma_info *di = (struct dma_info *)pub;
1136
1137 DMA_TRACE(("%s: dma_txsuspend\n", di->name));
1138
1139 if (di->ntxd == 0)
1140 return;
1141
1142 OR_REG(&di->d64txregs->control, D64_XC_SE);
1143}
1144
1145void dma_txresume(struct dma_pub *pub)
1146{
1147 struct dma_info *di = (struct dma_info *)pub;
1148
1149 DMA_TRACE(("%s: dma_txresume\n", di->name));
1150
1151 if (di->ntxd == 0)
1152 return;
1153
1154 AND_REG(&di->d64txregs->control, ~D64_XC_SE);
1155}
1156
1157bool dma_txsuspended(struct dma_pub *pub)
1158{
1159 struct dma_info *di = (struct dma_info *)pub;
1160
1161 return (di->ntxd == 0) ||
1162 ((R_REG(&di->d64txregs->control) & D64_XC_SE) ==
1163 D64_XC_SE);
1164}
1165
1166void dma_txreclaim(struct dma_pub *pub, enum txd_range range)
1167{
1168 struct dma_info *di = (struct dma_info *)pub;
1169 struct sk_buff *p;
1170
1171 DMA_TRACE(("%s: dma_txreclaim %s\n", di->name,
1172 (range == DMA_RANGE_ALL) ? "all" :
1173 ((range ==
1174 DMA_RANGE_TRANSMITTED) ? "transmitted" :
1175 "transferred")));
1176
1177 if (di->txin == di->txout)
1178 return;
1179
1180 while ((p = dma_getnexttxp(pub, range))) {
1181 /* For unframed data, we don't have any packets to free */
1182 if (!(di->dma.dmactrlflags & DMA_CTRL_UNFRAMED))
1183 brcmu_pkt_buf_free_skb(p);
1184 }
1185}
1186
1187bool dma_txreset(struct dma_pub *pub)
1188{
1189 struct dma_info *di = (struct dma_info *)pub;
1190 u32 status;
1191
1192 if (di->ntxd == 0)
1193 return true;
1194
1195 /* suspend tx DMA first */
1196 W_REG(&di->d64txregs->control, D64_XC_SE);
1197 SPINWAIT(((status =
1198 (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
1199 != D64_XS0_XS_DISABLED) && (status != D64_XS0_XS_IDLE)
1200 && (status != D64_XS0_XS_STOPPED), 10000);
1201
1202 W_REG(&di->d64txregs->control, 0);
1203 SPINWAIT(((status =
1204 (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
1205 != D64_XS0_XS_DISABLED), 10000);
1206
1207 /* wait for the last transaction to complete */
1208 udelay(300);
1209
1210 return status == D64_XS0_XS_DISABLED;
1211}
1212
1213bool dma_rxreset(struct dma_pub *pub)
1214{
1215 struct dma_info *di = (struct dma_info *)pub;
1216 u32 status;
1217
1218 if (di->nrxd == 0)
1219 return true;
1220
1221 W_REG(&di->d64rxregs->control, 0);
1222 SPINWAIT(((status =
1223 (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK))
1224 != D64_RS0_RS_DISABLED), 10000);
1225
1226 return status == D64_RS0_RS_DISABLED;
1227}
1228
1229/*
1230 * !! tx entry routine
1231 * WARNING: call must check the return value for error.
1232 * the error(toss frames) could be fatal and cause many subsequent hard
1233 * to debug problems
1234 */
1235int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit)
1236{
1237 struct dma_info *di = (struct dma_info *)pub;
1238 struct sk_buff *p, *next;
1239 unsigned char *data;
1240 uint len;
1241 u16 txout;
1242 u32 flags = 0;
1243 dma_addr_t pa;
1244
1245 DMA_TRACE(("%s: dma_txfast\n", di->name));
1246
1247 txout = di->txout;
1248
1249 /*
1250 * Walk the chain of packet buffers
1251 * allocating and initializing transmit descriptor entries.
1252 */
1253 for (p = p0; p; p = next) {
1254 data = p->data;
1255 len = p->len;
1256 next = p->next;
1257
1258 /* return nonzero if out of tx descriptors */
1259 if (nexttxd(di, txout) == di->txin)
1260 goto outoftxd;
1261
1262 if (len == 0)
1263 continue;
1264
1265 /* get physical address of buffer start */
1266 pa = pci_map_single(di->pbus, data, len, PCI_DMA_TODEVICE);
1267
1268 flags = 0;
1269 if (p == p0)
1270 flags |= D64_CTRL1_SOF;
1271
1272 /* With a DMA segment list, Descriptor table is filled
1273 * using the segment list instead of looping over
1274 * buffers in multi-chain DMA. Therefore, EOF for SGLIST
1275 * is when end of segment list is reached.
1276 */
1277 if (next == NULL)
1278 flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
1279 if (txout == (di->ntxd - 1))
1280 flags |= D64_CTRL1_EOT;
1281
1282 dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
1283
1284 txout = nexttxd(di, txout);
1285 }
1286
1287 /* if last txd eof not set, fix it */
1288 if (!(flags & D64_CTRL1_EOF))
1289 di->txd64[prevtxd(di, txout)].ctrl1 =
1290 cpu_to_le32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF);
1291
1292 /* save the packet */
1293 di->txp[prevtxd(di, txout)] = p0;
1294
1295 /* bump the tx descriptor index */
1296 di->txout = txout;
1297
1298 /* kick the chip */
1299 if (commit)
1300 W_REG(&di->d64txregs->ptr,
1301 di->xmtptrbase + I2B(txout, struct dma64desc));
1302
1303 /* tx flow control */
1304 di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1;
1305
1306 return 0;
1307
1308 outoftxd:
1309 DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name));
1310 brcmu_pkt_buf_free_skb(p0);
1311 di->dma.txavail = 0;
1312 di->dma.txnobuf++;
1313 return -1;
1314}
1315
1316/*
1317 * Reclaim next completed txd (txds if using chained buffers) in the range
1318 * specified and return associated packet.
1319 * If range is DMA_RANGE_TRANSMITTED, reclaim descriptors that have be
1320 * transmitted as noted by the hardware "CurrDescr" pointer.
1321 * If range is DMA_RANGE_TRANSFERED, reclaim descriptors that have be
1322 * transferred by the DMA as noted by the hardware "ActiveDescr" pointer.
1323 * If range is DMA_RANGE_ALL, reclaim all txd(s) posted to the ring and
1324 * return associated packet regardless of the value of hardware pointers.
1325 */
1326struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range)
1327{
1328 struct dma_info *di = (struct dma_info *)pub;
1329 u16 start, end, i;
1330 u16 active_desc;
1331 struct sk_buff *txp;
1332
1333 DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name,
1334 (range == DMA_RANGE_ALL) ? "all" :
1335 ((range ==
1336 DMA_RANGE_TRANSMITTED) ? "transmitted" :
1337 "transferred")));
1338
1339 if (di->ntxd == 0)
1340 return NULL;
1341
1342 txp = NULL;
1343
1344 start = di->txin;
1345 if (range == DMA_RANGE_ALL)
1346 end = di->txout;
1347 else {
1348 struct dma64regs __iomem *dregs = di->d64txregs;
1349
1350 end = (u16) (B2I(((R_REG(&dregs->status0) &
1351 D64_XS0_CD_MASK) -
1352 di->xmtptrbase) & D64_XS0_CD_MASK,
1353 struct dma64desc));
1354
1355 if (range == DMA_RANGE_TRANSFERED) {
1356 active_desc =
1357 (u16) (R_REG(&dregs->status1) &
1358 D64_XS1_AD_MASK);
1359 active_desc =
1360 (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK;
1361 active_desc = B2I(active_desc, struct dma64desc);
1362 if (end != active_desc)
1363 end = prevtxd(di, active_desc);
1364 }
1365 }
1366
1367 if ((start == 0) && (end > di->txout))
1368 goto bogus;
1369
1370 for (i = start; i != end && !txp; i = nexttxd(di, i)) {
1371 dma_addr_t pa;
1372 uint size;
1373
1374 pa = le32_to_cpu(di->txd64[i].addrlow) - di->dataoffsetlow;
1375
1376 size =
1377 (le32_to_cpu(di->txd64[i].ctrl2) &
1378 D64_CTRL2_BC_MASK);
1379
1380 di->txd64[i].addrlow = cpu_to_le32(0xdeadbeef);
1381 di->txd64[i].addrhigh = cpu_to_le32(0xdeadbeef);
1382
1383 txp = di->txp[i];
1384 di->txp[i] = NULL;
1385
1386 pci_unmap_single(di->pbus, pa, size, PCI_DMA_TODEVICE);
1387 }
1388
1389 di->txin = i;
1390
1391 /* tx flow control */
1392 di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1;
1393
1394 return txp;
1395
1396 bogus:
1397 DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d "
1398 "force %d\n", start, end, di->txout, forceall));
1399 return NULL;
1400}
1401
1402/*
1403 * Mac80211 initiated actions sometimes require packets in the DMA queue to be
1404 * modified. The modified portion of the packet is not under control of the DMA
1405 * engine. This function calls a caller-supplied function for each packet in
1406 * the caller specified dma chain.
1407 */
1408void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
1409 (void *pkt, void *arg_a), void *arg_a)
1410{
1411 struct dma_info *di = (struct dma_info *) dmah;
1412 uint i = di->txin;
1413 uint end = di->txout;
1414 struct sk_buff *skb;
1415 struct ieee80211_tx_info *tx_info;
1416
1417 while (i != end) {
1418 skb = (struct sk_buff *)di->txp[i];
1419 if (skb != NULL) {
1420 tx_info = (struct ieee80211_tx_info *)skb->cb;
1421 (callback_fnc)(tx_info, arg_a);
1422 }
1423 i = nexttxd(di, i);
1424 }
1425}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
new file mode 100644
index 000000000000..ebc5bc546f3b
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
@@ -0,0 +1,120 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_DMA_H_
18#define _BRCM_DMA_H_
19
20#include <linux/delay.h>
21#include "types.h" /* forward structure declarations */
22
23/* map/unmap direction */
24#define DMA_TX 1 /* TX direction for DMA */
25#define DMA_RX 2 /* RX direction for DMA */
26
27/* DMA structure:
28 * support two DMA engines: 32 bits address or 64 bit addressing
29 * basic DMA register set is per channel(transmit or receive)
30 * a pair of channels is defined for convenience
31 */
32
33/* 32 bits addressing */
34
35struct dma32diag { /* diag access */
36 u32 fifoaddr; /* diag address */
37 u32 fifodatalow; /* low 32bits of data */
38 u32 fifodatahigh; /* high 32bits of data */
39 u32 pad; /* reserved */
40};
41
42/* 64 bits addressing */
43
44/* dma registers per channel(xmt or rcv) */
45struct dma64regs {
46 u32 control; /* enable, et al */
47 u32 ptr; /* last descriptor posted to chip */
48 u32 addrlow; /* desc ring base address low 32-bits (8K aligned) */
49 u32 addrhigh; /* desc ring base address bits 63:32 (8K aligned) */
50 u32 status0; /* current descriptor, xmt state */
51 u32 status1; /* active descriptor, xmt error */
52};
53
54/* range param for dma_getnexttxp() and dma_txreclaim */
55enum txd_range {
56 DMA_RANGE_ALL = 1,
57 DMA_RANGE_TRANSMITTED,
58 DMA_RANGE_TRANSFERED
59};
60
61/*
62 * Exported data structure (read-only)
63 */
64/* export structure */
65struct dma_pub {
66 uint txavail; /* # free tx descriptors */
67 uint dmactrlflags; /* dma control flags */
68
69 /* rx error counters */
70 uint rxgiants; /* rx giant frames */
71 uint rxnobuf; /* rx out of dma descriptors */
72 /* tx error counters */
73 uint txnobuf; /* tx out of dma descriptors */
74};
75
76extern struct dma_pub *dma_attach(char *name, struct si_pub *sih,
77 void __iomem *dmaregstx, void __iomem *dmaregsrx,
78 uint ntxd, uint nrxd,
79 uint rxbufsize, int rxextheadroom,
80 uint nrxpost, uint rxoffset, uint *msg_level);
81
82void dma_rxinit(struct dma_pub *pub);
83struct sk_buff *dma_rx(struct dma_pub *pub);
84bool dma_rxfill(struct dma_pub *pub);
85bool dma_rxreset(struct dma_pub *pub);
86bool dma_txreset(struct dma_pub *pub);
87void dma_txinit(struct dma_pub *pub);
88int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit);
89void dma_txsuspend(struct dma_pub *pub);
90bool dma_txsuspended(struct dma_pub *pub);
91void dma_txresume(struct dma_pub *pub);
92void dma_txreclaim(struct dma_pub *pub, enum txd_range range);
93void dma_rxreclaim(struct dma_pub *pub);
94void dma_detach(struct dma_pub *pub);
95unsigned long dma_getvar(struct dma_pub *pub, const char *name);
96struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range);
97void dma_counterreset(struct dma_pub *pub);
98
99void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
100 (void *pkt, void *arg_a), void *arg_a);
101
102/*
103 * DMA(Bug) on bcm47xx chips seems to declare that the packet is ready, but
104 * the packet length is not updated yet (by DMA) on the expected time.
105 * Workaround is to hold processor till DMA updates the length, and stay off
106 * the bus to allow DMA update the length in buffer
107 */
108static inline void dma_spin_for_len(uint len, struct sk_buff *head)
109{
110#if defined(CONFIG_BCM47XX)
111 if (!len) {
112 while (!(len = *(u16 *) KSEG1ADDR(head->data)))
113 udelay(1);
114
115 *(u16 *) (head->data) = cpu_to_le16((u16) len);
116 }
117#endif /* defined(CONFIG_BCM47XX) */
118}
119
120#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 000000000000..ac8d02bd34f2
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -0,0 +1,1696 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#define __UNDEF_NO_VERSION__
18
19#include <linux/etherdevice.h>
20#include <linux/pci.h>
21#include <linux/sched.h>
22#include <linux/firmware.h>
23#include <linux/interrupt.h>
24#include <net/mac80211.h>
25#include <defs.h>
26#include "nicpci.h"
27#include "phy/phy_int.h"
28#include "d11.h"
29#include "channel.h"
30#include "scb.h"
31#include "pub.h"
32#include "ucode_loader.h"
33#include "mac80211_if.h"
34#include "main.h"
35
36#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */
37
38/* Flags we support */
39#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
40 FIF_ALLMULTI | \
41 FIF_FCSFAIL | \
42 FIF_PLCPFAIL | \
43 FIF_CONTROL | \
44 FIF_OTHER_BSS | \
45 FIF_BCN_PRBRESP_PROMISC)
46
47#define CHAN2GHZ(channel, freqency, chflags) { \
48 .band = IEEE80211_BAND_2GHZ, \
49 .center_freq = (freqency), \
50 .hw_value = (channel), \
51 .flags = chflags, \
52 .max_antenna_gain = 0, \
53 .max_power = 19, \
54}
55
56#define CHAN5GHZ(channel, chflags) { \
57 .band = IEEE80211_BAND_5GHZ, \
58 .center_freq = 5000 + 5*(channel), \
59 .hw_value = (channel), \
60 .flags = chflags, \
61 .max_antenna_gain = 0, \
62 .max_power = 21, \
63}
64
65#define RATE(rate100m, _flags) { \
66 .bitrate = (rate100m), \
67 .flags = (_flags), \
68 .hw_value = (rate100m / 5), \
69}
70
71struct firmware_hdr {
72 __le32 offset;
73 __le32 len;
74 __le32 idx;
75};
76
77static const char * const brcms_firmwares[MAX_FW_IMAGES] = {
78 "brcm/bcm43xx",
79 NULL
80};
81
82static int n_adapters_found;
83
84MODULE_AUTHOR("Broadcom Corporation");
85MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
86MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
87MODULE_LICENSE("Dual BSD/GPL");
88
89/* recognized PCI IDs */
90static DEFINE_PCI_DEVICE_TABLE(brcms_pci_id_table) = {
91 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, /* 43225 2G */
92 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, /* 43224 DUAL */
93 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, /* 4313 DUAL */
94 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, /* 43224 Ven */
95 {0}
96};
97
98MODULE_DEVICE_TABLE(pci, brcms_pci_id_table);
99
100#ifdef BCMDBG
101static int msglevel = 0xdeadbeef;
102module_param(msglevel, int, 0);
103#endif /* BCMDBG */
104
105static struct ieee80211_channel brcms_2ghz_chantable[] = {
106 CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
107 CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS),
108 CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS),
109 CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS),
110 CHAN2GHZ(5, 2432, 0),
111 CHAN2GHZ(6, 2437, 0),
112 CHAN2GHZ(7, 2442, 0),
113 CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS),
114 CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS),
115 CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
116 CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
117 CHAN2GHZ(12, 2467,
118 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
119 IEEE80211_CHAN_NO_HT40PLUS),
120 CHAN2GHZ(13, 2472,
121 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
122 IEEE80211_CHAN_NO_HT40PLUS),
123 CHAN2GHZ(14, 2484,
124 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
125 IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
126};
127
128static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = {
129 /* UNII-1 */
130 CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS),
131 CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS),
132 CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS),
133 CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
134 /* UNII-2 */
135 CHAN5GHZ(52,
136 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
137 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
138 CHAN5GHZ(56,
139 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
140 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
141 CHAN5GHZ(60,
142 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
143 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
144 CHAN5GHZ(64,
145 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
146 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
147 /* MID */
148 CHAN5GHZ(100,
149 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
150 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
151 CHAN5GHZ(104,
152 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
153 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
154 CHAN5GHZ(108,
155 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
156 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
157 CHAN5GHZ(112,
158 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
159 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
160 CHAN5GHZ(116,
161 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
162 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
163 CHAN5GHZ(120,
164 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
165 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
166 CHAN5GHZ(124,
167 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
168 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
169 CHAN5GHZ(128,
170 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
171 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
172 CHAN5GHZ(132,
173 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
174 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
175 CHAN5GHZ(136,
176 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
177 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
178 CHAN5GHZ(140,
179 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
180 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS |
181 IEEE80211_CHAN_NO_HT40MINUS),
182 /* UNII-3 */
183 CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
184 CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS),
185 CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS),
186 CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS),
187 CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
188};
189
190/*
191 * The rate table is used for both 2.4G and 5G rates. The
192 * latter being a subset as it does not support CCK rates.
193 */
194static struct ieee80211_rate legacy_ratetable[] = {
195 RATE(10, 0),
196 RATE(20, IEEE80211_RATE_SHORT_PREAMBLE),
197 RATE(55, IEEE80211_RATE_SHORT_PREAMBLE),
198 RATE(110, IEEE80211_RATE_SHORT_PREAMBLE),
199 RATE(60, 0),
200 RATE(90, 0),
201 RATE(120, 0),
202 RATE(180, 0),
203 RATE(240, 0),
204 RATE(360, 0),
205 RATE(480, 0),
206 RATE(540, 0),
207};
208
209static const struct ieee80211_supported_band brcms_band_2GHz_nphy_template = {
210 .band = IEEE80211_BAND_2GHZ,
211 .channels = brcms_2ghz_chantable,
212 .n_channels = ARRAY_SIZE(brcms_2ghz_chantable),
213 .bitrates = legacy_ratetable,
214 .n_bitrates = ARRAY_SIZE(legacy_ratetable),
215 .ht_cap = {
216 /* from include/linux/ieee80211.h */
217 .cap = IEEE80211_HT_CAP_GRN_FLD |
218 IEEE80211_HT_CAP_SGI_20 |
219 IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT,
220 .ht_supported = true,
221 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
222 .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
223 .mcs = {
224 /* placeholders for now */
225 .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
226 .rx_highest = cpu_to_le16(500),
227 .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
228 }
229};
230
231static const struct ieee80211_supported_band brcms_band_5GHz_nphy_template = {
232 .band = IEEE80211_BAND_5GHZ,
233 .channels = brcms_5ghz_nphy_chantable,
234 .n_channels = ARRAY_SIZE(brcms_5ghz_nphy_chantable),
235 .bitrates = legacy_ratetable + BRCMS_LEGACY_5G_RATE_OFFSET,
236 .n_bitrates = ARRAY_SIZE(legacy_ratetable) -
237 BRCMS_LEGACY_5G_RATE_OFFSET,
238 .ht_cap = {
239 .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 |
240 IEEE80211_HT_CAP_SGI_40 |
241 IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */
242 .ht_supported = true,
243 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
244 .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
245 .mcs = {
246 /* placeholders for now */
247 .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
248 .rx_highest = cpu_to_le16(500),
249 .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
250 }
251};
252
253/* flags the given rate in rateset as requested */
254static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br)
255{
256 u32 i;
257
258 for (i = 0; i < rs->count; i++) {
259 if (rate != (rs->rates[i] & 0x7f))
260 continue;
261
262 if (is_br)
263 rs->rates[i] |= BRCMS_RATE_FLAG;
264 else
265 rs->rates[i] &= BRCMS_RATE_MASK;
266 return;
267 }
268}
269
270static void brcms_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
271{
272 struct brcms_info *wl = hw->priv;
273
274 spin_lock_bh(&wl->lock);
275 if (!wl->pub->up) {
276 wiphy_err(wl->wiphy, "ops->tx called while down\n");
277 kfree_skb(skb);
278 goto done;
279 }
280 brcms_c_sendpkt_mac80211(wl->wlc, skb, hw);
281 done:
282 spin_unlock_bh(&wl->lock);
283}
284
285static int brcms_ops_start(struct ieee80211_hw *hw)
286{
287 struct brcms_info *wl = hw->priv;
288 bool blocked;
289
290 ieee80211_wake_queues(hw);
291 spin_lock_bh(&wl->lock);
292 blocked = brcms_rfkill_set_hw_state(wl);
293 spin_unlock_bh(&wl->lock);
294 if (!blocked)
295 wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
296
297 return 0;
298}
299
300static void brcms_ops_stop(struct ieee80211_hw *hw)
301{
302 ieee80211_stop_queues(hw);
303}
304
305static int
306brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
307{
308 struct brcms_info *wl;
309 int err;
310
311 /* Just STA for now */
312 if (vif->type != NL80211_IFTYPE_AP &&
313 vif->type != NL80211_IFTYPE_MESH_POINT &&
314 vif->type != NL80211_IFTYPE_STATION &&
315 vif->type != NL80211_IFTYPE_WDS &&
316 vif->type != NL80211_IFTYPE_ADHOC) {
317 wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only"
318 " STA for now\n", __func__, vif->type);
319 return -EOPNOTSUPP;
320 }
321
322 wl = hw->priv;
323 spin_lock_bh(&wl->lock);
324 if (!wl->pub->up)
325 err = brcms_up(wl);
326 else
327 err = -ENODEV;
328 spin_unlock_bh(&wl->lock);
329
330 if (err != 0)
331 wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__,
332 err);
333
334 return err;
335}
336
337static void
338brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
339{
340 struct brcms_info *wl;
341
342 wl = hw->priv;
343
344 /* put driver in down state */
345 spin_lock_bh(&wl->lock);
346 brcms_down(wl);
347 spin_unlock_bh(&wl->lock);
348}
349
350static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
351{
352 struct ieee80211_conf *conf = &hw->conf;
353 struct brcms_info *wl = hw->priv;
354 int err = 0;
355 int new_int;
356 struct wiphy *wiphy = hw->wiphy;
357
358 spin_lock_bh(&wl->lock);
359 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
360 brcms_c_set_beacon_listen_interval(wl->wlc,
361 conf->listen_interval);
362 }
363 if (changed & IEEE80211_CONF_CHANGE_MONITOR)
364 wiphy_err(wiphy, "%s: change monitor mode: %s (implement)\n",
365 __func__, conf->flags & IEEE80211_CONF_MONITOR ?
366 "true" : "false");
367 if (changed & IEEE80211_CONF_CHANGE_PS)
368 wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n",
369 __func__, conf->flags & IEEE80211_CONF_PS ?
370 "true" : "false");
371
372 if (changed & IEEE80211_CONF_CHANGE_POWER) {
373 err = brcms_c_set_tx_power(wl->wlc, conf->power_level);
374 if (err < 0) {
375 wiphy_err(wiphy, "%s: Error setting power_level\n",
376 __func__);
377 goto config_out;
378 }
379 new_int = brcms_c_get_tx_power(wl->wlc);
380 if (new_int != conf->power_level)
381 wiphy_err(wiphy, "%s: Power level req != actual, %d %d"
382 "\n", __func__, conf->power_level,
383 new_int);
384 }
385 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
386 if (conf->channel_type == NL80211_CHAN_HT20 ||
387 conf->channel_type == NL80211_CHAN_NO_HT)
388 err = brcms_c_set_channel(wl->wlc,
389 conf->channel->hw_value);
390 else
391 err = -ENOTSUPP;
392 }
393 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
394 err = brcms_c_set_rate_limit(wl->wlc,
395 conf->short_frame_max_tx_count,
396 conf->long_frame_max_tx_count);
397
398 config_out:
399 spin_unlock_bh(&wl->lock);
400 return err;
401}
402
403static void
404brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
405 struct ieee80211_vif *vif,
406 struct ieee80211_bss_conf *info, u32 changed)
407{
408 struct brcms_info *wl = hw->priv;
409 struct wiphy *wiphy = hw->wiphy;
410
411 if (changed & BSS_CHANGED_ASSOC) {
412 /* association status changed (associated/disassociated)
413 * also implies a change in the AID.
414 */
415 wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME,
416 __func__, info->assoc ? "" : "dis");
417 spin_lock_bh(&wl->lock);
418 brcms_c_associate_upd(wl->wlc, info->assoc);
419 spin_unlock_bh(&wl->lock);
420 }
421 if (changed & BSS_CHANGED_ERP_SLOT) {
422 s8 val;
423
424 /* slot timing changed */
425 if (info->use_short_slot)
426 val = 1;
427 else
428 val = 0;
429 spin_lock_bh(&wl->lock);
430 brcms_c_set_shortslot_override(wl->wlc, val);
431 spin_unlock_bh(&wl->lock);
432 }
433
434 if (changed & BSS_CHANGED_HT) {
435 /* 802.11n parameters changed */
436 u16 mode = info->ht_operation_mode;
437
438 spin_lock_bh(&wl->lock);
439 brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_CFG,
440 mode & IEEE80211_HT_OP_MODE_PROTECTION);
441 brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_NONGF,
442 mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
443 brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_OBSS,
444 mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT);
445 spin_unlock_bh(&wl->lock);
446 }
447 if (changed & BSS_CHANGED_BASIC_RATES) {
448 struct ieee80211_supported_band *bi;
449 u32 br_mask, i;
450 u16 rate;
451 struct brcm_rateset rs;
452 int error;
453
454 /* retrieve the current rates */
455 spin_lock_bh(&wl->lock);
456 brcms_c_get_current_rateset(wl->wlc, &rs);
457 spin_unlock_bh(&wl->lock);
458
459 br_mask = info->basic_rates;
460 bi = hw->wiphy->bands[brcms_c_get_curband(wl->wlc)];
461 for (i = 0; i < bi->n_bitrates; i++) {
462 /* convert to internal rate value */
463 rate = (bi->bitrates[i].bitrate << 1) / 10;
464
465 /* set/clear basic rate flag */
466 brcms_set_basic_rate(&rs, rate, br_mask & 1);
467 br_mask >>= 1;
468 }
469
470 /* update the rate set */
471 spin_lock_bh(&wl->lock);
472 error = brcms_c_set_rateset(wl->wlc, &rs);
473 spin_unlock_bh(&wl->lock);
474 if (error)
475 wiphy_err(wiphy, "changing basic rates failed: %d\n",
476 error);
477 }
478 if (changed & BSS_CHANGED_BEACON_INT) {
479 /* Beacon interval changed */
480 spin_lock_bh(&wl->lock);
481 brcms_c_set_beacon_period(wl->wlc, info->beacon_int);
482 spin_unlock_bh(&wl->lock);
483 }
484 if (changed & BSS_CHANGED_BSSID) {
485 /* BSSID changed, for whatever reason (IBSS and managed mode) */
486 spin_lock_bh(&wl->lock);
487 brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid);
488 spin_unlock_bh(&wl->lock);
489 }
490 if (changed & BSS_CHANGED_BEACON)
491 /* Beacon data changed, retrieve new beacon (beaconing modes) */
492 wiphy_err(wiphy, "%s: beacon changed\n", __func__);
493
494 if (changed & BSS_CHANGED_BEACON_ENABLED) {
495 /* Beaconing should be enabled/disabled (beaconing modes) */
496 wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__,
497 info->enable_beacon ? "true" : "false");
498 }
499
500 if (changed & BSS_CHANGED_CQM) {
501 /* Connection quality monitor config changed */
502 wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d "
503 " (implement)\n", __func__, info->cqm_rssi_thold,
504 info->cqm_rssi_hyst);
505 }
506
507 if (changed & BSS_CHANGED_IBSS) {
508 /* IBSS join status changed */
509 wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__,
510 info->ibss_joined ? "true" : "false");
511 }
512
513 if (changed & BSS_CHANGED_ARP_FILTER) {
514 /* Hardware ARP filter address list or state changed */
515 wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d"
516 " (implement)\n", __func__, info->arp_filter_enabled ?
517 "true" : "false", info->arp_addr_cnt);
518 }
519
520 if (changed & BSS_CHANGED_QOS) {
521 /*
522 * QoS for this association was enabled/disabled.
523 * Note that it is only ever disabled for station mode.
524 */
525 wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__,
526 info->qos ? "true" : "false");
527 }
528 return;
529}
530
531static void
532brcms_ops_configure_filter(struct ieee80211_hw *hw,
533 unsigned int changed_flags,
534 unsigned int *total_flags, u64 multicast)
535{
536 struct brcms_info *wl = hw->priv;
537 struct wiphy *wiphy = hw->wiphy;
538
539 changed_flags &= MAC_FILTERS;
540 *total_flags &= MAC_FILTERS;
541 if (changed_flags & FIF_PROMISC_IN_BSS)
542 wiphy_err(wiphy, "FIF_PROMISC_IN_BSS\n");
543 if (changed_flags & FIF_ALLMULTI)
544 wiphy_err(wiphy, "FIF_ALLMULTI\n");
545 if (changed_flags & FIF_FCSFAIL)
546 wiphy_err(wiphy, "FIF_FCSFAIL\n");
547 if (changed_flags & FIF_PLCPFAIL)
548 wiphy_err(wiphy, "FIF_PLCPFAIL\n");
549 if (changed_flags & FIF_CONTROL)
550 wiphy_err(wiphy, "FIF_CONTROL\n");
551 if (changed_flags & FIF_OTHER_BSS)
552 wiphy_err(wiphy, "FIF_OTHER_BSS\n");
553 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
554 spin_lock_bh(&wl->lock);
555 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
556 wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS;
557 brcms_c_mac_bcn_promisc_change(wl->wlc, 1);
558 } else {
559 brcms_c_mac_bcn_promisc_change(wl->wlc, 0);
560 wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS;
561 }
562 spin_unlock_bh(&wl->lock);
563 }
564 return;
565}
566
567static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw)
568{
569 struct brcms_info *wl = hw->priv;
570 spin_lock_bh(&wl->lock);
571 brcms_c_scan_start(wl->wlc);
572 spin_unlock_bh(&wl->lock);
573 return;
574}
575
576static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw)
577{
578 struct brcms_info *wl = hw->priv;
579 spin_lock_bh(&wl->lock);
580 brcms_c_scan_stop(wl->wlc);
581 spin_unlock_bh(&wl->lock);
582 return;
583}
584
585static int
586brcms_ops_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
587 const struct ieee80211_tx_queue_params *params)
588{
589 struct brcms_info *wl = hw->priv;
590
591 spin_lock_bh(&wl->lock);
592 brcms_c_wme_setparams(wl->wlc, queue, params, true);
593 spin_unlock_bh(&wl->lock);
594
595 return 0;
596}
597
598static int
599brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
600 struct ieee80211_sta *sta)
601{
602 struct brcms_info *wl = hw->priv;
603 struct scb *scb = &wl->wlc->pri_scb;
604
605 brcms_c_init_scb(scb);
606
607 wl->pub->global_ampdu = &(scb->scb_ampdu);
608 wl->pub->global_ampdu->scb = scb;
609 wl->pub->global_ampdu->max_pdu = 16;
610
611 sta->ht_cap.ht_supported = true;
612 sta->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
613 sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY;
614 sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD |
615 IEEE80211_HT_CAP_SGI_20 |
616 IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT;
617
618 /*
619 * minstrel_ht initiates addBA on our behalf by calling
620 * ieee80211_start_tx_ba_session()
621 */
622 return 0;
623}
624
625static int
626brcms_ops_ampdu_action(struct ieee80211_hw *hw,
627 struct ieee80211_vif *vif,
628 enum ieee80211_ampdu_mlme_action action,
629 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
630 u8 buf_size)
631{
632 struct brcms_info *wl = hw->priv;
633 struct scb *scb = &wl->wlc->pri_scb;
634 int status;
635
636 if (WARN_ON(scb->magic != SCB_MAGIC))
637 return -EIDRM;
638 switch (action) {
639 case IEEE80211_AMPDU_RX_START:
640 break;
641 case IEEE80211_AMPDU_RX_STOP:
642 break;
643 case IEEE80211_AMPDU_TX_START:
644 spin_lock_bh(&wl->lock);
645 status = brcms_c_aggregatable(wl->wlc, tid);
646 spin_unlock_bh(&wl->lock);
647 if (!status) {
648 wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n",
649 tid);
650 return -EINVAL;
651 }
652 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
653 break;
654
655 case IEEE80211_AMPDU_TX_STOP:
656 spin_lock_bh(&wl->lock);
657 brcms_c_ampdu_flush(wl->wlc, sta, tid);
658 spin_unlock_bh(&wl->lock);
659 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
660 break;
661 case IEEE80211_AMPDU_TX_OPERATIONAL:
662 /*
663 * BA window size from ADDBA response ('buf_size') defines how
664 * many outstanding MPDUs are allowed for the BA stream by
665 * recipient and traffic class. 'ampdu_factor' gives maximum
666 * AMPDU size.
667 */
668 spin_lock_bh(&wl->lock);
669 brcms_c_ampdu_tx_operational(wl->wlc, tid, buf_size,
670 (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
671 sta->ht_cap.ampdu_factor)) - 1);
672 spin_unlock_bh(&wl->lock);
673 /* Power save wakeup */
674 break;
675 default:
676 wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n",
677 __func__);
678 }
679
680 return 0;
681}
682
683static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw)
684{
685 struct brcms_info *wl = hw->priv;
686 bool blocked;
687
688 spin_lock_bh(&wl->lock);
689 blocked = brcms_c_check_radio_disabled(wl->wlc);
690 spin_unlock_bh(&wl->lock);
691
692 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
693}
694
695static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop)
696{
697 struct brcms_info *wl = hw->priv;
698
699 no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
700
701 /* wait for packet queue and dma fifos to run empty */
702 spin_lock_bh(&wl->lock);
703 brcms_c_wait_for_tx_completion(wl->wlc, drop);
704 spin_unlock_bh(&wl->lock);
705}
706
707static const struct ieee80211_ops brcms_ops = {
708 .tx = brcms_ops_tx,
709 .start = brcms_ops_start,
710 .stop = brcms_ops_stop,
711 .add_interface = brcms_ops_add_interface,
712 .remove_interface = brcms_ops_remove_interface,
713 .config = brcms_ops_config,
714 .bss_info_changed = brcms_ops_bss_info_changed,
715 .configure_filter = brcms_ops_configure_filter,
716 .sw_scan_start = brcms_ops_sw_scan_start,
717 .sw_scan_complete = brcms_ops_sw_scan_complete,
718 .conf_tx = brcms_ops_conf_tx,
719 .sta_add = brcms_ops_sta_add,
720 .ampdu_action = brcms_ops_ampdu_action,
721 .rfkill_poll = brcms_ops_rfkill_poll,
722 .flush = brcms_ops_flush,
723};
724
725/*
726 * is called in brcms_pci_probe() context, therefore no locking required.
727 */
728static int brcms_set_hint(struct brcms_info *wl, char *abbrev)
729{
730 return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev);
731}
732
733void brcms_dpc(unsigned long data)
734{
735 struct brcms_info *wl;
736
737 wl = (struct brcms_info *) data;
738
739 spin_lock_bh(&wl->lock);
740
741 /* call the common second level interrupt handler */
742 if (wl->pub->up) {
743 if (wl->resched) {
744 unsigned long flags;
745
746 spin_lock_irqsave(&wl->isr_lock, flags);
747 brcms_c_intrsupd(wl->wlc);
748 spin_unlock_irqrestore(&wl->isr_lock, flags);
749 }
750
751 wl->resched = brcms_c_dpc(wl->wlc, true);
752 }
753
754 /* brcms_c_dpc() may bring the driver down */
755 if (!wl->pub->up)
756 goto done;
757
758 /* re-schedule dpc */
759 if (wl->resched)
760 tasklet_schedule(&wl->tasklet);
761 else
762 /* re-enable interrupts */
763 brcms_intrson(wl);
764
765 done:
766 spin_unlock_bh(&wl->lock);
767}
768
769/*
770 * Precondition: Since this function is called in brcms_pci_probe() context,
771 * no locking is required.
772 */
773static int brcms_request_fw(struct brcms_info *wl, struct pci_dev *pdev)
774{
775 int status;
776 struct device *device = &pdev->dev;
777 char fw_name[100];
778 int i;
779
780 memset(&wl->fw, 0, sizeof(struct brcms_firmware));
781 for (i = 0; i < MAX_FW_IMAGES; i++) {
782 if (brcms_firmwares[i] == NULL)
783 break;
784 sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i],
785 UCODE_LOADER_API_VER);
786 status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
787 if (status) {
788 wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
789 KBUILD_MODNAME, fw_name);
790 return status;
791 }
792 sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i],
793 UCODE_LOADER_API_VER);
794 status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
795 if (status) {
796 wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
797 KBUILD_MODNAME, fw_name);
798 return status;
799 }
800 wl->fw.hdr_num_entries[i] =
801 wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr));
802 }
803 wl->fw.fw_cnt = i;
804 return brcms_ucode_data_init(wl, &wl->ucode);
805}
806
807/*
808 * Precondition: Since this function is called in brcms_pci_probe() context,
809 * no locking is required.
810 */
811static void brcms_release_fw(struct brcms_info *wl)
812{
813 int i;
814 for (i = 0; i < MAX_FW_IMAGES; i++) {
815 release_firmware(wl->fw.fw_bin[i]);
816 release_firmware(wl->fw.fw_hdr[i]);
817 }
818}
819
820/**
821 * This function frees the WL per-device resources.
822 *
823 * This function frees resources owned by the WL device pointed to
824 * by the wl parameter.
825 *
826 * precondition: can both be called locked and unlocked
827 *
828 */
829static void brcms_free(struct brcms_info *wl)
830{
831 struct brcms_timer *t, *next;
832
833 /* free ucode data */
834 if (wl->fw.fw_cnt)
835 brcms_ucode_data_free(&wl->ucode);
836 if (wl->irq)
837 free_irq(wl->irq, wl);
838
839 /* kill dpc */
840 tasklet_kill(&wl->tasklet);
841
842 if (wl->pub)
843 brcms_c_module_unregister(wl->pub, "linux", wl);
844
845 /* free common resources */
846 if (wl->wlc) {
847 brcms_c_detach(wl->wlc);
848 wl->wlc = NULL;
849 wl->pub = NULL;
850 }
851
852 /* virtual interface deletion is deferred so we cannot spinwait */
853
854 /* wait for all pending callbacks to complete */
855 while (atomic_read(&wl->callbacks) > 0)
856 schedule();
857
858 /* free timers */
859 for (t = wl->timers; t; t = next) {
860 next = t->next;
861#ifdef BCMDBG
862 kfree(t->name);
863#endif
864 kfree(t);
865 }
866
867 /*
868 * unregister_netdev() calls get_stats() which may read chip
869 * registers so we cannot unmap the chip registers until
870 * after calling unregister_netdev() .
871 */
872 if (wl->regsva)
873 iounmap(wl->regsva);
874
875 wl->regsva = NULL;
876}
877
878/*
879* called from both kernel as from this kernel module.
880* precondition: perimeter lock is not acquired.
881*/
882static void brcms_remove(struct pci_dev *pdev)
883{
884 struct brcms_info *wl;
885 struct ieee80211_hw *hw;
886 int status;
887
888 hw = pci_get_drvdata(pdev);
889 wl = hw->priv;
890 if (!wl) {
891 pr_err("wl: brcms_remove: pci_get_drvdata failed\n");
892 return;
893 }
894
895 spin_lock_bh(&wl->lock);
896 status = brcms_c_chipmatch(pdev->vendor, pdev->device);
897 spin_unlock_bh(&wl->lock);
898 if (!status) {
899 wiphy_err(wl->wiphy, "wl: brcms_remove: chipmatch "
900 "failed\n");
901 return;
902 }
903 if (wl->wlc) {
904 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
905 wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
906 ieee80211_unregister_hw(hw);
907 spin_lock_bh(&wl->lock);
908 brcms_down(wl);
909 spin_unlock_bh(&wl->lock);
910 }
911 pci_disable_device(pdev);
912
913 brcms_free(wl);
914
915 pci_set_drvdata(pdev, NULL);
916 ieee80211_free_hw(hw);
917}
918
919static irqreturn_t brcms_isr(int irq, void *dev_id)
920{
921 struct brcms_info *wl;
922 bool ours, wantdpc;
923
924 wl = (struct brcms_info *) dev_id;
925
926 spin_lock(&wl->isr_lock);
927
928 /* call common first level interrupt handler */
929 ours = brcms_c_isr(wl->wlc, &wantdpc);
930 if (ours) {
931 /* if more to do... */
932 if (wantdpc) {
933
934 /* ...and call the second level interrupt handler */
935 /* schedule dpc */
936 tasklet_schedule(&wl->tasklet);
937 }
938 }
939
940 spin_unlock(&wl->isr_lock);
941
942 return IRQ_RETVAL(ours);
943}
944
945/*
946 * is called in brcms_pci_probe() context, therefore no locking required.
947 */
948static int ieee_hw_rate_init(struct ieee80211_hw *hw)
949{
950 struct brcms_info *wl = hw->priv;
951 struct brcms_c_info *wlc = wl->wlc;
952 struct ieee80211_supported_band *band;
953 int has_5g = 0;
954 u16 phy_type;
955
956 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
957 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
958
959 phy_type = brcms_c_get_phy_type(wl->wlc, 0);
960 if (phy_type == PHY_TYPE_N || phy_type == PHY_TYPE_LCN) {
961 band = &wlc->bandstate[BAND_2G_INDEX]->band;
962 *band = brcms_band_2GHz_nphy_template;
963 if (phy_type == PHY_TYPE_LCN) {
964 /* Single stream */
965 band->ht_cap.mcs.rx_mask[1] = 0;
966 band->ht_cap.mcs.rx_highest = cpu_to_le16(72);
967 }
968 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
969 } else {
970 return -EPERM;
971 }
972
973 /* Assume all bands use the same phy. True for 11n devices. */
974 if (wl->pub->_nbands > 1) {
975 has_5g++;
976 if (phy_type == PHY_TYPE_N || phy_type == PHY_TYPE_LCN) {
977 band = &wlc->bandstate[BAND_5G_INDEX]->band;
978 *band = brcms_band_5GHz_nphy_template;
979 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = band;
980 } else {
981 return -EPERM;
982 }
983 }
984 return 0;
985}
986
987/*
988 * is called in brcms_pci_probe() context, therefore no locking required.
989 */
990static int ieee_hw_init(struct ieee80211_hw *hw)
991{
992 hw->flags = IEEE80211_HW_SIGNAL_DBM
993 /* | IEEE80211_HW_CONNECTION_MONITOR What is this? */
994 | IEEE80211_HW_REPORTS_TX_ACK_STATUS
995 | IEEE80211_HW_AMPDU_AGGREGATION;
996
997 hw->extra_tx_headroom = brcms_c_get_header_len();
998 hw->queues = N_TX_QUEUES;
999 hw->max_rates = 2; /* Primary rate and 1 fallback rate */
1000
1001 /* channel change time is dependent on chip and band */
1002 hw->channel_change_time = 7 * 1000;
1003 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1004
1005 hw->rate_control_algorithm = "minstrel_ht";
1006
1007 hw->sta_data_size = 0;
1008 return ieee_hw_rate_init(hw);
1009}
1010
1011/**
1012 * attach to the WL device.
1013 *
1014 * Attach to the WL device identified by vendor and device parameters.
1015 * regs is a host accessible memory address pointing to WL device registers.
1016 *
1017 * brcms_attach is not defined as static because in the case where no bus
1018 * is defined, wl_attach will never be called, and thus, gcc will issue
1019 * a warning that this function is defined but not used if we declare
1020 * it as static.
1021 *
1022 *
1023 * is called in brcms_pci_probe() context, therefore no locking required.
1024 */
1025static struct brcms_info *brcms_attach(u16 vendor, u16 device,
1026 resource_size_t regs,
1027 struct pci_dev *btparam, uint irq)
1028{
1029 struct brcms_info *wl = NULL;
1030 int unit, err;
1031 struct ieee80211_hw *hw;
1032 u8 perm[ETH_ALEN];
1033
1034 unit = n_adapters_found;
1035 err = 0;
1036
1037 if (unit < 0)
1038 return NULL;
1039
1040 /* allocate private info */
1041 hw = pci_get_drvdata(btparam); /* btparam == pdev */
1042 if (hw != NULL)
1043 wl = hw->priv;
1044 if (WARN_ON(hw == NULL) || WARN_ON(wl == NULL))
1045 return NULL;
1046 wl->wiphy = hw->wiphy;
1047
1048 atomic_set(&wl->callbacks, 0);
1049
1050 /* setup the bottom half handler */
1051 tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl);
1052
1053 wl->regsva = ioremap_nocache(regs, PCI_BAR0_WINSZ);
1054 if (wl->regsva == NULL) {
1055 wiphy_err(wl->wiphy, "wl%d: ioremap() failed\n", unit);
1056 goto fail;
1057 }
1058 spin_lock_init(&wl->lock);
1059 spin_lock_init(&wl->isr_lock);
1060
1061 /* prepare ucode */
1062 if (brcms_request_fw(wl, btparam) < 0) {
1063 wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
1064 "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
1065 brcms_release_fw(wl);
1066 brcms_remove(btparam);
1067 return NULL;
1068 }
1069
1070 /* common load-time initialization */
1071 wl->wlc = brcms_c_attach(wl, vendor, device, unit, false,
1072 wl->regsva, btparam, &err);
1073 brcms_release_fw(wl);
1074 if (!wl->wlc) {
1075 wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n",
1076 KBUILD_MODNAME, err);
1077 goto fail;
1078 }
1079 wl->pub = brcms_c_pub(wl->wlc);
1080
1081 wl->pub->ieee_hw = hw;
1082
1083 /* disable mpc */
1084 brcms_c_set_radio_mpc(wl->wlc, false);
1085
1086 /* register our interrupt handler */
1087 if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
1088 wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
1089 goto fail;
1090 }
1091 wl->irq = irq;
1092
1093 /* register module */
1094 brcms_c_module_register(wl->pub, "linux", wl, NULL);
1095
1096 if (ieee_hw_init(hw)) {
1097 wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit,
1098 __func__);
1099 goto fail;
1100 }
1101
1102 memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN);
1103 if (WARN_ON(!is_valid_ether_addr(perm)))
1104 goto fail;
1105 SET_IEEE80211_PERM_ADDR(hw, perm);
1106
1107 err = ieee80211_register_hw(hw);
1108 if (err)
1109 wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status"
1110 "%d\n", __func__, err);
1111
1112 if (wl->pub->srom_ccode[0])
1113 err = brcms_set_hint(wl, wl->pub->srom_ccode);
1114 else
1115 err = brcms_set_hint(wl, "US");
1116 if (err)
1117 wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n",
1118 __func__, err);
1119
1120 n_adapters_found++;
1121 return wl;
1122
1123fail:
1124 brcms_free(wl);
1125 return NULL;
1126}
1127
1128
1129
1130/**
1131 * determines if a device is a WL device, and if so, attaches it.
1132 *
1133 * This function determines if a device pointed to by pdev is a WL device,
1134 * and if so, performs a brcms_attach() on it.
1135 *
1136 * Perimeter lock is initialized in the course of this function.
1137 */
1138static int __devinit
1139brcms_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1140{
1141 int rc;
1142 struct brcms_info *wl;
1143 struct ieee80211_hw *hw;
1144 u32 val;
1145
1146 dev_info(&pdev->dev, "bus %d slot %d func %d irq %d\n",
1147 pdev->bus->number, PCI_SLOT(pdev->devfn),
1148 PCI_FUNC(pdev->devfn), pdev->irq);
1149
1150 if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) ||
1151 ((pdev->device != 0x0576) &&
1152 ((pdev->device & 0xff00) != 0x4300) &&
1153 ((pdev->device & 0xff00) != 0x4700) &&
1154 ((pdev->device < 43000) || (pdev->device > 43999))))
1155 return -ENODEV;
1156
1157 rc = pci_enable_device(pdev);
1158 if (rc) {
1159 pr_err("%s: Cannot enable device %d-%d_%d\n",
1160 __func__, pdev->bus->number, PCI_SLOT(pdev->devfn),
1161 PCI_FUNC(pdev->devfn));
1162 return -ENODEV;
1163 }
1164 pci_set_master(pdev);
1165
1166 pci_read_config_dword(pdev, 0x40, &val);
1167 if ((val & 0x0000ff00) != 0)
1168 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1169
1170 hw = ieee80211_alloc_hw(sizeof(struct brcms_info), &brcms_ops);
1171 if (!hw) {
1172 pr_err("%s: ieee80211_alloc_hw failed\n", __func__);
1173 return -ENOMEM;
1174 }
1175
1176 SET_IEEE80211_DEV(hw, &pdev->dev);
1177
1178 pci_set_drvdata(pdev, hw);
1179
1180 memset(hw->priv, 0, sizeof(*wl));
1181
1182 wl = brcms_attach(pdev->vendor, pdev->device,
1183 pci_resource_start(pdev, 0), pdev,
1184 pdev->irq);
1185
1186 if (!wl) {
1187 pr_err("%s: %s: brcms_attach failed!\n", KBUILD_MODNAME,
1188 __func__);
1189 return -ENODEV;
1190 }
1191 return 0;
1192}
1193
1194static int brcms_suspend(struct pci_dev *pdev, pm_message_t state)
1195{
1196 struct brcms_info *wl;
1197 struct ieee80211_hw *hw;
1198
1199 hw = pci_get_drvdata(pdev);
1200 wl = hw->priv;
1201 if (!wl) {
1202 wiphy_err(wl->wiphy,
1203 "brcms_suspend: pci_get_drvdata failed\n");
1204 return -ENODEV;
1205 }
1206
1207 /* only need to flag hw is down for proper resume */
1208 spin_lock_bh(&wl->lock);
1209 wl->pub->hw_up = false;
1210 spin_unlock_bh(&wl->lock);
1211
1212 pci_save_state(pdev);
1213 pci_disable_device(pdev);
1214 return pci_set_power_state(pdev, PCI_D3hot);
1215}
1216
1217static int brcms_resume(struct pci_dev *pdev)
1218{
1219 struct brcms_info *wl;
1220 struct ieee80211_hw *hw;
1221 int err = 0;
1222 u32 val;
1223
1224 hw = pci_get_drvdata(pdev);
1225 wl = hw->priv;
1226 if (!wl) {
1227 wiphy_err(wl->wiphy,
1228 "wl: brcms_resume: pci_get_drvdata failed\n");
1229 return -ENODEV;
1230 }
1231
1232 err = pci_set_power_state(pdev, PCI_D0);
1233 if (err)
1234 return err;
1235
1236 pci_restore_state(pdev);
1237
1238 err = pci_enable_device(pdev);
1239 if (err)
1240 return err;
1241
1242 pci_set_master(pdev);
1243
1244 pci_read_config_dword(pdev, 0x40, &val);
1245 if ((val & 0x0000ff00) != 0)
1246 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1247
1248 /*
1249 * done. driver will be put in up state
1250 * in brcms_ops_add_interface() call.
1251 */
1252 return err;
1253}
1254
1255static struct pci_driver brcms_pci_driver = {
1256 .name = KBUILD_MODNAME,
1257 .probe = brcms_pci_probe,
1258 .suspend = brcms_suspend,
1259 .resume = brcms_resume,
1260 .remove = __devexit_p(brcms_remove),
1261 .id_table = brcms_pci_id_table,
1262};
1263
1264/**
1265 * This is the main entry point for the WL driver.
1266 *
1267 * This function determines if a device pointed to by pdev is a WL device,
1268 * and if so, performs a brcms_attach() on it.
1269 *
1270 */
1271static int __init brcms_module_init(void)
1272{
1273 int error = -ENODEV;
1274
1275#ifdef BCMDBG
1276 if (msglevel != 0xdeadbeef)
1277 brcm_msg_level = msglevel;
1278#endif /* BCMDBG */
1279
1280 error = pci_register_driver(&brcms_pci_driver);
1281 if (!error)
1282 return 0;
1283
1284
1285
1286 return error;
1287}
1288
1289/**
1290 * This function unloads the WL driver from the system.
1291 *
1292 * This function unconditionally unloads the WL driver module from the
1293 * system.
1294 *
1295 */
1296static void __exit brcms_module_exit(void)
1297{
1298 pci_unregister_driver(&brcms_pci_driver);
1299
1300}
1301
1302module_init(brcms_module_init);
1303module_exit(brcms_module_exit);
1304
1305/*
1306 * precondition: perimeter lock has been acquired
1307 */
1308void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
1309 bool state, int prio)
1310{
1311 wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__);
1312}
1313
1314/*
1315 * precondition: perimeter lock has been acquired
1316 */
1317void brcms_init(struct brcms_info *wl)
1318{
1319 BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit);
1320 brcms_reset(wl);
1321
1322 brcms_c_init(wl->wlc);
1323}
1324
1325/*
1326 * precondition: perimeter lock has been acquired
1327 */
1328uint brcms_reset(struct brcms_info *wl)
1329{
1330 BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit);
1331 brcms_c_reset(wl->wlc);
1332
1333 /* dpc will not be rescheduled */
1334 wl->resched = 0;
1335
1336 return 0;
1337}
1338
1339/*
1340 * These are interrupt on/off entry points. Disable interrupts
1341 * during interrupt state transition.
1342 */
1343void brcms_intrson(struct brcms_info *wl)
1344{
1345 unsigned long flags;
1346
1347 spin_lock_irqsave(&wl->isr_lock, flags);
1348 brcms_c_intrson(wl->wlc);
1349 spin_unlock_irqrestore(&wl->isr_lock, flags);
1350}
1351
1352u32 brcms_intrsoff(struct brcms_info *wl)
1353{
1354 unsigned long flags;
1355 u32 status;
1356
1357 spin_lock_irqsave(&wl->isr_lock, flags);
1358 status = brcms_c_intrsoff(wl->wlc);
1359 spin_unlock_irqrestore(&wl->isr_lock, flags);
1360 return status;
1361}
1362
1363void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask)
1364{
1365 unsigned long flags;
1366
1367 spin_lock_irqsave(&wl->isr_lock, flags);
1368 brcms_c_intrsrestore(wl->wlc, macintmask);
1369 spin_unlock_irqrestore(&wl->isr_lock, flags);
1370}
1371
1372/*
1373 * precondition: perimeter lock has been acquired
1374 */
1375int brcms_up(struct brcms_info *wl)
1376{
1377 int error = 0;
1378
1379 if (wl->pub->up)
1380 return 0;
1381
1382 error = brcms_c_up(wl->wlc);
1383
1384 return error;
1385}
1386
1387/*
1388 * precondition: perimeter lock has been acquired
1389 */
1390void brcms_down(struct brcms_info *wl)
1391{
1392 uint callbacks, ret_val = 0;
1393
1394 /* call common down function */
1395 ret_val = brcms_c_down(wl->wlc);
1396 callbacks = atomic_read(&wl->callbacks) - ret_val;
1397
1398 /* wait for down callbacks to complete */
1399 spin_unlock_bh(&wl->lock);
1400
1401 /* For HIGH_only driver, it's important to actually schedule other work,
1402 * not just spin wait since everything runs at schedule level
1403 */
1404 SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000);
1405
1406 spin_lock_bh(&wl->lock);
1407}
1408
1409/*
1410* precondition: perimeter lock is not acquired
1411 */
1412static void _brcms_timer(struct work_struct *work)
1413{
1414 struct brcms_timer *t = container_of(work, struct brcms_timer,
1415 dly_wrk.work);
1416
1417 spin_lock_bh(&t->wl->lock);
1418
1419 if (t->set) {
1420 if (t->periodic) {
1421 atomic_inc(&t->wl->callbacks);
1422 ieee80211_queue_delayed_work(t->wl->pub->ieee_hw,
1423 &t->dly_wrk,
1424 msecs_to_jiffies(t->ms));
1425 } else {
1426 t->set = false;
1427 }
1428
1429 t->fn(t->arg);
1430 }
1431
1432 atomic_dec(&t->wl->callbacks);
1433
1434 spin_unlock_bh(&t->wl->lock);
1435}
1436
1437/*
1438 * Adds a timer to the list. Caller supplies a timer function.
1439 * Is called from wlc.
1440 *
1441 * precondition: perimeter lock has been acquired
1442 */
1443struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
1444 void (*fn) (void *arg),
1445 void *arg, const char *name)
1446{
1447 struct brcms_timer *t;
1448
1449 t = kzalloc(sizeof(struct brcms_timer), GFP_ATOMIC);
1450 if (!t)
1451 return NULL;
1452
1453 INIT_DELAYED_WORK(&t->dly_wrk, _brcms_timer);
1454 t->wl = wl;
1455 t->fn = fn;
1456 t->arg = arg;
1457 t->next = wl->timers;
1458 wl->timers = t;
1459
1460#ifdef BCMDBG
1461 t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC);
1462 if (t->name)
1463 strcpy(t->name, name);
1464#endif
1465
1466 return t;
1467}
1468
1469/*
1470 * adds only the kernel timer since it's going to be more accurate
1471 * as well as it's easier to make it periodic
1472 *
1473 * precondition: perimeter lock has been acquired
1474 */
1475void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
1476{
1477 struct ieee80211_hw *hw = t->wl->pub->ieee_hw;
1478
1479#ifdef BCMDBG
1480 if (t->set)
1481 wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n",
1482 __func__, t->name, periodic);
1483#endif
1484 t->ms = ms;
1485 t->periodic = (bool) periodic;
1486 t->set = true;
1487
1488 atomic_inc(&t->wl->callbacks);
1489
1490 ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));
1491}
1492
1493/*
1494 * return true if timer successfully deleted, false if still pending
1495 *
1496 * precondition: perimeter lock has been acquired
1497 */
1498bool brcms_del_timer(struct brcms_timer *t)
1499{
1500 if (t->set) {
1501 t->set = false;
1502 if (!cancel_delayed_work(&t->dly_wrk))
1503 return false;
1504
1505 atomic_dec(&t->wl->callbacks);
1506 }
1507
1508 return true;
1509}
1510
1511/*
1512 * precondition: perimeter lock has been acquired
1513 */
1514void brcms_free_timer(struct brcms_timer *t)
1515{
1516 struct brcms_info *wl = t->wl;
1517 struct brcms_timer *tmp;
1518
1519 /* delete the timer in case it is active */
1520 brcms_del_timer(t);
1521
1522 if (wl->timers == t) {
1523 wl->timers = wl->timers->next;
1524#ifdef BCMDBG
1525 kfree(t->name);
1526#endif
1527 kfree(t);
1528 return;
1529
1530 }
1531
1532 tmp = wl->timers;
1533 while (tmp) {
1534 if (tmp->next == t) {
1535 tmp->next = t->next;
1536#ifdef BCMDBG
1537 kfree(t->name);
1538#endif
1539 kfree(t);
1540 return;
1541 }
1542 tmp = tmp->next;
1543 }
1544
1545}
1546
1547/*
1548 * precondition: perimeter lock has been acquired
1549 */
1550int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx)
1551{
1552 int i, entry;
1553 const u8 *pdata;
1554 struct firmware_hdr *hdr;
1555 for (i = 0; i < wl->fw.fw_cnt; i++) {
1556 hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data;
1557 for (entry = 0; entry < wl->fw.hdr_num_entries[i];
1558 entry++, hdr++) {
1559 u32 len = le32_to_cpu(hdr->len);
1560 if (le32_to_cpu(hdr->idx) == idx) {
1561 pdata = wl->fw.fw_bin[i]->data +
1562 le32_to_cpu(hdr->offset);
1563 *pbuf = kmalloc(len, GFP_ATOMIC);
1564 if (*pbuf == NULL)
1565 goto fail;
1566
1567 memcpy(*pbuf, pdata, len);
1568 return 0;
1569 }
1570 }
1571 }
1572 wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n",
1573 idx);
1574 *pbuf = NULL;
1575fail:
1576 return -ENODATA;
1577}
1578
1579/*
1580 * Precondition: Since this function is called in brcms_pci_probe() context,
1581 * no locking is required.
1582 */
1583int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx)
1584{
1585 int i, entry;
1586 const u8 *pdata;
1587 struct firmware_hdr *hdr;
1588 for (i = 0; i < wl->fw.fw_cnt; i++) {
1589 hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data;
1590 for (entry = 0; entry < wl->fw.hdr_num_entries[i];
1591 entry++, hdr++) {
1592 if (le32_to_cpu(hdr->idx) == idx) {
1593 pdata = wl->fw.fw_bin[i]->data +
1594 le32_to_cpu(hdr->offset);
1595 if (le32_to_cpu(hdr->len) != 4) {
1596 wiphy_err(wl->wiphy,
1597 "ERROR: fw hdr len\n");
1598 return -ENOMSG;
1599 }
1600 *n_bytes = le32_to_cpu(*((__le32 *) pdata));
1601 return 0;
1602 }
1603 }
1604 }
1605 wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx);
1606 return -ENOMSG;
1607}
1608
1609/*
1610 * precondition: can both be called locked and unlocked
1611 */
1612void brcms_ucode_free_buf(void *p)
1613{
1614 kfree(p);
1615}
1616
1617/*
1618 * checks validity of all firmware images loaded from user space
1619 *
1620 * Precondition: Since this function is called in brcms_pci_probe() context,
1621 * no locking is required.
1622 */
1623int brcms_check_firmwares(struct brcms_info *wl)
1624{
1625 int i;
1626 int entry;
1627 int rc = 0;
1628 const struct firmware *fw;
1629 const struct firmware *fw_hdr;
1630 struct firmware_hdr *ucode_hdr;
1631 for (i = 0; i < MAX_FW_IMAGES && rc == 0; i++) {
1632 fw = wl->fw.fw_bin[i];
1633 fw_hdr = wl->fw.fw_hdr[i];
1634 if (fw == NULL && fw_hdr == NULL) {
1635 break;
1636 } else if (fw == NULL || fw_hdr == NULL) {
1637 wiphy_err(wl->wiphy, "%s: invalid bin/hdr fw\n",
1638 __func__);
1639 rc = -EBADF;
1640 } else if (fw_hdr->size % sizeof(struct firmware_hdr)) {
1641 wiphy_err(wl->wiphy, "%s: non integral fw hdr file "
1642 "size %zu/%zu\n", __func__, fw_hdr->size,
1643 sizeof(struct firmware_hdr));
1644 rc = -EBADF;
1645 } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) {
1646 wiphy_err(wl->wiphy, "%s: out of bounds fw file size "
1647 "%zu\n", __func__, fw->size);
1648 rc = -EBADF;
1649 } else {
1650 /* check if ucode section overruns firmware image */
1651 ucode_hdr = (struct firmware_hdr *)fw_hdr->data;
1652 for (entry = 0; entry < wl->fw.hdr_num_entries[i] &&
1653 !rc; entry++, ucode_hdr++) {
1654 if (le32_to_cpu(ucode_hdr->offset) +
1655 le32_to_cpu(ucode_hdr->len) >
1656 fw->size) {
1657 wiphy_err(wl->wiphy,
1658 "%s: conflicting bin/hdr\n",
1659 __func__);
1660 rc = -EBADF;
1661 }
1662 }
1663 }
1664 }
1665 if (rc == 0 && wl->fw.fw_cnt != i) {
1666 wiphy_err(wl->wiphy, "%s: invalid fw_cnt=%d\n", __func__,
1667 wl->fw.fw_cnt);
1668 rc = -EBADF;
1669 }
1670 return rc;
1671}
1672
1673/*
1674 * precondition: perimeter lock has been acquired
1675 */
1676bool brcms_rfkill_set_hw_state(struct brcms_info *wl)
1677{
1678 bool blocked = brcms_c_check_radio_disabled(wl->wlc);
1679
1680 spin_unlock_bh(&wl->lock);
1681 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
1682 if (blocked)
1683 wiphy_rfkill_start_polling(wl->pub->ieee_hw->wiphy);
1684 spin_lock_bh(&wl->lock);
1685 return blocked;
1686}
1687
1688/*
1689 * precondition: perimeter lock has been acquired
1690 */
1691void brcms_msleep(struct brcms_info *wl, uint ms)
1692{
1693 spin_unlock_bh(&wl->lock);
1694 msleep(ms);
1695 spin_lock_bh(&wl->lock);
1696}
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 000000000000..177f0e44e4b6
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
@@ -0,0 +1,108 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_MAC80211_IF_H_
18#define _BRCM_MAC80211_IF_H_
19
20#include <linux/timer.h>
21#include <linux/interrupt.h>
22#include <linux/workqueue.h>
23
24#include "ucode_loader.h"
25/*
26 * Starting index for 5G rates in the
27 * legacy rate table.
28 */
29#define BRCMS_LEGACY_5G_RATE_OFFSET 4
30
31/* softmac ioctl definitions */
32#define BRCMS_SET_SHORTSLOT_OVERRIDE 146
33
34struct brcms_timer {
35 struct delayed_work dly_wrk;
36 struct brcms_info *wl;
37 void (*fn) (void *); /* function called upon expiration */
38 void *arg; /* fixed argument provided to called function */
39 uint ms;
40 bool periodic;
41 bool set; /* indicates if timer is active */
42 struct brcms_timer *next; /* for freeing on unload */
43#ifdef BCMDBG
44 char *name; /* Description of the timer */
45#endif
46};
47
48struct brcms_if {
49 uint subunit; /* WDS/BSS unit */
50 struct pci_dev *pci_dev;
51};
52
53#define MAX_FW_IMAGES 4
54struct brcms_firmware {
55 u32 fw_cnt;
56 const struct firmware *fw_bin[MAX_FW_IMAGES];
57 const struct firmware *fw_hdr[MAX_FW_IMAGES];
58 u32 hdr_num_entries[MAX_FW_IMAGES];
59};
60
61struct brcms_info {
62 struct brcms_pub *pub; /* pointer to public wlc state */
63 struct brcms_c_info *wlc; /* pointer to private common data */
64 u32 magic;
65
66 int irq;
67
68 spinlock_t lock; /* per-device perimeter lock */
69 spinlock_t isr_lock; /* per-device ISR synchronization lock */
70
71 /* regsva for unmap in brcms_free() */
72 void __iomem *regsva; /* opaque chip registers virtual address */
73
74 /* timer related fields */
75 atomic_t callbacks; /* # outstanding callback functions */
76 struct brcms_timer *timers; /* timer cleanup queue */
77
78 struct tasklet_struct tasklet; /* dpc tasklet */
79 bool resched; /* dpc needs to be and is rescheduled */
80 struct brcms_firmware fw;
81 struct wiphy *wiphy;
82 struct brcms_ucode ucode;
83};
84
85/* misc callbacks */
86extern void brcms_init(struct brcms_info *wl);
87extern uint brcms_reset(struct brcms_info *wl);
88extern void brcms_intrson(struct brcms_info *wl);
89extern u32 brcms_intrsoff(struct brcms_info *wl);
90extern void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask);
91extern int brcms_up(struct brcms_info *wl);
92extern void brcms_down(struct brcms_info *wl);
93extern void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
94 bool state, int prio);
95extern bool brcms_rfkill_set_hw_state(struct brcms_info *wl);
96
97/* timer functions */
98extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
99 void (*fn) (void *arg), void *arg,
100 const char *name);
101extern void brcms_free_timer(struct brcms_timer *timer);
102extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic);
103extern bool brcms_del_timer(struct brcms_timer *timer);
104extern void brcms_msleep(struct brcms_info *wl, uint ms);
105extern void brcms_dpc(unsigned long data);
106extern void brcms_timer(struct brcms_timer *t);
107
108#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 000000000000..510e9bb52287
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -0,0 +1,8775 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/pci_ids.h>
18#include <linux/if_ether.h>
19#include <net/mac80211.h>
20#include <brcm_hw_ids.h>
21#include <aiutils.h>
22#include <chipcommon.h>
23#include "rate.h"
24#include "scb.h"
25#include "phy/phy_hal.h"
26#include "channel.h"
27#include "antsel.h"
28#include "stf.h"
29#include "ampdu.h"
30#include "mac80211_if.h"
31#include "ucode_loader.h"
32#include "main.h"
33
34/*
35 * Indication for txflowcontrol that all priority bits in
36 * TXQ_STOP_FOR_PRIOFC_MASK are to be considered.
37 */
38#define ALLPRIO -1
39
40/*
41 * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
42 */
43#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1)
44
45/* watchdog timer, in unit of ms */
46#define TIMER_INTERVAL_WATCHDOG 1000
47/* radio monitor timer, in unit of ms */
48#define TIMER_INTERVAL_RADIOCHK 800
49
50/* Max MPC timeout, in unit of watchdog */
51#ifndef BRCMS_MPC_MAX_DELAYCNT
52#define BRCMS_MPC_MAX_DELAYCNT 10
53#endif
54
55/* Min MPC timeout, in unit of watchdog */
56#define BRCMS_MPC_MIN_DELAYCNT 1
57#define BRCMS_MPC_THRESHOLD 3 /* MPC count threshold level */
58
59/* beacon interval, in unit of 1024TU */
60#define BEACON_INTERVAL_DEFAULT 100
61/* DTIM interval, in unit of beacon interval */
62#define DTIM_INTERVAL_DEFAULT 3
63
64/* Scale down delays to accommodate QT slow speed */
65/* beacon interval, in unit of 1024TU */
66#define BEACON_INTERVAL_DEF_QT 20
67/* DTIM interval, in unit of beacon interval */
68#define DTIM_INTERVAL_DEF_QT 1
69
70#define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */
71
72/* n-mode support capability */
73/* 2x2 includes both 1x1 & 2x2 devices
74 * reserved #define 2 for future when we want to separate 1x1 & 2x2 and
75 * control it independently
76 */
77#define WL_11N_2x2 1
78#define WL_11N_3x3 3
79#define WL_11N_4x4 4
80
81/* define 11n feature disable flags */
82#define WLFEATURE_DISABLE_11N 0x00000001
83#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002
84#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004
85#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008
86#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010
87#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020
88#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040
89#define WLFEATURE_DISABLE_11N_GF 0x00000080
90
91#define EDCF_ACI_MASK 0x60
92#define EDCF_ACI_SHIFT 5
93#define EDCF_ECWMIN_MASK 0x0f
94#define EDCF_ECWMAX_SHIFT 4
95#define EDCF_AIFSN_MASK 0x0f
96#define EDCF_AIFSN_MAX 15
97#define EDCF_ECWMAX_MASK 0xf0
98
99#define EDCF_AC_BE_TXOP_STA 0x0000
100#define EDCF_AC_BK_TXOP_STA 0x0000
101#define EDCF_AC_VO_ACI_STA 0x62
102#define EDCF_AC_VO_ECW_STA 0x32
103#define EDCF_AC_VI_ACI_STA 0x42
104#define EDCF_AC_VI_ECW_STA 0x43
105#define EDCF_AC_BK_ECW_STA 0xA4
106#define EDCF_AC_VI_TXOP_STA 0x005e
107#define EDCF_AC_VO_TXOP_STA 0x002f
108#define EDCF_AC_BE_ACI_STA 0x03
109#define EDCF_AC_BE_ECW_STA 0xA4
110#define EDCF_AC_BK_ACI_STA 0x27
111#define EDCF_AC_VO_TXOP_AP 0x002f
112
113#define EDCF_TXOP2USEC(txop) ((txop) << 5)
114#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1)
115
116#define APHY_SYMBOL_TIME 4
117#define APHY_PREAMBLE_TIME 16
118#define APHY_SIGNAL_TIME 4
119#define APHY_SIFS_TIME 16
120#define APHY_SERVICE_NBITS 16
121#define APHY_TAIL_NBITS 6
122#define BPHY_SIFS_TIME 10
123#define BPHY_PLCP_SHORT_TIME 96
124
125#define PREN_PREAMBLE 24
126#define PREN_MM_EXT 12
127#define PREN_PREAMBLE_EXT 4
128
129#define DOT11_MAC_HDR_LEN 24
130#define DOT11_ACK_LEN 10
131#define DOT11_BA_LEN 4
132#define DOT11_OFDM_SIGNAL_EXTENSION 6
133#define DOT11_MIN_FRAG_LEN 256
134#define DOT11_RTS_LEN 16
135#define DOT11_CTS_LEN 10
136#define DOT11_BA_BITMAP_LEN 128
137#define DOT11_MIN_BEACON_PERIOD 1
138#define DOT11_MAX_BEACON_PERIOD 0xFFFF
139#define DOT11_MAXNUMFRAGS 16
140#define DOT11_MAX_FRAG_LEN 2346
141
142#define BPHY_PLCP_TIME 192
143#define RIFS_11N_TIME 2
144
145#define WME_VER 1
146#define WME_SUBTYPE_PARAM_IE 1
147#define WME_TYPE 2
148#define WME_OUI "\x00\x50\xf2"
149
150#define AC_BE 0
151#define AC_BK 1
152#define AC_VI 2
153#define AC_VO 3
154
155#define BCN_TMPL_LEN 512 /* length of the BCN template area */
156
157/* brcms_bss_info flag bit values */
158#define BRCMS_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */
159
160/* Flags used in brcms_c_txq_info.stopped */
161/* per prio flow control bits */
162#define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF
163/* stop txq enqueue for packet drain */
164#define TXQ_STOP_FOR_PKT_DRAIN 0x00000100
165/* stop txq enqueue for ampdu flow control */
166#define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200
167
168#define BRCMS_HWRXOFF 38 /* chip rx buffer offset */
169
170/* Find basic rate for a given rate */
171static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec)
172{
173 if (is_mcs_rate(rspec))
174 return wlc->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK]
175 .leg_ofdm];
176 return wlc->band->basic_rate[rspec & RSPEC_RATE_MASK];
177}
178
179static u16 frametype(u32 rspec, u8 mimoframe)
180{
181 if (is_mcs_rate(rspec))
182 return mimoframe;
183 return is_cck_rate(rspec) ? FT_CCK : FT_OFDM;
184}
185
186/* rfdisable delay timer 500 ms, runs of ALP clock */
187#define RFDISABLE_DEFAULT 10000000
188
189#define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */
190
191/* precedences numbers for wlc queues. These are twice as may levels as
192 * 802.1D priorities.
193 * Odd numbers are used for HI priority traffic at same precedence levels
194 * These constants are used ONLY by wlc_prio2prec_map. Do not use them
195 * elsewhere.
196 */
197#define _BRCMS_PREC_NONE 0 /* None = - */
198#define _BRCMS_PREC_BK 2 /* BK - Background */
199#define _BRCMS_PREC_BE 4 /* BE - Best-effort */
200#define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */
201#define _BRCMS_PREC_CL 8 /* CL - Controlled Load */
202#define _BRCMS_PREC_VI 10 /* Vi - Video */
203#define _BRCMS_PREC_VO 12 /* Vo - Voice */
204#define _BRCMS_PREC_NC 14 /* NC - Network Control */
205
206/* The BSS is generating beacons in HW */
207#define BRCMS_BSSCFG_HW_BCN 0x20
208
209#define SYNTHPU_DLY_APHY_US 3700 /* a phy synthpu_dly time in us */
210#define SYNTHPU_DLY_BPHY_US 1050 /* b/g phy synthpu_dly time in us */
211#define SYNTHPU_DLY_NPHY_US 2048 /* n phy REV3 synthpu_dly time in us */
212#define SYNTHPU_DLY_LPPHY_US 300 /* lpphy synthpu_dly time in us */
213
214#define SYNTHPU_DLY_PHY_US_QT 100 /* QT synthpu_dly time in us */
215
216#define ANTCNT 10 /* vanilla M_MAX_ANTCNT value */
217
218/* Per-AC retry limit register definitions; uses defs.h bitfield macros */
219#define EDCF_SHORT_S 0
220#define EDCF_SFB_S 4
221#define EDCF_LONG_S 8
222#define EDCF_LFB_S 12
223#define EDCF_SHORT_M BITFIELD_MASK(4)
224#define EDCF_SFB_M BITFIELD_MASK(4)
225#define EDCF_LONG_M BITFIELD_MASK(4)
226#define EDCF_LFB_M BITFIELD_MASK(4)
227
228#define RETRY_SHORT_DEF 7 /* Default Short retry Limit */
229#define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */
230#define RETRY_LONG_DEF 4 /* Default Long retry count */
231#define RETRY_SHORT_FB 3 /* Short count for fallback rate */
232#define RETRY_LONG_FB 2 /* Long count for fallback rate */
233
234#define APHY_CWMIN 15
235#define PHY_CWMAX 1023
236
237#define EDCF_AIFSN_MIN 1
238
239#define FRAGNUM_MASK 0xF
240
241#define APHY_SLOT_TIME 9
242#define BPHY_SLOT_TIME 20
243
244#define WL_SPURAVOID_OFF 0
245#define WL_SPURAVOID_ON1 1
246#define WL_SPURAVOID_ON2 2
247
248/* invalid core flags, use the saved coreflags */
249#define BRCMS_USE_COREFLAGS 0xffffffff
250
251/* values for PLCPHdr_override */
252#define BRCMS_PLCP_AUTO -1
253#define BRCMS_PLCP_SHORT 0
254#define BRCMS_PLCP_LONG 1
255
256/* values for g_protection_override and n_protection_override */
257#define BRCMS_PROTECTION_AUTO -1
258#define BRCMS_PROTECTION_OFF 0
259#define BRCMS_PROTECTION_ON 1
260#define BRCMS_PROTECTION_MMHDR_ONLY 2
261#define BRCMS_PROTECTION_CTS_ONLY 3
262
263/* values for g_protection_control and n_protection_control */
264#define BRCMS_PROTECTION_CTL_OFF 0
265#define BRCMS_PROTECTION_CTL_LOCAL 1
266#define BRCMS_PROTECTION_CTL_OVERLAP 2
267
268/* values for n_protection */
269#define BRCMS_N_PROTECTION_OFF 0
270#define BRCMS_N_PROTECTION_OPTIONAL 1
271#define BRCMS_N_PROTECTION_20IN40 2
272#define BRCMS_N_PROTECTION_MIXEDMODE 3
273
274/* values for band specific 40MHz capabilities */
275#define BRCMS_N_BW_20ALL 0
276#define BRCMS_N_BW_40ALL 1
277#define BRCMS_N_BW_20IN2G_40IN5G 2
278
279/* bitflags for SGI support (sgi_rx iovar) */
280#define BRCMS_N_SGI_20 0x01
281#define BRCMS_N_SGI_40 0x02
282
283/* defines used by the nrate iovar */
284/* MSC in use,indicates b0-6 holds an mcs */
285#define NRATE_MCS_INUSE 0x00000080
286/* rate/mcs value */
287#define NRATE_RATE_MASK 0x0000007f
288/* stf mode mask: siso, cdd, stbc, sdm */
289#define NRATE_STF_MASK 0x0000ff00
290/* stf mode shift */
291#define NRATE_STF_SHIFT 8
292/* bit indicates override both rate & mode */
293#define NRATE_OVERRIDE 0x80000000
294/* bit indicate to override mcs only */
295#define NRATE_OVERRIDE_MCS_ONLY 0x40000000
296#define NRATE_SGI_MASK 0x00800000 /* sgi mode */
297#define NRATE_SGI_SHIFT 23 /* sgi mode */
298#define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */
299#define NRATE_LDPC_SHIFT 22 /* ldpc shift */
300
301#define NRATE_STF_SISO 0 /* stf mode SISO */
302#define NRATE_STF_CDD 1 /* stf mode CDD */
303#define NRATE_STF_STBC 2 /* stf mode STBC */
304#define NRATE_STF_SDM 3 /* stf mode SDM */
305
306#define MAX_DMA_SEGS 4
307
308/* Max # of entries in Tx FIFO based on 4kb page size */
309#define NTXD 256
310/* Max # of entries in Rx FIFO based on 4kb page size */
311#define NRXD 256
312
313/* try to keep this # rbufs posted to the chip */
314#define NRXBUFPOST 32
315
316/* data msg txq hiwat mark */
317#define BRCMS_DATAHIWAT 50
318
319/* bounded rx loops */
320#define RXBND 8 /* max # frames to process in brcms_c_recv() */
321#define TXSBND 8 /* max # tx status to process in wlc_txstatus() */
322
323/*
324 * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
325 */
326#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1)
327
328/* brcmu_format_flags() bit description structure */
329struct brcms_c_bit_desc {
330 u32 bit;
331 const char *name;
332};
333
334/*
335 * The following table lists the buffer memory allocated to xmt fifos in HW.
336 * the size is in units of 256bytes(one block), total size is HW dependent
337 * ucode has default fifo partition, sw can overwrite if necessary
338 *
339 * This is documented in twiki under the topic UcodeTxFifo. Please ensure
340 * the twiki is updated before making changes.
341 */
342
343/* Starting corerev for the fifo size table */
344#define XMTFIFOTBL_STARTREV 20
345
346struct d11init {
347 __le16 addr;
348 __le16 size;
349 __le32 value;
350};
351
352struct edcf_acparam {
353 u8 ACI;
354 u8 ECW;
355 u16 TXOP;
356} __packed;
357
358const u8 prio2fifo[NUMPRIO] = {
359 TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */
360 TX_AC_BK_FIFO, /* 1 BK AC_BK Background */
361 TX_AC_BK_FIFO, /* 2 -- AC_BK Background */
362 TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */
363 TX_AC_VI_FIFO, /* 4 CL AC_VI Video */
364 TX_AC_VI_FIFO, /* 5 VI AC_VI Video */
365 TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */
366 TX_AC_VO_FIFO /* 7 NC AC_VO Voice */
367};
368
369/* debug/trace */
370uint brcm_msg_level =
371#if defined(BCMDBG)
372 LOG_ERROR_VAL;
373#else
374 0;
375#endif /* BCMDBG */
376
377/* TX FIFO number to WME/802.1E Access Category */
378static const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE };
379
380/* WME/802.1E Access Category to TX FIFO number */
381static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 };
382
383/* 802.1D Priority to precedence queue mapping */
384const u8 wlc_prio2prec_map[] = {
385 _BRCMS_PREC_BE, /* 0 BE - Best-effort */
386 _BRCMS_PREC_BK, /* 1 BK - Background */
387 _BRCMS_PREC_NONE, /* 2 None = - */
388 _BRCMS_PREC_EE, /* 3 EE - Excellent-effort */
389 _BRCMS_PREC_CL, /* 4 CL - Controlled Load */
390 _BRCMS_PREC_VI, /* 5 Vi - Video */
391 _BRCMS_PREC_VO, /* 6 Vo - Voice */
392 _BRCMS_PREC_NC, /* 7 NC - Network Control */
393};
394
395static const u16 xmtfifo_sz[][NFIFO] = {
396 /* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */
397 {20, 192, 192, 21, 17, 5},
398 /* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */
399 {9, 58, 22, 14, 14, 5},
400 /* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */
401 {20, 192, 192, 21, 17, 5},
402 /* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */
403 {20, 192, 192, 21, 17, 5},
404 /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */
405 {9, 58, 22, 14, 14, 5},
406};
407
408static const u8 acbitmap2maxprio[] = {
409 PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK,
410 PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI,
411 PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO,
412 PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO
413};
414
415#ifdef BCMDBG
416static const char * const fifo_names[] = {
417 "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
418#else
419static const char fifo_names[6][0];
420#endif
421
422#ifdef BCMDBG
423/* pointer to most recently allocated wl/wlc */
424static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
425#endif
426
427/* currently the best mechanism for determining SIFS is the band in use */
428static u16 get_sifs(struct brcms_band *band)
429{
430 return band->bandtype == BRCM_BAND_5G ? APHY_SIFS_TIME :
431 BPHY_SIFS_TIME;
432}
433
434/*
435 * Detect Card removed.
436 * Even checking an sbconfig register read will not false trigger when the core
437 * is in reset it breaks CF address mechanism. Accessing gphy phyversion will
438 * cause SB error if aphy is in reset on 4306B0-DB. Need a simple accessible
439 * reg with fixed 0/1 pattern (some platforms return all 0).
440 * If clocks are present, call the sb routine which will figure out if the
441 * device is removed.
442 */
443static bool brcms_deviceremoved(struct brcms_c_info *wlc)
444{
445 if (!wlc->hw->clk)
446 return ai_deviceremoved(wlc->hw->sih);
447 return (R_REG(&wlc->hw->regs->maccontrol) &
448 (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN;
449}
450
451/* sum the individual fifo tx pending packet counts */
452static s16 brcms_txpktpendtot(struct brcms_c_info *wlc)
453{
454 return wlc->core->txpktpend[0] + wlc->core->txpktpend[1] +
455 wlc->core->txpktpend[2] + wlc->core->txpktpend[3];
456}
457
458static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc)
459{
460 return wlc->pub->_nbands > 1 && !wlc->bandlocked;
461}
462
463static int brcms_chspec_bw(u16 chanspec)
464{
465 if (CHSPEC_IS40(chanspec))
466 return BRCMS_40_MHZ;
467 if (CHSPEC_IS20(chanspec))
468 return BRCMS_20_MHZ;
469
470 return BRCMS_10_MHZ;
471}
472
473/*
474 * return true if Minimum Power Consumption should
475 * be entered, false otherwise
476 */
477static bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc)
478{
479 return false;
480}
481
482static bool brcms_c_ismpc(struct brcms_c_info *wlc)
483{
484 return (wlc->mpc_delay_off == 0) && (brcms_c_is_non_delay_mpc(wlc));
485}
486
487static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg)
488{
489 if (cfg == NULL)
490 return;
491
492 kfree(cfg->current_bss);
493 kfree(cfg);
494}
495
496static void brcms_c_detach_mfree(struct brcms_c_info *wlc)
497{
498 if (wlc == NULL)
499 return;
500
501 brcms_c_bsscfg_mfree(wlc->bsscfg);
502 kfree(wlc->pub);
503 kfree(wlc->modulecb);
504 kfree(wlc->default_bss);
505 kfree(wlc->protection);
506 kfree(wlc->stf);
507 kfree(wlc->bandstate[0]);
508 kfree(wlc->corestate->macstat_snapshot);
509 kfree(wlc->corestate);
510 kfree(wlc->hw->bandstate[0]);
511 kfree(wlc->hw);
512
513 /* free the wlc */
514 kfree(wlc);
515 wlc = NULL;
516}
517
518static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit)
519{
520 struct brcms_bss_cfg *cfg;
521
522 cfg = kzalloc(sizeof(struct brcms_bss_cfg), GFP_ATOMIC);
523 if (cfg == NULL)
524 goto fail;
525
526 cfg->current_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
527 if (cfg->current_bss == NULL)
528 goto fail;
529
530 return cfg;
531
532 fail:
533 brcms_c_bsscfg_mfree(cfg);
534 return NULL;
535}
536
537static struct brcms_c_info *
538brcms_c_attach_malloc(uint unit, uint *err, uint devid)
539{
540 struct brcms_c_info *wlc;
541
542 wlc = kzalloc(sizeof(struct brcms_c_info), GFP_ATOMIC);
543 if (wlc == NULL) {
544 *err = 1002;
545 goto fail;
546 }
547
548 /* allocate struct brcms_c_pub state structure */
549 wlc->pub = kzalloc(sizeof(struct brcms_pub), GFP_ATOMIC);
550 if (wlc->pub == NULL) {
551 *err = 1003;
552 goto fail;
553 }
554 wlc->pub->wlc = wlc;
555
556 /* allocate struct brcms_hardware state structure */
557
558 wlc->hw = kzalloc(sizeof(struct brcms_hardware), GFP_ATOMIC);
559 if (wlc->hw == NULL) {
560 *err = 1005;
561 goto fail;
562 }
563 wlc->hw->wlc = wlc;
564
565 wlc->hw->bandstate[0] =
566 kzalloc(sizeof(struct brcms_hw_band) * MAXBANDS, GFP_ATOMIC);
567 if (wlc->hw->bandstate[0] == NULL) {
568 *err = 1006;
569 goto fail;
570 } else {
571 int i;
572
573 for (i = 1; i < MAXBANDS; i++)
574 wlc->hw->bandstate[i] = (struct brcms_hw_band *)
575 ((unsigned long)wlc->hw->bandstate[0] +
576 (sizeof(struct brcms_hw_band) * i));
577 }
578
579 wlc->modulecb =
580 kzalloc(sizeof(struct modulecb) * BRCMS_MAXMODULES, GFP_ATOMIC);
581 if (wlc->modulecb == NULL) {
582 *err = 1009;
583 goto fail;
584 }
585
586 wlc->default_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
587 if (wlc->default_bss == NULL) {
588 *err = 1010;
589 goto fail;
590 }
591
592 wlc->bsscfg = brcms_c_bsscfg_malloc(unit);
593 if (wlc->bsscfg == NULL) {
594 *err = 1011;
595 goto fail;
596 }
597
598 wlc->protection = kzalloc(sizeof(struct brcms_protection),
599 GFP_ATOMIC);
600 if (wlc->protection == NULL) {
601 *err = 1016;
602 goto fail;
603 }
604
605 wlc->stf = kzalloc(sizeof(struct brcms_stf), GFP_ATOMIC);
606 if (wlc->stf == NULL) {
607 *err = 1017;
608 goto fail;
609 }
610
611 wlc->bandstate[0] =
612 kzalloc(sizeof(struct brcms_band)*MAXBANDS, GFP_ATOMIC);
613 if (wlc->bandstate[0] == NULL) {
614 *err = 1025;
615 goto fail;
616 } else {
617 int i;
618
619 for (i = 1; i < MAXBANDS; i++)
620 wlc->bandstate[i] = (struct brcms_band *)
621 ((unsigned long)wlc->bandstate[0]
622 + (sizeof(struct brcms_band)*i));
623 }
624
625 wlc->corestate = kzalloc(sizeof(struct brcms_core), GFP_ATOMIC);
626 if (wlc->corestate == NULL) {
627 *err = 1026;
628 goto fail;
629 }
630
631 wlc->corestate->macstat_snapshot =
632 kzalloc(sizeof(struct macstat), GFP_ATOMIC);
633 if (wlc->corestate->macstat_snapshot == NULL) {
634 *err = 1027;
635 goto fail;
636 }
637
638 return wlc;
639
640 fail:
641 brcms_c_detach_mfree(wlc);
642 return NULL;
643}
644
645/*
646 * Update the slot timing for standard 11b/g (20us slots)
647 * or shortslot 11g (9us slots)
648 * The PSM needs to be suspended for this call.
649 */
650static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw,
651 bool shortslot)
652{
653 struct d11regs __iomem *regs;
654
655 regs = wlc_hw->regs;
656
657 if (shortslot) {
658 /* 11g short slot: 11a timing */
659 W_REG(&regs->ifs_slot, 0x0207); /* APHY_SLOT_TIME */
660 brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME);
661 } else {
662 /* 11g long slot: 11b timing */
663 W_REG(&regs->ifs_slot, 0x0212); /* BPHY_SLOT_TIME */
664 brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME);
665 }
666}
667
668/*
669 * calculate frame duration of a given rate and length, return
670 * time in usec unit
671 */
672uint
673brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec,
674 u8 preamble_type, uint mac_len)
675{
676 uint nsyms, dur = 0, Ndps, kNdps;
677 uint rate = rspec2rate(ratespec);
678
679 if (rate == 0) {
680 wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n",
681 wlc->pub->unit);
682 rate = BRCM_RATE_1M;
683 }
684
685 BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
686 wlc->pub->unit, ratespec, preamble_type, mac_len);
687
688 if (is_mcs_rate(ratespec)) {
689 uint mcs = ratespec & RSPEC_RATE_MASK;
690 int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
691
692 dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
693 if (preamble_type == BRCMS_MM_PREAMBLE)
694 dur += PREN_MM_EXT;
695 /* 1000Ndbps = kbps * 4 */
696 kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
697 rspec_issgi(ratespec)) * 4;
698
699 if (rspec_stc(ratespec) == 0)
700 nsyms =
701 CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
702 APHY_TAIL_NBITS) * 1000, kNdps);
703 else
704 /* STBC needs to have even number of symbols */
705 nsyms =
706 2 *
707 CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
708 APHY_TAIL_NBITS) * 1000, 2 * kNdps);
709
710 dur += APHY_SYMBOL_TIME * nsyms;
711 if (wlc->band->bandtype == BRCM_BAND_2G)
712 dur += DOT11_OFDM_SIGNAL_EXTENSION;
713 } else if (is_ofdm_rate(rate)) {
714 dur = APHY_PREAMBLE_TIME;
715 dur += APHY_SIGNAL_TIME;
716 /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
717 Ndps = rate * 2;
718 /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
719 nsyms =
720 CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS),
721 Ndps);
722 dur += APHY_SYMBOL_TIME * nsyms;
723 if (wlc->band->bandtype == BRCM_BAND_2G)
724 dur += DOT11_OFDM_SIGNAL_EXTENSION;
725 } else {
726 /*
727 * calc # bits * 2 so factor of 2 in rate (1/2 mbps)
728 * will divide out
729 */
730 mac_len = mac_len * 8 * 2;
731 /* calc ceiling of bits/rate = microseconds of air time */
732 dur = (mac_len + rate - 1) / rate;
733 if (preamble_type & BRCMS_SHORT_PREAMBLE)
734 dur += BPHY_PLCP_SHORT_TIME;
735 else
736 dur += BPHY_PLCP_TIME;
737 }
738 return dur;
739}
740
741static void brcms_c_write_inits(struct brcms_hardware *wlc_hw,
742 const struct d11init *inits)
743{
744 int i;
745 u8 __iomem *base;
746 u8 __iomem *addr;
747 u16 size;
748 u32 value;
749
750 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
751
752 base = (u8 __iomem *)wlc_hw->regs;
753
754 for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) {
755 size = le16_to_cpu(inits[i].size);
756 addr = base + le16_to_cpu(inits[i].addr);
757 value = le32_to_cpu(inits[i].value);
758 if (size == 2)
759 W_REG((u16 __iomem *)addr, value);
760 else if (size == 4)
761 W_REG((u32 __iomem *)addr, value);
762 else
763 break;
764 }
765}
766
767static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs)
768{
769 u8 idx;
770 u16 addr[] = {
771 M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
772 M_HOST_FLAGS5
773 };
774
775 for (idx = 0; idx < MHFMAX; idx++)
776 brcms_b_write_shm(wlc_hw, addr[idx], mhfs[idx]);
777}
778
779static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw)
780{
781 struct wiphy *wiphy = wlc_hw->wlc->wiphy;
782 struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
783
784 /* init microcode host flags */
785 brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs);
786
787 /* do band-specific ucode IHR, SHM, and SCR inits */
788 if (D11REV_IS(wlc_hw->corerev, 23)) {
789 if (BRCMS_ISNPHY(wlc_hw->band))
790 brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16);
791 else
792 wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
793 " %d\n", __func__, wlc_hw->unit,
794 wlc_hw->corerev);
795 } else {
796 if (D11REV_IS(wlc_hw->corerev, 24)) {
797 if (BRCMS_ISLCNPHY(wlc_hw->band))
798 brcms_c_write_inits(wlc_hw,
799 ucode->d11lcn0bsinitvals24);
800 else
801 wiphy_err(wiphy, "%s: wl%d: unsupported phy in"
802 " core rev %d\n", __func__,
803 wlc_hw->unit, wlc_hw->corerev);
804 } else {
805 wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
806 __func__, wlc_hw->unit, wlc_hw->corerev);
807 }
808 }
809}
810
811static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk)
812{
813 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk);
814
815 wlc_hw->phyclk = clk;
816
817 if (OFF == clk) { /* clear gmode bit, put phy into reset */
818
819 ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE),
820 (SICF_PRST | SICF_FGC));
821 udelay(1);
822 ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST);
823 udelay(1);
824
825 } else { /* take phy out of reset */
826
827 ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC);
828 udelay(1);
829 ai_core_cflags(wlc_hw->sih, (SICF_FGC), 0);
830 udelay(1);
831
832 }
833}
834
835/* low-level band switch utility routine */
836static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit)
837{
838 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
839 bandunit);
840
841 wlc_hw->band = wlc_hw->bandstate[bandunit];
842
843 /*
844 * BMAC_NOTE:
845 * until we eliminate need for wlc->band refs in low level code
846 */
847 wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit];
848
849 /* set gmode core flag */
850 if (wlc_hw->sbclk && !wlc_hw->noreset)
851 ai_core_cflags(wlc_hw->sih, SICF_GMODE,
852 ((bandunit == 0) ? SICF_GMODE : 0));
853}
854
855/* switch to new band but leave it inactive */
856static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit)
857{
858 struct brcms_hardware *wlc_hw = wlc->hw;
859 u32 macintmask;
860
861 BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
862
863 WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0);
864
865 /* disable interrupts */
866 macintmask = brcms_intrsoff(wlc->wl);
867
868 /* radio off */
869 wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
870
871 brcms_b_core_phy_clk(wlc_hw, OFF);
872
873 brcms_c_setxband(wlc_hw, bandunit);
874
875 return macintmask;
876}
877
878/* process an individual struct tx_status */
879static bool
880brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
881{
882 struct sk_buff *p;
883 uint queue;
884 struct d11txh *txh;
885 struct scb *scb = NULL;
886 bool free_pdu;
887 int tx_rts, tx_frame_count, tx_rts_count;
888 uint totlen, supr_status;
889 bool lastframe;
890 struct ieee80211_hdr *h;
891 u16 mcl;
892 struct ieee80211_tx_info *tx_info;
893 struct ieee80211_tx_rate *txrate;
894 int i;
895
896 /* discard intermediate indications for ucode with one legitimate case:
897 * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange,
898 * but the subsequent tx of DATA failed. so it will start rts/cts
899 * from the beginning (resetting the rts transmission count)
900 */
901 if (!(txs->status & TX_STATUS_AMPDU)
902 && (txs->status & TX_STATUS_INTERMEDIATE)) {
903 wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n",
904 __func__);
905 return false;
906 }
907
908 queue = txs->frameid & TXFID_QUEUE_MASK;
909 if (queue >= NFIFO) {
910 p = NULL;
911 goto fatal;
912 }
913
914 p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
915 if (p == NULL)
916 goto fatal;
917
918 txh = (struct d11txh *) (p->data);
919 mcl = le16_to_cpu(txh->MacTxControlLow);
920
921 if (txs->phyerr) {
922 if (brcm_msg_level & LOG_ERROR_VAL) {
923 wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n",
924 txs->phyerr, txh->MainRates);
925 brcms_c_print_txdesc(txh);
926 }
927 brcms_c_print_txstatus(txs);
928 }
929
930 if (txs->frameid != le16_to_cpu(txh->TxFrameID))
931 goto fatal;
932 tx_info = IEEE80211_SKB_CB(p);
933 h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
934
935 if (tx_info->control.sta)
936 scb = &wlc->pri_scb;
937
938 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
939 brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
940 return false;
941 }
942
943 supr_status = txs->status & TX_STATUS_SUPR_MASK;
944 if (supr_status == TX_STATUS_SUPR_BADCH)
945 BCMMSG(wlc->wiphy,
946 "%s: Pkt tx suppressed, possibly channel %d\n",
947 __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec));
948
949 tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS;
950 tx_frame_count =
951 (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT;
952 tx_rts_count =
953 (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT;
954
955 lastframe = !ieee80211_has_morefrags(h->frame_control);
956
957 if (!lastframe) {
958 wiphy_err(wlc->wiphy, "Not last frame!\n");
959 } else {
960 /*
961 * Set information to be consumed by Minstrel ht.
962 *
963 * The "fallback limit" is the number of tx attempts a given
964 * MPDU is sent at the "primary" rate. Tx attempts beyond that
965 * limit are sent at the "secondary" rate.
966 * A 'short frame' does not exceed RTS treshold.
967 */
968 u16 sfbl, /* Short Frame Rate Fallback Limit */
969 lfbl, /* Long Frame Rate Fallback Limit */
970 fbl;
971
972 if (queue < AC_COUNT) {
973 sfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]],
974 EDCF_SFB);
975 lfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]],
976 EDCF_LFB);
977 } else {
978 sfbl = wlc->SFBL;
979 lfbl = wlc->LFBL;
980 }
981
982 txrate = tx_info->status.rates;
983 if (txrate[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
984 fbl = lfbl;
985 else
986 fbl = sfbl;
987
988 ieee80211_tx_info_clear_status(tx_info);
989
990 if ((tx_frame_count > fbl) && (txrate[1].idx >= 0)) {
991 /*
992 * rate selection requested a fallback rate
993 * and we used it
994 */
995 txrate[0].count = fbl;
996 txrate[1].count = tx_frame_count - fbl;
997 } else {
998 /*
999 * rate selection did not request fallback rate, or
1000 * we didn't need it
1001 */
1002 txrate[0].count = tx_frame_count;
1003 /*
1004 * rc80211_minstrel.c:minstrel_tx_status() expects
1005 * unused rates to be marked with idx = -1
1006 */
1007 txrate[1].idx = -1;
1008 txrate[1].count = 0;
1009 }
1010
1011 /* clear the rest of the rates */
1012 for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
1013 txrate[i].idx = -1;
1014 txrate[i].count = 0;
1015 }
1016
1017 if (txs->status & TX_STATUS_ACK_RCV)
1018 tx_info->flags |= IEEE80211_TX_STAT_ACK;
1019 }
1020
1021 totlen = brcmu_pkttotlen(p);
1022 free_pdu = true;
1023
1024 brcms_c_txfifo_complete(wlc, queue, 1);
1025
1026 if (lastframe) {
1027 p->next = NULL;
1028 p->prev = NULL;
1029 /* remove PLCP & Broadcom tx descriptor header */
1030 skb_pull(p, D11_PHY_HDR_LEN);
1031 skb_pull(p, D11_TXH_LEN);
1032 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
1033 } else {
1034 wiphy_err(wlc->wiphy, "%s: Not last frame => not calling "
1035 "tx_status\n", __func__);
1036 }
1037
1038 return false;
1039
1040 fatal:
1041 if (p)
1042 brcmu_pkt_buf_free_skb(p);
1043
1044 return true;
1045
1046}
1047
1048/* process tx completion events in BMAC
1049 * Return true if more tx status need to be processed. false otherwise.
1050 */
1051static bool
1052brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
1053{
1054 bool morepending = false;
1055 struct brcms_c_info *wlc = wlc_hw->wlc;
1056 struct d11regs __iomem *regs;
1057 struct tx_status txstatus, *txs;
1058 u32 s1, s2;
1059 uint n = 0;
1060 /*
1061 * Param 'max_tx_num' indicates max. # tx status to process before
1062 * break out.
1063 */
1064 uint max_tx_num = bound ? TXSBND : -1;
1065
1066 BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
1067
1068 txs = &txstatus;
1069 regs = wlc_hw->regs;
1070 *fatal = false;
1071 while (!(*fatal)
1072 && (s1 = R_REG(&regs->frmtxstatus)) & TXS_V) {
1073
1074 if (s1 == 0xffffffff) {
1075 wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n",
1076 wlc_hw->unit, __func__);
1077 return morepending;
1078 }
1079
1080 s2 = R_REG(&regs->frmtxstatus2);
1081
1082 txs->status = s1 & TXS_STATUS_MASK;
1083 txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
1084 txs->sequence = s2 & TXS_SEQ_MASK;
1085 txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT;
1086 txs->lasttxtime = 0;
1087
1088 *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs);
1089
1090 /* !give others some time to run! */
1091 if (++n >= max_tx_num)
1092 break;
1093 }
1094
1095 if (*fatal)
1096 return 0;
1097
1098 if (n >= max_tx_num)
1099 morepending = true;
1100
1101 if (!pktq_empty(&wlc->pkt_queue->q))
1102 brcms_c_send_q(wlc);
1103
1104 return morepending;
1105}
1106
1107static void brcms_c_tbtt(struct brcms_c_info *wlc)
1108{
1109 if (!wlc->bsscfg->BSS)
1110 /*
1111 * DirFrmQ is now valid...defer setting until end
1112 * of ATIM window
1113 */
1114 wlc->qvalid |= MCMD_DIRFRMQVAL;
1115}
1116
1117/* set initial host flags value */
1118static void
1119brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init)
1120{
1121 struct brcms_hardware *wlc_hw = wlc->hw;
1122
1123 memset(mhfs, 0, MHFMAX * sizeof(u16));
1124
1125 mhfs[MHF2] |= mhf2_init;
1126
1127 /* prohibit use of slowclock on multifunction boards */
1128 if (wlc_hw->boardflags & BFL_NOPLLDOWN)
1129 mhfs[MHF1] |= MHF1_FORCEFASTCLK;
1130
1131 if (BRCMS_ISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) {
1132 mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR;
1133 mhfs[MHF1] |= MHF1_IQSWAP_WAR;
1134 }
1135}
1136
1137static struct dma64regs __iomem *
1138dmareg(struct brcms_hardware *hw, uint direction, uint fifonum)
1139{
1140 if (direction == DMA_TX)
1141 return &(hw->regs->fifo64regs[fifonum].dmaxmt);
1142 return &(hw->regs->fifo64regs[fifonum].dmarcv);
1143}
1144
1145static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
1146{
1147 uint i;
1148 char name[8];
1149 /*
1150 * ucode host flag 2 needed for pio mode, independent of band and fifo
1151 */
1152 u16 pio_mhf2 = 0;
1153 struct brcms_hardware *wlc_hw = wlc->hw;
1154 uint unit = wlc_hw->unit;
1155 struct wiphy *wiphy = wlc->wiphy;
1156
1157 /* name and offsets for dma_attach */
1158 snprintf(name, sizeof(name), "wl%d", unit);
1159
1160 if (wlc_hw->di[0] == NULL) { /* Init FIFOs */
1161 int dma_attach_err = 0;
1162
1163 /*
1164 * FIFO 0
1165 * TX: TX_AC_BK_FIFO (TX AC Background data packets)
1166 * RX: RX_FIFO (RX data packets)
1167 */
1168 wlc_hw->di[0] = dma_attach(name, wlc_hw->sih,
1169 (wme ? dmareg(wlc_hw, DMA_TX, 0) :
1170 NULL), dmareg(wlc_hw, DMA_RX, 0),
1171 (wme ? NTXD : 0), NRXD,
1172 RXBUFSZ, -1, NRXBUFPOST,
1173 BRCMS_HWRXOFF, &brcm_msg_level);
1174 dma_attach_err |= (NULL == wlc_hw->di[0]);
1175
1176 /*
1177 * FIFO 1
1178 * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets)
1179 * (legacy) TX_DATA_FIFO (TX data packets)
1180 * RX: UNUSED
1181 */
1182 wlc_hw->di[1] = dma_attach(name, wlc_hw->sih,
1183 dmareg(wlc_hw, DMA_TX, 1), NULL,
1184 NTXD, 0, 0, -1, 0, 0,
1185 &brcm_msg_level);
1186 dma_attach_err |= (NULL == wlc_hw->di[1]);
1187
1188 /*
1189 * FIFO 2
1190 * TX: TX_AC_VI_FIFO (TX AC Video data packets)
1191 * RX: UNUSED
1192 */
1193 wlc_hw->di[2] = dma_attach(name, wlc_hw->sih,
1194 dmareg(wlc_hw, DMA_TX, 2), NULL,
1195 NTXD, 0, 0, -1, 0, 0,
1196 &brcm_msg_level);
1197 dma_attach_err |= (NULL == wlc_hw->di[2]);
1198 /*
1199 * FIFO 3
1200 * TX: TX_AC_VO_FIFO (TX AC Voice data packets)
1201 * (legacy) TX_CTL_FIFO (TX control & mgmt packets)
1202 */
1203 wlc_hw->di[3] = dma_attach(name, wlc_hw->sih,
1204 dmareg(wlc_hw, DMA_TX, 3),
1205 NULL, NTXD, 0, 0, -1,
1206 0, 0, &brcm_msg_level);
1207 dma_attach_err |= (NULL == wlc_hw->di[3]);
1208/* Cleaner to leave this as if with AP defined */
1209
1210 if (dma_attach_err) {
1211 wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed"
1212 "\n", unit);
1213 return false;
1214 }
1215
1216 /* get pointer to dma engine tx flow control variable */
1217 for (i = 0; i < NFIFO; i++)
1218 if (wlc_hw->di[i])
1219 wlc_hw->txavail[i] =
1220 (uint *) dma_getvar(wlc_hw->di[i],
1221 "&txavail");
1222 }
1223
1224 /* initial ucode host flags */
1225 brcms_c_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2);
1226
1227 return true;
1228}
1229
1230static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw)
1231{
1232 uint j;
1233
1234 for (j = 0; j < NFIFO; j++) {
1235 if (wlc_hw->di[j]) {
1236 dma_detach(wlc_hw->di[j]);
1237 wlc_hw->di[j] = NULL;
1238 }
1239 }
1240}
1241
1242/*
1243 * Initialize brcms_c_info default values ...
1244 * may get overrides later in this function
1245 * BMAC_NOTES, move low out and resolve the dangling ones
1246 */
1247static void brcms_b_info_init(struct brcms_hardware *wlc_hw)
1248{
1249 struct brcms_c_info *wlc = wlc_hw->wlc;
1250
1251 /* set default sw macintmask value */
1252 wlc->defmacintmask = DEF_MACINTMASK;
1253
1254 /* various 802.11g modes */
1255 wlc_hw->shortslot = false;
1256
1257 wlc_hw->SFBL = RETRY_SHORT_FB;
1258 wlc_hw->LFBL = RETRY_LONG_FB;
1259
1260 /* default mac retry limits */
1261 wlc_hw->SRL = RETRY_SHORT_DEF;
1262 wlc_hw->LRL = RETRY_LONG_DEF;
1263 wlc_hw->chanspec = ch20mhz_chspec(1);
1264}
1265
1266static void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw)
1267{
1268 /* delay before first read of ucode state */
1269 udelay(40);
1270
1271 /* wait until ucode is no longer asleep */
1272 SPINWAIT((brcms_b_read_shm(wlc_hw, M_UCODE_DBGST) ==
1273 DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly);
1274}
1275
1276/* control chip clock to save power, enable dynamic clock or force fast clock */
1277static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, uint mode)
1278{
1279 if (wlc_hw->sih->cccaps & CC_CAP_PMU) {
1280 /* new chips with PMU, CCS_FORCEHT will distribute the HT clock
1281 * on backplane, but mac core will still run on ALP(not HT) when
1282 * it enters powersave mode, which means the FCA bit may not be
1283 * set. Should wakeup mac if driver wants it to run on HT.
1284 */
1285
1286 if (wlc_hw->clk) {
1287 if (mode == CLK_FAST) {
1288 OR_REG(&wlc_hw->regs->clk_ctl_st,
1289 CCS_FORCEHT);
1290
1291 udelay(64);
1292
1293 SPINWAIT(((R_REG
1294 (&wlc_hw->regs->
1295 clk_ctl_st) & CCS_HTAVAIL) == 0),
1296 PMU_MAX_TRANSITION_DLY);
1297 WARN_ON(!(R_REG
1298 (&wlc_hw->regs->
1299 clk_ctl_st) & CCS_HTAVAIL));
1300 } else {
1301 if ((wlc_hw->sih->pmurev == 0) &&
1302 (R_REG
1303 (&wlc_hw->regs->
1304 clk_ctl_st) & (CCS_FORCEHT | CCS_HTAREQ)))
1305 SPINWAIT(((R_REG
1306 (&wlc_hw->regs->
1307 clk_ctl_st) & CCS_HTAVAIL)
1308 == 0),
1309 PMU_MAX_TRANSITION_DLY);
1310 AND_REG(&wlc_hw->regs->clk_ctl_st,
1311 ~CCS_FORCEHT);
1312 }
1313 }
1314 wlc_hw->forcefastclk = (mode == CLK_FAST);
1315 } else {
1316
1317 /* old chips w/o PMU, force HT through cc,
1318 * then use FCA to verify mac is running fast clock
1319 */
1320
1321 wlc_hw->forcefastclk = ai_clkctl_cc(wlc_hw->sih, mode);
1322
1323 /* check fast clock is available (if core is not in reset) */
1324 if (wlc_hw->forcefastclk && wlc_hw->clk)
1325 WARN_ON(!(ai_core_sflags(wlc_hw->sih, 0, 0) &
1326 SISF_FCLKA));
1327
1328 /*
1329 * keep the ucode wake bit on if forcefastclk is on since we
1330 * do not want ucode to put us back to slow clock when it dozes
1331 * for PM mode. Code below matches the wake override bit with
1332 * current forcefastclk state. Only setting bit in wake_override
1333 * instead of waking ucode immediately since old code had this
1334 * behavior. Older code set wlc->forcefastclk but only had the
1335 * wake happen if the wakup_ucode work (protected by an up
1336 * check) was executed just below.
1337 */
1338 if (wlc_hw->forcefastclk)
1339 mboolset(wlc_hw->wake_override,
1340 BRCMS_WAKE_OVERRIDE_FORCEFAST);
1341 else
1342 mboolclr(wlc_hw->wake_override,
1343 BRCMS_WAKE_OVERRIDE_FORCEFAST);
1344 }
1345}
1346
1347/* set or clear ucode host flag bits
1348 * it has an optimization for no-change write
1349 * it only writes through shared memory when the core has clock;
1350 * pre-CLK changes should use wlc_write_mhf to get around the optimization
1351 *
1352 *
1353 * bands values are: BRCM_BAND_AUTO <--- Current band only
1354 * BRCM_BAND_5G <--- 5G band only
1355 * BRCM_BAND_2G <--- 2G band only
1356 * BRCM_BAND_ALL <--- All bands
1357 */
1358void
1359brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val,
1360 int bands)
1361{
1362 u16 save;
1363 u16 addr[MHFMAX] = {
1364 M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
1365 M_HOST_FLAGS5
1366 };
1367 struct brcms_hw_band *band;
1368
1369 if ((val & ~mask) || idx >= MHFMAX)
1370 return; /* error condition */
1371
1372 switch (bands) {
1373 /* Current band only or all bands,
1374 * then set the band to current band
1375 */
1376 case BRCM_BAND_AUTO:
1377 case BRCM_BAND_ALL:
1378 band = wlc_hw->band;
1379 break;
1380 case BRCM_BAND_5G:
1381 band = wlc_hw->bandstate[BAND_5G_INDEX];
1382 break;
1383 case BRCM_BAND_2G:
1384 band = wlc_hw->bandstate[BAND_2G_INDEX];
1385 break;
1386 default:
1387 band = NULL; /* error condition */
1388 }
1389
1390 if (band) {
1391 save = band->mhfs[idx];
1392 band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val;
1393
1394 /* optimization: only write through if changed, and
1395 * changed band is the current band
1396 */
1397 if (wlc_hw->clk && (band->mhfs[idx] != save)
1398 && (band == wlc_hw->band))
1399 brcms_b_write_shm(wlc_hw, addr[idx],
1400 (u16) band->mhfs[idx]);
1401 }
1402
1403 if (bands == BRCM_BAND_ALL) {
1404 wlc_hw->bandstate[0]->mhfs[idx] =
1405 (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val;
1406 wlc_hw->bandstate[1]->mhfs[idx] =
1407 (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val;
1408 }
1409}
1410
1411/* set the maccontrol register to desired reset state and
1412 * initialize the sw cache of the register
1413 */
1414static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw)
1415{
1416 /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */
1417 wlc_hw->maccontrol = 0;
1418 wlc_hw->suspended_fifos = 0;
1419 wlc_hw->wake_override = 0;
1420 wlc_hw->mute_override = 0;
1421 brcms_b_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE);
1422}
1423
1424/*
1425 * write the software state of maccontrol and
1426 * overrides to the maccontrol register
1427 */
1428static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw)
1429{
1430 u32 maccontrol = wlc_hw->maccontrol;
1431
1432 /* OR in the wake bit if overridden */
1433 if (wlc_hw->wake_override)
1434 maccontrol |= MCTL_WAKE;
1435
1436 /* set AP and INFRA bits for mute if needed */
1437 if (wlc_hw->mute_override) {
1438 maccontrol &= ~(MCTL_AP);
1439 maccontrol |= MCTL_INFRA;
1440 }
1441
1442 W_REG(&wlc_hw->regs->maccontrol, maccontrol);
1443}
1444
1445/* set or clear maccontrol bits */
1446void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val)
1447{
1448 u32 maccontrol;
1449 u32 new_maccontrol;
1450
1451 if (val & ~mask)
1452 return; /* error condition */
1453 maccontrol = wlc_hw->maccontrol;
1454 new_maccontrol = (maccontrol & ~mask) | val;
1455
1456 /* if the new maccontrol value is the same as the old, nothing to do */
1457 if (new_maccontrol == maccontrol)
1458 return;
1459
1460 /* something changed, cache the new value */
1461 wlc_hw->maccontrol = new_maccontrol;
1462
1463 /* write the new values with overrides applied */
1464 brcms_c_mctrl_write(wlc_hw);
1465}
1466
1467void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
1468 u32 override_bit)
1469{
1470 if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) {
1471 mboolset(wlc_hw->wake_override, override_bit);
1472 return;
1473 }
1474
1475 mboolset(wlc_hw->wake_override, override_bit);
1476
1477 brcms_c_mctrl_write(wlc_hw);
1478 brcms_b_wait_for_wake(wlc_hw);
1479}
1480
1481void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
1482 u32 override_bit)
1483{
1484 mboolclr(wlc_hw->wake_override, override_bit);
1485
1486 if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE))
1487 return;
1488
1489 brcms_c_mctrl_write(wlc_hw);
1490}
1491
1492/* When driver needs ucode to stop beaconing, it has to make sure that
1493 * MCTL_AP is clear and MCTL_INFRA is set
1494 * Mode MCTL_AP MCTL_INFRA
1495 * AP 1 1
1496 * STA 0 1 <--- This will ensure no beacons
1497 * IBSS 0 0
1498 */
1499static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw)
1500{
1501 wlc_hw->mute_override = 1;
1502
1503 /* if maccontrol already has AP == 0 and INFRA == 1 without this
1504 * override, then there is no change to write
1505 */
1506 if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
1507 return;
1508
1509 brcms_c_mctrl_write(wlc_hw);
1510}
1511
1512/* Clear the override on AP and INFRA bits */
1513static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw)
1514{
1515 if (wlc_hw->mute_override == 0)
1516 return;
1517
1518 wlc_hw->mute_override = 0;
1519
1520 /* if maccontrol already has AP == 0 and INFRA == 1 without this
1521 * override, then there is no change to write
1522 */
1523 if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
1524 return;
1525
1526 brcms_c_mctrl_write(wlc_hw);
1527}
1528
1529/*
1530 * Write a MAC address to the given match reg offset in the RXE match engine.
1531 */
1532static void
1533brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset,
1534 const u8 *addr)
1535{
1536 struct d11regs __iomem *regs;
1537 u16 mac_l;
1538 u16 mac_m;
1539 u16 mac_h;
1540
1541 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n",
1542 wlc_hw->unit);
1543
1544 regs = wlc_hw->regs;
1545 mac_l = addr[0] | (addr[1] << 8);
1546 mac_m = addr[2] | (addr[3] << 8);
1547 mac_h = addr[4] | (addr[5] << 8);
1548
1549 /* enter the MAC addr into the RXE match registers */
1550 W_REG(&regs->rcm_ctl, RCM_INC_DATA | match_reg_offset);
1551 W_REG(&regs->rcm_mat_data, mac_l);
1552 W_REG(&regs->rcm_mat_data, mac_m);
1553 W_REG(&regs->rcm_mat_data, mac_h);
1554
1555}
1556
1557void
1558brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len,
1559 void *buf)
1560{
1561 struct d11regs __iomem *regs;
1562 u32 word;
1563 __le32 word_le;
1564 __be32 word_be;
1565 bool be_bit;
1566 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1567
1568 regs = wlc_hw->regs;
1569 W_REG(&regs->tplatewrptr, offset);
1570
1571 /* if MCTL_BIGEND bit set in mac control register,
1572 * the chip swaps data in fifo, as well as data in
1573 * template ram
1574 */
1575 be_bit = (R_REG(&regs->maccontrol) & MCTL_BIGEND) != 0;
1576
1577 while (len > 0) {
1578 memcpy(&word, buf, sizeof(u32));
1579
1580 if (be_bit) {
1581 word_be = cpu_to_be32(word);
1582 word = *(u32 *)&word_be;
1583 } else {
1584 word_le = cpu_to_le32(word);
1585 word = *(u32 *)&word_le;
1586 }
1587
1588 W_REG(&regs->tplatewrdata, word);
1589
1590 buf = (u8 *) buf + sizeof(u32);
1591 len -= sizeof(u32);
1592 }
1593}
1594
1595static void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin)
1596{
1597 wlc_hw->band->CWmin = newmin;
1598
1599 W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN);
1600 (void)R_REG(&wlc_hw->regs->objaddr);
1601 W_REG(&wlc_hw->regs->objdata, newmin);
1602}
1603
1604static void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax)
1605{
1606 wlc_hw->band->CWmax = newmax;
1607
1608 W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX);
1609 (void)R_REG(&wlc_hw->regs->objaddr);
1610 W_REG(&wlc_hw->regs->objdata, newmax);
1611}
1612
1613void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw)
1614{
1615 bool fastclk;
1616
1617 /* request FAST clock if not on */
1618 fastclk = wlc_hw->forcefastclk;
1619 if (!fastclk)
1620 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
1621
1622 wlc_phy_bw_state_set(wlc_hw->band->pi, bw);
1623
1624 brcms_b_phy_reset(wlc_hw);
1625 wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi));
1626
1627 /* restore the clk */
1628 if (!fastclk)
1629 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
1630}
1631
1632static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw)
1633{
1634 u16 v;
1635 struct brcms_c_info *wlc = wlc_hw->wlc;
1636 /* update SYNTHPU_DLY */
1637
1638 if (BRCMS_ISLCNPHY(wlc->band))
1639 v = SYNTHPU_DLY_LPPHY_US;
1640 else if (BRCMS_ISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3)))
1641 v = SYNTHPU_DLY_NPHY_US;
1642 else
1643 v = SYNTHPU_DLY_BPHY_US;
1644
1645 brcms_b_write_shm(wlc_hw, M_SYNTHPU_DLY, v);
1646}
1647
1648static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw)
1649{
1650 u16 phyctl;
1651 u16 phytxant = wlc_hw->bmac_phytxant;
1652 u16 mask = PHY_TXC_ANT_MASK;
1653
1654 /* set the Probe Response frame phy control word */
1655 phyctl = brcms_b_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS);
1656 phyctl = (phyctl & ~mask) | phytxant;
1657 brcms_b_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl);
1658
1659 /* set the Response (ACK/CTS) frame phy control word */
1660 phyctl = brcms_b_read_shm(wlc_hw, M_RSP_PCTLWD);
1661 phyctl = (phyctl & ~mask) | phytxant;
1662 brcms_b_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl);
1663}
1664
1665static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw,
1666 u8 rate)
1667{
1668 uint i;
1669 u8 plcp_rate = 0;
1670 struct plcp_signal_rate_lookup {
1671 u8 rate;
1672 u8 signal_rate;
1673 };
1674 /* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */
1675 const struct plcp_signal_rate_lookup rate_lookup[] = {
1676 {BRCM_RATE_6M, 0xB},
1677 {BRCM_RATE_9M, 0xF},
1678 {BRCM_RATE_12M, 0xA},
1679 {BRCM_RATE_18M, 0xE},
1680 {BRCM_RATE_24M, 0x9},
1681 {BRCM_RATE_36M, 0xD},
1682 {BRCM_RATE_48M, 0x8},
1683 {BRCM_RATE_54M, 0xC}
1684 };
1685
1686 for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) {
1687 if (rate == rate_lookup[i].rate) {
1688 plcp_rate = rate_lookup[i].signal_rate;
1689 break;
1690 }
1691 }
1692
1693 /* Find the SHM pointer to the rate table entry by looking in the
1694 * Direct-map Table
1695 */
1696 return 2 * brcms_b_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2));
1697}
1698
1699static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw)
1700{
1701 u8 rate;
1702 u8 rates[8] = {
1703 BRCM_RATE_6M, BRCM_RATE_9M, BRCM_RATE_12M, BRCM_RATE_18M,
1704 BRCM_RATE_24M, BRCM_RATE_36M, BRCM_RATE_48M, BRCM_RATE_54M
1705 };
1706 u16 entry_ptr;
1707 u16 pctl1;
1708 uint i;
1709
1710 if (!BRCMS_PHY_11N_CAP(wlc_hw->band))
1711 return;
1712
1713 /* walk the phy rate table and update the entries */
1714 for (i = 0; i < ARRAY_SIZE(rates); i++) {
1715 rate = rates[i];
1716
1717 entry_ptr = brcms_b_ofdm_ratetable_offset(wlc_hw, rate);
1718
1719 /* read the SHM Rate Table entry OFDM PCTL1 values */
1720 pctl1 =
1721 brcms_b_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS);
1722
1723 /* modify the value */
1724 pctl1 &= ~PHY_TXC1_MODE_MASK;
1725 pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT);
1726
1727 /* Update the SHM Rate Table entry OFDM PCTL1 values */
1728 brcms_b_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS,
1729 pctl1);
1730 }
1731}
1732
1733/* band-specific init */
1734static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec)
1735{
1736 struct brcms_hardware *wlc_hw = wlc->hw;
1737
1738 BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
1739 wlc_hw->band->bandunit);
1740
1741 brcms_c_ucode_bsinit(wlc_hw);
1742
1743 wlc_phy_init(wlc_hw->band->pi, chanspec);
1744
1745 brcms_c_ucode_txant_set(wlc_hw);
1746
1747 /*
1748 * cwmin is band-specific, update hardware
1749 * with value for current band
1750 */
1751 brcms_b_set_cwmin(wlc_hw, wlc_hw->band->CWmin);
1752 brcms_b_set_cwmax(wlc_hw, wlc_hw->band->CWmax);
1753
1754 brcms_b_update_slot_timing(wlc_hw,
1755 wlc_hw->band->bandtype == BRCM_BAND_5G ?
1756 true : wlc_hw->shortslot);
1757
1758 /* write phytype and phyvers */
1759 brcms_b_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype);
1760 brcms_b_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev);
1761
1762 /*
1763 * initialize the txphyctl1 rate table since
1764 * shmem is shared between bands
1765 */
1766 brcms_upd_ofdm_pctl1_table(wlc_hw);
1767
1768 brcms_b_upd_synthpu(wlc_hw);
1769}
1770
1771/* Perform a soft reset of the PHY PLL */
1772void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw)
1773{
1774 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1775
1776 ai_corereg(wlc_hw->sih, SI_CC_IDX,
1777 offsetof(struct chipcregs, chipcontrol_addr), ~0, 0);
1778 udelay(1);
1779 ai_corereg(wlc_hw->sih, SI_CC_IDX,
1780 offsetof(struct chipcregs, chipcontrol_data), 0x4, 0);
1781 udelay(1);
1782 ai_corereg(wlc_hw->sih, SI_CC_IDX,
1783 offsetof(struct chipcregs, chipcontrol_data), 0x4, 4);
1784 udelay(1);
1785 ai_corereg(wlc_hw->sih, SI_CC_IDX,
1786 offsetof(struct chipcregs, chipcontrol_data), 0x4, 0);
1787 udelay(1);
1788}
1789
1790/* light way to turn on phy clock without reset for NPHY only
1791 * refer to brcms_b_core_phy_clk for full version
1792 */
1793void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk)
1794{
1795 /* support(necessary for NPHY and HYPHY) only */
1796 if (!BRCMS_ISNPHY(wlc_hw->band))
1797 return;
1798
1799 if (ON == clk)
1800 ai_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC);
1801 else
1802 ai_core_cflags(wlc_hw->sih, SICF_FGC, 0);
1803
1804}
1805
1806void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk)
1807{
1808 if (ON == clk)
1809 ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE);
1810 else
1811 ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0);
1812}
1813
1814void brcms_b_phy_reset(struct brcms_hardware *wlc_hw)
1815{
1816 struct brcms_phy_pub *pih = wlc_hw->band->pi;
1817 u32 phy_bw_clkbits;
1818 bool phy_in_reset = false;
1819
1820 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1821
1822 if (pih == NULL)
1823 return;
1824
1825 phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi);
1826
1827 /* Specific reset sequence required for NPHY rev 3 and 4 */
1828 if (BRCMS_ISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) &&
1829 NREV_LE(wlc_hw->band->phyrev, 4)) {
1830 /* Set the PHY bandwidth */
1831 ai_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits);
1832
1833 udelay(1);
1834
1835 /* Perform a soft reset of the PHY PLL */
1836 brcms_b_core_phypll_reset(wlc_hw);
1837
1838 /* reset the PHY */
1839 ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE),
1840 (SICF_PRST | SICF_PCLKE));
1841 phy_in_reset = true;
1842 } else {
1843 ai_core_cflags(wlc_hw->sih,
1844 (SICF_PRST | SICF_PCLKE | SICF_BWMASK),
1845 (SICF_PRST | SICF_PCLKE | phy_bw_clkbits));
1846 }
1847
1848 udelay(2);
1849 brcms_b_core_phy_clk(wlc_hw, ON);
1850
1851 if (pih)
1852 wlc_phy_anacore(pih, ON);
1853}
1854
1855/* switch to and initialize new band */
1856static void brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit,
1857 u16 chanspec) {
1858 struct brcms_c_info *wlc = wlc_hw->wlc;
1859 u32 macintmask;
1860
1861 /* Enable the d11 core before accessing it */
1862 if (!ai_iscoreup(wlc_hw->sih)) {
1863 ai_core_reset(wlc_hw->sih, 0, 0);
1864 brcms_c_mctrl_reset(wlc_hw);
1865 }
1866
1867 macintmask = brcms_c_setband_inact(wlc, bandunit);
1868
1869 if (!wlc_hw->up)
1870 return;
1871
1872 brcms_b_core_phy_clk(wlc_hw, ON);
1873
1874 /* band-specific initializations */
1875 brcms_b_bsinit(wlc, chanspec);
1876
1877 /*
1878 * If there are any pending software interrupt bits,
1879 * then replace these with a harmless nonzero value
1880 * so brcms_c_dpc() will re-enable interrupts when done.
1881 */
1882 if (wlc->macintstatus)
1883 wlc->macintstatus = MI_DMAINT;
1884
1885 /* restore macintmask */
1886 brcms_intrsrestore(wlc->wl, macintmask);
1887
1888 /* ucode should still be suspended.. */
1889 WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0);
1890}
1891
1892static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw)
1893{
1894
1895 /* reject unsupported corerev */
1896 if (!CONF_HAS(D11CONF, wlc_hw->corerev)) {
1897 wiphy_err(wlc_hw->wlc->wiphy, "unsupported core rev %d\n",
1898 wlc_hw->corerev);
1899 return false;
1900 }
1901
1902 return true;
1903}
1904
1905/* Validate some board info parameters */
1906static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw)
1907{
1908 uint boardrev = wlc_hw->boardrev;
1909
1910 /* 4 bits each for board type, major, minor, and tiny version */
1911 uint brt = (boardrev & 0xf000) >> 12;
1912 uint b0 = (boardrev & 0xf00) >> 8;
1913 uint b1 = (boardrev & 0xf0) >> 4;
1914 uint b2 = boardrev & 0xf;
1915
1916 /* voards from other vendors are always considered valid */
1917 if (wlc_hw->sih->boardvendor != PCI_VENDOR_ID_BROADCOM)
1918 return true;
1919
1920 /* do some boardrev sanity checks when boardvendor is Broadcom */
1921 if (boardrev == 0)
1922 return false;
1923
1924 if (boardrev <= 0xff)
1925 return true;
1926
1927 if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9)
1928 || (b2 > 9))
1929 return false;
1930
1931 return true;
1932}
1933
1934static char *brcms_c_get_macaddr(struct brcms_hardware *wlc_hw)
1935{
1936 enum brcms_srom_id var_id = BRCMS_SROM_MACADDR;
1937 char *macaddr;
1938
1939 /* If macaddr exists, use it (Sromrev4, CIS, ...). */
1940 macaddr = getvar(wlc_hw->sih, var_id);
1941 if (macaddr != NULL)
1942 return macaddr;
1943
1944 if (wlc_hw->_nbands > 1)
1945 var_id = BRCMS_SROM_ET1MACADDR;
1946 else
1947 var_id = BRCMS_SROM_IL0MACADDR;
1948
1949 macaddr = getvar(wlc_hw->sih, var_id);
1950 if (macaddr == NULL)
1951 wiphy_err(wlc_hw->wlc->wiphy, "wl%d: wlc_get_macaddr: macaddr "
1952 "getvar(%d) not found\n", wlc_hw->unit, var_id);
1953
1954 return macaddr;
1955}
1956
1957/* power both the pll and external oscillator on/off */
1958static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want)
1959{
1960 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want);
1961
1962 /*
1963 * dont power down if plldown is false or
1964 * we must poll hw radio disable
1965 */
1966 if (!want && wlc_hw->pllreq)
1967 return;
1968
1969 if (wlc_hw->sih)
1970 ai_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want);
1971
1972 wlc_hw->sbclk = want;
1973 if (!wlc_hw->sbclk) {
1974 wlc_hw->clk = false;
1975 if (wlc_hw->band && wlc_hw->band->pi)
1976 wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
1977 }
1978}
1979
1980/*
1981 * Return true if radio is disabled, otherwise false.
1982 * hw radio disable signal is an external pin, users activate it asynchronously
1983 * this function could be called when driver is down and w/o clock
1984 * it operates on different registers depending on corerev and boardflag.
1985 */
1986static bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw)
1987{
1988 bool v, clk, xtal;
1989 u32 resetbits = 0, flags = 0;
1990
1991 xtal = wlc_hw->sbclk;
1992 if (!xtal)
1993 brcms_b_xtal(wlc_hw, ON);
1994
1995 /* may need to take core out of reset first */
1996 clk = wlc_hw->clk;
1997 if (!clk) {
1998 /*
1999 * mac no longer enables phyclk automatically when driver
2000 * accesses phyreg throughput mac. This can be skipped since
2001 * only mac reg is accessed below
2002 */
2003 flags |= SICF_PCLKE;
2004
2005 /*
2006 * AI chip doesn't restore bar0win2 on
2007 * hibernation/resume, need sw fixup
2008 */
2009 if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
2010 (wlc_hw->sih->chip == BCM43225_CHIP_ID))
2011 wlc_hw->regs = (struct d11regs __iomem *)
2012 ai_setcore(wlc_hw->sih, D11_CORE_ID, 0);
2013 ai_core_reset(wlc_hw->sih, flags, resetbits);
2014 brcms_c_mctrl_reset(wlc_hw);
2015 }
2016
2017 v = ((R_REG(&wlc_hw->regs->phydebug) & PDBG_RFD) != 0);
2018
2019 /* put core back into reset */
2020 if (!clk)
2021 ai_core_disable(wlc_hw->sih, 0);
2022
2023 if (!xtal)
2024 brcms_b_xtal(wlc_hw, OFF);
2025
2026 return v;
2027}
2028
2029static bool wlc_dma_rxreset(struct brcms_hardware *wlc_hw, uint fifo)
2030{
2031 struct dma_pub *di = wlc_hw->di[fifo];
2032 return dma_rxreset(di);
2033}
2034
2035/* d11 core reset
2036 * ensure fask clock during reset
2037 * reset dma
2038 * reset d11(out of reset)
2039 * reset phy(out of reset)
2040 * clear software macintstatus for fresh new start
2041 * one testing hack wlc_hw->noreset will bypass the d11/phy reset
2042 */
2043void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
2044{
2045 struct d11regs __iomem *regs;
2046 uint i;
2047 bool fastclk;
2048 u32 resetbits = 0;
2049
2050 if (flags == BRCMS_USE_COREFLAGS)
2051 flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0);
2052
2053 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
2054
2055 regs = wlc_hw->regs;
2056
2057 /* request FAST clock if not on */
2058 fastclk = wlc_hw->forcefastclk;
2059 if (!fastclk)
2060 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
2061
2062 /* reset the dma engines except first time thru */
2063 if (ai_iscoreup(wlc_hw->sih)) {
2064 for (i = 0; i < NFIFO; i++)
2065 if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i])))
2066 wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: "
2067 "dma_txreset[%d]: cannot stop dma\n",
2068 wlc_hw->unit, __func__, i);
2069
2070 if ((wlc_hw->di[RX_FIFO])
2071 && (!wlc_dma_rxreset(wlc_hw, RX_FIFO)))
2072 wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset"
2073 "[%d]: cannot stop dma\n",
2074 wlc_hw->unit, __func__, RX_FIFO);
2075 }
2076 /* if noreset, just stop the psm and return */
2077 if (wlc_hw->noreset) {
2078 wlc_hw->wlc->macintstatus = 0; /* skip wl_dpc after down */
2079 brcms_b_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0);
2080 return;
2081 }
2082
2083 /*
2084 * mac no longer enables phyclk automatically when driver accesses
2085 * phyreg throughput mac, AND phy_reset is skipped at early stage when
2086 * band->pi is invalid. need to enable PHY CLK
2087 */
2088 flags |= SICF_PCLKE;
2089
2090 /*
2091 * reset the core
2092 * In chips with PMU, the fastclk request goes through d11 core
2093 * reg 0x1e0, which is cleared by the core_reset. have to re-request it.
2094 *
2095 * This adds some delay and we can optimize it by also requesting
2096 * fastclk through chipcommon during this period if necessary. But
2097 * that has to work coordinate with other driver like mips/arm since
2098 * they may touch chipcommon as well.
2099 */
2100 wlc_hw->clk = false;
2101 ai_core_reset(wlc_hw->sih, flags, resetbits);
2102 wlc_hw->clk = true;
2103 if (wlc_hw->band && wlc_hw->band->pi)
2104 wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true);
2105
2106 brcms_c_mctrl_reset(wlc_hw);
2107
2108 if (wlc_hw->sih->cccaps & CC_CAP_PMU)
2109 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
2110
2111 brcms_b_phy_reset(wlc_hw);
2112
2113 /* turn on PHY_PLL */
2114 brcms_b_core_phypll_ctl(wlc_hw, true);
2115
2116 /* clear sw intstatus */
2117 wlc_hw->wlc->macintstatus = 0;
2118
2119 /* restore the clk setting */
2120 if (!fastclk)
2121 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
2122}
2123
2124/* txfifo sizes needs to be modified(increased) since the newer cores
2125 * have more memory.
2126 */
2127static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw)
2128{
2129 struct d11regs __iomem *regs = wlc_hw->regs;
2130 u16 fifo_nu;
2131 u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk;
2132 u16 txfifo_def, txfifo_def1;
2133 u16 txfifo_cmd;
2134
2135 /* tx fifos start at TXFIFO_START_BLK from the Base address */
2136 txfifo_startblk = TXFIFO_START_BLK;
2137
2138 /* sequence of operations: reset fifo, set fifo size, reset fifo */
2139 for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) {
2140
2141 txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu];
2142 txfifo_def = (txfifo_startblk & 0xff) |
2143 (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT);
2144 txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) |
2145 ((((txfifo_endblk -
2146 1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT);
2147 txfifo_cmd =
2148 TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT);
2149
2150 W_REG(&regs->xmtfifocmd, txfifo_cmd);
2151 W_REG(&regs->xmtfifodef, txfifo_def);
2152 W_REG(&regs->xmtfifodef1, txfifo_def1);
2153
2154 W_REG(&regs->xmtfifocmd, txfifo_cmd);
2155
2156 txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu];
2157 }
2158 /*
2159 * need to propagate to shm location to be in sync since ucode/hw won't
2160 * do this
2161 */
2162 brcms_b_write_shm(wlc_hw, M_FIFOSIZE0,
2163 wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]);
2164 brcms_b_write_shm(wlc_hw, M_FIFOSIZE1,
2165 wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]);
2166 brcms_b_write_shm(wlc_hw, M_FIFOSIZE2,
2167 ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw->
2168 xmtfifo_sz[TX_AC_BK_FIFO]));
2169 brcms_b_write_shm(wlc_hw, M_FIFOSIZE3,
2170 ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw->
2171 xmtfifo_sz[TX_BCMC_FIFO]));
2172}
2173
2174/* This function is used for changing the tsf frac register
2175 * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz
2176 * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz
2177 * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz
2178 * HTPHY Formula is 2^26/freq(MHz) e.g.
2179 * For spuron2 - 126MHz -> 2^26/126 = 532610.0
2180 * - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082
2181 * For spuron: 123MHz -> 2^26/123 = 545600.5
2182 * - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341
2183 * For spur off: 120MHz -> 2^26/120 = 559240.5
2184 * - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889
2185 */
2186
2187void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode)
2188{
2189 struct d11regs __iomem *regs = wlc_hw->regs;
2190
2191 if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
2192 (wlc_hw->sih->chip == BCM43225_CHIP_ID)) {
2193 if (spurmode == WL_SPURAVOID_ON2) { /* 126Mhz */
2194 W_REG(&regs->tsf_clk_frac_l, 0x2082);
2195 W_REG(&regs->tsf_clk_frac_h, 0x8);
2196 } else if (spurmode == WL_SPURAVOID_ON1) { /* 123Mhz */
2197 W_REG(&regs->tsf_clk_frac_l, 0x5341);
2198 W_REG(&regs->tsf_clk_frac_h, 0x8);
2199 } else { /* 120Mhz */
2200 W_REG(&regs->tsf_clk_frac_l, 0x8889);
2201 W_REG(&regs->tsf_clk_frac_h, 0x8);
2202 }
2203 } else if (BRCMS_ISLCNPHY(wlc_hw->band)) {
2204 if (spurmode == WL_SPURAVOID_ON1) { /* 82Mhz */
2205 W_REG(&regs->tsf_clk_frac_l, 0x7CE0);
2206 W_REG(&regs->tsf_clk_frac_h, 0xC);
2207 } else { /* 80Mhz */
2208 W_REG(&regs->tsf_clk_frac_l, 0xCCCD);
2209 W_REG(&regs->tsf_clk_frac_h, 0xC);
2210 }
2211 }
2212}
2213
2214/* Initialize GPIOs that are controlled by D11 core */
2215static void brcms_c_gpio_init(struct brcms_c_info *wlc)
2216{
2217 struct brcms_hardware *wlc_hw = wlc->hw;
2218 struct d11regs __iomem *regs;
2219 u32 gc, gm;
2220
2221 regs = wlc_hw->regs;
2222
2223 /* use GPIO select 0 to get all gpio signals from the gpio out reg */
2224 brcms_b_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0);
2225
2226 /*
2227 * Common GPIO setup:
2228 * G0 = LED 0 = WLAN Activity
2229 * G1 = LED 1 = WLAN 2.4 GHz Radio State
2230 * G2 = LED 2 = WLAN 5 GHz Radio State
2231 * G4 = radio disable input (HI enabled, LO disabled)
2232 */
2233
2234 gc = gm = 0;
2235
2236 /* Allocate GPIOs for mimo antenna diversity feature */
2237 if (wlc_hw->antsel_type == ANTSEL_2x3) {
2238 /* Enable antenna diversity, use 2x3 mode */
2239 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
2240 MHF3_ANTSEL_EN, BRCM_BAND_ALL);
2241 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE,
2242 MHF3_ANTSEL_MODE, BRCM_BAND_ALL);
2243
2244 /* init superswitch control */
2245 wlc_phy_antsel_init(wlc_hw->band->pi, false);
2246
2247 } else if (wlc_hw->antsel_type == ANTSEL_2x4) {
2248 gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13);
2249 /*
2250 * The board itself is powered by these GPIOs
2251 * (when not sending pattern) so set them high
2252 */
2253 OR_REG(&regs->psm_gpio_oe,
2254 (BOARD_GPIO_12 | BOARD_GPIO_13));
2255 OR_REG(&regs->psm_gpio_out,
2256 (BOARD_GPIO_12 | BOARD_GPIO_13));
2257
2258 /* Enable antenna diversity, use 2x4 mode */
2259 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
2260 MHF3_ANTSEL_EN, BRCM_BAND_ALL);
2261 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0,
2262 BRCM_BAND_ALL);
2263
2264 /* Configure the desired clock to be 4Mhz */
2265 brcms_b_write_shm(wlc_hw, M_ANTSEL_CLKDIV,
2266 ANTSEL_CLKDIV_4MHZ);
2267 }
2268
2269 /*
2270 * gpio 9 controls the PA. ucode is responsible
2271 * for wiggling out and oe
2272 */
2273 if (wlc_hw->boardflags & BFL_PACTRL)
2274 gm |= gc |= BOARD_GPIO_PACTRL;
2275
2276 /* apply to gpiocontrol register */
2277 ai_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY);
2278}
2279
2280static void brcms_ucode_write(struct brcms_hardware *wlc_hw,
2281 const __le32 ucode[], const size_t nbytes)
2282{
2283 struct d11regs __iomem *regs = wlc_hw->regs;
2284 uint i;
2285 uint count;
2286
2287 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
2288
2289 count = (nbytes / sizeof(u32));
2290
2291 W_REG(&regs->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL));
2292 (void)R_REG(&regs->objaddr);
2293 for (i = 0; i < count; i++)
2294 W_REG(&regs->objdata, le32_to_cpu(ucode[i]));
2295
2296}
2297
2298static void brcms_ucode_download(struct brcms_hardware *wlc_hw)
2299{
2300 struct brcms_c_info *wlc;
2301 struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
2302
2303 wlc = wlc_hw->wlc;
2304
2305 if (wlc_hw->ucode_loaded)
2306 return;
2307
2308 if (D11REV_IS(wlc_hw->corerev, 23)) {
2309 if (BRCMS_ISNPHY(wlc_hw->band)) {
2310 brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo,
2311 ucode->bcm43xx_16_mimosz);
2312 wlc_hw->ucode_loaded = true;
2313 } else
2314 wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
2315 "corerev %d\n",
2316 __func__, wlc_hw->unit, wlc_hw->corerev);
2317 } else if (D11REV_IS(wlc_hw->corerev, 24)) {
2318 if (BRCMS_ISLCNPHY(wlc_hw->band)) {
2319 brcms_ucode_write(wlc_hw, ucode->bcm43xx_24_lcn,
2320 ucode->bcm43xx_24_lcnsz);
2321 wlc_hw->ucode_loaded = true;
2322 } else {
2323 wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
2324 "corerev %d\n",
2325 __func__, wlc_hw->unit, wlc_hw->corerev);
2326 }
2327 }
2328}
2329
2330void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant)
2331{
2332 /* update sw state */
2333 wlc_hw->bmac_phytxant = phytxant;
2334
2335 /* push to ucode if up */
2336 if (!wlc_hw->up)
2337 return;
2338 brcms_c_ucode_txant_set(wlc_hw);
2339
2340}
2341
2342u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw)
2343{
2344 return (u16) wlc_hw->wlc->stf->txant;
2345}
2346
2347void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type)
2348{
2349 wlc_hw->antsel_type = antsel_type;
2350
2351 /* Update the antsel type for phy module to use */
2352 wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type);
2353}
2354
2355static void brcms_c_fatal_error(struct brcms_c_info *wlc)
2356{
2357 wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n",
2358 wlc->pub->unit);
2359 brcms_init(wlc->wl);
2360}
2361
2362static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw)
2363{
2364 bool fatal = false;
2365 uint unit;
2366 uint intstatus, idx;
2367 struct d11regs __iomem *regs = wlc_hw->regs;
2368 struct wiphy *wiphy = wlc_hw->wlc->wiphy;
2369
2370 unit = wlc_hw->unit;
2371
2372 for (idx = 0; idx < NFIFO; idx++) {
2373 /* read intstatus register and ignore any non-error bits */
2374 intstatus =
2375 R_REG(&regs->intctrlregs[idx].intstatus) & I_ERRORS;
2376 if (!intstatus)
2377 continue;
2378
2379 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n",
2380 unit, idx, intstatus);
2381
2382 if (intstatus & I_RO) {
2383 wiphy_err(wiphy, "wl%d: fifo %d: receive fifo "
2384 "overflow\n", unit, idx);
2385 fatal = true;
2386 }
2387
2388 if (intstatus & I_PC) {
2389 wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n",
2390 unit, idx);
2391 fatal = true;
2392 }
2393
2394 if (intstatus & I_PD) {
2395 wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit,
2396 idx);
2397 fatal = true;
2398 }
2399
2400 if (intstatus & I_DE) {
2401 wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol "
2402 "error\n", unit, idx);
2403 fatal = true;
2404 }
2405
2406 if (intstatus & I_RU)
2407 wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor "
2408 "underflow\n", idx, unit);
2409
2410 if (intstatus & I_XU) {
2411 wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo "
2412 "underflow\n", idx, unit);
2413 fatal = true;
2414 }
2415
2416 if (fatal) {
2417 brcms_c_fatal_error(wlc_hw->wlc); /* big hammer */
2418 break;
2419 } else
2420 W_REG(&regs->intctrlregs[idx].intstatus,
2421 intstatus);
2422 }
2423}
2424
2425void brcms_c_intrson(struct brcms_c_info *wlc)
2426{
2427 struct brcms_hardware *wlc_hw = wlc->hw;
2428 wlc->macintmask = wlc->defmacintmask;
2429 W_REG(&wlc_hw->regs->macintmask, wlc->macintmask);
2430}
2431
2432/*
2433 * callback for siutils.c, which has only wlc handler, no wl they both check
2434 * up, not only because there is no need to off/restore d11 interrupt but also
2435 * because per-port code may require sync with valid interrupt.
2436 */
2437static u32 brcms_c_wlintrsoff(struct brcms_c_info *wlc)
2438{
2439 if (!wlc->hw->up)
2440 return 0;
2441
2442 return brcms_intrsoff(wlc->wl);
2443}
2444
2445static void brcms_c_wlintrsrestore(struct brcms_c_info *wlc, u32 macintmask)
2446{
2447 if (!wlc->hw->up)
2448 return;
2449
2450 brcms_intrsrestore(wlc->wl, macintmask);
2451}
2452
2453u32 brcms_c_intrsoff(struct brcms_c_info *wlc)
2454{
2455 struct brcms_hardware *wlc_hw = wlc->hw;
2456 u32 macintmask;
2457
2458 if (!wlc_hw->clk)
2459 return 0;
2460
2461 macintmask = wlc->macintmask; /* isr can still happen */
2462
2463 W_REG(&wlc_hw->regs->macintmask, 0);
2464 (void)R_REG(&wlc_hw->regs->macintmask); /* sync readback */
2465 udelay(1); /* ensure int line is no longer driven */
2466 wlc->macintmask = 0;
2467
2468 /* return previous macintmask; resolve race between us and our isr */
2469 return wlc->macintstatus ? 0 : macintmask;
2470}
2471
2472void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask)
2473{
2474 struct brcms_hardware *wlc_hw = wlc->hw;
2475 if (!wlc_hw->clk)
2476 return;
2477
2478 wlc->macintmask = macintmask;
2479 W_REG(&wlc_hw->regs->macintmask, wlc->macintmask);
2480}
2481
2482static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw,
2483 uint tx_fifo)
2484{
2485 u8 fifo = 1 << tx_fifo;
2486
2487 /* Two clients of this code, 11h Quiet period and scanning. */
2488
2489 /* only suspend if not already suspended */
2490 if ((wlc_hw->suspended_fifos & fifo) == fifo)
2491 return;
2492
2493 /* force the core awake only if not already */
2494 if (wlc_hw->suspended_fifos == 0)
2495 brcms_c_ucode_wake_override_set(wlc_hw,
2496 BRCMS_WAKE_OVERRIDE_TXFIFO);
2497
2498 wlc_hw->suspended_fifos |= fifo;
2499
2500 if (wlc_hw->di[tx_fifo]) {
2501 /*
2502 * Suspending AMPDU transmissions in the middle can cause
2503 * underflow which may result in mismatch between ucode and
2504 * driver so suspend the mac before suspending the FIFO
2505 */
2506 if (BRCMS_PHY_11N_CAP(wlc_hw->band))
2507 brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
2508
2509 dma_txsuspend(wlc_hw->di[tx_fifo]);
2510
2511 if (BRCMS_PHY_11N_CAP(wlc_hw->band))
2512 brcms_c_enable_mac(wlc_hw->wlc);
2513 }
2514}
2515
2516static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw,
2517 uint tx_fifo)
2518{
2519 /* BMAC_NOTE: BRCMS_TX_FIFO_ENAB is done in brcms_c_dpc() for DMA case
2520 * but need to be done here for PIO otherwise the watchdog will catch
2521 * the inconsistency and fire
2522 */
2523 /* Two clients of this code, 11h Quiet period and scanning. */
2524 if (wlc_hw->di[tx_fifo])
2525 dma_txresume(wlc_hw->di[tx_fifo]);
2526
2527 /* allow core to sleep again */
2528 if (wlc_hw->suspended_fifos == 0)
2529 return;
2530 else {
2531 wlc_hw->suspended_fifos &= ~(1 << tx_fifo);
2532 if (wlc_hw->suspended_fifos == 0)
2533 brcms_c_ucode_wake_override_clear(wlc_hw,
2534 BRCMS_WAKE_OVERRIDE_TXFIFO);
2535 }
2536}
2537
2538static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, u32 flags)
2539{
2540 static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
2541
2542 if (on) {
2543 /* suspend tx fifos */
2544 brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO);
2545 brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO);
2546 brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO);
2547 brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO);
2548
2549 /* zero the address match register so we do not send ACKs */
2550 brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
2551 null_ether_addr);
2552 } else {
2553 /* resume tx fifos */
2554 brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO);
2555 brcms_b_tx_fifo_resume(wlc_hw, TX_CTL_FIFO);
2556 brcms_b_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO);
2557 brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO);
2558
2559 /* Restore address */
2560 brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
2561 wlc_hw->etheraddr);
2562 }
2563
2564 wlc_phy_mute_upd(wlc_hw->band->pi, on, flags);
2565
2566 if (on)
2567 brcms_c_ucode_mute_override_set(wlc_hw);
2568 else
2569 brcms_c_ucode_mute_override_clear(wlc_hw);
2570}
2571
2572/*
2573 * Read and clear macintmask and macintstatus and intstatus registers.
2574 * This routine should be called with interrupts off
2575 * Return:
2576 * -1 if brcms_deviceremoved(wlc) evaluates to true;
2577 * 0 if the interrupt is not for us, or we are in some special cases;
2578 * device interrupt status bits otherwise.
2579 */
2580static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
2581{
2582 struct brcms_hardware *wlc_hw = wlc->hw;
2583 struct d11regs __iomem *regs = wlc_hw->regs;
2584 u32 macintstatus;
2585
2586 /* macintstatus includes a DMA interrupt summary bit */
2587 macintstatus = R_REG(&regs->macintstatus);
2588
2589 BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit,
2590 macintstatus);
2591
2592 /* detect cardbus removed, in power down(suspend) and in reset */
2593 if (brcms_deviceremoved(wlc))
2594 return -1;
2595
2596 /* brcms_deviceremoved() succeeds even when the core is still resetting,
2597 * handle that case here.
2598 */
2599 if (macintstatus == 0xffffffff)
2600 return 0;
2601
2602 /* defer unsolicited interrupts */
2603 macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask);
2604
2605 /* if not for us */
2606 if (macintstatus == 0)
2607 return 0;
2608
2609 /* interrupts are already turned off for CFE build
2610 * Caution: For CFE Turning off the interrupts again has some undesired
2611 * consequences
2612 */
2613 /* turn off the interrupts */
2614 W_REG(&regs->macintmask, 0);
2615 (void)R_REG(&regs->macintmask); /* sync readback */
2616 wlc->macintmask = 0;
2617
2618 /* clear device interrupts */
2619 W_REG(&regs->macintstatus, macintstatus);
2620
2621 /* MI_DMAINT is indication of non-zero intstatus */
2622 if (macintstatus & MI_DMAINT)
2623 /*
2624 * only fifo interrupt enabled is I_RI in
2625 * RX_FIFO. If MI_DMAINT is set, assume it
2626 * is set and clear the interrupt.
2627 */
2628 W_REG(&regs->intctrlregs[RX_FIFO].intstatus,
2629 DEF_RXINTMASK);
2630
2631 return macintstatus;
2632}
2633
2634/* Update wlc->macintstatus and wlc->intstatus[]. */
2635/* Return true if they are updated successfully. false otherwise */
2636bool brcms_c_intrsupd(struct brcms_c_info *wlc)
2637{
2638 u32 macintstatus;
2639
2640 /* read and clear macintstatus and intstatus registers */
2641 macintstatus = wlc_intstatus(wlc, false);
2642
2643 /* device is removed */
2644 if (macintstatus == 0xffffffff)
2645 return false;
2646
2647 /* update interrupt status in software */
2648 wlc->macintstatus |= macintstatus;
2649
2650 return true;
2651}
2652
2653/*
2654 * First-level interrupt processing.
2655 * Return true if this was our interrupt, false otherwise.
2656 * *wantdpc will be set to true if further brcms_c_dpc() processing is required,
2657 * false otherwise.
2658 */
2659bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc)
2660{
2661 struct brcms_hardware *wlc_hw = wlc->hw;
2662 u32 macintstatus;
2663
2664 *wantdpc = false;
2665
2666 if (!wlc_hw->up || !wlc->macintmask)
2667 return false;
2668
2669 /* read and clear macintstatus and intstatus registers */
2670 macintstatus = wlc_intstatus(wlc, true);
2671
2672 if (macintstatus == 0xffffffff)
2673 wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code"
2674 " path\n");
2675
2676 /* it is not for us */
2677 if (macintstatus == 0)
2678 return false;
2679
2680 *wantdpc = true;
2681
2682 /* save interrupt status bits */
2683 wlc->macintstatus = macintstatus;
2684
2685 return true;
2686
2687}
2688
2689void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
2690{
2691 struct brcms_hardware *wlc_hw = wlc->hw;
2692 struct d11regs __iomem *regs = wlc_hw->regs;
2693 u32 mc, mi;
2694 struct wiphy *wiphy = wlc->wiphy;
2695
2696 BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
2697 wlc_hw->band->bandunit);
2698
2699 /*
2700 * Track overlapping suspend requests
2701 */
2702 wlc_hw->mac_suspend_depth++;
2703 if (wlc_hw->mac_suspend_depth > 1)
2704 return;
2705
2706 /* force the core awake */
2707 brcms_c_ucode_wake_override_set(wlc_hw, BRCMS_WAKE_OVERRIDE_MACSUSPEND);
2708
2709 mc = R_REG(&regs->maccontrol);
2710
2711 if (mc == 0xffffffff) {
2712 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
2713 __func__);
2714 brcms_down(wlc->wl);
2715 return;
2716 }
2717 WARN_ON(mc & MCTL_PSM_JMP_0);
2718 WARN_ON(!(mc & MCTL_PSM_RUN));
2719 WARN_ON(!(mc & MCTL_EN_MAC));
2720
2721 mi = R_REG(&regs->macintstatus);
2722 if (mi == 0xffffffff) {
2723 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
2724 __func__);
2725 brcms_down(wlc->wl);
2726 return;
2727 }
2728 WARN_ON(mi & MI_MACSSPNDD);
2729
2730 brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, 0);
2731
2732 SPINWAIT(!(R_REG(&regs->macintstatus) & MI_MACSSPNDD),
2733 BRCMS_MAX_MAC_SUSPEND);
2734
2735 if (!(R_REG(&regs->macintstatus) & MI_MACSSPNDD)) {
2736 wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS"
2737 " and MI_MACSSPNDD is still not on.\n",
2738 wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND);
2739 wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, "
2740 "psm_brc 0x%04x\n", wlc_hw->unit,
2741 R_REG(&regs->psmdebug),
2742 R_REG(&regs->phydebug),
2743 R_REG(&regs->psm_brc));
2744 }
2745
2746 mc = R_REG(&regs->maccontrol);
2747 if (mc == 0xffffffff) {
2748 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
2749 __func__);
2750 brcms_down(wlc->wl);
2751 return;
2752 }
2753 WARN_ON(mc & MCTL_PSM_JMP_0);
2754 WARN_ON(!(mc & MCTL_PSM_RUN));
2755 WARN_ON(mc & MCTL_EN_MAC);
2756}
2757
2758void brcms_c_enable_mac(struct brcms_c_info *wlc)
2759{
2760 struct brcms_hardware *wlc_hw = wlc->hw;
2761 struct d11regs __iomem *regs = wlc_hw->regs;
2762 u32 mc, mi;
2763
2764 BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
2765 wlc->band->bandunit);
2766
2767 /*
2768 * Track overlapping suspend requests
2769 */
2770 wlc_hw->mac_suspend_depth--;
2771 if (wlc_hw->mac_suspend_depth > 0)
2772 return;
2773
2774 mc = R_REG(&regs->maccontrol);
2775 WARN_ON(mc & MCTL_PSM_JMP_0);
2776 WARN_ON(mc & MCTL_EN_MAC);
2777 WARN_ON(!(mc & MCTL_PSM_RUN));
2778
2779 brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC);
2780 W_REG(&regs->macintstatus, MI_MACSSPNDD);
2781
2782 mc = R_REG(&regs->maccontrol);
2783 WARN_ON(mc & MCTL_PSM_JMP_0);
2784 WARN_ON(!(mc & MCTL_EN_MAC));
2785 WARN_ON(!(mc & MCTL_PSM_RUN));
2786
2787 mi = R_REG(&regs->macintstatus);
2788 WARN_ON(mi & MI_MACSSPNDD);
2789
2790 brcms_c_ucode_wake_override_clear(wlc_hw,
2791 BRCMS_WAKE_OVERRIDE_MACSUSPEND);
2792}
2793
2794void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode)
2795{
2796 wlc_hw->hw_stf_ss_opmode = stf_mode;
2797
2798 if (wlc_hw->clk)
2799 brcms_upd_ofdm_pctl1_table(wlc_hw);
2800}
2801
2802static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw)
2803{
2804 struct d11regs __iomem *regs;
2805 u32 w, val;
2806 struct wiphy *wiphy = wlc_hw->wlc->wiphy;
2807
2808 BCMMSG(wiphy, "wl%d\n", wlc_hw->unit);
2809
2810 regs = wlc_hw->regs;
2811
2812 /* Validate dchip register access */
2813
2814 W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
2815 (void)R_REG(&regs->objaddr);
2816 w = R_REG(&regs->objdata);
2817
2818 /* Can we write and read back a 32bit register? */
2819 W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
2820 (void)R_REG(&regs->objaddr);
2821 W_REG(&regs->objdata, (u32) 0xaa5555aa);
2822
2823 W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
2824 (void)R_REG(&regs->objaddr);
2825 val = R_REG(&regs->objdata);
2826 if (val != (u32) 0xaa5555aa) {
2827 wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
2828 "expected 0xaa5555aa\n", wlc_hw->unit, val);
2829 return false;
2830 }
2831
2832 W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
2833 (void)R_REG(&regs->objaddr);
2834 W_REG(&regs->objdata, (u32) 0x55aaaa55);
2835
2836 W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
2837 (void)R_REG(&regs->objaddr);
2838 val = R_REG(&regs->objdata);
2839 if (val != (u32) 0x55aaaa55) {
2840 wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
2841 "expected 0x55aaaa55\n", wlc_hw->unit, val);
2842 return false;
2843 }
2844
2845 W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
2846 (void)R_REG(&regs->objaddr);
2847 W_REG(&regs->objdata, w);
2848
2849 /* clear CFPStart */
2850 W_REG(&regs->tsf_cfpstart, 0);
2851
2852 w = R_REG(&regs->maccontrol);
2853 if ((w != (MCTL_IHR_EN | MCTL_WAKE)) &&
2854 (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) {
2855 wiphy_err(wiphy, "wl%d: validate_chip_access: maccontrol = "
2856 "0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w,
2857 (MCTL_IHR_EN | MCTL_WAKE),
2858 (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE));
2859 return false;
2860 }
2861
2862 return true;
2863}
2864
2865#define PHYPLL_WAIT_US 100000
2866
2867void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)
2868{
2869 struct d11regs __iomem *regs;
2870 u32 tmp;
2871
2872 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
2873
2874 tmp = 0;
2875 regs = wlc_hw->regs;
2876
2877 if (on) {
2878 if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) {
2879 OR_REG(&regs->clk_ctl_st,
2880 (CCS_ERSRC_REQ_HT | CCS_ERSRC_REQ_D11PLL |
2881 CCS_ERSRC_REQ_PHYPLL));
2882 SPINWAIT((R_REG(&regs->clk_ctl_st) &
2883 (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT),
2884 PHYPLL_WAIT_US);
2885
2886 tmp = R_REG(&regs->clk_ctl_st);
2887 if ((tmp & (CCS_ERSRC_AVAIL_HT)) !=
2888 (CCS_ERSRC_AVAIL_HT))
2889 wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY"
2890 " PLL failed\n", __func__);
2891 } else {
2892 OR_REG(&regs->clk_ctl_st,
2893 (CCS_ERSRC_REQ_D11PLL | CCS_ERSRC_REQ_PHYPLL));
2894 SPINWAIT((R_REG(&regs->clk_ctl_st) &
2895 (CCS_ERSRC_AVAIL_D11PLL |
2896 CCS_ERSRC_AVAIL_PHYPLL)) !=
2897 (CCS_ERSRC_AVAIL_D11PLL |
2898 CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US);
2899
2900 tmp = R_REG(&regs->clk_ctl_st);
2901 if ((tmp &
2902 (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
2903 !=
2904 (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
2905 wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on "
2906 "PHY PLL failed\n", __func__);
2907 }
2908 } else {
2909 /*
2910 * Since the PLL may be shared, other cores can still
2911 * be requesting it; so we'll deassert the request but
2912 * not wait for status to comply.
2913 */
2914 AND_REG(&regs->clk_ctl_st, ~CCS_ERSRC_REQ_PHYPLL);
2915 tmp = R_REG(&regs->clk_ctl_st);
2916 }
2917}
2918
2919static void brcms_c_coredisable(struct brcms_hardware *wlc_hw)
2920{
2921 bool dev_gone;
2922
2923 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
2924
2925 dev_gone = brcms_deviceremoved(wlc_hw->wlc);
2926
2927 if (dev_gone)
2928 return;
2929
2930 if (wlc_hw->noreset)
2931 return;
2932
2933 /* radio off */
2934 wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
2935
2936 /* turn off analog core */
2937 wlc_phy_anacore(wlc_hw->band->pi, OFF);
2938
2939 /* turn off PHYPLL to save power */
2940 brcms_b_core_phypll_ctl(wlc_hw, false);
2941
2942 wlc_hw->clk = false;
2943 ai_core_disable(wlc_hw->sih, 0);
2944 wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
2945}
2946
2947static void brcms_c_flushqueues(struct brcms_c_info *wlc)
2948{
2949 struct brcms_hardware *wlc_hw = wlc->hw;
2950 uint i;
2951
2952 /* free any posted tx packets */
2953 for (i = 0; i < NFIFO; i++)
2954 if (wlc_hw->di[i]) {
2955 dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL);
2956 wlc->core->txpktpend[i] = 0;
2957 BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i);
2958 }
2959
2960 /* free any posted rx packets */
2961 dma_rxreclaim(wlc_hw->di[RX_FIFO]);
2962}
2963
2964static u16
2965brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel)
2966{
2967 struct d11regs __iomem *regs = wlc_hw->regs;
2968 u16 __iomem *objdata_lo = (u16 __iomem *)&regs->objdata;
2969 u16 __iomem *objdata_hi = objdata_lo + 1;
2970 u16 v;
2971
2972 W_REG(&regs->objaddr, sel | (offset >> 2));
2973 (void)R_REG(&regs->objaddr);
2974 if (offset & 2)
2975 v = R_REG(objdata_hi);
2976 else
2977 v = R_REG(objdata_lo);
2978
2979 return v;
2980}
2981
2982static void
2983brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, u16 v,
2984 u32 sel)
2985{
2986 struct d11regs __iomem *regs = wlc_hw->regs;
2987 u16 __iomem *objdata_lo = (u16 __iomem *)&regs->objdata;
2988 u16 __iomem *objdata_hi = objdata_lo + 1;
2989
2990 W_REG(&regs->objaddr, sel | (offset >> 2));
2991 (void)R_REG(&regs->objaddr);
2992 if (offset & 2)
2993 W_REG(objdata_hi, v);
2994 else
2995 W_REG(objdata_lo, v);
2996}
2997
2998/*
2999 * Read a single u16 from shared memory.
3000 * SHM 'offset' needs to be an even address
3001 */
3002u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset)
3003{
3004 return brcms_b_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL);
3005}
3006
3007/*
3008 * Write a single u16 to shared memory.
3009 * SHM 'offset' needs to be an even address
3010 */
3011void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v)
3012{
3013 brcms_b_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL);
3014}
3015
3016/*
3017 * Copy a buffer to shared memory of specified type .
3018 * SHM 'offset' needs to be an even address and
3019 * Buffer length 'len' must be an even number of bytes
3020 * 'sel' selects the type of memory
3021 */
3022void
3023brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset,
3024 const void *buf, int len, u32 sel)
3025{
3026 u16 v;
3027 const u8 *p = (const u8 *)buf;
3028 int i;
3029
3030 if (len <= 0 || (offset & 1) || (len & 1))
3031 return;
3032
3033 for (i = 0; i < len; i += 2) {
3034 v = p[i] | (p[i + 1] << 8);
3035 brcms_b_write_objmem(wlc_hw, offset + i, v, sel);
3036 }
3037}
3038
3039/*
3040 * Copy a piece of shared memory of specified type to a buffer .
3041 * SHM 'offset' needs to be an even address and
3042 * Buffer length 'len' must be an even number of bytes
3043 * 'sel' selects the type of memory
3044 */
3045void
3046brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, void *buf,
3047 int len, u32 sel)
3048{
3049 u16 v;
3050 u8 *p = (u8 *) buf;
3051 int i;
3052
3053 if (len <= 0 || (offset & 1) || (len & 1))
3054 return;
3055
3056 for (i = 0; i < len; i += 2) {
3057 v = brcms_b_read_objmem(wlc_hw, offset + i, sel);
3058 p[i] = v & 0xFF;
3059 p[i + 1] = (v >> 8) & 0xFF;
3060 }
3061}
3062
3063/* Copy a buffer to shared memory.
3064 * SHM 'offset' needs to be an even address and
3065 * Buffer length 'len' must be an even number of bytes
3066 */
3067static void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset,
3068 const void *buf, int len)
3069{
3070 brcms_b_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
3071}
3072
3073static void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw,
3074 u16 SRL, u16 LRL)
3075{
3076 wlc_hw->SRL = SRL;
3077 wlc_hw->LRL = LRL;
3078
3079 /* write retry limit to SCR, shouldn't need to suspend */
3080 if (wlc_hw->up) {
3081 W_REG(&wlc_hw->regs->objaddr,
3082 OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
3083 (void)R_REG(&wlc_hw->regs->objaddr);
3084 W_REG(&wlc_hw->regs->objdata, wlc_hw->SRL);
3085 W_REG(&wlc_hw->regs->objaddr,
3086 OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
3087 (void)R_REG(&wlc_hw->regs->objaddr);
3088 W_REG(&wlc_hw->regs->objdata, wlc_hw->LRL);
3089 }
3090}
3091
3092static void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set, u32 req_bit)
3093{
3094 if (set) {
3095 if (mboolisset(wlc_hw->pllreq, req_bit))
3096 return;
3097
3098 mboolset(wlc_hw->pllreq, req_bit);
3099
3100 if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) {
3101 if (!wlc_hw->sbclk)
3102 brcms_b_xtal(wlc_hw, ON);
3103 }
3104 } else {
3105 if (!mboolisset(wlc_hw->pllreq, req_bit))
3106 return;
3107
3108 mboolclr(wlc_hw->pllreq, req_bit);
3109
3110 if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) {
3111 if (wlc_hw->sbclk)
3112 brcms_b_xtal(wlc_hw, OFF);
3113 }
3114 }
3115}
3116
3117static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail)
3118{
3119 wlc_hw->antsel_avail = antsel_avail;
3120}
3121
3122/*
3123 * conditions under which the PM bit should be set in outgoing frames
3124 * and STAY_AWAKE is meaningful
3125 */
3126static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
3127{
3128 struct brcms_bss_cfg *cfg = wlc->bsscfg;
3129
3130 /* disallow PS when one of the following global conditions meets */
3131 if (!wlc->pub->associated)
3132 return false;
3133
3134 /* disallow PS when one of these meets when not scanning */
3135 if (wlc->monitor)
3136 return false;
3137
3138 if (cfg->associated) {
3139 /*
3140 * disallow PS when one of the following
3141 * bsscfg specific conditions meets
3142 */
3143 if (!cfg->BSS)
3144 return false;
3145
3146 return false;
3147 }
3148
3149 return true;
3150}
3151
3152static void brcms_c_statsupd(struct brcms_c_info *wlc)
3153{
3154 int i;
3155 struct macstat macstats;
3156#ifdef BCMDBG
3157 u16 delta;
3158 u16 rxf0ovfl;
3159 u16 txfunfl[NFIFO];
3160#endif /* BCMDBG */
3161
3162 /* if driver down, make no sense to update stats */
3163 if (!wlc->pub->up)
3164 return;
3165
3166#ifdef BCMDBG
3167 /* save last rx fifo 0 overflow count */
3168 rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;
3169
3170 /* save last tx fifo underflow count */
3171 for (i = 0; i < NFIFO; i++)
3172 txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
3173#endif /* BCMDBG */
3174
3175 /* Read mac stats from contiguous shared memory */
3176 brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, &macstats,
3177 sizeof(struct macstat), OBJADDR_SHM_SEL);
3178
3179#ifdef BCMDBG
3180 /* check for rx fifo 0 overflow */
3181 delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
3182 if (delta)
3183 wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n",
3184 wlc->pub->unit, delta);
3185
3186 /* check for tx fifo underflows */
3187 for (i = 0; i < NFIFO; i++) {
3188 delta =
3189 (u16) (wlc->core->macstat_snapshot->txfunfl[i] -
3190 txfunfl[i]);
3191 if (delta)
3192 wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
3193 "\n", wlc->pub->unit, delta, i);
3194 }
3195#endif /* BCMDBG */
3196
3197 /* merge counters from dma module */
3198 for (i = 0; i < NFIFO; i++) {
3199 if (wlc->hw->di[i])
3200 dma_counterreset(wlc->hw->di[i]);
3201 }
3202}
3203
3204static void brcms_b_reset(struct brcms_hardware *wlc_hw)
3205{
3206 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
3207
3208 /* reset the core */
3209 if (!brcms_deviceremoved(wlc_hw->wlc))
3210 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
3211
3212 /* purge the dma rings */
3213 brcms_c_flushqueues(wlc_hw->wlc);
3214}
3215
3216void brcms_c_reset(struct brcms_c_info *wlc)
3217{
3218 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
3219
3220 /* slurp up hw mac counters before core reset */
3221 brcms_c_statsupd(wlc);
3222
3223 /* reset our snapshot of macstat counters */
3224 memset((char *)wlc->core->macstat_snapshot, 0,
3225 sizeof(struct macstat));
3226
3227 brcms_b_reset(wlc->hw);
3228}
3229
3230/* Return the channel the driver should initialize during brcms_c_init.
3231 * the channel may have to be changed from the currently configured channel
3232 * if other configurations are in conflict (bandlocked, 11n mode disabled,
3233 * invalid channel for current country, etc.)
3234 */
3235static u16 brcms_c_init_chanspec(struct brcms_c_info *wlc)
3236{
3237 u16 chanspec =
3238 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE |
3239 WL_CHANSPEC_BAND_2G;
3240
3241 return chanspec;
3242}
3243
3244void brcms_c_init_scb(struct scb *scb)
3245{
3246 int i;
3247
3248 memset(scb, 0, sizeof(struct scb));
3249 scb->flags = SCB_WMECAP | SCB_HTCAP;
3250 for (i = 0; i < NUMPRIO; i++) {
3251 scb->seqnum[i] = 0;
3252 scb->seqctl[i] = 0xFFFF;
3253 }
3254
3255 scb->seqctl_nonqos = 0xFFFF;
3256 scb->magic = SCB_MAGIC;
3257}
3258
3259/* d11 core init
3260 * reset PSM
3261 * download ucode/PCM
3262 * let ucode run to suspended
3263 * download ucode inits
3264 * config other core registers
3265 * init dma
3266 */
3267static void brcms_b_coreinit(struct brcms_c_info *wlc)
3268{
3269 struct brcms_hardware *wlc_hw = wlc->hw;
3270 struct d11regs __iomem *regs;
3271 u32 sflags;
3272 uint bcnint_us;
3273 uint i = 0;
3274 bool fifosz_fixup = false;
3275 int err = 0;
3276 u16 buf[NFIFO];
3277 struct wiphy *wiphy = wlc->wiphy;
3278 struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
3279
3280 regs = wlc_hw->regs;
3281
3282 BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
3283
3284 /* reset PSM */
3285 brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE));
3286
3287 brcms_ucode_download(wlc_hw);
3288 /*
3289 * FIFOSZ fixup. driver wants to controls the fifo allocation.
3290 */
3291 fifosz_fixup = true;
3292
3293 /* let the PSM run to the suspended state, set mode to BSS STA */
3294 W_REG(&regs->macintstatus, -1);
3295 brcms_b_mctrl(wlc_hw, ~0,
3296 (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE));
3297
3298 /* wait for ucode to self-suspend after auto-init */
3299 SPINWAIT(((R_REG(&regs->macintstatus) & MI_MACSSPNDD) == 0),
3300 1000 * 1000);
3301 if ((R_REG(&regs->macintstatus) & MI_MACSSPNDD) == 0)
3302 wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-"
3303 "suspend!\n", wlc_hw->unit);
3304
3305 brcms_c_gpio_init(wlc);
3306
3307 sflags = ai_core_sflags(wlc_hw->sih, 0, 0);
3308
3309 if (D11REV_IS(wlc_hw->corerev, 23)) {
3310 if (BRCMS_ISNPHY(wlc_hw->band))
3311 brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16);
3312 else
3313 wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
3314 " %d\n", __func__, wlc_hw->unit,
3315 wlc_hw->corerev);
3316 } else if (D11REV_IS(wlc_hw->corerev, 24)) {
3317 if (BRCMS_ISLCNPHY(wlc_hw->band))
3318 brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24);
3319 else
3320 wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
3321 " %d\n", __func__, wlc_hw->unit,
3322 wlc_hw->corerev);
3323 } else {
3324 wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
3325 __func__, wlc_hw->unit, wlc_hw->corerev);
3326 }
3327
3328 /* For old ucode, txfifo sizes needs to be modified(increased) */
3329 if (fifosz_fixup == true)
3330 brcms_b_corerev_fifofixup(wlc_hw);
3331
3332 /* check txfifo allocations match between ucode and driver */
3333 buf[TX_AC_BE_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE0);
3334 if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) {
3335 i = TX_AC_BE_FIFO;
3336 err = -1;
3337 }
3338 buf[TX_AC_VI_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE1);
3339 if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) {
3340 i = TX_AC_VI_FIFO;
3341 err = -1;
3342 }
3343 buf[TX_AC_BK_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE2);
3344 buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff;
3345 buf[TX_AC_BK_FIFO] &= 0xff;
3346 if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) {
3347 i = TX_AC_BK_FIFO;
3348 err = -1;
3349 }
3350 if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) {
3351 i = TX_AC_VO_FIFO;
3352 err = -1;
3353 }
3354 buf[TX_BCMC_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE3);
3355 buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff;
3356 buf[TX_BCMC_FIFO] &= 0xff;
3357 if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) {
3358 i = TX_BCMC_FIFO;
3359 err = -1;
3360 }
3361 if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) {
3362 i = TX_ATIM_FIFO;
3363 err = -1;
3364 }
3365 if (err != 0)
3366 wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d"
3367 " driver size %d index %d\n", buf[i],
3368 wlc_hw->xmtfifo_sz[i], i);
3369
3370 /* make sure we can still talk to the mac */
3371 WARN_ON(R_REG(&regs->maccontrol) == 0xffffffff);
3372
3373 /* band-specific inits done by wlc_bsinit() */
3374
3375 /* Set up frame burst size and antenna swap threshold init values */
3376 brcms_b_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST);
3377 brcms_b_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT);
3378
3379 /* enable one rx interrupt per received frame */
3380 W_REG(&regs->intrcvlazy[0], (1 << IRL_FC_SHIFT));
3381
3382 /* set the station mode (BSS STA) */
3383 brcms_b_mctrl(wlc_hw,
3384 (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP),
3385 (MCTL_INFRA | MCTL_DISCARD_PMQ));
3386
3387 /* set up Beacon interval */
3388 bcnint_us = 0x8000 << 10;
3389 W_REG(&regs->tsf_cfprep, (bcnint_us << CFPREP_CBI_SHIFT));
3390 W_REG(&regs->tsf_cfpstart, bcnint_us);
3391 W_REG(&regs->macintstatus, MI_GP1);
3392
3393 /* write interrupt mask */
3394 W_REG(&regs->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK);
3395
3396 /* allow the MAC to control the PHY clock (dynamic on/off) */
3397 brcms_b_macphyclk_set(wlc_hw, ON);
3398
3399 /* program dynamic clock control fast powerup delay register */
3400 wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih);
3401 W_REG(&regs->scc_fastpwrup_dly, wlc->fastpwrup_dly);
3402
3403 /* tell the ucode the corerev */
3404 brcms_b_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev);
3405
3406 /* tell the ucode MAC capabilities */
3407 brcms_b_write_shm(wlc_hw, M_MACHW_CAP_L,
3408 (u16) (wlc_hw->machwcap & 0xffff));
3409 brcms_b_write_shm(wlc_hw, M_MACHW_CAP_H,
3410 (u16) ((wlc_hw->
3411 machwcap >> 16) & 0xffff));
3412
3413 /* write retry limits to SCR, this done after PSM init */
3414 W_REG(&regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
3415 (void)R_REG(&regs->objaddr);
3416 W_REG(&regs->objdata, wlc_hw->SRL);
3417 W_REG(&regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
3418 (void)R_REG(&regs->objaddr);
3419 W_REG(&regs->objdata, wlc_hw->LRL);
3420
3421 /* write rate fallback retry limits */
3422 brcms_b_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL);
3423 brcms_b_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL);
3424
3425 AND_REG(&regs->ifs_ctl, 0x0FFF);
3426 W_REG(&regs->ifs_aifsn, EDCF_AIFSN_MIN);
3427
3428 /* init the tx dma engines */
3429 for (i = 0; i < NFIFO; i++) {
3430 if (wlc_hw->di[i])
3431 dma_txinit(wlc_hw->di[i]);
3432 }
3433
3434 /* init the rx dma engine(s) and post receive buffers */
3435 dma_rxinit(wlc_hw->di[RX_FIFO]);
3436 dma_rxfill(wlc_hw->di[RX_FIFO]);
3437}
3438
3439void
3440static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec,
3441 bool mute) {
3442 u32 macintmask;
3443 bool fastclk;
3444 struct brcms_c_info *wlc = wlc_hw->wlc;
3445
3446 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
3447
3448 /* request FAST clock if not on */
3449 fastclk = wlc_hw->forcefastclk;
3450 if (!fastclk)
3451 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
3452
3453 /* disable interrupts */
3454 macintmask = brcms_intrsoff(wlc->wl);
3455
3456 /* set up the specified band and chanspec */
3457 brcms_c_setxband(wlc_hw, chspec_bandunit(chanspec));
3458 wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
3459
3460 /* do one-time phy inits and calibration */
3461 wlc_phy_cal_init(wlc_hw->band->pi);
3462
3463 /* core-specific initialization */
3464 brcms_b_coreinit(wlc);
3465
3466 /* suspend the tx fifos and mute the phy for preism cac time */
3467 if (mute)
3468 brcms_b_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM);
3469
3470 /* band-specific inits */
3471 brcms_b_bsinit(wlc, chanspec);
3472
3473 /* restore macintmask */
3474 brcms_intrsrestore(wlc->wl, macintmask);
3475
3476 /* seed wake_override with BRCMS_WAKE_OVERRIDE_MACSUSPEND since the mac
3477 * is suspended and brcms_c_enable_mac() will clear this override bit.
3478 */
3479 mboolset(wlc_hw->wake_override, BRCMS_WAKE_OVERRIDE_MACSUSPEND);
3480
3481 /*
3482 * initialize mac_suspend_depth to 1 to match ucode
3483 * initial suspended state
3484 */
3485 wlc_hw->mac_suspend_depth = 1;
3486
3487 /* restore the clk */
3488 if (!fastclk)
3489 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
3490}
3491
3492static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc,
3493 u16 chanspec)
3494{
3495 /* Save our copy of the chanspec */
3496 wlc->chanspec = chanspec;
3497
3498 /* Set the chanspec and power limits for this locale */
3499 brcms_c_channel_set_chanspec(wlc->cmi, chanspec, BRCMS_TXPWR_MAX);
3500
3501 if (wlc->stf->ss_algosel_auto)
3502 brcms_c_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel,
3503 chanspec);
3504
3505 brcms_c_stf_ss_update(wlc, wlc->band);
3506}
3507
3508static void
3509brcms_default_rateset(struct brcms_c_info *wlc, struct brcms_c_rateset *rs)
3510{
3511 brcms_c_rateset_default(rs, NULL, wlc->band->phytype,
3512 wlc->band->bandtype, false, BRCMS_RATE_MASK_FULL,
3513 (bool) (wlc->pub->_n_enab & SUPPORT_11N),
3514 brcms_chspec_bw(wlc->default_bss->chanspec),
3515 wlc->stf->txstreams);
3516}
3517
3518/* derive wlc->band->basic_rate[] table from 'rateset' */
3519static void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
3520 struct brcms_c_rateset *rateset)
3521{
3522 u8 rate;
3523 u8 mandatory;
3524 u8 cck_basic = 0;
3525 u8 ofdm_basic = 0;
3526 u8 *br = wlc->band->basic_rate;
3527 uint i;
3528
3529 /* incoming rates are in 500kbps units as in 802.11 Supported Rates */
3530 memset(br, 0, BRCM_MAXRATE + 1);
3531
3532 /* For each basic rate in the rates list, make an entry in the
3533 * best basic lookup.
3534 */
3535 for (i = 0; i < rateset->count; i++) {
3536 /* only make an entry for a basic rate */
3537 if (!(rateset->rates[i] & BRCMS_RATE_FLAG))
3538 continue;
3539
3540 /* mask off basic bit */
3541 rate = (rateset->rates[i] & BRCMS_RATE_MASK);
3542
3543 if (rate > BRCM_MAXRATE) {
3544 wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: "
3545 "invalid rate 0x%X in rate set\n",
3546 rateset->rates[i]);
3547 continue;
3548 }
3549
3550 br[rate] = rate;
3551 }
3552
3553 /* The rate lookup table now has non-zero entries for each
3554 * basic rate, equal to the basic rate: br[basicN] = basicN
3555 *
3556 * To look up the best basic rate corresponding to any
3557 * particular rate, code can use the basic_rate table
3558 * like this
3559 *
3560 * basic_rate = wlc->band->basic_rate[tx_rate]
3561 *
3562 * Make sure there is a best basic rate entry for
3563 * every rate by walking up the table from low rates
3564 * to high, filling in holes in the lookup table
3565 */
3566
3567 for (i = 0; i < wlc->band->hw_rateset.count; i++) {
3568 rate = wlc->band->hw_rateset.rates[i];
3569
3570 if (br[rate] != 0) {
3571 /* This rate is a basic rate.
3572 * Keep track of the best basic rate so far by
3573 * modulation type.
3574 */
3575 if (is_ofdm_rate(rate))
3576 ofdm_basic = rate;
3577 else
3578 cck_basic = rate;
3579
3580 continue;
3581 }
3582
3583 /* This rate is not a basic rate so figure out the
3584 * best basic rate less than this rate and fill in
3585 * the hole in the table
3586 */
3587
3588 br[rate] = is_ofdm_rate(rate) ? ofdm_basic : cck_basic;
3589
3590 if (br[rate] != 0)
3591 continue;
3592
3593 if (is_ofdm_rate(rate)) {
3594 /*
3595 * In 11g and 11a, the OFDM mandatory rates
3596 * are 6, 12, and 24 Mbps
3597 */
3598 if (rate >= BRCM_RATE_24M)
3599 mandatory = BRCM_RATE_24M;
3600 else if (rate >= BRCM_RATE_12M)
3601 mandatory = BRCM_RATE_12M;
3602 else
3603 mandatory = BRCM_RATE_6M;
3604 } else {
3605 /* In 11b, all CCK rates are mandatory 1 - 11 Mbps */
3606 mandatory = rate;
3607 }
3608
3609 br[rate] = mandatory;
3610 }
3611}
3612
3613static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
3614 u16 chanspec)
3615{
3616 struct brcms_c_rateset default_rateset;
3617 uint parkband;
3618 uint i, band_order[2];
3619
3620 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
3621 /*
3622 * We might have been bandlocked during down and the chip
3623 * power-cycled (hibernate). Figure out the right band to park on
3624 */
3625 if (wlc->bandlocked || wlc->pub->_nbands == 1) {
3626 /* updated in brcms_c_bandlock() */
3627 parkband = wlc->band->bandunit;
3628 band_order[0] = band_order[1] = parkband;
3629 } else {
3630 /* park on the band of the specified chanspec */
3631 parkband = chspec_bandunit(chanspec);
3632
3633 /* order so that parkband initialize last */
3634 band_order[0] = parkband ^ 1;
3635 band_order[1] = parkband;
3636 }
3637
3638 /* make each band operational, software state init */
3639 for (i = 0; i < wlc->pub->_nbands; i++) {
3640 uint j = band_order[i];
3641
3642 wlc->band = wlc->bandstate[j];
3643
3644 brcms_default_rateset(wlc, &default_rateset);
3645
3646 /* fill in hw_rate */
3647 brcms_c_rateset_filter(&default_rateset, &wlc->band->hw_rateset,
3648 false, BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
3649 (bool) (wlc->pub->_n_enab & SUPPORT_11N));
3650
3651 /* init basic rate lookup */
3652 brcms_c_rate_lookup_init(wlc, &default_rateset);
3653 }
3654
3655 /* sync up phy/radio chanspec */
3656 brcms_c_set_phy_chanspec(wlc, chanspec);
3657}
3658
3659static void brcms_c_mac_bcn_promisc(struct brcms_c_info *wlc)
3660{
3661 if (wlc->bcnmisc_monitor)
3662 brcms_b_mctrl(wlc->hw, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC);
3663 else
3664 brcms_b_mctrl(wlc->hw, MCTL_BCNS_PROMISC, 0);
3665}
3666
3667void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, bool promisc)
3668{
3669 wlc->bcnmisc_monitor = promisc;
3670 brcms_c_mac_bcn_promisc(wlc);
3671}
3672
3673/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */
3674static void brcms_c_mac_promisc(struct brcms_c_info *wlc)
3675{
3676 u32 promisc_bits = 0;
3677
3678 /*
3679 * promiscuous mode just sets MCTL_PROMISC
3680 * Note: APs get all BSS traffic without the need to set
3681 * the MCTL_PROMISC bit since all BSS data traffic is
3682 * directed at the AP
3683 */
3684 if (wlc->pub->promisc)
3685 promisc_bits |= MCTL_PROMISC;
3686
3687 /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL
3688 * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is
3689 * handled in brcms_c_mac_bcn_promisc()
3690 */
3691 if (wlc->monitor)
3692 promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL;
3693
3694 brcms_b_mctrl(wlc->hw, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits);
3695}
3696
3697/*
3698 * ucode, hwmac update
3699 * Channel dependent updates for ucode and hw
3700 */
3701static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc)
3702{
3703 /* enable or disable any active IBSSs depending on whether or not
3704 * we are on the home channel
3705 */
3706 if (wlc->home_chanspec == wlc_phy_chanspec_get(wlc->band->pi)) {
3707 if (wlc->pub->associated) {
3708 /*
3709 * BMAC_NOTE: This is something that should be fixed
3710 * in ucode inits. I think that the ucode inits set
3711 * up the bcn templates and shm values with a bogus
3712 * beacon. This should not be done in the inits. If
3713 * ucode needs to set up a beacon for testing, the
3714 * test routines should write it down, not expect the
3715 * inits to populate a bogus beacon.
3716 */
3717 if (BRCMS_PHY_11N_CAP(wlc->band))
3718 brcms_b_write_shm(wlc->hw,
3719 M_BCN_TXTSF_OFFSET, 0);
3720 }
3721 } else {
3722 /* disable an active IBSS if we are not on the home channel */
3723 }
3724
3725 /* update the various promisc bits */
3726 brcms_c_mac_bcn_promisc(wlc);
3727 brcms_c_mac_promisc(wlc);
3728}
3729
3730static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate,
3731 u8 basic_rate)
3732{
3733 u8 phy_rate, index;
3734 u8 basic_phy_rate, basic_index;
3735 u16 dir_table, basic_table;
3736 u16 basic_ptr;
3737
3738 /* Shared memory address for the table we are reading */
3739 dir_table = is_ofdm_rate(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B;
3740
3741 /* Shared memory address for the table we are writing */
3742 basic_table = is_ofdm_rate(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B;
3743
3744 /*
3745 * for a given rate, the LS-nibble of the PLCP SIGNAL field is
3746 * the index into the rate table.
3747 */
3748 phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
3749 basic_phy_rate = rate_info[basic_rate] & BRCMS_RATE_MASK;
3750 index = phy_rate & 0xf;
3751 basic_index = basic_phy_rate & 0xf;
3752
3753 /* Find the SHM pointer to the ACK rate entry by looking in the
3754 * Direct-map Table
3755 */
3756 basic_ptr = brcms_b_read_shm(wlc->hw, (dir_table + basic_index * 2));
3757
3758 /* Update the SHM BSS-basic-rate-set mapping table with the pointer
3759 * to the correct basic rate for the given incoming rate
3760 */
3761 brcms_b_write_shm(wlc->hw, (basic_table + index * 2), basic_ptr);
3762}
3763
3764static const struct brcms_c_rateset *
3765brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc)
3766{
3767 const struct brcms_c_rateset *rs_dflt;
3768
3769 if (BRCMS_PHY_11N_CAP(wlc->band)) {
3770 if (wlc->band->bandtype == BRCM_BAND_5G)
3771 rs_dflt = &ofdm_mimo_rates;
3772 else
3773 rs_dflt = &cck_ofdm_mimo_rates;
3774 } else if (wlc->band->gmode)
3775 rs_dflt = &cck_ofdm_rates;
3776 else
3777 rs_dflt = &cck_rates;
3778
3779 return rs_dflt;
3780}
3781
3782static void brcms_c_set_ratetable(struct brcms_c_info *wlc)
3783{
3784 const struct brcms_c_rateset *rs_dflt;
3785 struct brcms_c_rateset rs;
3786 u8 rate, basic_rate;
3787 uint i;
3788
3789 rs_dflt = brcms_c_rateset_get_hwrs(wlc);
3790
3791 brcms_c_rateset_copy(rs_dflt, &rs);
3792 brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
3793
3794 /* walk the phy rate table and update SHM basic rate lookup table */
3795 for (i = 0; i < rs.count; i++) {
3796 rate = rs.rates[i] & BRCMS_RATE_MASK;
3797
3798 /* for a given rate brcms_basic_rate returns the rate at
3799 * which a response ACK/CTS should be sent.
3800 */
3801 basic_rate = brcms_basic_rate(wlc, rate);
3802 if (basic_rate == 0)
3803 /* This should only happen if we are using a
3804 * restricted rateset.
3805 */
3806 basic_rate = rs.rates[0] & BRCMS_RATE_MASK;
3807
3808 brcms_c_write_rate_shm(wlc, rate, basic_rate);
3809 }
3810}
3811
3812/* band-specific init */
3813static void brcms_c_bsinit(struct brcms_c_info *wlc)
3814{
3815 BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n",
3816 wlc->pub->unit, wlc->band->bandunit);
3817
3818 /* write ucode ACK/CTS rate table */
3819 brcms_c_set_ratetable(wlc);
3820
3821 /* update some band specific mac configuration */
3822 brcms_c_ucode_mac_upd(wlc);
3823
3824 /* init antenna selection */
3825 brcms_c_antsel_init(wlc->asi);
3826
3827}
3828
3829/* formula: IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */
3830static int
3831brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
3832 bool writeToShm)
3833{
3834 int idle_busy_ratio_x_16 = 0;
3835 uint offset =
3836 isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
3837 M_TX_IDLE_BUSY_RATIO_X_16_CCK;
3838 if (duty_cycle > 100 || duty_cycle < 0) {
3839 wiphy_err(wlc->wiphy, "wl%d: duty cycle value off limit\n",
3840 wlc->pub->unit);
3841 return -EINVAL;
3842 }
3843 if (duty_cycle)
3844 idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle;
3845 /* Only write to shared memory when wl is up */
3846 if (writeToShm)
3847 brcms_b_write_shm(wlc->hw, offset, (u16) idle_busy_ratio_x_16);
3848
3849 if (isOFDM)
3850 wlc->tx_duty_cycle_ofdm = (u16) duty_cycle;
3851 else
3852 wlc->tx_duty_cycle_cck = (u16) duty_cycle;
3853
3854 return 0;
3855}
3856
3857/*
3858 * Initialize the base precedence map for dequeueing
3859 * from txq based on WME settings
3860 */
3861static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc)
3862{
3863 wlc->tx_prec_map = BRCMS_PREC_BMP_ALL;
3864 memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16));
3865
3866 wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK;
3867 wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE;
3868 wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI;
3869 wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO;
3870}
3871
3872static void
3873brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc,
3874 struct brcms_txq_info *qi, bool on, int prio)
3875{
3876 /* transmit flowcontrol is not yet implemented */
3877}
3878
3879static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc)
3880{
3881 struct brcms_txq_info *qi;
3882
3883 for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
3884 if (qi->stopped) {
3885 brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
3886 qi->stopped = 0;
3887 }
3888 }
3889}
3890
3891/* push sw hps and wake state through hardware */
3892static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
3893{
3894 u32 v1, v2;
3895 bool hps;
3896 bool awake_before;
3897
3898 hps = brcms_c_ps_allowed(wlc);
3899
3900 BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps);
3901
3902 v1 = R_REG(&wlc->regs->maccontrol);
3903 v2 = MCTL_WAKE;
3904 if (hps)
3905 v2 |= MCTL_HPS;
3906
3907 brcms_b_mctrl(wlc->hw, MCTL_WAKE | MCTL_HPS, v2);
3908
3909 awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));
3910
3911 if (!awake_before)
3912 brcms_b_wait_for_wake(wlc->hw);
3913}
3914
3915/*
3916 * Write this BSS config's MAC address to core.
3917 * Updates RXE match engine.
3918 */
3919static int brcms_c_set_mac(struct brcms_bss_cfg *bsscfg)
3920{
3921 int err = 0;
3922 struct brcms_c_info *wlc = bsscfg->wlc;
3923
3924 /* enter the MAC addr into the RXE match registers */
3925 brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, bsscfg->cur_etheraddr);
3926
3927 brcms_c_ampdu_macaddr_upd(wlc);
3928
3929 return err;
3930}
3931
3932/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
3933 * Updates RXE match engine.
3934 */
3935static void brcms_c_set_bssid(struct brcms_bss_cfg *bsscfg)
3936{
3937 /* we need to update BSSID in RXE match registers */
3938 brcms_c_set_addrmatch(bsscfg->wlc, RCM_BSSID_OFFSET, bsscfg->BSSID);
3939}
3940
3941static void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot)
3942{
3943 wlc_hw->shortslot = shortslot;
3944
3945 if (wlc_hw->band->bandtype == BRCM_BAND_2G && wlc_hw->up) {
3946 brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
3947 brcms_b_update_slot_timing(wlc_hw, shortslot);
3948 brcms_c_enable_mac(wlc_hw->wlc);
3949 }
3950}
3951
3952/*
3953 * Suspend the the MAC and update the slot timing
3954 * for standard 11b/g (20us slots) or shortslot 11g (9us slots).
3955 */
3956static void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot)
3957{
3958 /* use the override if it is set */
3959 if (wlc->shortslot_override != BRCMS_SHORTSLOT_AUTO)
3960 shortslot = (wlc->shortslot_override == BRCMS_SHORTSLOT_ON);
3961
3962 if (wlc->shortslot == shortslot)
3963 return;
3964
3965 wlc->shortslot = shortslot;
3966
3967 brcms_b_set_shortslot(wlc->hw, shortslot);
3968}
3969
3970static void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec)
3971{
3972 if (wlc->home_chanspec != chanspec) {
3973 wlc->home_chanspec = chanspec;
3974
3975 if (wlc->bsscfg->associated)
3976 wlc->bsscfg->current_bss->chanspec = chanspec;
3977 }
3978}
3979
3980void
3981brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec,
3982 bool mute, struct txpwr_limits *txpwr)
3983{
3984 uint bandunit;
3985
3986 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec);
3987
3988 wlc_hw->chanspec = chanspec;
3989
3990 /* Switch bands if necessary */
3991 if (wlc_hw->_nbands > 1) {
3992 bandunit = chspec_bandunit(chanspec);
3993 if (wlc_hw->band->bandunit != bandunit) {
3994 /* brcms_b_setband disables other bandunit,
3995 * use light band switch if not up yet
3996 */
3997 if (wlc_hw->up) {
3998 wlc_phy_chanspec_radio_set(wlc_hw->
3999 bandstate[bandunit]->
4000 pi, chanspec);
4001 brcms_b_setband(wlc_hw, bandunit, chanspec);
4002 } else {
4003 brcms_c_setxband(wlc_hw, bandunit);
4004 }
4005 }
4006 }
4007
4008 wlc_phy_initcal_enable(wlc_hw->band->pi, !mute);
4009
4010 if (!wlc_hw->up) {
4011 if (wlc_hw->clk)
4012 wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr,
4013 chanspec);
4014 wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
4015 } else {
4016 wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec);
4017 wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec);
4018
4019 /* Update muting of the channel */
4020 brcms_b_mute(wlc_hw, mute, 0);
4021 }
4022}
4023
4024/* switch to and initialize new band */
4025static void brcms_c_setband(struct brcms_c_info *wlc,
4026 uint bandunit)
4027{
4028 wlc->band = wlc->bandstate[bandunit];
4029
4030 if (!wlc->pub->up)
4031 return;
4032
4033 /* wait for at least one beacon before entering sleeping state */
4034 brcms_c_set_ps_ctrl(wlc);
4035
4036 /* band-specific initializations */
4037 brcms_c_bsinit(wlc);
4038}
4039
4040static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec)
4041{
4042 uint bandunit;
4043 bool switchband = false;
4044 u16 old_chanspec = wlc->chanspec;
4045
4046 if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) {
4047 wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n",
4048 wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
4049 return;
4050 }
4051
4052 /* Switch bands if necessary */
4053 if (wlc->pub->_nbands > 1) {
4054 bandunit = chspec_bandunit(chanspec);
4055 if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
4056 switchband = true;
4057 if (wlc->bandlocked) {
4058 wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d "
4059 "band is locked!\n",
4060 wlc->pub->unit, __func__,
4061 CHSPEC_CHANNEL(chanspec));
4062 return;
4063 }
4064 /*
4065 * should the setband call come after the
4066 * brcms_b_chanspec() ? if the setband updates
4067 * (brcms_c_bsinit) use low level calls to inspect and
4068 * set state, the state inspected may be from the wrong
4069 * band, or the following brcms_b_set_chanspec() may
4070 * undo the work.
4071 */
4072 brcms_c_setband(wlc, bandunit);
4073 }
4074 }
4075
4076 /* sync up phy/radio chanspec */
4077 brcms_c_set_phy_chanspec(wlc, chanspec);
4078
4079 /* init antenna selection */
4080 if (brcms_chspec_bw(old_chanspec) != brcms_chspec_bw(chanspec)) {
4081 brcms_c_antsel_init(wlc->asi);
4082
4083 /* Fix the hardware rateset based on bw.
4084 * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz
4085 */
4086 brcms_c_rateset_bw_mcs_filter(&wlc->band->hw_rateset,
4087 wlc->band->mimo_cap_40 ? brcms_chspec_bw(chanspec) : 0);
4088 }
4089
4090 /* update some mac configuration since chanspec changed */
4091 brcms_c_ucode_mac_upd(wlc);
4092}
4093
4094/*
4095 * This function changes the phytxctl for beacon based on current
4096 * beacon ratespec AND txant setting as per this table:
4097 * ratespec CCK ant = wlc->stf->txant
4098 * OFDM ant = 3
4099 */
4100void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
4101 u32 bcn_rspec)
4102{
4103 u16 phyctl;
4104 u16 phytxant = wlc->stf->phytxant;
4105 u16 mask = PHY_TXC_ANT_MASK;
4106
4107 /* for non-siso rates or default setting, use the available chains */
4108 if (BRCMS_PHY_11N_CAP(wlc->band))
4109 phytxant = brcms_c_stf_phytxchain_sel(wlc, bcn_rspec);
4110
4111 phyctl = brcms_b_read_shm(wlc->hw, M_BCN_PCTLWD);
4112 phyctl = (phyctl & ~mask) | phytxant;
4113 brcms_b_write_shm(wlc->hw, M_BCN_PCTLWD, phyctl);
4114}
4115
4116/*
4117 * centralized protection config change function to simplify debugging, no
4118 * consistency checking this should be called only on changes to avoid overhead
4119 * in periodic function
4120 */
4121void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val)
4122{
4123 BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val);
4124
4125 switch (idx) {
4126 case BRCMS_PROT_G_SPEC:
4127 wlc->protection->_g = (bool) val;
4128 break;
4129 case BRCMS_PROT_G_OVR:
4130 wlc->protection->g_override = (s8) val;
4131 break;
4132 case BRCMS_PROT_G_USER:
4133 wlc->protection->gmode_user = (u8) val;
4134 break;
4135 case BRCMS_PROT_OVERLAP:
4136 wlc->protection->overlap = (s8) val;
4137 break;
4138 case BRCMS_PROT_N_USER:
4139 wlc->protection->nmode_user = (s8) val;
4140 break;
4141 case BRCMS_PROT_N_CFG:
4142 wlc->protection->n_cfg = (s8) val;
4143 break;
4144 case BRCMS_PROT_N_CFG_OVR:
4145 wlc->protection->n_cfg_override = (s8) val;
4146 break;
4147 case BRCMS_PROT_N_NONGF:
4148 wlc->protection->nongf = (bool) val;
4149 break;
4150 case BRCMS_PROT_N_NONGF_OVR:
4151 wlc->protection->nongf_override = (s8) val;
4152 break;
4153 case BRCMS_PROT_N_PAM_OVR:
4154 wlc->protection->n_pam_override = (s8) val;
4155 break;
4156 case BRCMS_PROT_N_OBSS:
4157 wlc->protection->n_obss = (bool) val;
4158 break;
4159
4160 default:
4161 break;
4162 }
4163
4164}
4165
4166static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val)
4167{
4168 if (wlc->pub->up) {
4169 brcms_c_update_beacon(wlc);
4170 brcms_c_update_probe_resp(wlc, true);
4171 }
4172}
4173
4174static void brcms_c_ht_update_ldpc(struct brcms_c_info *wlc, s8 val)
4175{
4176 wlc->stf->ldpc = val;
4177
4178 if (wlc->pub->up) {
4179 brcms_c_update_beacon(wlc);
4180 brcms_c_update_probe_resp(wlc, true);
4181 wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false));
4182 }
4183}
4184
4185void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
4186 const struct ieee80211_tx_queue_params *params,
4187 bool suspend)
4188{
4189 int i;
4190 struct shm_acparams acp_shm;
4191 u16 *shm_entry;
4192
4193 /* Only apply params if the core is out of reset and has clocks */
4194 if (!wlc->clk) {
4195 wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit,
4196 __func__);
4197 return;
4198 }
4199
4200 memset((char *)&acp_shm, 0, sizeof(struct shm_acparams));
4201 /* fill in shm ac params struct */
4202 acp_shm.txop = params->txop;
4203 /* convert from units of 32us to us for ucode */
4204 wlc->edcf_txop[aci & 0x3] = acp_shm.txop =
4205 EDCF_TXOP2USEC(acp_shm.txop);
4206 acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK);
4207
4208 if (aci == AC_VI && acp_shm.txop == 0
4209 && acp_shm.aifs < EDCF_AIFSN_MAX)
4210 acp_shm.aifs++;
4211
4212 if (acp_shm.aifs < EDCF_AIFSN_MIN
4213 || acp_shm.aifs > EDCF_AIFSN_MAX) {
4214 wiphy_err(wlc->wiphy, "wl%d: edcf_setparams: bad "
4215 "aifs %d\n", wlc->pub->unit, acp_shm.aifs);
4216 } else {
4217 acp_shm.cwmin = params->cw_min;
4218 acp_shm.cwmax = params->cw_max;
4219 acp_shm.cwcur = acp_shm.cwmin;
4220 acp_shm.bslots =
4221 R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur;
4222 acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
4223 /* Indicate the new params to the ucode */
4224 acp_shm.status = brcms_b_read_shm(wlc->hw, (M_EDCF_QINFO +
4225 wme_ac2fifo[aci] *
4226 M_EDCF_QLEN +
4227 M_EDCF_STATUS_OFF));
4228 acp_shm.status |= WME_STATUS_NEWAC;
4229
4230 /* Fill in shm acparam table */
4231 shm_entry = (u16 *) &acp_shm;
4232 for (i = 0; i < (int)sizeof(struct shm_acparams); i += 2)
4233 brcms_b_write_shm(wlc->hw,
4234 M_EDCF_QINFO +
4235 wme_ac2fifo[aci] * M_EDCF_QLEN + i,
4236 *shm_entry++);
4237 }
4238
4239 if (suspend) {
4240 brcms_c_suspend_mac_and_wait(wlc);
4241 brcms_c_enable_mac(wlc);
4242 }
4243}
4244
4245void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend)
4246{
4247 u16 aci;
4248 int i_ac;
4249 struct ieee80211_tx_queue_params txq_pars;
4250 static const struct edcf_acparam default_edcf_acparams[] = {
4251 {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA, EDCF_AC_BE_TXOP_STA},
4252 {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA, EDCF_AC_BK_TXOP_STA},
4253 {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA, EDCF_AC_VI_TXOP_STA},
4254 {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA, EDCF_AC_VO_TXOP_STA}
4255 }; /* ucode needs these parameters during its initialization */
4256 const struct edcf_acparam *edcf_acp = &default_edcf_acparams[0];
4257
4258 for (i_ac = 0; i_ac < AC_COUNT; i_ac++, edcf_acp++) {
4259 /* find out which ac this set of params applies to */
4260 aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT;
4261
4262 /* fill in shm ac params struct */
4263 txq_pars.txop = edcf_acp->TXOP;
4264 txq_pars.aifs = edcf_acp->ACI;
4265
4266 /* CWmin = 2^(ECWmin) - 1 */
4267 txq_pars.cw_min = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK);
4268 /* CWmax = 2^(ECWmax) - 1 */
4269 txq_pars.cw_max = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK)
4270 >> EDCF_ECWMAX_SHIFT);
4271 brcms_c_wme_setparams(wlc, aci, &txq_pars, suspend);
4272 }
4273
4274 if (suspend) {
4275 brcms_c_suspend_mac_and_wait(wlc);
4276 brcms_c_enable_mac(wlc);
4277 }
4278}
4279
4280/* maintain LED behavior in down state */
4281static void brcms_c_down_led_upd(struct brcms_c_info *wlc)
4282{
4283 /*
4284 * maintain LEDs while in down state, turn on sbclk if
4285 * not available yet. Turn on sbclk if necessary
4286 */
4287 brcms_b_pllreq(wlc->hw, true, BRCMS_PLLREQ_FLIP);
4288 brcms_b_pllreq(wlc->hw, false, BRCMS_PLLREQ_FLIP);
4289}
4290
4291static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc)
4292{
4293 /* Don't start the timer if HWRADIO feature is disabled */
4294 if (wlc->radio_monitor)
4295 return;
4296
4297 wlc->radio_monitor = true;
4298 brcms_b_pllreq(wlc->hw, true, BRCMS_PLLREQ_RADIO_MON);
4299 brcms_add_timer(wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true);
4300}
4301
4302static void brcms_c_radio_disable(struct brcms_c_info *wlc)
4303{
4304 if (!wlc->pub->up) {
4305 brcms_c_down_led_upd(wlc);
4306 return;
4307 }
4308
4309 brcms_c_radio_monitor_start(wlc);
4310 brcms_down(wlc->wl);
4311}
4312
4313static void brcms_c_radio_enable(struct brcms_c_info *wlc)
4314{
4315 if (wlc->pub->up)
4316 return;
4317
4318 if (brcms_deviceremoved(wlc))
4319 return;
4320
4321 brcms_up(wlc->wl);
4322}
4323
4324static bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc)
4325{
4326 if (!wlc->radio_monitor)
4327 return true;
4328
4329 wlc->radio_monitor = false;
4330 brcms_b_pllreq(wlc->hw, false, BRCMS_PLLREQ_RADIO_MON);
4331 return brcms_del_timer(wlc->radio_timer);
4332}
4333
4334/* read hwdisable state and propagate to wlc flag */
4335static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc)
4336{
4337 if (wlc->pub->hw_off)
4338 return;
4339
4340 if (brcms_b_radio_read_hwdisabled(wlc->hw))
4341 mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
4342 else
4343 mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
4344}
4345
4346/*
4347 * centralized radio disable/enable function,
4348 * invoke radio enable/disable after updating hwradio status
4349 */
4350static void brcms_c_radio_upd(struct brcms_c_info *wlc)
4351{
4352 if (wlc->pub->radio_disabled)
4353 brcms_c_radio_disable(wlc);
4354 else
4355 brcms_c_radio_enable(wlc);
4356}
4357
4358/* update hwradio status and return it */
4359bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc)
4360{
4361 brcms_c_radio_hwdisable_upd(wlc);
4362
4363 return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ?
4364 true : false;
4365}
4366
4367/* periodical query hw radio button while driver is "down" */
4368static void brcms_c_radio_timer(void *arg)
4369{
4370 struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
4371
4372 if (brcms_deviceremoved(wlc)) {
4373 wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
4374 __func__);
4375 brcms_down(wlc->wl);
4376 return;
4377 }
4378
4379 /* cap mpc off count */
4380 if (wlc->mpc_offcnt < BRCMS_MPC_MAX_DELAYCNT)
4381 wlc->mpc_offcnt++;
4382
4383 brcms_c_radio_hwdisable_upd(wlc);
4384 brcms_c_radio_upd(wlc);
4385}
4386
4387/* common low-level watchdog code */
4388static void brcms_b_watchdog(void *arg)
4389{
4390 struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
4391 struct brcms_hardware *wlc_hw = wlc->hw;
4392
4393 BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
4394
4395 if (!wlc_hw->up)
4396 return;
4397
4398 /* increment second count */
4399 wlc_hw->now++;
4400
4401 /* Check for FIFO error interrupts */
4402 brcms_b_fifoerrors(wlc_hw);
4403
4404 /* make sure RX dma has buffers */
4405 dma_rxfill(wlc->hw->di[RX_FIFO]);
4406
4407 wlc_phy_watchdog(wlc_hw->band->pi);
4408}
4409
4410static void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc)
4411{
4412 bool mpc_radio, radio_state;
4413
4414 /*
4415 * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled
4416 * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio
4417 * monitor also when WL_RADIO_MPC_DISABLE is the only reason that
4418 * the radio is going down.
4419 */
4420 if (!wlc->mpc) {
4421 if (!wlc->pub->radio_disabled)
4422 return;
4423 mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
4424 brcms_c_radio_upd(wlc);
4425 if (!wlc->pub->radio_disabled)
4426 brcms_c_radio_monitor_stop(wlc);
4427 return;
4428 }
4429
4430 /*
4431 * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in
4432 * wlc->pub->radio_disabled to go ON, always call radio_upd
4433 * synchronously to go OFF, postpone radio_upd to later when
4434 * context is safe(e.g. watchdog)
4435 */
4436 radio_state =
4437 (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF :
4438 ON);
4439 mpc_radio = (brcms_c_ismpc(wlc) == true) ? OFF : ON;
4440
4441 if (radio_state == ON && mpc_radio == OFF)
4442 wlc->mpc_delay_off = wlc->mpc_dlycnt;
4443 else if (radio_state == OFF && mpc_radio == ON) {
4444 mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
4445 brcms_c_radio_upd(wlc);
4446 if (wlc->mpc_offcnt < BRCMS_MPC_THRESHOLD)
4447 wlc->mpc_dlycnt = BRCMS_MPC_MAX_DELAYCNT;
4448 else
4449 wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
4450 }
4451 /*
4452 * Below logic is meant to capture the transition from mpc off
4453 * to mpc on for reasons other than wlc->mpc_delay_off keeping
4454 * the mpc off. In that case reset wlc->mpc_delay_off to
4455 * wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off
4456 */
4457 if ((wlc->prev_non_delay_mpc == false) &&
4458 (brcms_c_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off)
4459 wlc->mpc_delay_off = wlc->mpc_dlycnt;
4460
4461 wlc->prev_non_delay_mpc = brcms_c_is_non_delay_mpc(wlc);
4462}
4463
4464/* common watchdog code */
4465static void brcms_c_watchdog(void *arg)
4466{
4467 struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
4468
4469 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
4470
4471 if (!wlc->pub->up)
4472 return;
4473
4474 if (brcms_deviceremoved(wlc)) {
4475 wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
4476 __func__);
4477 brcms_down(wlc->wl);
4478 return;
4479 }
4480
4481 /* increment second count */
4482 wlc->pub->now++;
4483
4484 /* delay radio disable */
4485 if (wlc->mpc_delay_off) {
4486 if (--wlc->mpc_delay_off == 0) {
4487 mboolset(wlc->pub->radio_disabled,
4488 WL_RADIO_MPC_DISABLE);
4489 if (wlc->mpc && brcms_c_ismpc(wlc))
4490 wlc->mpc_offcnt = 0;
4491 }
4492 }
4493
4494 /* mpc sync */
4495 brcms_c_radio_mpc_upd(wlc);
4496 /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */
4497 brcms_c_radio_hwdisable_upd(wlc);
4498 brcms_c_radio_upd(wlc);
4499 /* if radio is disable, driver may be down, quit here */
4500 if (wlc->pub->radio_disabled)
4501 return;
4502
4503 brcms_b_watchdog(wlc);
4504
4505 /*
4506 * occasionally sample mac stat counters to
4507 * detect 16-bit counter wrap
4508 */
4509 if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0)
4510 brcms_c_statsupd(wlc);
4511
4512 if (BRCMS_ISNPHY(wlc->band) &&
4513 ((wlc->pub->now - wlc->tempsense_lasttime) >=
4514 BRCMS_TEMPSENSE_PERIOD)) {
4515 wlc->tempsense_lasttime = wlc->pub->now;
4516 brcms_c_tempsense_upd(wlc);
4517 }
4518}
4519
4520static void brcms_c_watchdog_by_timer(void *arg)
4521{
4522 brcms_c_watchdog(arg);
4523}
4524
4525static bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit)
4526{
4527 wlc->wdtimer = brcms_init_timer(wlc->wl, brcms_c_watchdog_by_timer,
4528 wlc, "watchdog");
4529 if (!wlc->wdtimer) {
4530 wiphy_err(wlc->wiphy, "wl%d: wl_init_timer for wdtimer "
4531 "failed\n", unit);
4532 goto fail;
4533 }
4534
4535 wlc->radio_timer = brcms_init_timer(wlc->wl, brcms_c_radio_timer,
4536 wlc, "radio");
4537 if (!wlc->radio_timer) {
4538 wiphy_err(wlc->wiphy, "wl%d: wl_init_timer for radio_timer "
4539 "failed\n", unit);
4540 goto fail;
4541 }
4542
4543 return true;
4544
4545 fail:
4546 return false;
4547}
4548
4549/*
4550 * Initialize brcms_c_info default values ...
4551 * may get overrides later in this function
4552 */
4553static void brcms_c_info_init(struct brcms_c_info *wlc, int unit)
4554{
4555 int i;
4556
4557 /* Save our copy of the chanspec */
4558 wlc->chanspec = ch20mhz_chspec(1);
4559
4560 /* various 802.11g modes */
4561 wlc->shortslot = false;
4562 wlc->shortslot_override = BRCMS_SHORTSLOT_AUTO;
4563
4564 brcms_c_protection_upd(wlc, BRCMS_PROT_G_OVR, BRCMS_PROTECTION_AUTO);
4565 brcms_c_protection_upd(wlc, BRCMS_PROT_G_SPEC, false);
4566
4567 brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG_OVR,
4568 BRCMS_PROTECTION_AUTO);
4569 brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG, BRCMS_N_PROTECTION_OFF);
4570 brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF_OVR,
4571 BRCMS_PROTECTION_AUTO);
4572 brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF, false);
4573 brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, AUTO);
4574
4575 brcms_c_protection_upd(wlc, BRCMS_PROT_OVERLAP,
4576 BRCMS_PROTECTION_CTL_OVERLAP);
4577
4578 /* 802.11g draft 4.0 NonERP elt advertisement */
4579 wlc->include_legacy_erp = true;
4580
4581 wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF;
4582 wlc->stf->txant = ANT_TX_DEF;
4583
4584 wlc->prb_resp_timeout = BRCMS_PRB_RESP_TIMEOUT;
4585
4586 wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN;
4587 for (i = 0; i < NFIFO; i++)
4588 wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN;
4589 wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN;
4590
4591 /* default rate fallback retry limits */
4592 wlc->SFBL = RETRY_SHORT_FB;
4593 wlc->LFBL = RETRY_LONG_FB;
4594
4595 /* default mac retry limits */
4596 wlc->SRL = RETRY_SHORT_DEF;
4597 wlc->LRL = RETRY_LONG_DEF;
4598
4599 /* WME QoS mode is Auto by default */
4600 wlc->pub->_ampdu = AMPDU_AGG_HOST;
4601 wlc->pub->bcmerror = 0;
4602
4603 /* initialize mpc delay */
4604 wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
4605}
4606
4607static uint brcms_c_attach_module(struct brcms_c_info *wlc)
4608{
4609 uint err = 0;
4610 uint unit;
4611 unit = wlc->pub->unit;
4612
4613 wlc->asi = brcms_c_antsel_attach(wlc);
4614 if (wlc->asi == NULL) {
4615 wiphy_err(wlc->wiphy, "wl%d: attach: antsel_attach "
4616 "failed\n", unit);
4617 err = 44;
4618 goto fail;
4619 }
4620
4621 wlc->ampdu = brcms_c_ampdu_attach(wlc);
4622 if (wlc->ampdu == NULL) {
4623 wiphy_err(wlc->wiphy, "wl%d: attach: ampdu_attach "
4624 "failed\n", unit);
4625 err = 50;
4626 goto fail;
4627 }
4628
4629 if ((brcms_c_stf_attach(wlc) != 0)) {
4630 wiphy_err(wlc->wiphy, "wl%d: attach: stf_attach "
4631 "failed\n", unit);
4632 err = 68;
4633 goto fail;
4634 }
4635 fail:
4636 return err;
4637}
4638
4639struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc)
4640{
4641 return wlc->pub;
4642}
4643
4644/* low level attach
4645 * run backplane attach, init nvram
4646 * run phy attach
4647 * initialize software state for each core and band
4648 * put the whole chip in reset(driver down state), no clock
4649 */
4650static int brcms_b_attach(struct brcms_c_info *wlc, u16 vendor, u16 device,
4651 uint unit, bool piomode, void __iomem *regsva,
4652 struct pci_dev *btparam)
4653{
4654 struct brcms_hardware *wlc_hw;
4655 struct d11regs __iomem *regs;
4656 char *macaddr = NULL;
4657 uint err = 0;
4658 uint j;
4659 bool wme = false;
4660 struct shared_phy_params sha_params;
4661 struct wiphy *wiphy = wlc->wiphy;
4662
4663 BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, vendor,
4664 device);
4665
4666 wme = true;
4667
4668 wlc_hw = wlc->hw;
4669 wlc_hw->wlc = wlc;
4670 wlc_hw->unit = unit;
4671 wlc_hw->band = wlc_hw->bandstate[0];
4672 wlc_hw->_piomode = piomode;
4673
4674 /* populate struct brcms_hardware with default values */
4675 brcms_b_info_init(wlc_hw);
4676
4677 /*
4678 * Do the hardware portion of the attach. Also initialize software
4679 * state that depends on the particular hardware we are running.
4680 */
4681 wlc_hw->sih = ai_attach(regsva, btparam);
4682 if (wlc_hw->sih == NULL) {
4683 wiphy_err(wiphy, "wl%d: brcms_b_attach: si_attach failed\n",
4684 unit);
4685 err = 11;
4686 goto fail;
4687 }
4688
4689 /* verify again the device is supported */
4690 if (!brcms_c_chipmatch(vendor, device)) {
4691 wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported "
4692 "vendor/device (0x%x/0x%x)\n",
4693 unit, vendor, device);
4694 err = 12;
4695 goto fail;
4696 }
4697
4698 wlc_hw->vendorid = vendor;
4699 wlc_hw->deviceid = device;
4700
4701 /* set bar0 window to point at D11 core */
4702 wlc_hw->regs = (struct d11regs __iomem *)
4703 ai_setcore(wlc_hw->sih, D11_CORE_ID, 0);
4704 wlc_hw->corerev = ai_corerev(wlc_hw->sih);
4705
4706 regs = wlc_hw->regs;
4707
4708 wlc->regs = wlc_hw->regs;
4709
4710 /* validate chip, chiprev and corerev */
4711 if (!brcms_c_isgoodchip(wlc_hw)) {
4712 err = 13;
4713 goto fail;
4714 }
4715
4716 /* initialize power control registers */
4717 ai_clkctl_init(wlc_hw->sih);
4718
4719 /* request fastclock and force fastclock for the rest of attach
4720 * bring the d11 core out of reset.
4721 * For PMU chips, the first wlc_clkctl_clk is no-op since core-clk
4722 * is still false; But it will be called again inside wlc_corereset,
4723 * after d11 is out of reset.
4724 */
4725 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
4726 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
4727
4728 if (!brcms_b_validate_chip_access(wlc_hw)) {
4729 wiphy_err(wiphy, "wl%d: brcms_b_attach: validate_chip_access "
4730 "failed\n", unit);
4731 err = 14;
4732 goto fail;
4733 }
4734
4735 /* get the board rev, used just below */
4736 j = getintvar(wlc_hw->sih, BRCMS_SROM_BOARDREV);
4737 /* promote srom boardrev of 0xFF to 1 */
4738 if (j == BOARDREV_PROMOTABLE)
4739 j = BOARDREV_PROMOTED;
4740 wlc_hw->boardrev = (u16) j;
4741 if (!brcms_c_validboardtype(wlc_hw)) {
4742 wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported Broadcom "
4743 "board type (0x%x)" " or revision level (0x%x)\n",
4744 unit, wlc_hw->sih->boardtype, wlc_hw->boardrev);
4745 err = 15;
4746 goto fail;
4747 }
4748 wlc_hw->sromrev = (u8) getintvar(wlc_hw->sih, BRCMS_SROM_REV);
4749 wlc_hw->boardflags = (u32) getintvar(wlc_hw->sih,
4750 BRCMS_SROM_BOARDFLAGS);
4751 wlc_hw->boardflags2 = (u32) getintvar(wlc_hw->sih,
4752 BRCMS_SROM_BOARDFLAGS2);
4753
4754 if (wlc_hw->boardflags & BFL_NOPLLDOWN)
4755 brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED);
4756
4757 /* check device id(srom, nvram etc.) to set bands */
4758 if (wlc_hw->deviceid == BCM43224_D11N_ID ||
4759 wlc_hw->deviceid == BCM43224_D11N_ID_VEN1)
4760 /* Dualband boards */
4761 wlc_hw->_nbands = 2;
4762 else
4763 wlc_hw->_nbands = 1;
4764
4765 if ((wlc_hw->sih->chip == BCM43225_CHIP_ID))
4766 wlc_hw->_nbands = 1;
4767
4768 /* BMAC_NOTE: remove init of pub values when brcms_c_attach()
4769 * unconditionally does the init of these values
4770 */
4771 wlc->vendorid = wlc_hw->vendorid;
4772 wlc->deviceid = wlc_hw->deviceid;
4773 wlc->pub->sih = wlc_hw->sih;
4774 wlc->pub->corerev = wlc_hw->corerev;
4775 wlc->pub->sromrev = wlc_hw->sromrev;
4776 wlc->pub->boardrev = wlc_hw->boardrev;
4777 wlc->pub->boardflags = wlc_hw->boardflags;
4778 wlc->pub->boardflags2 = wlc_hw->boardflags2;
4779 wlc->pub->_nbands = wlc_hw->_nbands;
4780
4781 wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc);
4782
4783 if (wlc_hw->physhim == NULL) {
4784 wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_shim_attach "
4785 "failed\n", unit);
4786 err = 25;
4787 goto fail;
4788 }
4789
4790 /* pass all the parameters to wlc_phy_shared_attach in one struct */
4791 sha_params.sih = wlc_hw->sih;
4792 sha_params.physhim = wlc_hw->physhim;
4793 sha_params.unit = unit;
4794 sha_params.corerev = wlc_hw->corerev;
4795 sha_params.vid = wlc_hw->vendorid;
4796 sha_params.did = wlc_hw->deviceid;
4797 sha_params.chip = wlc_hw->sih->chip;
4798 sha_params.chiprev = wlc_hw->sih->chiprev;
4799 sha_params.chippkg = wlc_hw->sih->chippkg;
4800 sha_params.sromrev = wlc_hw->sromrev;
4801 sha_params.boardtype = wlc_hw->sih->boardtype;
4802 sha_params.boardrev = wlc_hw->boardrev;
4803 sha_params.boardvendor = wlc_hw->sih->boardvendor;
4804 sha_params.boardflags = wlc_hw->boardflags;
4805 sha_params.boardflags2 = wlc_hw->boardflags2;
4806 sha_params.buscorerev = wlc_hw->sih->buscorerev;
4807
4808 /* alloc and save pointer to shared phy state area */
4809 wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params);
4810 if (!wlc_hw->phy_sh) {
4811 err = 16;
4812 goto fail;
4813 }
4814
4815 /* initialize software state for each core and band */
4816 for (j = 0; j < wlc_hw->_nbands; j++) {
4817 /*
4818 * band0 is always 2.4Ghz
4819 * band1, if present, is 5Ghz
4820 */
4821
4822 brcms_c_setxband(wlc_hw, j);
4823
4824 wlc_hw->band->bandunit = j;
4825 wlc_hw->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G;
4826 wlc->band->bandunit = j;
4827 wlc->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G;
4828 wlc->core->coreidx = ai_coreidx(wlc_hw->sih);
4829
4830 wlc_hw->machwcap = R_REG(&regs->machwcap);
4831 wlc_hw->machwcap_backup = wlc_hw->machwcap;
4832
4833 /* init tx fifo size */
4834 wlc_hw->xmtfifo_sz =
4835 xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)];
4836
4837 /* Get a phy for this band */
4838 wlc_hw->band->pi =
4839 wlc_phy_attach(wlc_hw->phy_sh, regs,
4840 wlc_hw->band->bandtype,
4841 wlc->wiphy);
4842 if (wlc_hw->band->pi == NULL) {
4843 wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_"
4844 "attach failed\n", unit);
4845 err = 17;
4846 goto fail;
4847 }
4848
4849 wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap);
4850
4851 wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype,
4852 &wlc_hw->band->phyrev,
4853 &wlc_hw->band->radioid,
4854 &wlc_hw->band->radiorev);
4855 wlc_hw->band->abgphy_encore =
4856 wlc_phy_get_encore(wlc_hw->band->pi);
4857 wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi);
4858 wlc_hw->band->core_flags =
4859 wlc_phy_get_coreflags(wlc_hw->band->pi);
4860
4861 /* verify good phy_type & supported phy revision */
4862 if (BRCMS_ISNPHY(wlc_hw->band)) {
4863 if (NCONF_HAS(wlc_hw->band->phyrev))
4864 goto good_phy;
4865 else
4866 goto bad_phy;
4867 } else if (BRCMS_ISLCNPHY(wlc_hw->band)) {
4868 if (LCNCONF_HAS(wlc_hw->band->phyrev))
4869 goto good_phy;
4870 else
4871 goto bad_phy;
4872 } else {
4873 bad_phy:
4874 wiphy_err(wiphy, "wl%d: brcms_b_attach: unsupported "
4875 "phy type/rev (%d/%d)\n", unit,
4876 wlc_hw->band->phytype, wlc_hw->band->phyrev);
4877 err = 18;
4878 goto fail;
4879 }
4880
4881 good_phy:
4882 /*
4883 * BMAC_NOTE: wlc->band->pi should not be set below and should
4884 * be done in the high level attach. However we can not make
4885 * that change until all low level access is changed to
4886 * wlc_hw->band->pi. Instead do the wlc->band->pi init below,
4887 * keeping wlc_hw->band->pi as well for incremental update of
4888 * low level fns, and cut over low only init when all fns
4889 * updated.
4890 */
4891 wlc->band->pi = wlc_hw->band->pi;
4892 wlc->band->phytype = wlc_hw->band->phytype;
4893 wlc->band->phyrev = wlc_hw->band->phyrev;
4894 wlc->band->radioid = wlc_hw->band->radioid;
4895 wlc->band->radiorev = wlc_hw->band->radiorev;
4896
4897 /* default contention windows size limits */
4898 wlc_hw->band->CWmin = APHY_CWMIN;
4899 wlc_hw->band->CWmax = PHY_CWMAX;
4900
4901 if (!brcms_b_attach_dmapio(wlc, j, wme)) {
4902 err = 19;
4903 goto fail;
4904 }
4905 }
4906
4907 /* disable core to match driver "down" state */
4908 brcms_c_coredisable(wlc_hw);
4909
4910 /* Match driver "down" state */
4911 ai_pci_down(wlc_hw->sih);
4912
4913 /* register sb interrupt callback functions */
4914 ai_register_intr_callback(wlc_hw->sih, (void *)brcms_c_wlintrsoff,
4915 (void *)brcms_c_wlintrsrestore, NULL, wlc);
4916
4917 /* turn off pll and xtal to match driver "down" state */
4918 brcms_b_xtal(wlc_hw, OFF);
4919
4920 /* *******************************************************************
4921 * The hardware is in the DOWN state at this point. D11 core
4922 * or cores are in reset with clocks off, and the board PLLs
4923 * are off if possible.
4924 *
4925 * Beyond this point, wlc->sbclk == false and chip registers
4926 * should not be touched.
4927 *********************************************************************
4928 */
4929
4930 /* init etheraddr state variables */
4931 macaddr = brcms_c_get_macaddr(wlc_hw);
4932 if (macaddr == NULL) {
4933 wiphy_err(wiphy, "wl%d: brcms_b_attach: macaddr not found\n",
4934 unit);
4935 err = 21;
4936 goto fail;
4937 }
4938 if (!mac_pton(macaddr, wlc_hw->etheraddr) ||
4939 is_broadcast_ether_addr(wlc_hw->etheraddr) ||
4940 is_zero_ether_addr(wlc_hw->etheraddr)) {
4941 wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr %s\n",
4942 unit, macaddr);
4943 err = 22;
4944 goto fail;
4945 }
4946
4947 BCMMSG(wlc->wiphy,
4948 "deviceid 0x%x nbands %d board 0x%x macaddr: %s\n",
4949 wlc_hw->deviceid, wlc_hw->_nbands,
4950 wlc_hw->sih->boardtype, macaddr);
4951
4952 return err;
4953
4954 fail:
4955 wiphy_err(wiphy, "wl%d: brcms_b_attach: failed with err %d\n", unit,
4956 err);
4957 return err;
4958}
4959
4960static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc)
4961{
4962 uint unit;
4963 unit = wlc->pub->unit;
4964
4965 if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
4966 /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
4967 wlc->band->antgain = 8;
4968 } else if (wlc->band->antgain == -1) {
4969 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
4970 " srom, using 2dB\n", unit, __func__);
4971 wlc->band->antgain = 8;
4972 } else {
4973 s8 gain, fract;
4974 /* Older sroms specified gain in whole dbm only. In order
4975 * be able to specify qdbm granularity and remain backward
4976 * compatible the whole dbms are now encoded in only
4977 * low 6 bits and remaining qdbms are encoded in the hi 2 bits.
4978 * 6 bit signed number ranges from -32 - 31.
4979 *
4980 * Examples:
4981 * 0x1 = 1 db,
4982 * 0xc1 = 1.75 db (1 + 3 quarters),
4983 * 0x3f = -1 (-1 + 0 quarters),
4984 * 0x7f = -.75 (-1 + 1 quarters) = -3 qdbm.
4985 * 0xbf = -.50 (-1 + 2 quarters) = -2 qdbm.
4986 */
4987 gain = wlc->band->antgain & 0x3f;
4988 gain <<= 2; /* Sign extend */
4989 gain >>= 2;
4990 fract = (wlc->band->antgain & 0xc0) >> 6;
4991 wlc->band->antgain = 4 * gain + fract;
4992 }
4993}
4994
4995static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
4996{
4997 int aa;
4998 uint unit;
4999 int bandtype;
5000 struct si_pub *sih = wlc->hw->sih;
5001
5002 unit = wlc->pub->unit;
5003 bandtype = wlc->band->bandtype;
5004
5005 /* get antennas available */
5006 if (bandtype == BRCM_BAND_5G)
5007 aa = (s8) getintvar(sih, BRCMS_SROM_AA5G);
5008 else
5009 aa = (s8) getintvar(sih, BRCMS_SROM_AA2G);
5010
5011 if ((aa < 1) || (aa > 15)) {
5012 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
5013 " srom (0x%x), using 3\n", unit, __func__, aa);
5014 aa = 3;
5015 }
5016
5017 /* reset the defaults if we have a single antenna */
5018 if (aa == 1) {
5019 wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0;
5020 wlc->stf->txant = ANT_TX_FORCE_0;
5021 } else if (aa == 2) {
5022 wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1;
5023 wlc->stf->txant = ANT_TX_FORCE_1;
5024 } else {
5025 }
5026
5027 /* Compute Antenna Gain */
5028 if (bandtype == BRCM_BAND_5G)
5029 wlc->band->antgain = (s8) getintvar(sih, BRCMS_SROM_AG1);
5030 else
5031 wlc->band->antgain = (s8) getintvar(sih, BRCMS_SROM_AG0);
5032
5033 brcms_c_attach_antgain_init(wlc);
5034
5035 return true;
5036}
5037
5038static void brcms_c_bss_default_init(struct brcms_c_info *wlc)
5039{
5040 u16 chanspec;
5041 struct brcms_band *band;
5042 struct brcms_bss_info *bi = wlc->default_bss;
5043
5044 /* init default and target BSS with some sane initial values */
5045 memset((char *)(bi), 0, sizeof(struct brcms_bss_info));
5046 bi->beacon_period = BEACON_INTERVAL_DEFAULT;
5047
5048 /* fill the default channel as the first valid channel
5049 * starting from the 2G channels
5050 */
5051 chanspec = ch20mhz_chspec(1);
5052 wlc->home_chanspec = bi->chanspec = chanspec;
5053
5054 /* find the band of our default channel */
5055 band = wlc->band;
5056 if (wlc->pub->_nbands > 1 &&
5057 band->bandunit != chspec_bandunit(chanspec))
5058 band = wlc->bandstate[OTHERBANDUNIT(wlc)];
5059
5060 /* init bss rates to the band specific default rate set */
5061 brcms_c_rateset_default(&bi->rateset, NULL, band->phytype,
5062 band->bandtype, false, BRCMS_RATE_MASK_FULL,
5063 (bool) (wlc->pub->_n_enab & SUPPORT_11N),
5064 brcms_chspec_bw(chanspec), wlc->stf->txstreams);
5065
5066 if (wlc->pub->_n_enab & SUPPORT_11N)
5067 bi->flags |= BRCMS_BSS_HT;
5068}
5069
5070static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc)
5071{
5072 struct brcms_txq_info *qi, *p;
5073
5074 qi = kzalloc(sizeof(struct brcms_txq_info), GFP_ATOMIC);
5075 if (qi != NULL) {
5076 /*
5077 * Have enough room for control packets along with HI watermark
5078 * Also, add room to txq for total psq packets if all the SCBs
5079 * leave PS mode. The watermark for flowcontrol to OS packets
5080 * will remain the same
5081 */
5082 brcmu_pktq_init(&qi->q, BRCMS_PREC_COUNT,
5083 2 * BRCMS_DATAHIWAT + PKTQ_LEN_DEFAULT);
5084
5085 /* add this queue to the the global list */
5086 p = wlc->tx_queues;
5087 if (p == NULL) {
5088 wlc->tx_queues = qi;
5089 } else {
5090 while (p->next != NULL)
5091 p = p->next;
5092 p->next = qi;
5093 }
5094 }
5095 return qi;
5096}
5097
5098static void brcms_c_txq_free(struct brcms_c_info *wlc,
5099 struct brcms_txq_info *qi)
5100{
5101 struct brcms_txq_info *p;
5102
5103 if (qi == NULL)
5104 return;
5105
5106 /* remove the queue from the linked list */
5107 p = wlc->tx_queues;
5108 if (p == qi)
5109 wlc->tx_queues = p->next;
5110 else {
5111 while (p != NULL && p->next != qi)
5112 p = p->next;
5113 if (p != NULL)
5114 p->next = p->next->next;
5115 }
5116
5117 kfree(qi);
5118}
5119
5120static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap)
5121{
5122 uint i;
5123 struct brcms_band *band;
5124
5125 for (i = 0; i < wlc->pub->_nbands; i++) {
5126 band = wlc->bandstate[i];
5127 if (band->bandtype == BRCM_BAND_5G) {
5128 if ((bwcap == BRCMS_N_BW_40ALL)
5129 || (bwcap == BRCMS_N_BW_20IN2G_40IN5G))
5130 band->mimo_cap_40 = true;
5131 else
5132 band->mimo_cap_40 = false;
5133 } else {
5134 if (bwcap == BRCMS_N_BW_40ALL)
5135 band->mimo_cap_40 = true;
5136 else
5137 band->mimo_cap_40 = false;
5138 }
5139 }
5140}
5141
5142static void brcms_c_timers_deinit(struct brcms_c_info *wlc)
5143{
5144 /* free timer state */
5145 if (wlc->wdtimer) {
5146 brcms_free_timer(wlc->wdtimer);
5147 wlc->wdtimer = NULL;
5148 }
5149 if (wlc->radio_timer) {
5150 brcms_free_timer(wlc->radio_timer);
5151 wlc->radio_timer = NULL;
5152 }
5153}
5154
5155static void brcms_c_detach_module(struct brcms_c_info *wlc)
5156{
5157 if (wlc->asi) {
5158 brcms_c_antsel_detach(wlc->asi);
5159 wlc->asi = NULL;
5160 }
5161
5162 if (wlc->ampdu) {
5163 brcms_c_ampdu_detach(wlc->ampdu);
5164 wlc->ampdu = NULL;
5165 }
5166
5167 brcms_c_stf_detach(wlc);
5168}
5169
5170/*
5171 * low level detach
5172 */
5173static int brcms_b_detach(struct brcms_c_info *wlc)
5174{
5175 uint i;
5176 struct brcms_hw_band *band;
5177 struct brcms_hardware *wlc_hw = wlc->hw;
5178 int callbacks;
5179
5180 callbacks = 0;
5181
5182 if (wlc_hw->sih) {
5183 /*
5184 * detach interrupt sync mechanism since interrupt is disabled
5185 * and per-port interrupt object may has been freed. this must
5186 * be done before sb core switch
5187 */
5188 ai_deregister_intr_callback(wlc_hw->sih);
5189 ai_pci_sleep(wlc_hw->sih);
5190 }
5191
5192 brcms_b_detach_dmapio(wlc_hw);
5193
5194 band = wlc_hw->band;
5195 for (i = 0; i < wlc_hw->_nbands; i++) {
5196 if (band->pi) {
5197 /* Detach this band's phy */
5198 wlc_phy_detach(band->pi);
5199 band->pi = NULL;
5200 }
5201 band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)];
5202 }
5203
5204 /* Free shared phy state */
5205 kfree(wlc_hw->phy_sh);
5206
5207 wlc_phy_shim_detach(wlc_hw->physhim);
5208
5209 if (wlc_hw->sih) {
5210 ai_detach(wlc_hw->sih);
5211 wlc_hw->sih = NULL;
5212 }
5213
5214 return callbacks;
5215
5216}
5217
5218/*
5219 * Return a count of the number of driver callbacks still pending.
5220 *
5221 * General policy is that brcms_c_detach can only dealloc/free software states.
5222 * It can NOT touch hardware registers since the d11core may be in reset and
5223 * clock may not be available.
5224 * One exception is sb register access, which is possible if crystal is turned
5225 * on after "down" state, driver should avoid software timer with the exception
5226 * of radio_monitor.
5227 */
5228uint brcms_c_detach(struct brcms_c_info *wlc)
5229{
5230 uint callbacks = 0;
5231
5232 if (wlc == NULL)
5233 return 0;
5234
5235 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
5236
5237 callbacks += brcms_b_detach(wlc);
5238
5239 /* delete software timers */
5240 if (!brcms_c_radio_monitor_stop(wlc))
5241 callbacks++;
5242
5243 brcms_c_channel_mgr_detach(wlc->cmi);
5244
5245 brcms_c_timers_deinit(wlc);
5246
5247 brcms_c_detach_module(wlc);
5248
5249
5250 while (wlc->tx_queues != NULL)
5251 brcms_c_txq_free(wlc, wlc->tx_queues);
5252
5253 brcms_c_detach_mfree(wlc);
5254 return callbacks;
5255}
5256
5257/* update state that depends on the current value of "ap" */
5258static void brcms_c_ap_upd(struct brcms_c_info *wlc)
5259{
5260 /* STA-BSS; short capable */
5261 wlc->PLCPHdr_override = BRCMS_PLCP_SHORT;
5262
5263 /* fixup mpc */
5264 wlc->mpc = true;
5265}
5266
5267/* Initialize just the hardware when coming out of POR or S3/S5 system states */
5268static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
5269{
5270 if (wlc_hw->wlc->pub->hw_up)
5271 return;
5272
5273 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
5274
5275 /*
5276 * Enable pll and xtal, initialize the power control registers,
5277 * and force fastclock for the remainder of brcms_c_up().
5278 */
5279 brcms_b_xtal(wlc_hw, ON);
5280 ai_clkctl_init(wlc_hw->sih);
5281 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
5282
5283 ai_pci_fixcfg(wlc_hw->sih);
5284
5285 /*
5286 * AI chip doesn't restore bar0win2 on
5287 * hibernation/resume, need sw fixup
5288 */
5289 if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
5290 (wlc_hw->sih->chip == BCM43225_CHIP_ID))
5291 wlc_hw->regs = (struct d11regs __iomem *)
5292 ai_setcore(wlc_hw->sih, D11_CORE_ID, 0);
5293
5294 /*
5295 * Inform phy that a POR reset has occurred so
5296 * it does a complete phy init
5297 */
5298 wlc_phy_por_inform(wlc_hw->band->pi);
5299
5300 wlc_hw->ucode_loaded = false;
5301 wlc_hw->wlc->pub->hw_up = true;
5302
5303 if ((wlc_hw->boardflags & BFL_FEM)
5304 && (wlc_hw->sih->chip == BCM4313_CHIP_ID)) {
5305 if (!
5306 (wlc_hw->boardrev >= 0x1250
5307 && (wlc_hw->boardflags & BFL_FEM_BT)))
5308 ai_epa_4313war(wlc_hw->sih);
5309 }
5310}
5311
5312static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
5313{
5314 uint coremask;
5315
5316 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
5317
5318 /*
5319 * Enable pll and xtal, initialize the power control registers,
5320 * and force fastclock for the remainder of brcms_c_up().
5321 */
5322 brcms_b_xtal(wlc_hw, ON);
5323 ai_clkctl_init(wlc_hw->sih);
5324 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
5325
5326 /*
5327 * Configure pci/pcmcia here instead of in brcms_c_attach()
5328 * to allow mfg hotswap: down, hotswap (chip power cycle), up.
5329 */
5330 coremask = (1 << wlc_hw->wlc->core->coreidx);
5331
5332 ai_pci_setup(wlc_hw->sih, coremask);
5333
5334 /*
5335 * Need to read the hwradio status here to cover the case where the
5336 * system is loaded with the hw radio disabled. We do not want to
5337 * bring the driver up in this case.
5338 */
5339 if (brcms_b_radio_read_hwdisabled(wlc_hw)) {
5340 /* put SB PCI in down state again */
5341 ai_pci_down(wlc_hw->sih);
5342 brcms_b_xtal(wlc_hw, OFF);
5343 return -ENOMEDIUM;
5344 }
5345
5346 ai_pci_up(wlc_hw->sih);
5347
5348 /* reset the d11 core */
5349 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
5350
5351 return 0;
5352}
5353
5354static int brcms_b_up_finish(struct brcms_hardware *wlc_hw)
5355{
5356 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
5357
5358 wlc_hw->up = true;
5359 wlc_phy_hw_state_upd(wlc_hw->band->pi, true);
5360
5361 /* FULLY enable dynamic power control and d11 core interrupt */
5362 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
5363 brcms_intrson(wlc_hw->wlc->wl);
5364 return 0;
5365}
5366
5367/*
5368 * Write WME tunable parameters for retransmit/max rate
5369 * from wlc struct to ucode
5370 */
5371static void brcms_c_wme_retries_write(struct brcms_c_info *wlc)
5372{
5373 int ac;
5374
5375 /* Need clock to do this */
5376 if (!wlc->clk)
5377 return;
5378
5379 for (ac = 0; ac < AC_COUNT; ac++)
5380 brcms_b_write_shm(wlc->hw, M_AC_TXLMT_ADDR(ac),
5381 wlc->wme_retries[ac]);
5382}
5383
5384/* make interface operational */
5385int brcms_c_up(struct brcms_c_info *wlc)
5386{
5387 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
5388
5389 /* HW is turned off so don't try to access it */
5390 if (wlc->pub->hw_off || brcms_deviceremoved(wlc))
5391 return -ENOMEDIUM;
5392
5393 if (!wlc->pub->hw_up) {
5394 brcms_b_hw_up(wlc->hw);
5395 wlc->pub->hw_up = true;
5396 }
5397
5398 if ((wlc->pub->boardflags & BFL_FEM)
5399 && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) {
5400 if (wlc->pub->boardrev >= 0x1250
5401 && (wlc->pub->boardflags & BFL_FEM_BT))
5402 brcms_b_mhf(wlc->hw, MHF5, MHF5_4313_GPIOCTRL,
5403 MHF5_4313_GPIOCTRL, BRCM_BAND_ALL);
5404 else
5405 brcms_b_mhf(wlc->hw, MHF4, MHF4_EXTPA_ENABLE,
5406 MHF4_EXTPA_ENABLE, BRCM_BAND_ALL);
5407 }
5408
5409 /*
5410 * Need to read the hwradio status here to cover the case where the
5411 * system is loaded with the hw radio disabled. We do not want to bring
5412 * the driver up in this case. If radio is disabled, abort up, lower
5413 * power, start radio timer and return 0(for NDIS) don't call
5414 * radio_update to avoid looping brcms_c_up.
5415 *
5416 * brcms_b_up_prep() returns either 0 or -BCME_RADIOOFF only
5417 */
5418 if (!wlc->pub->radio_disabled) {
5419 int status = brcms_b_up_prep(wlc->hw);
5420 if (status == -ENOMEDIUM) {
5421 if (!mboolisset
5422 (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) {
5423 struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
5424 mboolset(wlc->pub->radio_disabled,
5425 WL_RADIO_HW_DISABLE);
5426
5427 if (bsscfg->enable && bsscfg->BSS)
5428 wiphy_err(wlc->wiphy, "wl%d: up"
5429 ": rfdisable -> "
5430 "bsscfg_disable()\n",
5431 wlc->pub->unit);
5432 }
5433 }
5434 }
5435
5436 if (wlc->pub->radio_disabled) {
5437 brcms_c_radio_monitor_start(wlc);
5438 return 0;
5439 }
5440
5441 /* brcms_b_up_prep has done brcms_c_corereset(). so clk is on, set it */
5442 wlc->clk = true;
5443
5444 brcms_c_radio_monitor_stop(wlc);
5445
5446 /* Set EDCF hostflags */
5447 brcms_b_mhf(wlc->hw, MHF1, MHF1_EDCF, MHF1_EDCF, BRCM_BAND_ALL);
5448
5449 brcms_init(wlc->wl);
5450 wlc->pub->up = true;
5451
5452 if (wlc->bandinit_pending) {
5453 brcms_c_suspend_mac_and_wait(wlc);
5454 brcms_c_set_chanspec(wlc, wlc->default_bss->chanspec);
5455 wlc->bandinit_pending = false;
5456 brcms_c_enable_mac(wlc);
5457 }
5458
5459 brcms_b_up_finish(wlc->hw);
5460
5461 /* Program the TX wme params with the current settings */
5462 brcms_c_wme_retries_write(wlc);
5463
5464 /* start one second watchdog timer */
5465 brcms_add_timer(wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true);
5466 wlc->WDarmed = true;
5467
5468 /* ensure antenna config is up to date */
5469 brcms_c_stf_phy_txant_upd(wlc);
5470 /* ensure LDPC config is in sync */
5471 brcms_c_ht_update_ldpc(wlc, wlc->stf->ldpc);
5472
5473 return 0;
5474}
5475
5476static uint brcms_c_down_del_timer(struct brcms_c_info *wlc)
5477{
5478 uint callbacks = 0;
5479
5480 return callbacks;
5481}
5482
5483static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw)
5484{
5485 bool dev_gone;
5486 uint callbacks = 0;
5487
5488 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
5489
5490 if (!wlc_hw->up)
5491 return callbacks;
5492
5493 dev_gone = brcms_deviceremoved(wlc_hw->wlc);
5494
5495 /* disable interrupts */
5496 if (dev_gone)
5497 wlc_hw->wlc->macintmask = 0;
5498 else {
5499 /* now disable interrupts */
5500 brcms_intrsoff(wlc_hw->wlc->wl);
5501
5502 /* ensure we're running on the pll clock again */
5503 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
5504 }
5505 /* down phy at the last of this stage */
5506 callbacks += wlc_phy_down(wlc_hw->band->pi);
5507
5508 return callbacks;
5509}
5510
5511static int brcms_b_down_finish(struct brcms_hardware *wlc_hw)
5512{
5513 uint callbacks = 0;
5514 bool dev_gone;
5515
5516 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
5517
5518 if (!wlc_hw->up)
5519 return callbacks;
5520
5521 wlc_hw->up = false;
5522 wlc_phy_hw_state_upd(wlc_hw->band->pi, false);
5523
5524 dev_gone = brcms_deviceremoved(wlc_hw->wlc);
5525
5526 if (dev_gone) {
5527 wlc_hw->sbclk = false;
5528 wlc_hw->clk = false;
5529 wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
5530
5531 /* reclaim any posted packets */
5532 brcms_c_flushqueues(wlc_hw->wlc);
5533 } else {
5534
5535 /* Reset and disable the core */
5536 if (ai_iscoreup(wlc_hw->sih)) {
5537 if (R_REG(&wlc_hw->regs->maccontrol) &
5538 MCTL_EN_MAC)
5539 brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
5540 callbacks += brcms_reset(wlc_hw->wlc->wl);
5541 brcms_c_coredisable(wlc_hw);
5542 }
5543
5544 /* turn off primary xtal and pll */
5545 if (!wlc_hw->noreset) {
5546 ai_pci_down(wlc_hw->sih);
5547 brcms_b_xtal(wlc_hw, OFF);
5548 }
5549 }
5550
5551 return callbacks;
5552}
5553
5554/*
5555 * Mark the interface nonoperational, stop the software mechanisms,
5556 * disable the hardware, free any transient buffer state.
5557 * Return a count of the number of driver callbacks still pending.
5558 */
5559uint brcms_c_down(struct brcms_c_info *wlc)
5560{
5561
5562 uint callbacks = 0;
5563 int i;
5564 bool dev_gone = false;
5565 struct brcms_txq_info *qi;
5566
5567 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
5568
5569 /* check if we are already in the going down path */
5570 if (wlc->going_down) {
5571 wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return"
5572 "\n", wlc->pub->unit, __func__);
5573 return 0;
5574 }
5575 if (!wlc->pub->up)
5576 return callbacks;
5577
5578 /* in between, mpc could try to bring down again.. */
5579 wlc->going_down = true;
5580
5581 callbacks += brcms_b_bmac_down_prep(wlc->hw);
5582
5583 dev_gone = brcms_deviceremoved(wlc);
5584
5585 /* Call any registered down handlers */
5586 for (i = 0; i < BRCMS_MAXMODULES; i++) {
5587 if (wlc->modulecb[i].down_fn)
5588 callbacks +=
5589 wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl);
5590 }
5591
5592 /* cancel the watchdog timer */
5593 if (wlc->WDarmed) {
5594 if (!brcms_del_timer(wlc->wdtimer))
5595 callbacks++;
5596 wlc->WDarmed = false;
5597 }
5598 /* cancel all other timers */
5599 callbacks += brcms_c_down_del_timer(wlc);
5600
5601 wlc->pub->up = false;
5602
5603 wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);
5604
5605 /* clear txq flow control */
5606 brcms_c_txflowcontrol_reset(wlc);
5607
5608 /* flush tx queues */
5609 for (qi = wlc->tx_queues; qi != NULL; qi = qi->next)
5610 brcmu_pktq_flush(&qi->q, true, NULL, NULL);
5611
5612 callbacks += brcms_b_down_finish(wlc->hw);
5613
5614 /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */
5615 wlc->clk = false;
5616
5617 wlc->going_down = false;
5618 return callbacks;
5619}
5620
5621/* Set the current gmode configuration */
5622int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config)
5623{
5624 int ret = 0;
5625 uint i;
5626 struct brcms_c_rateset rs;
5627 /* Default to 54g Auto */
5628 /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */
5629 s8 shortslot = BRCMS_SHORTSLOT_AUTO;
5630 bool shortslot_restrict = false; /* Restrict association to stations
5631 * that support shortslot
5632 */
5633 bool ofdm_basic = false; /* Make 6, 12, and 24 basic rates */
5634 /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */
5635 int preamble = BRCMS_PLCP_LONG;
5636 bool preamble_restrict = false; /* Restrict association to stations
5637 * that support short preambles
5638 */
5639 struct brcms_band *band;
5640
5641 /* if N-support is enabled, allow Gmode set as long as requested
5642 * Gmode is not GMODE_LEGACY_B
5643 */
5644 if ((wlc->pub->_n_enab & SUPPORT_11N) && gmode == GMODE_LEGACY_B)
5645 return -ENOTSUPP;
5646
5647 /* verify that we are dealing with 2G band and grab the band pointer */
5648 if (wlc->band->bandtype == BRCM_BAND_2G)
5649 band = wlc->band;
5650 else if ((wlc->pub->_nbands > 1) &&
5651 (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == BRCM_BAND_2G))
5652 band = wlc->bandstate[OTHERBANDUNIT(wlc)];
5653 else
5654 return -EINVAL;
5655
5656 /* Legacy or bust when no OFDM is supported by regulatory */
5657 if ((brcms_c_channel_locale_flags_in_band(wlc->cmi, band->bandunit) &
5658 BRCMS_NO_OFDM) && (gmode != GMODE_LEGACY_B))
5659 return -EINVAL;
5660
5661 /* update configuration value */
5662 if (config == true)
5663 brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode);
5664
5665 /* Clear rateset override */
5666 memset(&rs, 0, sizeof(struct brcms_c_rateset));
5667
5668 switch (gmode) {
5669 case GMODE_LEGACY_B:
5670 shortslot = BRCMS_SHORTSLOT_OFF;
5671 brcms_c_rateset_copy(&gphy_legacy_rates, &rs);
5672
5673 break;
5674
5675 case GMODE_LRS:
5676 break;
5677
5678 case GMODE_AUTO:
5679 /* Accept defaults */
5680 break;
5681
5682 case GMODE_ONLY:
5683 ofdm_basic = true;
5684 preamble = BRCMS_PLCP_SHORT;
5685 preamble_restrict = true;
5686 break;
5687
5688 case GMODE_PERFORMANCE:
5689 shortslot = BRCMS_SHORTSLOT_ON;
5690 shortslot_restrict = true;
5691 ofdm_basic = true;
5692 preamble = BRCMS_PLCP_SHORT;
5693 preamble_restrict = true;
5694 break;
5695
5696 default:
5697 /* Error */
5698 wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n",
5699 wlc->pub->unit, __func__, gmode);
5700 return -ENOTSUPP;
5701 }
5702
5703 band->gmode = gmode;
5704
5705 wlc->shortslot_override = shortslot;
5706
5707 /* Use the default 11g rateset */
5708 if (!rs.count)
5709 brcms_c_rateset_copy(&cck_ofdm_rates, &rs);
5710
5711 if (ofdm_basic) {
5712 for (i = 0; i < rs.count; i++) {
5713 if (rs.rates[i] == BRCM_RATE_6M
5714 || rs.rates[i] == BRCM_RATE_12M
5715 || rs.rates[i] == BRCM_RATE_24M)
5716 rs.rates[i] |= BRCMS_RATE_FLAG;
5717 }
5718 }
5719
5720 /* Set default bss rateset */
5721 wlc->default_bss->rateset.count = rs.count;
5722 memcpy(wlc->default_bss->rateset.rates, rs.rates,
5723 sizeof(wlc->default_bss->rateset.rates));
5724
5725 return ret;
5726}
5727
5728int brcms_c_set_nmode(struct brcms_c_info *wlc)
5729{
5730 uint i;
5731 s32 nmode = AUTO;
5732
5733 if (wlc->stf->txstreams == WL_11N_3x3)
5734 nmode = WL_11N_3x3;
5735 else
5736 nmode = WL_11N_2x2;
5737
5738 /* force GMODE_AUTO if NMODE is ON */
5739 brcms_c_set_gmode(wlc, GMODE_AUTO, true);
5740 if (nmode == WL_11N_3x3)
5741 wlc->pub->_n_enab = SUPPORT_HT;
5742 else
5743 wlc->pub->_n_enab = SUPPORT_11N;
5744 wlc->default_bss->flags |= BRCMS_BSS_HT;
5745 /* add the mcs rates to the default and hw ratesets */
5746 brcms_c_rateset_mcs_build(&wlc->default_bss->rateset,
5747 wlc->stf->txstreams);
5748 for (i = 0; i < wlc->pub->_nbands; i++)
5749 memcpy(wlc->bandstate[i]->hw_rateset.mcs,
5750 wlc->default_bss->rateset.mcs, MCSSET_LEN);
5751
5752 return 0;
5753}
5754
5755static int
5756brcms_c_set_internal_rateset(struct brcms_c_info *wlc,
5757 struct brcms_c_rateset *rs_arg)
5758{
5759 struct brcms_c_rateset rs, new;
5760 uint bandunit;
5761
5762 memcpy(&rs, rs_arg, sizeof(struct brcms_c_rateset));
5763
5764 /* check for bad count value */
5765 if ((rs.count == 0) || (rs.count > BRCMS_NUMRATES))
5766 return -EINVAL;
5767
5768 /* try the current band */
5769 bandunit = wlc->band->bandunit;
5770 memcpy(&new, &rs, sizeof(struct brcms_c_rateset));
5771 if (brcms_c_rate_hwrs_filter_sort_validate
5772 (&new, &wlc->bandstate[bandunit]->hw_rateset, true,
5773 wlc->stf->txstreams))
5774 goto good;
5775
5776 /* try the other band */
5777 if (brcms_is_mband_unlocked(wlc)) {
5778 bandunit = OTHERBANDUNIT(wlc);
5779 memcpy(&new, &rs, sizeof(struct brcms_c_rateset));
5780 if (brcms_c_rate_hwrs_filter_sort_validate(&new,
5781 &wlc->
5782 bandstate[bandunit]->
5783 hw_rateset, true,
5784 wlc->stf->txstreams))
5785 goto good;
5786 }
5787
5788 return -EBADE;
5789
5790 good:
5791 /* apply new rateset */
5792 memcpy(&wlc->default_bss->rateset, &new,
5793 sizeof(struct brcms_c_rateset));
5794 memcpy(&wlc->bandstate[bandunit]->defrateset, &new,
5795 sizeof(struct brcms_c_rateset));
5796 return 0;
5797}
5798
5799static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc)
5800{
5801 u8 r;
5802 bool war = false;
5803
5804 if (wlc->bsscfg->associated)
5805 r = wlc->bsscfg->current_bss->rateset.rates[0];
5806 else
5807 r = wlc->default_bss->rateset.rates[0];
5808
5809 wlc_phy_ofdm_rateset_war(wlc->band->pi, war);
5810}
5811
5812int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel)
5813{
5814 u16 chspec = ch20mhz_chspec(channel);
5815
5816 if (channel < 0 || channel > MAXCHANNEL)
5817 return -EINVAL;
5818
5819 if (!brcms_c_valid_chanspec_db(wlc->cmi, chspec))
5820 return -EINVAL;
5821
5822
5823 if (!wlc->pub->up && brcms_is_mband_unlocked(wlc)) {
5824 if (wlc->band->bandunit != chspec_bandunit(chspec))
5825 wlc->bandinit_pending = true;
5826 else
5827 wlc->bandinit_pending = false;
5828 }
5829
5830 wlc->default_bss->chanspec = chspec;
5831 /* brcms_c_BSSinit() will sanitize the rateset before
5832 * using it.. */
5833 if (wlc->pub->up && (wlc_phy_chanspec_get(wlc->band->pi) != chspec)) {
5834 brcms_c_set_home_chanspec(wlc, chspec);
5835 brcms_c_suspend_mac_and_wait(wlc);
5836 brcms_c_set_chanspec(wlc, chspec);
5837 brcms_c_enable_mac(wlc);
5838 }
5839 return 0;
5840}
5841
5842int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl)
5843{
5844 int ac;
5845
5846 if (srl < 1 || srl > RETRY_SHORT_MAX ||
5847 lrl < 1 || lrl > RETRY_SHORT_MAX)
5848 return -EINVAL;
5849
5850 wlc->SRL = srl;
5851 wlc->LRL = lrl;
5852
5853 brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
5854
5855 for (ac = 0; ac < AC_COUNT; ac++) {
5856 wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac],
5857 EDCF_SHORT, wlc->SRL);
5858 wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac],
5859 EDCF_LONG, wlc->LRL);
5860 }
5861 brcms_c_wme_retries_write(wlc);
5862
5863 return 0;
5864}
5865
5866void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
5867 struct brcm_rateset *currs)
5868{
5869 struct brcms_c_rateset *rs;
5870
5871 if (wlc->pub->associated)
5872 rs = &wlc->bsscfg->current_bss->rateset;
5873 else
5874 rs = &wlc->default_bss->rateset;
5875
5876 /* Copy only legacy rateset section */
5877 currs->count = rs->count;
5878 memcpy(&currs->rates, &rs->rates, rs->count);
5879}
5880
5881int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs)
5882{
5883 struct brcms_c_rateset internal_rs;
5884 int bcmerror;
5885
5886 if (rs->count > BRCMS_NUMRATES)
5887 return -ENOBUFS;
5888
5889 memset(&internal_rs, 0, sizeof(struct brcms_c_rateset));
5890
5891 /* Copy only legacy rateset section */
5892 internal_rs.count = rs->count;
5893 memcpy(&internal_rs.rates, &rs->rates, internal_rs.count);
5894
5895 /* merge rateset coming in with the current mcsset */
5896 if (wlc->pub->_n_enab & SUPPORT_11N) {
5897 struct brcms_bss_info *mcsset_bss;
5898 if (wlc->bsscfg->associated)
5899 mcsset_bss = wlc->bsscfg->current_bss;
5900 else
5901 mcsset_bss = wlc->default_bss;
5902 memcpy(internal_rs.mcs, &mcsset_bss->rateset.mcs[0],
5903 MCSSET_LEN);
5904 }
5905
5906 bcmerror = brcms_c_set_internal_rateset(wlc, &internal_rs);
5907 if (!bcmerror)
5908 brcms_c_ofdm_rateset_war(wlc);
5909
5910 return bcmerror;
5911}
5912
5913int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
5914{
5915 if (period < DOT11_MIN_BEACON_PERIOD ||
5916 period > DOT11_MAX_BEACON_PERIOD)
5917 return -EINVAL;
5918
5919 wlc->default_bss->beacon_period = period;
5920 return 0;
5921}
5922
5923u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx)
5924{
5925 return wlc->band->phytype;
5926}
5927
5928void brcms_c_set_shortslot_override(struct brcms_c_info *wlc, s8 sslot_override)
5929{
5930 wlc->shortslot_override = sslot_override;
5931
5932 /*
5933 * shortslot is an 11g feature, so no more work if we are
5934 * currently on the 5G band
5935 */
5936 if (wlc->band->bandtype == BRCM_BAND_5G)
5937 return;
5938
5939 if (wlc->pub->up && wlc->pub->associated) {
5940 /* let watchdog or beacon processing update shortslot */
5941 } else if (wlc->pub->up) {
5942 /* unassociated shortslot is off */
5943 brcms_c_switch_shortslot(wlc, false);
5944 } else {
5945 /* driver is down, so just update the brcms_c_info
5946 * value */
5947 if (wlc->shortslot_override == BRCMS_SHORTSLOT_AUTO)
5948 wlc->shortslot = false;
5949 else
5950 wlc->shortslot =
5951 (wlc->shortslot_override ==
5952 BRCMS_SHORTSLOT_ON);
5953 }
5954}
5955
5956/*
5957 * register watchdog and down handlers.
5958 */
5959int brcms_c_module_register(struct brcms_pub *pub,
5960 const char *name, struct brcms_info *hdl,
5961 int (*d_fn)(void *handle))
5962{
5963 struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
5964 int i;
5965
5966 /* find an empty entry and just add, no duplication check! */
5967 for (i = 0; i < BRCMS_MAXMODULES; i++) {
5968 if (wlc->modulecb[i].name[0] == '\0') {
5969 strncpy(wlc->modulecb[i].name, name,
5970 sizeof(wlc->modulecb[i].name) - 1);
5971 wlc->modulecb[i].hdl = hdl;
5972 wlc->modulecb[i].down_fn = d_fn;
5973 return 0;
5974 }
5975 }
5976
5977 return -ENOSR;
5978}
5979
5980/* unregister module callbacks */
5981int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
5982 struct brcms_info *hdl)
5983{
5984 struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
5985 int i;
5986
5987 if (wlc == NULL)
5988 return -ENODATA;
5989
5990 for (i = 0; i < BRCMS_MAXMODULES; i++) {
5991 if (!strcmp(wlc->modulecb[i].name, name) &&
5992 (wlc->modulecb[i].hdl == hdl)) {
5993 memset(&wlc->modulecb[i], 0, sizeof(struct modulecb));
5994 return 0;
5995 }
5996 }
5997
5998 /* table not found! */
5999 return -ENODATA;
6000}
6001
6002#ifdef BCMDBG
6003static const char * const supr_reason[] = {
6004 "None", "PMQ Entry", "Flush request",
6005 "Previous frag failure", "Channel mismatch",
6006 "Lifetime Expiry", "Underflow"
6007};
6008
6009static void brcms_c_print_txs_status(u16 s)
6010{
6011 printk(KERN_DEBUG "[15:12] %d frame attempts\n",
6012 (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT);
6013 printk(KERN_DEBUG " [11:8] %d rts attempts\n",
6014 (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT);
6015 printk(KERN_DEBUG " [7] %d PM mode indicated\n",
6016 ((s & TX_STATUS_PMINDCTD) ? 1 : 0));
6017 printk(KERN_DEBUG " [6] %d intermediate status\n",
6018 ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0));
6019 printk(KERN_DEBUG " [5] %d AMPDU\n",
6020 (s & TX_STATUS_AMPDU) ? 1 : 0);
6021 printk(KERN_DEBUG " [4:2] %d Frame Suppressed Reason (%s)\n",
6022 ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT),
6023 supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]);
6024 printk(KERN_DEBUG " [1] %d acked\n",
6025 ((s & TX_STATUS_ACK_RCV) ? 1 : 0));
6026}
6027#endif /* BCMDBG */
6028
6029void brcms_c_print_txstatus(struct tx_status *txs)
6030{
6031#if defined(BCMDBG)
6032 u16 s = txs->status;
6033 u16 ackphyrxsh = txs->ackphyrxsh;
6034
6035 printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n");
6036
6037 printk(KERN_DEBUG "FrameID: %04x ", txs->frameid);
6038 printk(KERN_DEBUG "TxStatus: %04x", s);
6039 printk(KERN_DEBUG "\n");
6040
6041 brcms_c_print_txs_status(s);
6042
6043 printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime);
6044 printk(KERN_DEBUG "Seq: %04x ", txs->sequence);
6045 printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr);
6046 printk(KERN_DEBUG "RxAckRSSI: %04x ",
6047 (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT);
6048 printk(KERN_DEBUG "RxAckSQ: %04x",
6049 (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
6050 printk(KERN_DEBUG "\n");
6051#endif /* defined(BCMDBG) */
6052}
6053
6054bool brcms_c_chipmatch(u16 vendor, u16 device)
6055{
6056 if (vendor != PCI_VENDOR_ID_BROADCOM) {
6057 pr_err("chipmatch: unknown vendor id %04x\n", vendor);
6058 return false;
6059 }
6060
6061 if (device == BCM43224_D11N_ID_VEN1)
6062 return true;
6063 if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID))
6064 return true;
6065 if (device == BCM4313_D11N2G_ID)
6066 return true;
6067 if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
6068 return true;
6069
6070 pr_err("chipmatch: unknown device id %04x\n", device);
6071 return false;
6072}
6073
6074#if defined(BCMDBG)
6075void brcms_c_print_txdesc(struct d11txh *txh)
6076{
6077 u16 mtcl = le16_to_cpu(txh->MacTxControlLow);
6078 u16 mtch = le16_to_cpu(txh->MacTxControlHigh);
6079 u16 mfc = le16_to_cpu(txh->MacFrameControl);
6080 u16 tfest = le16_to_cpu(txh->TxFesTimeNormal);
6081 u16 ptcw = le16_to_cpu(txh->PhyTxControlWord);
6082 u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1);
6083 u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr);
6084 u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts);
6085 u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts);
6086 u16 mainrates = le16_to_cpu(txh->MainRates);
6087 u16 xtraft = le16_to_cpu(txh->XtraFrameTypes);
6088 u8 *iv = txh->IV;
6089 u8 *ra = txh->TxFrameRA;
6090 u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback);
6091 u8 *rtspfb = txh->RTSPLCPFallback;
6092 u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback);
6093 u8 *fragpfb = txh->FragPLCPFallback;
6094 u16 fragdfb = le16_to_cpu(txh->FragDurFallback);
6095 u16 mmodelen = le16_to_cpu(txh->MModeLen);
6096 u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen);
6097 u16 tfid = le16_to_cpu(txh->TxFrameID);
6098 u16 txs = le16_to_cpu(txh->TxStatus);
6099 u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus);
6100 u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT);
6101 u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR);
6102 u16 mmbyte = le16_to_cpu(txh->MinMBytes);
6103
6104 u8 *rtsph = txh->RTSPhyHeader;
6105 struct ieee80211_rts rts = txh->rts_frame;
6106 char hexbuf[256];
6107
6108 /* add plcp header along with txh descriptor */
6109 printk(KERN_DEBUG "Raw TxDesc + plcp header:\n");
6110 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
6111 txh, sizeof(struct d11txh) + 48);
6112
6113 printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl);
6114 printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch);
6115 printk(KERN_DEBUG "FC: %04x ", mfc);
6116 printk(KERN_DEBUG "FES Time: %04x\n", tfest);
6117 printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw,
6118 (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
6119 printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1);
6120 printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
6121 printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
6122 printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
6123 printk(KERN_DEBUG "MainRates: %04x ", mainrates);
6124 printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft);
6125 printk(KERN_DEBUG "\n");
6126
6127 brcmu_format_hex(hexbuf, iv, sizeof(txh->IV));
6128 printk(KERN_DEBUG "SecIV: %s\n", hexbuf);
6129 brcmu_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA));
6130 printk(KERN_DEBUG "RA: %s\n", hexbuf);
6131
6132 printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb);
6133 brcmu_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback));
6134 printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf);
6135 printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb);
6136 brcmu_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback));
6137 printk(KERN_DEBUG "PLCP: %s ", hexbuf);
6138 printk(KERN_DEBUG "DUR: %04x", fragdfb);
6139 printk(KERN_DEBUG "\n");
6140
6141 printk(KERN_DEBUG "MModeLen: %04x ", mmodelen);
6142 printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen);
6143
6144 printk(KERN_DEBUG "FrameID: %04x\n", tfid);
6145 printk(KERN_DEBUG "TxStatus: %04x\n", txs);
6146
6147 printk(KERN_DEBUG "MaxNumMpdu: %04x\n", mnmpdu);
6148 printk(KERN_DEBUG "MaxAggbyte: %04x\n", mabyte);
6149 printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f);
6150 printk(KERN_DEBUG "MinByte: %04x\n", mmbyte);
6151
6152 brcmu_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader));
6153 printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf);
6154 brcmu_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame));
6155 printk(KERN_DEBUG "RTS Frame: %s", hexbuf);
6156 printk(KERN_DEBUG "\n");
6157}
6158#endif /* defined(BCMDBG) */
6159
6160#if defined(BCMDBG)
6161int
6162brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf,
6163 int len)
6164{
6165 int i;
6166 char *p = buf;
6167 char hexstr[16];
6168 int slen = 0, nlen = 0;
6169 u32 bit;
6170 const char *name;
6171
6172 if (len < 2 || !buf)
6173 return 0;
6174
6175 buf[0] = '\0';
6176
6177 for (i = 0; flags != 0; i++) {
6178 bit = bd[i].bit;
6179 name = bd[i].name;
6180 if (bit == 0 && flags != 0) {
6181 /* print any unnamed bits */
6182 snprintf(hexstr, 16, "0x%X", flags);
6183 name = hexstr;
6184 flags = 0; /* exit loop */
6185 } else if ((flags & bit) == 0)
6186 continue;
6187 flags &= ~bit;
6188 nlen = strlen(name);
6189 slen += nlen;
6190 /* count btwn flag space */
6191 if (flags != 0)
6192 slen += 1;
6193 /* need NULL char as well */
6194 if (len <= slen)
6195 break;
6196 /* copy NULL char but don't count it */
6197 strncpy(p, name, nlen + 1);
6198 p += nlen;
6199 /* copy btwn flag space and NULL char */
6200 if (flags != 0)
6201 p += snprintf(p, 2, " ");
6202 len -= slen;
6203 }
6204
6205 /* indicate the str was too short */
6206 if (flags != 0) {
6207 if (len < 2)
6208 p -= 2 - len; /* overwrite last char */
6209 p += snprintf(p, 2, ">");
6210 }
6211
6212 return (int)(p - buf);
6213}
6214#endif /* defined(BCMDBG) */
6215
6216#if defined(BCMDBG)
6217void brcms_c_print_rxh(struct d11rxhdr *rxh)
6218{
6219 u16 len = rxh->RxFrameSize;
6220 u16 phystatus_0 = rxh->PhyRxStatus_0;
6221 u16 phystatus_1 = rxh->PhyRxStatus_1;
6222 u16 phystatus_2 = rxh->PhyRxStatus_2;
6223 u16 phystatus_3 = rxh->PhyRxStatus_3;
6224 u16 macstatus1 = rxh->RxStatus1;
6225 u16 macstatus2 = rxh->RxStatus2;
6226 char flagstr[64];
6227 char lenbuf[20];
6228 static const struct brcms_c_bit_desc macstat_flags[] = {
6229 {RXS_FCSERR, "FCSErr"},
6230 {RXS_RESPFRAMETX, "Reply"},
6231 {RXS_PBPRES, "PADDING"},
6232 {RXS_DECATMPT, "DeCr"},
6233 {RXS_DECERR, "DeCrErr"},
6234 {RXS_BCNSENT, "Bcn"},
6235 {0, NULL}
6236 };
6237
6238 printk(KERN_DEBUG "Raw RxDesc:\n");
6239 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh,
6240 sizeof(struct d11rxhdr));
6241
6242 brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64);
6243
6244 snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);
6245
6246 printk(KERN_DEBUG "RxFrameSize: %6s (%d)%s\n", lenbuf, len,
6247 (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
6248 printk(KERN_DEBUG "RxPHYStatus: %04x %04x %04x %04x\n",
6249 phystatus_0, phystatus_1, phystatus_2, phystatus_3);
6250 printk(KERN_DEBUG "RxMACStatus: %x %s\n", macstatus1, flagstr);
6251 printk(KERN_DEBUG "RXMACaggtype: %x\n",
6252 (macstatus2 & RXS_AGGTYPE_MASK));
6253 printk(KERN_DEBUG "RxTSFTime: %04x\n", rxh->RxTSFTime);
6254}
6255#endif /* defined(BCMDBG) */
6256
6257u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
6258{
6259 u16 table_ptr;
6260 u8 phy_rate, index;
6261
6262 /* get the phy specific rate encoding for the PLCP SIGNAL field */
6263 if (is_ofdm_rate(rate))
6264 table_ptr = M_RT_DIRMAP_A;
6265 else
6266 table_ptr = M_RT_DIRMAP_B;
6267
6268 /* for a given rate, the LS-nibble of the PLCP SIGNAL field is
6269 * the index into the rate table.
6270 */
6271 phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
6272 index = phy_rate & 0xf;
6273
6274 /* Find the SHM pointer to the rate table entry by looking in the
6275 * Direct-map Table
6276 */
6277 return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2));
6278}
6279
6280static bool
6281brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q,
6282 struct sk_buff *pkt, int prec, bool head)
6283{
6284 struct sk_buff *p;
6285 int eprec = -1; /* precedence to evict from */
6286
6287 /* Determine precedence from which to evict packet, if any */
6288 if (pktq_pfull(q, prec))
6289 eprec = prec;
6290 else if (pktq_full(q)) {
6291 p = brcmu_pktq_peek_tail(q, &eprec);
6292 if (eprec > prec) {
6293 wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d"
6294 "\n", __func__, eprec, prec);
6295 return false;
6296 }
6297 }
6298
6299 /* Evict if needed */
6300 if (eprec >= 0) {
6301 bool discard_oldest;
6302
6303 discard_oldest = ac_bitmap_tst(0, eprec);
6304
6305 /* Refuse newer packet unless configured to discard oldest */
6306 if (eprec == prec && !discard_oldest) {
6307 wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d"
6308 "\n", __func__, prec);
6309 return false;
6310 }
6311
6312 /* Evict packet according to discard policy */
6313 p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
6314 brcmu_pktq_pdeq_tail(q, eprec);
6315 brcmu_pkt_buf_free_skb(p);
6316 }
6317
6318 /* Enqueue */
6319 if (head)
6320 p = brcmu_pktq_penq_head(q, prec, pkt);
6321 else
6322 p = brcmu_pktq_penq(q, prec, pkt);
6323
6324 return true;
6325}
6326
6327/*
6328 * Attempts to queue a packet onto a multiple-precedence queue,
6329 * if necessary evicting a lower precedence packet from the queue.
6330 *
6331 * 'prec' is the precedence number that has already been mapped
6332 * from the packet priority.
6333 *
6334 * Returns true if packet consumed (queued), false if not.
6335 */
6336static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q,
6337 struct sk_buff *pkt, int prec)
6338{
6339 return brcms_c_prec_enq_head(wlc, q, pkt, prec, false);
6340}
6341
6342void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
6343 struct sk_buff *sdu, uint prec)
6344{
6345 struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */
6346 struct pktq *q = &qi->q;
6347 int prio;
6348
6349 prio = sdu->priority;
6350
6351 if (!brcms_c_prec_enq(wlc, q, sdu, prec)) {
6352 /*
6353 * we might hit this condtion in case
6354 * packet flooding from mac80211 stack
6355 */
6356 brcmu_pkt_buf_free_skb(sdu);
6357 }
6358}
6359
6360/*
6361 * bcmc_fid_generate:
6362 * Generate frame ID for a BCMC packet. The frag field is not used
6363 * for MC frames so is used as part of the sequence number.
6364 */
6365static inline u16
6366bcmc_fid_generate(struct brcms_c_info *wlc, struct brcms_bss_cfg *bsscfg,
6367 struct d11txh *txh)
6368{
6369 u16 frameid;
6370
6371 frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK |
6372 TXFID_QUEUE_MASK);
6373 frameid |=
6374 (((wlc->
6375 mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
6376 TX_BCMC_FIFO;
6377
6378 return frameid;
6379}
6380
6381static uint
6382brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec,
6383 u8 preamble_type)
6384{
6385 uint dur = 0;
6386
6387 BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n",
6388 wlc->pub->unit, rspec, preamble_type);
6389 /*
6390 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
6391 * is less than or equal to the rate of the immediately previous
6392 * frame in the FES
6393 */
6394 rspec = brcms_basic_rate(wlc, rspec);
6395 /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */
6396 dur =
6397 brcms_c_calc_frame_time(wlc, rspec, preamble_type,
6398 (DOT11_ACK_LEN + FCS_LEN));
6399 return dur;
6400}
6401
6402static uint
6403brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec,
6404 u8 preamble_type)
6405{
6406 BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n",
6407 wlc->pub->unit, rspec, preamble_type);
6408 return brcms_c_calc_ack_time(wlc, rspec, preamble_type);
6409}
6410
6411static uint
6412brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec,
6413 u8 preamble_type)
6414{
6415 BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, "
6416 "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type);
6417 /*
6418 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
6419 * is less than or equal to the rate of the immediately previous
6420 * frame in the FES
6421 */
6422 rspec = brcms_basic_rate(wlc, rspec);
6423 /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */
6424 return brcms_c_calc_frame_time(wlc, rspec, preamble_type,
6425 (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN +
6426 FCS_LEN));
6427}
6428
6429/* brcms_c_compute_frame_dur()
6430 *
6431 * Calculate the 802.11 MAC header DUR field for MPDU
6432 * DUR for a single frame = 1 SIFS + 1 ACK
6433 * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time
6434 *
6435 * rate MPDU rate in unit of 500kbps
6436 * next_frag_len next MPDU length in bytes
6437 * preamble_type use short/GF or long/MM PLCP header
6438 */
6439static u16
6440brcms_c_compute_frame_dur(struct brcms_c_info *wlc, u32 rate,
6441 u8 preamble_type, uint next_frag_len)
6442{
6443 u16 dur, sifs;
6444
6445 sifs = get_sifs(wlc->band);
6446
6447 dur = sifs;
6448 dur += (u16) brcms_c_calc_ack_time(wlc, rate, preamble_type);
6449
6450 if (next_frag_len) {
6451 /* Double the current DUR to get 2 SIFS + 2 ACKs */
6452 dur *= 2;
6453 /* add another SIFS and the frag time */
6454 dur += sifs;
6455 dur +=
6456 (u16) brcms_c_calc_frame_time(wlc, rate, preamble_type,
6457 next_frag_len);
6458 }
6459 return dur;
6460}
6461
6462/* The opposite of brcms_c_calc_frame_time */
6463static uint
6464brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec,
6465 u8 preamble_type, uint dur)
6466{
6467 uint nsyms, mac_len, Ndps, kNdps;
6468 uint rate = rspec2rate(ratespec);
6469
6470 BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n",
6471 wlc->pub->unit, ratespec, preamble_type, dur);
6472
6473 if (is_mcs_rate(ratespec)) {
6474 uint mcs = ratespec & RSPEC_RATE_MASK;
6475 int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
6476 dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
6477 /* payload calculation matches that of regular ofdm */
6478 if (wlc->band->bandtype == BRCM_BAND_2G)
6479 dur -= DOT11_OFDM_SIGNAL_EXTENSION;
6480 /* kNdbps = kbps * 4 */
6481 kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
6482 rspec_issgi(ratespec)) * 4;
6483 nsyms = dur / APHY_SYMBOL_TIME;
6484 mac_len =
6485 ((nsyms * kNdps) -
6486 ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000;
6487 } else if (is_ofdm_rate(ratespec)) {
6488 dur -= APHY_PREAMBLE_TIME;
6489 dur -= APHY_SIGNAL_TIME;
6490 /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
6491 Ndps = rate * 2;
6492 nsyms = dur / APHY_SYMBOL_TIME;
6493 mac_len =
6494 ((nsyms * Ndps) -
6495 (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8;
6496 } else {
6497 if (preamble_type & BRCMS_SHORT_PREAMBLE)
6498 dur -= BPHY_PLCP_SHORT_TIME;
6499 else
6500 dur -= BPHY_PLCP_TIME;
6501 mac_len = dur * rate;
6502 /* divide out factor of 2 in rate (1/2 mbps) */
6503 mac_len = mac_len / 8 / 2;
6504 }
6505 return mac_len;
6506}
6507
6508/*
6509 * Return true if the specified rate is supported by the specified band.
6510 * BRCM_BAND_AUTO indicates the current band.
6511 */
6512static bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band,
6513 bool verbose)
6514{
6515 struct brcms_c_rateset *hw_rateset;
6516 uint i;
6517
6518 if ((band == BRCM_BAND_AUTO) || (band == wlc->band->bandtype))
6519 hw_rateset = &wlc->band->hw_rateset;
6520 else if (wlc->pub->_nbands > 1)
6521 hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset;
6522 else
6523 /* other band specified and we are a single band device */
6524 return false;
6525
6526 /* check if this is a mimo rate */
6527 if (is_mcs_rate(rspec)) {
6528 if ((rspec & RSPEC_RATE_MASK) >= MCS_TABLE_SIZE)
6529 goto error;
6530
6531 return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK));
6532 }
6533
6534 for (i = 0; i < hw_rateset->count; i++)
6535 if (hw_rateset->rates[i] == rspec2rate(rspec))
6536 return true;
6537 error:
6538 if (verbose)
6539 wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x "
6540 "not in hw_rateset\n", wlc->pub->unit, rspec);
6541
6542 return false;
6543}
6544
6545static u32
6546mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
6547 u32 int_val)
6548{
6549 u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT;
6550 u8 rate = int_val & NRATE_RATE_MASK;
6551 u32 rspec;
6552 bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE);
6553 bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT);
6554 bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY)
6555 == NRATE_OVERRIDE_MCS_ONLY);
6556 int bcmerror = 0;
6557
6558 if (!ismcs)
6559 return (u32) rate;
6560
6561 /* validate the combination of rate/mcs/stf is allowed */
6562 if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) {
6563 /* mcs only allowed when nmode */
6564 if (stf > PHY_TXC1_MODE_SDM) {
6565 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n",
6566 wlc->pub->unit, __func__);
6567 bcmerror = -EINVAL;
6568 goto done;
6569 }
6570
6571 /* mcs 32 is a special case, DUP mode 40 only */
6572 if (rate == 32) {
6573 if (!CHSPEC_IS40(wlc->home_chanspec) ||
6574 ((stf != PHY_TXC1_MODE_SISO)
6575 && (stf != PHY_TXC1_MODE_CDD))) {
6576 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs "
6577 "32\n", wlc->pub->unit, __func__);
6578 bcmerror = -EINVAL;
6579 goto done;
6580 }
6581 /* mcs > 7 must use stf SDM */
6582 } else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
6583 /* mcs > 7 must use stf SDM */
6584 if (stf != PHY_TXC1_MODE_SDM) {
6585 BCMMSG(wlc->wiphy, "wl%d: enabling "
6586 "SDM mode for mcs %d\n",
6587 wlc->pub->unit, rate);
6588 stf = PHY_TXC1_MODE_SDM;
6589 }
6590 } else {
6591 /*
6592 * MCS 0-7 may use SISO, CDD, and for
6593 * phy_rev >= 3 STBC
6594 */
6595 if ((stf > PHY_TXC1_MODE_STBC) ||
6596 (!BRCMS_STBC_CAP_PHY(wlc)
6597 && (stf == PHY_TXC1_MODE_STBC))) {
6598 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC"
6599 "\n", wlc->pub->unit, __func__);
6600 bcmerror = -EINVAL;
6601 goto done;
6602 }
6603 }
6604 } else if (is_ofdm_rate(rate)) {
6605 if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
6606 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n",
6607 wlc->pub->unit, __func__);
6608 bcmerror = -EINVAL;
6609 goto done;
6610 }
6611 } else if (is_cck_rate(rate)) {
6612 if ((cur_band->bandtype != BRCM_BAND_2G)
6613 || (stf != PHY_TXC1_MODE_SISO)) {
6614 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n",
6615 wlc->pub->unit, __func__);
6616 bcmerror = -EINVAL;
6617 goto done;
6618 }
6619 } else {
6620 wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n",
6621 wlc->pub->unit, __func__);
6622 bcmerror = -EINVAL;
6623 goto done;
6624 }
6625 /* make sure multiple antennae are available for non-siso rates */
6626 if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
6627 wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO "
6628 "request\n", wlc->pub->unit, __func__);
6629 bcmerror = -EINVAL;
6630 goto done;
6631 }
6632
6633 rspec = rate;
6634 if (ismcs) {
6635 rspec |= RSPEC_MIMORATE;
6636 /* For STBC populate the STC field of the ratespec */
6637 if (stf == PHY_TXC1_MODE_STBC) {
6638 u8 stc;
6639 stc = 1; /* Nss for single stream is always 1 */
6640 rspec |= (stc << RSPEC_STC_SHIFT);
6641 }
6642 }
6643
6644 rspec |= (stf << RSPEC_STF_SHIFT);
6645
6646 if (override_mcs_only)
6647 rspec |= RSPEC_OVERRIDE_MCS_ONLY;
6648
6649 if (issgi)
6650 rspec |= RSPEC_SHORT_GI;
6651
6652 if ((rate != 0)
6653 && !brcms_c_valid_rate(wlc, rspec, cur_band->bandtype, true))
6654 return rate;
6655
6656 return rspec;
6657done:
6658 return rate;
6659}
6660
6661/*
6662 * Compute PLCP, but only requires actual rate and length of pkt.
6663 * Rate is given in the driver standard multiple of 500 kbps.
6664 * le is set for 11 Mbps rate if necessary.
6665 * Broken out for PRQ.
6666 */
6667
6668static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500,
6669 uint length, u8 *plcp)
6670{
6671 u16 usec = 0;
6672 u8 le = 0;
6673
6674 switch (rate_500) {
6675 case BRCM_RATE_1M:
6676 usec = length << 3;
6677 break;
6678 case BRCM_RATE_2M:
6679 usec = length << 2;
6680 break;
6681 case BRCM_RATE_5M5:
6682 usec = (length << 4) / 11;
6683 if ((length << 4) - (usec * 11) > 0)
6684 usec++;
6685 break;
6686 case BRCM_RATE_11M:
6687 usec = (length << 3) / 11;
6688 if ((length << 3) - (usec * 11) > 0) {
6689 usec++;
6690 if ((usec * 11) - (length << 3) >= 8)
6691 le = D11B_PLCP_SIGNAL_LE;
6692 }
6693 break;
6694
6695 default:
6696 wiphy_err(wlc->wiphy,
6697 "brcms_c_cck_plcp_set: unsupported rate %d\n",
6698 rate_500);
6699 rate_500 = BRCM_RATE_1M;
6700 usec = length << 3;
6701 break;
6702 }
6703 /* PLCP signal byte */
6704 plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */
6705 /* PLCP service byte */
6706 plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED);
6707 /* PLCP length u16, little endian */
6708 plcp[2] = usec & 0xff;
6709 plcp[3] = (usec >> 8) & 0xff;
6710 /* PLCP CRC16 */
6711 plcp[4] = 0;
6712 plcp[5] = 0;
6713}
6714
6715/* Rate: 802.11 rate code, length: PSDU length in octets */
6716static void brcms_c_compute_mimo_plcp(u32 rspec, uint length, u8 *plcp)
6717{
6718 u8 mcs = (u8) (rspec & RSPEC_RATE_MASK);
6719 plcp[0] = mcs;
6720 if (rspec_is40mhz(rspec) || (mcs == 32))
6721 plcp[0] |= MIMO_PLCP_40MHZ;
6722 BRCMS_SET_MIMO_PLCP_LEN(plcp, length);
6723 plcp[3] = rspec_mimoplcp3(rspec); /* rspec already holds this byte */
6724 plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */
6725 plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */
6726 plcp[5] = 0;
6727}
6728
6729/* Rate: 802.11 rate code, length: PSDU length in octets */
6730static void
6731brcms_c_compute_ofdm_plcp(u32 rspec, u32 length, u8 *plcp)
6732{
6733 u8 rate_signal;
6734 u32 tmp = 0;
6735 int rate = rspec2rate(rspec);
6736
6737 /*
6738 * encode rate per 802.11a-1999 sec 17.3.4.1, with lsb
6739 * transmitted first
6740 */
6741 rate_signal = rate_info[rate] & BRCMS_RATE_MASK;
6742 memset(plcp, 0, D11_PHY_HDR_LEN);
6743 D11A_PHY_HDR_SRATE((struct ofdm_phy_hdr *) plcp, rate_signal);
6744
6745 tmp = (length & 0xfff) << 5;
6746 plcp[2] |= (tmp >> 16) & 0xff;
6747 plcp[1] |= (tmp >> 8) & 0xff;
6748 plcp[0] |= tmp & 0xff;
6749}
6750
6751/* Rate: 802.11 rate code, length: PSDU length in octets */
6752static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, u32 rspec,
6753 uint length, u8 *plcp)
6754{
6755 int rate = rspec2rate(rspec);
6756
6757 brcms_c_cck_plcp_set(wlc, rate, length, plcp);
6758}
6759
6760static void
6761brcms_c_compute_plcp(struct brcms_c_info *wlc, u32 rspec,
6762 uint length, u8 *plcp)
6763{
6764 if (is_mcs_rate(rspec))
6765 brcms_c_compute_mimo_plcp(rspec, length, plcp);
6766 else if (is_ofdm_rate(rspec))
6767 brcms_c_compute_ofdm_plcp(rspec, length, plcp);
6768 else
6769 brcms_c_compute_cck_plcp(wlc, rspec, length, plcp);
6770}
6771
6772/* brcms_c_compute_rtscts_dur()
6773 *
6774 * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
6775 * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
6776 * DUR for CTS-TO-SELF w/ frame = 2 SIFS + next frame time + 1 ACK
6777 *
6778 * cts cts-to-self or rts/cts
6779 * rts_rate rts or cts rate in unit of 500kbps
6780 * rate next MPDU rate in unit of 500kbps
6781 * frame_len next MPDU frame length in bytes
6782 */
6783u16
6784brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
6785 u32 rts_rate,
6786 u32 frame_rate, u8 rts_preamble_type,
6787 u8 frame_preamble_type, uint frame_len, bool ba)
6788{
6789 u16 dur, sifs;
6790
6791 sifs = get_sifs(wlc->band);
6792
6793 if (!cts_only) {
6794 /* RTS/CTS */
6795 dur = 3 * sifs;
6796 dur +=
6797 (u16) brcms_c_calc_cts_time(wlc, rts_rate,
6798 rts_preamble_type);
6799 } else {
6800 /* CTS-TO-SELF */
6801 dur = 2 * sifs;
6802 }
6803
6804 dur +=
6805 (u16) brcms_c_calc_frame_time(wlc, frame_rate, frame_preamble_type,
6806 frame_len);
6807 if (ba)
6808 dur +=
6809 (u16) brcms_c_calc_ba_time(wlc, frame_rate,
6810 BRCMS_SHORT_PREAMBLE);
6811 else
6812 dur +=
6813 (u16) brcms_c_calc_ack_time(wlc, frame_rate,
6814 frame_preamble_type);
6815 return dur;
6816}
6817
6818static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec)
6819{
6820 u16 phyctl1 = 0;
6821 u16 bw;
6822
6823 if (BRCMS_ISLCNPHY(wlc->band)) {
6824 bw = PHY_TXC1_BW_20MHZ;
6825 } else {
6826 bw = rspec_get_bw(rspec);
6827 /* 10Mhz is not supported yet */
6828 if (bw < PHY_TXC1_BW_20MHZ) {
6829 wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is "
6830 "not supported yet, set to 20L\n", bw);
6831 bw = PHY_TXC1_BW_20MHZ;
6832 }
6833 }
6834
6835 if (is_mcs_rate(rspec)) {
6836 uint mcs = rspec & RSPEC_RATE_MASK;
6837
6838 /* bw, stf, coding-type is part of rspec_phytxbyte2 returns */
6839 phyctl1 = rspec_phytxbyte2(rspec);
6840 /* set the upper byte of phyctl1 */
6841 phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8);
6842 } else if (is_cck_rate(rspec) && !BRCMS_ISLCNPHY(wlc->band)
6843 && !BRCMS_ISSSLPNPHY(wlc->band)) {
6844 /*
6845 * In CCK mode LPPHY overloads OFDM Modulation bits with CCK
6846 * Data Rate. Eventually MIMOPHY would also be converted to
6847 * this format
6848 */
6849 /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
6850 phyctl1 = (bw | (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
6851 } else { /* legacy OFDM/CCK */
6852 s16 phycfg;
6853 /* get the phyctl byte from rate phycfg table */
6854 phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec));
6855 if (phycfg == -1) {
6856 wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong "
6857 "legacy OFDM/CCK rate\n");
6858 phycfg = 0;
6859 }
6860 /* set the upper byte of phyctl1 */
6861 phyctl1 =
6862 (bw | (phycfg << 8) |
6863 (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
6864 }
6865 return phyctl1;
6866}
6867
6868/*
6869 * Add struct d11txh, struct cck_phy_hdr.
6870 *
6871 * 'p' data must start with 802.11 MAC header
6872 * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
6873 *
6874 * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
6875 *
6876 */
6877static u16
6878brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
6879 struct sk_buff *p, struct scb *scb, uint frag,
6880 uint nfrags, uint queue, uint next_frag_len)
6881{
6882 struct ieee80211_hdr *h;
6883 struct d11txh *txh;
6884 u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN];
6885 int len, phylen, rts_phylen;
6886 u16 mch, phyctl, xfts, mainrates;
6887 u16 seq = 0, mcl = 0, status = 0, frameid = 0;
6888 u32 rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
6889 u32 rts_rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
6890 bool use_rts = false;
6891 bool use_cts = false;
6892 bool use_rifs = false;
6893 bool short_preamble[2] = { false, false };
6894 u8 preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
6895 u8 rts_preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
6896 u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN];
6897 struct ieee80211_rts *rts = NULL;
6898 bool qos;
6899 uint ac;
6900 bool hwtkmic = false;
6901 u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
6902#define ANTCFG_NONE 0xFF
6903 u8 antcfg = ANTCFG_NONE;
6904 u8 fbantcfg = ANTCFG_NONE;
6905 uint phyctl1_stf = 0;
6906 u16 durid = 0;
6907 struct ieee80211_tx_rate *txrate[2];
6908 int k;
6909 struct ieee80211_tx_info *tx_info;
6910 bool is_mcs;
6911 u16 mimo_txbw;
6912 u8 mimo_preamble_type;
6913
6914 /* locate 802.11 MAC header */
6915 h = (struct ieee80211_hdr *)(p->data);
6916 qos = ieee80211_is_data_qos(h->frame_control);
6917
6918 /* compute length of frame in bytes for use in PLCP computations */
6919 len = brcmu_pkttotlen(p);
6920 phylen = len + FCS_LEN;
6921
6922 /* Get tx_info */
6923 tx_info = IEEE80211_SKB_CB(p);
6924
6925 /* add PLCP */
6926 plcp = skb_push(p, D11_PHY_HDR_LEN);
6927
6928 /* add Broadcom tx descriptor header */
6929 txh = (struct d11txh *) skb_push(p, D11_TXH_LEN);
6930 memset(txh, 0, D11_TXH_LEN);
6931
6932 /* setup frameid */
6933 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
6934 /* non-AP STA should never use BCMC queue */
6935 if (queue == TX_BCMC_FIFO) {
6936 wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == "
6937 "TX_BCMC!\n", wlc->pub->unit, __func__);
6938 frameid = bcmc_fid_generate(wlc, NULL, txh);
6939 } else {
6940 /* Increment the counter for first fragment */
6941 if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
6942 scb->seqnum[p->priority]++;
6943
6944 /* extract fragment number from frame first */
6945 seq = le16_to_cpu(h->seq_ctrl) & FRAGNUM_MASK;
6946 seq |= (scb->seqnum[p->priority] << SEQNUM_SHIFT);
6947 h->seq_ctrl = cpu_to_le16(seq);
6948
6949 frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
6950 (queue & TXFID_QUEUE_MASK);
6951 }
6952 }
6953 frameid |= queue & TXFID_QUEUE_MASK;
6954
6955 /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */
6956 if (ieee80211_is_beacon(h->frame_control))
6957 mcl |= TXC_IGNOREPMQ;
6958
6959 txrate[0] = tx_info->control.rates;
6960 txrate[1] = txrate[0] + 1;
6961
6962 /*
6963 * if rate control algorithm didn't give us a fallback
6964 * rate, use the primary rate
6965 */
6966 if (txrate[1]->idx < 0)
6967 txrate[1] = txrate[0];
6968
6969 for (k = 0; k < hw->max_rates; k++) {
6970 is_mcs = txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false;
6971 if (!is_mcs) {
6972 if ((txrate[k]->idx >= 0)
6973 && (txrate[k]->idx <
6974 hw->wiphy->bands[tx_info->band]->n_bitrates)) {
6975 rspec[k] =
6976 hw->wiphy->bands[tx_info->band]->
6977 bitrates[txrate[k]->idx].hw_value;
6978 short_preamble[k] =
6979 txrate[k]->
6980 flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ?
6981 true : false;
6982 } else {
6983 rspec[k] = BRCM_RATE_1M;
6984 }
6985 } else {
6986 rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band,
6987 NRATE_MCS_INUSE | txrate[k]->idx);
6988 }
6989
6990 /*
6991 * Currently only support same setting for primay and
6992 * fallback rates. Unify flags for each rate into a
6993 * single value for the frame
6994 */
6995 use_rts |=
6996 txrate[k]->
6997 flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false;
6998 use_cts |=
6999 txrate[k]->
7000 flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false;
7001
7002
7003 /*
7004 * (1) RATE:
7005 * determine and validate primary rate
7006 * and fallback rates
7007 */
7008 if (!rspec_active(rspec[k])) {
7009 rspec[k] = BRCM_RATE_1M;
7010 } else {
7011 if (!is_multicast_ether_addr(h->addr1)) {
7012 /* set tx antenna config */
7013 brcms_c_antsel_antcfg_get(wlc->asi, false,
7014 false, 0, 0, &antcfg, &fbantcfg);
7015 }
7016 }
7017 }
7018
7019 phyctl1_stf = wlc->stf->ss_opmode;
7020
7021 if (wlc->pub->_n_enab & SUPPORT_11N) {
7022 for (k = 0; k < hw->max_rates; k++) {
7023 /*
7024 * apply siso/cdd to single stream mcs's or ofdm
7025 * if rspec is auto selected
7026 */
7027 if (((is_mcs_rate(rspec[k]) &&
7028 is_single_stream(rspec[k] & RSPEC_RATE_MASK)) ||
7029 is_ofdm_rate(rspec[k]))
7030 && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY)
7031 || !(rspec[k] & RSPEC_OVERRIDE))) {
7032 rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK);
7033
7034 /* For SISO MCS use STBC if possible */
7035 if (is_mcs_rate(rspec[k])
7036 && BRCMS_STF_SS_STBC_TX(wlc, scb)) {
7037 u8 stc;
7038
7039 /* Nss for single stream is always 1 */
7040 stc = 1;
7041 rspec[k] |= (PHY_TXC1_MODE_STBC <<
7042 RSPEC_STF_SHIFT) |
7043 (stc << RSPEC_STC_SHIFT);
7044 } else
7045 rspec[k] |=
7046 (phyctl1_stf << RSPEC_STF_SHIFT);
7047 }
7048
7049 /*
7050 * Is the phy configured to use 40MHZ frames? If
7051 * so then pick the desired txbw
7052 */
7053 if (brcms_chspec_bw(wlc->chanspec) == BRCMS_40_MHZ) {
7054 /* default txbw is 20in40 SB */
7055 mimo_ctlchbw = mimo_txbw =
7056 CHSPEC_SB_UPPER(wlc_phy_chanspec_get(
7057 wlc->band->pi))
7058 ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
7059
7060 if (is_mcs_rate(rspec[k])) {
7061 /* mcs 32 must be 40b/w DUP */
7062 if ((rspec[k] & RSPEC_RATE_MASK)
7063 == 32) {
7064 mimo_txbw =
7065 PHY_TXC1_BW_40MHZ_DUP;
7066 /* use override */
7067 } else if (wlc->mimo_40txbw != AUTO)
7068 mimo_txbw = wlc->mimo_40txbw;
7069 /* else check if dst is using 40 Mhz */
7070 else if (scb->flags & SCB_IS40)
7071 mimo_txbw = PHY_TXC1_BW_40MHZ;
7072 } else if (is_ofdm_rate(rspec[k])) {
7073 if (wlc->ofdm_40txbw != AUTO)
7074 mimo_txbw = wlc->ofdm_40txbw;
7075 } else if (wlc->cck_40txbw != AUTO) {
7076 mimo_txbw = wlc->cck_40txbw;
7077 }
7078 } else {
7079 /*
7080 * mcs32 is 40 b/w only.
7081 * This is possible for probe packets on
7082 * a STA during SCAN
7083 */
7084 if ((rspec[k] & RSPEC_RATE_MASK) == 32)
7085 /* mcs 0 */
7086 rspec[k] = RSPEC_MIMORATE;
7087
7088 mimo_txbw = PHY_TXC1_BW_20MHZ;
7089 }
7090
7091 /* Set channel width */
7092 rspec[k] &= ~RSPEC_BW_MASK;
7093 if ((k == 0) || ((k > 0) && is_mcs_rate(rspec[k])))
7094 rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT);
7095 else
7096 rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
7097
7098 /* Disable short GI, not supported yet */
7099 rspec[k] &= ~RSPEC_SHORT_GI;
7100
7101 mimo_preamble_type = BRCMS_MM_PREAMBLE;
7102 if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD)
7103 mimo_preamble_type = BRCMS_GF_PREAMBLE;
7104
7105 if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
7106 && (!is_mcs_rate(rspec[k]))) {
7107 wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_"
7108 "RC_MCS != is_mcs_rate(rspec)\n",
7109 wlc->pub->unit, __func__);
7110 }
7111
7112 if (is_mcs_rate(rspec[k])) {
7113 preamble_type[k] = mimo_preamble_type;
7114
7115 /*
7116 * if SGI is selected, then forced mm
7117 * for single stream
7118 */
7119 if ((rspec[k] & RSPEC_SHORT_GI)
7120 && is_single_stream(rspec[k] &
7121 RSPEC_RATE_MASK))
7122 preamble_type[k] = BRCMS_MM_PREAMBLE;
7123 }
7124
7125 /* should be better conditionalized */
7126 if (!is_mcs_rate(rspec[0])
7127 && (tx_info->control.rates[0].
7128 flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
7129 preamble_type[k] = BRCMS_SHORT_PREAMBLE;
7130 }
7131 } else {
7132 for (k = 0; k < hw->max_rates; k++) {
7133 /* Set ctrlchbw as 20Mhz */
7134 rspec[k] &= ~RSPEC_BW_MASK;
7135 rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT);
7136
7137 /* for nphy, stf of ofdm frames must follow policies */
7138 if (BRCMS_ISNPHY(wlc->band) && is_ofdm_rate(rspec[k])) {
7139 rspec[k] &= ~RSPEC_STF_MASK;
7140 rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT;
7141 }
7142 }
7143 }
7144
7145 /* Reset these for use with AMPDU's */
7146 txrate[0]->count = 0;
7147 txrate[1]->count = 0;
7148
7149 /* (2) PROTECTION, may change rspec */
7150 if ((ieee80211_is_data(h->frame_control) ||
7151 ieee80211_is_mgmt(h->frame_control)) &&
7152 (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1))
7153 use_rts = true;
7154
7155 /* (3) PLCP: determine PLCP header and MAC duration,
7156 * fill struct d11txh */
7157 brcms_c_compute_plcp(wlc, rspec[0], phylen, plcp);
7158 brcms_c_compute_plcp(wlc, rspec[1], phylen, plcp_fallback);
7159 memcpy(&txh->FragPLCPFallback,
7160 plcp_fallback, sizeof(txh->FragPLCPFallback));
7161
7162 /* Length field now put in CCK FBR CRC field */
7163 if (is_cck_rate(rspec[1])) {
7164 txh->FragPLCPFallback[4] = phylen & 0xff;
7165 txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8;
7166 }
7167
7168 /* MIMO-RATE: need validation ?? */
7169 mainrates = is_ofdm_rate(rspec[0]) ?
7170 D11A_PHY_HDR_GRATE((struct ofdm_phy_hdr *) plcp) :
7171 plcp[0];
7172
7173 /* DUR field for main rate */
7174 if (!ieee80211_is_pspoll(h->frame_control) &&
7175 !is_multicast_ether_addr(h->addr1) && !use_rifs) {
7176 durid =
7177 brcms_c_compute_frame_dur(wlc, rspec[0], preamble_type[0],
7178 next_frag_len);
7179 h->duration_id = cpu_to_le16(durid);
7180 } else if (use_rifs) {
7181 /* NAV protect to end of next max packet size */
7182 durid =
7183 (u16) brcms_c_calc_frame_time(wlc, rspec[0],
7184 preamble_type[0],
7185 DOT11_MAX_FRAG_LEN);
7186 durid += RIFS_11N_TIME;
7187 h->duration_id = cpu_to_le16(durid);
7188 }
7189
7190 /* DUR field for fallback rate */
7191 if (ieee80211_is_pspoll(h->frame_control))
7192 txh->FragDurFallback = h->duration_id;
7193 else if (is_multicast_ether_addr(h->addr1) || use_rifs)
7194 txh->FragDurFallback = 0;
7195 else {
7196 durid = brcms_c_compute_frame_dur(wlc, rspec[1],
7197 preamble_type[1], next_frag_len);
7198 txh->FragDurFallback = cpu_to_le16(durid);
7199 }
7200
7201 /* (4) MAC-HDR: MacTxControlLow */
7202 if (frag == 0)
7203 mcl |= TXC_STARTMSDU;
7204
7205 if (!is_multicast_ether_addr(h->addr1))
7206 mcl |= TXC_IMMEDACK;
7207
7208 if (wlc->band->bandtype == BRCM_BAND_5G)
7209 mcl |= TXC_FREQBAND_5G;
7210
7211 if (CHSPEC_IS40(wlc_phy_chanspec_get(wlc->band->pi)))
7212 mcl |= TXC_BW_40;
7213
7214 /* set AMIC bit if using hardware TKIP MIC */
7215 if (hwtkmic)
7216 mcl |= TXC_AMIC;
7217
7218 txh->MacTxControlLow = cpu_to_le16(mcl);
7219
7220 /* MacTxControlHigh */
7221 mch = 0;
7222
7223 /* Set fallback rate preamble type */
7224 if ((preamble_type[1] == BRCMS_SHORT_PREAMBLE) ||
7225 (preamble_type[1] == BRCMS_GF_PREAMBLE)) {
7226 if (rspec2rate(rspec[1]) != BRCM_RATE_1M)
7227 mch |= TXC_PREAMBLE_DATA_FB_SHORT;
7228 }
7229
7230 /* MacFrameControl */
7231 memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16));
7232 txh->TxFesTimeNormal = cpu_to_le16(0);
7233
7234 txh->TxFesTimeFallback = cpu_to_le16(0);
7235
7236 /* TxFrameRA */
7237 memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN);
7238
7239 /* TxFrameID */
7240 txh->TxFrameID = cpu_to_le16(frameid);
7241
7242 /*
7243 * TxStatus, Note the case of recreating the first frag of a suppressed
7244 * frame then we may need to reset the retry cnt's via the status reg
7245 */
7246 txh->TxStatus = cpu_to_le16(status);
7247
7248 /*
7249 * extra fields for ucode AMPDU aggregation, the new fields are added to
7250 * the END of previous structure so that it's compatible in driver.
7251 */
7252 txh->MaxNMpdus = cpu_to_le16(0);
7253 txh->MaxABytes_MRT = cpu_to_le16(0);
7254 txh->MaxABytes_FBR = cpu_to_le16(0);
7255 txh->MinMBytes = cpu_to_le16(0);
7256
7257 /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration,
7258 * furnish struct d11txh */
7259 /* RTS PLCP header and RTS frame */
7260 if (use_rts || use_cts) {
7261 if (use_rts && use_cts)
7262 use_cts = false;
7263
7264 for (k = 0; k < 2; k++) {
7265 rts_rspec[k] = brcms_c_rspec_to_rts_rspec(wlc, rspec[k],
7266 false,
7267 mimo_ctlchbw);
7268 }
7269
7270 if (!is_ofdm_rate(rts_rspec[0]) &&
7271 !((rspec2rate(rts_rspec[0]) == BRCM_RATE_1M) ||
7272 (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
7273 rts_preamble_type[0] = BRCMS_SHORT_PREAMBLE;
7274 mch |= TXC_PREAMBLE_RTS_MAIN_SHORT;
7275 }
7276
7277 if (!is_ofdm_rate(rts_rspec[1]) &&
7278 !((rspec2rate(rts_rspec[1]) == BRCM_RATE_1M) ||
7279 (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
7280 rts_preamble_type[1] = BRCMS_SHORT_PREAMBLE;
7281 mch |= TXC_PREAMBLE_RTS_FB_SHORT;
7282 }
7283
7284 /* RTS/CTS additions to MacTxControlLow */
7285 if (use_cts) {
7286 txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS);
7287 } else {
7288 txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS);
7289 txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME);
7290 }
7291
7292 /* RTS PLCP header */
7293 rts_plcp = txh->RTSPhyHeader;
7294 if (use_cts)
7295 rts_phylen = DOT11_CTS_LEN + FCS_LEN;
7296 else
7297 rts_phylen = DOT11_RTS_LEN + FCS_LEN;
7298
7299 brcms_c_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp);
7300
7301 /* fallback rate version of RTS PLCP header */
7302 brcms_c_compute_plcp(wlc, rts_rspec[1], rts_phylen,
7303 rts_plcp_fallback);
7304 memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback,
7305 sizeof(txh->RTSPLCPFallback));
7306
7307 /* RTS frame fields... */
7308 rts = (struct ieee80211_rts *)&txh->rts_frame;
7309
7310 durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec[0],
7311 rspec[0], rts_preamble_type[0],
7312 preamble_type[0], phylen, false);
7313 rts->duration = cpu_to_le16(durid);
7314 /* fallback rate version of RTS DUR field */
7315 durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
7316 rts_rspec[1], rspec[1],
7317 rts_preamble_type[1],
7318 preamble_type[1], phylen, false);
7319 txh->RTSDurFallback = cpu_to_le16(durid);
7320
7321 if (use_cts) {
7322 rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
7323 IEEE80211_STYPE_CTS);
7324
7325 memcpy(&rts->ra, &h->addr2, ETH_ALEN);
7326 } else {
7327 rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
7328 IEEE80211_STYPE_RTS);
7329
7330 memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN);
7331 }
7332
7333 /* mainrate
7334 * low 8 bits: main frag rate/mcs,
7335 * high 8 bits: rts/cts rate/mcs
7336 */
7337 mainrates |= (is_ofdm_rate(rts_rspec[0]) ?
7338 D11A_PHY_HDR_GRATE(
7339 (struct ofdm_phy_hdr *) rts_plcp) :
7340 rts_plcp[0]) << 8;
7341 } else {
7342 memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN);
7343 memset((char *)&txh->rts_frame, 0,
7344 sizeof(struct ieee80211_rts));
7345 memset((char *)txh->RTSPLCPFallback, 0,
7346 sizeof(txh->RTSPLCPFallback));
7347 txh->RTSDurFallback = 0;
7348 }
7349
7350#ifdef SUPPORT_40MHZ
7351 /* add null delimiter count */
7352 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && is_mcs_rate(rspec))
7353 txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] =
7354 brcm_c_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen);
7355
7356#endif
7357
7358 /*
7359 * Now that RTS/RTS FB preamble types are updated, write
7360 * the final value
7361 */
7362 txh->MacTxControlHigh = cpu_to_le16(mch);
7363
7364 /*
7365 * MainRates (both the rts and frag plcp rates have
7366 * been calculated now)
7367 */
7368 txh->MainRates = cpu_to_le16(mainrates);
7369
7370 /* XtraFrameTypes */
7371 xfts = frametype(rspec[1], wlc->mimoft);
7372 xfts |= (frametype(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT);
7373 xfts |= (frametype(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT);
7374 xfts |= CHSPEC_CHANNEL(wlc_phy_chanspec_get(wlc->band->pi)) <<
7375 XFTS_CHANNEL_SHIFT;
7376 txh->XtraFrameTypes = cpu_to_le16(xfts);
7377
7378 /* PhyTxControlWord */
7379 phyctl = frametype(rspec[0], wlc->mimoft);
7380 if ((preamble_type[0] == BRCMS_SHORT_PREAMBLE) ||
7381 (preamble_type[0] == BRCMS_GF_PREAMBLE)) {
7382 if (rspec2rate(rspec[0]) != BRCM_RATE_1M)
7383 phyctl |= PHY_TXC_SHORT_HDR;
7384 }
7385
7386 /* phytxant is properly bit shifted */
7387 phyctl |= brcms_c_stf_d11hdrs_phyctl_txant(wlc, rspec[0]);
7388 txh->PhyTxControlWord = cpu_to_le16(phyctl);
7389
7390 /* PhyTxControlWord_1 */
7391 if (BRCMS_PHY_11N_CAP(wlc->band)) {
7392 u16 phyctl1 = 0;
7393
7394 phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[0]);
7395 txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1);
7396 phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[1]);
7397 txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1);
7398
7399 if (use_rts || use_cts) {
7400 phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[0]);
7401 txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1);
7402 phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[1]);
7403 txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1);
7404 }
7405
7406 /*
7407 * For mcs frames, if mixedmode(overloaded with long preamble)
7408 * is going to be set, fill in non-zero MModeLen and/or
7409 * MModeFbrLen it will be unnecessary if they are separated
7410 */
7411 if (is_mcs_rate(rspec[0]) &&
7412 (preamble_type[0] == BRCMS_MM_PREAMBLE)) {
7413 u16 mmodelen =
7414 brcms_c_calc_lsig_len(wlc, rspec[0], phylen);
7415 txh->MModeLen = cpu_to_le16(mmodelen);
7416 }
7417
7418 if (is_mcs_rate(rspec[1]) &&
7419 (preamble_type[1] == BRCMS_MM_PREAMBLE)) {
7420 u16 mmodefbrlen =
7421 brcms_c_calc_lsig_len(wlc, rspec[1], phylen);
7422 txh->MModeFbrLen = cpu_to_le16(mmodefbrlen);
7423 }
7424 }
7425
7426 ac = skb_get_queue_mapping(p);
7427 if ((scb->flags & SCB_WMECAP) && qos && wlc->edcf_txop[ac]) {
7428 uint frag_dur, dur, dur_fallback;
7429
7430 /* WME: Update TXOP threshold */
7431 if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) && frag == 0) {
7432 frag_dur =
7433 brcms_c_calc_frame_time(wlc, rspec[0],
7434 preamble_type[0], phylen);
7435
7436 if (rts) {
7437 /* 1 RTS or CTS-to-self frame */
7438 dur =
7439 brcms_c_calc_cts_time(wlc, rts_rspec[0],
7440 rts_preamble_type[0]);
7441 dur_fallback =
7442 brcms_c_calc_cts_time(wlc, rts_rspec[1],
7443 rts_preamble_type[1]);
7444 /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */
7445 dur += le16_to_cpu(rts->duration);
7446 dur_fallback +=
7447 le16_to_cpu(txh->RTSDurFallback);
7448 } else if (use_rifs) {
7449 dur = frag_dur;
7450 dur_fallback = 0;
7451 } else {
7452 /* frame + SIFS + ACK */
7453 dur = frag_dur;
7454 dur +=
7455 brcms_c_compute_frame_dur(wlc, rspec[0],
7456 preamble_type[0], 0);
7457
7458 dur_fallback =
7459 brcms_c_calc_frame_time(wlc, rspec[1],
7460 preamble_type[1],
7461 phylen);
7462 dur_fallback +=
7463 brcms_c_compute_frame_dur(wlc, rspec[1],
7464 preamble_type[1], 0);
7465 }
7466 /* NEED to set TxFesTimeNormal (hard) */
7467 txh->TxFesTimeNormal = cpu_to_le16((u16) dur);
7468 /*
7469 * NEED to set fallback rate version of
7470 * TxFesTimeNormal (hard)
7471 */
7472 txh->TxFesTimeFallback =
7473 cpu_to_le16((u16) dur_fallback);
7474
7475 /*
7476 * update txop byte threshold (txop minus intraframe
7477 * overhead)
7478 */
7479 if (wlc->edcf_txop[ac] >= (dur - frag_dur)) {
7480 uint newfragthresh;
7481
7482 newfragthresh =
7483 brcms_c_calc_frame_len(wlc,
7484 rspec[0], preamble_type[0],
7485 (wlc->edcf_txop[ac] -
7486 (dur - frag_dur)));
7487 /* range bound the fragthreshold */
7488 if (newfragthresh < DOT11_MIN_FRAG_LEN)
7489 newfragthresh =
7490 DOT11_MIN_FRAG_LEN;
7491 else if (newfragthresh >
7492 wlc->usr_fragthresh)
7493 newfragthresh =
7494 wlc->usr_fragthresh;
7495 /* update the fragthresh and do txc update */
7496 if (wlc->fragthresh[queue] !=
7497 (u16) newfragthresh)
7498 wlc->fragthresh[queue] =
7499 (u16) newfragthresh;
7500 } else {
7501 wiphy_err(wlc->wiphy, "wl%d: %s txop invalid "
7502 "for rate %d\n",
7503 wlc->pub->unit, fifo_names[queue],
7504 rspec2rate(rspec[0]));
7505 }
7506
7507 if (dur > wlc->edcf_txop[ac])
7508 wiphy_err(wlc->wiphy, "wl%d: %s: %s txop "
7509 "exceeded phylen %d/%d dur %d/%d\n",
7510 wlc->pub->unit, __func__,
7511 fifo_names[queue],
7512 phylen, wlc->fragthresh[queue],
7513 dur, wlc->edcf_txop[ac]);
7514 }
7515 }
7516
7517 return 0;
7518}
7519
7520void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
7521 struct ieee80211_hw *hw)
7522{
7523 u8 prio;
7524 uint fifo;
7525 struct scb *scb = &wlc->pri_scb;
7526 struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data);
7527
7528 /*
7529 * 802.11 standard requires management traffic
7530 * to go at highest priority
7531 */
7532 prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
7533 MAXPRIO;
7534 fifo = prio2fifo[prio];
7535 if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0))
7536 return;
7537 brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio));
7538 brcms_c_send_q(wlc);
7539}
7540
7541void brcms_c_send_q(struct brcms_c_info *wlc)
7542{
7543 struct sk_buff *pkt[DOT11_MAXNUMFRAGS];
7544 int prec;
7545 u16 prec_map;
7546 int err = 0, i, count;
7547 uint fifo;
7548 struct brcms_txq_info *qi = wlc->pkt_queue;
7549 struct pktq *q = &qi->q;
7550 struct ieee80211_tx_info *tx_info;
7551
7552 prec_map = wlc->tx_prec_map;
7553
7554 /* Send all the enq'd pkts that we can.
7555 * Dequeue packets with precedence with empty HW fifo only
7556 */
7557 while (prec_map && (pkt[0] = brcmu_pktq_mdeq(q, prec_map, &prec))) {
7558 tx_info = IEEE80211_SKB_CB(pkt[0]);
7559 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
7560 err = brcms_c_sendampdu(wlc->ampdu, qi, pkt, prec);
7561 } else {
7562 count = 1;
7563 err = brcms_c_prep_pdu(wlc, pkt[0], &fifo);
7564 if (!err) {
7565 for (i = 0; i < count; i++)
7566 brcms_c_txfifo(wlc, fifo, pkt[i], true,
7567 1);
7568 }
7569 }
7570
7571 if (err == -EBUSY) {
7572 brcmu_pktq_penq_head(q, prec, pkt[0]);
7573 /*
7574 * If send failed due to any other reason than a
7575 * change in HW FIFO condition, quit. Otherwise,
7576 * read the new prec_map!
7577 */
7578 if (prec_map == wlc->tx_prec_map)
7579 break;
7580 prec_map = wlc->tx_prec_map;
7581 }
7582 }
7583}
7584
7585void
7586brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
7587 bool commit, s8 txpktpend)
7588{
7589 u16 frameid = INVALIDFID;
7590 struct d11txh *txh;
7591
7592 txh = (struct d11txh *) (p->data);
7593
7594 /* When a BC/MC frame is being committed to the BCMC fifo
7595 * via DMA (NOT PIO), update ucode or BSS info as appropriate.
7596 */
7597 if (fifo == TX_BCMC_FIFO)
7598 frameid = le16_to_cpu(txh->TxFrameID);
7599
7600 /*
7601 * Bump up pending count for if not using rpc. If rpc is
7602 * used, this will be handled in brcms_b_txfifo()
7603 */
7604 if (commit) {
7605 wlc->core->txpktpend[fifo] += txpktpend;
7606 BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n",
7607 txpktpend, wlc->core->txpktpend[fifo]);
7608 }
7609
7610 /* Commit BCMC sequence number in the SHM frame ID location */
7611 if (frameid != INVALIDFID) {
7612 /*
7613 * To inform the ucode of the last mcast frame posted
7614 * so that it can clear moredata bit
7615 */
7616 brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid);
7617 }
7618
7619 if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0)
7620 wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n");
7621}
7622
7623u32
7624brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec,
7625 bool use_rspec, u16 mimo_ctlchbw)
7626{
7627 u32 rts_rspec = 0;
7628
7629 if (use_rspec)
7630 /* use frame rate as rts rate */
7631 rts_rspec = rspec;
7632 else if (wlc->band->gmode && wlc->protection->_g && !is_cck_rate(rspec))
7633 /* Use 11Mbps as the g protection RTS target rate and fallback.
7634 * Use the brcms_basic_rate() lookup to find the best basic rate
7635 * under the target in case 11 Mbps is not Basic.
7636 * 6 and 9 Mbps are not usually selected by rate selection, but
7637 * even if the OFDM rate we are protecting is 6 or 9 Mbps, 11
7638 * is more robust.
7639 */
7640 rts_rspec = brcms_basic_rate(wlc, BRCM_RATE_11M);
7641 else
7642 /* calculate RTS rate and fallback rate based on the frame rate
7643 * RTS must be sent at a basic rate since it is a
7644 * control frame, sec 9.6 of 802.11 spec
7645 */
7646 rts_rspec = brcms_basic_rate(wlc, rspec);
7647
7648 if (BRCMS_PHY_11N_CAP(wlc->band)) {
7649 /* set rts txbw to correct side band */
7650 rts_rspec &= ~RSPEC_BW_MASK;
7651
7652 /*
7653 * if rspec/rspec_fallback is 40MHz, then send RTS on both
7654 * 20MHz channel (DUP), otherwise send RTS on control channel
7655 */
7656 if (rspec_is40mhz(rspec) && !is_cck_rate(rts_rspec))
7657 rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT);
7658 else
7659 rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
7660
7661 /* pick siso/cdd as default for ofdm */
7662 if (is_ofdm_rate(rts_rspec)) {
7663 rts_rspec &= ~RSPEC_STF_MASK;
7664 rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
7665 }
7666 }
7667 return rts_rspec;
7668}
7669
7670void
7671brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend)
7672{
7673 wlc->core->txpktpend[fifo] -= txpktpend;
7674 BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend,
7675 wlc->core->txpktpend[fifo]);
7676
7677 /* There is more room; mark precedences related to this FIFO sendable */
7678 wlc->tx_prec_map |= wlc->fifo2prec_map[fifo];
7679
7680 /* figure out which bsscfg is being worked on... */
7681}
7682
7683/* Update beacon listen interval in shared memory */
7684static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc)
7685{
7686 /* wake up every DTIM is the default */
7687 if (wlc->bcn_li_dtim == 1)
7688 brcms_b_write_shm(wlc->hw, M_BCN_LI, 0);
7689 else
7690 brcms_b_write_shm(wlc->hw, M_BCN_LI,
7691 (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn);
7692}
7693
7694static void
7695brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr,
7696 u32 *tsf_h_ptr)
7697{
7698 struct d11regs __iomem *regs = wlc_hw->regs;
7699
7700 /* read the tsf timer low, then high to get an atomic read */
7701 *tsf_l_ptr = R_REG(&regs->tsf_timerlow);
7702 *tsf_h_ptr = R_REG(&regs->tsf_timerhigh);
7703}
7704
7705/*
7706 * recover 64bit TSF value from the 16bit TSF value in the rx header
7707 * given the assumption that the TSF passed in header is within 65ms
7708 * of the current tsf.
7709 *
7710 * 6 5 4 4 3 2 1
7711 * 3.......6.......8.......0.......2.......4.......6.......8......0
7712 * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->|
7713 *
7714 * The RxTSFTime are the lowest 16 bits and provided by the ucode. The
7715 * tsf_l is filled in by brcms_b_recv, which is done earlier in the
7716 * receive call sequence after rx interrupt. Only the higher 16 bits
7717 * are used. Finally, the tsf_h is read from the tsf register.
7718 */
7719static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc,
7720 struct d11rxhdr *rxh)
7721{
7722 u32 tsf_h, tsf_l;
7723 u16 rx_tsf_0_15, rx_tsf_16_31;
7724
7725 brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h);
7726
7727 rx_tsf_16_31 = (u16)(tsf_l >> 16);
7728 rx_tsf_0_15 = rxh->RxTSFTime;
7729
7730 /*
7731 * a greater tsf time indicates the low 16 bits of
7732 * tsf_l wrapped, so decrement the high 16 bits.
7733 */
7734 if ((u16)tsf_l < rx_tsf_0_15) {
7735 rx_tsf_16_31 -= 1;
7736 if (rx_tsf_16_31 == 0xffff)
7737 tsf_h -= 1;
7738 }
7739
7740 return ((u64)tsf_h << 32) | (((u32)rx_tsf_16_31 << 16) + rx_tsf_0_15);
7741}
7742
7743static void
7744prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
7745 struct sk_buff *p,
7746 struct ieee80211_rx_status *rx_status)
7747{
7748 int preamble;
7749 int channel;
7750 u32 rspec;
7751 unsigned char *plcp;
7752
7753 /* fill in TSF and flag its presence */
7754 rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh);
7755 rx_status->flag |= RX_FLAG_MACTIME_MPDU;
7756
7757 channel = BRCMS_CHAN_CHANNEL(rxh->RxChan);
7758
7759 if (channel > 14) {
7760 rx_status->band = IEEE80211_BAND_5GHZ;
7761 rx_status->freq = ieee80211_ofdm_chan_to_freq(
7762 WF_CHAN_FACTOR_5_G/2, channel);
7763
7764 } else {
7765 rx_status->band = IEEE80211_BAND_2GHZ;
7766 rx_status->freq = ieee80211_dsss_chan_to_freq(channel);
7767 }
7768
7769 rx_status->signal = wlc_phy_rssi_compute(wlc->hw->band->pi, rxh);
7770
7771 /* noise */
7772 /* qual */
7773 rx_status->antenna =
7774 (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;
7775
7776 plcp = p->data;
7777
7778 rspec = brcms_c_compute_rspec(rxh, plcp);
7779 if (is_mcs_rate(rspec)) {
7780 rx_status->rate_idx = rspec & RSPEC_RATE_MASK;
7781 rx_status->flag |= RX_FLAG_HT;
7782 if (rspec_is40mhz(rspec))
7783 rx_status->flag |= RX_FLAG_40MHZ;
7784 } else {
7785 switch (rspec2rate(rspec)) {
7786 case BRCM_RATE_1M:
7787 rx_status->rate_idx = 0;
7788 break;
7789 case BRCM_RATE_2M:
7790 rx_status->rate_idx = 1;
7791 break;
7792 case BRCM_RATE_5M5:
7793 rx_status->rate_idx = 2;
7794 break;
7795 case BRCM_RATE_11M:
7796 rx_status->rate_idx = 3;
7797 break;
7798 case BRCM_RATE_6M:
7799 rx_status->rate_idx = 4;
7800 break;
7801 case BRCM_RATE_9M:
7802 rx_status->rate_idx = 5;
7803 break;
7804 case BRCM_RATE_12M:
7805 rx_status->rate_idx = 6;
7806 break;
7807 case BRCM_RATE_18M:
7808 rx_status->rate_idx = 7;
7809 break;
7810 case BRCM_RATE_24M:
7811 rx_status->rate_idx = 8;
7812 break;
7813 case BRCM_RATE_36M:
7814 rx_status->rate_idx = 9;
7815 break;
7816 case BRCM_RATE_48M:
7817 rx_status->rate_idx = 10;
7818 break;
7819 case BRCM_RATE_54M:
7820 rx_status->rate_idx = 11;
7821 break;
7822 default:
7823 wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__);
7824 }
7825
7826 /*
7827 * For 5GHz, we should decrease the index as it is
7828 * a subset of the 2.4G rates. See bitrates field
7829 * of brcms_band_5GHz_nphy (in mac80211_if.c).
7830 */
7831 if (rx_status->band == IEEE80211_BAND_5GHZ)
7832 rx_status->rate_idx -= BRCMS_LEGACY_5G_RATE_OFFSET;
7833
7834 /* Determine short preamble and rate_idx */
7835 preamble = 0;
7836 if (is_cck_rate(rspec)) {
7837 if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
7838 rx_status->flag |= RX_FLAG_SHORTPRE;
7839 } else if (is_ofdm_rate(rspec)) {
7840 rx_status->flag |= RX_FLAG_SHORTPRE;
7841 } else {
7842 wiphy_err(wlc->wiphy, "%s: Unknown modulation\n",
7843 __func__);
7844 }
7845 }
7846
7847 if (plcp3_issgi(plcp[3]))
7848 rx_status->flag |= RX_FLAG_SHORT_GI;
7849
7850 if (rxh->RxStatus1 & RXS_DECERR) {
7851 rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
7852 wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_PLCP_CRC\n",
7853 __func__);
7854 }
7855 if (rxh->RxStatus1 & RXS_FCSERR) {
7856 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
7857 wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_FCS_CRC\n",
7858 __func__);
7859 }
7860}
7861
7862static void
7863brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
7864 struct sk_buff *p)
7865{
7866 int len_mpdu;
7867 struct ieee80211_rx_status rx_status;
7868
7869 memset(&rx_status, 0, sizeof(rx_status));
7870 prep_mac80211_status(wlc, rxh, p, &rx_status);
7871
7872 /* mac header+body length, exclude CRC and plcp header */
7873 len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN;
7874 skb_pull(p, D11_PHY_HDR_LEN);
7875 __skb_trim(p, len_mpdu);
7876
7877 memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
7878 ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
7879}
7880
7881/* calculate frame duration for Mixed-mode L-SIG spoofing, return
7882 * number of bytes goes in the length field
7883 *
7884 * Formula given by HT PHY Spec v 1.13
7885 * len = 3(nsyms + nstream + 3) - 3
7886 */
7887u16
7888brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
7889 uint mac_len)
7890{
7891 uint nsyms, len = 0, kNdps;
7892
7893 BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n",
7894 wlc->pub->unit, rspec2rate(ratespec), mac_len);
7895
7896 if (is_mcs_rate(ratespec)) {
7897 uint mcs = ratespec & RSPEC_RATE_MASK;
7898 int tot_streams = (mcs_2_txstreams(mcs) + 1) +
7899 rspec_stc(ratespec);
7900
7901 /*
7902 * the payload duration calculation matches that
7903 * of regular ofdm
7904 */
7905 /* 1000Ndbps = kbps * 4 */
7906 kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
7907 rspec_issgi(ratespec)) * 4;
7908
7909 if (rspec_stc(ratespec) == 0)
7910 nsyms =
7911 CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
7912 APHY_TAIL_NBITS) * 1000, kNdps);
7913 else
7914 /* STBC needs to have even number of symbols */
7915 nsyms =
7916 2 *
7917 CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
7918 APHY_TAIL_NBITS) * 1000, 2 * kNdps);
7919
7920 /* (+3) account for HT-SIG(2) and HT-STF(1) */
7921 nsyms += (tot_streams + 3);
7922 /*
7923 * 3 bytes/symbol @ legacy 6Mbps rate
7924 * (-3) excluding service bits and tail bits
7925 */
7926 len = (3 * nsyms) - 3;
7927 }
7928
7929 return (u16) len;
7930}
7931
7932static void
7933brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len)
7934{
7935 const struct brcms_c_rateset *rs_dflt;
7936 struct brcms_c_rateset rs;
7937 u8 rate;
7938 u16 entry_ptr;
7939 u8 plcp[D11_PHY_HDR_LEN];
7940 u16 dur, sifs;
7941 uint i;
7942
7943 sifs = get_sifs(wlc->band);
7944
7945 rs_dflt = brcms_c_rateset_get_hwrs(wlc);
7946
7947 brcms_c_rateset_copy(rs_dflt, &rs);
7948 brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
7949
7950 /*
7951 * walk the phy rate table and update MAC core SHM
7952 * basic rate table entries
7953 */
7954 for (i = 0; i < rs.count; i++) {
7955 rate = rs.rates[i] & BRCMS_RATE_MASK;
7956
7957 entry_ptr = brcms_b_rate_shm_offset(wlc->hw, rate);
7958
7959 /* Calculate the Probe Response PLCP for the given rate */
7960 brcms_c_compute_plcp(wlc, rate, frame_len, plcp);
7961
7962 /*
7963 * Calculate the duration of the Probe Response
7964 * frame plus SIFS for the MAC
7965 */
7966 dur = (u16) brcms_c_calc_frame_time(wlc, rate,
7967 BRCMS_LONG_PREAMBLE, frame_len);
7968 dur += sifs;
7969
7970 /* Update the SHM Rate Table entry Probe Response values */
7971 brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS,
7972 (u16) (plcp[0] + (plcp[1] << 8)));
7973 brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS + 2,
7974 (u16) (plcp[2] + (plcp[3] << 8)));
7975 brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_DUR_POS, dur);
7976 }
7977}
7978
7979/* Max buffering needed for beacon template/prb resp template is 142 bytes.
7980 *
7981 * PLCP header is 6 bytes.
7982 * 802.11 A3 header is 24 bytes.
7983 * Max beacon frame body template length is 112 bytes.
7984 * Max probe resp frame body template length is 110 bytes.
7985 *
7986 * *len on input contains the max length of the packet available.
7987 *
7988 * The *len value is set to the number of bytes in buf used, and starts
7989 * with the PLCP and included up to, but not including, the 4 byte FCS.
7990 */
7991static void
7992brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
7993 u32 bcn_rspec,
7994 struct brcms_bss_cfg *cfg, u16 *buf, int *len)
7995{
7996 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
7997 struct cck_phy_hdr *plcp;
7998 struct ieee80211_mgmt *h;
7999 int hdr_len, body_len;
8000
8001 hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
8002
8003 /* calc buffer size provided for frame body */
8004 body_len = *len - hdr_len;
8005 /* return actual size */
8006 *len = hdr_len + body_len;
8007
8008 /* format PHY and MAC headers */
8009 memset((char *)buf, 0, hdr_len);
8010
8011 plcp = (struct cck_phy_hdr *) buf;
8012
8013 /*
8014 * PLCP for Probe Response frames are filled in from
8015 * core's rate table
8016 */
8017 if (type == IEEE80211_STYPE_BEACON)
8018 /* fill in PLCP */
8019 brcms_c_compute_plcp(wlc, bcn_rspec,
8020 (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
8021 (u8 *) plcp);
8022
8023 /* "Regular" and 16 MBSS but not for 4 MBSS */
8024 /* Update the phytxctl for the beacon based on the rspec */
8025 brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
8026
8027 h = (struct ieee80211_mgmt *)&plcp[1];
8028
8029 /* fill in 802.11 header */
8030 h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);
8031
8032 /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
8033 /* A1 filled in by MAC for prb resp, broadcast for bcn */
8034 if (type == IEEE80211_STYPE_BEACON)
8035 memcpy(&h->da, &ether_bcast, ETH_ALEN);
8036 memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
8037 memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
8038
8039 /* SEQ filled in by MAC */
8040}
8041
8042int brcms_c_get_header_len(void)
8043{
8044 return TXOFF;
8045}
8046
8047/*
8048 * Update all beacons for the system.
8049 */
8050void brcms_c_update_beacon(struct brcms_c_info *wlc)
8051{
8052 struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
8053
8054 if (bsscfg->up && !bsscfg->BSS)
8055 /* Clear the soft intmask */
8056 wlc->defmacintmask &= ~MI_BCNTPL;
8057}
8058
8059/* Write ssid into shared memory */
8060static void
8061brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
8062{
8063 u8 *ssidptr = cfg->SSID;
8064 u16 base = M_SSID;
8065 u8 ssidbuf[IEEE80211_MAX_SSID_LEN];
8066
8067 /* padding the ssid with zero and copy it into shm */
8068 memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN);
8069 memcpy(ssidbuf, ssidptr, cfg->SSID_len);
8070
8071 brcms_c_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN);
8072 brcms_b_write_shm(wlc->hw, M_SSIDLEN, (u16) cfg->SSID_len);
8073}
8074
8075static void
8076brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
8077 struct brcms_bss_cfg *cfg,
8078 bool suspend)
8079{
8080 u16 prb_resp[BCN_TMPL_LEN / 2];
8081 int len = BCN_TMPL_LEN;
8082
8083 /*
8084 * write the probe response to hardware, or save in
8085 * the config structure
8086 */
8087
8088 /* create the probe response template */
8089 brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0,
8090 cfg, prb_resp, &len);
8091
8092 if (suspend)
8093 brcms_c_suspend_mac_and_wait(wlc);
8094
8095 /* write the probe response into the template region */
8096 brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
8097 (len + 3) & ~3, prb_resp);
8098
8099 /* write the length of the probe response frame (+PLCP/-FCS) */
8100 brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len);
8101
8102 /* write the SSID and SSID length */
8103 brcms_c_shm_ssid_upd(wlc, cfg);
8104
8105 /*
8106 * Write PLCP headers and durations for probe response frames
8107 * at all rates. Use the actual frame length covered by the
8108 * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table()
8109 * by subtracting the PLCP len and adding the FCS.
8110 */
8111 len += (-D11_PHY_HDR_LEN + FCS_LEN);
8112 brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len);
8113
8114 if (suspend)
8115 brcms_c_enable_mac(wlc);
8116}
8117
8118void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
8119{
8120 struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
8121
8122 /* update AP or IBSS probe responses */
8123 if (bsscfg->up && !bsscfg->BSS)
8124 brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
8125}
8126
8127/* prepares pdu for transmission. returns BCM error codes */
8128int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop)
8129{
8130 uint fifo;
8131 struct d11txh *txh;
8132 struct ieee80211_hdr *h;
8133 struct scb *scb;
8134
8135 txh = (struct d11txh *) (pdu->data);
8136 h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
8137
8138 /* get the pkt queue info. This was put at brcms_c_sendctl or
8139 * brcms_c_send for PDU */
8140 fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
8141
8142 scb = NULL;
8143
8144 *fifop = fifo;
8145
8146 /* return if insufficient dma resources */
8147 if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) {
8148 /* Mark precedences related to this FIFO, unsendable */
8149 /* A fifo is full. Clear precedences related to that FIFO */
8150 wlc->tx_prec_map &= ~(wlc->fifo2prec_map[fifo]);
8151 return -EBUSY;
8152 }
8153 return 0;
8154}
8155
8156int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
8157 uint *blocks)
8158{
8159 if (fifo >= NFIFO)
8160 return -EINVAL;
8161
8162 *blocks = wlc_hw->xmtfifo_sz[fifo];
8163
8164 return 0;
8165}
8166
8167void
8168brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset,
8169 const u8 *addr)
8170{
8171 brcms_b_set_addrmatch(wlc->hw, match_reg_offset, addr);
8172 if (match_reg_offset == RCM_BSSID_OFFSET)
8173 memcpy(wlc->bsscfg->BSSID, addr, ETH_ALEN);
8174}
8175
8176/*
8177 * Flag 'scan in progress' to withhold dynamic phy calibration
8178 */
8179void brcms_c_scan_start(struct brcms_c_info *wlc)
8180{
8181 wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
8182}
8183
8184void brcms_c_scan_stop(struct brcms_c_info *wlc)
8185{
8186 wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
8187}
8188
8189void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state)
8190{
8191 wlc->pub->associated = state;
8192 wlc->bsscfg->associated = state;
8193}
8194
8195/*
8196 * When a remote STA/AP is removed by Mac80211, or when it can no longer accept
8197 * AMPDU traffic, packets pending in hardware have to be invalidated so that
8198 * when later on hardware releases them, they can be handled appropriately.
8199 */
8200void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
8201 struct ieee80211_sta *sta,
8202 void (*dma_callback_fn))
8203{
8204 struct dma_pub *dmah;
8205 int i;
8206 for (i = 0; i < NFIFO; i++) {
8207 dmah = hw->di[i];
8208 if (dmah != NULL)
8209 dma_walk_packets(dmah, dma_callback_fn, sta);
8210 }
8211}
8212
8213int brcms_c_get_curband(struct brcms_c_info *wlc)
8214{
8215 return wlc->band->bandunit;
8216}
8217
8218void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
8219{
8220 /* flush packet queue when requested */
8221 if (drop)
8222 brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
8223
8224 /* wait for queue and DMA fifos to run dry */
8225 while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0)
8226 brcms_msleep(wlc->wl, 1);
8227}
8228
8229void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
8230{
8231 wlc->bcn_li_bcn = interval;
8232 if (wlc->pub->up)
8233 brcms_c_bcn_li_upd(wlc);
8234}
8235
8236int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr)
8237{
8238 uint qdbm;
8239
8240 /* Remove override bit and clip to max qdbm value */
8241 qdbm = min_t(uint, txpwr * BRCMS_TXPWR_DB_FACTOR, 0xff);
8242 return wlc_phy_txpower_set(wlc->band->pi, qdbm, false);
8243}
8244
8245int brcms_c_get_tx_power(struct brcms_c_info *wlc)
8246{
8247 uint qdbm;
8248 bool override;
8249
8250 wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override);
8251
8252 /* Return qdbm units */
8253 return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR);
8254}
8255
8256void brcms_c_set_radio_mpc(struct brcms_c_info *wlc, bool mpc)
8257{
8258 wlc->mpc = mpc;
8259 brcms_c_radio_mpc_upd(wlc);
8260}
8261
8262/* Process received frames */
8263/*
8264 * Return true if more frames need to be processed. false otherwise.
8265 * Param 'bound' indicates max. # frames to process before break out.
8266 */
8267static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
8268{
8269 struct d11rxhdr *rxh;
8270 struct ieee80211_hdr *h;
8271 uint len;
8272 bool is_amsdu;
8273
8274 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
8275
8276 /* frame starts with rxhdr */
8277 rxh = (struct d11rxhdr *) (p->data);
8278
8279 /* strip off rxhdr */
8280 skb_pull(p, BRCMS_HWRXOFF);
8281
8282 /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
8283 if (rxh->RxStatus1 & RXS_PBPRES) {
8284 if (p->len < 2) {
8285 wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of "
8286 "len %d\n", wlc->pub->unit, p->len);
8287 goto toss;
8288 }
8289 skb_pull(p, 2);
8290 }
8291
8292 h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN);
8293 len = p->len;
8294
8295 if (rxh->RxStatus1 & RXS_FCSERR) {
8296 if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) {
8297 wiphy_err(wlc->wiphy, "FCSERR while scanning******* -"
8298 " tossing\n");
8299 goto toss;
8300 } else {
8301 wiphy_err(wlc->wiphy, "RCSERR!!!\n");
8302 goto toss;
8303 }
8304 }
8305
8306 /* check received pkt has at least frame control field */
8307 if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control))
8308 goto toss;
8309
8310 /* not supporting A-MSDU */
8311 is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK;
8312 if (is_amsdu)
8313 goto toss;
8314
8315 brcms_c_recvctl(wlc, rxh, p);
8316 return;
8317
8318 toss:
8319 brcmu_pkt_buf_free_skb(p);
8320}
8321
8322/* Process received frames */
8323/*
8324 * Return true if more frames need to be processed. false otherwise.
8325 * Param 'bound' indicates max. # frames to process before break out.
8326 */
8327static bool
8328brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
8329{
8330 struct sk_buff *p;
8331 struct sk_buff *head = NULL;
8332 struct sk_buff *tail = NULL;
8333 uint n = 0;
8334 uint bound_limit = bound ? RXBND : -1;
8335
8336 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
8337 /* gather received frames */
8338 while ((p = dma_rx(wlc_hw->di[fifo]))) {
8339
8340 if (!tail)
8341 head = tail = p;
8342 else {
8343 tail->prev = p;
8344 tail = p;
8345 }
8346
8347 /* !give others some time to run! */
8348 if (++n >= bound_limit)
8349 break;
8350 }
8351
8352 /* post more rbufs */
8353 dma_rxfill(wlc_hw->di[fifo]);
8354
8355 /* process each frame */
8356 while ((p = head) != NULL) {
8357 struct d11rxhdr_le *rxh_le;
8358 struct d11rxhdr *rxh;
8359 head = head->prev;
8360 p->prev = NULL;
8361
8362 rxh_le = (struct d11rxhdr_le *)p->data;
8363 rxh = (struct d11rxhdr *)p->data;
8364
8365 /* fixup rx header endianness */
8366 rxh->RxFrameSize = le16_to_cpu(rxh_le->RxFrameSize);
8367 rxh->PhyRxStatus_0 = le16_to_cpu(rxh_le->PhyRxStatus_0);
8368 rxh->PhyRxStatus_1 = le16_to_cpu(rxh_le->PhyRxStatus_1);
8369 rxh->PhyRxStatus_2 = le16_to_cpu(rxh_le->PhyRxStatus_2);
8370 rxh->PhyRxStatus_3 = le16_to_cpu(rxh_le->PhyRxStatus_3);
8371 rxh->PhyRxStatus_4 = le16_to_cpu(rxh_le->PhyRxStatus_4);
8372 rxh->PhyRxStatus_5 = le16_to_cpu(rxh_le->PhyRxStatus_5);
8373 rxh->RxStatus1 = le16_to_cpu(rxh_le->RxStatus1);
8374 rxh->RxStatus2 = le16_to_cpu(rxh_le->RxStatus2);
8375 rxh->RxTSFTime = le16_to_cpu(rxh_le->RxTSFTime);
8376 rxh->RxChan = le16_to_cpu(rxh_le->RxChan);
8377
8378 brcms_c_recv(wlc_hw->wlc, p);
8379 }
8380
8381 return n >= bound_limit;
8382}
8383
8384/* second-level interrupt processing
8385 * Return true if another dpc needs to be re-scheduled. false otherwise.
8386 * Param 'bounded' indicates if applicable loops should be bounded.
8387 */
8388bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
8389{
8390 u32 macintstatus;
8391 struct brcms_hardware *wlc_hw = wlc->hw;
8392 struct d11regs __iomem *regs = wlc_hw->regs;
8393 struct wiphy *wiphy = wlc->wiphy;
8394
8395 if (brcms_deviceremoved(wlc)) {
8396 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
8397 __func__);
8398 brcms_down(wlc->wl);
8399 return false;
8400 }
8401
8402 /* grab and clear the saved software intstatus bits */
8403 macintstatus = wlc->macintstatus;
8404 wlc->macintstatus = 0;
8405
8406 BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n",
8407 wlc_hw->unit, macintstatus);
8408
8409 WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */
8410
8411 /* tx status */
8412 if (macintstatus & MI_TFS) {
8413 bool fatal;
8414 if (brcms_b_txstatus(wlc->hw, bounded, &fatal))
8415 wlc->macintstatus |= MI_TFS;
8416 if (fatal) {
8417 wiphy_err(wiphy, "MI_TFS: fatal\n");
8418 goto fatal;
8419 }
8420 }
8421
8422 if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
8423 brcms_c_tbtt(wlc);
8424
8425 /* ATIM window end */
8426 if (macintstatus & MI_ATIMWINEND) {
8427 BCMMSG(wlc->wiphy, "end of ATIM window\n");
8428 OR_REG(&regs->maccommand, wlc->qvalid);
8429 wlc->qvalid = 0;
8430 }
8431
8432 /*
8433 * received data or control frame, MI_DMAINT is
8434 * indication of RX_FIFO interrupt
8435 */
8436 if (macintstatus & MI_DMAINT)
8437 if (brcms_b_recv(wlc_hw, RX_FIFO, bounded))
8438 wlc->macintstatus |= MI_DMAINT;
8439
8440 /* noise sample collected */
8441 if (macintstatus & MI_BG_NOISE)
8442 wlc_phy_noise_sample_intr(wlc_hw->band->pi);
8443
8444 if (macintstatus & MI_GP0) {
8445 wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d "
8446 "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now);
8447
8448 printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
8449 __func__, wlc_hw->sih->chip,
8450 wlc_hw->sih->chiprev);
8451 /* big hammer */
8452 brcms_init(wlc->wl);
8453 }
8454
8455 /* gptimer timeout */
8456 if (macintstatus & MI_TO)
8457 W_REG(&regs->gptimer, 0);
8458
8459 if (macintstatus & MI_RFDISABLE) {
8460 BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the"
8461 " RF Disable Input\n", wlc_hw->unit);
8462 brcms_rfkill_set_hw_state(wlc->wl);
8463 }
8464
8465 /* send any enq'd tx packets. Just makes sure to jump start tx */
8466 if (!pktq_empty(&wlc->pkt_queue->q))
8467 brcms_c_send_q(wlc);
8468
8469 /* it isn't done and needs to be resched if macintstatus is non-zero */
8470 return wlc->macintstatus != 0;
8471
8472 fatal:
8473 brcms_init(wlc->wl);
8474 return wlc->macintstatus != 0;
8475}
8476
8477void brcms_c_init(struct brcms_c_info *wlc)
8478{
8479 struct d11regs __iomem *regs;
8480 u16 chanspec;
8481 bool mute = false;
8482
8483 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
8484
8485 regs = wlc->regs;
8486
8487 /*
8488 * This will happen if a big-hammer was executed. In
8489 * that case, we want to go back to the channel that
8490 * we were on and not new channel
8491 */
8492 if (wlc->pub->associated)
8493 chanspec = wlc->home_chanspec;
8494 else
8495 chanspec = brcms_c_init_chanspec(wlc);
8496
8497 brcms_b_init(wlc->hw, chanspec, mute);
8498
8499 /* update beacon listen interval */
8500 brcms_c_bcn_li_upd(wlc);
8501
8502 /* write ethernet address to core */
8503 brcms_c_set_mac(wlc->bsscfg);
8504 brcms_c_set_bssid(wlc->bsscfg);
8505
8506 /* Update tsf_cfprep if associated and up */
8507 if (wlc->pub->associated && wlc->bsscfg->up) {
8508 u32 bi;
8509
8510 /* get beacon period and convert to uS */
8511 bi = wlc->bsscfg->current_bss->beacon_period << 10;
8512 /*
8513 * update since init path would reset
8514 * to default value
8515 */
8516 W_REG(&regs->tsf_cfprep,
8517 (bi << CFPREP_CBI_SHIFT));
8518
8519 /* Update maccontrol PM related bits */
8520 brcms_c_set_ps_ctrl(wlc);
8521 }
8522
8523 brcms_c_bandinit_ordered(wlc, chanspec);
8524
8525 /* init probe response timeout */
8526 brcms_b_write_shm(wlc->hw, M_PRS_MAXTIME, wlc->prb_resp_timeout);
8527
8528 /* init max burst txop (framebursting) */
8529 brcms_b_write_shm(wlc->hw, M_MBURST_TXOP,
8530 (wlc->
8531 _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP));
8532
8533 /* initialize maximum allowed duty cycle */
8534 brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true);
8535 brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true);
8536
8537 /*
8538 * Update some shared memory locations related to
8539 * max AMPDU size allowed to received
8540 */
8541 brcms_c_ampdu_shm_upd(wlc->ampdu);
8542
8543 /* band-specific inits */
8544 brcms_c_bsinit(wlc);
8545
8546 /* Enable EDCF mode (while the MAC is suspended) */
8547 OR_REG(&regs->ifs_ctl, IFS_USEEDCF);
8548 brcms_c_edcf_setparams(wlc, false);
8549
8550 /* Init precedence maps for empty FIFOs */
8551 brcms_c_tx_prec_map_init(wlc);
8552
8553 /* read the ucode version if we have not yet done so */
8554 if (wlc->ucode_rev == 0) {
8555 wlc->ucode_rev =
8556 brcms_b_read_shm(wlc->hw, M_BOM_REV_MAJOR) << NBITS(u16);
8557 wlc->ucode_rev |= brcms_b_read_shm(wlc->hw, M_BOM_REV_MINOR);
8558 }
8559
8560 /* ..now really unleash hell (allow the MAC out of suspend) */
8561 brcms_c_enable_mac(wlc);
8562
8563 /* clear tx flow control */
8564 brcms_c_txflowcontrol_reset(wlc);
8565
8566 /* enable the RF Disable Delay timer */
8567 W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT);
8568
8569 /* initialize mpc delay */
8570 wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
8571
8572 /*
8573 * Initialize WME parameters; if they haven't been set by some other
8574 * mechanism (IOVar, etc) then read them from the hardware.
8575 */
8576 if (GFIELD(wlc->wme_retries[0], EDCF_SHORT) == 0) {
8577 /* Uninitialized; read from HW */
8578 int ac;
8579
8580 for (ac = 0; ac < AC_COUNT; ac++)
8581 wlc->wme_retries[ac] =
8582 brcms_b_read_shm(wlc->hw, M_AC_TXLMT_ADDR(ac));
8583 }
8584}
8585
8586/*
8587 * The common driver entry routine. Error codes should be unique
8588 */
8589struct brcms_c_info *
8590brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit,
8591 bool piomode, void __iomem *regsva, struct pci_dev *btparam,
8592 uint *perr)
8593{
8594 struct brcms_c_info *wlc;
8595 uint err = 0;
8596 uint i, j;
8597 struct brcms_pub *pub;
8598
8599 /* allocate struct brcms_c_info state and its substructures */
8600 wlc = (struct brcms_c_info *) brcms_c_attach_malloc(unit, &err, device);
8601 if (wlc == NULL)
8602 goto fail;
8603 wlc->wiphy = wl->wiphy;
8604 pub = wlc->pub;
8605
8606#if defined(BCMDBG)
8607 wlc_info_dbg = wlc;
8608#endif
8609
8610 wlc->band = wlc->bandstate[0];
8611 wlc->core = wlc->corestate;
8612 wlc->wl = wl;
8613 pub->unit = unit;
8614 pub->_piomode = piomode;
8615 wlc->bandinit_pending = false;
8616
8617 /* populate struct brcms_c_info with default values */
8618 brcms_c_info_init(wlc, unit);
8619
8620 /* update sta/ap related parameters */
8621 brcms_c_ap_upd(wlc);
8622
8623 /*
8624 * low level attach steps(all hw accesses go
8625 * inside, no more in rest of the attach)
8626 */
8627 err = brcms_b_attach(wlc, vendor, device, unit, piomode, regsva,
8628 btparam);
8629 if (err)
8630 goto fail;
8631
8632 brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, OFF);
8633
8634 pub->phy_11ncapable = BRCMS_PHY_11N_CAP(wlc->band);
8635
8636 /* disable allowed duty cycle */
8637 wlc->tx_duty_cycle_ofdm = 0;
8638 wlc->tx_duty_cycle_cck = 0;
8639
8640 brcms_c_stf_phy_chain_calc(wlc);
8641
8642 /* txchain 1: txant 0, txchain 2: txant 1 */
8643 if (BRCMS_ISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
8644 wlc->stf->txant = wlc->stf->hw_txchain - 1;
8645
8646 /* push to BMAC driver */
8647 wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain,
8648 wlc->stf->hw_rxchain);
8649
8650 /* pull up some info resulting from the low attach */
8651 for (i = 0; i < NFIFO; i++)
8652 wlc->core->txavail[i] = wlc->hw->txavail[i];
8653
8654 memcpy(&wlc->perm_etheraddr, &wlc->hw->etheraddr, ETH_ALEN);
8655 memcpy(&pub->cur_etheraddr, &wlc->hw->etheraddr, ETH_ALEN);
8656
8657 for (j = 0; j < wlc->pub->_nbands; j++) {
8658 wlc->band = wlc->bandstate[j];
8659
8660 if (!brcms_c_attach_stf_ant_init(wlc)) {
8661 err = 24;
8662 goto fail;
8663 }
8664
8665 /* default contention windows size limits */
8666 wlc->band->CWmin = APHY_CWMIN;
8667 wlc->band->CWmax = PHY_CWMAX;
8668
8669 /* init gmode value */
8670 if (wlc->band->bandtype == BRCM_BAND_2G) {
8671 wlc->band->gmode = GMODE_AUTO;
8672 brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER,
8673 wlc->band->gmode);
8674 }
8675
8676 /* init _n_enab supported mode */
8677 if (BRCMS_PHY_11N_CAP(wlc->band)) {
8678 pub->_n_enab = SUPPORT_11N;
8679 brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER,
8680 ((pub->_n_enab ==
8681 SUPPORT_11N) ? WL_11N_2x2 :
8682 WL_11N_3x3));
8683 }
8684
8685 /* init per-band default rateset, depend on band->gmode */
8686 brcms_default_rateset(wlc, &wlc->band->defrateset);
8687
8688 /* fill in hw_rateset */
8689 brcms_c_rateset_filter(&wlc->band->defrateset,
8690 &wlc->band->hw_rateset, false,
8691 BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
8692 (bool) (wlc->pub->_n_enab & SUPPORT_11N));
8693 }
8694
8695 /*
8696 * update antenna config due to
8697 * wlc->stf->txant/txchain/ant_rx_ovr change
8698 */
8699 brcms_c_stf_phy_txant_upd(wlc);
8700
8701 /* attach each modules */
8702 err = brcms_c_attach_module(wlc);
8703 if (err != 0)
8704 goto fail;
8705
8706 if (!brcms_c_timers_init(wlc, unit)) {
8707 wiphy_err(wl->wiphy, "wl%d: %s: init_timer failed\n", unit,
8708 __func__);
8709 err = 32;
8710 goto fail;
8711 }
8712
8713 /* depend on rateset, gmode */
8714 wlc->cmi = brcms_c_channel_mgr_attach(wlc);
8715 if (!wlc->cmi) {
8716 wiphy_err(wl->wiphy, "wl%d: %s: channel_mgr_attach failed"
8717 "\n", unit, __func__);
8718 err = 33;
8719 goto fail;
8720 }
8721
8722 /* init default when all parameters are ready, i.e. ->rateset */
8723 brcms_c_bss_default_init(wlc);
8724
8725 /*
8726 * Complete the wlc default state initializations..
8727 */
8728
8729 /* allocate our initial queue */
8730 wlc->pkt_queue = brcms_c_txq_alloc(wlc);
8731 if (wlc->pkt_queue == NULL) {
8732 wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n",
8733 unit, __func__);
8734 err = 100;
8735 goto fail;
8736 }
8737
8738 wlc->bsscfg->wlc = wlc;
8739
8740 wlc->mimoft = FT_HT;
8741 wlc->mimo_40txbw = AUTO;
8742 wlc->ofdm_40txbw = AUTO;
8743 wlc->cck_40txbw = AUTO;
8744 brcms_c_update_mimo_band_bwcap(wlc, BRCMS_N_BW_20IN2G_40IN5G);
8745
8746 /* Set default values of SGI */
8747 if (BRCMS_SGI_CAP_PHY(wlc)) {
8748 brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
8749 BRCMS_N_SGI_40));
8750 } else if (BRCMS_ISSSLPNPHY(wlc->band)) {
8751 brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
8752 BRCMS_N_SGI_40));
8753 } else {
8754 brcms_c_ht_update_sgi_rx(wlc, 0);
8755 }
8756
8757 /* initialize radio_mpc_disable according to wlc->mpc */
8758 brcms_c_radio_mpc_upd(wlc);
8759 brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail);
8760
8761 if (perr)
8762 *perr = 0;
8763
8764 return wlc;
8765
8766 fail:
8767 wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n",
8768 unit, __func__, err);
8769 if (wlc)
8770 brcms_c_detach(wlc);
8771
8772 if (perr)
8773 *perr = err;
8774 return NULL;
8775}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
new file mode 100644
index 000000000000..c0e0fcfdfaf8
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
@@ -0,0 +1,735 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_MAIN_H_
18#define _BRCM_MAIN_H_
19
20#include <linux/etherdevice.h>
21
22#include <brcmu_utils.h>
23#include "types.h"
24#include "d11.h"
25#include "scb.h"
26
27#define INVCHANNEL 255 /* invalid channel */
28
29/* max # brcms_c_module_register() calls */
30#define BRCMS_MAXMODULES 22
31
32#define SEQNUM_SHIFT 4
33#define SEQNUM_MAX 0x1000
34
35#define NTXRATE 64 /* # tx MPDUs rate is reported for */
36
37/* Maximum wait time for a MAC suspend */
38/* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */
39#define BRCMS_MAX_MAC_SUSPEND 83000
40
41/* responses for probe requests older that this are tossed, zero to disable */
42#define BRCMS_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */
43
44/* transmit buffer max headroom for protocol headers */
45#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN)
46
47#define AC_COUNT 4
48
49/* Macros for doing definition and get/set of bitfields
50 * Usage example, e.g. a three-bit field (bits 4-6):
51 * #define <NAME>_M BITFIELD_MASK(3)
52 * #define <NAME>_S 4
53 * ...
54 * regval = R_REG(osh, &regs->regfoo);
55 * field = GFIELD(regval, <NAME>);
56 * regval = SFIELD(regval, <NAME>, 1);
57 * W_REG(osh, &regs->regfoo, regval);
58 */
59#define BITFIELD_MASK(width) \
60 (((unsigned)1 << (width)) - 1)
61#define GFIELD(val, field) \
62 (((val) >> field ## _S) & field ## _M)
63#define SFIELD(val, field, bits) \
64 (((val) & (~(field ## _M << field ## _S))) | \
65 ((unsigned)(bits) << field ## _S))
66
67#define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */
68
69/* max # supported core revisions (0 .. MAXCOREREV - 1) */
70#define MAXCOREREV 28
71
72/* Double check that unsupported cores are not enabled */
73#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV)
74#error "Configuration for D11CONF includes unsupported versions."
75#endif /* Bad versions */
76
77/* values for shortslot_override */
78#define BRCMS_SHORTSLOT_AUTO -1 /* Driver will manage Shortslot setting */
79#define BRCMS_SHORTSLOT_OFF 0 /* Turn off short slot */
80#define BRCMS_SHORTSLOT_ON 1 /* Turn on short slot */
81
82/* value for short/long and mixmode/greenfield preamble */
83#define BRCMS_LONG_PREAMBLE (0)
84#define BRCMS_SHORT_PREAMBLE (1 << 0)
85#define BRCMS_GF_PREAMBLE (1 << 1)
86#define BRCMS_MM_PREAMBLE (1 << 2)
87#define BRCMS_IS_MIMO_PREAMBLE(_pre) (((_pre) == BRCMS_GF_PREAMBLE) || \
88 ((_pre) == BRCMS_MM_PREAMBLE))
89
90/* TxFrameID */
91/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */
92/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */
93#define TXFID_QUEUE_MASK 0x0007 /* Bits 0-2 */
94#define TXFID_SEQ_MASK 0x7FE0 /* Bits 5-15 */
95#define TXFID_SEQ_SHIFT 5 /* Number of bit shifts */
96#define TXFID_RATE_PROBE_MASK 0x8000 /* Bit 15 for rate probe */
97#define TXFID_RATE_MASK 0x0018 /* Mask for bits 3 and 4 */
98#define TXFID_RATE_SHIFT 3 /* Shift 3 bits for rate mask */
99
100/* promote boardrev */
101#define BOARDREV_PROMOTABLE 0xFF /* from */
102#define BOARDREV_PROMOTED 1 /* to */
103
104#define DATA_BLOCK_TX_SUPR (1 << 4)
105
106/* 802.1D Priority to TX FIFO number for wme */
107extern const u8 prio2fifo[];
108
109/* Ucode MCTL_WAKE override bits */
110#define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01
111#define BRCMS_WAKE_OVERRIDE_PHYREG 0x02
112#define BRCMS_WAKE_OVERRIDE_MACSUSPEND 0x04
113#define BRCMS_WAKE_OVERRIDE_TXFIFO 0x08
114#define BRCMS_WAKE_OVERRIDE_FORCEFAST 0x10
115
116/* stuff pulled in from wlc.c */
117
118/* Interrupt bit error summary. Don't include I_RU: we refill DMA at other
119 * times; and if we run out, constant I_RU interrupts may cause lockup. We
120 * will still get error counts from rx0ovfl.
121 */
122#define I_ERRORS (I_PC | I_PD | I_DE | I_RO | I_XU)
123/* default software intmasks */
124#define DEF_RXINTMASK (I_RI) /* enable rx int on rxfifo only */
125#define DEF_MACINTMASK (MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \
126 MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \
127 MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP)
128
129#define MAXTXPKTS 6 /* max # pkts pending */
130
131/* frameburst */
132#define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */
133#define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */
134
135#define NFIFO 6 /* # tx/rx fifopairs */
136
137/* PLL requests */
138
139/* pll is shared on old chips */
140#define BRCMS_PLLREQ_SHARED 0x1
141/* hold pll for radio monitor register checking */
142#define BRCMS_PLLREQ_RADIO_MON 0x2
143/* hold/release pll for some short operation */
144#define BRCMS_PLLREQ_FLIP 0x4
145
146#define CHANNEL_BANDUNIT(wlc, ch) \
147 (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX)
148
149#define OTHERBANDUNIT(wlc) \
150 ((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX))
151
152/*
153 * 802.11 protection information
154 *
155 * _g: use g spec protection, driver internal.
156 * g_override: override for use of g spec protection.
157 * gmode_user: user config gmode, operating band->gmode is different.
158 * overlap: Overlap BSS/IBSS protection for both 11g and 11n.
159 * nmode_user: user config nmode, operating pub->nmode is different.
160 * n_cfg: use OFDM protection on MIMO frames.
161 * n_cfg_override: override for use of N protection.
162 * nongf: non-GF present protection.
163 * nongf_override: override for use of GF protection.
164 * n_pam_override: override for preamble: MM or GF.
165 * n_obss: indicated OBSS Non-HT STA present.
166*/
167struct brcms_protection {
168 bool _g;
169 s8 g_override;
170 u8 gmode_user;
171 s8 overlap;
172 s8 nmode_user;
173 s8 n_cfg;
174 s8 n_cfg_override;
175 bool nongf;
176 s8 nongf_override;
177 s8 n_pam_override;
178 bool n_obss;
179};
180
181/*
182 * anything affecting the single/dual streams/antenna operation
183 *
184 * hw_txchain: HW txchain bitmap cfg.
185 * txchain: txchain bitmap being used.
186 * txstreams: number of txchains being used.
187 * hw_rxchain: HW rxchain bitmap cfg.
188 * rxchain: rxchain bitmap being used.
189 * rxstreams: number of rxchains being used.
190 * ant_rx_ovr: rx antenna override.
191 * txant: userTx antenna setting.
192 * phytxant: phyTx antenna setting in txheader.
193 * ss_opmode: singlestream Operational mode, 0:siso; 1:cdd.
194 * ss_algosel_auto: if true, use wlc->stf->ss_algo_channel;
195 * else use wlc->band->stf->ss_mode_band.
196 * ss_algo_channel: ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC.
197 * rxchain_restore_delay: delay time to restore default rxchain.
198 * ldpc: AUTO/ON/OFF ldpc cap supported.
199 * txcore[MAX_STREAMS_SUPPORTED + 1]: bitmap of selected core for each Nsts.
200 * spatial_policy:
201 */
202struct brcms_stf {
203 u8 hw_txchain;
204 u8 txchain;
205 u8 txstreams;
206 u8 hw_rxchain;
207 u8 rxchain;
208 u8 rxstreams;
209 u8 ant_rx_ovr;
210 s8 txant;
211 u16 phytxant;
212 u8 ss_opmode;
213 bool ss_algosel_auto;
214 u16 ss_algo_channel;
215 u8 rxchain_restore_delay;
216 s8 ldpc;
217 u8 txcore[MAX_STREAMS_SUPPORTED + 1];
218 s8 spatial_policy;
219};
220
221#define BRCMS_STF_SS_STBC_TX(wlc, scb) \
222 (((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) \
223 || (((scb)->flags & SCB_STBCCAP) && \
224 (wlc)->band->band_stf_stbc_tx == AUTO && \
225 isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC))))
226
227#define BRCMS_STBC_CAP_PHY(wlc) (BRCMS_ISNPHY(wlc->band) && \
228 NREV_GE(wlc->band->phyrev, 3))
229
230#define BRCMS_SGI_CAP_PHY(wlc) ((BRCMS_ISNPHY(wlc->band) && \
231 NREV_GE(wlc->band->phyrev, 3)) || \
232 BRCMS_ISLCNPHY(wlc->band))
233
234#define BRCMS_CHAN_PHYTYPE(x) (((x) & RXS_CHAN_PHYTYPE_MASK) \
235 >> RXS_CHAN_PHYTYPE_SHIFT)
236#define BRCMS_CHAN_CHANNEL(x) (((x) & RXS_CHAN_ID_MASK) \
237 >> RXS_CHAN_ID_SHIFT)
238
239/*
240 * core state (mac)
241 */
242struct brcms_core {
243 uint coreidx; /* # sb enumerated core */
244
245 /* fifo */
246 uint *txavail[NFIFO]; /* # tx descriptors available */
247 s16 txpktpend[NFIFO]; /* tx admission control */
248
249 struct macstat *macstat_snapshot; /* mac hw prev read values */
250};
251
252/*
253 * band state (phy+ana+radio)
254 */
255struct brcms_band {
256 int bandtype; /* BRCM_BAND_2G, BRCM_BAND_5G */
257 uint bandunit; /* bandstate[] index */
258
259 u16 phytype; /* phytype */
260 u16 phyrev;
261 u16 radioid;
262 u16 radiorev;
263 struct brcms_phy_pub *pi; /* pointer to phy specific information */
264 bool abgphy_encore;
265
266 u8 gmode; /* currently active gmode */
267
268 struct scb *hwrs_scb; /* permanent scb for hw rateset */
269
270 /* band-specific copy of default_bss.rateset */
271 struct brcms_c_rateset defrateset;
272
273 u8 band_stf_ss_mode; /* Configured STF type, 0:siso; 1:cdd */
274 s8 band_stf_stbc_tx; /* STBC TX 0:off; 1:force on; -1:auto */
275 /* rates supported by chip (phy-specific) */
276 struct brcms_c_rateset hw_rateset;
277 u8 basic_rate[BRCM_MAXRATE + 1]; /* basic rates indexed by rate */
278 bool mimo_cap_40; /* 40 MHz cap enabled on this band */
279 s8 antgain; /* antenna gain from srom */
280
281 u16 CWmin; /* minimum size of contention window, in unit of aSlotTime */
282 u16 CWmax; /* maximum size of contention window, in unit of aSlotTime */
283 struct ieee80211_supported_band band;
284};
285
286/* module control blocks */
287struct modulecb {
288 /* module name : NULL indicates empty array member */
289 char name[32];
290 /* handle passed when handler 'doiovar' is called */
291 struct brcms_info *hdl;
292
293 int (*down_fn)(void *handle); /* down handler. Note: the int returned
294 * by the down function is a count of the
295 * number of timers that could not be
296 * freed.
297 */
298
299};
300
301struct brcms_hw_band {
302 int bandtype; /* BRCM_BAND_2G, BRCM_BAND_5G */
303 uint bandunit; /* bandstate[] index */
304 u16 mhfs[MHFMAX]; /* MHF array shadow */
305 u8 bandhw_stf_ss_mode; /* HW configured STF type, 0:siso; 1:cdd */
306 u16 CWmin;
307 u16 CWmax;
308 u32 core_flags;
309
310 u16 phytype; /* phytype */
311 u16 phyrev;
312 u16 radioid;
313 u16 radiorev;
314 struct brcms_phy_pub *pi; /* pointer to phy specific information */
315 bool abgphy_encore;
316};
317
318struct brcms_hardware {
319 bool _piomode; /* true if pio mode */
320 struct brcms_c_info *wlc;
321
322 /* fifo */
323 struct dma_pub *di[NFIFO]; /* dma handles, per fifo */
324
325 uint unit; /* device instance number */
326
327 /* version info */
328 u16 vendorid; /* PCI vendor id */
329 u16 deviceid; /* PCI device id */
330 uint corerev; /* core revision */
331 u8 sromrev; /* version # of the srom */
332 u16 boardrev; /* version # of particular board */
333 u32 boardflags; /* Board specific flags from srom */
334 u32 boardflags2; /* More board flags if sromrev >= 4 */
335 u32 machwcap; /* MAC capabilities */
336 u32 machwcap_backup; /* backup of machwcap */
337
338 struct si_pub *sih; /* SI handle (cookie for siutils calls) */
339 struct d11regs __iomem *regs; /* pointer to device registers */
340 struct phy_shim_info *physhim; /* phy shim layer handler */
341 struct shared_phy *phy_sh; /* pointer to shared phy state */
342 struct brcms_hw_band *band;/* pointer to active per-band state */
343 /* band state per phy/radio */
344 struct brcms_hw_band *bandstate[MAXBANDS];
345 u16 bmac_phytxant; /* cache of high phytxant state */
346 bool shortslot; /* currently using 11g ShortSlot timing */
347 u16 SRL; /* 802.11 dot11ShortRetryLimit */
348 u16 LRL; /* 802.11 dot11LongRetryLimit */
349 u16 SFBL; /* Short Frame Rate Fallback Limit */
350 u16 LFBL; /* Long Frame Rate Fallback Limit */
351
352 bool up; /* d11 hardware up and running */
353 uint now; /* # elapsed seconds */
354 uint _nbands; /* # bands supported */
355 u16 chanspec; /* bmac chanspec shadow */
356
357 uint *txavail[NFIFO]; /* # tx descriptors available */
358 const u16 *xmtfifo_sz; /* fifo size in 256B for each xmt fifo */
359
360 u32 pllreq; /* pll requests to keep PLL on */
361
362 u8 suspended_fifos; /* Which TX fifo to remain awake for */
363 u32 maccontrol; /* Cached value of maccontrol */
364 uint mac_suspend_depth; /* current depth of mac_suspend levels */
365 u32 wake_override; /* bit flags to force MAC to WAKE mode */
366 u32 mute_override; /* Prevent ucode from sending beacons */
367 u8 etheraddr[ETH_ALEN]; /* currently configured ethernet address */
368 bool noreset; /* true= do not reset hw, used by WLC_OUT */
369 bool forcefastclk; /* true if h/w is forcing to use fast clk */
370 bool clk; /* core is out of reset and has clock */
371 bool sbclk; /* sb has clock */
372 bool phyclk; /* phy is out of reset and has clock */
373
374 bool ucode_loaded; /* true after ucode downloaded */
375
376
377 u8 hw_stf_ss_opmode; /* STF single stream operation mode */
378 u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic
379 * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
380 */
381 u32 antsel_avail; /*
382 * put struct antsel_info here if more info is
383 * needed
384 */
385};
386
387/* TX Queue information
388 *
389 * Each flow of traffic out of the device has a TX Queue with independent
390 * flow control. Several interfaces may be associated with a single TX Queue
391 * if they belong to the same flow of traffic from the device. For multi-channel
392 * operation there are independent TX Queues for each channel.
393 */
394struct brcms_txq_info {
395 struct brcms_txq_info *next;
396 struct pktq q;
397 uint stopped; /* tx flow control bits */
398};
399
400/*
401 * Principal common driver data structure.
402 *
403 * pub: pointer to driver public state.
404 * wl: pointer to specific private state.
405 * regs: pointer to device registers.
406 * hw: HW related state.
407 * clkreq_override: setting for clkreq for PCIE : Auto, 0, 1.
408 * fastpwrup_dly: time in us needed to bring up d11 fast clock.
409 * macintstatus: bit channel between isr and dpc.
410 * macintmask: sw runtime master macintmask value.
411 * defmacintmask: default "on" macintmask value.
412 * clk: core is out of reset and has clock.
413 * core: pointer to active io core.
414 * band: pointer to active per-band state.
415 * corestate: per-core state (one per hw core).
416 * bandstate: per-band state (one per phy/radio).
417 * qvalid: DirFrmQValid and BcMcFrmQValid.
418 * ampdu: ampdu module handler.
419 * asi: antsel module handler.
420 * cmi: channel manager module handler.
421 * vendorid: PCI vendor id.
422 * deviceid: PCI device id.
423 * ucode_rev: microcode revision.
424 * machwcap: MAC capabilities, BMAC shadow.
425 * perm_etheraddr: original sprom local ethernet address.
426 * bandlocked: disable auto multi-band switching.
427 * bandinit_pending: track band init in auto band.
428 * radio_monitor: radio timer is running.
429 * going_down: down path intermediate variable.
430 * mpc: enable minimum power consumption.
431 * mpc_dlycnt: # of watchdog cnt before turn disable radio.
432 * mpc_offcnt: # of watchdog cnt that radio is disabled.
433 * mpc_delay_off: delay radio disable by # of watchdog cnt.
434 * prev_non_delay_mpc: prev state brcms_c_is_non_delay_mpc.
435 * wdtimer: timer for watchdog routine.
436 * radio_timer: timer for hw radio button monitor routine.
437 * monitor: monitor (MPDU sniffing) mode.
438 * bcnmisc_monitor: bcns promisc mode override for monitor.
439 * _rifs: enable per-packet rifs.
440 * bcn_li_bcn: beacon listen interval in # beacons.
441 * bcn_li_dtim: beacon listen interval in # dtims.
442 * WDarmed: watchdog timer is armed.
443 * WDlast: last time wlc_watchdog() was called.
444 * edcf_txop[AC_COUNT]: current txop for each ac.
445 * wme_retries: per-AC retry limits.
446 * tx_prec_map: Precedence map based on HW FIFO space.
447 * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME.
448 * bsscfg: set of BSS configurations, idx 0 is default and always valid.
449 * cfg: the primary bsscfg (can be AP or STA).
450 * tx_queues: common TX Queue list.
451 * modulecb:
452 * mimoft: SIGN or 11N.
453 * cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode.
454 * ofdm_40txbw: 11N, ofdm tx b/w override when in 40MHZ mode.
455 * mimo_40txbw: 11N, mimo tx b/w override when in 40MHZ mode.
456 * default_bss: configured BSS parameters.
457 * mc_fid_counter: BC/MC FIFO frame ID counter.
458 * country_default: saved country for leaving 802.11d auto-country mode.
459 * autocountry_default: initial country for 802.11d auto-country mode.
460 * prb_resp_timeout: do not send prb resp if request older
461 * than this, 0 = disable.
462 * home_chanspec: shared home chanspec.
463 * chanspec: target operational channel.
464 * usr_fragthresh: user configured fragmentation threshold.
465 * fragthresh[NFIFO]: per-fifo fragmentation thresholds.
466 * RTSThresh: 802.11 dot11RTSThreshold.
467 * SRL: 802.11 dot11ShortRetryLimit.
468 * LRL: 802.11 dot11LongRetryLimit.
469 * SFBL: Short Frame Rate Fallback Limit.
470 * LFBL: Long Frame Rate Fallback Limit.
471 * shortslot: currently using 11g ShortSlot timing.
472 * shortslot_override: 11g ShortSlot override.
473 * include_legacy_erp: include Legacy ERP info elt ID 47 as well as g ID 42.
474 * PLCPHdr_override: 802.11b Preamble Type override.
475 * stf:
476 * bcn_rspec: save bcn ratespec purpose.
477 * tempsense_lasttime;
478 * tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM.
479 * tx_duty_cycle_cck: maximum allowed duty cycle for CCK.
480 * pkt_queue: txq for transmit packets.
481 * wiphy:
482 * pri_scb: primary Station Control Block
483 */
484struct brcms_c_info {
485 struct brcms_pub *pub;
486 struct brcms_info *wl;
487 struct d11regs __iomem *regs;
488 struct brcms_hardware *hw;
489
490 /* clock */
491 u16 fastpwrup_dly;
492
493 /* interrupt */
494 u32 macintstatus;
495 u32 macintmask;
496 u32 defmacintmask;
497
498 bool clk;
499
500 /* multiband */
501 struct brcms_core *core;
502 struct brcms_band *band;
503 struct brcms_core *corestate;
504 struct brcms_band *bandstate[MAXBANDS];
505
506 /* packet queue */
507 uint qvalid;
508
509 struct ampdu_info *ampdu;
510 struct antsel_info *asi;
511 struct brcms_cm_info *cmi;
512
513 u16 vendorid;
514 u16 deviceid;
515 uint ucode_rev;
516
517 u8 perm_etheraddr[ETH_ALEN];
518
519 bool bandlocked;
520 bool bandinit_pending;
521
522 bool radio_monitor;
523 bool going_down;
524
525 bool mpc;
526 u8 mpc_dlycnt;
527 u8 mpc_offcnt;
528 u8 mpc_delay_off;
529 u8 prev_non_delay_mpc;
530
531 struct brcms_timer *wdtimer;
532 struct brcms_timer *radio_timer;
533
534 /* promiscuous */
535 bool monitor;
536 bool bcnmisc_monitor;
537
538 /* driver feature */
539 bool _rifs;
540
541 /* AP-STA synchronization, power save */
542 u8 bcn_li_bcn;
543 u8 bcn_li_dtim;
544
545 bool WDarmed;
546 u32 WDlast;
547
548 /* WME */
549 u16 edcf_txop[AC_COUNT];
550
551 u16 wme_retries[AC_COUNT];
552 u16 tx_prec_map;
553 u16 fifo2prec_map[NFIFO];
554
555 struct brcms_bss_cfg *bsscfg;
556
557 /* tx queue */
558 struct brcms_txq_info *tx_queues;
559
560 struct modulecb *modulecb;
561
562 u8 mimoft;
563 s8 cck_40txbw;
564 s8 ofdm_40txbw;
565 s8 mimo_40txbw;
566
567 struct brcms_bss_info *default_bss;
568
569 u16 mc_fid_counter;
570
571 char country_default[BRCM_CNTRY_BUF_SZ];
572 char autocountry_default[BRCM_CNTRY_BUF_SZ];
573 u16 prb_resp_timeout;
574
575 u16 home_chanspec;
576
577 /* PHY parameters */
578 u16 chanspec;
579 u16 usr_fragthresh;
580 u16 fragthresh[NFIFO];
581 u16 RTSThresh;
582 u16 SRL;
583 u16 LRL;
584 u16 SFBL;
585 u16 LFBL;
586
587 /* network config */
588 bool shortslot;
589 s8 shortslot_override;
590 bool include_legacy_erp;
591
592 struct brcms_protection *protection;
593 s8 PLCPHdr_override;
594
595 struct brcms_stf *stf;
596
597 u32 bcn_rspec;
598
599 uint tempsense_lasttime;
600
601 u16 tx_duty_cycle_ofdm;
602 u16 tx_duty_cycle_cck;
603
604 struct brcms_txq_info *pkt_queue;
605 struct wiphy *wiphy;
606 struct scb pri_scb;
607};
608
609/* antsel module specific state */
610struct antsel_info {
611 struct brcms_c_info *wlc; /* pointer to main wlc structure */
612 struct brcms_pub *pub; /* pointer to public fn */
613 u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic
614 * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
615 */
616 u8 antsel_antswitch; /* board level antenna switch type */
617 bool antsel_avail; /* Ant selection availability (SROM based) */
618 struct brcms_antselcfg antcfg_11n; /* antenna configuration */
619 struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */
620};
621
622/*
623 * BSS configuration state
624 *
625 * wlc: wlc to which this bsscfg belongs to.
626 * up: is this configuration up operational
627 * enable: is this configuration enabled
628 * associated: is BSS in ASSOCIATED state
629 * BSS: infraustructure or adhoc
630 * SSID_len: the length of SSID
631 * SSID: SSID string
632 *
633 *
634 * BSSID: BSSID (associated)
635 * cur_etheraddr: h/w address
636 * flags: BSSCFG flags; see below
637 *
638 * current_bss: BSS parms in ASSOCIATED state
639 *
640 *
641 * ID: 'unique' ID of this bsscfg, assigned at bsscfg allocation
642 */
643struct brcms_bss_cfg {
644 struct brcms_c_info *wlc;
645 bool up;
646 bool enable;
647 bool associated;
648 bool BSS;
649 u8 SSID_len;
650 u8 SSID[IEEE80211_MAX_SSID_LEN];
651 u8 BSSID[ETH_ALEN];
652 u8 cur_etheraddr[ETH_ALEN];
653 struct brcms_bss_info *current_bss;
654};
655
656extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
657 struct sk_buff *p,
658 bool commit, s8 txpktpend);
659extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo,
660 s8 txpktpend);
661extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
662 struct sk_buff *sdu, uint prec);
663extern void brcms_c_print_txstatus(struct tx_status *txs);
664extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
665 uint *blocks);
666
667#if defined(BCMDBG)
668extern void brcms_c_print_txdesc(struct d11txh *txh);
669#else
670#define brcms_c_print_txdesc(a)
671#endif
672
673extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
674extern void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc,
675 bool promisc);
676extern void brcms_c_send_q(struct brcms_c_info *wlc);
677extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu,
678 uint *fifo);
679extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
680 uint mac_len);
681extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc,
682 u32 rspec,
683 bool use_rspec, u16 mimo_ctlchbw);
684extern u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
685 u32 rts_rate,
686 u32 frame_rate,
687 u8 rts_preamble_type,
688 u8 frame_preamble_type, uint frame_len,
689 bool ba);
690extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
691 struct ieee80211_sta *sta,
692 void (*dma_callback_fn));
693extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
694extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend);
695extern int brcms_c_set_nmode(struct brcms_c_info *wlc);
696extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
697 u32 bcn_rate);
698extern void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw,
699 u8 antsel_type);
700extern void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw,
701 u16 chanspec,
702 bool mute, struct txpwr_limits *txpwr);
703extern void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset,
704 u16 v);
705extern u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset);
706extern void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask,
707 u16 val, int bands);
708extern void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags);
709extern void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val);
710extern void brcms_b_phy_reset(struct brcms_hardware *wlc_hw);
711extern void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw);
712extern void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw);
713extern void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
714 u32 override_bit);
715extern void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
716 u32 override_bit);
717extern void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw,
718 int offset, int len, void *buf);
719extern u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate);
720extern void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw,
721 uint offset, const void *buf, int len,
722 u32 sel);
723extern void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset,
724 void *buf, int len, u32 sel);
725extern void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode);
726extern u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw);
727extern void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk);
728extern void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk);
729extern void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on);
730extern void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant);
731extern void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw,
732 u8 stf_mode);
733extern void brcms_c_init_scb(struct scb *scb);
734
735#endif /* _BRCM_MAIN_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/nicpci.c b/drivers/net/wireless/brcm80211/brcmsmac/nicpci.c
new file mode 100644
index 000000000000..0bcb26792046
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/nicpci.c
@@ -0,0 +1,835 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/slab.h>
18#include <linux/delay.h>
19#include <linux/pci.h>
20
21#include <defs.h>
22#include <soc.h>
23#include <chipcommon.h>
24#include "aiutils.h"
25#include "pub.h"
26#include "nicpci.h"
27
28/* SPROM offsets */
29#define SRSH_ASPM_OFFSET 4 /* word 4 */
30#define SRSH_ASPM_ENB 0x18 /* bit 3, 4 */
31#define SRSH_ASPM_L1_ENB 0x10 /* bit 4 */
32#define SRSH_ASPM_L0s_ENB 0x8 /* bit 3 */
33
34#define SRSH_PCIE_MISC_CONFIG 5 /* word 5 */
35#define SRSH_L23READY_EXIT_NOPERST 0x8000 /* bit 15 */
36#define SRSH_CLKREQ_OFFSET_REV5 20 /* word 20 for srom rev <= 5 */
37#define SRSH_CLKREQ_ENB 0x0800 /* bit 11 */
38#define SRSH_BD_OFFSET 6 /* word 6 */
39
40/* chipcontrol */
41#define CHIPCTRL_4321_PLL_DOWN 0x800000/* serdes PLL down override */
42
43/* MDIO control */
44#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */
45#define MDIOCTL_DIVISOR_VAL 0x2
46#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */
47#define MDIOCTL_ACCESS_DONE 0x100 /* Transaction complete */
48
49/* MDIO Data */
50#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */
51#define MDIODATA_TA 0x00020000 /* Turnaround */
52
53#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */
54#define MDIODATA_REGADDR_MASK 0x007c0000 /* Regaddr Mask */
55#define MDIODATA_DEVADDR_SHF 23 /* Physmedia devaddr shift */
56#define MDIODATA_DEVADDR_MASK 0x0f800000
57 /* Physmedia devaddr Mask */
58
59/* MDIO Data for older revisions < 10 */
60#define MDIODATA_REGADDR_SHF_OLD 18 /* Regaddr shift */
61#define MDIODATA_REGADDR_MASK_OLD 0x003c0000
62 /* Regaddr Mask */
63#define MDIODATA_DEVADDR_SHF_OLD 22 /* Physmedia devaddr shift */
64#define MDIODATA_DEVADDR_MASK_OLD 0x0fc00000
65 /* Physmedia devaddr Mask */
66
67/* Transactions flags */
68#define MDIODATA_WRITE 0x10000000
69#define MDIODATA_READ 0x20000000
70#define MDIODATA_START 0x40000000
71
72#define MDIODATA_DEV_ADDR 0x0 /* dev address for serdes */
73#define MDIODATA_BLK_ADDR 0x1F /* blk address for serdes */
74
75/* serdes regs (rev < 10) */
76#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */
77#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */
78#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */
79
80/* SERDES RX registers */
81#define SERDES_RX_CTRL 1 /* Rx cntrl */
82#define SERDES_RX_TIMER1 2 /* Rx Timer1 */
83#define SERDES_RX_CDR 6 /* CDR */
84#define SERDES_RX_CDRBW 7 /* CDR BW */
85/* SERDES RX control register */
86#define SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */
87#define SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */
88
89/* SERDES PLL registers */
90#define SERDES_PLL_CTRL 1 /* PLL control reg */
91#define PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */
92
93/* Linkcontrol reg offset in PCIE Cap */
94#define PCIE_CAP_LINKCTRL_OFFSET 16 /* offset in pcie cap */
95#define PCIE_CAP_LCREG_ASPML0s 0x01 /* ASPM L0s in linkctrl */
96#define PCIE_CAP_LCREG_ASPML1 0x02 /* ASPM L1 in linkctrl */
97#define PCIE_CLKREQ_ENAB 0x100 /* CLKREQ Enab in linkctrl */
98
99#define PCIE_ASPM_ENAB 3 /* ASPM L0s & L1 in linkctrl */
100#define PCIE_ASPM_L1_ENAB 2 /* ASPM L0s & L1 in linkctrl */
101#define PCIE_ASPM_L0s_ENAB 1 /* ASPM L0s & L1 in linkctrl */
102#define PCIE_ASPM_DISAB 0 /* ASPM L0s & L1 in linkctrl */
103
104/* Power management threshold */
105#define PCIE_L1THRESHOLDTIME_MASK 0xFF00 /* bits 8 - 15 */
106#define PCIE_L1THRESHOLDTIME_SHIFT 8 /* PCIE_L1THRESHOLDTIME_SHIFT */
107#define PCIE_L1THRESHOLD_WARVAL 0x72 /* WAR value */
108#define PCIE_ASPMTIMER_EXTEND 0x01000000
109 /* > rev7:
110 * enable extend ASPM timer
111 */
112
113/* different register spaces to access thru pcie indirect access */
114#define PCIE_CONFIGREGS 1 /* Access to config space */
115#define PCIE_PCIEREGS 2 /* Access to pcie registers */
116
117/* PCIE protocol PHY diagnostic registers */
118#define PCIE_PLP_STATUSREG 0x204 /* Status */
119
120/* Status reg PCIE_PLP_STATUSREG */
121#define PCIE_PLP_POLARITYINV_STAT 0x10
122
123/* PCIE protocol DLLP diagnostic registers */
124#define PCIE_DLLP_LCREG 0x100 /* Link Control */
125#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */
126
127/* PCIE protocol TLP diagnostic registers */
128#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */
129
130/* Sonics to PCI translation types */
131#define SBTOPCI_PREF 0x4 /* prefetch enable */
132#define SBTOPCI_BURST 0x8 /* burst enable */
133#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */
134
135#define PCI_CLKRUN_DSBL 0x8000 /* Bit 15 forceClkrun */
136
137/* PCI core index in SROM shadow area */
138#define SRSH_PI_OFFSET 0 /* first word */
139#define SRSH_PI_MASK 0xf000 /* bit 15:12 */
140#define SRSH_PI_SHIFT 12 /* bit 15:12 */
141
142/* Sonics side: PCI core and host control registers */
143struct sbpciregs {
144 u32 control; /* PCI control */
145 u32 PAD[3];
146 u32 arbcontrol; /* PCI arbiter control */
147 u32 clkrun; /* Clkrun Control (>=rev11) */
148 u32 PAD[2];
149 u32 intstatus; /* Interrupt status */
150 u32 intmask; /* Interrupt mask */
151 u32 sbtopcimailbox; /* Sonics to PCI mailbox */
152 u32 PAD[9];
153 u32 bcastaddr; /* Sonics broadcast address */
154 u32 bcastdata; /* Sonics broadcast data */
155 u32 PAD[2];
156 u32 gpioin; /* ro: gpio input (>=rev2) */
157 u32 gpioout; /* rw: gpio output (>=rev2) */
158 u32 gpioouten; /* rw: gpio output enable (>= rev2) */
159 u32 gpiocontrol; /* rw: gpio control (>= rev2) */
160 u32 PAD[36];
161 u32 sbtopci0; /* Sonics to PCI translation 0 */
162 u32 sbtopci1; /* Sonics to PCI translation 1 */
163 u32 sbtopci2; /* Sonics to PCI translation 2 */
164 u32 PAD[189];
165 u32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */
166 u16 sprom[36]; /* SPROM shadow Area */
167 u32 PAD[46];
168};
169
170/* SB side: PCIE core and host control registers */
171struct sbpcieregs {
172 u32 control; /* host mode only */
173 u32 PAD[2];
174 u32 biststatus; /* bist Status: 0x00C */
175 u32 gpiosel; /* PCIE gpio sel: 0x010 */
176 u32 gpioouten; /* PCIE gpio outen: 0x14 */
177 u32 PAD[2];
178 u32 intstatus; /* Interrupt status: 0x20 */
179 u32 intmask; /* Interrupt mask: 0x24 */
180 u32 sbtopcimailbox; /* sb to pcie mailbox: 0x028 */
181 u32 PAD[53];
182 u32 sbtopcie0; /* sb to pcie translation 0: 0x100 */
183 u32 sbtopcie1; /* sb to pcie translation 1: 0x104 */
184 u32 sbtopcie2; /* sb to pcie translation 2: 0x108 */
185 u32 PAD[5];
186
187 /* pcie core supports in direct access to config space */
188 u32 configaddr; /* pcie config space access: Address field: 0x120 */
189 u32 configdata; /* pcie config space access: Data field: 0x124 */
190
191 /* mdio access to serdes */
192 u32 mdiocontrol; /* controls the mdio access: 0x128 */
193 u32 mdiodata; /* Data to the mdio access: 0x12c */
194
195 /* pcie protocol phy/dllp/tlp register indirect access mechanism */
196 u32 pcieindaddr; /* indirect access to
197 * the internal register: 0x130
198 */
199 u32 pcieinddata; /* Data to/from the internal regsiter: 0x134 */
200
201 u32 clkreqenctrl; /* >= rev 6, Clkreq rdma control : 0x138 */
202 u32 PAD[177];
203 u32 pciecfg[4][64]; /* 0x400 - 0x7FF, PCIE Cfg Space */
204 u16 sprom[64]; /* SPROM shadow Area */
205};
206
207struct pcicore_info {
208 union {
209 struct sbpcieregs __iomem *pcieregs;
210 struct sbpciregs __iomem *pciregs;
211 } regs; /* Memory mapped register to the core */
212
213 struct si_pub *sih; /* System interconnect handle */
214 struct pci_dev *dev;
215 u8 pciecap_lcreg_offset;/* PCIE capability LCreg offset
216 * in the config space
217 */
218 bool pcie_pr42767;
219 u8 pcie_polarity;
220 u8 pcie_war_aspm_ovr; /* Override ASPM/Clkreq settings */
221
222 u8 pmecap_offset; /* PM Capability offset in the config space */
223 bool pmecap; /* Capable of generating PME */
224};
225
226#define PCIE_ASPM(sih) \
227 (((sih)->buscoretype == PCIE_CORE_ID) && \
228 (((sih)->buscorerev >= 3) && \
229 ((sih)->buscorerev <= 5)))
230
231
232/* delay needed between the mdio control/ mdiodata register data access */
233static void pr28829_delay(void)
234{
235 udelay(10);
236}
237
238/* Initialize the PCI core.
239 * It's caller's responsibility to make sure that this is done only once
240 */
241struct pcicore_info *pcicore_init(struct si_pub *sih, struct pci_dev *pdev,
242 void __iomem *regs)
243{
244 struct pcicore_info *pi;
245
246 /* alloc struct pcicore_info */
247 pi = kzalloc(sizeof(struct pcicore_info), GFP_ATOMIC);
248 if (pi == NULL)
249 return NULL;
250
251 pi->sih = sih;
252 pi->dev = pdev;
253
254 if (sih->buscoretype == PCIE_CORE_ID) {
255 u8 cap_ptr;
256 pi->regs.pcieregs = regs;
257 cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP,
258 NULL, NULL);
259 pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
260 } else
261 pi->regs.pciregs = regs;
262
263 return pi;
264}
265
266void pcicore_deinit(struct pcicore_info *pch)
267{
268 kfree(pch);
269}
270
271/* return cap_offset if requested capability exists in the PCI config space */
272/* Note that it's caller's responsibility to make sure it's a pci bus */
273u8
274pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,
275 unsigned char *buf, u32 *buflen)
276{
277 u8 cap_id;
278 u8 cap_ptr = 0;
279 u32 bufsize;
280 u8 byte_val;
281
282 /* check for Header type 0 */
283 pci_read_config_byte(dev, PCI_HEADER_TYPE, &byte_val);
284 if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
285 goto end;
286
287 /* check if the capability pointer field exists */
288 pci_read_config_byte(dev, PCI_STATUS, &byte_val);
289 if (!(byte_val & PCI_STATUS_CAP_LIST))
290 goto end;
291
292 pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &cap_ptr);
293 /* check if the capability pointer is 0x00 */
294 if (cap_ptr == 0x00)
295 goto end;
296
297 /* loop thru the capability list
298 * and see if the pcie capability exists
299 */
300
301 pci_read_config_byte(dev, cap_ptr, &cap_id);
302
303 while (cap_id != req_cap_id) {
304 pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr);
305 if (cap_ptr == 0x00)
306 break;
307 pci_read_config_byte(dev, cap_ptr, &cap_id);
308 }
309 if (cap_id != req_cap_id)
310 goto end;
311
312 /* found the caller requested capability */
313 if (buf != NULL && buflen != NULL) {
314 u8 cap_data;
315
316 bufsize = *buflen;
317 if (!bufsize)
318 goto end;
319 *buflen = 0;
320 /* copy the capability data excluding cap ID and next ptr */
321 cap_data = cap_ptr + 2;
322 if ((bufsize + cap_data) > PCI_SZPCR)
323 bufsize = PCI_SZPCR - cap_data;
324 *buflen = bufsize;
325 while (bufsize--) {
326 pci_read_config_byte(dev, cap_data, buf);
327 cap_data++;
328 buf++;
329 }
330 }
331end:
332 return cap_ptr;
333}
334
335/* ***** Register Access API */
336static uint
337pcie_readreg(struct sbpcieregs __iomem *pcieregs, uint addrtype, uint offset)
338{
339 uint retval = 0xFFFFFFFF;
340
341 switch (addrtype) {
342 case PCIE_CONFIGREGS:
343 W_REG(&pcieregs->configaddr, offset);
344 (void)R_REG((&pcieregs->configaddr));
345 retval = R_REG(&pcieregs->configdata);
346 break;
347 case PCIE_PCIEREGS:
348 W_REG(&pcieregs->pcieindaddr, offset);
349 (void)R_REG(&pcieregs->pcieindaddr);
350 retval = R_REG(&pcieregs->pcieinddata);
351 break;
352 }
353
354 return retval;
355}
356
357static uint pcie_writereg(struct sbpcieregs __iomem *pcieregs, uint addrtype,
358 uint offset, uint val)
359{
360 switch (addrtype) {
361 case PCIE_CONFIGREGS:
362 W_REG((&pcieregs->configaddr), offset);
363 W_REG((&pcieregs->configdata), val);
364 break;
365 case PCIE_PCIEREGS:
366 W_REG((&pcieregs->pcieindaddr), offset);
367 W_REG((&pcieregs->pcieinddata), val);
368 break;
369 default:
370 break;
371 }
372 return 0;
373}
374
375static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk)
376{
377 struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
378 uint mdiodata, i = 0;
379 uint pcie_serdes_spinwait = 200;
380
381 mdiodata = (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
382 (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
383 (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) |
384 (blk << 4));
385 W_REG(&pcieregs->mdiodata, mdiodata);
386
387 pr28829_delay();
388 /* retry till the transaction is complete */
389 while (i < pcie_serdes_spinwait) {
390 if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE)
391 break;
392
393 udelay(1000);
394 i++;
395 }
396
397 if (i >= pcie_serdes_spinwait)
398 return false;
399
400 return true;
401}
402
403static int
404pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
405 uint *val)
406{
407 struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
408 uint mdiodata;
409 uint i = 0;
410 uint pcie_serdes_spinwait = 10;
411
412 /* enable mdio access to SERDES */
413 W_REG(&pcieregs->mdiocontrol, MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
414
415 if (pi->sih->buscorerev >= 10) {
416 /* new serdes is slower in rw,
417 * using two layers of reg address mapping
418 */
419 if (!pcie_mdiosetblock(pi, physmedia))
420 return 1;
421 mdiodata = ((MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
422 (regaddr << MDIODATA_REGADDR_SHF));
423 pcie_serdes_spinwait *= 20;
424 } else {
425 mdiodata = ((physmedia << MDIODATA_DEVADDR_SHF_OLD) |
426 (regaddr << MDIODATA_REGADDR_SHF_OLD));
427 }
428
429 if (!write)
430 mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
431 else
432 mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
433 *val);
434
435 W_REG(&pcieregs->mdiodata, mdiodata);
436
437 pr28829_delay();
438
439 /* retry till the transaction is complete */
440 while (i < pcie_serdes_spinwait) {
441 if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE) {
442 if (!write) {
443 pr28829_delay();
444 *val = (R_REG(&pcieregs->mdiodata) &
445 MDIODATA_MASK);
446 }
447 /* Disable mdio access to SERDES */
448 W_REG(&pcieregs->mdiocontrol, 0);
449 return 0;
450 }
451 udelay(1000);
452 i++;
453 }
454
455 /* Timed out. Disable mdio access to SERDES. */
456 W_REG(&pcieregs->mdiocontrol, 0);
457 return 1;
458}
459
460/* use the mdio interface to read from mdio slaves */
461static int
462pcie_mdioread(struct pcicore_info *pi, uint physmedia, uint regaddr,
463 uint *regval)
464{
465 return pcie_mdioop(pi, physmedia, regaddr, false, regval);
466}
467
468/* use the mdio interface to write to mdio slaves */
469static int
470pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint regaddr, uint val)
471{
472 return pcie_mdioop(pi, physmedia, regaddr, true, &val);
473}
474
475/* ***** Support functions ***** */
476static u8 pcie_clkreq(struct pcicore_info *pi, u32 mask, u32 val)
477{
478 u32 reg_val;
479 u8 offset;
480
481 offset = pi->pciecap_lcreg_offset;
482 if (!offset)
483 return 0;
484
485 pci_read_config_dword(pi->dev, offset, &reg_val);
486 /* set operation */
487 if (mask) {
488 if (val)
489 reg_val |= PCIE_CLKREQ_ENAB;
490 else
491 reg_val &= ~PCIE_CLKREQ_ENAB;
492 pci_write_config_dword(pi->dev, offset, reg_val);
493 pci_read_config_dword(pi->dev, offset, &reg_val);
494 }
495 if (reg_val & PCIE_CLKREQ_ENAB)
496 return 1;
497 else
498 return 0;
499}
500
501static void pcie_extendL1timer(struct pcicore_info *pi, bool extend)
502{
503 u32 w;
504 struct si_pub *sih = pi->sih;
505 struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
506
507 if (sih->buscoretype != PCIE_CORE_ID || sih->buscorerev < 7)
508 return;
509
510 w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
511 if (extend)
512 w |= PCIE_ASPMTIMER_EXTEND;
513 else
514 w &= ~PCIE_ASPMTIMER_EXTEND;
515 pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
516 w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
517}
518
519/* centralized clkreq control policy */
520static void pcie_clkreq_upd(struct pcicore_info *pi, uint state)
521{
522 struct si_pub *sih = pi->sih;
523
524 switch (state) {
525 case SI_DOATTACH:
526 if (PCIE_ASPM(sih))
527 pcie_clkreq(pi, 1, 0);
528 break;
529 case SI_PCIDOWN:
530 if (sih->buscorerev == 6) { /* turn on serdes PLL down */
531 ai_corereg(sih, SI_CC_IDX,
532 offsetof(struct chipcregs, chipcontrol_addr),
533 ~0, 0);
534 ai_corereg(sih, SI_CC_IDX,
535 offsetof(struct chipcregs, chipcontrol_data),
536 ~0x40, 0);
537 } else if (pi->pcie_pr42767) {
538 pcie_clkreq(pi, 1, 1);
539 }
540 break;
541 case SI_PCIUP:
542 if (sih->buscorerev == 6) { /* turn off serdes PLL down */
543 ai_corereg(sih, SI_CC_IDX,
544 offsetof(struct chipcregs, chipcontrol_addr),
545 ~0, 0);
546 ai_corereg(sih, SI_CC_IDX,
547 offsetof(struct chipcregs, chipcontrol_data),
548 ~0x40, 0x40);
549 } else if (PCIE_ASPM(sih)) { /* disable clkreq */
550 pcie_clkreq(pi, 1, 0);
551 }
552 break;
553 }
554}
555
556/* ***** PCI core WARs ***** */
557/* Done only once at attach time */
558static void pcie_war_polarity(struct pcicore_info *pi)
559{
560 u32 w;
561
562 if (pi->pcie_polarity != 0)
563 return;
564
565 w = pcie_readreg(pi->regs.pcieregs, PCIE_PCIEREGS, PCIE_PLP_STATUSREG);
566
567 /* Detect the current polarity at attach and force that polarity and
568 * disable changing the polarity
569 */
570 if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
571 pi->pcie_polarity = SERDES_RX_CTRL_FORCE;
572 else
573 pi->pcie_polarity = (SERDES_RX_CTRL_FORCE |
574 SERDES_RX_CTRL_POLARITY);
575}
576
577/* enable ASPM and CLKREQ if srom doesn't have it */
578/* Needs to happen when update to shadow SROM is needed
579 * : Coming out of 'standby'/'hibernate'
580 * : If pcie_war_aspm_ovr state changed
581 */
582static void pcie_war_aspm_clkreq(struct pcicore_info *pi)
583{
584 struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
585 struct si_pub *sih = pi->sih;
586 u16 val16;
587 u16 __iomem *reg16;
588 u32 w;
589
590 if (!PCIE_ASPM(sih))
591 return;
592
593 /* bypass this on QT or VSIM */
594 reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
595 val16 = R_REG(reg16);
596
597 val16 &= ~SRSH_ASPM_ENB;
598 if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
599 val16 |= SRSH_ASPM_ENB;
600 else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB)
601 val16 |= SRSH_ASPM_L1_ENB;
602 else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
603 val16 |= SRSH_ASPM_L0s_ENB;
604
605 W_REG(reg16, val16);
606
607 pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
608 w &= ~PCIE_ASPM_ENAB;
609 w |= pi->pcie_war_aspm_ovr;
610 pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
611
612 reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5];
613 val16 = R_REG(reg16);
614
615 if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
616 val16 |= SRSH_CLKREQ_ENB;
617 pi->pcie_pr42767 = true;
618 } else
619 val16 &= ~SRSH_CLKREQ_ENB;
620
621 W_REG(reg16, val16);
622}
623
624/* Apply the polarity determined at the start */
625/* Needs to happen when coming out of 'standby'/'hibernate' */
626static void pcie_war_serdes(struct pcicore_info *pi)
627{
628 u32 w = 0;
629
630 if (pi->pcie_polarity != 0)
631 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
632 pi->pcie_polarity);
633
634 pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
635 if (w & PLL_CTRL_FREQDET_EN) {
636 w &= ~PLL_CTRL_FREQDET_EN;
637 pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
638 }
639}
640
641/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
642/* Needs to happen when coming out of 'standby'/'hibernate' */
643static void pcie_misc_config_fixup(struct pcicore_info *pi)
644{
645 struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
646 u16 val16;
647 u16 __iomem *reg16;
648
649 reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG];
650 val16 = R_REG(reg16);
651
652 if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
653 val16 |= SRSH_L23READY_EXIT_NOPERST;
654 W_REG(reg16, val16);
655 }
656}
657
658/* quick hack for testing */
659/* Needs to happen when coming out of 'standby'/'hibernate' */
660static void pcie_war_noplldown(struct pcicore_info *pi)
661{
662 struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
663 u16 __iomem *reg16;
664
665 /* turn off serdes PLL down */
666 ai_corereg(pi->sih, SI_CC_IDX, offsetof(struct chipcregs, chipcontrol),
667 CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
668
669 /* clear srom shadow backdoor */
670 reg16 = &pcieregs->sprom[SRSH_BD_OFFSET];
671 W_REG(reg16, 0);
672}
673
674/* Needs to happen when coming out of 'standby'/'hibernate' */
675static void pcie_war_pci_setup(struct pcicore_info *pi)
676{
677 struct si_pub *sih = pi->sih;
678 struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
679 u32 w;
680
681 if (sih->buscorerev == 0 || sih->buscorerev == 1) {
682 w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
683 PCIE_TLP_WORKAROUNDSREG);
684 w |= 0x8;
685 pcie_writereg(pcieregs, PCIE_PCIEREGS,
686 PCIE_TLP_WORKAROUNDSREG, w);
687 }
688
689 if (sih->buscorerev == 1) {
690 w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
691 w |= 0x40;
692 pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
693 }
694
695 if (sih->buscorerev == 0) {
696 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
697 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
698 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
699 } else if (PCIE_ASPM(sih)) {
700 /* Change the L1 threshold for better performance */
701 w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
702 PCIE_DLLP_PMTHRESHREG);
703 w &= ~PCIE_L1THRESHOLDTIME_MASK;
704 w |= PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT;
705 pcie_writereg(pcieregs, PCIE_PCIEREGS,
706 PCIE_DLLP_PMTHRESHREG, w);
707
708 pcie_war_serdes(pi);
709
710 pcie_war_aspm_clkreq(pi);
711 } else if (pi->sih->buscorerev == 7)
712 pcie_war_noplldown(pi);
713
714 /* Note that the fix is actually in the SROM,
715 * that's why this is open-ended
716 */
717 if (pi->sih->buscorerev >= 6)
718 pcie_misc_config_fixup(pi);
719}
720
721/* ***** Functions called during driver state changes ***** */
722void pcicore_attach(struct pcicore_info *pi, int state)
723{
724 struct si_pub *sih = pi->sih;
725 u32 bfl2 = (u32)getintvar(sih, BRCMS_SROM_BOARDFLAGS2);
726
727 /* Determine if this board needs override */
728 if (PCIE_ASPM(sih)) {
729 if (bfl2 & BFL2_PCIEWAR_OVR)
730 pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
731 else
732 pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
733 }
734
735 /* These need to happen in this order only */
736 pcie_war_polarity(pi);
737
738 pcie_war_serdes(pi);
739
740 pcie_war_aspm_clkreq(pi);
741
742 pcie_clkreq_upd(pi, state);
743
744}
745
746void pcicore_hwup(struct pcicore_info *pi)
747{
748 if (!pi || pi->sih->buscoretype != PCIE_CORE_ID)
749 return;
750
751 pcie_war_pci_setup(pi);
752}
753
754void pcicore_up(struct pcicore_info *pi, int state)
755{
756 if (!pi || pi->sih->buscoretype != PCIE_CORE_ID)
757 return;
758
759 /* Restore L1 timer for better performance */
760 pcie_extendL1timer(pi, true);
761
762 pcie_clkreq_upd(pi, state);
763}
764
765/* When the device is going to enter D3 state
766 * (or the system is going to enter S3/S4 states)
767 */
768void pcicore_sleep(struct pcicore_info *pi)
769{
770 u32 w;
771
772 if (!pi || !PCIE_ASPM(pi->sih))
773 return;
774
775 pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
776 w &= ~PCIE_CAP_LCREG_ASPML1;
777 pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
778
779 pi->pcie_pr42767 = false;
780}
781
782void pcicore_down(struct pcicore_info *pi, int state)
783{
784 if (!pi || pi->sih->buscoretype != PCIE_CORE_ID)
785 return;
786
787 pcie_clkreq_upd(pi, state);
788
789 /* Reduce L1 timer for better power savings */
790 pcie_extendL1timer(pi, false);
791}
792
793/* precondition: current core is sii->buscoretype */
794static void pcicore_fixcfg(struct pcicore_info *pi, u16 __iomem *reg16)
795{
796 struct si_info *sii = (struct si_info *)(pi->sih);
797 u16 val16;
798 uint pciidx;
799
800 pciidx = ai_coreidx(&sii->pub);
801 val16 = R_REG(reg16);
802 if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16)pciidx) {
803 val16 = (u16)(pciidx << SRSH_PI_SHIFT) |
804 (val16 & ~SRSH_PI_MASK);
805 W_REG(reg16, val16);
806 }
807}
808
809void
810pcicore_fixcfg_pci(struct pcicore_info *pi, struct sbpciregs __iomem *pciregs)
811{
812 pcicore_fixcfg(pi, &pciregs->sprom[SRSH_PI_OFFSET]);
813}
814
815void pcicore_fixcfg_pcie(struct pcicore_info *pi,
816 struct sbpcieregs __iomem *pcieregs)
817{
818 pcicore_fixcfg(pi, &pcieregs->sprom[SRSH_PI_OFFSET]);
819}
820
821/* precondition: current core is pci core */
822void
823pcicore_pci_setup(struct pcicore_info *pi, struct sbpciregs __iomem *pciregs)
824{
825 u32 w;
826
827 OR_REG(&pciregs->sbtopci2, SBTOPCI_PREF | SBTOPCI_BURST);
828
829 if (((struct si_info *)(pi->sih))->pub.buscorerev >= 11) {
830 OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI);
831 w = R_REG(&pciregs->clkrun);
832 W_REG(&pciregs->clkrun, w | PCI_CLKRUN_DSBL);
833 w = R_REG(&pciregs->clkrun);
834 }
835}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/nicpci.h b/drivers/net/wireless/brcm80211/brcmsmac/nicpci.h
new file mode 100644
index 000000000000..58aa80dc3329
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/nicpci.h
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_NICPCI_H_
18#define _BRCM_NICPCI_H_
19
20#include "types.h"
21
22/* PCI configuration address space size */
23#define PCI_SZPCR 256
24
25/* Brcm PCI configuration registers */
26/* backplane address space accessed by BAR0 */
27#define PCI_BAR0_WIN 0x80
28/* sprom property control */
29#define PCI_SPROM_CONTROL 0x88
30/* mask of PCI and other cores interrupts */
31#define PCI_INT_MASK 0x94
32/* backplane core interrupt mask bits offset */
33#define PCI_SBIM_SHIFT 8
34/* backplane address space accessed by second 4KB of BAR0 */
35#define PCI_BAR0_WIN2 0xac
36/* pci config space gpio input (>=rev3) */
37#define PCI_GPIO_IN 0xb0
38/* pci config space gpio output (>=rev3) */
39#define PCI_GPIO_OUT 0xb4
40/* pci config space gpio output enable (>=rev3) */
41#define PCI_GPIO_OUTEN 0xb8
42
43/* bar0 + 4K accesses external sprom */
44#define PCI_BAR0_SPROM_OFFSET (4 * 1024)
45/* bar0 + 6K accesses pci core registers */
46#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024)
47/*
48 * pci core SB registers are at the end of the
49 * 8KB window, so their address is the "regular"
50 * address plus 4K
51 */
52#define PCI_BAR0_PCISBR_OFFSET (4 * 1024)
53/* bar0 window size Match with corerev 13 */
54#define PCI_BAR0_WINSZ (16 * 1024)
55/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */
56/* bar0 + 8K accesses pci/pcie core registers */
57#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024)
58/* bar0 + 12K accesses chipc core registers */
59#define PCI_16KB0_CCREGS_OFFSET (12 * 1024)
60
61struct sbpciregs;
62struct sbpcieregs;
63
64extern struct pcicore_info *pcicore_init(struct si_pub *sih,
65 struct pci_dev *pdev,
66 void __iomem *regs);
67extern void pcicore_deinit(struct pcicore_info *pch);
68extern void pcicore_attach(struct pcicore_info *pch, int state);
69extern void pcicore_hwup(struct pcicore_info *pch);
70extern void pcicore_up(struct pcicore_info *pch, int state);
71extern void pcicore_sleep(struct pcicore_info *pch);
72extern void pcicore_down(struct pcicore_info *pch, int state);
73extern u8 pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,
74 unsigned char *buf, u32 *buflen);
75extern void pcicore_fixcfg_pci(struct pcicore_info *pch,
76 struct sbpciregs __iomem *pciregs);
77extern void pcicore_fixcfg_pcie(struct pcicore_info *pch,
78 struct sbpcieregs __iomem *pciregs);
79extern void pcicore_pci_setup(struct pcicore_info *pch,
80 struct sbpciregs __iomem *pciregs);
81
82#endif /* _BRCM_NICPCI_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/otp.c b/drivers/net/wireless/brcm80211/brcmsmac/otp.c
new file mode 100644
index 000000000000..edf551561fd8
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/otp.c
@@ -0,0 +1,426 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/io.h>
18#include <linux/errno.h>
19#include <linux/string.h>
20
21#include <brcm_hw_ids.h>
22#include <chipcommon.h>
23#include "aiutils.h"
24#include "otp.h"
25
26#define OTPS_GUP_MASK 0x00000f00
27#define OTPS_GUP_SHIFT 8
28/* h/w subregion is programmed */
29#define OTPS_GUP_HW 0x00000100
30/* s/w subregion is programmed */
31#define OTPS_GUP_SW 0x00000200
32/* chipid/pkgopt subregion is programmed */
33#define OTPS_GUP_CI 0x00000400
34/* fuse subregion is programmed */
35#define OTPS_GUP_FUSE 0x00000800
36
37/* Fields in otpprog in rev >= 21 */
38#define OTPP_COL_MASK 0x000000ff
39#define OTPP_COL_SHIFT 0
40#define OTPP_ROW_MASK 0x0000ff00
41#define OTPP_ROW_SHIFT 8
42#define OTPP_OC_MASK 0x0f000000
43#define OTPP_OC_SHIFT 24
44#define OTPP_READERR 0x10000000
45#define OTPP_VALUE_MASK 0x20000000
46#define OTPP_VALUE_SHIFT 29
47#define OTPP_START_BUSY 0x80000000
48#define OTPP_READ 0x40000000
49
50/* Opcodes for OTPP_OC field */
51#define OTPPOC_READ 0
52#define OTPPOC_BIT_PROG 1
53#define OTPPOC_VERIFY 3
54#define OTPPOC_INIT 4
55#define OTPPOC_SET 5
56#define OTPPOC_RESET 6
57#define OTPPOC_OCST 7
58#define OTPPOC_ROW_LOCK 8
59#define OTPPOC_PRESCN_TEST 9
60
61#define OTPTYPE_IPX(ccrev) ((ccrev) == 21 || (ccrev) >= 23)
62
63#define OTPP_TRIES 10000000 /* # of tries for OTPP */
64
65#define MAXNUMRDES 9 /* Maximum OTP redundancy entries */
66
67/* Fixed size subregions sizes in words */
68#define OTPGU_CI_SZ 2
69
70struct otpinfo;
71
72/* OTP function struct */
73struct otp_fn_s {
74 int (*init)(struct si_pub *sih, struct otpinfo *oi);
75 int (*read_region)(struct otpinfo *oi, int region, u16 *data,
76 uint *wlen);
77};
78
79struct otpinfo {
80 uint ccrev; /* chipc revision */
81 const struct otp_fn_s *fn; /* OTP functions */
82 struct si_pub *sih; /* Saved sb handle */
83
84 /* IPX OTP section */
85 u16 wsize; /* Size of otp in words */
86 u16 rows; /* Geometry */
87 u16 cols; /* Geometry */
88 u32 status; /* Flag bits (lock/prog/rv).
89 * (Reflected only when OTP is power cycled)
90 */
91 u16 hwbase; /* hardware subregion offset */
92 u16 hwlim; /* hardware subregion boundary */
93 u16 swbase; /* software subregion offset */
94 u16 swlim; /* software subregion boundary */
95 u16 fbase; /* fuse subregion offset */
96 u16 flim; /* fuse subregion boundary */
97 int otpgu_base; /* offset to General Use Region */
98};
99
100/* OTP layout */
101/* CC revs 21, 24 and 27 OTP General Use Region word offset */
102#define REVA4_OTPGU_BASE 12
103
104/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
105#define REVB8_OTPGU_BASE 20
106
107/* CC rev 36 OTP General Use Region word offset */
108#define REV36_OTPGU_BASE 12
109
110/* Subregion word offsets in General Use region */
111#define OTPGU_HSB_OFF 0
112#define OTPGU_SFB_OFF 1
113#define OTPGU_CI_OFF 2
114#define OTPGU_P_OFF 3
115#define OTPGU_SROM_OFF 4
116
117/* Flag bit offsets in General Use region */
118#define OTPGU_HWP_OFF 60
119#define OTPGU_SWP_OFF 61
120#define OTPGU_CIP_OFF 62
121#define OTPGU_FUSEP_OFF 63
122#define OTPGU_CIP_MSK 0x4000
123#define OTPGU_P_MSK 0xf000
124#define OTPGU_P_SHIFT (OTPGU_HWP_OFF % 16)
125
126/* OTP Size */
127#define OTP_SZ_FU_324 ((roundup(324, 8))/8) /* 324 bits */
128#define OTP_SZ_FU_288 (288/8) /* 288 bits */
129#define OTP_SZ_FU_216 (216/8) /* 216 bits */
130#define OTP_SZ_FU_72 (72/8) /* 72 bits */
131#define OTP_SZ_CHECKSUM (16/8) /* 16 bits */
132#define OTP4315_SWREG_SZ 178 /* 178 bytes */
133#define OTP_SZ_FU_144 (144/8) /* 144 bits */
134
135static u16
136ipxotp_otpr(struct otpinfo *oi, struct chipcregs __iomem *cc, uint wn)
137{
138 return R_REG(&cc->sromotp[wn]);
139}
140
141/*
142 * Calculate max HW/SW region byte size by subtracting fuse region
143 * and checksum size, osizew is oi->wsize (OTP size - GU size) in words
144 */
145static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew)
146{
147 int ret = 0;
148
149 switch (sih->chip) {
150 case BCM43224_CHIP_ID:
151 case BCM43225_CHIP_ID:
152 ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
153 break;
154 case BCM4313_CHIP_ID:
155 ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
156 break;
157 default:
158 break; /* Don't know about this chip */
159 }
160
161 return ret;
162}
163
164static void _ipxotp_init(struct otpinfo *oi, struct chipcregs __iomem *cc)
165{
166 uint k;
167 u32 otpp, st;
168
169 /*
170 * record word offset of General Use Region
171 * for various chipcommon revs
172 */
173 if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
174 || oi->sih->ccrev == 27) {
175 oi->otpgu_base = REVA4_OTPGU_BASE;
176 } else if (oi->sih->ccrev == 36) {
177 /*
178 * OTP size greater than equal to 2KB (128 words),
179 * otpgu_base is similar to rev23
180 */
181 if (oi->wsize >= 128)
182 oi->otpgu_base = REVB8_OTPGU_BASE;
183 else
184 oi->otpgu_base = REV36_OTPGU_BASE;
185 } else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
186 oi->otpgu_base = REVB8_OTPGU_BASE;
187 }
188
189 /* First issue an init command so the status is up to date */
190 otpp =
191 OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
192
193 W_REG(&cc->otpprog, otpp);
194 for (k = 0;
195 ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
196 && (k < OTPP_TRIES); k++)
197 ;
198 if (k >= OTPP_TRIES)
199 return;
200
201 /* Read OTP lock bits and subregion programmed indication bits */
202 oi->status = R_REG(&cc->otpstatus);
203
204 if ((oi->sih->chip == BCM43224_CHIP_ID)
205 || (oi->sih->chip == BCM43225_CHIP_ID)) {
206 u32 p_bits;
207 p_bits =
208 (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
209 OTPGU_P_MSK)
210 >> OTPGU_P_SHIFT;
211 oi->status |= (p_bits << OTPS_GUP_SHIFT);
212 }
213
214 /*
215 * h/w region base and fuse region limit are fixed to
216 * the top and the bottom of the general use region.
217 * Everything else can be flexible.
218 */
219 oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
220 oi->hwlim = oi->wsize;
221 if (oi->status & OTPS_GUP_HW) {
222 oi->hwlim =
223 ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
224 oi->swbase = oi->hwlim;
225 } else
226 oi->swbase = oi->hwbase;
227
228 /* subtract fuse and checksum from beginning */
229 oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
230
231 if (oi->status & OTPS_GUP_SW) {
232 oi->swlim =
233 ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
234 oi->fbase = oi->swlim;
235 } else
236 oi->fbase = oi->swbase;
237
238 oi->flim = oi->wsize;
239}
240
241static int ipxotp_init(struct si_pub *sih, struct otpinfo *oi)
242{
243 uint idx;
244 struct chipcregs __iomem *cc;
245
246 /* Make sure we're running IPX OTP */
247 if (!OTPTYPE_IPX(sih->ccrev))
248 return -EBADE;
249
250 /* Make sure OTP is not disabled */
251 if (ai_is_otp_disabled(sih))
252 return -EBADE;
253
254 /* Check for otp size */
255 switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
256 case 0:
257 /* Nothing there */
258 return -EBADE;
259 case 1: /* 32x64 */
260 oi->rows = 32;
261 oi->cols = 64;
262 oi->wsize = 128;
263 break;
264 case 2: /* 64x64 */
265 oi->rows = 64;
266 oi->cols = 64;
267 oi->wsize = 256;
268 break;
269 case 5: /* 96x64 */
270 oi->rows = 96;
271 oi->cols = 64;
272 oi->wsize = 384;
273 break;
274 case 7: /* 16x64 *//* 1024 bits */
275 oi->rows = 16;
276 oi->cols = 64;
277 oi->wsize = 64;
278 break;
279 default:
280 /* Don't know the geometry */
281 return -EBADE;
282 }
283
284 /* Retrieve OTP region info */
285 idx = ai_coreidx(sih);
286 cc = ai_setcoreidx(sih, SI_CC_IDX);
287
288 _ipxotp_init(oi, cc);
289
290 ai_setcoreidx(sih, idx);
291
292 return 0;
293}
294
295static int
296ipxotp_read_region(struct otpinfo *oi, int region, u16 *data, uint *wlen)
297{
298 uint idx;
299 struct chipcregs __iomem *cc;
300 uint base, i, sz;
301
302 /* Validate region selection */
303 switch (region) {
304 case OTP_HW_RGN:
305 sz = (uint) oi->hwlim - oi->hwbase;
306 if (!(oi->status & OTPS_GUP_HW)) {
307 *wlen = sz;
308 return -ENODATA;
309 }
310 if (*wlen < sz) {
311 *wlen = sz;
312 return -EOVERFLOW;
313 }
314 base = oi->hwbase;
315 break;
316 case OTP_SW_RGN:
317 sz = ((uint) oi->swlim - oi->swbase);
318 if (!(oi->status & OTPS_GUP_SW)) {
319 *wlen = sz;
320 return -ENODATA;
321 }
322 if (*wlen < sz) {
323 *wlen = sz;
324 return -EOVERFLOW;
325 }
326 base = oi->swbase;
327 break;
328 case OTP_CI_RGN:
329 sz = OTPGU_CI_SZ;
330 if (!(oi->status & OTPS_GUP_CI)) {
331 *wlen = sz;
332 return -ENODATA;
333 }
334 if (*wlen < sz) {
335 *wlen = sz;
336 return -EOVERFLOW;
337 }
338 base = oi->otpgu_base + OTPGU_CI_OFF;
339 break;
340 case OTP_FUSE_RGN:
341 sz = (uint) oi->flim - oi->fbase;
342 if (!(oi->status & OTPS_GUP_FUSE)) {
343 *wlen = sz;
344 return -ENODATA;
345 }
346 if (*wlen < sz) {
347 *wlen = sz;
348 return -EOVERFLOW;
349 }
350 base = oi->fbase;
351 break;
352 case OTP_ALL_RGN:
353 sz = ((uint) oi->flim - oi->hwbase);
354 if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
355 *wlen = sz;
356 return -ENODATA;
357 }
358 if (*wlen < sz) {
359 *wlen = sz;
360 return -EOVERFLOW;
361 }
362 base = oi->hwbase;
363 break;
364 default:
365 return -EINVAL;
366 }
367
368 idx = ai_coreidx(oi->sih);
369 cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
370
371 /* Read the data */
372 for (i = 0; i < sz; i++)
373 data[i] = ipxotp_otpr(oi, cc, base + i);
374
375 ai_setcoreidx(oi->sih, idx);
376 *wlen = sz;
377 return 0;
378}
379
380static const struct otp_fn_s ipxotp_fn = {
381 (int (*)(struct si_pub *, struct otpinfo *)) ipxotp_init,
382 (int (*)(struct otpinfo *, int, u16 *, uint *)) ipxotp_read_region,
383};
384
385static int otp_init(struct si_pub *sih, struct otpinfo *oi)
386{
387
388 int ret;
389
390 memset(oi, 0, sizeof(struct otpinfo));
391
392 oi->ccrev = sih->ccrev;
393
394 if (OTPTYPE_IPX(oi->ccrev))
395 oi->fn = &ipxotp_fn;
396
397 if (oi->fn == NULL)
398 return -EBADE;
399
400 oi->sih = sih;
401
402 ret = (oi->fn->init) (sih, oi);
403
404 return ret;
405}
406
407int
408otp_read_region(struct si_pub *sih, int region, u16 *data, uint *wlen) {
409 struct otpinfo otpinfo;
410 struct otpinfo *oi = &otpinfo;
411 int err = 0;
412
413 if (ai_is_otp_disabled(sih)) {
414 err = -EPERM;
415 goto out;
416 }
417
418 err = otp_init(sih, oi);
419 if (err)
420 goto out;
421
422 err = ((oi)->fn->read_region)(oi, region, data, wlen);
423
424 out:
425 return err;
426}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/otp.h b/drivers/net/wireless/brcm80211/brcmsmac/otp.h
new file mode 100644
index 000000000000..6b6d31cf9569
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/otp.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_OTP_H_
18#define _BRCM_OTP_H_
19
20#include "types.h"
21
22/* OTP regions */
23#define OTP_HW_RGN 1
24#define OTP_SW_RGN 2
25#define OTP_CI_RGN 4
26#define OTP_FUSE_RGN 8
27/* From h/w region to end of OTP including checksum */
28#define OTP_ALL_RGN 0xf
29
30/* OTP Size */
31#define OTP_SZ_MAX (6144/8) /* maximum bytes in one CIS */
32
33extern int otp_read_region(struct si_pub *sih, int region, u16 *data,
34 uint *wlen);
35
36#endif /* _BRCM_OTP_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 000000000000..a3149254cbcd
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
@@ -0,0 +1,2988 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/kernel.h>
17#include <linux/delay.h>
18#include <linux/bitops.h>
19
20#include <brcm_hw_ids.h>
21#include <chipcommon.h>
22#include <aiutils.h>
23#include <d11.h>
24#include <phy_shim.h>
25#include "phy_hal.h"
26#include "phy_int.h"
27#include "phy_radio.h"
28#include "phy_lcn.h"
29#include "phyreg_n.h"
30
31#define VALID_N_RADIO(radioid) ((radioid == BCM2055_ID) || \
32 (radioid == BCM2056_ID) || \
33 (radioid == BCM2057_ID))
34
35#define VALID_LCN_RADIO(radioid) (radioid == BCM2064_ID)
36
37#define VALID_RADIO(pi, radioid) ( \
38 (ISNPHY(pi) ? VALID_N_RADIO(radioid) : false) || \
39 (ISLCNPHY(pi) ? VALID_LCN_RADIO(radioid) : false))
40
41/* basic mux operation - can be optimized on several architectures */
42#define MUX(pred, true, false) ((pred) ? (true) : (false))
43
44/* modulo inc/dec - assumes x E [0, bound - 1] */
45#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1)
46
47/* modulo inc/dec, bound = 2^k */
48#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1))
49#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1))
50
51struct chan_info_basic {
52 u16 chan;
53 u16 freq;
54};
55
56static const struct chan_info_basic chan_info_all[] = {
57 {1, 2412},
58 {2, 2417},
59 {3, 2422},
60 {4, 2427},
61 {5, 2432},
62 {6, 2437},
63 {7, 2442},
64 {8, 2447},
65 {9, 2452},
66 {10, 2457},
67 {11, 2462},
68 {12, 2467},
69 {13, 2472},
70 {14, 2484},
71
72 {34, 5170},
73 {38, 5190},
74 {42, 5210},
75 {46, 5230},
76
77 {36, 5180},
78 {40, 5200},
79 {44, 5220},
80 {48, 5240},
81 {52, 5260},
82 {56, 5280},
83 {60, 5300},
84 {64, 5320},
85
86 {100, 5500},
87 {104, 5520},
88 {108, 5540},
89 {112, 5560},
90 {116, 5580},
91 {120, 5600},
92 {124, 5620},
93 {128, 5640},
94 {132, 5660},
95 {136, 5680},
96 {140, 5700},
97
98 {149, 5745},
99 {153, 5765},
100 {157, 5785},
101 {161, 5805},
102 {165, 5825},
103
104 {184, 4920},
105 {188, 4940},
106 {192, 4960},
107 {196, 4980},
108 {200, 5000},
109 {204, 5020},
110 {208, 5040},
111 {212, 5060},
112 {216, 50800}
113};
114
115const u8 ofdm_rate_lookup[] = {
116
117 BRCM_RATE_48M,
118 BRCM_RATE_24M,
119 BRCM_RATE_12M,
120 BRCM_RATE_6M,
121 BRCM_RATE_54M,
122 BRCM_RATE_36M,
123 BRCM_RATE_18M,
124 BRCM_RATE_9M
125};
126
127#define PHY_WREG_LIMIT 24
128
129void wlc_phyreg_enter(struct brcms_phy_pub *pih)
130{
131 struct brcms_phy *pi = (struct brcms_phy *) pih;
132 wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim);
133}
134
135void wlc_phyreg_exit(struct brcms_phy_pub *pih)
136{
137 struct brcms_phy *pi = (struct brcms_phy *) pih;
138 wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim);
139}
140
141void wlc_radioreg_enter(struct brcms_phy_pub *pih)
142{
143 struct brcms_phy *pi = (struct brcms_phy *) pih;
144 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO);
145
146 udelay(10);
147}
148
149void wlc_radioreg_exit(struct brcms_phy_pub *pih)
150{
151 struct brcms_phy *pi = (struct brcms_phy *) pih;
152 u16 dummy;
153
154 dummy = R_REG(&pi->regs->phyversion);
155 pi->phy_wreg = 0;
156 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, 0);
157}
158
159u16 read_radio_reg(struct brcms_phy *pi, u16 addr)
160{
161 u16 data;
162
163 if ((addr == RADIO_IDCODE))
164 return 0xffff;
165
166 switch (pi->pubpi.phy_type) {
167 case PHY_TYPE_N:
168 if (!CONF_HAS(PHYTYPE, PHY_TYPE_N))
169 break;
170 if (NREV_GE(pi->pubpi.phy_rev, 7))
171 addr |= RADIO_2057_READ_OFF;
172 else
173 addr |= RADIO_2055_READ_OFF;
174 break;
175
176 case PHY_TYPE_LCN:
177 if (!CONF_HAS(PHYTYPE, PHY_TYPE_LCN))
178 break;
179 addr |= RADIO_2064_READ_OFF;
180 break;
181
182 default:
183 break;
184 }
185
186 if ((D11REV_GE(pi->sh->corerev, 24)) ||
187 (D11REV_IS(pi->sh->corerev, 22)
188 && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
189 W_REG_FLUSH(&pi->regs->radioregaddr, addr);
190 data = R_REG(&pi->regs->radioregdata);
191 } else {
192 W_REG_FLUSH(&pi->regs->phy4waddr, addr);
193
194#ifdef __ARM_ARCH_4T__
195 __asm__(" .align 4 ");
196 __asm__(" nop ");
197 data = R_REG(&pi->regs->phy4wdatalo);
198#else
199 data = R_REG(&pi->regs->phy4wdatalo);
200#endif
201
202 }
203 pi->phy_wreg = 0;
204
205 return data;
206}
207
208void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
209{
210 if ((D11REV_GE(pi->sh->corerev, 24)) ||
211 (D11REV_IS(pi->sh->corerev, 22)
212 && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
213
214 W_REG_FLUSH(&pi->regs->radioregaddr, addr);
215 W_REG(&pi->regs->radioregdata, val);
216 } else {
217 W_REG_FLUSH(&pi->regs->phy4waddr, addr);
218 W_REG(&pi->regs->phy4wdatalo, val);
219 }
220
221 if (++pi->phy_wreg >= pi->phy_wreg_limit) {
222 (void)R_REG(&pi->regs->maccontrol);
223 pi->phy_wreg = 0;
224 }
225}
226
227static u32 read_radio_id(struct brcms_phy *pi)
228{
229 u32 id;
230
231 if (D11REV_GE(pi->sh->corerev, 24)) {
232 u32 b0, b1, b2;
233
234 W_REG_FLUSH(&pi->regs->radioregaddr, 0);
235 b0 = (u32) R_REG(&pi->regs->radioregdata);
236 W_REG_FLUSH(&pi->regs->radioregaddr, 1);
237 b1 = (u32) R_REG(&pi->regs->radioregdata);
238 W_REG_FLUSH(&pi->regs->radioregaddr, 2);
239 b2 = (u32) R_REG(&pi->regs->radioregdata);
240
241 id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4)
242 & 0xf);
243 } else {
244 W_REG_FLUSH(&pi->regs->phy4waddr, RADIO_IDCODE);
245 id = (u32) R_REG(&pi->regs->phy4wdatalo);
246 id |= (u32) R_REG(&pi->regs->phy4wdatahi) << 16;
247 }
248 pi->phy_wreg = 0;
249 return id;
250}
251
252void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
253{
254 u16 rval;
255
256 rval = read_radio_reg(pi, addr);
257 write_radio_reg(pi, addr, (rval & val));
258}
259
260void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
261{
262 u16 rval;
263
264 rval = read_radio_reg(pi, addr);
265 write_radio_reg(pi, addr, (rval | val));
266}
267
268void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask)
269{
270 u16 rval;
271
272 rval = read_radio_reg(pi, addr);
273 write_radio_reg(pi, addr, (rval ^ mask));
274}
275
276void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val)
277{
278 u16 rval;
279
280 rval = read_radio_reg(pi, addr);
281 write_radio_reg(pi, addr, (rval & ~mask) | (val & mask));
282}
283
284void write_phy_channel_reg(struct brcms_phy *pi, uint val)
285{
286 W_REG(&pi->regs->phychannel, val);
287}
288
289u16 read_phy_reg(struct brcms_phy *pi, u16 addr)
290{
291 struct d11regs __iomem *regs;
292
293 regs = pi->regs;
294
295 W_REG_FLUSH(&regs->phyregaddr, addr);
296
297 pi->phy_wreg = 0;
298 return R_REG(&regs->phyregdata);
299}
300
301void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
302{
303 struct d11regs __iomem *regs;
304
305 regs = pi->regs;
306
307#ifdef CONFIG_BCM47XX
308 W_REG_FLUSH(&regs->phyregaddr, addr);
309 W_REG(&regs->phyregdata, val);
310 if (addr == 0x72)
311 (void)R_REG(&regs->phyregdata);
312#else
313 W_REG((u32 __iomem *)(&regs->phyregaddr), addr | (val << 16));
314 if (++pi->phy_wreg >= pi->phy_wreg_limit) {
315 pi->phy_wreg = 0;
316 (void)R_REG(&regs->phyversion);
317 }
318#endif
319}
320
321void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
322{
323 struct d11regs __iomem *regs;
324
325 regs = pi->regs;
326
327 W_REG_FLUSH(&regs->phyregaddr, addr);
328
329 W_REG(&regs->phyregdata, (R_REG(&regs->phyregdata) & val));
330 pi->phy_wreg = 0;
331}
332
333void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
334{
335 struct d11regs __iomem *regs;
336
337 regs = pi->regs;
338
339 W_REG_FLUSH(&regs->phyregaddr, addr);
340
341 W_REG(&regs->phyregdata, (R_REG(&regs->phyregdata) | val));
342 pi->phy_wreg = 0;
343}
344
345void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val)
346{
347 struct d11regs __iomem *regs;
348
349 regs = pi->regs;
350
351 W_REG_FLUSH(&regs->phyregaddr, addr);
352
353 W_REG(&regs->phyregdata,
354 ((R_REG(&regs->phyregdata) & ~mask) | (val & mask)));
355 pi->phy_wreg = 0;
356}
357
358static void wlc_set_phy_uninitted(struct brcms_phy *pi)
359{
360 int i, j;
361
362 pi->initialized = false;
363
364 pi->tx_vos = 0xffff;
365 pi->nrssi_table_delta = 0x7fffffff;
366 pi->rc_cal = 0xffff;
367 pi->mintxbias = 0xffff;
368 pi->txpwridx = -1;
369 if (ISNPHY(pi)) {
370 pi->phy_spuravoid = SPURAVOID_DISABLE;
371
372 if (NREV_GE(pi->pubpi.phy_rev, 3)
373 && NREV_LT(pi->pubpi.phy_rev, 7))
374 pi->phy_spuravoid = SPURAVOID_AUTO;
375
376 pi->nphy_papd_skip = 0;
377 pi->nphy_papd_epsilon_offset[0] = 0xf588;
378 pi->nphy_papd_epsilon_offset[1] = 0xf588;
379 pi->nphy_txpwr_idx[0] = 128;
380 pi->nphy_txpwr_idx[1] = 128;
381 pi->nphy_txpwrindex[0].index_internal = 40;
382 pi->nphy_txpwrindex[1].index_internal = 40;
383 pi->phy_pabias = 0;
384 } else {
385 pi->phy_spuravoid = SPURAVOID_AUTO;
386 }
387 pi->radiopwr = 0xffff;
388 for (i = 0; i < STATIC_NUM_RF; i++) {
389 for (j = 0; j < STATIC_NUM_BB; j++)
390 pi->stats_11b_txpower[i][j] = -1;
391 }
392}
393
394struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp)
395{
396 struct shared_phy *sh;
397
398 sh = kzalloc(sizeof(struct shared_phy), GFP_ATOMIC);
399 if (sh == NULL)
400 return NULL;
401
402 sh->sih = shp->sih;
403 sh->physhim = shp->physhim;
404 sh->unit = shp->unit;
405 sh->corerev = shp->corerev;
406
407 sh->vid = shp->vid;
408 sh->did = shp->did;
409 sh->chip = shp->chip;
410 sh->chiprev = shp->chiprev;
411 sh->chippkg = shp->chippkg;
412 sh->sromrev = shp->sromrev;
413 sh->boardtype = shp->boardtype;
414 sh->boardrev = shp->boardrev;
415 sh->boardvendor = shp->boardvendor;
416 sh->boardflags = shp->boardflags;
417 sh->boardflags2 = shp->boardflags2;
418 sh->buscorerev = shp->buscorerev;
419
420 sh->fast_timer = PHY_SW_TIMER_FAST;
421 sh->slow_timer = PHY_SW_TIMER_SLOW;
422 sh->glacial_timer = PHY_SW_TIMER_GLACIAL;
423
424 sh->rssi_mode = RSSI_ANT_MERGE_MAX;
425
426 return sh;
427}
428
429static void wlc_phy_timercb_phycal(struct brcms_phy *pi)
430{
431 uint delay = 5;
432
433 if (PHY_PERICAL_MPHASE_PENDING(pi)) {
434 if (!pi->sh->up) {
435 wlc_phy_cal_perical_mphase_reset(pi);
436 return;
437 }
438
439 if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)) {
440
441 delay = 1000;
442 wlc_phy_cal_perical_mphase_restart(pi);
443 } else
444 wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO);
445 wlapi_add_timer(pi->phycal_timer, delay, 0);
446 return;
447 }
448
449}
450
451static u32 wlc_phy_get_radio_ver(struct brcms_phy *pi)
452{
453 u32 ver;
454
455 ver = read_radio_id(pi);
456
457 return ver;
458}
459
460struct brcms_phy_pub *
461wlc_phy_attach(struct shared_phy *sh, struct d11regs __iomem *regs,
462 int bandtype, struct wiphy *wiphy)
463{
464 struct brcms_phy *pi;
465 u32 sflags = 0;
466 uint phyversion;
467 u32 idcode;
468 int i;
469
470 if (D11REV_IS(sh->corerev, 4))
471 sflags = SISF_2G_PHY | SISF_5G_PHY;
472 else
473 sflags = ai_core_sflags(sh->sih, 0, 0);
474
475 if (bandtype == BRCM_BAND_5G) {
476 if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0)
477 return NULL;
478 }
479
480 pi = sh->phy_head;
481 if ((sflags & SISF_DB_PHY) && pi) {
482 wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
483 pi->refcnt++;
484 return &pi->pubpi_ro;
485 }
486
487 pi = kzalloc(sizeof(struct brcms_phy), GFP_ATOMIC);
488 if (pi == NULL)
489 return NULL;
490 pi->wiphy = wiphy;
491 pi->regs = regs;
492 pi->sh = sh;
493 pi->phy_init_por = true;
494 pi->phy_wreg_limit = PHY_WREG_LIMIT;
495
496 pi->txpwr_percent = 100;
497
498 pi->do_initcal = true;
499
500 pi->phycal_tempdelta = 0;
501
502 if (bandtype == BRCM_BAND_2G && (sflags & SISF_2G_PHY))
503 pi->pubpi.coreflags = SICF_GMODE;
504
505 wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
506 phyversion = R_REG(&pi->regs->phyversion);
507
508 pi->pubpi.phy_type = PHY_TYPE(phyversion);
509 pi->pubpi.phy_rev = phyversion & PV_PV_MASK;
510
511 if (pi->pubpi.phy_type == PHY_TYPE_LCNXN) {
512 pi->pubpi.phy_type = PHY_TYPE_N;
513 pi->pubpi.phy_rev += LCNXN_BASEREV;
514 }
515 pi->pubpi.phy_corenum = PHY_CORE_NUM_2;
516 pi->pubpi.ana_rev = (phyversion & PV_AV_MASK) >> PV_AV_SHIFT;
517
518 if (!pi->pubpi.phy_type == PHY_TYPE_N &&
519 !pi->pubpi.phy_type == PHY_TYPE_LCN)
520 goto err;
521
522 if (bandtype == BRCM_BAND_5G) {
523 if (!ISNPHY(pi))
524 goto err;
525 } else if (!ISNPHY(pi) && !ISLCNPHY(pi)) {
526 goto err;
527 }
528
529 wlc_phy_anacore((struct brcms_phy_pub *) pi, ON);
530
531 idcode = wlc_phy_get_radio_ver(pi);
532 pi->pubpi.radioid =
533 (idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT;
534 pi->pubpi.radiorev =
535 (idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT;
536 pi->pubpi.radiover =
537 (idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT;
538 if (!VALID_RADIO(pi, pi->pubpi.radioid))
539 goto err;
540
541 wlc_phy_switch_radio((struct brcms_phy_pub *) pi, OFF);
542
543 wlc_set_phy_uninitted(pi);
544
545 pi->bw = WL_CHANSPEC_BW_20;
546 pi->radio_chanspec = (bandtype == BRCM_BAND_2G) ?
547 ch20mhz_chspec(1) : ch20mhz_chspec(36);
548
549 pi->rxiq_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
550 pi->rxiq_antsel = ANT_RX_DIV_DEF;
551
552 pi->watchdog_override = true;
553
554 pi->cal_type_override = PHY_PERICAL_AUTO;
555
556 pi->nphy_saved_noisevars.bufcount = 0;
557
558 if (ISNPHY(pi))
559 pi->min_txpower = PHY_TXPWR_MIN_NPHY;
560 else
561 pi->min_txpower = PHY_TXPWR_MIN;
562
563 pi->sh->phyrxchain = 0x3;
564
565 pi->rx2tx_biasentry = -1;
566
567 pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
568 pi->phy_txcore_enable_temp =
569 PHY_CHAIN_TX_DISABLE_TEMP - PHY_HYSTERESIS_DELTATEMP;
570 pi->phy_tempsense_offset = 0;
571 pi->phy_txcore_heatedup = false;
572
573 pi->nphy_lastcal_temp = -50;
574
575 pi->phynoise_polling = true;
576 if (ISNPHY(pi) || ISLCNPHY(pi))
577 pi->phynoise_polling = false;
578
579 for (i = 0; i < TXP_NUM_RATES; i++) {
580 pi->txpwr_limit[i] = BRCMS_TXPWR_MAX;
581 pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX;
582 pi->tx_user_target[i] = BRCMS_TXPWR_MAX;
583 }
584
585 pi->radiopwr_override = RADIOPWR_OVERRIDE_DEF;
586
587 pi->user_txpwr_at_rfport = false;
588
589 if (ISNPHY(pi)) {
590
591 pi->phycal_timer = wlapi_init_timer(pi->sh->physhim,
592 wlc_phy_timercb_phycal,
593 pi, "phycal");
594 if (!pi->phycal_timer)
595 goto err;
596
597 if (!wlc_phy_attach_nphy(pi))
598 goto err;
599
600 } else if (ISLCNPHY(pi)) {
601 if (!wlc_phy_attach_lcnphy(pi))
602 goto err;
603
604 }
605
606 pi->refcnt++;
607 pi->next = pi->sh->phy_head;
608 sh->phy_head = pi;
609
610 memcpy(&pi->pubpi_ro, &pi->pubpi, sizeof(struct brcms_phy_pub));
611
612 return &pi->pubpi_ro;
613
614err:
615 kfree(pi);
616 return NULL;
617}
618
619void wlc_phy_detach(struct brcms_phy_pub *pih)
620{
621 struct brcms_phy *pi = (struct brcms_phy *) pih;
622
623 if (pih) {
624 if (--pi->refcnt)
625 return;
626
627 if (pi->phycal_timer) {
628 wlapi_free_timer(pi->phycal_timer);
629 pi->phycal_timer = NULL;
630 }
631
632 if (pi->sh->phy_head == pi)
633 pi->sh->phy_head = pi->next;
634 else if (pi->sh->phy_head->next == pi)
635 pi->sh->phy_head->next = NULL;
636
637 if (pi->pi_fptr.detach)
638 (pi->pi_fptr.detach)(pi);
639
640 kfree(pi);
641 }
642}
643
644bool
645wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, u16 *phyrev,
646 u16 *radioid, u16 *radiover)
647{
648 struct brcms_phy *pi = (struct brcms_phy *) pih;
649 *phytype = (u16) pi->pubpi.phy_type;
650 *phyrev = (u16) pi->pubpi.phy_rev;
651 *radioid = pi->pubpi.radioid;
652 *radiover = pi->pubpi.radiorev;
653
654 return true;
655}
656
657bool wlc_phy_get_encore(struct brcms_phy_pub *pih)
658{
659 struct brcms_phy *pi = (struct brcms_phy *) pih;
660 return pi->pubpi.abgphy_encore;
661}
662
663u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih)
664{
665 struct brcms_phy *pi = (struct brcms_phy *) pih;
666 return pi->pubpi.coreflags;
667}
668
669void wlc_phy_anacore(struct brcms_phy_pub *pih, bool on)
670{
671 struct brcms_phy *pi = (struct brcms_phy *) pih;
672
673 if (ISNPHY(pi)) {
674 if (on) {
675 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
676 write_phy_reg(pi, 0xa6, 0x0d);
677 write_phy_reg(pi, 0x8f, 0x0);
678 write_phy_reg(pi, 0xa7, 0x0d);
679 write_phy_reg(pi, 0xa5, 0x0);
680 } else {
681 write_phy_reg(pi, 0xa5, 0x0);
682 }
683 } else {
684 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
685 write_phy_reg(pi, 0x8f, 0x07ff);
686 write_phy_reg(pi, 0xa6, 0x0fd);
687 write_phy_reg(pi, 0xa5, 0x07ff);
688 write_phy_reg(pi, 0xa7, 0x0fd);
689 } else {
690 write_phy_reg(pi, 0xa5, 0x7fff);
691 }
692 }
693 } else if (ISLCNPHY(pi)) {
694 if (on) {
695 and_phy_reg(pi, 0x43b,
696 ~((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
697 } else {
698 or_phy_reg(pi, 0x43c,
699 (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
700 or_phy_reg(pi, 0x43b,
701 (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
702 }
703 }
704}
705
706u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih)
707{
708 struct brcms_phy *pi = (struct brcms_phy *) pih;
709
710 u32 phy_bw_clkbits = 0;
711
712 if (pi && (ISNPHY(pi) || ISLCNPHY(pi))) {
713 switch (pi->bw) {
714 case WL_CHANSPEC_BW_10:
715 phy_bw_clkbits = SICF_BW10;
716 break;
717 case WL_CHANSPEC_BW_20:
718 phy_bw_clkbits = SICF_BW20;
719 break;
720 case WL_CHANSPEC_BW_40:
721 phy_bw_clkbits = SICF_BW40;
722 break;
723 default:
724 break;
725 }
726 }
727
728 return phy_bw_clkbits;
729}
730
731void wlc_phy_por_inform(struct brcms_phy_pub *ppi)
732{
733 struct brcms_phy *pi = (struct brcms_phy *) ppi;
734
735 pi->phy_init_por = true;
736}
737
738void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock)
739{
740 struct brcms_phy *pi = (struct brcms_phy *) pih;
741
742 pi->edcrs_threshold_lock = lock;
743
744 write_phy_reg(pi, 0x22c, 0x46b);
745 write_phy_reg(pi, 0x22d, 0x46b);
746 write_phy_reg(pi, 0x22e, 0x3c0);
747 write_phy_reg(pi, 0x22f, 0x3c0);
748}
749
750void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal)
751{
752 struct brcms_phy *pi = (struct brcms_phy *) pih;
753
754 pi->do_initcal = initcal;
755}
756
757void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *pih, bool newstate)
758{
759 struct brcms_phy *pi = (struct brcms_phy *) pih;
760
761 if (!pi || !pi->sh)
762 return;
763
764 pi->sh->clk = newstate;
765}
766
767void wlc_phy_hw_state_upd(struct brcms_phy_pub *pih, bool newstate)
768{
769 struct brcms_phy *pi = (struct brcms_phy *) pih;
770
771 if (!pi || !pi->sh)
772 return;
773
774 pi->sh->up = newstate;
775}
776
777void wlc_phy_init(struct brcms_phy_pub *pih, u16 chanspec)
778{
779 u32 mc;
780 void (*phy_init)(struct brcms_phy *) = NULL;
781 struct brcms_phy *pi = (struct brcms_phy *) pih;
782
783 if (pi->init_in_progress)
784 return;
785
786 pi->init_in_progress = true;
787
788 pi->radio_chanspec = chanspec;
789
790 mc = R_REG(&pi->regs->maccontrol);
791 if (WARN(mc & MCTL_EN_MAC, "HW error MAC running on init"))
792 return;
793
794 if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN))
795 pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
796
797 if (WARN(!(ai_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA),
798 "HW error SISF_FCLKA\n"))
799 return;
800
801 phy_init = pi->pi_fptr.init;
802
803 if (phy_init == NULL)
804 return;
805
806 wlc_phy_anacore(pih, ON);
807
808 if (CHSPEC_BW(pi->radio_chanspec) != pi->bw)
809 wlapi_bmac_bw_set(pi->sh->physhim,
810 CHSPEC_BW(pi->radio_chanspec));
811
812 pi->nphy_gain_boost = true;
813
814 wlc_phy_switch_radio((struct brcms_phy_pub *) pi, ON);
815
816 (*phy_init)(pi);
817
818 pi->phy_init_por = false;
819
820 if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
821 wlc_phy_do_dummy_tx(pi, true, OFF);
822
823 if (!(ISNPHY(pi)))
824 wlc_phy_txpower_update_shm(pi);
825
826 wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi, pi->sh->rx_antdiv);
827
828 pi->init_in_progress = false;
829}
830
831void wlc_phy_cal_init(struct brcms_phy_pub *pih)
832{
833 struct brcms_phy *pi = (struct brcms_phy *) pih;
834 void (*cal_init)(struct brcms_phy *) = NULL;
835
836 if (WARN((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) != 0,
837 "HW error: MAC enabled during phy cal\n"))
838 return;
839
840 if (!pi->initialized) {
841 cal_init = pi->pi_fptr.calinit;
842 if (cal_init)
843 (*cal_init)(pi);
844
845 pi->initialized = true;
846 }
847}
848
849int wlc_phy_down(struct brcms_phy_pub *pih)
850{
851 struct brcms_phy *pi = (struct brcms_phy *) pih;
852 int callbacks = 0;
853
854 if (pi->phycal_timer
855 && !wlapi_del_timer(pi->phycal_timer))
856 callbacks++;
857
858 pi->nphy_iqcal_chanspec_2G = 0;
859 pi->nphy_iqcal_chanspec_5G = 0;
860
861 return callbacks;
862}
863
864void
865wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id, uint tbl_offset,
866 u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
867{
868 write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
869
870 pi->tbl_data_hi = tblDataHi;
871 pi->tbl_data_lo = tblDataLo;
872
873 if (pi->sh->chip == BCM43224_CHIP_ID &&
874 pi->sh->chiprev == 1) {
875 pi->tbl_addr = tblAddr;
876 pi->tbl_save_id = tbl_id;
877 pi->tbl_save_offset = tbl_offset;
878 }
879}
880
881void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val)
882{
883 if ((pi->sh->chip == BCM43224_CHIP_ID) &&
884 (pi->sh->chiprev == 1) &&
885 (pi->tbl_save_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
886 read_phy_reg(pi, pi->tbl_data_lo);
887
888 write_phy_reg(pi, pi->tbl_addr,
889 (pi->tbl_save_id << 10) | pi->tbl_save_offset);
890 pi->tbl_save_offset++;
891 }
892
893 if (width == 32) {
894 write_phy_reg(pi, pi->tbl_data_hi, (u16) (val >> 16));
895 write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
896 } else {
897 write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
898 }
899}
900
901void
902wlc_phy_write_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info,
903 u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
904{
905 uint idx;
906 uint tbl_id = ptbl_info->tbl_id;
907 uint tbl_offset = ptbl_info->tbl_offset;
908 uint tbl_width = ptbl_info->tbl_width;
909 const u8 *ptbl_8b = (const u8 *)ptbl_info->tbl_ptr;
910 const u16 *ptbl_16b = (const u16 *)ptbl_info->tbl_ptr;
911 const u32 *ptbl_32b = (const u32 *)ptbl_info->tbl_ptr;
912
913 write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
914
915 for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
916
917 if ((pi->sh->chip == BCM43224_CHIP_ID) &&
918 (pi->sh->chiprev == 1) &&
919 (tbl_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
920 read_phy_reg(pi, tblDataLo);
921
922 write_phy_reg(pi, tblAddr,
923 (tbl_id << 10) | (tbl_offset + idx));
924 }
925
926 if (tbl_width == 32) {
927 write_phy_reg(pi, tblDataHi,
928 (u16) (ptbl_32b[idx] >> 16));
929 write_phy_reg(pi, tblDataLo, (u16) ptbl_32b[idx]);
930 } else if (tbl_width == 16) {
931 write_phy_reg(pi, tblDataLo, ptbl_16b[idx]);
932 } else {
933 write_phy_reg(pi, tblDataLo, ptbl_8b[idx]);
934 }
935 }
936}
937
938void
939wlc_phy_read_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info,
940 u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
941{
942 uint idx;
943 uint tbl_id = ptbl_info->tbl_id;
944 uint tbl_offset = ptbl_info->tbl_offset;
945 uint tbl_width = ptbl_info->tbl_width;
946 u8 *ptbl_8b = (u8 *)ptbl_info->tbl_ptr;
947 u16 *ptbl_16b = (u16 *)ptbl_info->tbl_ptr;
948 u32 *ptbl_32b = (u32 *)ptbl_info->tbl_ptr;
949
950 write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
951
952 for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
953
954 if ((pi->sh->chip == BCM43224_CHIP_ID) &&
955 (pi->sh->chiprev == 1)) {
956 (void)read_phy_reg(pi, tblDataLo);
957
958 write_phy_reg(pi, tblAddr,
959 (tbl_id << 10) | (tbl_offset + idx));
960 }
961
962 if (tbl_width == 32) {
963 ptbl_32b[idx] = read_phy_reg(pi, tblDataLo);
964 ptbl_32b[idx] |= (read_phy_reg(pi, tblDataHi) << 16);
965 } else if (tbl_width == 16) {
966 ptbl_16b[idx] = read_phy_reg(pi, tblDataLo);
967 } else {
968 ptbl_8b[idx] = (u8) read_phy_reg(pi, tblDataLo);
969 }
970 }
971}
972
973uint
974wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi,
975 struct radio_20xx_regs *radioregs)
976{
977 uint i = 0;
978
979 do {
980 if (radioregs[i].do_init)
981 write_radio_reg(pi, radioregs[i].address,
982 (u16) radioregs[i].init);
983
984 i++;
985 } while (radioregs[i].address != 0xffff);
986
987 return i;
988}
989
990uint
991wlc_phy_init_radio_regs(struct brcms_phy *pi,
992 const struct radio_regs *radioregs,
993 u16 core_offset)
994{
995 uint i = 0;
996 uint count = 0;
997
998 do {
999 if (CHSPEC_IS5G(pi->radio_chanspec)) {
1000 if (radioregs[i].do_init_a) {
1001 write_radio_reg(pi,
1002 radioregs[i].
1003 address | core_offset,
1004 (u16) radioregs[i].init_a);
1005 if (ISNPHY(pi) && (++count % 4 == 0))
1006 BRCMS_PHY_WAR_PR51571(pi);
1007 }
1008 } else {
1009 if (radioregs[i].do_init_g) {
1010 write_radio_reg(pi,
1011 radioregs[i].
1012 address | core_offset,
1013 (u16) radioregs[i].init_g);
1014 if (ISNPHY(pi) && (++count % 4 == 0))
1015 BRCMS_PHY_WAR_PR51571(pi);
1016 }
1017 }
1018
1019 i++;
1020 } while (radioregs[i].address != 0xffff);
1021
1022 return i;
1023}
1024
1025void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on)
1026{
1027#define DUMMY_PKT_LEN 20
1028 struct d11regs __iomem *regs = pi->regs;
1029 int i, count;
1030 u8 ofdmpkt[DUMMY_PKT_LEN] = {
1031 0xcc, 0x01, 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
1032 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
1033 };
1034 u8 cckpkt[DUMMY_PKT_LEN] = {
1035 0x6e, 0x84, 0x0b, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
1036 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
1037 };
1038 u32 *dummypkt;
1039
1040 dummypkt = (u32 *) (ofdm ? ofdmpkt : cckpkt);
1041 wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN,
1042 dummypkt);
1043
1044 W_REG(&regs->xmtsel, 0);
1045
1046 if (D11REV_GE(pi->sh->corerev, 11))
1047 W_REG(&regs->wepctl, 0x100);
1048 else
1049 W_REG(&regs->wepctl, 0);
1050
1051 W_REG(&regs->txe_phyctl, (ofdm ? 1 : 0) | PHY_TXC_ANT_0);
1052 if (ISNPHY(pi) || ISLCNPHY(pi))
1053 W_REG(&regs->txe_phyctl1, 0x1A02);
1054
1055 W_REG(&regs->txe_wm_0, 0);
1056 W_REG(&regs->txe_wm_1, 0);
1057
1058 W_REG(&regs->xmttplatetxptr, 0);
1059 W_REG(&regs->xmttxcnt, DUMMY_PKT_LEN);
1060
1061 W_REG(&regs->xmtsel, ((8 << 8) | (1 << 5) | (1 << 2) | 2));
1062
1063 W_REG(&regs->txe_ctl, 0);
1064
1065 if (!pa_on) {
1066 if (ISNPHY(pi))
1067 wlc_phy_pa_override_nphy(pi, OFF);
1068 }
1069
1070 if (ISNPHY(pi) || ISLCNPHY(pi))
1071 W_REG(&regs->txe_aux, 0xD0);
1072 else
1073 W_REG(&regs->txe_aux, ((1 << 5) | (1 << 4)));
1074
1075 (void)R_REG(&regs->txe_aux);
1076
1077 i = 0;
1078 count = ofdm ? 30 : 250;
1079 while ((i++ < count)
1080 && (R_REG(&regs->txe_status) & (1 << 7)))
1081 udelay(10);
1082
1083 i = 0;
1084
1085 while ((i++ < 10)
1086 && ((R_REG(&regs->txe_status) & (1 << 10)) == 0))
1087 udelay(10);
1088
1089 i = 0;
1090
1091 while ((i++ < 10) && ((R_REG(&regs->ifsstat) & (1 << 8))))
1092 udelay(10);
1093
1094 if (!pa_on) {
1095 if (ISNPHY(pi))
1096 wlc_phy_pa_override_nphy(pi, ON);
1097 }
1098}
1099
1100void wlc_phy_hold_upd(struct brcms_phy_pub *pih, u32 id, bool set)
1101{
1102 struct brcms_phy *pi = (struct brcms_phy *) pih;
1103
1104 if (set)
1105 mboolset(pi->measure_hold, id);
1106 else
1107 mboolclr(pi->measure_hold, id);
1108
1109 return;
1110}
1111
1112void wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, u32 flags)
1113{
1114 struct brcms_phy *pi = (struct brcms_phy *) pih;
1115
1116 if (mute)
1117 mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE);
1118 else
1119 mboolclr(pi->measure_hold, PHY_HOLD_FOR_MUTE);
1120
1121 if (!mute && (flags & PHY_MUTE_FOR_PREISM))
1122 pi->nphy_perical_last = pi->sh->now - pi->sh->glacial_timer;
1123 return;
1124}
1125
1126void wlc_phy_clear_tssi(struct brcms_phy_pub *pih)
1127{
1128 struct brcms_phy *pi = (struct brcms_phy *) pih;
1129
1130 if (ISNPHY(pi)) {
1131 return;
1132 } else {
1133 wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_0, NULL_TSSI_W);
1134 wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_1, NULL_TSSI_W);
1135 wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_0, NULL_TSSI_W);
1136 wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_1, NULL_TSSI_W);
1137 }
1138}
1139
1140static bool wlc_phy_cal_txpower_recalc_sw(struct brcms_phy *pi)
1141{
1142 return false;
1143}
1144
1145void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on)
1146{
1147 struct brcms_phy *pi = (struct brcms_phy *) pih;
1148 (void)R_REG(&pi->regs->maccontrol);
1149
1150 if (ISNPHY(pi)) {
1151 wlc_phy_switch_radio_nphy(pi, on);
1152 } else if (ISLCNPHY(pi)) {
1153 if (on) {
1154 and_phy_reg(pi, 0x44c,
1155 ~((0x1 << 8) |
1156 (0x1 << 9) |
1157 (0x1 << 10) | (0x1 << 11) | (0x1 << 12)));
1158 and_phy_reg(pi, 0x4b0, ~((0x1 << 3) | (0x1 << 11)));
1159 and_phy_reg(pi, 0x4f9, ~(0x1 << 3));
1160 } else {
1161 and_phy_reg(pi, 0x44d,
1162 ~((0x1 << 10) |
1163 (0x1 << 11) |
1164 (0x1 << 12) | (0x1 << 13) | (0x1 << 14)));
1165 or_phy_reg(pi, 0x44c,
1166 (0x1 << 8) |
1167 (0x1 << 9) |
1168 (0x1 << 10) | (0x1 << 11) | (0x1 << 12));
1169
1170 and_phy_reg(pi, 0x4b7, ~((0x7f << 8)));
1171 and_phy_reg(pi, 0x4b1, ~((0x1 << 13)));
1172 or_phy_reg(pi, 0x4b0, (0x1 << 3) | (0x1 << 11));
1173 and_phy_reg(pi, 0x4fa, ~((0x1 << 3)));
1174 or_phy_reg(pi, 0x4f9, (0x1 << 3));
1175 }
1176 }
1177}
1178
1179u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi)
1180{
1181 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1182
1183 return pi->bw;
1184}
1185
1186void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw)
1187{
1188 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1189
1190 pi->bw = bw;
1191}
1192
1193void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, u16 newch)
1194{
1195 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1196 pi->radio_chanspec = newch;
1197
1198}
1199
1200u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi)
1201{
1202 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1203
1204 return pi->radio_chanspec;
1205}
1206
1207void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, u16 chanspec)
1208{
1209 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1210 u16 m_cur_channel;
1211 void (*chanspec_set)(struct brcms_phy *, u16) = NULL;
1212 m_cur_channel = CHSPEC_CHANNEL(chanspec);
1213 if (CHSPEC_IS5G(chanspec))
1214 m_cur_channel |= D11_CURCHANNEL_5G;
1215 if (CHSPEC_IS40(chanspec))
1216 m_cur_channel |= D11_CURCHANNEL_40;
1217 wlapi_bmac_write_shm(pi->sh->physhim, M_CURCHANNEL, m_cur_channel);
1218
1219 chanspec_set = pi->pi_fptr.chanset;
1220 if (chanspec_set)
1221 (*chanspec_set)(pi, chanspec);
1222
1223}
1224
1225int wlc_phy_chanspec_freq2bandrange_lpssn(uint freq)
1226{
1227 int range = -1;
1228
1229 if (freq < 2500)
1230 range = WL_CHAN_FREQ_RANGE_2G;
1231 else if (freq <= 5320)
1232 range = WL_CHAN_FREQ_RANGE_5GL;
1233 else if (freq <= 5700)
1234 range = WL_CHAN_FREQ_RANGE_5GM;
1235 else
1236 range = WL_CHAN_FREQ_RANGE_5GH;
1237
1238 return range;
1239}
1240
1241int wlc_phy_chanspec_bandrange_get(struct brcms_phy *pi, u16 chanspec)
1242{
1243 int range = -1;
1244 uint channel = CHSPEC_CHANNEL(chanspec);
1245 uint freq = wlc_phy_channel2freq(channel);
1246
1247 if (ISNPHY(pi))
1248 range = wlc_phy_get_chan_freq_range_nphy(pi, channel);
1249 else if (ISLCNPHY(pi))
1250 range = wlc_phy_chanspec_freq2bandrange_lpssn(freq);
1251
1252 return range;
1253}
1254
1255void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
1256 bool wide_filter)
1257{
1258 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1259
1260 pi->channel_14_wide_filter = wide_filter;
1261
1262}
1263
1264int wlc_phy_channel2freq(uint channel)
1265{
1266 uint i;
1267
1268 for (i = 0; i < ARRAY_SIZE(chan_info_all); i++)
1269 if (chan_info_all[i].chan == channel)
1270 return chan_info_all[i].freq;
1271 return 0;
1272}
1273
1274void
1275wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
1276 struct brcms_chanvec *channels)
1277{
1278 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1279 uint i;
1280 uint channel;
1281
1282 memset(channels, 0, sizeof(struct brcms_chanvec));
1283
1284 for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
1285 channel = chan_info_all[i].chan;
1286
1287 if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
1288 && (channel <= LAST_REF5_CHANNUM))
1289 continue;
1290
1291 if ((band == BRCM_BAND_2G && channel <= CH_MAX_2G_CHANNEL) ||
1292 (band == BRCM_BAND_5G && channel > CH_MAX_2G_CHANNEL))
1293 setbit(channels->vec, channel);
1294 }
1295}
1296
1297u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band)
1298{
1299 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1300 uint i;
1301 uint channel;
1302 u16 chspec;
1303
1304 for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
1305 channel = chan_info_all[i].chan;
1306
1307 if (ISNPHY(pi) && pi->bw == WL_CHANSPEC_BW_40) {
1308 uint j;
1309
1310 for (j = 0; j < ARRAY_SIZE(chan_info_all); j++) {
1311 if (chan_info_all[j].chan ==
1312 channel + CH_10MHZ_APART)
1313 break;
1314 }
1315
1316 if (j == ARRAY_SIZE(chan_info_all))
1317 continue;
1318
1319 channel = upper_20_sb(channel);
1320 chspec = channel | WL_CHANSPEC_BW_40 |
1321 WL_CHANSPEC_CTL_SB_LOWER;
1322 if (band == BRCM_BAND_2G)
1323 chspec |= WL_CHANSPEC_BAND_2G;
1324 else
1325 chspec |= WL_CHANSPEC_BAND_5G;
1326 } else
1327 chspec = ch20mhz_chspec(channel);
1328
1329 if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
1330 && (channel <= LAST_REF5_CHANNUM))
1331 continue;
1332
1333 if ((band == BRCM_BAND_2G && channel <= CH_MAX_2G_CHANNEL) ||
1334 (band == BRCM_BAND_5G && channel > CH_MAX_2G_CHANNEL))
1335 return chspec;
1336 }
1337
1338 return (u16) INVCHANSPEC;
1339}
1340
1341int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override)
1342{
1343 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1344
1345 *qdbm = pi->tx_user_target[0];
1346 if (override != NULL)
1347 *override = pi->txpwroverride;
1348 return 0;
1349}
1350
1351void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
1352 struct txpwr_limits *txpwr)
1353{
1354 bool mac_enabled = false;
1355 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1356
1357 memcpy(&pi->tx_user_target[TXP_FIRST_CCK],
1358 &txpwr->cck[0], BRCMS_NUM_RATES_CCK);
1359
1360 memcpy(&pi->tx_user_target[TXP_FIRST_OFDM],
1361 &txpwr->ofdm[0], BRCMS_NUM_RATES_OFDM);
1362 memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_20_CDD],
1363 &txpwr->ofdm_cdd[0], BRCMS_NUM_RATES_OFDM);
1364
1365 memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_SISO],
1366 &txpwr->ofdm_40_siso[0], BRCMS_NUM_RATES_OFDM);
1367 memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_CDD],
1368 &txpwr->ofdm_40_cdd[0], BRCMS_NUM_RATES_OFDM);
1369
1370 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SISO],
1371 &txpwr->mcs_20_siso[0], BRCMS_NUM_RATES_MCS_1_STREAM);
1372 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_CDD],
1373 &txpwr->mcs_20_cdd[0], BRCMS_NUM_RATES_MCS_1_STREAM);
1374 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_STBC],
1375 &txpwr->mcs_20_stbc[0], BRCMS_NUM_RATES_MCS_1_STREAM);
1376 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SDM],
1377 &txpwr->mcs_20_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM);
1378
1379 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SISO],
1380 &txpwr->mcs_40_siso[0], BRCMS_NUM_RATES_MCS_1_STREAM);
1381 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_CDD],
1382 &txpwr->mcs_40_cdd[0], BRCMS_NUM_RATES_MCS_1_STREAM);
1383 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_STBC],
1384 &txpwr->mcs_40_stbc[0], BRCMS_NUM_RATES_MCS_1_STREAM);
1385 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SDM],
1386 &txpwr->mcs_40_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM);
1387
1388 if (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)
1389 mac_enabled = true;
1390
1391 if (mac_enabled)
1392 wlapi_suspend_mac_and_wait(pi->sh->physhim);
1393
1394 wlc_phy_txpower_recalc_target(pi);
1395 wlc_phy_cal_txpower_recalc_sw(pi);
1396
1397 if (mac_enabled)
1398 wlapi_enable_mac(pi->sh->physhim);
1399}
1400
1401int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override)
1402{
1403 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1404 int i;
1405
1406 if (qdbm > 127)
1407 return -EINVAL;
1408
1409 for (i = 0; i < TXP_NUM_RATES; i++)
1410 pi->tx_user_target[i] = (u8) qdbm;
1411
1412 pi->txpwroverride = false;
1413
1414 if (pi->sh->up) {
1415 if (!SCAN_INPROG_PHY(pi)) {
1416 bool suspend;
1417
1418 suspend = (0 == (R_REG(&pi->regs->maccontrol) &
1419 MCTL_EN_MAC));
1420
1421 if (!suspend)
1422 wlapi_suspend_mac_and_wait(pi->sh->physhim);
1423
1424 wlc_phy_txpower_recalc_target(pi);
1425 wlc_phy_cal_txpower_recalc_sw(pi);
1426
1427 if (!suspend)
1428 wlapi_enable_mac(pi->sh->physhim);
1429 }
1430 }
1431 return 0;
1432}
1433
1434void
1435wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint channel, u8 *min_pwr,
1436 u8 *max_pwr, int txp_rate_idx)
1437{
1438 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1439 uint i;
1440
1441 *min_pwr = pi->min_txpower * BRCMS_TXPWR_DB_FACTOR;
1442
1443 if (ISNPHY(pi)) {
1444 if (txp_rate_idx < 0)
1445 txp_rate_idx = TXP_FIRST_CCK;
1446 wlc_phy_txpower_sromlimit_get_nphy(pi, channel, max_pwr,
1447 (u8) txp_rate_idx);
1448
1449 } else if ((channel <= CH_MAX_2G_CHANNEL)) {
1450 if (txp_rate_idx < 0)
1451 txp_rate_idx = TXP_FIRST_CCK;
1452 *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
1453 } else {
1454
1455 *max_pwr = BRCMS_TXPWR_MAX;
1456
1457 if (txp_rate_idx < 0)
1458 txp_rate_idx = TXP_FIRST_OFDM;
1459
1460 for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
1461 if (channel == chan_info_all[i].chan)
1462 break;
1463 }
1464
1465 if (pi->hwtxpwr) {
1466 *max_pwr = pi->hwtxpwr[i];
1467 } else {
1468
1469 if ((i >= FIRST_MID_5G_CHAN) && (i <= LAST_MID_5G_CHAN))
1470 *max_pwr =
1471 pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
1472 if ((i >= FIRST_HIGH_5G_CHAN)
1473 && (i <= LAST_HIGH_5G_CHAN))
1474 *max_pwr =
1475 pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
1476 if ((i >= FIRST_LOW_5G_CHAN) && (i <= LAST_LOW_5G_CHAN))
1477 *max_pwr =
1478 pi->tx_srom_max_rate_5g_low[txp_rate_idx];
1479 }
1480 }
1481}
1482
1483void
1484wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan,
1485 u8 *max_txpwr, u8 *min_txpwr)
1486{
1487 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1488 u8 tx_pwr_max = 0;
1489 u8 tx_pwr_min = 255;
1490 u8 max_num_rate;
1491 u8 maxtxpwr, mintxpwr, rate, pactrl;
1492
1493 pactrl = 0;
1494
1495 max_num_rate = ISNPHY(pi) ? TXP_NUM_RATES :
1496 ISLCNPHY(pi) ? (TXP_LAST_SISO_MCS_20 +
1497 1) : (TXP_LAST_OFDM + 1);
1498
1499 for (rate = 0; rate < max_num_rate; rate++) {
1500
1501 wlc_phy_txpower_sromlimit(ppi, chan, &mintxpwr, &maxtxpwr,
1502 rate);
1503
1504 maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
1505
1506 maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
1507
1508 tx_pwr_max = max(tx_pwr_max, maxtxpwr);
1509 tx_pwr_min = min(tx_pwr_min, maxtxpwr);
1510 }
1511 *max_txpwr = tx_pwr_max;
1512 *min_txpwr = tx_pwr_min;
1513}
1514
1515void
1516wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, uint bandunit,
1517 s32 *max_pwr, s32 *min_pwr, u32 *step_pwr)
1518{
1519 return;
1520}
1521
1522u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi)
1523{
1524 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1525
1526 return pi->tx_power_min;
1527}
1528
1529u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi)
1530{
1531 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1532
1533 return pi->tx_power_max;
1534}
1535
1536static s8 wlc_phy_env_measure_vbat(struct brcms_phy *pi)
1537{
1538 if (ISLCNPHY(pi))
1539 return wlc_lcnphy_vbatsense(pi, 0);
1540 else
1541 return 0;
1542}
1543
1544static s8 wlc_phy_env_measure_temperature(struct brcms_phy *pi)
1545{
1546 if (ISLCNPHY(pi))
1547 return wlc_lcnphy_tempsense_degree(pi, 0);
1548 else
1549 return 0;
1550}
1551
1552static void wlc_phy_upd_env_txpwr_rate_limits(struct brcms_phy *pi, u32 band)
1553{
1554 u8 i;
1555 s8 temp, vbat;
1556
1557 for (i = 0; i < TXP_NUM_RATES; i++)
1558 pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX;
1559
1560 vbat = wlc_phy_env_measure_vbat(pi);
1561 temp = wlc_phy_env_measure_temperature(pi);
1562
1563}
1564
1565static s8
1566wlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan, u32 band,
1567 u8 rate)
1568{
1569 s8 offset = 0;
1570
1571 if (!pi->user_txpwr_at_rfport)
1572 return offset;
1573 return offset;
1574}
1575
1576void wlc_phy_txpower_recalc_target(struct brcms_phy *pi)
1577{
1578 u8 maxtxpwr, mintxpwr, rate, pactrl;
1579 uint target_chan;
1580 u8 tx_pwr_target[TXP_NUM_RATES];
1581 u8 tx_pwr_max = 0;
1582 u8 tx_pwr_min = 255;
1583 u8 tx_pwr_max_rate_ind = 0;
1584 u8 max_num_rate;
1585 u8 start_rate = 0;
1586 u16 chspec;
1587 u32 band = CHSPEC2BAND(pi->radio_chanspec);
1588 void (*txpwr_recalc_fn)(struct brcms_phy *) = NULL;
1589
1590 chspec = pi->radio_chanspec;
1591 if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE)
1592 target_chan = CHSPEC_CHANNEL(chspec);
1593 else if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER)
1594 target_chan = upper_20_sb(CHSPEC_CHANNEL(chspec));
1595 else
1596 target_chan = lower_20_sb(CHSPEC_CHANNEL(chspec));
1597
1598 pactrl = 0;
1599 if (ISLCNPHY(pi)) {
1600 u32 offset_mcs, i;
1601
1602 if (CHSPEC_IS40(pi->radio_chanspec)) {
1603 offset_mcs = pi->mcs40_po;
1604 for (i = TXP_FIRST_SISO_MCS_20;
1605 i <= TXP_LAST_SISO_MCS_20; i++) {
1606 pi->tx_srom_max_rate_2g[i - 8] =
1607 pi->tx_srom_max_2g -
1608 ((offset_mcs & 0xf) * 2);
1609 offset_mcs >>= 4;
1610 }
1611 } else {
1612 offset_mcs = pi->mcs20_po;
1613 for (i = TXP_FIRST_SISO_MCS_20;
1614 i <= TXP_LAST_SISO_MCS_20; i++) {
1615 pi->tx_srom_max_rate_2g[i - 8] =
1616 pi->tx_srom_max_2g -
1617 ((offset_mcs & 0xf) * 2);
1618 offset_mcs >>= 4;
1619 }
1620 }
1621 }
1622
1623 max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
1624 ((ISLCNPHY(pi)) ?
1625 (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1)));
1626
1627 wlc_phy_upd_env_txpwr_rate_limits(pi, band);
1628
1629 for (rate = start_rate; rate < max_num_rate; rate++) {
1630
1631 tx_pwr_target[rate] = pi->tx_user_target[rate];
1632
1633 if (pi->user_txpwr_at_rfport)
1634 tx_pwr_target[rate] +=
1635 wlc_user_txpwr_antport_to_rfport(pi,
1636 target_chan,
1637 band,
1638 rate);
1639
1640 wlc_phy_txpower_sromlimit((struct brcms_phy_pub *) pi,
1641 target_chan,
1642 &mintxpwr, &maxtxpwr, rate);
1643
1644 maxtxpwr = min(maxtxpwr, pi->txpwr_limit[rate]);
1645
1646 maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
1647
1648 maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
1649
1650 maxtxpwr = min(maxtxpwr, tx_pwr_target[rate]);
1651
1652 if (pi->txpwr_percent <= 100)
1653 maxtxpwr = (maxtxpwr * pi->txpwr_percent) / 100;
1654
1655 tx_pwr_target[rate] = max(maxtxpwr, mintxpwr);
1656
1657 tx_pwr_target[rate] =
1658 min(tx_pwr_target[rate], pi->txpwr_env_limit[rate]);
1659
1660 if (tx_pwr_target[rate] > tx_pwr_max)
1661 tx_pwr_max_rate_ind = rate;
1662
1663 tx_pwr_max = max(tx_pwr_max, tx_pwr_target[rate]);
1664 tx_pwr_min = min(tx_pwr_min, tx_pwr_target[rate]);
1665 }
1666
1667 memset(pi->tx_power_offset, 0, sizeof(pi->tx_power_offset));
1668 pi->tx_power_max = tx_pwr_max;
1669 pi->tx_power_min = tx_pwr_min;
1670 pi->tx_power_max_rate_ind = tx_pwr_max_rate_ind;
1671 for (rate = 0; rate < max_num_rate; rate++) {
1672
1673 pi->tx_power_target[rate] = tx_pwr_target[rate];
1674
1675 if (!pi->hwpwrctrl || ISNPHY(pi))
1676 pi->tx_power_offset[rate] =
1677 pi->tx_power_max - pi->tx_power_target[rate];
1678 else
1679 pi->tx_power_offset[rate] =
1680 pi->tx_power_target[rate] - pi->tx_power_min;
1681 }
1682
1683 txpwr_recalc_fn = pi->pi_fptr.txpwrrecalc;
1684 if (txpwr_recalc_fn)
1685 (*txpwr_recalc_fn)(pi);
1686}
1687
1688static void
1689wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *txpwr,
1690 u16 chanspec)
1691{
1692 u8 tmp_txpwr_limit[2 * BRCMS_NUM_RATES_OFDM];
1693 u8 *txpwr_ptr1 = NULL, *txpwr_ptr2 = NULL;
1694 int rate_start_index = 0, rate1, rate2, k;
1695
1696 for (rate1 = WL_TX_POWER_CCK_FIRST, rate2 = 0;
1697 rate2 < WL_TX_POWER_CCK_NUM; rate1++, rate2++)
1698 pi->txpwr_limit[rate1] = txpwr->cck[rate2];
1699
1700 for (rate1 = WL_TX_POWER_OFDM_FIRST, rate2 = 0;
1701 rate2 < WL_TX_POWER_OFDM_NUM; rate1++, rate2++)
1702 pi->txpwr_limit[rate1] = txpwr->ofdm[rate2];
1703
1704 if (ISNPHY(pi)) {
1705
1706 for (k = 0; k < 4; k++) {
1707 switch (k) {
1708 case 0:
1709
1710 txpwr_ptr1 = txpwr->mcs_20_siso;
1711 txpwr_ptr2 = txpwr->ofdm;
1712 rate_start_index = WL_TX_POWER_OFDM_FIRST;
1713 break;
1714 case 1:
1715
1716 txpwr_ptr1 = txpwr->mcs_20_cdd;
1717 txpwr_ptr2 = txpwr->ofdm_cdd;
1718 rate_start_index = WL_TX_POWER_OFDM20_CDD_FIRST;
1719 break;
1720 case 2:
1721
1722 txpwr_ptr1 = txpwr->mcs_40_siso;
1723 txpwr_ptr2 = txpwr->ofdm_40_siso;
1724 rate_start_index =
1725 WL_TX_POWER_OFDM40_SISO_FIRST;
1726 break;
1727 case 3:
1728
1729 txpwr_ptr1 = txpwr->mcs_40_cdd;
1730 txpwr_ptr2 = txpwr->ofdm_40_cdd;
1731 rate_start_index = WL_TX_POWER_OFDM40_CDD_FIRST;
1732 break;
1733 }
1734
1735 for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM;
1736 rate2++) {
1737 tmp_txpwr_limit[rate2] = 0;
1738 tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] =
1739 txpwr_ptr1[rate2];
1740 }
1741 wlc_phy_mcs_to_ofdm_powers_nphy(
1742 tmp_txpwr_limit, 0,
1743 BRCMS_NUM_RATES_OFDM -
1744 1, BRCMS_NUM_RATES_OFDM);
1745 for (rate1 = rate_start_index, rate2 = 0;
1746 rate2 < BRCMS_NUM_RATES_OFDM; rate1++, rate2++)
1747 pi->txpwr_limit[rate1] =
1748 min(txpwr_ptr2[rate2],
1749 tmp_txpwr_limit[rate2]);
1750 }
1751
1752 for (k = 0; k < 4; k++) {
1753 switch (k) {
1754 case 0:
1755
1756 txpwr_ptr1 = txpwr->ofdm;
1757 txpwr_ptr2 = txpwr->mcs_20_siso;
1758 rate_start_index = WL_TX_POWER_MCS20_SISO_FIRST;
1759 break;
1760 case 1:
1761
1762 txpwr_ptr1 = txpwr->ofdm_cdd;
1763 txpwr_ptr2 = txpwr->mcs_20_cdd;
1764 rate_start_index = WL_TX_POWER_MCS20_CDD_FIRST;
1765 break;
1766 case 2:
1767
1768 txpwr_ptr1 = txpwr->ofdm_40_siso;
1769 txpwr_ptr2 = txpwr->mcs_40_siso;
1770 rate_start_index = WL_TX_POWER_MCS40_SISO_FIRST;
1771 break;
1772 case 3:
1773
1774 txpwr_ptr1 = txpwr->ofdm_40_cdd;
1775 txpwr_ptr2 = txpwr->mcs_40_cdd;
1776 rate_start_index = WL_TX_POWER_MCS40_CDD_FIRST;
1777 break;
1778 }
1779 for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM;
1780 rate2++) {
1781 tmp_txpwr_limit[rate2] = 0;
1782 tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] =
1783 txpwr_ptr1[rate2];
1784 }
1785 wlc_phy_ofdm_to_mcs_powers_nphy(
1786 tmp_txpwr_limit, 0,
1787 BRCMS_NUM_RATES_OFDM -
1788 1, BRCMS_NUM_RATES_OFDM);
1789 for (rate1 = rate_start_index, rate2 = 0;
1790 rate2 < BRCMS_NUM_RATES_MCS_1_STREAM;
1791 rate1++, rate2++)
1792 pi->txpwr_limit[rate1] =
1793 min(txpwr_ptr2[rate2],
1794 tmp_txpwr_limit[rate2]);
1795 }
1796
1797 for (k = 0; k < 2; k++) {
1798 switch (k) {
1799 case 0:
1800
1801 rate_start_index = WL_TX_POWER_MCS20_STBC_FIRST;
1802 txpwr_ptr1 = txpwr->mcs_20_stbc;
1803 break;
1804 case 1:
1805
1806 rate_start_index = WL_TX_POWER_MCS40_STBC_FIRST;
1807 txpwr_ptr1 = txpwr->mcs_40_stbc;
1808 break;
1809 }
1810 for (rate1 = rate_start_index, rate2 = 0;
1811 rate2 < BRCMS_NUM_RATES_MCS_1_STREAM;
1812 rate1++, rate2++)
1813 pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
1814 }
1815
1816 for (k = 0; k < 2; k++) {
1817 switch (k) {
1818 case 0:
1819
1820 rate_start_index = WL_TX_POWER_MCS20_SDM_FIRST;
1821 txpwr_ptr1 = txpwr->mcs_20_mimo;
1822 break;
1823 case 1:
1824
1825 rate_start_index = WL_TX_POWER_MCS40_SDM_FIRST;
1826 txpwr_ptr1 = txpwr->mcs_40_mimo;
1827 break;
1828 }
1829 for (rate1 = rate_start_index, rate2 = 0;
1830 rate2 < BRCMS_NUM_RATES_MCS_2_STREAM;
1831 rate1++, rate2++)
1832 pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
1833 }
1834
1835 pi->txpwr_limit[WL_TX_POWER_MCS_32] = txpwr->mcs32;
1836
1837 pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST] =
1838 min(pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST],
1839 pi->txpwr_limit[WL_TX_POWER_MCS_32]);
1840 pi->txpwr_limit[WL_TX_POWER_MCS_32] =
1841 pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST];
1842 }
1843}
1844
1845void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, u8 txpwr_percent)
1846{
1847 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1848
1849 pi->txpwr_percent = txpwr_percent;
1850}
1851
1852void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap)
1853{
1854 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1855
1856 pi->sh->machwcap = machwcap;
1857}
1858
1859void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end)
1860{
1861 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1862 u16 rxc;
1863 rxc = 0;
1864
1865 if (start_end == ON) {
1866 if (!ISNPHY(pi))
1867 return;
1868
1869 if (NREV_IS(pi->pubpi.phy_rev, 3)
1870 || NREV_IS(pi->pubpi.phy_rev, 4)) {
1871 W_REG(&pi->regs->phyregaddr, 0xa0);
1872 (void)R_REG(&pi->regs->phyregaddr);
1873 rxc = R_REG(&pi->regs->phyregdata);
1874 W_REG(&pi->regs->phyregdata,
1875 (0x1 << 15) | rxc);
1876 }
1877 } else {
1878 if (NREV_IS(pi->pubpi.phy_rev, 3)
1879 || NREV_IS(pi->pubpi.phy_rev, 4)) {
1880 W_REG(&pi->regs->phyregaddr, 0xa0);
1881 (void)R_REG(&pi->regs->phyregaddr);
1882 W_REG(&pi->regs->phyregdata, rxc);
1883 }
1884
1885 wlc_phy_por_inform(ppi);
1886 }
1887}
1888
1889void
1890wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *txpwr,
1891 u16 chanspec)
1892{
1893 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1894
1895 wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec);
1896
1897 if (ISLCNPHY(pi)) {
1898 int i, j;
1899 for (i = TXP_FIRST_OFDM_20_CDD, j = 0;
1900 j < BRCMS_NUM_RATES_MCS_1_STREAM; i++, j++) {
1901 if (txpwr->mcs_20_siso[j])
1902 pi->txpwr_limit[i] = txpwr->mcs_20_siso[j];
1903 else
1904 pi->txpwr_limit[i] = txpwr->ofdm[j];
1905 }
1906 }
1907
1908 wlapi_suspend_mac_and_wait(pi->sh->physhim);
1909
1910 wlc_phy_txpower_recalc_target(pi);
1911 wlc_phy_cal_txpower_recalc_sw(pi);
1912 wlapi_enable_mac(pi->sh->physhim);
1913}
1914
1915void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war)
1916{
1917 struct brcms_phy *pi = (struct brcms_phy *) pih;
1918
1919 pi->ofdm_rateset_war = war;
1920}
1921
1922void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt)
1923{
1924 struct brcms_phy *pi = (struct brcms_phy *) pih;
1925
1926 pi->bf_preempt_4306 = bf_preempt;
1927}
1928
1929void wlc_phy_txpower_update_shm(struct brcms_phy *pi)
1930{
1931 int j;
1932 if (ISNPHY(pi))
1933 return;
1934
1935 if (!pi->sh->clk)
1936 return;
1937
1938 if (pi->hwpwrctrl) {
1939 u16 offset;
1940
1941 wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_MAX, 63);
1942 wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_N,
1943 1 << NUM_TSSI_FRAMES);
1944
1945 wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_TARGET,
1946 pi->tx_power_min << NUM_TSSI_FRAMES);
1947
1948 wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_CUR,
1949 pi->hwpwr_txcur);
1950
1951 for (j = TXP_FIRST_OFDM; j <= TXP_LAST_OFDM; j++) {
1952 const u8 ucode_ofdm_rates[] = {
1953 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c
1954 };
1955 offset = wlapi_bmac_rate_shm_offset(
1956 pi->sh->physhim,
1957 ucode_ofdm_rates[j - TXP_FIRST_OFDM]);
1958 wlapi_bmac_write_shm(pi->sh->physhim, offset + 6,
1959 pi->tx_power_offset[j]);
1960 wlapi_bmac_write_shm(pi->sh->physhim, offset + 14,
1961 -(pi->tx_power_offset[j] / 2));
1962 }
1963
1964 wlapi_bmac_mhf(pi->sh->physhim, MHF2, MHF2_HWPWRCTL,
1965 MHF2_HWPWRCTL, BRCM_BAND_ALL);
1966 } else {
1967 int i;
1968
1969 for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++)
1970 pi->tx_power_offset[i] =
1971 (u8) roundup(pi->tx_power_offset[i], 8);
1972 wlapi_bmac_write_shm(pi->sh->physhim, M_OFDM_OFFSET,
1973 (u16)
1974 ((pi->tx_power_offset[TXP_FIRST_OFDM]
1975 + 7) >> 3));
1976 }
1977}
1978
1979bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi)
1980{
1981 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1982
1983 if (ISNPHY(pi))
1984 return pi->nphy_txpwrctrl;
1985 else
1986 return pi->hwpwrctrl;
1987}
1988
1989void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl)
1990{
1991 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1992 bool suspend;
1993
1994 if (!pi->hwpwrctrl_capable)
1995 return;
1996
1997 pi->hwpwrctrl = hwpwrctrl;
1998 pi->nphy_txpwrctrl = hwpwrctrl;
1999 pi->txpwrctrl = hwpwrctrl;
2000
2001 if (ISNPHY(pi)) {
2002 suspend = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
2003 if (!suspend)
2004 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2005
2006 wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
2007 if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF)
2008 wlc_phy_txpwr_fixpower_nphy(pi);
2009 else
2010 mod_phy_reg(pi, 0x1e7, (0x7f << 0),
2011 pi->saved_txpwr_idx);
2012
2013 if (!suspend)
2014 wlapi_enable_mac(pi->sh->physhim);
2015 }
2016}
2017
2018void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi)
2019{
2020
2021 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
2022 pi->ipa2g_on = (pi->srom_fem2g.extpagain == 2);
2023 pi->ipa5g_on = (pi->srom_fem5g.extpagain == 2);
2024 } else {
2025 pi->ipa2g_on = false;
2026 pi->ipa5g_on = false;
2027 }
2028}
2029
2030static u32 wlc_phy_txpower_est_power_nphy(struct brcms_phy *pi)
2031{
2032 s16 tx0_status, tx1_status;
2033 u16 estPower1, estPower2;
2034 u8 pwr0, pwr1, adj_pwr0, adj_pwr1;
2035 u32 est_pwr;
2036
2037 estPower1 = read_phy_reg(pi, 0x118);
2038 estPower2 = read_phy_reg(pi, 0x119);
2039
2040 if ((estPower1 & (0x1 << 8)) == (0x1 << 8))
2041 pwr0 = (u8) (estPower1 & (0xff << 0)) >> 0;
2042 else
2043 pwr0 = 0x80;
2044
2045 if ((estPower2 & (0x1 << 8)) == (0x1 << 8))
2046 pwr1 = (u8) (estPower2 & (0xff << 0)) >> 0;
2047 else
2048 pwr1 = 0x80;
2049
2050 tx0_status = read_phy_reg(pi, 0x1ed);
2051 tx1_status = read_phy_reg(pi, 0x1ee);
2052
2053 if ((tx0_status & (0x1 << 15)) == (0x1 << 15))
2054 adj_pwr0 = (u8) (tx0_status & (0xff << 0)) >> 0;
2055 else
2056 adj_pwr0 = 0x80;
2057 if ((tx1_status & (0x1 << 15)) == (0x1 << 15))
2058 adj_pwr1 = (u8) (tx1_status & (0xff << 0)) >> 0;
2059 else
2060 adj_pwr1 = 0x80;
2061
2062 est_pwr = (u32) ((pwr0 << 24) | (pwr1 << 16) | (adj_pwr0 << 8) |
2063 adj_pwr1);
2064
2065 return est_pwr;
2066}
2067
2068void
2069wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power,
2070 uint channel)
2071{
2072 struct brcms_phy *pi = (struct brcms_phy *) ppi;
2073 uint rate, num_rates;
2074 u8 min_pwr, max_pwr;
2075
2076#if WL_TX_POWER_RATES != TXP_NUM_RATES
2077#error "struct tx_power out of sync with this fn"
2078#endif
2079
2080 if (ISNPHY(pi)) {
2081 power->rf_cores = 2;
2082 power->flags |= (WL_TX_POWER_F_MIMO);
2083 if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
2084 power->flags |=
2085 (WL_TX_POWER_F_ENABLED | WL_TX_POWER_F_HW);
2086 } else if (ISLCNPHY(pi)) {
2087 power->rf_cores = 1;
2088 power->flags |= (WL_TX_POWER_F_SISO);
2089 if (pi->radiopwr_override == RADIOPWR_OVERRIDE_DEF)
2090 power->flags |= WL_TX_POWER_F_ENABLED;
2091 if (pi->hwpwrctrl)
2092 power->flags |= WL_TX_POWER_F_HW;
2093 }
2094
2095 num_rates = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
2096 ((ISLCNPHY(pi)) ?
2097 (TXP_LAST_OFDM_20_CDD + 1) : (TXP_LAST_OFDM + 1)));
2098
2099 for (rate = 0; rate < num_rates; rate++) {
2100 power->user_limit[rate] = pi->tx_user_target[rate];
2101 wlc_phy_txpower_sromlimit(ppi, channel, &min_pwr, &max_pwr,
2102 rate);
2103 power->board_limit[rate] = (u8) max_pwr;
2104 power->target[rate] = pi->tx_power_target[rate];
2105 }
2106
2107 if (ISNPHY(pi)) {
2108 u32 est_pout;
2109
2110 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2111 wlc_phyreg_enter((struct brcms_phy_pub *) pi);
2112 est_pout = wlc_phy_txpower_est_power_nphy(pi);
2113 wlc_phyreg_exit((struct brcms_phy_pub *) pi);
2114 wlapi_enable_mac(pi->sh->physhim);
2115
2116 power->est_Pout[0] = (est_pout >> 8) & 0xff;
2117 power->est_Pout[1] = est_pout & 0xff;
2118
2119 power->est_Pout_act[0] = est_pout >> 24;
2120 power->est_Pout_act[1] = (est_pout >> 16) & 0xff;
2121
2122 if (power->est_Pout[0] == 0x80)
2123 power->est_Pout[0] = 0;
2124 if (power->est_Pout[1] == 0x80)
2125 power->est_Pout[1] = 0;
2126
2127 if (power->est_Pout_act[0] == 0x80)
2128 power->est_Pout_act[0] = 0;
2129 if (power->est_Pout_act[1] == 0x80)
2130 power->est_Pout_act[1] = 0;
2131
2132 power->est_Pout_cck = 0;
2133
2134 power->tx_power_max[0] = pi->tx_power_max;
2135 power->tx_power_max[1] = pi->tx_power_max;
2136
2137 power->tx_power_max_rate_ind[0] = pi->tx_power_max_rate_ind;
2138 power->tx_power_max_rate_ind[1] = pi->tx_power_max_rate_ind;
2139 } else if (pi->hwpwrctrl && pi->sh->up) {
2140
2141 wlc_phyreg_enter(ppi);
2142 if (ISLCNPHY(pi)) {
2143
2144 power->tx_power_max[0] = pi->tx_power_max;
2145 power->tx_power_max[1] = pi->tx_power_max;
2146
2147 power->tx_power_max_rate_ind[0] =
2148 pi->tx_power_max_rate_ind;
2149 power->tx_power_max_rate_ind[1] =
2150 pi->tx_power_max_rate_ind;
2151
2152 if (wlc_phy_tpc_isenabled_lcnphy(pi))
2153 power->flags |=
2154 (WL_TX_POWER_F_HW |
2155 WL_TX_POWER_F_ENABLED);
2156 else
2157 power->flags &=
2158 ~(WL_TX_POWER_F_HW |
2159 WL_TX_POWER_F_ENABLED);
2160
2161 wlc_lcnphy_get_tssi(pi, (s8 *) &power->est_Pout[0],
2162 (s8 *) &power->est_Pout_cck);
2163 }
2164 wlc_phyreg_exit(ppi);
2165 }
2166}
2167
2168void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type)
2169{
2170 struct brcms_phy *pi = (struct brcms_phy *) ppi;
2171
2172 pi->antsel_type = antsel_type;
2173}
2174
2175bool wlc_phy_test_ison(struct brcms_phy_pub *ppi)
2176{
2177 struct brcms_phy *pi = (struct brcms_phy *) ppi;
2178
2179 return pi->phytest_on;
2180}
2181
2182void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val)
2183{
2184 struct brcms_phy *pi = (struct brcms_phy *) ppi;
2185 bool suspend;
2186
2187 pi->sh->rx_antdiv = val;
2188
2189 if (!(ISNPHY(pi) && D11REV_IS(pi->sh->corerev, 16))) {
2190 if (val > ANT_RX_DIV_FORCE_1)
2191 wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV,
2192 MHF1_ANTDIV, BRCM_BAND_ALL);
2193 else
2194 wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, 0,
2195 BRCM_BAND_ALL);
2196 }
2197
2198 if (ISNPHY(pi))
2199 return;
2200
2201 if (!pi->sh->clk)
2202 return;
2203
2204 suspend = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
2205 if (!suspend)
2206 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2207
2208 if (ISLCNPHY(pi)) {
2209 if (val > ANT_RX_DIV_FORCE_1) {
2210 mod_phy_reg(pi, 0x410, (0x1 << 1), 0x01 << 1);
2211 mod_phy_reg(pi, 0x410,
2212 (0x1 << 0),
2213 ((ANT_RX_DIV_START_1 == val) ? 1 : 0) << 0);
2214 } else {
2215 mod_phy_reg(pi, 0x410, (0x1 << 1), 0x00 << 1);
2216 mod_phy_reg(pi, 0x410, (0x1 << 0), (u16) val << 0);
2217 }
2218 }
2219
2220 if (!suspend)
2221 wlapi_enable_mac(pi->sh->physhim);
2222
2223 return;
2224}
2225
2226static bool
2227wlc_phy_noise_calc_phy(struct brcms_phy *pi, u32 *cmplx_pwr, s8 *pwr_ant)
2228{
2229 s8 cmplx_pwr_dbm[PHY_CORE_MAX];
2230 u8 i;
2231
2232 memset((u8 *) cmplx_pwr_dbm, 0, sizeof(cmplx_pwr_dbm));
2233 wlc_phy_compute_dB(cmplx_pwr, cmplx_pwr_dbm, pi->pubpi.phy_corenum);
2234
2235 for (i = 0; i < pi->pubpi.phy_corenum; i++) {
2236 if (NREV_GE(pi->pubpi.phy_rev, 3))
2237 cmplx_pwr_dbm[i] += (s8) PHY_NOISE_OFFSETFACT_4322;
2238 else
2239
2240 cmplx_pwr_dbm[i] += (s8) (16 - (15) * 3 - 70);
2241 }
2242
2243 for (i = 0; i < pi->pubpi.phy_corenum; i++) {
2244 pi->nphy_noise_win[i][pi->nphy_noise_index] = cmplx_pwr_dbm[i];
2245 pwr_ant[i] = cmplx_pwr_dbm[i];
2246 }
2247 pi->nphy_noise_index =
2248 MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
2249 return true;
2250}
2251
2252static void wlc_phy_noise_cb(struct brcms_phy *pi, u8 channel, s8 noise_dbm)
2253{
2254 if (!pi->phynoise_state)
2255 return;
2256
2257 if (pi->phynoise_state & PHY_NOISE_STATE_MON) {
2258 if (pi->phynoise_chan_watchdog == channel) {
2259 pi->sh->phy_noise_window[pi->sh->phy_noise_index] =
2260 noise_dbm;
2261 pi->sh->phy_noise_index =
2262 MODINC(pi->sh->phy_noise_index, MA_WINDOW_SZ);
2263 }
2264 pi->phynoise_state &= ~PHY_NOISE_STATE_MON;
2265 }
2266
2267 if (pi->phynoise_state & PHY_NOISE_STATE_EXTERNAL)
2268 pi->phynoise_state &= ~PHY_NOISE_STATE_EXTERNAL;
2269
2270}
2271
2272static s8 wlc_phy_noise_read_shmem(struct brcms_phy *pi)
2273{
2274 u32 cmplx_pwr[PHY_CORE_MAX];
2275 s8 noise_dbm_ant[PHY_CORE_MAX];
2276 u16 lo, hi;
2277 u32 cmplx_pwr_tot = 0;
2278 s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
2279 u8 idx, core;
2280
2281 memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
2282 memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
2283
2284 for (idx = 0, core = 0; core < pi->pubpi.phy_corenum; idx += 2,
2285 core++) {
2286 lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP(idx));
2287 hi = wlapi_bmac_read_shm(pi->sh->physhim,
2288 M_PWRIND_MAP(idx + 1));
2289 cmplx_pwr[core] = (hi << 16) + lo;
2290 cmplx_pwr_tot += cmplx_pwr[core];
2291 if (cmplx_pwr[core] == 0)
2292 noise_dbm_ant[core] = PHY_NOISE_FIXED_VAL_NPHY;
2293 else
2294 cmplx_pwr[core] >>= PHY_NOISE_SAMPLE_LOG_NUM_UCODE;
2295 }
2296
2297 if (cmplx_pwr_tot != 0)
2298 wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
2299
2300 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
2301 pi->nphy_noise_win[core][pi->nphy_noise_index] =
2302 noise_dbm_ant[core];
2303
2304 if (noise_dbm_ant[core] > noise_dbm)
2305 noise_dbm = noise_dbm_ant[core];
2306 }
2307 pi->nphy_noise_index =
2308 MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
2309
2310 return noise_dbm;
2311
2312}
2313
2314void wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih)
2315{
2316 struct brcms_phy *pi = (struct brcms_phy *) pih;
2317 u16 jssi_aux;
2318 u8 channel = 0;
2319 s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
2320
2321 if (ISLCNPHY(pi)) {
2322 u32 cmplx_pwr, cmplx_pwr0, cmplx_pwr1;
2323 u16 lo, hi;
2324 s32 pwr_offset_dB, gain_dB;
2325 u16 status_0, status_1;
2326
2327 jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
2328 channel = jssi_aux & D11_CURCHANNEL_MAX;
2329
2330 lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP0);
2331 hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP1);
2332 cmplx_pwr0 = (hi << 16) + lo;
2333
2334 lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP2);
2335 hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP3);
2336 cmplx_pwr1 = (hi << 16) + lo;
2337 cmplx_pwr = (cmplx_pwr0 + cmplx_pwr1) >> 6;
2338
2339 status_0 = 0x44;
2340 status_1 = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_0);
2341 if ((cmplx_pwr > 0 && cmplx_pwr < 500)
2342 && ((status_1 & 0xc000) == 0x4000)) {
2343
2344 wlc_phy_compute_dB(&cmplx_pwr, &noise_dbm,
2345 pi->pubpi.phy_corenum);
2346 pwr_offset_dB = (read_phy_reg(pi, 0x434) & 0xFF);
2347 if (pwr_offset_dB > 127)
2348 pwr_offset_dB -= 256;
2349
2350 noise_dbm += (s8) (pwr_offset_dB - 30);
2351
2352 gain_dB = (status_0 & 0x1ff);
2353 noise_dbm -= (s8) (gain_dB);
2354 } else {
2355 noise_dbm = PHY_NOISE_FIXED_VAL_LCNPHY;
2356 }
2357 } else if (ISNPHY(pi)) {
2358
2359 jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
2360 channel = jssi_aux & D11_CURCHANNEL_MAX;
2361
2362 noise_dbm = wlc_phy_noise_read_shmem(pi);
2363 }
2364
2365 wlc_phy_noise_cb(pi, channel, noise_dbm);
2366
2367}
2368
2369static void
2370wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch)
2371{
2372 struct brcms_phy *pi = (struct brcms_phy *) pih;
2373 s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
2374 bool sampling_in_progress = (pi->phynoise_state != 0);
2375 bool wait_for_intr = true;
2376
2377 switch (reason) {
2378 case PHY_NOISE_SAMPLE_MON:
2379 pi->phynoise_chan_watchdog = ch;
2380 pi->phynoise_state |= PHY_NOISE_STATE_MON;
2381 break;
2382
2383 case PHY_NOISE_SAMPLE_EXTERNAL:
2384 pi->phynoise_state |= PHY_NOISE_STATE_EXTERNAL;
2385 break;
2386
2387 default:
2388 break;
2389 }
2390
2391 if (sampling_in_progress)
2392 return;
2393
2394 pi->phynoise_now = pi->sh->now;
2395
2396 if (pi->phy_fixed_noise) {
2397 if (ISNPHY(pi)) {
2398 pi->nphy_noise_win[WL_ANT_IDX_1][pi->nphy_noise_index] =
2399 PHY_NOISE_FIXED_VAL_NPHY;
2400 pi->nphy_noise_win[WL_ANT_IDX_2][pi->nphy_noise_index] =
2401 PHY_NOISE_FIXED_VAL_NPHY;
2402 pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
2403 PHY_NOISE_WINDOW_SZ);
2404 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
2405 } else {
2406 noise_dbm = PHY_NOISE_FIXED_VAL;
2407 }
2408
2409 wait_for_intr = false;
2410 goto done;
2411 }
2412
2413 if (ISLCNPHY(pi)) {
2414 if (!pi->phynoise_polling
2415 || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
2416 wlapi_bmac_write_shm(pi->sh->physhim, M_JSSI_0, 0);
2417 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
2418 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
2419 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
2420 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
2421
2422 OR_REG(&pi->regs->maccommand,
2423 MCMD_BG_NOISE);
2424 } else {
2425 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2426 wlc_lcnphy_deaf_mode(pi, (bool) 0);
2427 noise_dbm = (s8) wlc_lcnphy_rx_signal_power(pi, 20);
2428 wlc_lcnphy_deaf_mode(pi, (bool) 1);
2429 wlapi_enable_mac(pi->sh->physhim);
2430 wait_for_intr = false;
2431 }
2432 } else if (ISNPHY(pi)) {
2433 if (!pi->phynoise_polling
2434 || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
2435
2436 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
2437 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
2438 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
2439 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
2440
2441 OR_REG(&pi->regs->maccommand,
2442 MCMD_BG_NOISE);
2443 } else {
2444 struct phy_iq_est est[PHY_CORE_MAX];
2445 u32 cmplx_pwr[PHY_CORE_MAX];
2446 s8 noise_dbm_ant[PHY_CORE_MAX];
2447 u16 log_num_samps, num_samps, classif_state = 0;
2448 u8 wait_time = 32;
2449 u8 wait_crs = 0;
2450 u8 i;
2451
2452 memset((u8 *) est, 0, sizeof(est));
2453 memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
2454 memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
2455
2456 log_num_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
2457 num_samps = 1 << log_num_samps;
2458
2459 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2460 classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
2461 wlc_phy_classifier_nphy(pi, 3, 0);
2462 wlc_phy_rx_iq_est_nphy(pi, est, num_samps, wait_time,
2463 wait_crs);
2464 wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
2465 wlapi_enable_mac(pi->sh->physhim);
2466
2467 for (i = 0; i < pi->pubpi.phy_corenum; i++)
2468 cmplx_pwr[i] = (est[i].i_pwr + est[i].q_pwr) >>
2469 log_num_samps;
2470
2471 wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
2472
2473 for (i = 0; i < pi->pubpi.phy_corenum; i++) {
2474 pi->nphy_noise_win[i][pi->nphy_noise_index] =
2475 noise_dbm_ant[i];
2476
2477 if (noise_dbm_ant[i] > noise_dbm)
2478 noise_dbm = noise_dbm_ant[i];
2479 }
2480 pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
2481 PHY_NOISE_WINDOW_SZ);
2482
2483 wait_for_intr = false;
2484 }
2485 }
2486
2487done:
2488
2489 if (!wait_for_intr)
2490 wlc_phy_noise_cb(pi, ch, noise_dbm);
2491
2492}
2493
2494void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *pih)
2495{
2496 u8 channel;
2497
2498 channel = CHSPEC_CHANNEL(wlc_phy_chanspec_get(pih));
2499
2500 wlc_phy_noise_sample_request(pih, PHY_NOISE_SAMPLE_EXTERNAL, channel);
2501}
2502
2503static const s8 lcnphy_gain_index_offset_for_pkt_rssi[] = {
2504 8,
2505 8,
2506 8,
2507 8,
2508 8,
2509 8,
2510 8,
2511 9,
2512 10,
2513 8,
2514 8,
2515 7,
2516 7,
2517 1,
2518 2,
2519 2,
2520 2,
2521 2,
2522 2,
2523 2,
2524 2,
2525 2,
2526 2,
2527 2,
2528 2,
2529 2,
2530 2,
2531 2,
2532 2,
2533 2,
2534 2,
2535 2,
2536 1,
2537 1,
2538 0,
2539 0,
2540 0,
2541 0
2542};
2543
2544void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_cmplx_pwr_dB, u8 core)
2545{
2546 u8 msb, secondmsb, i;
2547 u32 tmp;
2548
2549 for (i = 0; i < core; i++) {
2550 secondmsb = 0;
2551 tmp = cmplx_pwr[i];
2552 msb = fls(tmp);
2553 if (msb)
2554 secondmsb = (u8) ((tmp >> (--msb - 1)) & 1);
2555 p_cmplx_pwr_dB[i] = (s8) (3 * msb + 2 * secondmsb);
2556 }
2557}
2558
2559int wlc_phy_rssi_compute(struct brcms_phy_pub *pih,
2560 struct d11rxhdr *rxh)
2561{
2562 int rssi = rxh->PhyRxStatus_1 & PRXS1_JSSI_MASK;
2563 uint radioid = pih->radioid;
2564 struct brcms_phy *pi = (struct brcms_phy *) pih;
2565
2566 if ((pi->sh->corerev >= 11)
2567 && !(rxh->RxStatus2 & RXS_PHYRXST_VALID)) {
2568 rssi = BRCMS_RSSI_INVALID;
2569 goto end;
2570 }
2571
2572 if (ISLCNPHY(pi)) {
2573 u8 gidx = (rxh->PhyRxStatus_2 & 0xFC00) >> 10;
2574 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
2575
2576 if (rssi > 127)
2577 rssi -= 256;
2578
2579 rssi = rssi + lcnphy_gain_index_offset_for_pkt_rssi[gidx];
2580 if ((rssi > -46) && (gidx > 18))
2581 rssi = rssi + 7;
2582
2583 rssi = rssi + pi_lcn->lcnphy_pkteng_rssi_slope;
2584
2585 rssi = rssi + 2;
2586
2587 }
2588
2589 if (ISLCNPHY(pi)) {
2590 if (rssi > 127)
2591 rssi -= 256;
2592 } else if (radioid == BCM2055_ID || radioid == BCM2056_ID
2593 || radioid == BCM2057_ID) {
2594 rssi = wlc_phy_rssi_compute_nphy(pi, rxh);
2595 }
2596
2597end:
2598 return rssi;
2599}
2600
2601void wlc_phy_freqtrack_start(struct brcms_phy_pub *pih)
2602{
2603 return;
2604}
2605
2606void wlc_phy_freqtrack_end(struct brcms_phy_pub *pih)
2607{
2608 return;
2609}
2610
2611void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag)
2612{
2613 struct brcms_phy *pi;
2614 pi = (struct brcms_phy *) ppi;
2615
2616 if (ISLCNPHY(pi))
2617 wlc_lcnphy_deaf_mode(pi, true);
2618 else if (ISNPHY(pi))
2619 wlc_nphy_deaf_mode(pi, true);
2620}
2621
2622void wlc_phy_watchdog(struct brcms_phy_pub *pih)
2623{
2624 struct brcms_phy *pi = (struct brcms_phy *) pih;
2625 bool delay_phy_cal = false;
2626 pi->sh->now++;
2627
2628 if (!pi->watchdog_override)
2629 return;
2630
2631 if (!(SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)))
2632 wlc_phy_noise_sample_request((struct brcms_phy_pub *) pi,
2633 PHY_NOISE_SAMPLE_MON,
2634 CHSPEC_CHANNEL(pi->
2635 radio_chanspec));
2636
2637 if (pi->phynoise_state && (pi->sh->now - pi->phynoise_now) > 5)
2638 pi->phynoise_state = 0;
2639
2640 if ((!pi->phycal_txpower) ||
2641 ((pi->sh->now - pi->phycal_txpower) >= pi->sh->fast_timer)) {
2642
2643 if (!SCAN_INPROG_PHY(pi) && wlc_phy_cal_txpower_recalc_sw(pi))
2644 pi->phycal_txpower = pi->sh->now;
2645 }
2646
2647 if ((SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
2648 || ASSOC_INPROG_PHY(pi)))
2649 return;
2650
2651 if (ISNPHY(pi) && !pi->disable_percal && !delay_phy_cal) {
2652
2653 if ((pi->nphy_perical != PHY_PERICAL_DISABLE) &&
2654 (pi->nphy_perical != PHY_PERICAL_MANUAL) &&
2655 ((pi->sh->now - pi->nphy_perical_last) >=
2656 pi->sh->glacial_timer))
2657 wlc_phy_cal_perical((struct brcms_phy_pub *) pi,
2658 PHY_PERICAL_WATCHDOG);
2659
2660 wlc_phy_txpwr_papd_cal_nphy(pi);
2661 }
2662
2663 if (ISLCNPHY(pi)) {
2664 if (pi->phy_forcecal ||
2665 ((pi->sh->now - pi->phy_lastcal) >=
2666 pi->sh->glacial_timer)) {
2667 if (!(SCAN_RM_IN_PROGRESS(pi) || ASSOC_INPROG_PHY(pi)))
2668 wlc_lcnphy_calib_modes(
2669 pi,
2670 LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
2671 if (!
2672 (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
2673 || ASSOC_INPROG_PHY(pi)
2674 || pi->carrier_suppr_disable
2675 || pi->disable_percal))
2676 wlc_lcnphy_calib_modes(pi,
2677 PHY_PERICAL_WATCHDOG);
2678 }
2679 }
2680}
2681
2682void wlc_phy_BSSinit(struct brcms_phy_pub *pih, bool bonlyap, int rssi)
2683{
2684 struct brcms_phy *pi = (struct brcms_phy *) pih;
2685 uint i;
2686 uint k;
2687
2688 for (i = 0; i < MA_WINDOW_SZ; i++)
2689 pi->sh->phy_noise_window[i] = (s8) (rssi & 0xff);
2690 if (ISLCNPHY(pi)) {
2691 for (i = 0; i < MA_WINDOW_SZ; i++)
2692 pi->sh->phy_noise_window[i] =
2693 PHY_NOISE_FIXED_VAL_LCNPHY;
2694 }
2695 pi->sh->phy_noise_index = 0;
2696
2697 for (i = 0; i < PHY_NOISE_WINDOW_SZ; i++) {
2698 for (k = WL_ANT_IDX_1; k < WL_ANT_RX_MAX; k++)
2699 pi->nphy_noise_win[k][i] = PHY_NOISE_FIXED_VAL_NPHY;
2700 }
2701 pi->nphy_noise_index = 0;
2702}
2703
2704void
2705wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag)
2706{
2707 *eps_imag = (epsilon >> 13);
2708 if (*eps_imag > 0xfff)
2709 *eps_imag -= 0x2000;
2710
2711 *eps_real = (epsilon & 0x1fff);
2712 if (*eps_real > 0xfff)
2713 *eps_real -= 0x2000;
2714}
2715
2716void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi)
2717{
2718 wlapi_del_timer(pi->phycal_timer);
2719
2720 pi->cal_type_override = PHY_PERICAL_AUTO;
2721 pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
2722 pi->mphase_txcal_cmdidx = 0;
2723}
2724
2725static void
2726wlc_phy_cal_perical_mphase_schedule(struct brcms_phy *pi, uint delay)
2727{
2728
2729 if ((pi->nphy_perical != PHY_PERICAL_MPHASE) &&
2730 (pi->nphy_perical != PHY_PERICAL_MANUAL))
2731 return;
2732
2733 wlapi_del_timer(pi->phycal_timer);
2734
2735 pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
2736 wlapi_add_timer(pi->phycal_timer, delay, 0);
2737}
2738
2739void wlc_phy_cal_perical(struct brcms_phy_pub *pih, u8 reason)
2740{
2741 s16 nphy_currtemp = 0;
2742 s16 delta_temp = 0;
2743 bool do_periodic_cal = true;
2744 struct brcms_phy *pi = (struct brcms_phy *) pih;
2745
2746 if (!ISNPHY(pi))
2747 return;
2748
2749 if ((pi->nphy_perical == PHY_PERICAL_DISABLE) ||
2750 (pi->nphy_perical == PHY_PERICAL_MANUAL))
2751 return;
2752
2753 switch (reason) {
2754 case PHY_PERICAL_DRIVERUP:
2755 break;
2756
2757 case PHY_PERICAL_PHYINIT:
2758 if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
2759 if (PHY_PERICAL_MPHASE_PENDING(pi))
2760 wlc_phy_cal_perical_mphase_reset(pi);
2761
2762 wlc_phy_cal_perical_mphase_schedule(
2763 pi,
2764 PHY_PERICAL_INIT_DELAY);
2765 }
2766 break;
2767
2768 case PHY_PERICAL_JOIN_BSS:
2769 case PHY_PERICAL_START_IBSS:
2770 case PHY_PERICAL_UP_BSS:
2771 if ((pi->nphy_perical == PHY_PERICAL_MPHASE) &&
2772 PHY_PERICAL_MPHASE_PENDING(pi))
2773 wlc_phy_cal_perical_mphase_reset(pi);
2774
2775 pi->first_cal_after_assoc = true;
2776
2777 pi->cal_type_override = PHY_PERICAL_FULL;
2778
2779 if (pi->phycal_tempdelta)
2780 pi->nphy_lastcal_temp = wlc_phy_tempsense_nphy(pi);
2781
2782 wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_FULL);
2783 break;
2784
2785 case PHY_PERICAL_WATCHDOG:
2786 if (pi->phycal_tempdelta) {
2787 nphy_currtemp = wlc_phy_tempsense_nphy(pi);
2788 delta_temp =
2789 (nphy_currtemp > pi->nphy_lastcal_temp) ?
2790 nphy_currtemp - pi->nphy_lastcal_temp :
2791 pi->nphy_lastcal_temp - nphy_currtemp;
2792
2793 if ((delta_temp < (s16) pi->phycal_tempdelta) &&
2794 (pi->nphy_txiqlocal_chanspec ==
2795 pi->radio_chanspec))
2796 do_periodic_cal = false;
2797 else
2798 pi->nphy_lastcal_temp = nphy_currtemp;
2799 }
2800
2801 if (do_periodic_cal) {
2802 if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
2803 if (!PHY_PERICAL_MPHASE_PENDING(pi))
2804 wlc_phy_cal_perical_mphase_schedule(
2805 pi,
2806 PHY_PERICAL_WDOG_DELAY);
2807 } else if (pi->nphy_perical == PHY_PERICAL_SPHASE)
2808 wlc_phy_cal_perical_nphy_run(pi,
2809 PHY_PERICAL_AUTO);
2810 }
2811 break;
2812 default:
2813 break;
2814 }
2815}
2816
2817void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi)
2818{
2819 pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
2820 pi->mphase_txcal_cmdidx = 0;
2821}
2822
2823u8 wlc_phy_nbits(s32 value)
2824{
2825 s32 abs_val;
2826 u8 nbits = 0;
2827
2828 abs_val = abs(value);
2829 while ((abs_val >> nbits) > 0)
2830 nbits++;
2831
2832 return nbits;
2833}
2834
2835void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
2836{
2837 struct brcms_phy *pi = (struct brcms_phy *) pih;
2838
2839 pi->sh->hw_phytxchain = txchain;
2840 pi->sh->hw_phyrxchain = rxchain;
2841 pi->sh->phytxchain = txchain;
2842 pi->sh->phyrxchain = rxchain;
2843 pi->pubpi.phy_corenum = (u8)hweight8(pi->sh->phyrxchain);
2844}
2845
2846void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
2847{
2848 struct brcms_phy *pi = (struct brcms_phy *) pih;
2849
2850 pi->sh->phytxchain = txchain;
2851
2852 if (ISNPHY(pi))
2853 wlc_phy_rxcore_setstate_nphy(pih, rxchain);
2854
2855 pi->pubpi.phy_corenum = (u8)hweight8(pi->sh->phyrxchain);
2856}
2857
2858void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, u8 *rxchain)
2859{
2860 struct brcms_phy *pi = (struct brcms_phy *) pih;
2861
2862 *txchain = pi->sh->phytxchain;
2863 *rxchain = pi->sh->phyrxchain;
2864}
2865
2866u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih)
2867{
2868 s16 nphy_currtemp;
2869 u8 active_bitmap;
2870 struct brcms_phy *pi = (struct brcms_phy *) pih;
2871
2872 active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33;
2873
2874 if (!pi->watchdog_override)
2875 return active_bitmap;
2876
2877 if (NREV_GE(pi->pubpi.phy_rev, 6)) {
2878 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2879 nphy_currtemp = wlc_phy_tempsense_nphy(pi);
2880 wlapi_enable_mac(pi->sh->physhim);
2881
2882 if (!pi->phy_txcore_heatedup) {
2883 if (nphy_currtemp >= pi->phy_txcore_disable_temp) {
2884 active_bitmap &= 0xFD;
2885 pi->phy_txcore_heatedup = true;
2886 }
2887 } else {
2888 if (nphy_currtemp <= pi->phy_txcore_enable_temp) {
2889 active_bitmap |= 0x2;
2890 pi->phy_txcore_heatedup = false;
2891 }
2892 }
2893 }
2894
2895 return active_bitmap;
2896}
2897
2898s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, u16 chanspec)
2899{
2900 struct brcms_phy *pi = (struct brcms_phy *) pih;
2901 u8 siso_mcs_id, cdd_mcs_id;
2902
2903 siso_mcs_id =
2904 (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_SISO :
2905 TXP_FIRST_MCS_20_SISO;
2906 cdd_mcs_id =
2907 (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_CDD :
2908 TXP_FIRST_MCS_20_CDD;
2909
2910 if (pi->tx_power_target[siso_mcs_id] >
2911 (pi->tx_power_target[cdd_mcs_id] + 12))
2912 return PHY_TXC1_MODE_SISO;
2913 else
2914 return PHY_TXC1_MODE_CDD;
2915}
2916
2917const u8 *wlc_phy_get_ofdm_rate_lookup(void)
2918{
2919 return ofdm_rate_lookup;
2920}
2921
2922void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode)
2923{
2924 if ((pi->sh->chip == BCM4313_CHIP_ID) &&
2925 (pi->sh->boardflags & BFL_FEM)) {
2926 if (mode) {
2927 u16 txant = 0;
2928 txant = wlapi_bmac_get_txant(pi->sh->physhim);
2929 if (txant == 1) {
2930 mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
2931
2932 mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2);
2933
2934 }
2935 ai_corereg(pi->sh->sih, SI_CC_IDX,
2936 offsetof(struct chipcregs, gpiocontrol),
2937 ~0x0, 0x0);
2938 ai_corereg(pi->sh->sih, SI_CC_IDX,
2939 offsetof(struct chipcregs, gpioout), 0x40,
2940 0x40);
2941 ai_corereg(pi->sh->sih, SI_CC_IDX,
2942 offsetof(struct chipcregs, gpioouten), 0x40,
2943 0x40);
2944 } else {
2945 mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2);
2946
2947 mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2);
2948
2949 ai_corereg(pi->sh->sih, SI_CC_IDX,
2950 offsetof(struct chipcregs, gpioout), 0x40,
2951 0x00);
2952 ai_corereg(pi->sh->sih, SI_CC_IDX,
2953 offsetof(struct chipcregs, gpioouten), 0x40,
2954 0x0);
2955 ai_corereg(pi->sh->sih, SI_CC_IDX,
2956 offsetof(struct chipcregs, gpiocontrol),
2957 ~0x0, 0x40);
2958 }
2959 }
2960}
2961
2962void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool ldpc)
2963{
2964 return;
2965}
2966
2967void
2968wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset, s8 *ofdmoffset)
2969{
2970 *cckoffset = 0;
2971 *ofdmoffset = 0;
2972}
2973
2974s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, u16 chanspec)
2975{
2976
2977 return rssi;
2978}
2979
2980bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *ppi)
2981{
2982 struct brcms_phy *pi = (struct brcms_phy *) ppi;
2983
2984 if (ISNPHY(pi))
2985 return wlc_phy_n_txpower_ipa_ison(pi);
2986 else
2987 return 0;
2988}
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 000000000000..96e15163222b
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
@@ -0,0 +1,301 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/*
18 * phy_hal.h: functionality exported from the phy to higher layers
19 */
20
21#ifndef _BRCM_PHY_HAL_H_
22#define _BRCM_PHY_HAL_H_
23
24#include <brcmu_utils.h>
25#include <brcmu_wifi.h>
26#include <phy_shim.h>
27
28#define IDCODE_VER_MASK 0x0000000f
29#define IDCODE_VER_SHIFT 0
30#define IDCODE_MFG_MASK 0x00000fff
31#define IDCODE_MFG_SHIFT 0
32#define IDCODE_ID_MASK 0x0ffff000
33#define IDCODE_ID_SHIFT 12
34#define IDCODE_REV_MASK 0xf0000000
35#define IDCODE_REV_SHIFT 28
36
37#define NORADIO_ID 0xe4f5
38#define NORADIO_IDCODE 0x4e4f5246
39
40#define BCM2055_ID 0x2055
41#define BCM2055_IDCODE 0x02055000
42#define BCM2055A0_IDCODE 0x1205517f
43
44#define BCM2056_ID 0x2056
45#define BCM2056_IDCODE 0x02056000
46#define BCM2056A0_IDCODE 0x1205617f
47
48#define BCM2057_ID 0x2057
49#define BCM2057_IDCODE 0x02057000
50#define BCM2057A0_IDCODE 0x1205717f
51
52#define BCM2064_ID 0x2064
53#define BCM2064_IDCODE 0x02064000
54#define BCM2064A0_IDCODE 0x0206417f
55
56#define PHY_TPC_HW_OFF false
57#define PHY_TPC_HW_ON true
58
59#define PHY_PERICAL_DRIVERUP 1
60#define PHY_PERICAL_WATCHDOG 2
61#define PHY_PERICAL_PHYINIT 3
62#define PHY_PERICAL_JOIN_BSS 4
63#define PHY_PERICAL_START_IBSS 5
64#define PHY_PERICAL_UP_BSS 6
65#define PHY_PERICAL_CHAN 7
66#define PHY_FULLCAL 8
67
68#define PHY_PERICAL_DISABLE 0
69#define PHY_PERICAL_SPHASE 1
70#define PHY_PERICAL_MPHASE 2
71#define PHY_PERICAL_MANUAL 3
72
73#define PHY_HOLD_FOR_ASSOC 1
74#define PHY_HOLD_FOR_SCAN 2
75#define PHY_HOLD_FOR_RM 4
76#define PHY_HOLD_FOR_PLT 8
77#define PHY_HOLD_FOR_MUTE 16
78#define PHY_HOLD_FOR_NOT_ASSOC 0x20
79
80#define PHY_MUTE_FOR_PREISM 1
81#define PHY_MUTE_ALL 0xffffffff
82
83#define PHY_NOISE_FIXED_VAL (-95)
84#define PHY_NOISE_FIXED_VAL_NPHY (-92)
85#define PHY_NOISE_FIXED_VAL_LCNPHY (-92)
86
87#define PHY_MODE_CAL 0x0002
88#define PHY_MODE_NOISEM 0x0004
89
90#define BRCMS_TXPWR_DB_FACTOR 4
91
92/* a large TX Power as an init value to factor out of min() calculations,
93 * keep low enough to fit in an s8, units are .25 dBm
94 */
95#define BRCMS_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */
96
97#define BRCMS_NUM_RATES_CCK 4
98#define BRCMS_NUM_RATES_OFDM 8
99#define BRCMS_NUM_RATES_MCS_1_STREAM 8
100#define BRCMS_NUM_RATES_MCS_2_STREAM 8
101#define BRCMS_NUM_RATES_MCS_3_STREAM 8
102#define BRCMS_NUM_RATES_MCS_4_STREAM 8
103
104#define BRCMS_RSSI_INVALID 0 /* invalid RSSI value */
105
106struct d11regs;
107struct phy_shim_info;
108
109struct txpwr_limits {
110 u8 cck[BRCMS_NUM_RATES_CCK];
111 u8 ofdm[BRCMS_NUM_RATES_OFDM];
112
113 u8 ofdm_cdd[BRCMS_NUM_RATES_OFDM];
114
115 u8 ofdm_40_siso[BRCMS_NUM_RATES_OFDM];
116 u8 ofdm_40_cdd[BRCMS_NUM_RATES_OFDM];
117
118 u8 mcs_20_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
119 u8 mcs_20_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
120 u8 mcs_20_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
121 u8 mcs_20_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
122
123 u8 mcs_40_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
124 u8 mcs_40_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
125 u8 mcs_40_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
126 u8 mcs_40_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
127 u8 mcs32;
128};
129
130struct tx_power {
131 u32 flags;
132 u16 chanspec; /* txpwr report for this channel */
133 u16 local_chanspec; /* channel on which we are associated */
134 u8 local_max; /* local max according to the AP */
135 u8 local_constraint; /* local constraint according to the AP */
136 s8 antgain[2]; /* Ant gain for each band - from SROM */
137 u8 rf_cores; /* count of RF Cores being reported */
138 u8 est_Pout[4]; /* Latest tx power out estimate per RF chain */
139 u8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain
140 * without adjustment */
141 u8 est_Pout_cck; /* Latest CCK tx power out estimate */
142 u8 tx_power_max[4]; /* Maximum target power among all rates */
143 /* Index of the rate with the max target power */
144 u8 tx_power_max_rate_ind[4];
145 /* User limit */
146 u8 user_limit[WL_TX_POWER_RATES];
147 /* Regulatory power limit */
148 u8 reg_limit[WL_TX_POWER_RATES];
149 /* Max power board can support (SROM) */
150 u8 board_limit[WL_TX_POWER_RATES];
151 /* Latest target power */
152 u8 target[WL_TX_POWER_RATES];
153};
154
155struct tx_inst_power {
156 u8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */
157 u8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */
158};
159
160struct brcms_chanvec {
161 u8 vec[MAXCHANNEL / NBBY];
162};
163
164struct shared_phy_params {
165 struct si_pub *sih;
166 struct phy_shim_info *physhim;
167 uint unit;
168 uint corerev;
169 uint buscorerev;
170 u16 vid;
171 u16 did;
172 uint chip;
173 uint chiprev;
174 uint chippkg;
175 uint sromrev;
176 uint boardtype;
177 uint boardrev;
178 uint boardvendor;
179 u32 boardflags;
180 u32 boardflags2;
181};
182
183
184extern struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp);
185extern struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh,
186 struct d11regs __iomem *regs,
187 int bandtype, struct wiphy *wiphy);
188extern void wlc_phy_detach(struct brcms_phy_pub *ppi);
189
190extern bool wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype,
191 u16 *phyrev, u16 *radioid,
192 u16 *radiover);
193extern bool wlc_phy_get_encore(struct brcms_phy_pub *pih);
194extern u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih);
195
196extern void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *ppi, bool newstate);
197extern void wlc_phy_hw_state_upd(struct brcms_phy_pub *ppi, bool newstate);
198extern void wlc_phy_init(struct brcms_phy_pub *ppi, u16 chanspec);
199extern void wlc_phy_watchdog(struct brcms_phy_pub *ppi);
200extern int wlc_phy_down(struct brcms_phy_pub *ppi);
201extern u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih);
202extern void wlc_phy_cal_init(struct brcms_phy_pub *ppi);
203extern void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init);
204
205extern void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi,
206 u16 chanspec);
207extern u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi);
208extern void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi,
209 u16 newch);
210extern u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi);
211extern void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw);
212
213extern int wlc_phy_rssi_compute(struct brcms_phy_pub *pih,
214 struct d11rxhdr *rxh);
215extern void wlc_phy_por_inform(struct brcms_phy_pub *ppi);
216extern void wlc_phy_noise_sample_intr(struct brcms_phy_pub *ppi);
217extern bool wlc_phy_bist_check_phy(struct brcms_phy_pub *ppi);
218
219extern void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag);
220
221extern void wlc_phy_switch_radio(struct brcms_phy_pub *ppi, bool on);
222extern void wlc_phy_anacore(struct brcms_phy_pub *ppi, bool on);
223
224
225extern void wlc_phy_BSSinit(struct brcms_phy_pub *ppi, bool bonlyap, int rssi);
226
227extern void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
228 bool wide_filter);
229extern void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
230 struct brcms_chanvec *channels);
231extern u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi,
232 uint band);
233
234extern void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan,
235 u8 *_min_, u8 *_max_, int rate);
236extern void wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi,
237 uint chan, u8 *_max_, u8 *_min_);
238extern void wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi,
239 uint band, s32 *, s32 *, u32 *);
240extern void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi,
241 struct txpwr_limits *,
242 u16 chanspec);
243extern int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm,
244 bool *override);
245extern int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm,
246 bool override);
247extern void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
248 struct txpwr_limits *);
249extern bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi);
250extern void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi,
251 bool hwpwrctrl);
252extern u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi);
253extern u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi);
254extern bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *pih);
255
256extern void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain,
257 u8 rxchain);
258extern void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain,
259 u8 rxchain);
260extern void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain,
261 u8 *rxchain);
262extern u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih);
263extern s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih,
264 u16 chanspec);
265extern void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val);
266
267extern void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason);
268extern void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *ppi);
269extern void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock);
270extern void wlc_phy_cal_papd_recal(struct brcms_phy_pub *ppi);
271
272extern void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val);
273extern void wlc_phy_clear_tssi(struct brcms_phy_pub *ppi);
274extern void wlc_phy_hold_upd(struct brcms_phy_pub *ppi, u32 id, bool val);
275extern void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, u32 flags);
276
277extern void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type);
278
279extern void wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi,
280 struct tx_power *power, uint channel);
281
282extern void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal);
283extern bool wlc_phy_test_ison(struct brcms_phy_pub *ppi);
284extern void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi,
285 u8 txpwr_percent);
286extern void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war);
287extern void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih,
288 bool bf_preempt);
289extern void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap);
290
291extern void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end);
292
293extern void wlc_phy_freqtrack_start(struct brcms_phy_pub *ppi);
294extern void wlc_phy_freqtrack_end(struct brcms_phy_pub *ppi);
295
296extern const u8 *wlc_phy_get_ofdm_rate_lookup(void);
297
298extern s8 wlc_phy_get_tx_power_offset_by_mcs(struct brcms_phy_pub *ppi,
299 u8 mcs_offset);
300extern s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset);
301#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 000000000000..bea85241a244
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
@@ -0,0 +1,1169 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_PHY_INT_H_
18#define _BRCM_PHY_INT_H_
19
20#include <types.h>
21#include <brcmu_utils.h>
22#include <brcmu_wifi.h>
23
24#define PHY_VERSION { 1, 82, 8, 0 }
25
26#define LCNXN_BASEREV 16
27
28struct phy_shim_info;
29
30struct brcms_phy_srom_fem {
31 /* TSSI positive slope, 1: positive, 0: negative */
32 u8 tssipos;
33 /* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */
34 u8 extpagain;
35 /* support 32 combinations of different Pdet dynamic ranges */
36 u8 pdetrange;
37 /* TR switch isolation */
38 u8 triso;
39 /* antswctrl lookup table configuration: 32 possible choices */
40 u8 antswctrllut;
41};
42
43#define ISNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_N)
44#define ISLCNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_LCN)
45
46#define PHY_GET_RFATTN(rfgain) ((rfgain) & 0x0f)
47#define PHY_GET_PADMIX(rfgain) (((rfgain) & 0x10) >> 4)
48#define PHY_GET_RFGAINID(rfattn, padmix, width) ((rfattn) + ((padmix)*(width)))
49#define PHY_SAT(x, n) ((x) > ((1<<((n)-1))-1) ? ((1<<((n)-1))-1) : \
50 ((x) < -(1<<((n)-1)) ? -(1<<((n)-1)) : (x)))
51#define PHY_SHIFT_ROUND(x, n) ((x) >= 0 ? ((x)+(1<<((n)-1)))>>(n) : (x)>>(n))
52#define PHY_HW_ROUND(x, s) ((x >> s) + ((x >> (s-1)) & (s != 0)))
53
54#define CH_5G_GROUP 3
55#define A_LOW_CHANS 0
56#define A_MID_CHANS 1
57#define A_HIGH_CHANS 2
58#define CH_2G_GROUP 1
59#define G_ALL_CHANS 0
60
61#define FIRST_REF5_CHANNUM 149
62#define LAST_REF5_CHANNUM 165
63#define FIRST_5G_CHAN 14
64#define LAST_5G_CHAN 50
65#define FIRST_MID_5G_CHAN 14
66#define LAST_MID_5G_CHAN 35
67#define FIRST_HIGH_5G_CHAN 36
68#define LAST_HIGH_5G_CHAN 41
69#define FIRST_LOW_5G_CHAN 42
70#define LAST_LOW_5G_CHAN 50
71
72#define BASE_LOW_5G_CHAN 4900
73#define BASE_MID_5G_CHAN 5100
74#define BASE_HIGH_5G_CHAN 5500
75
76#define CHAN5G_FREQ(chan) (5000 + chan*5)
77#define CHAN2G_FREQ(chan) (2407 + chan*5)
78
79#define TXP_FIRST_CCK 0
80#define TXP_LAST_CCK 3
81#define TXP_FIRST_OFDM 4
82#define TXP_LAST_OFDM 11
83#define TXP_FIRST_OFDM_20_CDD 12
84#define TXP_LAST_OFDM_20_CDD 19
85#define TXP_FIRST_MCS_20_SISO 20
86#define TXP_LAST_MCS_20_SISO 27
87#define TXP_FIRST_MCS_20_CDD 28
88#define TXP_LAST_MCS_20_CDD 35
89#define TXP_FIRST_MCS_20_STBC 36
90#define TXP_LAST_MCS_20_STBC 43
91#define TXP_FIRST_MCS_20_SDM 44
92#define TXP_LAST_MCS_20_SDM 51
93#define TXP_FIRST_OFDM_40_SISO 52
94#define TXP_LAST_OFDM_40_SISO 59
95#define TXP_FIRST_OFDM_40_CDD 60
96#define TXP_LAST_OFDM_40_CDD 67
97#define TXP_FIRST_MCS_40_SISO 68
98#define TXP_LAST_MCS_40_SISO 75
99#define TXP_FIRST_MCS_40_CDD 76
100#define TXP_LAST_MCS_40_CDD 83
101#define TXP_FIRST_MCS_40_STBC 84
102#define TXP_LAST_MCS_40_STBC 91
103#define TXP_FIRST_MCS_40_SDM 92
104#define TXP_LAST_MCS_40_SDM 99
105#define TXP_MCS_32 100
106#define TXP_NUM_RATES 101
107#define ADJ_PWR_TBL_LEN 84
108
109#define TXP_FIRST_SISO_MCS_20 20
110#define TXP_LAST_SISO_MCS_20 27
111
112#define PHY_CORE_NUM_1 1
113#define PHY_CORE_NUM_2 2
114#define PHY_CORE_NUM_3 3
115#define PHY_CORE_NUM_4 4
116#define PHY_CORE_MAX PHY_CORE_NUM_4
117#define PHY_CORE_0 0
118#define PHY_CORE_1 1
119#define PHY_CORE_2 2
120#define PHY_CORE_3 3
121
122#define MA_WINDOW_SZ 8
123
124#define PHY_NOISE_SAMPLE_MON 1
125#define PHY_NOISE_SAMPLE_EXTERNAL 2
126#define PHY_NOISE_WINDOW_SZ 16
127#define PHY_NOISE_GLITCH_INIT_MA 10
128#define PHY_NOISE_GLITCH_INIT_MA_BADPlCP 10
129#define PHY_NOISE_STATE_MON 0x1
130#define PHY_NOISE_STATE_EXTERNAL 0x2
131#define PHY_NOISE_SAMPLE_LOG_NUM_NPHY 10
132#define PHY_NOISE_SAMPLE_LOG_NUM_UCODE 9
133
134#define PHY_NOISE_OFFSETFACT_4322 (-103)
135#define PHY_NOISE_MA_WINDOW_SZ 2
136
137#define PHY_RSSI_TABLE_SIZE 64
138#define RSSI_ANT_MERGE_MAX 0
139#define RSSI_ANT_MERGE_MIN 1
140#define RSSI_ANT_MERGE_AVG 2
141
142#define PHY_TSSI_TABLE_SIZE 64
143#define APHY_TSSI_TABLE_SIZE 256
144#define TX_GAIN_TABLE_LENGTH 64
145#define DEFAULT_11A_TXP_IDX 24
146#define NUM_TSSI_FRAMES 4
147#define NULL_TSSI 0x7f
148#define NULL_TSSI_W 0x7f7f
149
150#define PHY_PAPD_EPS_TBL_SIZE_LCNPHY 64
151
152#define LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL 9
153
154#define PHY_TXPWR_MIN 10
155#define PHY_TXPWR_MIN_NPHY 8
156#define RADIOPWR_OVERRIDE_DEF (-1)
157
158#define PWRTBL_NUM_COEFF 3
159
160#define SPURAVOID_DISABLE 0
161#define SPURAVOID_AUTO 1
162#define SPURAVOID_FORCEON 2
163#define SPURAVOID_FORCEON2 3
164
165#define PHY_SW_TIMER_FAST 15
166#define PHY_SW_TIMER_SLOW 60
167#define PHY_SW_TIMER_GLACIAL 120
168
169#define PHY_PERICAL_AUTO 0
170#define PHY_PERICAL_FULL 1
171#define PHY_PERICAL_PARTIAL 2
172
173#define PHY_PERICAL_NODELAY 0
174#define PHY_PERICAL_INIT_DELAY 5
175#define PHY_PERICAL_ASSOC_DELAY 5
176#define PHY_PERICAL_WDOG_DELAY 5
177
178#define MPHASE_TXCAL_NUMCMDS 2
179
180#define PHY_PERICAL_MPHASE_PENDING(pi) \
181 (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_IDLE)
182
183enum {
184 MPHASE_CAL_STATE_IDLE = 0,
185 MPHASE_CAL_STATE_INIT = 1,
186 MPHASE_CAL_STATE_TXPHASE0,
187 MPHASE_CAL_STATE_TXPHASE1,
188 MPHASE_CAL_STATE_TXPHASE2,
189 MPHASE_CAL_STATE_TXPHASE3,
190 MPHASE_CAL_STATE_TXPHASE4,
191 MPHASE_CAL_STATE_TXPHASE5,
192 MPHASE_CAL_STATE_PAPDCAL,
193 MPHASE_CAL_STATE_RXCAL,
194 MPHASE_CAL_STATE_RSSICAL,
195 MPHASE_CAL_STATE_IDLETSSI
196};
197
198enum phy_cal_mode {
199 CAL_FULL,
200 CAL_RECAL,
201 CAL_CURRECAL,
202 CAL_DIGCAL,
203 CAL_GCTRL,
204 CAL_SOFT,
205 CAL_DIGLO
206};
207
208#define RDR_NTIERS 1
209#define RDR_TIER_SIZE 64
210#define RDR_LIST_SIZE (512/3)
211#define RDR_EPOCH_SIZE 40
212#define RDR_NANTENNAS 2
213#define RDR_NTIER_SIZE RDR_LIST_SIZE
214#define RDR_LP_BUFFER_SIZE 64
215#define LP_LEN_HIS_SIZE 10
216
217#define STATIC_NUM_RF 32
218#define STATIC_NUM_BB 9
219
220#define BB_MULT_MASK 0x0000ffff
221#define BB_MULT_VALID_MASK 0x80000000
222
223#define CORDIC_AG 39797
224#define CORDIC_NI 18
225#define FIXED(X) ((s32)((X) << 16))
226
227#define FLOAT(X) \
228 (((X) >= 0) ? ((((X) >> 15) + 1) >> 1) : -((((-(X)) >> 15) + 1) >> 1))
229
230#define PHY_CHAIN_TX_DISABLE_TEMP 115
231#define PHY_HYSTERESIS_DELTATEMP 5
232
233#define SCAN_INPROG_PHY(pi) \
234 (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN))
235
236#define PLT_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_PLT))
237
238#define ASSOC_INPROG_PHY(pi) \
239 (mboolisset(pi->measure_hold, PHY_HOLD_FOR_ASSOC))
240
241#define SCAN_RM_IN_PROGRESS(pi) \
242 (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN | PHY_HOLD_FOR_RM))
243
244#define PHY_MUTED(pi) \
245 (mboolisset(pi->measure_hold, PHY_HOLD_FOR_MUTE))
246
247#define PUB_NOT_ASSOC(pi) \
248 (mboolisset(pi->measure_hold, PHY_HOLD_FOR_NOT_ASSOC))
249
250struct phy_table_info {
251 uint table;
252 int q;
253 uint max;
254};
255
256struct phytbl_info {
257 const void *tbl_ptr;
258 u32 tbl_len;
259 u32 tbl_id;
260 u32 tbl_offset;
261 u32 tbl_width;
262};
263
264struct interference_info {
265 u8 curr_home_channel;
266 u16 crsminpwrthld_40_stored;
267 u16 crsminpwrthld_20L_stored;
268 u16 crsminpwrthld_20U_stored;
269 u16 init_gain_code_core1_stored;
270 u16 init_gain_code_core2_stored;
271 u16 init_gain_codeb_core1_stored;
272 u16 init_gain_codeb_core2_stored;
273 u16 init_gain_table_stored[4];
274
275 u16 clip1_hi_gain_code_core1_stored;
276 u16 clip1_hi_gain_code_core2_stored;
277 u16 clip1_hi_gain_codeb_core1_stored;
278 u16 clip1_hi_gain_codeb_core2_stored;
279 u16 nb_clip_thresh_core1_stored;
280 u16 nb_clip_thresh_core2_stored;
281 u16 init_ofdmlna2gainchange_stored[4];
282 u16 init_ccklna2gainchange_stored[4];
283 u16 clip1_lo_gain_code_core1_stored;
284 u16 clip1_lo_gain_code_core2_stored;
285 u16 clip1_lo_gain_codeb_core1_stored;
286 u16 clip1_lo_gain_codeb_core2_stored;
287 u16 w1_clip_thresh_core1_stored;
288 u16 w1_clip_thresh_core2_stored;
289 u16 radio_2056_core1_rssi_gain_stored;
290 u16 radio_2056_core2_rssi_gain_stored;
291 u16 energy_drop_timeout_len_stored;
292
293 u16 ed_crs40_assertthld0_stored;
294 u16 ed_crs40_assertthld1_stored;
295 u16 ed_crs40_deassertthld0_stored;
296 u16 ed_crs40_deassertthld1_stored;
297 u16 ed_crs20L_assertthld0_stored;
298 u16 ed_crs20L_assertthld1_stored;
299 u16 ed_crs20L_deassertthld0_stored;
300 u16 ed_crs20L_deassertthld1_stored;
301 u16 ed_crs20U_assertthld0_stored;
302 u16 ed_crs20U_assertthld1_stored;
303 u16 ed_crs20U_deassertthld0_stored;
304 u16 ed_crs20U_deassertthld1_stored;
305
306 u16 badplcp_ma;
307 u16 badplcp_ma_previous;
308 u16 badplcp_ma_total;
309 u16 badplcp_ma_list[MA_WINDOW_SZ];
310 int badplcp_ma_index;
311 s16 pre_badplcp_cnt;
312 s16 bphy_pre_badplcp_cnt;
313
314 u16 init_gain_core1;
315 u16 init_gain_core2;
316 u16 init_gainb_core1;
317 u16 init_gainb_core2;
318 u16 init_gain_rfseq[4];
319
320 u16 crsminpwr0;
321 u16 crsminpwrl0;
322 u16 crsminpwru0;
323
324 s16 crsminpwr_index;
325
326 u16 radio_2057_core1_rssi_wb1a_gc_stored;
327 u16 radio_2057_core2_rssi_wb1a_gc_stored;
328 u16 radio_2057_core1_rssi_wb1g_gc_stored;
329 u16 radio_2057_core2_rssi_wb1g_gc_stored;
330 u16 radio_2057_core1_rssi_wb2_gc_stored;
331 u16 radio_2057_core2_rssi_wb2_gc_stored;
332 u16 radio_2057_core1_rssi_nb_gc_stored;
333 u16 radio_2057_core2_rssi_nb_gc_stored;
334};
335
336struct aci_save_gphy {
337 u16 rc_cal_ovr;
338 u16 phycrsth1;
339 u16 phycrsth2;
340 u16 init_n1p1_gain;
341 u16 p1_p2_gain;
342 u16 n1_n2_gain;
343 u16 n1_p1_gain;
344 u16 div_search_gain;
345 u16 div_p1_p2_gain;
346 u16 div_search_gn_change;
347 u16 table_7_2;
348 u16 table_7_3;
349 u16 cckshbits_gnref;
350 u16 clip_thresh;
351 u16 clip2_thresh;
352 u16 clip3_thresh;
353 u16 clip_p2_thresh;
354 u16 clip_pwdn_thresh;
355 u16 clip_n1p1_thresh;
356 u16 clip_n1_pwdn_thresh;
357 u16 bbconfig;
358 u16 cthr_sthr_shdin;
359 u16 energy;
360 u16 clip_p1_p2_thresh;
361 u16 threshold;
362 u16 reg15;
363 u16 reg16;
364 u16 reg17;
365 u16 div_srch_idx;
366 u16 div_srch_p1_p2;
367 u16 div_srch_gn_back;
368 u16 ant_dwell;
369 u16 ant_wr_settle;
370};
371
372struct lo_complex_abgphy_info {
373 s8 i;
374 s8 q;
375};
376
377struct nphy_iq_comp {
378 s16 a0;
379 s16 b0;
380 s16 a1;
381 s16 b1;
382};
383
384struct nphy_txpwrindex {
385 s8 index;
386 s8 index_internal;
387 s8 index_internal_save;
388 u16 AfectrlOverride;
389 u16 AfeCtrlDacGain;
390 u16 rad_gain;
391 u8 bbmult;
392 u16 iqcomp_a;
393 u16 iqcomp_b;
394 u16 locomp;
395};
396
397struct txiqcal_cache {
398
399 u16 txcal_coeffs_2G[8];
400 u16 txcal_radio_regs_2G[8];
401 struct nphy_iq_comp rxcal_coeffs_2G;
402
403 u16 txcal_coeffs_5G[8];
404 u16 txcal_radio_regs_5G[8];
405 struct nphy_iq_comp rxcal_coeffs_5G;
406};
407
408struct nphy_pwrctrl {
409 s8 max_pwr_2g;
410 s8 idle_targ_2g;
411 s16 pwrdet_2g_a1;
412 s16 pwrdet_2g_b0;
413 s16 pwrdet_2g_b1;
414 s8 max_pwr_5gm;
415 s8 idle_targ_5gm;
416 s8 max_pwr_5gh;
417 s8 max_pwr_5gl;
418 s16 pwrdet_5gm_a1;
419 s16 pwrdet_5gm_b0;
420 s16 pwrdet_5gm_b1;
421 s16 pwrdet_5gl_a1;
422 s16 pwrdet_5gl_b0;
423 s16 pwrdet_5gl_b1;
424 s16 pwrdet_5gh_a1;
425 s16 pwrdet_5gh_b0;
426 s16 pwrdet_5gh_b1;
427 s8 idle_targ_5gl;
428 s8 idle_targ_5gh;
429 s8 idle_tssi_2g;
430 s8 idle_tssi_5g;
431 s8 idle_tssi;
432 s16 a1;
433 s16 b0;
434 s16 b1;
435};
436
437struct nphy_txgains {
438 u16 txlpf[2];
439 u16 txgm[2];
440 u16 pga[2];
441 u16 pad[2];
442 u16 ipa[2];
443};
444
445#define PHY_NOISEVAR_BUFSIZE 10
446
447struct nphy_noisevar_buf {
448 int bufcount;
449 int tone_id[PHY_NOISEVAR_BUFSIZE];
450 u32 noise_vars[PHY_NOISEVAR_BUFSIZE];
451 u32 min_noise_vars[PHY_NOISEVAR_BUFSIZE];
452};
453
454struct rssical_cache {
455 u16 rssical_radio_regs_2G[2];
456 u16 rssical_phyregs_2G[12];
457
458 u16 rssical_radio_regs_5G[2];
459 u16 rssical_phyregs_5G[12];
460};
461
462struct lcnphy_cal_results {
463
464 u16 txiqlocal_a;
465 u16 txiqlocal_b;
466 u16 txiqlocal_didq;
467 u8 txiqlocal_ei0;
468 u8 txiqlocal_eq0;
469 u8 txiqlocal_fi0;
470 u8 txiqlocal_fq0;
471
472 u16 txiqlocal_bestcoeffs[11];
473 u16 txiqlocal_bestcoeffs_valid;
474
475 u32 papd_eps_tbl[PHY_PAPD_EPS_TBL_SIZE_LCNPHY];
476 u16 analog_gain_ref;
477 u16 lut_begin;
478 u16 lut_end;
479 u16 lut_step;
480 u16 rxcompdbm;
481 u16 papdctrl;
482 u16 sslpnCalibClkEnCtrl;
483
484 u16 rxiqcal_coeff_a0;
485 u16 rxiqcal_coeff_b0;
486};
487
488struct shared_phy {
489 struct brcms_phy *phy_head;
490 uint unit;
491 struct si_pub *sih;
492 struct phy_shim_info *physhim;
493 uint corerev;
494 u32 machwcap;
495 bool up;
496 bool clk;
497 uint now;
498 u16 vid;
499 u16 did;
500 uint chip;
501 uint chiprev;
502 uint chippkg;
503 uint sromrev;
504 uint boardtype;
505 uint boardrev;
506 uint boardvendor;
507 u32 boardflags;
508 u32 boardflags2;
509 uint buscorerev;
510 uint fast_timer;
511 uint slow_timer;
512 uint glacial_timer;
513 u8 rx_antdiv;
514 s8 phy_noise_window[MA_WINDOW_SZ];
515 uint phy_noise_index;
516 u8 hw_phytxchain;
517 u8 hw_phyrxchain;
518 u8 phytxchain;
519 u8 phyrxchain;
520 u8 rssi_mode;
521 bool _rifs_phy;
522};
523
524struct brcms_phy_pub {
525 uint phy_type;
526 uint phy_rev;
527 u8 phy_corenum;
528 u16 radioid;
529 u8 radiorev;
530 u8 radiover;
531
532 uint coreflags;
533 uint ana_rev;
534 bool abgphy_encore;
535};
536
537struct phy_func_ptr {
538 void (*init)(struct brcms_phy *);
539 void (*calinit)(struct brcms_phy *);
540 void (*chanset)(struct brcms_phy *, u16 chanspec);
541 void (*txpwrrecalc)(struct brcms_phy *);
542 int (*longtrn)(struct brcms_phy *, int);
543 void (*txiqccget)(struct brcms_phy *, u16 *, u16 *);
544 void (*txiqccset)(struct brcms_phy *, u16, u16);
545 u16 (*txloccget)(struct brcms_phy *);
546 void (*radioloftget)(struct brcms_phy *, u8 *, u8 *, u8 *, u8 *);
547 void (*carrsuppr)(struct brcms_phy *);
548 s32 (*rxsigpwr)(struct brcms_phy *, s32);
549 void (*detach)(struct brcms_phy *);
550};
551
552struct brcms_phy {
553 struct brcms_phy_pub pubpi_ro;
554 struct shared_phy *sh;
555 struct phy_func_ptr pi_fptr;
556
557 union {
558 struct brcms_phy_lcnphy *pi_lcnphy;
559 } u;
560 bool user_txpwr_at_rfport;
561
562 struct d11regs __iomem *regs;
563 struct brcms_phy *next;
564 struct brcms_phy_pub pubpi;
565
566 bool do_initcal;
567 bool phytest_on;
568 bool ofdm_rateset_war;
569 bool bf_preempt_4306;
570 u16 radio_chanspec;
571 u8 antsel_type;
572 u16 bw;
573 u8 txpwr_percent;
574 bool phy_init_por;
575
576 bool init_in_progress;
577 bool initialized;
578 bool sbtml_gm;
579 uint refcnt;
580 bool watchdog_override;
581 u8 phynoise_state;
582 uint phynoise_now;
583 int phynoise_chan_watchdog;
584 bool phynoise_polling;
585 bool disable_percal;
586 u32 measure_hold;
587
588 s16 txpa_2g[PWRTBL_NUM_COEFF];
589 s16 txpa_2g_low_temp[PWRTBL_NUM_COEFF];
590 s16 txpa_2g_high_temp[PWRTBL_NUM_COEFF];
591 s16 txpa_5g_low[PWRTBL_NUM_COEFF];
592 s16 txpa_5g_mid[PWRTBL_NUM_COEFF];
593 s16 txpa_5g_hi[PWRTBL_NUM_COEFF];
594
595 u8 tx_srom_max_2g;
596 u8 tx_srom_max_5g_low;
597 u8 tx_srom_max_5g_mid;
598 u8 tx_srom_max_5g_hi;
599 u8 tx_srom_max_rate_2g[TXP_NUM_RATES];
600 u8 tx_srom_max_rate_5g_low[TXP_NUM_RATES];
601 u8 tx_srom_max_rate_5g_mid[TXP_NUM_RATES];
602 u8 tx_srom_max_rate_5g_hi[TXP_NUM_RATES];
603 u8 tx_user_target[TXP_NUM_RATES];
604 s8 tx_power_offset[TXP_NUM_RATES];
605 u8 tx_power_target[TXP_NUM_RATES];
606
607 struct brcms_phy_srom_fem srom_fem2g;
608 struct brcms_phy_srom_fem srom_fem5g;
609
610 u8 tx_power_max;
611 u8 tx_power_max_rate_ind;
612 bool hwpwrctrl;
613 u8 nphy_txpwrctrl;
614 s8 nphy_txrx_chain;
615 bool phy_5g_pwrgain;
616
617 u16 phy_wreg;
618 u16 phy_wreg_limit;
619
620 s8 n_preamble_override;
621 u8 antswitch;
622 u8 aa2g, aa5g;
623
624 s8 idle_tssi[CH_5G_GROUP];
625 s8 target_idle_tssi;
626 s8 txpwr_est_Pout;
627 u8 tx_power_min;
628 u8 txpwr_limit[TXP_NUM_RATES];
629 u8 txpwr_env_limit[TXP_NUM_RATES];
630 u8 adj_pwr_tbl_nphy[ADJ_PWR_TBL_LEN];
631
632 bool channel_14_wide_filter;
633
634 bool txpwroverride;
635 bool txpwridx_override_aphy;
636 s16 radiopwr_override;
637 u16 hwpwr_txcur;
638 u8 saved_txpwr_idx;
639
640 bool edcrs_threshold_lock;
641
642 u32 tr_R_gain_val;
643 u32 tr_T_gain_val;
644
645 s16 ofdm_analog_filt_bw_override;
646 s16 cck_analog_filt_bw_override;
647 s16 ofdm_rccal_override;
648 s16 cck_rccal_override;
649 u16 extlna_type;
650
651 uint interference_mode_crs_time;
652 u16 crsglitch_prev;
653 bool interference_mode_crs;
654
655 u32 phy_tx_tone_freq;
656 uint phy_lastcal;
657 bool phy_forcecal;
658 bool phy_fixed_noise;
659 u32 xtalfreq;
660 u8 pdiv;
661 s8 carrier_suppr_disable;
662
663 bool phy_bphy_evm;
664 bool phy_bphy_rfcs;
665 s8 phy_scraminit;
666 u8 phy_gpiosel;
667
668 s16 phy_txcore_disable_temp;
669 s16 phy_txcore_enable_temp;
670 s8 phy_tempsense_offset;
671 bool phy_txcore_heatedup;
672
673 u16 radiopwr;
674 u16 bb_atten;
675 u16 txctl1;
676
677 u16 mintxbias;
678 u16 mintxmag;
679 struct lo_complex_abgphy_info gphy_locomp_iq
680 [STATIC_NUM_RF][STATIC_NUM_BB];
681 s8 stats_11b_txpower[STATIC_NUM_RF][STATIC_NUM_BB];
682 u16 gain_table[TX_GAIN_TABLE_LENGTH];
683 bool loopback_gain;
684 s16 max_lpback_gain_hdB;
685 s16 trsw_rx_gain_hdB;
686 u8 power_vec[8];
687
688 u16 rc_cal;
689 int nrssi_table_delta;
690 int nrssi_slope_scale;
691 int nrssi_slope_offset;
692 int min_rssi;
693 int max_rssi;
694
695 s8 txpwridx;
696 u8 min_txpower;
697
698 u8 a_band_high_disable;
699
700 u16 tx_vos;
701 u16 global_tx_bb_dc_bias_loft;
702
703 int rf_max;
704 int bb_max;
705 int rf_list_size;
706 int bb_list_size;
707 u16 *rf_attn_list;
708 u16 *bb_attn_list;
709 u16 padmix_mask;
710 u16 padmix_reg;
711 u16 *txmag_list;
712 uint txmag_len;
713 bool txmag_enable;
714
715 s8 *a_tssi_to_dbm;
716 s8 *m_tssi_to_dbm;
717 s8 *l_tssi_to_dbm;
718 s8 *h_tssi_to_dbm;
719 u8 *hwtxpwr;
720
721 u16 freqtrack_saved_regs[2];
722 int cur_interference_mode;
723 bool hwpwrctrl_capable;
724 bool temppwrctrl_capable;
725
726 uint phycal_nslope;
727 uint phycal_noffset;
728 uint phycal_mlo;
729 uint phycal_txpower;
730
731 u8 phy_aa2g;
732
733 bool nphy_tableloaded;
734 s8 nphy_rssisel;
735 u32 nphy_bb_mult_save;
736 u16 nphy_txiqlocal_bestc[11];
737 bool nphy_txiqlocal_coeffsvalid;
738 struct nphy_txpwrindex nphy_txpwrindex[PHY_CORE_NUM_2];
739 struct nphy_pwrctrl nphy_pwrctrl_info[PHY_CORE_NUM_2];
740 u16 cck2gpo;
741 u32 ofdm2gpo;
742 u32 ofdm5gpo;
743 u32 ofdm5glpo;
744 u32 ofdm5ghpo;
745 u8 bw402gpo;
746 u8 bw405gpo;
747 u8 bw405glpo;
748 u8 bw405ghpo;
749 u8 cdd2gpo;
750 u8 cdd5gpo;
751 u8 cdd5glpo;
752 u8 cdd5ghpo;
753 u8 stbc2gpo;
754 u8 stbc5gpo;
755 u8 stbc5glpo;
756 u8 stbc5ghpo;
757 u8 bwdup2gpo;
758 u8 bwdup5gpo;
759 u8 bwdup5glpo;
760 u8 bwdup5ghpo;
761 u16 mcs2gpo[8];
762 u16 mcs5gpo[8];
763 u16 mcs5glpo[8];
764 u16 mcs5ghpo[8];
765 u32 nphy_rxcalparams;
766
767 u8 phy_spuravoid;
768 bool phy_isspuravoid;
769
770 u8 phy_pabias;
771 u8 nphy_papd_skip;
772 u8 nphy_tssi_slope;
773
774 s16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ];
775 u8 nphy_noise_index;
776
777 u8 nphy_txpid2g[PHY_CORE_NUM_2];
778 u8 nphy_txpid5g[PHY_CORE_NUM_2];
779 u8 nphy_txpid5gl[PHY_CORE_NUM_2];
780 u8 nphy_txpid5gh[PHY_CORE_NUM_2];
781
782 bool nphy_gain_boost;
783 bool nphy_elna_gain_config;
784 u16 old_bphy_test;
785 u16 old_bphy_testcontrol;
786
787 bool phyhang_avoid;
788
789 bool rssical_nphy;
790 u8 nphy_perical;
791 uint nphy_perical_last;
792 u8 cal_type_override;
793 u8 mphase_cal_phase_id;
794 u8 mphase_txcal_cmdidx;
795 u8 mphase_txcal_numcmds;
796 u16 mphase_txcal_bestcoeffs[11];
797 u16 nphy_txiqlocal_chanspec;
798 u16 nphy_iqcal_chanspec_2G;
799 u16 nphy_iqcal_chanspec_5G;
800 u16 nphy_rssical_chanspec_2G;
801 u16 nphy_rssical_chanspec_5G;
802 struct wlapi_timer *phycal_timer;
803 bool use_int_tx_iqlo_cal_nphy;
804 bool internal_tx_iqlo_cal_tapoff_intpa_nphy;
805 s16 nphy_lastcal_temp;
806
807 struct txiqcal_cache calibration_cache;
808 struct rssical_cache rssical_cache;
809
810 u8 nphy_txpwr_idx[2];
811 u8 nphy_papd_cal_type;
812 uint nphy_papd_last_cal;
813 u16 nphy_papd_tx_gain_at_last_cal[2];
814 u8 nphy_papd_cal_gain_index[2];
815 s16 nphy_papd_epsilon_offset[2];
816 bool nphy_papd_recal_enable;
817 u32 nphy_papd_recal_counter;
818 bool nphy_force_papd_cal;
819 bool nphy_papdcomp;
820 bool ipa2g_on;
821 bool ipa5g_on;
822
823 u16 classifier_state;
824 u16 clip_state[2];
825 uint nphy_deaf_count;
826 u8 rxiq_samps;
827 u8 rxiq_antsel;
828
829 u16 rfctrlIntc1_save;
830 u16 rfctrlIntc2_save;
831 bool first_cal_after_assoc;
832 u16 tx_rx_cal_radio_saveregs[22];
833 u16 tx_rx_cal_phy_saveregs[15];
834
835 u8 nphy_cal_orig_pwr_idx[2];
836 u8 nphy_txcal_pwr_idx[2];
837 u8 nphy_rxcal_pwr_idx[2];
838 u16 nphy_cal_orig_tx_gain[2];
839 struct nphy_txgains nphy_cal_target_gain;
840 u16 nphy_txcal_bbmult;
841 u16 nphy_gmval;
842
843 u16 nphy_saved_bbconf;
844
845 bool nphy_gband_spurwar_en;
846 bool nphy_gband_spurwar2_en;
847 bool nphy_aband_spurwar_en;
848 u16 nphy_rccal_value;
849 u16 nphy_crsminpwr[3];
850 struct nphy_noisevar_buf nphy_saved_noisevars;
851 bool nphy_anarxlpf_adjusted;
852 bool nphy_crsminpwr_adjusted;
853 bool nphy_noisevars_adjusted;
854
855 bool nphy_rxcal_active;
856 u16 radar_percal_mask;
857 bool dfs_lp_buffer_nphy;
858
859 u16 nphy_fineclockgatecontrol;
860
861 s8 rx2tx_biasentry;
862
863 u16 crsminpwr0;
864 u16 crsminpwrl0;
865 u16 crsminpwru0;
866 s16 noise_crsminpwr_index;
867 u16 init_gain_core1;
868 u16 init_gain_core2;
869 u16 init_gainb_core1;
870 u16 init_gainb_core2;
871 u8 aci_noise_curr_channel;
872 u16 init_gain_rfseq[4];
873
874 bool radio_is_on;
875
876 bool nphy_sample_play_lpf_bw_ctl_ovr;
877
878 u16 tbl_data_hi;
879 u16 tbl_data_lo;
880 u16 tbl_addr;
881
882 uint tbl_save_id;
883 uint tbl_save_offset;
884
885 u8 txpwrctrl;
886 s8 txpwrindex[PHY_CORE_MAX];
887
888 u8 phycal_tempdelta;
889 u32 mcs20_po;
890 u32 mcs40_po;
891 struct wiphy *wiphy;
892};
893
894struct cs32 {
895 s32 q;
896 s32 i;
897};
898
899struct radio_regs {
900 u16 address;
901 u32 init_a;
902 u32 init_g;
903 u8 do_init_a;
904 u8 do_init_g;
905};
906
907struct radio_20xx_regs {
908 u16 address;
909 u8 init;
910 u8 do_init;
911};
912
913struct lcnphy_radio_regs {
914 u16 address;
915 u8 init_a;
916 u8 init_g;
917 u8 do_init_a;
918 u8 do_init_g;
919};
920
921extern u16 read_phy_reg(struct brcms_phy *pi, u16 addr);
922extern void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
923extern void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
924extern void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
925extern void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val);
926
927extern u16 read_radio_reg(struct brcms_phy *pi, u16 addr);
928extern void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
929extern void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
930extern void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask,
931 u16 val);
932extern void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask);
933
934extern void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
935
936extern void wlc_phyreg_enter(struct brcms_phy_pub *pih);
937extern void wlc_phyreg_exit(struct brcms_phy_pub *pih);
938extern void wlc_radioreg_enter(struct brcms_phy_pub *pih);
939extern void wlc_radioreg_exit(struct brcms_phy_pub *pih);
940
941extern void wlc_phy_read_table(struct brcms_phy *pi,
942 const struct phytbl_info *ptbl_info,
943 u16 tblAddr, u16 tblDataHi,
944 u16 tblDatalo);
945extern void wlc_phy_write_table(struct brcms_phy *pi,
946 const struct phytbl_info *ptbl_info,
947 u16 tblAddr, u16 tblDataHi, u16 tblDatalo);
948extern void wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id,
949 uint tbl_offset, u16 tblAddr, u16 tblDataHi,
950 u16 tblDataLo);
951extern void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val);
952
953extern void write_phy_channel_reg(struct brcms_phy *pi, uint val);
954extern void wlc_phy_txpower_update_shm(struct brcms_phy *pi);
955
956extern u8 wlc_phy_nbits(s32 value);
957extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core);
958
959extern uint wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi,
960 struct radio_20xx_regs *radioregs);
961extern uint wlc_phy_init_radio_regs(struct brcms_phy *pi,
962 const struct radio_regs *radioregs,
963 u16 core_offset);
964
965extern void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi);
966
967extern void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on);
968extern void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real,
969 s32 *eps_imag);
970
971extern void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi);
972extern void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi);
973
974extern bool wlc_phy_attach_nphy(struct brcms_phy *pi);
975extern bool wlc_phy_attach_lcnphy(struct brcms_phy *pi);
976
977extern void wlc_phy_detach_lcnphy(struct brcms_phy *pi);
978
979extern void wlc_phy_init_nphy(struct brcms_phy *pi);
980extern void wlc_phy_init_lcnphy(struct brcms_phy *pi);
981
982extern void wlc_phy_cal_init_nphy(struct brcms_phy *pi);
983extern void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi);
984
985extern void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi,
986 u16 chanspec);
987extern void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi,
988 u16 chanspec);
989extern void wlc_phy_chanspec_set_fixup_lcnphy(struct brcms_phy *pi,
990 u16 chanspec);
991extern int wlc_phy_channel2freq(uint channel);
992extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint);
993extern int wlc_phy_chanspec_bandrange_get(struct brcms_phy *, u16 chanspec);
994
995extern void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode);
996extern s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi);
997
998extern void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi);
999extern void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi);
1000extern void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi);
1001
1002extern void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index);
1003extern void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable);
1004extern void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi);
1005extern void wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz,
1006 u16 max_val, bool iqcalmode);
1007
1008extern void wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan,
1009 u8 *max_pwr, u8 rate_id);
1010extern void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
1011 u8 rate_mcs_end,
1012 u8 rate_ofdm_start);
1013extern void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power,
1014 u8 rate_ofdm_start,
1015 u8 rate_ofdm_end,
1016 u8 rate_mcs_start);
1017
1018extern u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode);
1019extern s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode);
1020extern s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode);
1021extern s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode);
1022extern void wlc_phy_carrier_suppress_lcnphy(struct brcms_phy *pi);
1023extern void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel);
1024extern void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode);
1025extern void wlc_2064_vco_cal(struct brcms_phy *pi);
1026
1027extern void wlc_phy_txpower_recalc_target(struct brcms_phy *pi);
1028
1029#define LCNPHY_TBL_ID_PAPDCOMPDELTATBL 0x18
1030#define LCNPHY_TX_POWER_TABLE_SIZE 128
1031#define LCNPHY_MAX_TX_POWER_INDEX (LCNPHY_TX_POWER_TABLE_SIZE - 1)
1032#define LCNPHY_TBL_ID_TXPWRCTL 0x07
1033#define LCNPHY_TX_PWR_CTRL_OFF 0
1034#define LCNPHY_TX_PWR_CTRL_SW (0x1 << 15)
1035#define LCNPHY_TX_PWR_CTRL_HW ((0x1 << 15) | \
1036 (0x1 << 14) | \
1037 (0x1 << 13))
1038
1039#define LCNPHY_TX_PWR_CTRL_TEMPBASED 0xE001
1040
1041extern void wlc_lcnphy_write_table(struct brcms_phy *pi,
1042 const struct phytbl_info *pti);
1043extern void wlc_lcnphy_read_table(struct brcms_phy *pi,
1044 struct phytbl_info *pti);
1045extern void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b);
1046extern void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq);
1047extern void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b);
1048extern u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi);
1049extern void wlc_lcnphy_get_radio_loft(struct brcms_phy *pi, u8 *ei0,
1050 u8 *eq0, u8 *fi0, u8 *fq0);
1051extern void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode);
1052extern void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode);
1053extern bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi);
1054extern void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi);
1055extern s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1);
1056extern void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr,
1057 s8 *cck_pwr);
1058extern void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi);
1059
1060extern s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index);
1061
1062#define NPHY_MAX_HPVGA1_INDEX 10
1063#define NPHY_DEF_HPVGA1_INDEXLIMIT 7
1064
1065struct phy_iq_est {
1066 s32 iq_prod;
1067 u32 i_pwr;
1068 u32 q_pwr;
1069};
1070
1071extern void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi,
1072 bool enable);
1073extern void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode);
1074
1075#define wlc_phy_write_table_nphy(pi, pti) \
1076 wlc_phy_write_table(pi, pti, 0x72, 0x74, 0x73)
1077
1078#define wlc_phy_read_table_nphy(pi, pti) \
1079 wlc_phy_read_table(pi, pti, 0x72, 0x74, 0x73)
1080
1081#define wlc_nphy_table_addr(pi, id, off) \
1082 wlc_phy_table_addr((pi), (id), (off), 0x72, 0x74, 0x73)
1083
1084#define wlc_nphy_table_data_write(pi, w, v) \
1085 wlc_phy_table_data_write((pi), (w), (v))
1086
1087extern void wlc_phy_table_read_nphy(struct brcms_phy *pi, u32, u32 l, u32 o,
1088 u32 w, void *d);
1089extern void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32,
1090 u32, const void *);
1091
1092#define PHY_IPA(pi) \
1093 ((pi->ipa2g_on && CHSPEC_IS2G(pi->radio_chanspec)) || \
1094 (pi->ipa5g_on && CHSPEC_IS5G(pi->radio_chanspec)))
1095
1096#define BRCMS_PHY_WAR_PR51571(pi) \
1097 if (NREV_LT((pi)->pubpi.phy_rev, 3)) \
1098 (void)R_REG(&(pi)->regs->maccontrol)
1099
1100extern void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype);
1101extern void wlc_phy_aci_reset_nphy(struct brcms_phy *pi);
1102extern void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en);
1103
1104extern u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint chan);
1105extern void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on);
1106
1107extern void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi);
1108
1109extern void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd);
1110extern s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi);
1111
1112extern u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val);
1113
1114extern void wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est,
1115 u16 num_samps, u8 wait_time,
1116 u8 wait_for_crs);
1117
1118extern void wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write,
1119 struct nphy_iq_comp *comp);
1120extern void wlc_phy_aci_and_noise_reduction_nphy(struct brcms_phy *pi);
1121
1122extern void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih,
1123 u8 rxcore_bitmask);
1124extern u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih);
1125
1126extern void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type);
1127extern void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi);
1128extern void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi);
1129extern void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi);
1130extern u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi);
1131
1132extern struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi);
1133extern int wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi,
1134 struct nphy_txgains target_gain,
1135 bool full, bool m);
1136extern int wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi,
1137 struct nphy_txgains target_gain,
1138 u8 type, bool d);
1139extern void wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask,
1140 s8 txpwrindex, bool res);
1141extern void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core, u8 rssi_type);
1142extern int wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type,
1143 s32 *rssi_buf, u8 nsamps);
1144extern void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi);
1145extern int wlc_phy_aci_scan_nphy(struct brcms_phy *pi);
1146extern void wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi,
1147 s32 dBm_targetpower, bool debug);
1148extern int wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
1149 u8 mode, u8, bool);
1150extern void wlc_phy_stopplayback_nphy(struct brcms_phy *pi);
1151extern void wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf,
1152 u8 num_samps);
1153extern void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi);
1154
1155extern int wlc_phy_rssi_compute_nphy(struct brcms_phy *pi,
1156 struct d11rxhdr *rxh);
1157
1158#define NPHY_TESTPATTERN_BPHY_EVM 0
1159#define NPHY_TESTPATTERN_BPHY_RFCS 1
1160
1161extern void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs);
1162
1163void wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset,
1164 s8 *ofdmoffset);
1165extern s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi,
1166 u16 chanspec);
1167
1168extern bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pih);
1169#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 000000000000..a63aa99d9810
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -0,0 +1,5154 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/kernel.h>
18#include <linux/delay.h>
19#include <linux/cordic.h>
20
21#include <pmu.h>
22#include <d11.h>
23#include <phy_shim.h>
24#include "phy_qmath.h"
25#include "phy_hal.h"
26#include "phy_radio.h"
27#include "phytbl_lcn.h"
28#include "phy_lcn.h"
29
30#define PLL_2064_NDIV 90
31#define PLL_2064_LOW_END_VCO 3000
32#define PLL_2064_LOW_END_KVCO 27
33#define PLL_2064_HIGH_END_VCO 4200
34#define PLL_2064_HIGH_END_KVCO 68
35#define PLL_2064_LOOP_BW_DOUBLER 200
36#define PLL_2064_D30_DOUBLER 10500
37#define PLL_2064_LOOP_BW 260
38#define PLL_2064_D30 8000
39#define PLL_2064_CAL_REF_TO 8
40#define PLL_2064_MHZ 1000000
41#define PLL_2064_OPEN_LOOP_DELAY 5
42
43#define TEMPSENSE 1
44#define VBATSENSE 2
45
46#define NOISE_IF_UPD_CHK_INTERVAL 1
47#define NOISE_IF_UPD_RST_INTERVAL 60
48#define NOISE_IF_UPD_THRESHOLD_CNT 1
49#define NOISE_IF_UPD_TRHRESHOLD 50
50#define NOISE_IF_UPD_TIMEOUT 1000
51#define NOISE_IF_OFF 0
52#define NOISE_IF_CHK 1
53#define NOISE_IF_ON 2
54
55#define PAPD_BLANKING_PROFILE 3
56#define PAPD2LUT 0
57#define PAPD_CORR_NORM 0
58#define PAPD_BLANKING_THRESHOLD 0
59#define PAPD_STOP_AFTER_LAST_UPDATE 0
60
61#define LCN_TARGET_PWR 60
62
63#define LCN_VBAT_OFFSET_433X 34649679
64#define LCN_VBAT_SLOPE_433X 8258032
65
66#define LCN_VBAT_SCALE_NOM 53
67#define LCN_VBAT_SCALE_DEN 432
68
69#define LCN_TEMPSENSE_OFFSET 80812
70#define LCN_TEMPSENSE_DEN 2647
71
72#define LCN_BW_LMT 200
73#define LCN_CUR_LMT 1250
74#define LCN_MULT 1
75#define LCN_VCO_DIV 30
76#define LCN_OFFSET 680
77#define LCN_FACT 490
78#define LCN_CUR_DIV 2640
79
80#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT \
81 (0 + 8)
82#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK \
83 (0x7f << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT)
84
85#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT \
86 (0 + 8)
87#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK \
88 (0x7f << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT)
89
90#define wlc_lcnphy_enable_tx_gain_override(pi) \
91 wlc_lcnphy_set_tx_gain_override(pi, true)
92#define wlc_lcnphy_disable_tx_gain_override(pi) \
93 wlc_lcnphy_set_tx_gain_override(pi, false)
94
95#define wlc_lcnphy_iqcal_active(pi) \
96 (read_phy_reg((pi), 0x451) & \
97 ((0x1 << 15) | (0x1 << 14)))
98
99#define txpwrctrl_off(pi) (0x7 != ((read_phy_reg(pi, 0x4a4) & 0xE000) >> 13))
100#define wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) \
101 (pi->temppwrctrl_capable)
102#define wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) \
103 (pi->hwpwrctrl_capable)
104
105#define SWCTRL_BT_TX 0x18
106#define SWCTRL_OVR_DISABLE 0x40
107
108#define AFE_CLK_INIT_MODE_TXRX2X 1
109#define AFE_CLK_INIT_MODE_PAPD 0
110
111#define LCNPHY_TBL_ID_IQLOCAL 0x00
112
113#define LCNPHY_TBL_ID_RFSEQ 0x08
114#define LCNPHY_TBL_ID_GAIN_IDX 0x0d
115#define LCNPHY_TBL_ID_SW_CTRL 0x0f
116#define LCNPHY_TBL_ID_GAIN_TBL 0x12
117#define LCNPHY_TBL_ID_SPUR 0x14
118#define LCNPHY_TBL_ID_SAMPLEPLAY 0x15
119#define LCNPHY_TBL_ID_SAMPLEPLAY1 0x16
120
121#define LCNPHY_TX_PWR_CTRL_RATE_OFFSET 832
122#define LCNPHY_TX_PWR_CTRL_MAC_OFFSET 128
123#define LCNPHY_TX_PWR_CTRL_GAIN_OFFSET 192
124#define LCNPHY_TX_PWR_CTRL_IQ_OFFSET 320
125#define LCNPHY_TX_PWR_CTRL_LO_OFFSET 448
126#define LCNPHY_TX_PWR_CTRL_PWR_OFFSET 576
127
128#define LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313 140
129
130#define LCNPHY_TX_PWR_CTRL_START_NPT 1
131#define LCNPHY_TX_PWR_CTRL_MAX_NPT 7
132
133#define LCNPHY_NOISE_SAMPLES_DEFAULT 5000
134
135#define LCNPHY_ACI_DETECT_START 1
136#define LCNPHY_ACI_DETECT_PROGRESS 2
137#define LCNPHY_ACI_DETECT_STOP 3
138
139#define LCNPHY_ACI_CRSHIFRMLO_TRSH 100
140#define LCNPHY_ACI_GLITCH_TRSH 2000
141#define LCNPHY_ACI_TMOUT 250
142#define LCNPHY_ACI_DETECT_TIMEOUT 2
143#define LCNPHY_ACI_START_DELAY 0
144
145#define wlc_lcnphy_tx_gain_override_enabled(pi) \
146 (0 != (read_phy_reg((pi), 0x43b) & (0x1 << 6)))
147
148#define wlc_lcnphy_total_tx_frames(pi) \
149 wlapi_bmac_read_shm((pi)->sh->physhim, M_UCODE_MACSTAT + \
150 offsetof(struct macstat, txallfrm))
151
152struct lcnphy_txgains {
153 u16 gm_gain;
154 u16 pga_gain;
155 u16 pad_gain;
156 u16 dac_gain;
157};
158
159enum lcnphy_cal_mode {
160 LCNPHY_CAL_FULL,
161 LCNPHY_CAL_RECAL,
162 LCNPHY_CAL_CURRECAL,
163 LCNPHY_CAL_DIGCAL,
164 LCNPHY_CAL_GCTRL
165};
166
167struct lcnphy_rx_iqcomp {
168 u8 chan;
169 s16 a;
170 s16 b;
171};
172
173struct lcnphy_spb_tone {
174 s16 re;
175 s16 im;
176};
177
178struct lcnphy_unsign16_struct {
179 u16 re;
180 u16 im;
181};
182
183struct lcnphy_iq_est {
184 u32 iq_prod;
185 u32 i_pwr;
186 u32 q_pwr;
187};
188
189struct lcnphy_sfo_cfg {
190 u16 ptcentreTs20;
191 u16 ptcentreFactor;
192};
193
194enum lcnphy_papd_cal_type {
195 LCNPHY_PAPD_CAL_CW,
196 LCNPHY_PAPD_CAL_OFDM
197};
198
199typedef u16 iqcal_gain_params_lcnphy[9];
200
201static const iqcal_gain_params_lcnphy tbl_iqcal_gainparams_lcnphy_2G[] = {
202 {0, 0, 0, 0, 0, 0, 0, 0, 0},
203};
204
205static const iqcal_gain_params_lcnphy *tbl_iqcal_gainparams_lcnphy[1] = {
206 tbl_iqcal_gainparams_lcnphy_2G,
207};
208
209static const u16 iqcal_gainparams_numgains_lcnphy[1] = {
210 sizeof(tbl_iqcal_gainparams_lcnphy_2G) /
211 sizeof(*tbl_iqcal_gainparams_lcnphy_2G),
212};
213
214static const struct lcnphy_sfo_cfg lcnphy_sfo_cfg[] = {
215 {965, 1087},
216 {967, 1085},
217 {969, 1082},
218 {971, 1080},
219 {973, 1078},
220 {975, 1076},
221 {977, 1073},
222 {979, 1071},
223 {981, 1069},
224 {983, 1067},
225 {985, 1065},
226 {987, 1063},
227 {989, 1060},
228 {994, 1055}
229};
230
231static const
232u16 lcnphy_iqcal_loft_gainladder[] = {
233 ((2 << 8) | 0),
234 ((3 << 8) | 0),
235 ((4 << 8) | 0),
236 ((6 << 8) | 0),
237 ((8 << 8) | 0),
238 ((11 << 8) | 0),
239 ((16 << 8) | 0),
240 ((16 << 8) | 1),
241 ((16 << 8) | 2),
242 ((16 << 8) | 3),
243 ((16 << 8) | 4),
244 ((16 << 8) | 5),
245 ((16 << 8) | 6),
246 ((16 << 8) | 7),
247 ((23 << 8) | 7),
248 ((32 << 8) | 7),
249 ((45 << 8) | 7),
250 ((64 << 8) | 7),
251 ((91 << 8) | 7),
252 ((128 << 8) | 7)
253};
254
255static const
256u16 lcnphy_iqcal_ir_gainladder[] = {
257 ((1 << 8) | 0),
258 ((2 << 8) | 0),
259 ((4 << 8) | 0),
260 ((6 << 8) | 0),
261 ((8 << 8) | 0),
262 ((11 << 8) | 0),
263 ((16 << 8) | 0),
264 ((23 << 8) | 0),
265 ((32 << 8) | 0),
266 ((45 << 8) | 0),
267 ((64 << 8) | 0),
268 ((64 << 8) | 1),
269 ((64 << 8) | 2),
270 ((64 << 8) | 3),
271 ((64 << 8) | 4),
272 ((64 << 8) | 5),
273 ((64 << 8) | 6),
274 ((64 << 8) | 7),
275 ((91 << 8) | 7),
276 ((128 << 8) | 7)
277};
278
279static const
280struct lcnphy_spb_tone lcnphy_spb_tone_3750[] = {
281 {88, 0},
282 {73, 49},
283 {34, 81},
284 {-17, 86},
285 {-62, 62},
286 {-86, 17},
287 {-81, -34},
288 {-49, -73},
289 {0, -88},
290 {49, -73},
291 {81, -34},
292 {86, 17},
293 {62, 62},
294 {17, 86},
295 {-34, 81},
296 {-73, 49},
297 {-88, 0},
298 {-73, -49},
299 {-34, -81},
300 {17, -86},
301 {62, -62},
302 {86, -17},
303 {81, 34},
304 {49, 73},
305 {0, 88},
306 {-49, 73},
307 {-81, 34},
308 {-86, -17},
309 {-62, -62},
310 {-17, -86},
311 {34, -81},
312 {73, -49},
313};
314
315static const
316u16 iqlo_loopback_rf_regs[20] = {
317 RADIO_2064_REG036,
318 RADIO_2064_REG11A,
319 RADIO_2064_REG03A,
320 RADIO_2064_REG025,
321 RADIO_2064_REG028,
322 RADIO_2064_REG005,
323 RADIO_2064_REG112,
324 RADIO_2064_REG0FF,
325 RADIO_2064_REG11F,
326 RADIO_2064_REG00B,
327 RADIO_2064_REG113,
328 RADIO_2064_REG007,
329 RADIO_2064_REG0FC,
330 RADIO_2064_REG0FD,
331 RADIO_2064_REG012,
332 RADIO_2064_REG057,
333 RADIO_2064_REG059,
334 RADIO_2064_REG05C,
335 RADIO_2064_REG078,
336 RADIO_2064_REG092,
337};
338
339static const
340u16 tempsense_phy_regs[14] = {
341 0x503,
342 0x4a4,
343 0x4d0,
344 0x4d9,
345 0x4da,
346 0x4a6,
347 0x938,
348 0x939,
349 0x4d8,
350 0x4d0,
351 0x4d7,
352 0x4a5,
353 0x40d,
354 0x4a2,
355};
356
357static const
358u16 rxiq_cal_rf_reg[11] = {
359 RADIO_2064_REG098,
360 RADIO_2064_REG116,
361 RADIO_2064_REG12C,
362 RADIO_2064_REG06A,
363 RADIO_2064_REG00B,
364 RADIO_2064_REG01B,
365 RADIO_2064_REG113,
366 RADIO_2064_REG01D,
367 RADIO_2064_REG114,
368 RADIO_2064_REG02E,
369 RADIO_2064_REG12A,
370};
371
372static const
373struct lcnphy_rx_iqcomp lcnphy_rx_iqcomp_table_rev0[] = {
374 {1, 0, 0},
375 {2, 0, 0},
376 {3, 0, 0},
377 {4, 0, 0},
378 {5, 0, 0},
379 {6, 0, 0},
380 {7, 0, 0},
381 {8, 0, 0},
382 {9, 0, 0},
383 {10, 0, 0},
384 {11, 0, 0},
385 {12, 0, 0},
386 {13, 0, 0},
387 {14, 0, 0},
388 {34, 0, 0},
389 {38, 0, 0},
390 {42, 0, 0},
391 {46, 0, 0},
392 {36, 0, 0},
393 {40, 0, 0},
394 {44, 0, 0},
395 {48, 0, 0},
396 {52, 0, 0},
397 {56, 0, 0},
398 {60, 0, 0},
399 {64, 0, 0},
400 {100, 0, 0},
401 {104, 0, 0},
402 {108, 0, 0},
403 {112, 0, 0},
404 {116, 0, 0},
405 {120, 0, 0},
406 {124, 0, 0},
407 {128, 0, 0},
408 {132, 0, 0},
409 {136, 0, 0},
410 {140, 0, 0},
411 {149, 0, 0},
412 {153, 0, 0},
413 {157, 0, 0},
414 {161, 0, 0},
415 {165, 0, 0},
416 {184, 0, 0},
417 {188, 0, 0},
418 {192, 0, 0},
419 {196, 0, 0},
420 {200, 0, 0},
421 {204, 0, 0},
422 {208, 0, 0},
423 {212, 0, 0},
424 {216, 0, 0},
425};
426
427static const u32 lcnphy_23bitgaincode_table[] = {
428 0x200100,
429 0x200200,
430 0x200004,
431 0x200014,
432 0x200024,
433 0x200034,
434 0x200134,
435 0x200234,
436 0x200334,
437 0x200434,
438 0x200037,
439 0x200137,
440 0x200237,
441 0x200337,
442 0x200437,
443 0x000035,
444 0x000135,
445 0x000235,
446 0x000037,
447 0x000137,
448 0x000237,
449 0x000337,
450 0x00013f,
451 0x00023f,
452 0x00033f,
453 0x00034f,
454 0x00044f,
455 0x00144f,
456 0x00244f,
457 0x00254f,
458 0x00354f,
459 0x00454f,
460 0x00464f,
461 0x01464f,
462 0x02464f,
463 0x03464f,
464 0x04464f,
465};
466
467static const s8 lcnphy_gain_table[] = {
468 -16,
469 -13,
470 10,
471 7,
472 4,
473 0,
474 3,
475 6,
476 9,
477 12,
478 15,
479 18,
480 21,
481 24,
482 27,
483 30,
484 33,
485 36,
486 39,
487 42,
488 45,
489 48,
490 50,
491 53,
492 56,
493 59,
494 62,
495 65,
496 68,
497 71,
498 74,
499 77,
500 80,
501 83,
502 86,
503 89,
504 92,
505};
506
507static const s8 lcnphy_gain_index_offset_for_rssi[] = {
508 7,
509 7,
510 7,
511 7,
512 7,
513 7,
514 7,
515 8,
516 7,
517 7,
518 6,
519 7,
520 7,
521 4,
522 4,
523 4,
524 4,
525 4,
526 4,
527 4,
528 4,
529 3,
530 3,
531 3,
532 3,
533 3,
534 3,
535 4,
536 2,
537 2,
538 2,
539 2,
540 2,
541 2,
542 -1,
543 -2,
544 -2,
545 -2
546};
547
548struct chan_info_2064_lcnphy {
549 uint chan;
550 uint freq;
551 u8 logen_buftune;
552 u8 logen_rccr_tx;
553 u8 txrf_mix_tune_ctrl;
554 u8 pa_input_tune_g;
555 u8 logen_rccr_rx;
556 u8 pa_rxrf_lna1_freq_tune;
557 u8 pa_rxrf_lna2_freq_tune;
558 u8 rxrf_rxrf_spare1;
559};
560
561static const struct chan_info_2064_lcnphy chan_info_2064_lcnphy[] = {
562 {1, 2412, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
563 {2, 2417, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
564 {3, 2422, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
565 {4, 2427, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
566 {5, 2432, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
567 {6, 2437, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
568 {7, 2442, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
569 {8, 2447, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
570 {9, 2452, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
571 {10, 2457, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
572 {11, 2462, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
573 {12, 2467, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
574 {13, 2472, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
575 {14, 2484, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
576};
577
578static const struct lcnphy_radio_regs lcnphy_radio_regs_2064[] = {
579 {0x00, 0, 0, 0, 0},
580 {0x01, 0x64, 0x64, 0, 0},
581 {0x02, 0x20, 0x20, 0, 0},
582 {0x03, 0x66, 0x66, 0, 0},
583 {0x04, 0xf8, 0xf8, 0, 0},
584 {0x05, 0, 0, 0, 0},
585 {0x06, 0x10, 0x10, 0, 0},
586 {0x07, 0, 0, 0, 0},
587 {0x08, 0, 0, 0, 0},
588 {0x09, 0, 0, 0, 0},
589 {0x0A, 0x37, 0x37, 0, 0},
590 {0x0B, 0x6, 0x6, 0, 0},
591 {0x0C, 0x55, 0x55, 0, 0},
592 {0x0D, 0x8b, 0x8b, 0, 0},
593 {0x0E, 0, 0, 0, 0},
594 {0x0F, 0x5, 0x5, 0, 0},
595 {0x10, 0, 0, 0, 0},
596 {0x11, 0xe, 0xe, 0, 0},
597 {0x12, 0, 0, 0, 0},
598 {0x13, 0xb, 0xb, 0, 0},
599 {0x14, 0x2, 0x2, 0, 0},
600 {0x15, 0x12, 0x12, 0, 0},
601 {0x16, 0x12, 0x12, 0, 0},
602 {0x17, 0xc, 0xc, 0, 0},
603 {0x18, 0xc, 0xc, 0, 0},
604 {0x19, 0xc, 0xc, 0, 0},
605 {0x1A, 0x8, 0x8, 0, 0},
606 {0x1B, 0x2, 0x2, 0, 0},
607 {0x1C, 0, 0, 0, 0},
608 {0x1D, 0x1, 0x1, 0, 0},
609 {0x1E, 0x12, 0x12, 0, 0},
610 {0x1F, 0x6e, 0x6e, 0, 0},
611 {0x20, 0x2, 0x2, 0, 0},
612 {0x21, 0x23, 0x23, 0, 0},
613 {0x22, 0x8, 0x8, 0, 0},
614 {0x23, 0, 0, 0, 0},
615 {0x24, 0, 0, 0, 0},
616 {0x25, 0xc, 0xc, 0, 0},
617 {0x26, 0x33, 0x33, 0, 0},
618 {0x27, 0x55, 0x55, 0, 0},
619 {0x28, 0, 0, 0, 0},
620 {0x29, 0x30, 0x30, 0, 0},
621 {0x2A, 0xb, 0xb, 0, 0},
622 {0x2B, 0x1b, 0x1b, 0, 0},
623 {0x2C, 0x3, 0x3, 0, 0},
624 {0x2D, 0x1b, 0x1b, 0, 0},
625 {0x2E, 0, 0, 0, 0},
626 {0x2F, 0x20, 0x20, 0, 0},
627 {0x30, 0xa, 0xa, 0, 0},
628 {0x31, 0, 0, 0, 0},
629 {0x32, 0x62, 0x62, 0, 0},
630 {0x33, 0x19, 0x19, 0, 0},
631 {0x34, 0x33, 0x33, 0, 0},
632 {0x35, 0x77, 0x77, 0, 0},
633 {0x36, 0, 0, 0, 0},
634 {0x37, 0x70, 0x70, 0, 0},
635 {0x38, 0x3, 0x3, 0, 0},
636 {0x39, 0xf, 0xf, 0, 0},
637 {0x3A, 0x6, 0x6, 0, 0},
638 {0x3B, 0xcf, 0xcf, 0, 0},
639 {0x3C, 0x1a, 0x1a, 0, 0},
640 {0x3D, 0x6, 0x6, 0, 0},
641 {0x3E, 0x42, 0x42, 0, 0},
642 {0x3F, 0, 0, 0, 0},
643 {0x40, 0xfb, 0xfb, 0, 0},
644 {0x41, 0x9a, 0x9a, 0, 0},
645 {0x42, 0x7a, 0x7a, 0, 0},
646 {0x43, 0x29, 0x29, 0, 0},
647 {0x44, 0, 0, 0, 0},
648 {0x45, 0x8, 0x8, 0, 0},
649 {0x46, 0xce, 0xce, 0, 0},
650 {0x47, 0x27, 0x27, 0, 0},
651 {0x48, 0x62, 0x62, 0, 0},
652 {0x49, 0x6, 0x6, 0, 0},
653 {0x4A, 0x58, 0x58, 0, 0},
654 {0x4B, 0xf7, 0xf7, 0, 0},
655 {0x4C, 0, 0, 0, 0},
656 {0x4D, 0xb3, 0xb3, 0, 0},
657 {0x4E, 0, 0, 0, 0},
658 {0x4F, 0x2, 0x2, 0, 0},
659 {0x50, 0, 0, 0, 0},
660 {0x51, 0x9, 0x9, 0, 0},
661 {0x52, 0x5, 0x5, 0, 0},
662 {0x53, 0x17, 0x17, 0, 0},
663 {0x54, 0x38, 0x38, 0, 0},
664 {0x55, 0, 0, 0, 0},
665 {0x56, 0, 0, 0, 0},
666 {0x57, 0xb, 0xb, 0, 0},
667 {0x58, 0, 0, 0, 0},
668 {0x59, 0, 0, 0, 0},
669 {0x5A, 0, 0, 0, 0},
670 {0x5B, 0, 0, 0, 0},
671 {0x5C, 0, 0, 0, 0},
672 {0x5D, 0, 0, 0, 0},
673 {0x5E, 0x88, 0x88, 0, 0},
674 {0x5F, 0xcc, 0xcc, 0, 0},
675 {0x60, 0x74, 0x74, 0, 0},
676 {0x61, 0x74, 0x74, 0, 0},
677 {0x62, 0x74, 0x74, 0, 0},
678 {0x63, 0x44, 0x44, 0, 0},
679 {0x64, 0x77, 0x77, 0, 0},
680 {0x65, 0x44, 0x44, 0, 0},
681 {0x66, 0x77, 0x77, 0, 0},
682 {0x67, 0x55, 0x55, 0, 0},
683 {0x68, 0x77, 0x77, 0, 0},
684 {0x69, 0x77, 0x77, 0, 0},
685 {0x6A, 0, 0, 0, 0},
686 {0x6B, 0x7f, 0x7f, 0, 0},
687 {0x6C, 0x8, 0x8, 0, 0},
688 {0x6D, 0, 0, 0, 0},
689 {0x6E, 0x88, 0x88, 0, 0},
690 {0x6F, 0x66, 0x66, 0, 0},
691 {0x70, 0x66, 0x66, 0, 0},
692 {0x71, 0x28, 0x28, 0, 0},
693 {0x72, 0x55, 0x55, 0, 0},
694 {0x73, 0x4, 0x4, 0, 0},
695 {0x74, 0, 0, 0, 0},
696 {0x75, 0, 0, 0, 0},
697 {0x76, 0, 0, 0, 0},
698 {0x77, 0x1, 0x1, 0, 0},
699 {0x78, 0xd6, 0xd6, 0, 0},
700 {0x79, 0, 0, 0, 0},
701 {0x7A, 0, 0, 0, 0},
702 {0x7B, 0, 0, 0, 0},
703 {0x7C, 0, 0, 0, 0},
704 {0x7D, 0, 0, 0, 0},
705 {0x7E, 0, 0, 0, 0},
706 {0x7F, 0, 0, 0, 0},
707 {0x80, 0, 0, 0, 0},
708 {0x81, 0, 0, 0, 0},
709 {0x82, 0, 0, 0, 0},
710 {0x83, 0xb4, 0xb4, 0, 0},
711 {0x84, 0x1, 0x1, 0, 0},
712 {0x85, 0x20, 0x20, 0, 0},
713 {0x86, 0x5, 0x5, 0, 0},
714 {0x87, 0xff, 0xff, 0, 0},
715 {0x88, 0x7, 0x7, 0, 0},
716 {0x89, 0x77, 0x77, 0, 0},
717 {0x8A, 0x77, 0x77, 0, 0},
718 {0x8B, 0x77, 0x77, 0, 0},
719 {0x8C, 0x77, 0x77, 0, 0},
720 {0x8D, 0x8, 0x8, 0, 0},
721 {0x8E, 0xa, 0xa, 0, 0},
722 {0x8F, 0x8, 0x8, 0, 0},
723 {0x90, 0x18, 0x18, 0, 0},
724 {0x91, 0x5, 0x5, 0, 0},
725 {0x92, 0x1f, 0x1f, 0, 0},
726 {0x93, 0x10, 0x10, 0, 0},
727 {0x94, 0x3, 0x3, 0, 0},
728 {0x95, 0, 0, 0, 0},
729 {0x96, 0, 0, 0, 0},
730 {0x97, 0xaa, 0xaa, 0, 0},
731 {0x98, 0, 0, 0, 0},
732 {0x99, 0x23, 0x23, 0, 0},
733 {0x9A, 0x7, 0x7, 0, 0},
734 {0x9B, 0xf, 0xf, 0, 0},
735 {0x9C, 0x10, 0x10, 0, 0},
736 {0x9D, 0x3, 0x3, 0, 0},
737 {0x9E, 0x4, 0x4, 0, 0},
738 {0x9F, 0x20, 0x20, 0, 0},
739 {0xA0, 0, 0, 0, 0},
740 {0xA1, 0, 0, 0, 0},
741 {0xA2, 0, 0, 0, 0},
742 {0xA3, 0, 0, 0, 0},
743 {0xA4, 0x1, 0x1, 0, 0},
744 {0xA5, 0x77, 0x77, 0, 0},
745 {0xA6, 0x77, 0x77, 0, 0},
746 {0xA7, 0x77, 0x77, 0, 0},
747 {0xA8, 0x77, 0x77, 0, 0},
748 {0xA9, 0x8c, 0x8c, 0, 0},
749 {0xAA, 0x88, 0x88, 0, 0},
750 {0xAB, 0x78, 0x78, 0, 0},
751 {0xAC, 0x57, 0x57, 0, 0},
752 {0xAD, 0x88, 0x88, 0, 0},
753 {0xAE, 0, 0, 0, 0},
754 {0xAF, 0x8, 0x8, 0, 0},
755 {0xB0, 0x88, 0x88, 0, 0},
756 {0xB1, 0, 0, 0, 0},
757 {0xB2, 0x1b, 0x1b, 0, 0},
758 {0xB3, 0x3, 0x3, 0, 0},
759 {0xB4, 0x24, 0x24, 0, 0},
760 {0xB5, 0x3, 0x3, 0, 0},
761 {0xB6, 0x1b, 0x1b, 0, 0},
762 {0xB7, 0x24, 0x24, 0, 0},
763 {0xB8, 0x3, 0x3, 0, 0},
764 {0xB9, 0, 0, 0, 0},
765 {0xBA, 0xaa, 0xaa, 0, 0},
766 {0xBB, 0, 0, 0, 0},
767 {0xBC, 0x4, 0x4, 0, 0},
768 {0xBD, 0, 0, 0, 0},
769 {0xBE, 0x8, 0x8, 0, 0},
770 {0xBF, 0x11, 0x11, 0, 0},
771 {0xC0, 0, 0, 0, 0},
772 {0xC1, 0, 0, 0, 0},
773 {0xC2, 0x62, 0x62, 0, 0},
774 {0xC3, 0x1e, 0x1e, 0, 0},
775 {0xC4, 0x33, 0x33, 0, 0},
776 {0xC5, 0x37, 0x37, 0, 0},
777 {0xC6, 0, 0, 0, 0},
778 {0xC7, 0x70, 0x70, 0, 0},
779 {0xC8, 0x1e, 0x1e, 0, 0},
780 {0xC9, 0x6, 0x6, 0, 0},
781 {0xCA, 0x4, 0x4, 0, 0},
782 {0xCB, 0x2f, 0x2f, 0, 0},
783 {0xCC, 0xf, 0xf, 0, 0},
784 {0xCD, 0, 0, 0, 0},
785 {0xCE, 0xff, 0xff, 0, 0},
786 {0xCF, 0x8, 0x8, 0, 0},
787 {0xD0, 0x3f, 0x3f, 0, 0},
788 {0xD1, 0x3f, 0x3f, 0, 0},
789 {0xD2, 0x3f, 0x3f, 0, 0},
790 {0xD3, 0, 0, 0, 0},
791 {0xD4, 0, 0, 0, 0},
792 {0xD5, 0, 0, 0, 0},
793 {0xD6, 0xcc, 0xcc, 0, 0},
794 {0xD7, 0, 0, 0, 0},
795 {0xD8, 0x8, 0x8, 0, 0},
796 {0xD9, 0x8, 0x8, 0, 0},
797 {0xDA, 0x8, 0x8, 0, 0},
798 {0xDB, 0x11, 0x11, 0, 0},
799 {0xDC, 0, 0, 0, 0},
800 {0xDD, 0x87, 0x87, 0, 0},
801 {0xDE, 0x88, 0x88, 0, 0},
802 {0xDF, 0x8, 0x8, 0, 0},
803 {0xE0, 0x8, 0x8, 0, 0},
804 {0xE1, 0x8, 0x8, 0, 0},
805 {0xE2, 0, 0, 0, 0},
806 {0xE3, 0, 0, 0, 0},
807 {0xE4, 0, 0, 0, 0},
808 {0xE5, 0xf5, 0xf5, 0, 0},
809 {0xE6, 0x30, 0x30, 0, 0},
810 {0xE7, 0x1, 0x1, 0, 0},
811 {0xE8, 0, 0, 0, 0},
812 {0xE9, 0xff, 0xff, 0, 0},
813 {0xEA, 0, 0, 0, 0},
814 {0xEB, 0, 0, 0, 0},
815 {0xEC, 0x22, 0x22, 0, 0},
816 {0xED, 0, 0, 0, 0},
817 {0xEE, 0, 0, 0, 0},
818 {0xEF, 0, 0, 0, 0},
819 {0xF0, 0x3, 0x3, 0, 0},
820 {0xF1, 0x1, 0x1, 0, 0},
821 {0xF2, 0, 0, 0, 0},
822 {0xF3, 0, 0, 0, 0},
823 {0xF4, 0, 0, 0, 0},
824 {0xF5, 0, 0, 0, 0},
825 {0xF6, 0, 0, 0, 0},
826 {0xF7, 0x6, 0x6, 0, 0},
827 {0xF8, 0, 0, 0, 0},
828 {0xF9, 0, 0, 0, 0},
829 {0xFA, 0x40, 0x40, 0, 0},
830 {0xFB, 0, 0, 0, 0},
831 {0xFC, 0x1, 0x1, 0, 0},
832 {0xFD, 0x80, 0x80, 0, 0},
833 {0xFE, 0x2, 0x2, 0, 0},
834 {0xFF, 0x10, 0x10, 0, 0},
835 {0x100, 0x2, 0x2, 0, 0},
836 {0x101, 0x1e, 0x1e, 0, 0},
837 {0x102, 0x1e, 0x1e, 0, 0},
838 {0x103, 0, 0, 0, 0},
839 {0x104, 0x1f, 0x1f, 0, 0},
840 {0x105, 0, 0x8, 0, 1},
841 {0x106, 0x2a, 0x2a, 0, 0},
842 {0x107, 0xf, 0xf, 0, 0},
843 {0x108, 0, 0, 0, 0},
844 {0x109, 0, 0, 0, 0},
845 {0x10A, 0, 0, 0, 0},
846 {0x10B, 0, 0, 0, 0},
847 {0x10C, 0, 0, 0, 0},
848 {0x10D, 0, 0, 0, 0},
849 {0x10E, 0, 0, 0, 0},
850 {0x10F, 0, 0, 0, 0},
851 {0x110, 0, 0, 0, 0},
852 {0x111, 0, 0, 0, 0},
853 {0x112, 0, 0, 0, 0},
854 {0x113, 0, 0, 0, 0},
855 {0x114, 0, 0, 0, 0},
856 {0x115, 0, 0, 0, 0},
857 {0x116, 0, 0, 0, 0},
858 {0x117, 0, 0, 0, 0},
859 {0x118, 0, 0, 0, 0},
860 {0x119, 0, 0, 0, 0},
861 {0x11A, 0, 0, 0, 0},
862 {0x11B, 0, 0, 0, 0},
863 {0x11C, 0x1, 0x1, 0, 0},
864 {0x11D, 0, 0, 0, 0},
865 {0x11E, 0, 0, 0, 0},
866 {0x11F, 0, 0, 0, 0},
867 {0x120, 0, 0, 0, 0},
868 {0x121, 0, 0, 0, 0},
869 {0x122, 0x80, 0x80, 0, 0},
870 {0x123, 0, 0, 0, 0},
871 {0x124, 0xf8, 0xf8, 0, 0},
872 {0x125, 0, 0, 0, 0},
873 {0x126, 0, 0, 0, 0},
874 {0x127, 0, 0, 0, 0},
875 {0x128, 0, 0, 0, 0},
876 {0x129, 0, 0, 0, 0},
877 {0x12A, 0, 0, 0, 0},
878 {0x12B, 0, 0, 0, 0},
879 {0x12C, 0, 0, 0, 0},
880 {0x12D, 0, 0, 0, 0},
881 {0x12E, 0, 0, 0, 0},
882 {0x12F, 0, 0, 0, 0},
883 {0x130, 0, 0, 0, 0},
884 {0xFFFF, 0, 0, 0, 0}
885};
886
887#define LCNPHY_NUM_DIG_FILT_COEFFS 16
888#define LCNPHY_NUM_TX_DIG_FILTERS_CCK 13
889
890static const u16 LCNPHY_txdigfiltcoeffs_cck[LCNPHY_NUM_TX_DIG_FILTERS_CCK]
891 [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
892 {0, 1, 415, 1874, 64, 128, 64, 792, 1656, 64, 128, 64, 778, 1582, 64,
893 128, 64,},
894 {1, 1, 402, 1847, 259, 59, 259, 671, 1794, 68, 54, 68, 608, 1863, 93,
895 167, 93,},
896 {2, 1, 415, 1874, 64, 128, 64, 792, 1656, 192, 384, 192, 778, 1582, 64,
897 128, 64,},
898 {3, 1, 302, 1841, 129, 258, 129, 658, 1720, 205, 410, 205, 754, 1760,
899 170, 340, 170,},
900 {20, 1, 360, 1884, 242, 1734, 242, 752, 1720, 205, 1845, 205, 767, 1760,
901 256, 185, 256,},
902 {21, 1, 360, 1884, 149, 1874, 149, 752, 1720, 205, 1883, 205, 767, 1760,
903 256, 273, 256,},
904 {22, 1, 360, 1884, 98, 1948, 98, 752, 1720, 205, 1924, 205, 767, 1760,
905 256, 352, 256,},
906 {23, 1, 350, 1884, 116, 1966, 116, 752, 1720, 205, 2008, 205, 767, 1760,
907 128, 233, 128,},
908 {24, 1, 325, 1884, 32, 40, 32, 756, 1720, 256, 471, 256, 766, 1760, 256,
909 1881, 256,},
910 {25, 1, 299, 1884, 51, 64, 51, 736, 1720, 256, 471, 256, 765, 1760, 256,
911 1881, 256,},
912 {26, 1, 277, 1943, 39, 117, 88, 637, 1838, 64, 192, 144, 614, 1864, 128,
913 384, 288,},
914 {27, 1, 245, 1943, 49, 147, 110, 626, 1838, 256, 768, 576, 613, 1864,
915 128, 384, 288,},
916 {30, 1, 302, 1841, 61, 122, 61, 658, 1720, 205, 410, 205, 754, 1760,
917 170, 340, 170,},
918};
919
920#define LCNPHY_NUM_TX_DIG_FILTERS_OFDM 3
921static const u16 LCNPHY_txdigfiltcoeffs_ofdm[LCNPHY_NUM_TX_DIG_FILTERS_OFDM]
922 [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
923 {0, 0, 0xa2, 0x0, 0x100, 0x100, 0x0, 0x0, 0x0, 0x100, 0x0, 0x0,
924 0x278, 0xfea0, 0x80, 0x100, 0x80,},
925 {1, 0, 374, 0xFF79, 16, 32, 16, 799, 0xFE74, 50, 32, 50,
926 750, 0xFE2B, 212, 0xFFCE, 212,},
927 {2, 0, 375, 0xFF16, 37, 76, 37, 799, 0xFE74, 32, 20, 32, 748,
928 0xFEF2, 128, 0xFFE2, 128}
929};
930
931#define wlc_lcnphy_set_start_tx_pwr_idx(pi, idx) \
932 mod_phy_reg(pi, 0x4a4, \
933 (0x1ff << 0), \
934 (u16)(idx) << 0)
935
936#define wlc_lcnphy_set_tx_pwr_npt(pi, npt) \
937 mod_phy_reg(pi, 0x4a5, \
938 (0x7 << 8), \
939 (u16)(npt) << 8)
940
941#define wlc_lcnphy_get_tx_pwr_ctrl(pi) \
942 (read_phy_reg((pi), 0x4a4) & \
943 ((0x1 << 15) | \
944 (0x1 << 14) | \
945 (0x1 << 13)))
946
947#define wlc_lcnphy_get_tx_pwr_npt(pi) \
948 ((read_phy_reg(pi, 0x4a5) & \
949 (0x7 << 8)) >> \
950 8)
951
952#define wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi) \
953 (read_phy_reg(pi, 0x473) & 0x1ff)
954
955#define wlc_lcnphy_get_target_tx_pwr(pi) \
956 ((read_phy_reg(pi, 0x4a7) & \
957 (0xff << 0)) >> \
958 0)
959
960#define wlc_lcnphy_set_target_tx_pwr(pi, target) \
961 mod_phy_reg(pi, 0x4a7, \
962 (0xff << 0), \
963 (u16)(target) << 0)
964
965#define wlc_radio_2064_rcal_done(pi) \
966 (0 != (read_radio_reg(pi, RADIO_2064_REG05C) & 0x20))
967
968#define tempsense_done(pi) \
969 (0x8000 == (read_phy_reg(pi, 0x476) & 0x8000))
970
971#define LCNPHY_IQLOCC_READ(val) \
972 ((u8)(-(s8)(((val) & 0xf0) >> 4) + (s8)((val) & 0x0f)))
973
974#define FIXED_TXPWR 78
975#define LCNPHY_TEMPSENSE(val) ((s16)((val > 255) ? (val - 512) : val))
976
977void wlc_lcnphy_write_table(struct brcms_phy *pi, const struct phytbl_info *pti)
978{
979 wlc_phy_write_table(pi, pti, 0x455, 0x457, 0x456);
980}
981
982void wlc_lcnphy_read_table(struct brcms_phy *pi, struct phytbl_info *pti)
983{
984 wlc_phy_read_table(pi, pti, 0x455, 0x457, 0x456);
985}
986
987static void
988wlc_lcnphy_common_read_table(struct brcms_phy *pi, u32 tbl_id,
989 const u16 *tbl_ptr, u32 tbl_len,
990 u32 tbl_width, u32 tbl_offset)
991{
992 struct phytbl_info tab;
993 tab.tbl_id = tbl_id;
994 tab.tbl_ptr = tbl_ptr;
995 tab.tbl_len = tbl_len;
996 tab.tbl_width = tbl_width;
997 tab.tbl_offset = tbl_offset;
998 wlc_lcnphy_read_table(pi, &tab);
999}
1000
1001static void
1002wlc_lcnphy_common_write_table(struct brcms_phy *pi, u32 tbl_id,
1003 const u16 *tbl_ptr, u32 tbl_len,
1004 u32 tbl_width, u32 tbl_offset)
1005{
1006
1007 struct phytbl_info tab;
1008 tab.tbl_id = tbl_id;
1009 tab.tbl_ptr = tbl_ptr;
1010 tab.tbl_len = tbl_len;
1011 tab.tbl_width = tbl_width;
1012 tab.tbl_offset = tbl_offset;
1013 wlc_lcnphy_write_table(pi, &tab);
1014}
1015
1016static u32
1017wlc_lcnphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision)
1018{
1019 u32 quotient, remainder, roundup, rbit;
1020
1021 quotient = dividend / divisor;
1022 remainder = dividend % divisor;
1023 rbit = divisor & 1;
1024 roundup = (divisor >> 1) + rbit;
1025
1026 while (precision--) {
1027 quotient <<= 1;
1028 if (remainder >= roundup) {
1029 quotient++;
1030 remainder = ((remainder - roundup) << 1) + rbit;
1031 } else {
1032 remainder <<= 1;
1033 }
1034 }
1035
1036 if (remainder >= roundup)
1037 quotient++;
1038
1039 return quotient;
1040}
1041
1042static int wlc_lcnphy_calc_floor(s16 coeff_x, int type)
1043{
1044 int k;
1045 k = 0;
1046 if (type == 0) {
1047 if (coeff_x < 0)
1048 k = (coeff_x - 1) / 2;
1049 else
1050 k = coeff_x / 2;
1051 }
1052
1053 if (type == 1) {
1054 if ((coeff_x + 1) < 0)
1055 k = (coeff_x) / 2;
1056 else
1057 k = (coeff_x + 1) / 2;
1058 }
1059 return k;
1060}
1061
1062static void
1063wlc_lcnphy_get_tx_gain(struct brcms_phy *pi, struct lcnphy_txgains *gains)
1064{
1065 u16 dac_gain, rfgain0, rfgain1;
1066
1067 dac_gain = read_phy_reg(pi, 0x439) >> 0;
1068 gains->dac_gain = (dac_gain & 0x380) >> 7;
1069
1070 rfgain0 = (read_phy_reg(pi, 0x4b5) & (0xffff << 0)) >> 0;
1071 rfgain1 = (read_phy_reg(pi, 0x4fb) & (0x7fff << 0)) >> 0;
1072
1073 gains->gm_gain = rfgain0 & 0xff;
1074 gains->pga_gain = (rfgain0 >> 8) & 0xff;
1075 gains->pad_gain = rfgain1 & 0xff;
1076}
1077
1078
1079static void wlc_lcnphy_set_dac_gain(struct brcms_phy *pi, u16 dac_gain)
1080{
1081 u16 dac_ctrl;
1082
1083 dac_ctrl = (read_phy_reg(pi, 0x439) >> 0);
1084 dac_ctrl = dac_ctrl & 0xc7f;
1085 dac_ctrl = dac_ctrl | (dac_gain << 7);
1086 mod_phy_reg(pi, 0x439, (0xfff << 0), (dac_ctrl) << 0);
1087
1088}
1089
1090static void wlc_lcnphy_set_tx_gain_override(struct brcms_phy *pi, bool bEnable)
1091{
1092 u16 bit = bEnable ? 1 : 0;
1093
1094 mod_phy_reg(pi, 0x4b0, (0x1 << 7), bit << 7);
1095
1096 mod_phy_reg(pi, 0x4b0, (0x1 << 14), bit << 14);
1097
1098 mod_phy_reg(pi, 0x43b, (0x1 << 6), bit << 6);
1099}
1100
1101static void
1102wlc_lcnphy_rx_gain_override_enable(struct brcms_phy *pi, bool enable)
1103{
1104 u16 ebit = enable ? 1 : 0;
1105
1106 mod_phy_reg(pi, 0x4b0, (0x1 << 8), ebit << 8);
1107
1108 mod_phy_reg(pi, 0x44c, (0x1 << 0), ebit << 0);
1109
1110 if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
1111 mod_phy_reg(pi, 0x44c, (0x1 << 4), ebit << 4);
1112 mod_phy_reg(pi, 0x44c, (0x1 << 6), ebit << 6);
1113 mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
1114 mod_phy_reg(pi, 0x4b0, (0x1 << 6), ebit << 6);
1115 } else {
1116 mod_phy_reg(pi, 0x4b0, (0x1 << 12), ebit << 12);
1117 mod_phy_reg(pi, 0x4b0, (0x1 << 13), ebit << 13);
1118 mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
1119 }
1120
1121 if (CHSPEC_IS2G(pi->radio_chanspec)) {
1122 mod_phy_reg(pi, 0x4b0, (0x1 << 10), ebit << 10);
1123 mod_phy_reg(pi, 0x4e5, (0x1 << 3), ebit << 3);
1124 }
1125}
1126
1127static void
1128wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
1129 u16 trsw,
1130 u16 ext_lna,
1131 u16 biq2,
1132 u16 biq1,
1133 u16 tia, u16 lna2, u16 lna1)
1134{
1135 u16 gain0_15, gain16_19;
1136
1137 gain16_19 = biq2 & 0xf;
1138 gain0_15 = ((biq1 & 0xf) << 12) |
1139 ((tia & 0xf) << 8) |
1140 ((lna2 & 0x3) << 6) |
1141 ((lna2 &
1142 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
1143
1144 mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
1145 mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
1146 mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
1147
1148 if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
1149 mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
1150 mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
1151 } else {
1152 mod_phy_reg(pi, 0x4b1, (0x1 << 10), 0 << 10);
1153
1154 mod_phy_reg(pi, 0x4b1, (0x1 << 15), 0 << 15);
1155
1156 mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
1157 }
1158
1159 mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
1160
1161}
1162
1163static void wlc_lcnphy_set_trsw_override(struct brcms_phy *pi, bool tx, bool rx)
1164{
1165
1166 mod_phy_reg(pi, 0x44d,
1167 (0x1 << 1) |
1168 (0x1 << 0), (tx ? (0x1 << 1) : 0) | (rx ? (0x1 << 0) : 0));
1169
1170 or_phy_reg(pi, 0x44c, (0x1 << 1) | (0x1 << 0));
1171}
1172
1173static void wlc_lcnphy_clear_trsw_override(struct brcms_phy *pi)
1174{
1175
1176 and_phy_reg(pi, 0x44c, (u16) ~((0x1 << 1) | (0x1 << 0)));
1177}
1178
1179static void wlc_lcnphy_set_rx_iq_comp(struct brcms_phy *pi, u16 a, u16 b)
1180{
1181 mod_phy_reg(pi, 0x645, (0x3ff << 0), (a) << 0);
1182
1183 mod_phy_reg(pi, 0x646, (0x3ff << 0), (b) << 0);
1184
1185 mod_phy_reg(pi, 0x647, (0x3ff << 0), (a) << 0);
1186
1187 mod_phy_reg(pi, 0x648, (0x3ff << 0), (b) << 0);
1188
1189 mod_phy_reg(pi, 0x649, (0x3ff << 0), (a) << 0);
1190
1191 mod_phy_reg(pi, 0x64a, (0x3ff << 0), (b) << 0);
1192
1193}
1194
1195static bool
1196wlc_lcnphy_rx_iq_est(struct brcms_phy *pi,
1197 u16 num_samps,
1198 u8 wait_time, struct lcnphy_iq_est *iq_est)
1199{
1200 int wait_count = 0;
1201 bool result = true;
1202 u8 phybw40;
1203 phybw40 = CHSPEC_IS40(pi->radio_chanspec);
1204
1205 mod_phy_reg(pi, 0x6da, (0x1 << 5), (1) << 5);
1206
1207 mod_phy_reg(pi, 0x410, (0x1 << 3), (0) << 3);
1208
1209 mod_phy_reg(pi, 0x482, (0xffff << 0), (num_samps) << 0);
1210
1211 mod_phy_reg(pi, 0x481, (0xff << 0), ((u16) wait_time) << 0);
1212
1213 mod_phy_reg(pi, 0x481, (0x1 << 8), (0) << 8);
1214
1215 mod_phy_reg(pi, 0x481, (0x1 << 9), (1) << 9);
1216
1217 while (read_phy_reg(pi, 0x481) & (0x1 << 9)) {
1218
1219 if (wait_count > (10 * 500)) {
1220 result = false;
1221 goto cleanup;
1222 }
1223 udelay(100);
1224 wait_count++;
1225 }
1226
1227 iq_est->iq_prod = ((u32) read_phy_reg(pi, 0x483) << 16) |
1228 (u32) read_phy_reg(pi, 0x484);
1229 iq_est->i_pwr = ((u32) read_phy_reg(pi, 0x485) << 16) |
1230 (u32) read_phy_reg(pi, 0x486);
1231 iq_est->q_pwr = ((u32) read_phy_reg(pi, 0x487) << 16) |
1232 (u32) read_phy_reg(pi, 0x488);
1233
1234cleanup:
1235 mod_phy_reg(pi, 0x410, (0x1 << 3), (1) << 3);
1236
1237 mod_phy_reg(pi, 0x6da, (0x1 << 5), (0) << 5);
1238
1239 return result;
1240}
1241
1242static bool wlc_lcnphy_calc_rx_iq_comp(struct brcms_phy *pi, u16 num_samps)
1243{
1244#define LCNPHY_MIN_RXIQ_PWR 2
1245 bool result;
1246 u16 a0_new, b0_new;
1247 struct lcnphy_iq_est iq_est = { 0, 0, 0 };
1248 s32 a, b, temp;
1249 s16 iq_nbits, qq_nbits, arsh, brsh;
1250 s32 iq;
1251 u32 ii, qq;
1252 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
1253
1254 a0_new = ((read_phy_reg(pi, 0x645) & (0x3ff << 0)) >> 0);
1255 b0_new = ((read_phy_reg(pi, 0x646) & (0x3ff << 0)) >> 0);
1256 mod_phy_reg(pi, 0x6d1, (0x1 << 2), (0) << 2);
1257
1258 mod_phy_reg(pi, 0x64b, (0x1 << 6), (1) << 6);
1259
1260 wlc_lcnphy_set_rx_iq_comp(pi, 0, 0);
1261
1262 result = wlc_lcnphy_rx_iq_est(pi, num_samps, 32, &iq_est);
1263 if (!result)
1264 goto cleanup;
1265
1266 iq = (s32) iq_est.iq_prod;
1267 ii = iq_est.i_pwr;
1268 qq = iq_est.q_pwr;
1269
1270 if ((ii + qq) < LCNPHY_MIN_RXIQ_PWR) {
1271 result = false;
1272 goto cleanup;
1273 }
1274
1275 iq_nbits = wlc_phy_nbits(iq);
1276 qq_nbits = wlc_phy_nbits(qq);
1277
1278 arsh = 10 - (30 - iq_nbits);
1279 if (arsh >= 0) {
1280 a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
1281 temp = (s32) (ii >> arsh);
1282 if (temp == 0)
1283 return false;
1284 } else {
1285 a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
1286 temp = (s32) (ii << -arsh);
1287 if (temp == 0)
1288 return false;
1289 }
1290 a /= temp;
1291 brsh = qq_nbits - 31 + 20;
1292 if (brsh >= 0) {
1293 b = (qq << (31 - qq_nbits));
1294 temp = (s32) (ii >> brsh);
1295 if (temp == 0)
1296 return false;
1297 } else {
1298 b = (qq << (31 - qq_nbits));
1299 temp = (s32) (ii << -brsh);
1300 if (temp == 0)
1301 return false;
1302 }
1303 b /= temp;
1304 b -= a * a;
1305 b = (s32) int_sqrt((unsigned long) b);
1306 b -= (1 << 10);
1307 a0_new = (u16) (a & 0x3ff);
1308 b0_new = (u16) (b & 0x3ff);
1309cleanup:
1310
1311 wlc_lcnphy_set_rx_iq_comp(pi, a0_new, b0_new);
1312
1313 mod_phy_reg(pi, 0x64b, (0x1 << 0), (1) << 0);
1314
1315 mod_phy_reg(pi, 0x64b, (0x1 << 3), (1) << 3);
1316
1317 pi_lcn->lcnphy_cal_results.rxiqcal_coeff_a0 = a0_new;
1318 pi_lcn->lcnphy_cal_results.rxiqcal_coeff_b0 = b0_new;
1319
1320 return result;
1321}
1322
1323static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
1324{
1325 struct lcnphy_iq_est iq_est = { 0, 0, 0 };
1326
1327 if (!wlc_lcnphy_rx_iq_est(pi, nsamples, 32, &iq_est))
1328 return 0;
1329 return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
1330}
1331
1332static bool
1333wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
1334 const struct lcnphy_rx_iqcomp *iqcomp,
1335 int iqcomp_sz, bool tx_switch, bool rx_switch, int module,
1336 int tx_gain_idx)
1337{
1338 struct lcnphy_txgains old_gains;
1339 u16 tx_pwr_ctrl;
1340 u8 tx_gain_index_old = 0;
1341 bool result = false, tx_gain_override_old = false;
1342 u16 i, Core1TxControl_old, RFOverride0_old,
1343 RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
1344 rfoverride3_old, rfoverride3val_old, rfoverride4_old,
1345 rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
1346 int tia_gain;
1347 u32 received_power, rx_pwr_threshold;
1348 u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
1349 u16 values_to_save[11];
1350 s16 *ptr;
1351 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
1352
1353 ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC);
1354 if (NULL == ptr)
1355 return false;
1356 if (module == 2) {
1357 while (iqcomp_sz--) {
1358 if (iqcomp[iqcomp_sz].chan ==
1359 CHSPEC_CHANNEL(pi->radio_chanspec)) {
1360 wlc_lcnphy_set_rx_iq_comp(pi,
1361 (u16)
1362 iqcomp[iqcomp_sz].a,
1363 (u16)
1364 iqcomp[iqcomp_sz].b);
1365 result = true;
1366 break;
1367 }
1368 }
1369 goto cal_done;
1370 }
1371
1372 if (module == 1) {
1373
1374 tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
1375 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
1376
1377 for (i = 0; i < 11; i++)
1378 values_to_save[i] =
1379 read_radio_reg(pi, rxiq_cal_rf_reg[i]);
1380 Core1TxControl_old = read_phy_reg(pi, 0x631);
1381
1382 or_phy_reg(pi, 0x631, 0x0015);
1383
1384 RFOverride0_old = read_phy_reg(pi, 0x44c);
1385 RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
1386 rfoverride2_old = read_phy_reg(pi, 0x4b0);
1387 rfoverride2val_old = read_phy_reg(pi, 0x4b1);
1388 rfoverride3_old = read_phy_reg(pi, 0x4f9);
1389 rfoverride3val_old = read_phy_reg(pi, 0x4fa);
1390 rfoverride4_old = read_phy_reg(pi, 0x938);
1391 rfoverride4val_old = read_phy_reg(pi, 0x939);
1392 afectrlovr_old = read_phy_reg(pi, 0x43b);
1393 afectrlovrval_old = read_phy_reg(pi, 0x43c);
1394 old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
1395 old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
1396
1397 tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
1398 if (tx_gain_override_old) {
1399 wlc_lcnphy_get_tx_gain(pi, &old_gains);
1400 tx_gain_index_old = pi_lcn->lcnphy_current_index;
1401 }
1402
1403 wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
1404
1405 mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
1406 mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
1407
1408 mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
1409 mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
1410
1411 write_radio_reg(pi, RADIO_2064_REG116, 0x06);
1412 write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
1413 write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
1414 write_radio_reg(pi, RADIO_2064_REG098, 0x03);
1415 write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
1416 mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
1417 write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
1418 write_radio_reg(pi, RADIO_2064_REG114, 0x01);
1419 write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
1420 write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
1421
1422 mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
1423 mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
1424 mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
1425 mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
1426 mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
1427 mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
1428 mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
1429 mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
1430 mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
1431 mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
1432
1433 mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
1434 mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
1435
1436 wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
1437 write_phy_reg(pi, 0x6da, 0xffff);
1438 or_phy_reg(pi, 0x6db, 0x3);
1439 wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
1440 wlc_lcnphy_rx_gain_override_enable(pi, true);
1441
1442 tia_gain = 8;
1443 rx_pwr_threshold = 950;
1444 while (tia_gain > 0) {
1445 tia_gain -= 1;
1446 wlc_lcnphy_set_rx_gain_by_distribution(pi,
1447 0, 0, 2, 2,
1448 (u16)
1449 tia_gain, 1, 0);
1450 udelay(500);
1451
1452 received_power =
1453 wlc_lcnphy_measure_digital_power(pi, 2000);
1454 if (received_power < rx_pwr_threshold)
1455 break;
1456 }
1457 result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
1458
1459 wlc_lcnphy_stop_tx_tone(pi);
1460
1461 write_phy_reg(pi, 0x631, Core1TxControl_old);
1462
1463 write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
1464 write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
1465 write_phy_reg(pi, 0x4b0, rfoverride2_old);
1466 write_phy_reg(pi, 0x4b1, rfoverride2val_old);
1467 write_phy_reg(pi, 0x4f9, rfoverride3_old);
1468 write_phy_reg(pi, 0x4fa, rfoverride3val_old);
1469 write_phy_reg(pi, 0x938, rfoverride4_old);
1470 write_phy_reg(pi, 0x939, rfoverride4val_old);
1471 write_phy_reg(pi, 0x43b, afectrlovr_old);
1472 write_phy_reg(pi, 0x43c, afectrlovrval_old);
1473 write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
1474 write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
1475
1476 wlc_lcnphy_clear_trsw_override(pi);
1477
1478 mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
1479
1480 for (i = 0; i < 11; i++)
1481 write_radio_reg(pi, rxiq_cal_rf_reg[i],
1482 values_to_save[i]);
1483
1484 if (tx_gain_override_old)
1485 wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
1486 else
1487 wlc_lcnphy_disable_tx_gain_override(pi);
1488
1489 wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
1490 wlc_lcnphy_rx_gain_override_enable(pi, false);
1491 }
1492
1493cal_done:
1494 kfree(ptr);
1495 return result;
1496}
1497
1498s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi)
1499{
1500 s8 index;
1501 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
1502
1503 if (txpwrctrl_off(pi))
1504 index = pi_lcn->lcnphy_current_index;
1505 else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
1506 index = (s8) (wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(
1507 pi) / 2);
1508 else
1509 index = pi_lcn->lcnphy_current_index;
1510 return index;
1511}
1512
1513void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel)
1514{
1515 u16 afectrlovr, afectrlovrval;
1516 afectrlovr = read_phy_reg(pi, 0x43b);
1517 afectrlovrval = read_phy_reg(pi, 0x43c);
1518 if (channel != 0) {
1519 mod_phy_reg(pi, 0x43b, (0x1 << 1), (1) << 1);
1520
1521 mod_phy_reg(pi, 0x43c, (0x1 << 1), (0) << 1);
1522
1523 mod_phy_reg(pi, 0x43b, (0x1 << 4), (1) << 4);
1524
1525 mod_phy_reg(pi, 0x43c, (0x1 << 6), (0) << 6);
1526
1527 write_phy_reg(pi, 0x44b, 0xffff);
1528 wlc_lcnphy_tx_pu(pi, 1);
1529
1530 mod_phy_reg(pi, 0x634, (0xff << 8), (0) << 8);
1531
1532 or_phy_reg(pi, 0x6da, 0x0080);
1533
1534 or_phy_reg(pi, 0x00a, 0x228);
1535 } else {
1536 and_phy_reg(pi, 0x00a, ~(0x228));
1537
1538 and_phy_reg(pi, 0x6da, 0xFF7F);
1539 write_phy_reg(pi, 0x43b, afectrlovr);
1540 write_phy_reg(pi, 0x43c, afectrlovrval);
1541 }
1542}
1543
1544static void wlc_lcnphy_toggle_afe_pwdn(struct brcms_phy *pi)
1545{
1546 u16 save_AfeCtrlOvrVal, save_AfeCtrlOvr;
1547
1548 save_AfeCtrlOvrVal = read_phy_reg(pi, 0x43c);
1549 save_AfeCtrlOvr = read_phy_reg(pi, 0x43b);
1550
1551 write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal | 0x1);
1552 write_phy_reg(pi, 0x43b, save_AfeCtrlOvr | 0x1);
1553
1554 write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal & 0xfffe);
1555 write_phy_reg(pi, 0x43b, save_AfeCtrlOvr & 0xfffe);
1556
1557 write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal);
1558 write_phy_reg(pi, 0x43b, save_AfeCtrlOvr);
1559}
1560
1561static void
1562wlc_lcnphy_txrx_spur_avoidance_mode(struct brcms_phy *pi, bool enable)
1563{
1564 if (enable) {
1565 write_phy_reg(pi, 0x942, 0x7);
1566 write_phy_reg(pi, 0x93b, ((1 << 13) + 23));
1567 write_phy_reg(pi, 0x93c, ((1 << 13) + 1989));
1568
1569 write_phy_reg(pi, 0x44a, 0x084);
1570 write_phy_reg(pi, 0x44a, 0x080);
1571 write_phy_reg(pi, 0x6d3, 0x2222);
1572 write_phy_reg(pi, 0x6d3, 0x2220);
1573 } else {
1574 write_phy_reg(pi, 0x942, 0x0);
1575 write_phy_reg(pi, 0x93b, ((0 << 13) + 23));
1576 write_phy_reg(pi, 0x93c, ((0 << 13) + 1989));
1577 }
1578 wlapi_switch_macfreq(pi->sh->physhim, enable);
1579}
1580
1581static void
1582wlc_lcnphy_set_chanspec_tweaks(struct brcms_phy *pi, u16 chanspec)
1583{
1584 u8 channel = CHSPEC_CHANNEL(chanspec);
1585 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
1586
1587 if (channel == 14)
1588 mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
1589 else
1590 mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
1591
1592 pi_lcn->lcnphy_bandedge_corr = 2;
1593 if (channel == 1)
1594 pi_lcn->lcnphy_bandedge_corr = 4;
1595
1596 if (channel == 1 || channel == 2 || channel == 3 ||
1597 channel == 4 || channel == 9 ||
1598 channel == 10 || channel == 11 || channel == 12) {
1599 si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03000c04);
1600 si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x0);
1601 si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x200005c0);
1602
1603 si_pmu_pllupd(pi->sh->sih);
1604 write_phy_reg(pi, 0x942, 0);
1605 wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
1606 pi_lcn->lcnphy_spurmod = 0;
1607 mod_phy_reg(pi, 0x424, (0xff << 8), (0x1b) << 8);
1608
1609 write_phy_reg(pi, 0x425, 0x5907);
1610 } else {
1611 si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03140c04);
1612 si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x333333);
1613 si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x202c2820);
1614
1615 si_pmu_pllupd(pi->sh->sih);
1616 write_phy_reg(pi, 0x942, 0);
1617 wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
1618
1619 pi_lcn->lcnphy_spurmod = 0;
1620 mod_phy_reg(pi, 0x424, (0xff << 8), (0x1f) << 8);
1621
1622 write_phy_reg(pi, 0x425, 0x590a);
1623 }
1624
1625 or_phy_reg(pi, 0x44a, 0x44);
1626 write_phy_reg(pi, 0x44a, 0x80);
1627}
1628
1629static void
1630wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
1631{
1632 uint i;
1633 const struct chan_info_2064_lcnphy *ci;
1634 u8 rfpll_doubler = 0;
1635 u8 pll_pwrup, pll_pwrup_ovr;
1636 s32 qFxtal, qFref, qFvco, qFcal;
1637 u8 d15, d16, f16, e44, e45;
1638 u32 div_int, div_frac, fvco3, fpfd, fref3, fcal_div;
1639 u16 loop_bw, d30, setCount;
1640
1641 u8 h29, h28_ten, e30, h30_ten, cp_current;
1642 u16 g30, d28;
1643
1644 ci = &chan_info_2064_lcnphy[0];
1645 rfpll_doubler = 1;
1646
1647 mod_radio_reg(pi, RADIO_2064_REG09D, 0x4, 0x1 << 2);
1648
1649 write_radio_reg(pi, RADIO_2064_REG09E, 0xf);
1650 if (!rfpll_doubler) {
1651 loop_bw = PLL_2064_LOOP_BW;
1652 d30 = PLL_2064_D30;
1653 } else {
1654 loop_bw = PLL_2064_LOOP_BW_DOUBLER;
1655 d30 = PLL_2064_D30_DOUBLER;
1656 }
1657
1658 if (CHSPEC_IS2G(pi->radio_chanspec)) {
1659 for (i = 0; i < ARRAY_SIZE(chan_info_2064_lcnphy); i++)
1660 if (chan_info_2064_lcnphy[i].chan == channel)
1661 break;
1662
1663 if (i >= ARRAY_SIZE(chan_info_2064_lcnphy))
1664 return;
1665
1666 ci = &chan_info_2064_lcnphy[i];
1667 }
1668
1669 write_radio_reg(pi, RADIO_2064_REG02A, ci->logen_buftune);
1670
1671 mod_radio_reg(pi, RADIO_2064_REG030, 0x3, ci->logen_rccr_tx);
1672
1673 mod_radio_reg(pi, RADIO_2064_REG091, 0x3, ci->txrf_mix_tune_ctrl);
1674
1675 mod_radio_reg(pi, RADIO_2064_REG038, 0xf, ci->pa_input_tune_g);
1676
1677 mod_radio_reg(pi, RADIO_2064_REG030, 0x3 << 2,
1678 (ci->logen_rccr_rx) << 2);
1679
1680 mod_radio_reg(pi, RADIO_2064_REG05E, 0xf, ci->pa_rxrf_lna1_freq_tune);
1681
1682 mod_radio_reg(pi, RADIO_2064_REG05E, (0xf) << 4,
1683 (ci->pa_rxrf_lna2_freq_tune) << 4);
1684
1685 write_radio_reg(pi, RADIO_2064_REG06C, ci->rxrf_rxrf_spare1);
1686
1687 pll_pwrup = (u8) read_radio_reg(pi, RADIO_2064_REG044);
1688 pll_pwrup_ovr = (u8) read_radio_reg(pi, RADIO_2064_REG12B);
1689
1690 or_radio_reg(pi, RADIO_2064_REG044, 0x07);
1691
1692 or_radio_reg(pi, RADIO_2064_REG12B, (0x07) << 1);
1693 e44 = 0;
1694 e45 = 0;
1695
1696 fpfd = rfpll_doubler ? (pi->xtalfreq << 1) : (pi->xtalfreq);
1697 if (pi->xtalfreq > 26000000)
1698 e44 = 1;
1699 if (pi->xtalfreq > 52000000)
1700 e45 = 1;
1701 if (e44 == 0)
1702 fcal_div = 1;
1703 else if (e45 == 0)
1704 fcal_div = 2;
1705 else
1706 fcal_div = 4;
1707 fvco3 = (ci->freq * 3);
1708 fref3 = 2 * fpfd;
1709
1710 qFxtal = wlc_lcnphy_qdiv_roundup(pi->xtalfreq, PLL_2064_MHZ, 16);
1711 qFref = wlc_lcnphy_qdiv_roundup(fpfd, PLL_2064_MHZ, 16);
1712 qFcal = pi->xtalfreq * fcal_div / PLL_2064_MHZ;
1713 qFvco = wlc_lcnphy_qdiv_roundup(fvco3, 2, 16);
1714
1715 write_radio_reg(pi, RADIO_2064_REG04F, 0x02);
1716
1717 d15 = (pi->xtalfreq * fcal_div * 4 / 5) / PLL_2064_MHZ - 1;
1718 write_radio_reg(pi, RADIO_2064_REG052, (0x07 & (d15 >> 2)));
1719 write_radio_reg(pi, RADIO_2064_REG053, (d15 & 0x3) << 5);
1720
1721 d16 = (qFcal * 8 / (d15 + 1)) - 1;
1722 write_radio_reg(pi, RADIO_2064_REG051, d16);
1723
1724 f16 = ((d16 + 1) * (d15 + 1)) / qFcal;
1725 setCount = f16 * 3 * (ci->freq) / 32 - 1;
1726 mod_radio_reg(pi, RADIO_2064_REG053, (0x0f << 0),
1727 (u8) (setCount >> 8));
1728
1729 or_radio_reg(pi, RADIO_2064_REG053, 0x10);
1730 write_radio_reg(pi, RADIO_2064_REG054, (u8) (setCount & 0xff));
1731
1732 div_int = ((fvco3 * (PLL_2064_MHZ >> 4)) / fref3) << 4;
1733
1734 div_frac = ((fvco3 * (PLL_2064_MHZ >> 4)) % fref3) << 4;
1735 while (div_frac >= fref3) {
1736 div_int++;
1737 div_frac -= fref3;
1738 }
1739 div_frac = wlc_lcnphy_qdiv_roundup(div_frac, fref3, 20);
1740
1741 mod_radio_reg(pi, RADIO_2064_REG045, (0x1f << 0),
1742 (u8) (div_int >> 4));
1743 mod_radio_reg(pi, RADIO_2064_REG046, (0x1f << 4),
1744 (u8) (div_int << 4));
1745 mod_radio_reg(pi, RADIO_2064_REG046, (0x0f << 0),
1746 (u8) (div_frac >> 16));
1747 write_radio_reg(pi, RADIO_2064_REG047, (u8) (div_frac >> 8) & 0xff);
1748 write_radio_reg(pi, RADIO_2064_REG048, (u8) div_frac & 0xff);
1749
1750 write_radio_reg(pi, RADIO_2064_REG040, 0xfb);
1751
1752 write_radio_reg(pi, RADIO_2064_REG041, 0x9A);
1753 write_radio_reg(pi, RADIO_2064_REG042, 0xA3);
1754 write_radio_reg(pi, RADIO_2064_REG043, 0x0C);
1755
1756 h29 = LCN_BW_LMT / loop_bw;
1757 d28 = (((PLL_2064_HIGH_END_KVCO - PLL_2064_LOW_END_KVCO) *
1758 (fvco3 / 2 - PLL_2064_LOW_END_VCO)) /
1759 (PLL_2064_HIGH_END_VCO - PLL_2064_LOW_END_VCO))
1760 + PLL_2064_LOW_END_KVCO;
1761 h28_ten = (d28 * 10) / LCN_VCO_DIV;
1762 e30 = (d30 - LCN_OFFSET) / LCN_FACT;
1763 g30 = LCN_OFFSET + (e30 * LCN_FACT);
1764 h30_ten = (g30 * 10) / LCN_CUR_DIV;
1765 cp_current = ((LCN_CUR_LMT * h29 * LCN_MULT * 100) / h28_ten) / h30_ten;
1766 mod_radio_reg(pi, RADIO_2064_REG03C, 0x3f, cp_current);
1767
1768 if (channel >= 1 && channel <= 5)
1769 write_radio_reg(pi, RADIO_2064_REG03C, 0x8);
1770 else
1771 write_radio_reg(pi, RADIO_2064_REG03C, 0x7);
1772 write_radio_reg(pi, RADIO_2064_REG03D, 0x3);
1773
1774 mod_radio_reg(pi, RADIO_2064_REG044, 0x0c, 0x0c);
1775 udelay(1);
1776
1777 wlc_2064_vco_cal(pi);
1778
1779 write_radio_reg(pi, RADIO_2064_REG044, pll_pwrup);
1780 write_radio_reg(pi, RADIO_2064_REG12B, pll_pwrup_ovr);
1781 if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
1782 write_radio_reg(pi, RADIO_2064_REG038, 3);
1783 write_radio_reg(pi, RADIO_2064_REG091, 7);
1784 }
1785}
1786
1787static int
1788wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm, s16 filt_type)
1789{
1790 s16 filt_index = -1;
1791 int j;
1792
1793 u16 addr[] = {
1794 0x910,
1795 0x91e,
1796 0x91f,
1797 0x924,
1798 0x925,
1799 0x926,
1800 0x920,
1801 0x921,
1802 0x927,
1803 0x928,
1804 0x929,
1805 0x922,
1806 0x923,
1807 0x930,
1808 0x931,
1809 0x932
1810 };
1811
1812 u16 addr_ofdm[] = {
1813 0x90f,
1814 0x900,
1815 0x901,
1816 0x906,
1817 0x907,
1818 0x908,
1819 0x902,
1820 0x903,
1821 0x909,
1822 0x90a,
1823 0x90b,
1824 0x904,
1825 0x905,
1826 0x90c,
1827 0x90d,
1828 0x90e
1829 };
1830
1831 if (!is_ofdm) {
1832 for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_CCK; j++) {
1833 if (filt_type == LCNPHY_txdigfiltcoeffs_cck[j][0]) {
1834 filt_index = (s16) j;
1835 break;
1836 }
1837 }
1838
1839 if (filt_index != -1) {
1840 for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++)
1841 write_phy_reg(pi, addr[j],
1842 LCNPHY_txdigfiltcoeffs_cck
1843 [filt_index][j + 1]);
1844 }
1845 } else {
1846 for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_OFDM; j++) {
1847 if (filt_type == LCNPHY_txdigfiltcoeffs_ofdm[j][0]) {
1848 filt_index = (s16) j;
1849 break;
1850 }
1851 }
1852
1853 if (filt_index != -1) {
1854 for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++)
1855 write_phy_reg(pi, addr_ofdm[j],
1856 LCNPHY_txdigfiltcoeffs_ofdm
1857 [filt_index][j + 1]);
1858 }
1859 }
1860
1861 return (filt_index != -1) ? 0 : -1;
1862}
1863
1864void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
1865{
1866 u8 channel = CHSPEC_CHANNEL(chanspec);
1867
1868 wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec);
1869
1870 wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec);
1871
1872 or_phy_reg(pi, 0x44a, 0x44);
1873 write_phy_reg(pi, 0x44a, 0x80);
1874
1875 wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel);
1876 udelay(1000);
1877
1878 wlc_lcnphy_toggle_afe_pwdn(pi);
1879
1880 write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20);
1881 write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor);
1882
1883 if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
1884 mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
1885
1886 wlc_lcnphy_load_tx_iir_filter(pi, false, 3);
1887 } else {
1888 mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
1889
1890 wlc_lcnphy_load_tx_iir_filter(pi, false, 2);
1891 }
1892
1893 wlc_lcnphy_load_tx_iir_filter(pi, true, 0);
1894
1895 mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
1896
1897}
1898
1899static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi)
1900{
1901 u16 pa_gain;
1902
1903 pa_gain = (read_phy_reg(pi, 0x4fb) &
1904 LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK) >>
1905 LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT;
1906
1907 return pa_gain;
1908}
1909
1910static void wlc_lcnphy_set_tx_gain(struct brcms_phy *pi,
1911 struct lcnphy_txgains *target_gains)
1912{
1913 u16 pa_gain = wlc_lcnphy_get_pa_gain(pi);
1914
1915 mod_phy_reg(
1916 pi, 0x4b5,
1917 (0xffff << 0),
1918 ((target_gains->gm_gain) |
1919 (target_gains->pga_gain << 8)) <<
1920 0);
1921 mod_phy_reg(pi, 0x4fb,
1922 (0x7fff << 0),
1923 ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
1924
1925 mod_phy_reg(
1926 pi, 0x4fc,
1927 (0xffff << 0),
1928 ((target_gains->gm_gain) |
1929 (target_gains->pga_gain << 8)) <<
1930 0);
1931 mod_phy_reg(pi, 0x4fd,
1932 (0x7fff << 0),
1933 ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
1934
1935 wlc_lcnphy_set_dac_gain(pi, target_gains->dac_gain);
1936
1937 wlc_lcnphy_enable_tx_gain_override(pi);
1938}
1939
1940static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0)
1941{
1942 u16 m0m1 = (u16) m0 << 8;
1943 struct phytbl_info tab;
1944
1945 tab.tbl_ptr = &m0m1;
1946 tab.tbl_len = 1;
1947 tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
1948 tab.tbl_offset = 87;
1949 tab.tbl_width = 16;
1950 wlc_lcnphy_write_table(pi, &tab);
1951}
1952
1953static void wlc_lcnphy_clear_tx_power_offsets(struct brcms_phy *pi)
1954{
1955 u32 data_buf[64];
1956 struct phytbl_info tab;
1957
1958 memset(data_buf, 0, sizeof(data_buf));
1959
1960 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
1961 tab.tbl_width = 32;
1962 tab.tbl_ptr = data_buf;
1963
1964 if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
1965
1966 tab.tbl_len = 30;
1967 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
1968 wlc_lcnphy_write_table(pi, &tab);
1969 }
1970
1971 tab.tbl_len = 64;
1972 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_MAC_OFFSET;
1973 wlc_lcnphy_write_table(pi, &tab);
1974}
1975
1976enum lcnphy_tssi_mode {
1977 LCNPHY_TSSI_PRE_PA,
1978 LCNPHY_TSSI_POST_PA,
1979 LCNPHY_TSSI_EXT
1980};
1981
1982static void
1983wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
1984{
1985 mod_phy_reg(pi, 0x4d7, (0x1 << 0), (0x1) << 0);
1986
1987 mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1) << 6);
1988
1989 if (LCNPHY_TSSI_POST_PA == pos) {
1990 mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0) << 2);
1991
1992 mod_phy_reg(pi, 0x4d9, (0x1 << 3), (1) << 3);
1993
1994 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
1995 mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
1996 } else {
1997 mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
1998 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
1999 }
2000 } else {
2001 mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
2002
2003 mod_phy_reg(pi, 0x4d9, (0x1 << 3), (0) << 3);
2004
2005 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
2006 mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
2007 } else {
2008 mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
2009 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
2010 }
2011 }
2012 mod_phy_reg(pi, 0x637, (0x3 << 14), (0) << 14);
2013
2014 if (LCNPHY_TSSI_EXT == pos) {
2015 write_radio_reg(pi, RADIO_2064_REG07F, 1);
2016 mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 0x2);
2017 mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 0x1 << 7);
2018 mod_radio_reg(pi, RADIO_2064_REG028, 0x1f, 0x3);
2019 }
2020}
2021
2022static u16 wlc_lcnphy_rfseq_tbl_adc_pwrup(struct brcms_phy *pi)
2023{
2024 u16 N1, N2, N3, N4, N5, N6, N;
2025 N1 = ((read_phy_reg(pi, 0x4a5) & (0xff << 0))
2026 >> 0);
2027 N2 = 1 << ((read_phy_reg(pi, 0x4a5) & (0x7 << 12))
2028 >> 12);
2029 N3 = ((read_phy_reg(pi, 0x40d) & (0xff << 0))
2030 >> 0);
2031 N4 = 1 << ((read_phy_reg(pi, 0x40d) & (0x7 << 8))
2032 >> 8);
2033 N5 = ((read_phy_reg(pi, 0x4a2) & (0xff << 0))
2034 >> 0);
2035 N6 = 1 << ((read_phy_reg(pi, 0x4a2) & (0x7 << 8))
2036 >> 8);
2037 N = 2 * (N1 + N2 + N3 + N4 + 2 * (N5 + N6)) + 80;
2038 if (N < 1600)
2039 N = 1600;
2040 return N;
2041}
2042
2043static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
2044{
2045 u16 auxpga_vmid, auxpga_vmid_temp, auxpga_gain_temp;
2046 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
2047
2048 auxpga_vmid = (2 << 8) |
2049 (pi_lcn->lcnphy_rssi_vc << 4) | pi_lcn->lcnphy_rssi_vf;
2050 auxpga_vmid_temp = (2 << 8) | (8 << 4) | 4;
2051 auxpga_gain_temp = 2;
2052
2053 mod_phy_reg(pi, 0x4d8, (0x1 << 0), (0) << 0);
2054
2055 mod_phy_reg(pi, 0x4d8, (0x1 << 1), (0) << 1);
2056
2057 mod_phy_reg(pi, 0x4d7, (0x1 << 3), (0) << 3);
2058
2059 mod_phy_reg(pi, 0x4db,
2060 (0x3ff << 0) |
2061 (0x7 << 12),
2062 (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
2063
2064 mod_phy_reg(pi, 0x4dc,
2065 (0x3ff << 0) |
2066 (0x7 << 12),
2067 (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
2068
2069 mod_phy_reg(pi, 0x40a,
2070 (0x3ff << 0) |
2071 (0x7 << 12),
2072 (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
2073
2074 mod_phy_reg(pi, 0x40b,
2075 (0x3ff << 0) |
2076 (0x7 << 12),
2077 (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
2078
2079 mod_phy_reg(pi, 0x40c,
2080 (0x3ff << 0) |
2081 (0x7 << 12),
2082 (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
2083
2084 mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
2085}
2086
2087static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
2088{
2089 struct phytbl_info tab;
2090 u32 rfseq, ind;
2091
2092 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
2093 tab.tbl_width = 32;
2094 tab.tbl_ptr = &ind;
2095 tab.tbl_len = 1;
2096 tab.tbl_offset = 0;
2097 for (ind = 0; ind < 128; ind++) {
2098 wlc_lcnphy_write_table(pi, &tab);
2099 tab.tbl_offset++;
2100 }
2101 tab.tbl_offset = 704;
2102 for (ind = 0; ind < 128; ind++) {
2103 wlc_lcnphy_write_table(pi, &tab);
2104 tab.tbl_offset++;
2105 }
2106 mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
2107
2108 mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
2109
2110 mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
2111
2112 wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
2113 mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
2114
2115 mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
2116
2117 mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
2118
2119 mod_phy_reg(pi, 0x4a4, (0x1ff << 0), (0) << 0);
2120
2121 mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
2122
2123 mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
2124
2125 mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
2126
2127 mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
2128
2129 mod_phy_reg(pi, 0x40d, (0x7 << 8), (4) << 8);
2130
2131 mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
2132
2133 mod_phy_reg(pi, 0x4a2, (0x7 << 8), (4) << 8);
2134
2135 mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (0) << 6);
2136
2137 mod_phy_reg(pi, 0x4a8, (0xff << 0), (0x1) << 0);
2138
2139 wlc_lcnphy_clear_tx_power_offsets(pi);
2140
2141 mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
2142
2143 mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (0xff) << 0);
2144
2145 mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
2146
2147 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
2148 mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
2149 mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
2150 } else {
2151 mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
2152 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
2153 }
2154
2155 write_radio_reg(pi, RADIO_2064_REG025, 0xc);
2156
2157 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
2158 mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
2159 } else {
2160 if (CHSPEC_IS2G(pi->radio_chanspec))
2161 mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
2162 else
2163 mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 0 << 1);
2164 }
2165
2166 if (LCNREV_IS(pi->pubpi.phy_rev, 2))
2167 mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
2168 else
2169 mod_radio_reg(pi, RADIO_2064_REG03A, 0x4, 1 << 2);
2170
2171 mod_radio_reg(pi, RADIO_2064_REG11A, 0x1, 1 << 0);
2172
2173 mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 1 << 3);
2174
2175 if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
2176 mod_phy_reg(pi, 0x4d7,
2177 (0x1 << 3) | (0x7 << 12), 0 << 3 | 2 << 12);
2178
2179 rfseq = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
2180 tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
2181 tab.tbl_width = 16;
2182 tab.tbl_ptr = &rfseq;
2183 tab.tbl_len = 1;
2184 tab.tbl_offset = 6;
2185 wlc_lcnphy_write_table(pi, &tab);
2186
2187 mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
2188
2189 mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
2190
2191 mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
2192
2193 mod_phy_reg(pi, 0x4d7, (0x1 << 2), (1) << 2);
2194
2195 mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
2196
2197 wlc_lcnphy_pwrctrl_rssiparams(pi);
2198}
2199
2200void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi)
2201{
2202 u16 tx_cnt, tx_total, npt;
2203 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
2204
2205 tx_total = wlc_lcnphy_total_tx_frames(pi);
2206 tx_cnt = tx_total - pi_lcn->lcnphy_tssi_tx_cnt;
2207 npt = wlc_lcnphy_get_tx_pwr_npt(pi);
2208
2209 if (tx_cnt > (1 << npt)) {
2210
2211 pi_lcn->lcnphy_tssi_tx_cnt = tx_total;
2212
2213 pi_lcn->lcnphy_tssi_idx = wlc_lcnphy_get_current_tx_pwr_idx(pi);
2214 pi_lcn->lcnphy_tssi_npt = npt;
2215
2216 }
2217}
2218
2219s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1)
2220{
2221 s32 a, b, p;
2222
2223 a = 32768 + (a1 * tssi);
2224 b = (1024 * b0) + (64 * b1 * tssi);
2225 p = ((2 * b) + a) / (2 * a);
2226
2227 return p;
2228}
2229
2230static void wlc_lcnphy_txpower_reset_npt(struct brcms_phy *pi)
2231{
2232 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
2233 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
2234 return;
2235
2236 pi_lcn->lcnphy_tssi_idx = LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313;
2237 pi_lcn->lcnphy_tssi_npt = LCNPHY_TX_PWR_CTRL_START_NPT;
2238}
2239
2240void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi)
2241{
2242 struct phytbl_info tab;
2243 u32 rate_table[BRCMS_NUM_RATES_CCK + BRCMS_NUM_RATES_OFDM +
2244 BRCMS_NUM_RATES_MCS_1_STREAM];
2245 uint i, j;
2246 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
2247 return;
2248
2249 for (i = 0, j = 0; i < ARRAY_SIZE(rate_table); i++, j++) {
2250
2251 if (i == BRCMS_NUM_RATES_CCK + BRCMS_NUM_RATES_OFDM)
2252 j = TXP_FIRST_MCS_20_SISO;
2253
2254 rate_table[i] = (u32) ((s32) (-pi->tx_power_offset[j]));
2255 }
2256
2257 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
2258 tab.tbl_width = 32;
2259 tab.tbl_len = ARRAY_SIZE(rate_table);
2260 tab.tbl_ptr = rate_table;
2261 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
2262 wlc_lcnphy_write_table(pi, &tab);
2263
2264 if (wlc_lcnphy_get_target_tx_pwr(pi) != pi->tx_power_min) {
2265 wlc_lcnphy_set_target_tx_pwr(pi, pi->tx_power_min);
2266
2267 wlc_lcnphy_txpower_reset_npt(pi);
2268 }
2269}
2270
2271static void wlc_lcnphy_set_tx_pwr_soft_ctrl(struct brcms_phy *pi, s8 index)
2272{
2273 u32 cck_offset[4] = { 22, 22, 22, 22 };
2274 u32 ofdm_offset, reg_offset_cck;
2275 int i;
2276 u16 index2;
2277 struct phytbl_info tab;
2278
2279 if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
2280 return;
2281
2282 mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
2283
2284 mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x0) << 14);
2285
2286 or_phy_reg(pi, 0x6da, 0x0040);
2287
2288 reg_offset_cck = 0;
2289 for (i = 0; i < 4; i++)
2290 cck_offset[i] -= reg_offset_cck;
2291 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
2292 tab.tbl_width = 32;
2293 tab.tbl_len = 4;
2294 tab.tbl_ptr = cck_offset;
2295 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
2296 wlc_lcnphy_write_table(pi, &tab);
2297 ofdm_offset = 0;
2298 tab.tbl_len = 1;
2299 tab.tbl_ptr = &ofdm_offset;
2300 for (i = 836; i < 862; i++) {
2301 tab.tbl_offset = i;
2302 wlc_lcnphy_write_table(pi, &tab);
2303 }
2304
2305 mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0x1) << 15);
2306
2307 mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
2308
2309 mod_phy_reg(pi, 0x4a4, (0x1 << 13), (0x1) << 13);
2310
2311 mod_phy_reg(pi, 0x4b0, (0x1 << 7), (0) << 7);
2312
2313 mod_phy_reg(pi, 0x43b, (0x1 << 6), (0) << 6);
2314
2315 mod_phy_reg(pi, 0x4a9, (0x1 << 15), (1) << 15);
2316
2317 index2 = (u16) (index * 2);
2318 mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
2319
2320 mod_phy_reg(pi, 0x6a3, (0x1 << 4), (0) << 4);
2321
2322}
2323
2324static s8 wlc_lcnphy_tempcompensated_txpwrctrl(struct brcms_phy *pi)
2325{
2326 s8 index, delta_brd, delta_temp, new_index, tempcorrx;
2327 s16 manp, meas_temp, temp_diff;
2328 bool neg = 0;
2329 u16 temp;
2330 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
2331
2332 if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
2333 return pi_lcn->lcnphy_current_index;
2334
2335 index = FIXED_TXPWR;
2336
2337 if (pi_lcn->lcnphy_tempsense_slope == 0)
2338 return index;
2339
2340 temp = (u16) wlc_lcnphy_tempsense(pi, 0);
2341 meas_temp = LCNPHY_TEMPSENSE(temp);
2342
2343 if (pi->tx_power_min != 0)
2344 delta_brd = (pi_lcn->lcnphy_measPower - pi->tx_power_min);
2345 else
2346 delta_brd = 0;
2347
2348 manp = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_rawtempsense);
2349 temp_diff = manp - meas_temp;
2350 if (temp_diff < 0) {
2351 neg = 1;
2352 temp_diff = -temp_diff;
2353 }
2354
2355 delta_temp = (s8) wlc_lcnphy_qdiv_roundup((u32) (temp_diff * 192),
2356 (u32) (pi_lcn->
2357 lcnphy_tempsense_slope
2358 * 10), 0);
2359 if (neg)
2360 delta_temp = -delta_temp;
2361
2362 if (pi_lcn->lcnphy_tempsense_option == 3
2363 && LCNREV_IS(pi->pubpi.phy_rev, 0))
2364 delta_temp = 0;
2365 if (pi_lcn->lcnphy_tempcorrx > 31)
2366 tempcorrx = (s8) (pi_lcn->lcnphy_tempcorrx - 64);
2367 else
2368 tempcorrx = (s8) pi_lcn->lcnphy_tempcorrx;
2369 if (LCNREV_IS(pi->pubpi.phy_rev, 1))
2370 tempcorrx = 4;
2371 new_index =
2372 index + delta_brd + delta_temp - pi_lcn->lcnphy_bandedge_corr;
2373 new_index += tempcorrx;
2374
2375 if (LCNREV_IS(pi->pubpi.phy_rev, 1))
2376 index = 127;
2377
2378 if (new_index < 0 || new_index > 126)
2379 return index;
2380
2381 return new_index;
2382}
2383
2384static u16 wlc_lcnphy_set_tx_pwr_ctrl_mode(struct brcms_phy *pi, u16 mode)
2385{
2386
2387 u16 current_mode = mode;
2388 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) &&
2389 mode == LCNPHY_TX_PWR_CTRL_HW)
2390 current_mode = LCNPHY_TX_PWR_CTRL_TEMPBASED;
2391 if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
2392 mode == LCNPHY_TX_PWR_CTRL_TEMPBASED)
2393 current_mode = LCNPHY_TX_PWR_CTRL_HW;
2394 return current_mode;
2395}
2396
2397void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode)
2398{
2399 u16 old_mode = wlc_lcnphy_get_tx_pwr_ctrl(pi);
2400 s8 index;
2401 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
2402
2403 mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, mode);
2404 old_mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, old_mode);
2405
2406 mod_phy_reg(pi, 0x6da, (0x1 << 6),
2407 ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 1 : 0) << 6);
2408
2409 mod_phy_reg(pi, 0x6a3, (0x1 << 4),
2410 ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 0 : 1) << 4);
2411
2412 if (old_mode != mode) {
2413 if (LCNPHY_TX_PWR_CTRL_HW == old_mode) {
2414
2415 wlc_lcnphy_tx_pwr_update_npt(pi);
2416
2417 wlc_lcnphy_clear_tx_power_offsets(pi);
2418 }
2419 if (LCNPHY_TX_PWR_CTRL_HW == mode) {
2420
2421 wlc_lcnphy_txpower_recalc_target(pi);
2422
2423 wlc_lcnphy_set_start_tx_pwr_idx(pi,
2424 pi_lcn->
2425 lcnphy_tssi_idx);
2426 wlc_lcnphy_set_tx_pwr_npt(pi, pi_lcn->lcnphy_tssi_npt);
2427 mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0);
2428
2429 pi_lcn->lcnphy_tssi_tx_cnt =
2430 wlc_lcnphy_total_tx_frames(pi);
2431
2432 wlc_lcnphy_disable_tx_gain_override(pi);
2433 pi_lcn->lcnphy_tx_power_idx_override = -1;
2434 } else
2435 wlc_lcnphy_enable_tx_gain_override(pi);
2436
2437 mod_phy_reg(pi, 0x4a4,
2438 ((0x1 << 15) | (0x1 << 14) | (0x1 << 13)), mode);
2439 if (mode == LCNPHY_TX_PWR_CTRL_TEMPBASED) {
2440 index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
2441 wlc_lcnphy_set_tx_pwr_soft_ctrl(pi, index);
2442 pi_lcn->lcnphy_current_index = (s8)
2443 ((read_phy_reg(pi,
2444 0x4a9) &
2445 0xFF) / 2);
2446 }
2447 }
2448}
2449
2450static void
2451wlc_lcnphy_tx_iqlo_loopback(struct brcms_phy *pi, u16 *values_to_save)
2452{
2453 u16 vmid;
2454 int i;
2455 for (i = 0; i < 20; i++)
2456 values_to_save[i] =
2457 read_radio_reg(pi, iqlo_loopback_rf_regs[i]);
2458
2459 mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
2460 mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
2461
2462 mod_phy_reg(pi, 0x44c, (0x1 << 11), 1 << 11);
2463 mod_phy_reg(pi, 0x44d, (0x1 << 13), 0 << 13);
2464
2465 mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
2466 mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
2467
2468 mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
2469 mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
2470
2471 if (LCNREV_IS(pi->pubpi.phy_rev, 2))
2472 and_radio_reg(pi, RADIO_2064_REG03A, 0xFD);
2473 else
2474 and_radio_reg(pi, RADIO_2064_REG03A, 0xF9);
2475 or_radio_reg(pi, RADIO_2064_REG11A, 0x1);
2476
2477 or_radio_reg(pi, RADIO_2064_REG036, 0x01);
2478 or_radio_reg(pi, RADIO_2064_REG11A, 0x18);
2479 udelay(20);
2480
2481 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
2482 if (CHSPEC_IS5G(pi->radio_chanspec))
2483 mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
2484 else
2485 or_radio_reg(pi, RADIO_2064_REG03A, 1);
2486 } else {
2487 if (CHSPEC_IS5G(pi->radio_chanspec))
2488 mod_radio_reg(pi, RADIO_2064_REG03A, 3, 1);
2489 else
2490 or_radio_reg(pi, RADIO_2064_REG03A, 0x3);
2491 }
2492
2493 udelay(20);
2494
2495 write_radio_reg(pi, RADIO_2064_REG025, 0xF);
2496 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
2497 if (CHSPEC_IS5G(pi->radio_chanspec))
2498 mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x4);
2499 else
2500 mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x6);
2501 } else {
2502 if (CHSPEC_IS5G(pi->radio_chanspec))
2503 mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x4 << 1);
2504 else
2505 mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x6 << 1);
2506 }
2507
2508 udelay(20);
2509
2510 write_radio_reg(pi, RADIO_2064_REG005, 0x8);
2511 or_radio_reg(pi, RADIO_2064_REG112, 0x80);
2512 udelay(20);
2513
2514 or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
2515 or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
2516 udelay(20);
2517
2518 or_radio_reg(pi, RADIO_2064_REG00B, 0x7);
2519 or_radio_reg(pi, RADIO_2064_REG113, 0x10);
2520 udelay(20);
2521
2522 write_radio_reg(pi, RADIO_2064_REG007, 0x1);
2523 udelay(20);
2524
2525 vmid = 0x2A6;
2526 mod_radio_reg(pi, RADIO_2064_REG0FC, 0x3 << 0, (vmid >> 8) & 0x3);
2527 write_radio_reg(pi, RADIO_2064_REG0FD, (vmid & 0xff));
2528 or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
2529 udelay(20);
2530
2531 or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
2532 udelay(20);
2533 write_radio_reg(pi, RADIO_2064_REG012, 0x02);
2534 or_radio_reg(pi, RADIO_2064_REG112, 0x06);
2535 write_radio_reg(pi, RADIO_2064_REG036, 0x11);
2536 write_radio_reg(pi, RADIO_2064_REG059, 0xcc);
2537 write_radio_reg(pi, RADIO_2064_REG05C, 0x2e);
2538 write_radio_reg(pi, RADIO_2064_REG078, 0xd7);
2539 write_radio_reg(pi, RADIO_2064_REG092, 0x15);
2540}
2541
2542static bool wlc_lcnphy_iqcal_wait(struct brcms_phy *pi)
2543{
2544 uint delay_count = 0;
2545
2546 while (wlc_lcnphy_iqcal_active(pi)) {
2547 udelay(100);
2548 delay_count++;
2549
2550 if (delay_count > (10 * 500))
2551 break;
2552 }
2553
2554 return (0 == wlc_lcnphy_iqcal_active(pi));
2555}
2556
2557static void
2558wlc_lcnphy_tx_iqlo_loopback_cleanup(struct brcms_phy *pi, u16 *values_to_save)
2559{
2560 int i;
2561
2562 and_phy_reg(pi, 0x44c, 0x0 >> 11);
2563
2564 and_phy_reg(pi, 0x43b, 0xC);
2565
2566 for (i = 0; i < 20; i++)
2567 write_radio_reg(pi, iqlo_loopback_rf_regs[i],
2568 values_to_save[i]);
2569}
2570
2571static void
2572wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi,
2573 struct lcnphy_txgains *target_gains,
2574 enum lcnphy_cal_mode cal_mode, bool keep_tone)
2575{
2576
2577 struct lcnphy_txgains cal_gains, temp_gains;
2578 u16 hash;
2579 u8 band_idx;
2580 int j;
2581 u16 ncorr_override[5];
2582 u16 syst_coeffs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2583 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
2584
2585 u16 commands_fullcal[] = {
2586 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234
2587 };
2588
2589 u16 commands_recal[] = {
2590 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234
2591 };
2592
2593 u16 command_nums_fullcal[] = {
2594 0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97
2595 };
2596
2597 u16 command_nums_recal[] = {
2598 0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97
2599 };
2600 u16 *command_nums = command_nums_fullcal;
2601
2602 u16 *start_coeffs = NULL, *cal_cmds = NULL, cal_type, diq_start;
2603 u16 tx_pwr_ctrl_old, save_txpwrctrlrfctrl2;
2604 u16 save_sslpnCalibClkEnCtrl, save_sslpnRxFeClkEnCtrl;
2605 bool tx_gain_override_old;
2606 struct lcnphy_txgains old_gains;
2607 uint i, n_cal_cmds = 0, n_cal_start = 0;
2608 u16 *values_to_save;
2609 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
2610
2611 values_to_save = kmalloc(sizeof(u16) * 20, GFP_ATOMIC);
2612 if (NULL == values_to_save)
2613 return;
2614
2615 save_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
2616 save_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
2617
2618 or_phy_reg(pi, 0x6da, 0x40);
2619 or_phy_reg(pi, 0x6db, 0x3);
2620
2621 switch (cal_mode) {
2622 case LCNPHY_CAL_FULL:
2623 start_coeffs = syst_coeffs;
2624 cal_cmds = commands_fullcal;
2625 n_cal_cmds = ARRAY_SIZE(commands_fullcal);
2626 break;
2627
2628 case LCNPHY_CAL_RECAL:
2629 start_coeffs = syst_coeffs;
2630 cal_cmds = commands_recal;
2631 n_cal_cmds = ARRAY_SIZE(commands_recal);
2632 command_nums = command_nums_recal;
2633 break;
2634
2635 default:
2636 break;
2637 }
2638
2639 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2640 start_coeffs, 11, 16, 64);
2641
2642 write_phy_reg(pi, 0x6da, 0xffff);
2643 mod_phy_reg(pi, 0x503, (0x1 << 3), (1) << 3);
2644
2645 tx_pwr_ctrl_old = wlc_lcnphy_get_tx_pwr_ctrl(pi);
2646
2647 mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
2648
2649 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
2650
2651 save_txpwrctrlrfctrl2 = read_phy_reg(pi, 0x4db);
2652
2653 mod_phy_reg(pi, 0x4db, (0x3ff << 0), (0x2a6) << 0);
2654
2655 mod_phy_reg(pi, 0x4db, (0x7 << 12), (2) << 12);
2656
2657 wlc_lcnphy_tx_iqlo_loopback(pi, values_to_save);
2658
2659 tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
2660 if (tx_gain_override_old)
2661 wlc_lcnphy_get_tx_gain(pi, &old_gains);
2662
2663 if (!target_gains) {
2664 if (!tx_gain_override_old)
2665 wlc_lcnphy_set_tx_pwr_by_index(pi,
2666 pi_lcn->lcnphy_tssi_idx);
2667 wlc_lcnphy_get_tx_gain(pi, &temp_gains);
2668 target_gains = &temp_gains;
2669 }
2670
2671 hash = (target_gains->gm_gain << 8) |
2672 (target_gains->pga_gain << 4) | (target_gains->pad_gain);
2673
2674 band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
2675
2676 cal_gains = *target_gains;
2677 memset(ncorr_override, 0, sizeof(ncorr_override));
2678 for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) {
2679 if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) {
2680 cal_gains.gm_gain =
2681 tbl_iqcal_gainparams_lcnphy[band_idx][j][1];
2682 cal_gains.pga_gain =
2683 tbl_iqcal_gainparams_lcnphy[band_idx][j][2];
2684 cal_gains.pad_gain =
2685 tbl_iqcal_gainparams_lcnphy[band_idx][j][3];
2686 memcpy(ncorr_override,
2687 &tbl_iqcal_gainparams_lcnphy[band_idx][j][3],
2688 sizeof(ncorr_override));
2689 break;
2690 }
2691 }
2692
2693 wlc_lcnphy_set_tx_gain(pi, &cal_gains);
2694
2695 write_phy_reg(pi, 0x453, 0xaa9);
2696 write_phy_reg(pi, 0x93d, 0xc0);
2697
2698 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2699 lcnphy_iqcal_loft_gainladder,
2700 ARRAY_SIZE(lcnphy_iqcal_loft_gainladder),
2701 16, 0);
2702
2703 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2704 lcnphy_iqcal_ir_gainladder,
2705 ARRAY_SIZE(
2706 lcnphy_iqcal_ir_gainladder), 16,
2707 32);
2708
2709 if (pi->phy_tx_tone_freq) {
2710
2711 wlc_lcnphy_stop_tx_tone(pi);
2712 udelay(5);
2713 wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
2714 } else {
2715 wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
2716 }
2717
2718 write_phy_reg(pi, 0x6da, 0xffff);
2719
2720 for (i = n_cal_start; i < n_cal_cmds; i++) {
2721 u16 zero_diq = 0;
2722 u16 best_coeffs[11];
2723 u16 command_num;
2724
2725 cal_type = (cal_cmds[i] & 0x0f00) >> 8;
2726
2727 command_num = command_nums[i];
2728 if (ncorr_override[cal_type])
2729 command_num =
2730 ncorr_override[cal_type] << 8 | (command_num &
2731 0xff);
2732
2733 write_phy_reg(pi, 0x452, command_num);
2734
2735 if ((cal_type == 3) || (cal_type == 4)) {
2736 wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2737 &diq_start, 1, 16, 69);
2738
2739 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2740 &zero_diq, 1, 16, 69);
2741 }
2742
2743 write_phy_reg(pi, 0x451, cal_cmds[i]);
2744
2745 if (!wlc_lcnphy_iqcal_wait(pi))
2746 goto cleanup;
2747
2748 wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2749 best_coeffs,
2750 ARRAY_SIZE(best_coeffs), 16, 96);
2751 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2752 best_coeffs,
2753 ARRAY_SIZE(best_coeffs), 16, 64);
2754
2755 if ((cal_type == 3) || (cal_type == 4))
2756 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2757 &diq_start, 1, 16, 69);
2758 wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2759 pi_lcn->lcnphy_cal_results.
2760 txiqlocal_bestcoeffs,
2761 ARRAY_SIZE(pi_lcn->
2762 lcnphy_cal_results.
2763 txiqlocal_bestcoeffs),
2764 16, 96);
2765 }
2766
2767 wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2768 pi_lcn->lcnphy_cal_results.
2769 txiqlocal_bestcoeffs,
2770 ARRAY_SIZE(pi_lcn->lcnphy_cal_results.
2771 txiqlocal_bestcoeffs), 16, 96);
2772 pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid = true;
2773
2774 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2775 &pi_lcn->lcnphy_cal_results.
2776 txiqlocal_bestcoeffs[0], 4, 16, 80);
2777
2778 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2779 &pi_lcn->lcnphy_cal_results.
2780 txiqlocal_bestcoeffs[5], 2, 16, 85);
2781
2782cleanup:
2783 wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, values_to_save);
2784 kfree(values_to_save);
2785
2786 if (!keep_tone)
2787 wlc_lcnphy_stop_tx_tone(pi);
2788
2789 write_phy_reg(pi, 0x4db, save_txpwrctrlrfctrl2);
2790
2791 write_phy_reg(pi, 0x453, 0);
2792
2793 if (tx_gain_override_old)
2794 wlc_lcnphy_set_tx_gain(pi, &old_gains);
2795 wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl_old);
2796
2797 write_phy_reg(pi, 0x6da, save_sslpnCalibClkEnCtrl);
2798 write_phy_reg(pi, 0x6db, save_sslpnRxFeClkEnCtrl);
2799
2800}
2801
2802static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
2803{
2804 bool suspend, tx_gain_override_old;
2805 struct lcnphy_txgains old_gains;
2806 struct brcms_phy *pi = (struct brcms_phy *) ppi;
2807 u16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB,
2808 idleTssi0_regvalue_2C;
2809 u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
2810 u16 SAVE_lpfgain = read_radio_reg(pi, RADIO_2064_REG112);
2811 u16 SAVE_jtag_bb_afe_switch =
2812 read_radio_reg(pi, RADIO_2064_REG007) & 1;
2813 u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
2814 u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
2815 idleTssi = read_phy_reg(pi, 0x4ab);
2816 suspend =
2817 (0 ==
2818 (R_REG(&((struct brcms_phy *) pi)->regs->maccontrol) &
2819 MCTL_EN_MAC));
2820 if (!suspend)
2821 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2822 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
2823
2824 tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
2825 wlc_lcnphy_get_tx_gain(pi, &old_gains);
2826
2827 wlc_lcnphy_enable_tx_gain_override(pi);
2828 wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
2829 write_radio_reg(pi, RADIO_2064_REG112, 0x6);
2830 mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 1);
2831 mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
2832 mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
2833 wlc_lcnphy_tssi_setup(pi);
2834 wlc_phy_do_dummy_tx(pi, true, OFF);
2835 idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
2836 >> 0);
2837
2838 idleTssi0_2C = ((read_phy_reg(pi, 0x63e) & (0x1ff << 0))
2839 >> 0);
2840
2841 if (idleTssi0_2C >= 256)
2842 idleTssi0_OB = idleTssi0_2C - 256;
2843 else
2844 idleTssi0_OB = idleTssi0_2C + 256;
2845
2846 idleTssi0_regvalue_OB = idleTssi0_OB;
2847 if (idleTssi0_regvalue_OB >= 256)
2848 idleTssi0_regvalue_2C = idleTssi0_regvalue_OB - 256;
2849 else
2850 idleTssi0_regvalue_2C = idleTssi0_regvalue_OB + 256;
2851 mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (idleTssi0_regvalue_2C) << 0);
2852
2853 mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
2854
2855 wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
2856 wlc_lcnphy_set_tx_gain(pi, &old_gains);
2857 wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
2858
2859 write_radio_reg(pi, RADIO_2064_REG112, SAVE_lpfgain);
2860 mod_radio_reg(pi, RADIO_2064_REG007, 0x1, SAVE_jtag_bb_afe_switch);
2861 mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, SAVE_jtag_auxpga);
2862 mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, SAVE_iqadc_aux_en);
2863 mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1 << 7);
2864 if (!suspend)
2865 wlapi_enable_mac(pi->sh->physhim);
2866}
2867
2868static void wlc_lcnphy_vbat_temp_sense_setup(struct brcms_phy *pi, u8 mode)
2869{
2870 bool suspend;
2871 u16 save_txpwrCtrlEn;
2872 u8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain;
2873 u16 auxpga_vmid;
2874 struct phytbl_info tab;
2875 u32 val;
2876 u8 save_reg007, save_reg0FF, save_reg11F, save_reg005, save_reg025,
2877 save_reg112;
2878 u16 values_to_save[14];
2879 s8 index;
2880 int i;
2881 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
2882 udelay(999);
2883
2884 save_reg007 = (u8) read_radio_reg(pi, RADIO_2064_REG007);
2885 save_reg0FF = (u8) read_radio_reg(pi, RADIO_2064_REG0FF);
2886 save_reg11F = (u8) read_radio_reg(pi, RADIO_2064_REG11F);
2887 save_reg005 = (u8) read_radio_reg(pi, RADIO_2064_REG005);
2888 save_reg025 = (u8) read_radio_reg(pi, RADIO_2064_REG025);
2889 save_reg112 = (u8) read_radio_reg(pi, RADIO_2064_REG112);
2890
2891 for (i = 0; i < 14; i++)
2892 values_to_save[i] = read_phy_reg(pi, tempsense_phy_regs[i]);
2893 suspend = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
2894 if (!suspend)
2895 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2896 save_txpwrCtrlEn = read_radio_reg(pi, 0x4a4);
2897
2898 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
2899 index = pi_lcn->lcnphy_current_index;
2900 wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
2901 mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 0x1);
2902 mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 0x1 << 4);
2903 mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0x1 << 2);
2904 mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
2905
2906 mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
2907
2908 mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
2909
2910 mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0) << 15);
2911
2912 mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
2913
2914 mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
2915
2916 mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
2917
2918 mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
2919
2920 mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
2921
2922 mod_phy_reg(pi, 0x40d, (0x7 << 8), (6) << 8);
2923
2924 mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
2925
2926 mod_phy_reg(pi, 0x4a2, (0x7 << 8), (6) << 8);
2927
2928 mod_phy_reg(pi, 0x4d9, (0x7 << 4), (2) << 4);
2929
2930 mod_phy_reg(pi, 0x4d9, (0x7 << 8), (3) << 8);
2931
2932 mod_phy_reg(pi, 0x4d9, (0x7 << 12), (1) << 12);
2933
2934 mod_phy_reg(pi, 0x4da, (0x1 << 12), (0) << 12);
2935
2936 mod_phy_reg(pi, 0x4da, (0x1 << 13), (1) << 13);
2937
2938 mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
2939
2940 write_radio_reg(pi, RADIO_2064_REG025, 0xC);
2941
2942 mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 0x1 << 3);
2943
2944 mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
2945
2946 mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
2947
2948 mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
2949
2950 val = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
2951 tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
2952 tab.tbl_width = 16;
2953 tab.tbl_len = 1;
2954 tab.tbl_ptr = &val;
2955 tab.tbl_offset = 6;
2956 wlc_lcnphy_write_table(pi, &tab);
2957 if (mode == TEMPSENSE) {
2958 mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
2959
2960 mod_phy_reg(pi, 0x4d7, (0x7 << 12), (1) << 12);
2961
2962 auxpga_vmidcourse = 8;
2963 auxpga_vmidfine = 0x4;
2964 auxpga_gain = 2;
2965 mod_radio_reg(pi, RADIO_2064_REG082, 0x20, 1 << 5);
2966 } else {
2967 mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
2968
2969 mod_phy_reg(pi, 0x4d7, (0x7 << 12), (3) << 12);
2970
2971 auxpga_vmidcourse = 7;
2972 auxpga_vmidfine = 0xa;
2973 auxpga_gain = 2;
2974 }
2975 auxpga_vmid =
2976 (u16) ((2 << 8) | (auxpga_vmidcourse << 4) | auxpga_vmidfine);
2977 mod_phy_reg(pi, 0x4d8, (0x1 << 0), (1) << 0);
2978
2979 mod_phy_reg(pi, 0x4d8, (0x3ff << 2), (auxpga_vmid) << 2);
2980
2981 mod_phy_reg(pi, 0x4d8, (0x1 << 1), (1) << 1);
2982
2983 mod_phy_reg(pi, 0x4d8, (0x7 << 12), (auxpga_gain) << 12);
2984
2985 mod_phy_reg(pi, 0x4d0, (0x1 << 5), (1) << 5);
2986
2987 write_radio_reg(pi, RADIO_2064_REG112, 0x6);
2988
2989 wlc_phy_do_dummy_tx(pi, true, OFF);
2990 if (!tempsense_done(pi))
2991 udelay(10);
2992
2993 write_radio_reg(pi, RADIO_2064_REG007, (u16) save_reg007);
2994 write_radio_reg(pi, RADIO_2064_REG0FF, (u16) save_reg0FF);
2995 write_radio_reg(pi, RADIO_2064_REG11F, (u16) save_reg11F);
2996 write_radio_reg(pi, RADIO_2064_REG005, (u16) save_reg005);
2997 write_radio_reg(pi, RADIO_2064_REG025, (u16) save_reg025);
2998 write_radio_reg(pi, RADIO_2064_REG112, (u16) save_reg112);
2999 for (i = 0; i < 14; i++)
3000 write_phy_reg(pi, tempsense_phy_regs[i], values_to_save[i]);
3001 wlc_lcnphy_set_tx_pwr_by_index(pi, (int)index);
3002
3003 write_radio_reg(pi, 0x4a4, save_txpwrCtrlEn);
3004 if (!suspend)
3005 wlapi_enable_mac(pi->sh->physhim);
3006 udelay(999);
3007}
3008
3009static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
3010{
3011 struct lcnphy_txgains tx_gains;
3012 u8 bbmult;
3013 struct phytbl_info tab;
3014 s32 a1, b0, b1;
3015 s32 tssi, pwr, maxtargetpwr, mintargetpwr;
3016 bool suspend;
3017 struct brcms_phy *pi = (struct brcms_phy *) ppi;
3018
3019 suspend =
3020 (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
3021 if (!suspend)
3022 wlapi_suspend_mac_and_wait(pi->sh->physhim);
3023
3024 if (!pi->hwpwrctrl_capable) {
3025 if (CHSPEC_IS2G(pi->radio_chanspec)) {
3026 tx_gains.gm_gain = 4;
3027 tx_gains.pga_gain = 12;
3028 tx_gains.pad_gain = 12;
3029 tx_gains.dac_gain = 0;
3030
3031 bbmult = 150;
3032 } else {
3033 tx_gains.gm_gain = 7;
3034 tx_gains.pga_gain = 15;
3035 tx_gains.pad_gain = 14;
3036 tx_gains.dac_gain = 0;
3037
3038 bbmult = 150;
3039 }
3040 wlc_lcnphy_set_tx_gain(pi, &tx_gains);
3041 wlc_lcnphy_set_bbmult(pi, bbmult);
3042 wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
3043 } else {
3044
3045 wlc_lcnphy_idle_tssi_est(ppi);
3046
3047 wlc_lcnphy_clear_tx_power_offsets(pi);
3048
3049 b0 = pi->txpa_2g[0];
3050 b1 = pi->txpa_2g[1];
3051 a1 = pi->txpa_2g[2];
3052 maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
3053 mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
3054
3055 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
3056 tab.tbl_width = 32;
3057 tab.tbl_ptr = &pwr;
3058 tab.tbl_len = 1;
3059 tab.tbl_offset = 0;
3060 for (tssi = 0; tssi < 128; tssi++) {
3061 pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
3062
3063 pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
3064 wlc_lcnphy_write_table(pi, &tab);
3065 tab.tbl_offset++;
3066 }
3067
3068 mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
3069
3070 write_phy_reg(pi, 0x4a8, 10);
3071
3072 wlc_lcnphy_set_target_tx_pwr(pi, LCN_TARGET_PWR);
3073
3074 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
3075 }
3076 if (!suspend)
3077 wlapi_enable_mac(pi->sh->physhim);
3078}
3079
3080static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi)
3081{
3082 u16 m0m1;
3083 struct phytbl_info tab;
3084
3085 tab.tbl_ptr = &m0m1;
3086 tab.tbl_len = 1;
3087 tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
3088 tab.tbl_offset = 87;
3089 tab.tbl_width = 16;
3090 wlc_lcnphy_read_table(pi, &tab);
3091
3092 return (u8) ((m0m1 & 0xff00) >> 8);
3093}
3094
3095static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain)
3096{
3097 mod_phy_reg(pi, 0x4fb,
3098 LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK,
3099 gain << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT);
3100 mod_phy_reg(pi, 0x4fd,
3101 LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK,
3102 gain << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT);
3103}
3104
3105void
3106wlc_lcnphy_get_radio_loft(struct brcms_phy *pi,
3107 u8 *ei0, u8 *eq0, u8 *fi0, u8 *fq0)
3108{
3109 *ei0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG089));
3110 *eq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08A));
3111 *fi0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08B));
3112 *fq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08C));
3113}
3114
3115void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b)
3116{
3117 struct phytbl_info tab;
3118 u16 iqcc[2];
3119
3120 iqcc[0] = a;
3121 iqcc[1] = b;
3122
3123 tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
3124 tab.tbl_width = 16;
3125 tab.tbl_ptr = iqcc;
3126 tab.tbl_len = 2;
3127 tab.tbl_offset = 80;
3128 wlc_lcnphy_write_table(pi, &tab);
3129}
3130
3131void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq)
3132{
3133 struct phytbl_info tab;
3134
3135 tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
3136 tab.tbl_width = 16;
3137 tab.tbl_ptr = &didq;
3138 tab.tbl_len = 1;
3139 tab.tbl_offset = 85;
3140 wlc_lcnphy_write_table(pi, &tab);
3141}
3142
3143void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index)
3144{
3145 struct phytbl_info tab;
3146 u16 a, b;
3147 u8 bb_mult;
3148 u32 bbmultiqcomp, txgain, locoeffs, rfpower;
3149 struct lcnphy_txgains gains;
3150 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3151
3152 pi_lcn->lcnphy_tx_power_idx_override = (s8) index;
3153 pi_lcn->lcnphy_current_index = (u8) index;
3154
3155 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
3156 tab.tbl_width = 32;
3157 tab.tbl_len = 1;
3158
3159 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
3160
3161 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
3162 tab.tbl_ptr = &bbmultiqcomp;
3163 wlc_lcnphy_read_table(pi, &tab);
3164
3165 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
3166 tab.tbl_width = 32;
3167 tab.tbl_ptr = &txgain;
3168 wlc_lcnphy_read_table(pi, &tab);
3169
3170 gains.gm_gain = (u16) (txgain & 0xff);
3171 gains.pga_gain = (u16) (txgain >> 8) & 0xff;
3172 gains.pad_gain = (u16) (txgain >> 16) & 0xff;
3173 gains.dac_gain = (u16) (bbmultiqcomp >> 28) & 0x07;
3174 wlc_lcnphy_set_tx_gain(pi, &gains);
3175 wlc_lcnphy_set_pa_gain(pi, (u16) (txgain >> 24) & 0x7f);
3176
3177 bb_mult = (u8) ((bbmultiqcomp >> 20) & 0xff);
3178 wlc_lcnphy_set_bbmult(pi, bb_mult);
3179
3180 wlc_lcnphy_enable_tx_gain_override(pi);
3181
3182 if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
3183
3184 a = (u16) ((bbmultiqcomp >> 10) & 0x3ff);
3185 b = (u16) (bbmultiqcomp & 0x3ff);
3186 wlc_lcnphy_set_tx_iqcc(pi, a, b);
3187
3188 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + index;
3189 tab.tbl_ptr = &locoeffs;
3190 wlc_lcnphy_read_table(pi, &tab);
3191
3192 wlc_lcnphy_set_tx_locc(pi, (u16) locoeffs);
3193
3194 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
3195 tab.tbl_ptr = &rfpower;
3196 wlc_lcnphy_read_table(pi, &tab);
3197 mod_phy_reg(pi, 0x6a6, (0x1fff << 0), (rfpower * 8) << 0);
3198
3199 }
3200}
3201
3202static void wlc_lcnphy_clear_papd_comptable(struct brcms_phy *pi)
3203{
3204 u32 j;
3205 struct phytbl_info tab;
3206 u32 temp_offset[128];
3207 tab.tbl_ptr = temp_offset;
3208 tab.tbl_len = 128;
3209 tab.tbl_id = LCNPHY_TBL_ID_PAPDCOMPDELTATBL;
3210 tab.tbl_width = 32;
3211 tab.tbl_offset = 0;
3212
3213 memset(temp_offset, 0, sizeof(temp_offset));
3214 for (j = 1; j < 128; j += 2)
3215 temp_offset[j] = 0x80000;
3216
3217 wlc_lcnphy_write_table(pi, &tab);
3218 return;
3219}
3220
3221void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable)
3222{
3223 if (!bEnable) {
3224
3225 and_phy_reg(pi, 0x43b, ~(u16) ((0x1 << 1) | (0x1 << 4)));
3226
3227 mod_phy_reg(pi, 0x43c, (0x1 << 1), 1 << 1);
3228
3229 and_phy_reg(pi, 0x44c,
3230 ~(u16) ((0x1 << 3) |
3231 (0x1 << 5) |
3232 (0x1 << 12) |
3233 (0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
3234
3235 and_phy_reg(pi, 0x44d,
3236 ~(u16) ((0x1 << 3) | (0x1 << 5) | (0x1 << 14)));
3237 mod_phy_reg(pi, 0x44d, (0x1 << 2), 1 << 2);
3238
3239 mod_phy_reg(pi, 0x44d, (0x1 << 1) | (0x1 << 0), (0x1 << 0));
3240
3241 and_phy_reg(pi, 0x4f9,
3242 ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
3243
3244 and_phy_reg(pi, 0x4fa,
3245 ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
3246 } else {
3247
3248 mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
3249 mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
3250
3251 mod_phy_reg(pi, 0x43b, (0x1 << 4), 1 << 4);
3252 mod_phy_reg(pi, 0x43c, (0x1 << 6), 0 << 6);
3253
3254 mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
3255 mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
3256
3257 wlc_lcnphy_set_trsw_override(pi, true, false);
3258
3259 mod_phy_reg(pi, 0x44d, (0x1 << 2), 0 << 2);
3260 mod_phy_reg(pi, 0x44c, (0x1 << 2), 1 << 2);
3261
3262 if (CHSPEC_IS2G(pi->radio_chanspec)) {
3263
3264 mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
3265 mod_phy_reg(pi, 0x44d, (0x1 << 3), 1 << 3);
3266
3267 mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
3268 mod_phy_reg(pi, 0x44d, (0x1 << 5), 0 << 5);
3269
3270 mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
3271 mod_phy_reg(pi, 0x4fa, (0x1 << 1), 1 << 1);
3272
3273 mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
3274 mod_phy_reg(pi, 0x4fa, (0x1 << 2), 1 << 2);
3275
3276 mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
3277 mod_phy_reg(pi, 0x4fa, (0x1 << 0), 1 << 0);
3278 } else {
3279
3280 mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
3281 mod_phy_reg(pi, 0x44d, (0x1 << 3), 0 << 3);
3282
3283 mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
3284 mod_phy_reg(pi, 0x44d, (0x1 << 5), 1 << 5);
3285
3286 mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
3287 mod_phy_reg(pi, 0x4fa, (0x1 << 1), 0 << 1);
3288
3289 mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
3290 mod_phy_reg(pi, 0x4fa, (0x1 << 2), 0 << 2);
3291
3292 mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
3293 mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
3294 }
3295 }
3296}
3297
3298static void
3299wlc_lcnphy_run_samples(struct brcms_phy *pi,
3300 u16 num_samps,
3301 u16 num_loops, u16 wait, bool iqcalmode)
3302{
3303
3304 or_phy_reg(pi, 0x6da, 0x8080);
3305
3306 mod_phy_reg(pi, 0x642, (0x7f << 0), (num_samps - 1) << 0);
3307 if (num_loops != 0xffff)
3308 num_loops--;
3309 mod_phy_reg(pi, 0x640, (0xffff << 0), num_loops << 0);
3310
3311 mod_phy_reg(pi, 0x641, (0xffff << 0), wait << 0);
3312
3313 if (iqcalmode) {
3314
3315 and_phy_reg(pi, 0x453, (u16) ~(0x1 << 15));
3316 or_phy_reg(pi, 0x453, (0x1 << 15));
3317 } else {
3318 write_phy_reg(pi, 0x63f, 1);
3319 wlc_lcnphy_tx_pu(pi, 1);
3320 }
3321
3322 or_radio_reg(pi, RADIO_2064_REG112, 0x6);
3323}
3324
3325void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode)
3326{
3327
3328 u8 phybw40;
3329 phybw40 = CHSPEC_IS40(pi->radio_chanspec);
3330
3331 if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
3332 mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
3333 mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
3334 } else {
3335 mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
3336 mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
3337 }
3338
3339 if (phybw40 == 0) {
3340 mod_phy_reg((pi), 0x410,
3341 (0x1 << 6) |
3342 (0x1 << 5),
3343 ((CHSPEC_IS2G(
3344 pi->radio_chanspec)) ? (!mode) : 0) <<
3345 6 | (!mode) << 5);
3346 mod_phy_reg(pi, 0x410, (0x1 << 7), (mode) << 7);
3347 }
3348}
3349
3350void
3351wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz, u16 max_val,
3352 bool iqcalmode)
3353{
3354 u8 phy_bw;
3355 u16 num_samps, t, k;
3356 u32 bw;
3357 s32 theta = 0, rot = 0;
3358 struct cordic_iq tone_samp;
3359 u32 data_buf[64];
3360 u16 i_samp, q_samp;
3361 struct phytbl_info tab;
3362 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3363
3364 pi->phy_tx_tone_freq = f_kHz;
3365
3366 wlc_lcnphy_deaf_mode(pi, true);
3367
3368 phy_bw = 40;
3369 if (pi_lcn->lcnphy_spurmod) {
3370 write_phy_reg(pi, 0x942, 0x2);
3371 write_phy_reg(pi, 0x93b, 0x0);
3372 write_phy_reg(pi, 0x93c, 0x0);
3373 wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
3374 }
3375
3376 if (f_kHz) {
3377 k = 1;
3378 do {
3379 bw = phy_bw * 1000 * k;
3380 num_samps = bw / abs(f_kHz);
3381 k++;
3382 } while ((num_samps * (u32) (abs(f_kHz))) != bw);
3383 } else
3384 num_samps = 2;
3385
3386 rot = ((f_kHz * 36) / phy_bw) / 100;
3387 theta = 0;
3388
3389 for (t = 0; t < num_samps; t++) {
3390
3391 tone_samp = cordic_calc_iq(theta);
3392
3393 theta += rot;
3394
3395 i_samp = (u16) (FLOAT(tone_samp.i * max_val) & 0x3ff);
3396 q_samp = (u16) (FLOAT(tone_samp.q * max_val) & 0x3ff);
3397 data_buf[t] = (i_samp << 10) | q_samp;
3398 }
3399
3400 mod_phy_reg(pi, 0x6d6, (0x3 << 0), 0 << 0);
3401
3402 mod_phy_reg(pi, 0x6da, (0x1 << 3), 1 << 3);
3403
3404 tab.tbl_ptr = data_buf;
3405 tab.tbl_len = num_samps;
3406 tab.tbl_id = LCNPHY_TBL_ID_SAMPLEPLAY;
3407 tab.tbl_offset = 0;
3408 tab.tbl_width = 32;
3409 wlc_lcnphy_write_table(pi, &tab);
3410
3411 wlc_lcnphy_run_samples(pi, num_samps, 0xffff, 0, iqcalmode);
3412}
3413
3414void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi)
3415{
3416 s16 playback_status;
3417 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3418
3419 pi->phy_tx_tone_freq = 0;
3420 if (pi_lcn->lcnphy_spurmod) {
3421 write_phy_reg(pi, 0x942, 0x7);
3422 write_phy_reg(pi, 0x93b, 0x2017);
3423 write_phy_reg(pi, 0x93c, 0x27c5);
3424 wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
3425 }
3426
3427 playback_status = read_phy_reg(pi, 0x644);
3428 if (playback_status & (0x1 << 0)) {
3429 wlc_lcnphy_tx_pu(pi, 0);
3430 mod_phy_reg(pi, 0x63f, (0x1 << 1), 1 << 1);
3431 } else if (playback_status & (0x1 << 1))
3432 mod_phy_reg(pi, 0x453, (0x1 << 15), 0 << 15);
3433
3434 mod_phy_reg(pi, 0x6d6, (0x3 << 0), 1 << 0);
3435
3436 mod_phy_reg(pi, 0x6da, (0x1 << 3), 0 << 3);
3437
3438 mod_phy_reg(pi, 0x6da, (0x1 << 7), 0 << 7);
3439
3440 and_radio_reg(pi, RADIO_2064_REG112, 0xFFF9);
3441
3442 wlc_lcnphy_deaf_mode(pi, false);
3443}
3444
3445static void
3446wlc_lcnphy_set_cc(struct brcms_phy *pi, int cal_type, s16 coeff_x, s16 coeff_y)
3447{
3448 u16 di0dq0;
3449 u16 x, y, data_rf;
3450 int k;
3451 switch (cal_type) {
3452 case 0:
3453 wlc_lcnphy_set_tx_iqcc(pi, coeff_x, coeff_y);
3454 break;
3455 case 2:
3456 di0dq0 = (coeff_x & 0xff) << 8 | (coeff_y & 0xff);
3457 wlc_lcnphy_set_tx_locc(pi, di0dq0);
3458 break;
3459 case 3:
3460 k = wlc_lcnphy_calc_floor(coeff_x, 0);
3461 y = 8 + k;
3462 k = wlc_lcnphy_calc_floor(coeff_x, 1);
3463 x = 8 - k;
3464 data_rf = (x * 16 + y);
3465 write_radio_reg(pi, RADIO_2064_REG089, data_rf);
3466 k = wlc_lcnphy_calc_floor(coeff_y, 0);
3467 y = 8 + k;
3468 k = wlc_lcnphy_calc_floor(coeff_y, 1);
3469 x = 8 - k;
3470 data_rf = (x * 16 + y);
3471 write_radio_reg(pi, RADIO_2064_REG08A, data_rf);
3472 break;
3473 case 4:
3474 k = wlc_lcnphy_calc_floor(coeff_x, 0);
3475 y = 8 + k;
3476 k = wlc_lcnphy_calc_floor(coeff_x, 1);
3477 x = 8 - k;
3478 data_rf = (x * 16 + y);
3479 write_radio_reg(pi, RADIO_2064_REG08B, data_rf);
3480 k = wlc_lcnphy_calc_floor(coeff_y, 0);
3481 y = 8 + k;
3482 k = wlc_lcnphy_calc_floor(coeff_y, 1);
3483 x = 8 - k;
3484 data_rf = (x * 16 + y);
3485 write_radio_reg(pi, RADIO_2064_REG08C, data_rf);
3486 break;
3487 }
3488}
3489
3490static struct lcnphy_unsign16_struct
3491wlc_lcnphy_get_cc(struct brcms_phy *pi, int cal_type)
3492{
3493 u16 a, b, didq;
3494 u8 di0, dq0, ei, eq, fi, fq;
3495 struct lcnphy_unsign16_struct cc;
3496 cc.re = 0;
3497 cc.im = 0;
3498 switch (cal_type) {
3499 case 0:
3500 wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
3501 cc.re = a;
3502 cc.im = b;
3503 break;
3504 case 2:
3505 didq = wlc_lcnphy_get_tx_locc(pi);
3506 di0 = (((didq & 0xff00) << 16) >> 24);
3507 dq0 = (((didq & 0x00ff) << 24) >> 24);
3508 cc.re = (u16) di0;
3509 cc.im = (u16) dq0;
3510 break;
3511 case 3:
3512 wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
3513 cc.re = (u16) ei;
3514 cc.im = (u16) eq;
3515 break;
3516 case 4:
3517 wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
3518 cc.re = (u16) fi;
3519 cc.im = (u16) fq;
3520 break;
3521 }
3522 return cc;
3523}
3524
3525static void
3526wlc_lcnphy_samp_cap(struct brcms_phy *pi, int clip_detect_algo, u16 thresh,
3527 s16 *ptr, int mode)
3528{
3529 u32 curval1, curval2, stpptr, curptr, strptr, val;
3530 u16 sslpnCalibClkEnCtrl, timer;
3531 u16 old_sslpnCalibClkEnCtrl;
3532 s16 imag, real;
3533 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3534
3535 timer = 0;
3536 old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
3537
3538 curval1 = R_REG(&pi->regs->psm_corectlsts);
3539 ptr[130] = 0;
3540 W_REG(&pi->regs->psm_corectlsts, ((1 << 6) | curval1));
3541
3542 W_REG(&pi->regs->smpl_clct_strptr, 0x7E00);
3543 W_REG(&pi->regs->smpl_clct_stpptr, 0x8000);
3544 udelay(20);
3545 curval2 = R_REG(&pi->regs->psm_phy_hdr_param);
3546 W_REG(&pi->regs->psm_phy_hdr_param, curval2 | 0x30);
3547
3548 write_phy_reg(pi, 0x555, 0x0);
3549 write_phy_reg(pi, 0x5a6, 0x5);
3550
3551 write_phy_reg(pi, 0x5a2, (u16) (mode | mode << 6));
3552 write_phy_reg(pi, 0x5cf, 3);
3553 write_phy_reg(pi, 0x5a5, 0x3);
3554 write_phy_reg(pi, 0x583, 0x0);
3555 write_phy_reg(pi, 0x584, 0x0);
3556 write_phy_reg(pi, 0x585, 0x0fff);
3557 write_phy_reg(pi, 0x586, 0x0000);
3558
3559 write_phy_reg(pi, 0x580, 0x4501);
3560
3561 sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
3562 write_phy_reg(pi, 0x6da, (u32) (sslpnCalibClkEnCtrl | 0x2008));
3563 stpptr = R_REG(&pi->regs->smpl_clct_stpptr);
3564 curptr = R_REG(&pi->regs->smpl_clct_curptr);
3565 do {
3566 udelay(10);
3567 curptr = R_REG(&pi->regs->smpl_clct_curptr);
3568 timer++;
3569 } while ((curptr != stpptr) && (timer < 500));
3570
3571 W_REG(&pi->regs->psm_phy_hdr_param, 0x2);
3572 strptr = 0x7E00;
3573 W_REG(&pi->regs->tplatewrptr, strptr);
3574 while (strptr < 0x8000) {
3575 val = R_REG(&pi->regs->tplatewrdata);
3576 imag = ((val >> 16) & 0x3ff);
3577 real = ((val) & 0x3ff);
3578 if (imag > 511)
3579 imag -= 1024;
3580
3581 if (real > 511)
3582 real -= 1024;
3583
3584 if (pi_lcn->lcnphy_iqcal_swp_dis)
3585 ptr[(strptr - 0x7E00) / 4] = real;
3586 else
3587 ptr[(strptr - 0x7E00) / 4] = imag;
3588
3589 if (clip_detect_algo) {
3590 if (imag > thresh || imag < -thresh) {
3591 strptr = 0x8000;
3592 ptr[130] = 1;
3593 }
3594 }
3595
3596 strptr += 4;
3597 }
3598
3599 write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
3600 W_REG(&pi->regs->psm_phy_hdr_param, curval2);
3601 W_REG(&pi->regs->psm_corectlsts, curval1);
3602}
3603
3604static void
3605wlc_lcnphy_a1(struct brcms_phy *pi, int cal_type, int num_levels,
3606 int step_size_lg2)
3607{
3608 const struct lcnphy_spb_tone *phy_c1;
3609 struct lcnphy_spb_tone phy_c2;
3610 struct lcnphy_unsign16_struct phy_c3;
3611 int phy_c4, phy_c5, k, l, j, phy_c6;
3612 u16 phy_c7, phy_c8, phy_c9;
3613 s16 phy_c10, phy_c11, phy_c12, phy_c13, phy_c14, phy_c15, phy_c16;
3614 s16 *ptr, phy_c17;
3615 s32 phy_c18, phy_c19;
3616 u32 phy_c20, phy_c21;
3617 bool phy_c22, phy_c23, phy_c24, phy_c25;
3618 u16 phy_c26, phy_c27;
3619 u16 phy_c28, phy_c29, phy_c30;
3620 u16 phy_c31;
3621 u16 *phy_c32;
3622 phy_c21 = 0;
3623 phy_c10 = phy_c13 = phy_c14 = phy_c8 = 0;
3624 ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC);
3625 if (NULL == ptr)
3626 return;
3627
3628 phy_c32 = kmalloc(sizeof(u16) * 20, GFP_ATOMIC);
3629 if (NULL == phy_c32) {
3630 kfree(ptr);
3631 return;
3632 }
3633 phy_c26 = read_phy_reg(pi, 0x6da);
3634 phy_c27 = read_phy_reg(pi, 0x6db);
3635 phy_c31 = read_radio_reg(pi, RADIO_2064_REG026);
3636 write_phy_reg(pi, 0x93d, 0xC0);
3637
3638 wlc_lcnphy_start_tx_tone(pi, 3750, 88, 0);
3639 write_phy_reg(pi, 0x6da, 0xffff);
3640 or_phy_reg(pi, 0x6db, 0x3);
3641
3642 wlc_lcnphy_tx_iqlo_loopback(pi, phy_c32);
3643 udelay(500);
3644 phy_c28 = read_phy_reg(pi, 0x938);
3645 phy_c29 = read_phy_reg(pi, 0x4d7);
3646 phy_c30 = read_phy_reg(pi, 0x4d8);
3647 or_phy_reg(pi, 0x938, 0x1 << 2);
3648 or_phy_reg(pi, 0x4d7, 0x1 << 2);
3649 or_phy_reg(pi, 0x4d7, 0x1 << 3);
3650 mod_phy_reg(pi, 0x4d7, (0x7 << 12), 0x2 << 12);
3651 or_phy_reg(pi, 0x4d8, 1 << 0);
3652 or_phy_reg(pi, 0x4d8, 1 << 1);
3653 mod_phy_reg(pi, 0x4d8, (0x3ff << 2), 0x23A << 2);
3654 mod_phy_reg(pi, 0x4d8, (0x7 << 12), 0x7 << 12);
3655 phy_c1 = &lcnphy_spb_tone_3750[0];
3656 phy_c4 = 32;
3657
3658 if (num_levels == 0) {
3659 if (cal_type != 0)
3660 num_levels = 4;
3661 else
3662 num_levels = 9;
3663 }
3664 if (step_size_lg2 == 0) {
3665 if (cal_type != 0)
3666 step_size_lg2 = 3;
3667 else
3668 step_size_lg2 = 8;
3669 }
3670
3671 phy_c7 = (1 << step_size_lg2);
3672 phy_c3 = wlc_lcnphy_get_cc(pi, cal_type);
3673 phy_c15 = (s16) phy_c3.re;
3674 phy_c16 = (s16) phy_c3.im;
3675 if (cal_type == 2) {
3676 if (phy_c3.re > 127)
3677 phy_c15 = phy_c3.re - 256;
3678 if (phy_c3.im > 127)
3679 phy_c16 = phy_c3.im - 256;
3680 }
3681 wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
3682 udelay(20);
3683 for (phy_c8 = 0; phy_c7 != 0 && phy_c8 < num_levels; phy_c8++) {
3684 phy_c23 = 1;
3685 phy_c22 = 0;
3686 switch (cal_type) {
3687 case 0:
3688 phy_c10 = 511;
3689 break;
3690 case 2:
3691 phy_c10 = 127;
3692 break;
3693 case 3:
3694 phy_c10 = 15;
3695 break;
3696 case 4:
3697 phy_c10 = 15;
3698 break;
3699 }
3700
3701 phy_c9 = read_phy_reg(pi, 0x93d);
3702 phy_c9 = 2 * phy_c9;
3703 phy_c24 = 0;
3704 phy_c5 = 7;
3705 phy_c25 = 1;
3706 while (1) {
3707 write_radio_reg(pi, RADIO_2064_REG026,
3708 (phy_c5 & 0x7) | ((phy_c5 & 0x7) << 4));
3709 udelay(50);
3710 phy_c22 = 0;
3711 ptr[130] = 0;
3712 wlc_lcnphy_samp_cap(pi, 1, phy_c9, &ptr[0], 2);
3713 if (ptr[130] == 1)
3714 phy_c22 = 1;
3715 if (phy_c22)
3716 phy_c5 -= 1;
3717 if ((phy_c22 != phy_c24) && (!phy_c25))
3718 break;
3719 if (!phy_c22)
3720 phy_c5 += 1;
3721 if (phy_c5 <= 0 || phy_c5 >= 7)
3722 break;
3723 phy_c24 = phy_c22;
3724 phy_c25 = 0;
3725 }
3726
3727 if (phy_c5 < 0)
3728 phy_c5 = 0;
3729 else if (phy_c5 > 7)
3730 phy_c5 = 7;
3731
3732 for (k = -phy_c7; k <= phy_c7; k += phy_c7) {
3733 for (l = -phy_c7; l <= phy_c7; l += phy_c7) {
3734 phy_c11 = phy_c15 + k;
3735 phy_c12 = phy_c16 + l;
3736
3737 if (phy_c11 < -phy_c10)
3738 phy_c11 = -phy_c10;
3739 else if (phy_c11 > phy_c10)
3740 phy_c11 = phy_c10;
3741 if (phy_c12 < -phy_c10)
3742 phy_c12 = -phy_c10;
3743 else if (phy_c12 > phy_c10)
3744 phy_c12 = phy_c10;
3745 wlc_lcnphy_set_cc(pi, cal_type, phy_c11,
3746 phy_c12);
3747 udelay(20);
3748 wlc_lcnphy_samp_cap(pi, 0, 0, ptr, 2);
3749
3750 phy_c18 = 0;
3751 phy_c19 = 0;
3752 for (j = 0; j < 128; j++) {
3753 if (cal_type != 0)
3754 phy_c6 = j % phy_c4;
3755 else
3756 phy_c6 = (2 * j) % phy_c4;
3757
3758 phy_c2.re = phy_c1[phy_c6].re;
3759 phy_c2.im = phy_c1[phy_c6].im;
3760 phy_c17 = ptr[j];
3761 phy_c18 = phy_c18 + phy_c17 * phy_c2.re;
3762 phy_c19 = phy_c19 + phy_c17 * phy_c2.im;
3763 }
3764
3765 phy_c18 = phy_c18 >> 10;
3766 phy_c19 = phy_c19 >> 10;
3767 phy_c20 = ((phy_c18 * phy_c18) +
3768 (phy_c19 * phy_c19));
3769
3770 if (phy_c23 || phy_c20 < phy_c21) {
3771 phy_c21 = phy_c20;
3772 phy_c13 = phy_c11;
3773 phy_c14 = phy_c12;
3774 }
3775 phy_c23 = 0;
3776 }
3777 }
3778 phy_c23 = 1;
3779 phy_c15 = phy_c13;
3780 phy_c16 = phy_c14;
3781 phy_c7 = phy_c7 >> 1;
3782 wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
3783 udelay(20);
3784 }
3785 goto cleanup;
3786cleanup:
3787 wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, phy_c32);
3788 wlc_lcnphy_stop_tx_tone(pi);
3789 write_phy_reg(pi, 0x6da, phy_c26);
3790 write_phy_reg(pi, 0x6db, phy_c27);
3791 write_phy_reg(pi, 0x938, phy_c28);
3792 write_phy_reg(pi, 0x4d7, phy_c29);
3793 write_phy_reg(pi, 0x4d8, phy_c30);
3794 write_radio_reg(pi, RADIO_2064_REG026, phy_c31);
3795
3796 kfree(phy_c32);
3797 kfree(ptr);
3798}
3799
3800void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b)
3801{
3802 u16 iqcc[2];
3803 struct phytbl_info tab;
3804
3805 tab.tbl_ptr = iqcc;
3806 tab.tbl_len = 2;
3807 tab.tbl_id = 0;
3808 tab.tbl_offset = 80;
3809 tab.tbl_width = 16;
3810 wlc_lcnphy_read_table(pi, &tab);
3811
3812 *a = iqcc[0];
3813 *b = iqcc[1];
3814}
3815
3816static void wlc_lcnphy_tx_iqlo_soft_cal_full(struct brcms_phy *pi)
3817{
3818 struct lcnphy_unsign16_struct iqcc0, locc2, locc3, locc4;
3819
3820 wlc_lcnphy_set_cc(pi, 0, 0, 0);
3821 wlc_lcnphy_set_cc(pi, 2, 0, 0);
3822 wlc_lcnphy_set_cc(pi, 3, 0, 0);
3823 wlc_lcnphy_set_cc(pi, 4, 0, 0);
3824
3825 wlc_lcnphy_a1(pi, 4, 0, 0);
3826 wlc_lcnphy_a1(pi, 3, 0, 0);
3827 wlc_lcnphy_a1(pi, 2, 3, 2);
3828 wlc_lcnphy_a1(pi, 0, 5, 8);
3829 wlc_lcnphy_a1(pi, 2, 2, 1);
3830 wlc_lcnphy_a1(pi, 0, 4, 3);
3831
3832 iqcc0 = wlc_lcnphy_get_cc(pi, 0);
3833 locc2 = wlc_lcnphy_get_cc(pi, 2);
3834 locc3 = wlc_lcnphy_get_cc(pi, 3);
3835 locc4 = wlc_lcnphy_get_cc(pi, 4);
3836}
3837
3838u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi)
3839{
3840 struct phytbl_info tab;
3841 u16 didq;
3842
3843 tab.tbl_id = 0;
3844 tab.tbl_width = 16;
3845 tab.tbl_ptr = &didq;
3846 tab.tbl_len = 1;
3847 tab.tbl_offset = 85;
3848 wlc_lcnphy_read_table(pi, &tab);
3849
3850 return didq;
3851}
3852
3853static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
3854{
3855
3856 struct lcnphy_txgains target_gains, old_gains;
3857 u8 save_bb_mult;
3858 u16 a, b, didq, save_pa_gain = 0;
3859 uint idx, SAVE_txpwrindex = 0xFF;
3860 u32 val;
3861 u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
3862 struct phytbl_info tab;
3863 u8 ei0, eq0, fi0, fq0;
3864 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3865
3866 wlc_lcnphy_get_tx_gain(pi, &old_gains);
3867 save_pa_gain = wlc_lcnphy_get_pa_gain(pi);
3868
3869 save_bb_mult = wlc_lcnphy_get_bbmult(pi);
3870
3871 if (SAVE_txpwrctrl == LCNPHY_TX_PWR_CTRL_OFF)
3872 SAVE_txpwrindex = wlc_lcnphy_get_current_tx_pwr_idx(pi);
3873
3874 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
3875
3876 target_gains.gm_gain = 7;
3877 target_gains.pga_gain = 0;
3878 target_gains.pad_gain = 21;
3879 target_gains.dac_gain = 0;
3880 wlc_lcnphy_set_tx_gain(pi, &target_gains);
3881 wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
3882
3883 if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
3884
3885 wlc_lcnphy_set_tx_pwr_by_index(pi, 30);
3886
3887 wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
3888 (pi_lcn->
3889 lcnphy_recal ? LCNPHY_CAL_RECAL :
3890 LCNPHY_CAL_FULL), false);
3891 } else {
3892 wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
3893 }
3894
3895 wlc_lcnphy_get_radio_loft(pi, &ei0, &eq0, &fi0, &fq0);
3896 if ((abs((s8) fi0) == 15) && (abs((s8) fq0) == 15)) {
3897 if (CHSPEC_IS5G(pi->radio_chanspec)) {
3898 target_gains.gm_gain = 255;
3899 target_gains.pga_gain = 255;
3900 target_gains.pad_gain = 0xf0;
3901 target_gains.dac_gain = 0;
3902 } else {
3903 target_gains.gm_gain = 7;
3904 target_gains.pga_gain = 45;
3905 target_gains.pad_gain = 186;
3906 target_gains.dac_gain = 0;
3907 }
3908
3909 if (LCNREV_IS(pi->pubpi.phy_rev, 1)
3910 || pi_lcn->lcnphy_hw_iqcal_en) {
3911
3912 target_gains.pga_gain = 0;
3913 target_gains.pad_gain = 30;
3914 wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
3915 wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
3916 LCNPHY_CAL_FULL, false);
3917 } else {
3918 wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
3919 }
3920 }
3921
3922 wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
3923
3924 didq = wlc_lcnphy_get_tx_locc(pi);
3925
3926 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
3927 tab.tbl_width = 32;
3928 tab.tbl_ptr = &val;
3929
3930 tab.tbl_len = 1;
3931 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
3932
3933 for (idx = 0; idx < 128; idx++) {
3934 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + idx;
3935
3936 wlc_lcnphy_read_table(pi, &tab);
3937 val = (val & 0xfff00000) |
3938 ((u32) (a & 0x3FF) << 10) | (b & 0x3ff);
3939 wlc_lcnphy_write_table(pi, &tab);
3940
3941 val = didq;
3942 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + idx;
3943 wlc_lcnphy_write_table(pi, &tab);
3944 }
3945
3946 pi_lcn->lcnphy_cal_results.txiqlocal_a = a;
3947 pi_lcn->lcnphy_cal_results.txiqlocal_b = b;
3948 pi_lcn->lcnphy_cal_results.txiqlocal_didq = didq;
3949 pi_lcn->lcnphy_cal_results.txiqlocal_ei0 = ei0;
3950 pi_lcn->lcnphy_cal_results.txiqlocal_eq0 = eq0;
3951 pi_lcn->lcnphy_cal_results.txiqlocal_fi0 = fi0;
3952 pi_lcn->lcnphy_cal_results.txiqlocal_fq0 = fq0;
3953
3954 wlc_lcnphy_set_bbmult(pi, save_bb_mult);
3955 wlc_lcnphy_set_pa_gain(pi, save_pa_gain);
3956 wlc_lcnphy_set_tx_gain(pi, &old_gains);
3957
3958 if (SAVE_txpwrctrl != LCNPHY_TX_PWR_CTRL_OFF)
3959 wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
3960 else
3961 wlc_lcnphy_set_tx_pwr_by_index(pi, SAVE_txpwrindex);
3962}
3963
3964s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode)
3965{
3966 u16 tempsenseval1, tempsenseval2;
3967 s16 avg = 0;
3968 bool suspend = 0;
3969
3970 if (mode == 1) {
3971 suspend =
3972 (0 ==
3973 (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
3974 if (!suspend)
3975 wlapi_suspend_mac_and_wait(pi->sh->physhim);
3976 wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
3977 }
3978 tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
3979 tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
3980
3981 if (tempsenseval1 > 255)
3982 avg = (s16) (tempsenseval1 - 512);
3983 else
3984 avg = (s16) tempsenseval1;
3985
3986 if (tempsenseval2 > 255)
3987 avg += (s16) (tempsenseval2 - 512);
3988 else
3989 avg += (s16) tempsenseval2;
3990
3991 avg /= 2;
3992
3993 if (mode == 1) {
3994
3995 mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
3996
3997 udelay(100);
3998 mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
3999
4000 if (!suspend)
4001 wlapi_enable_mac(pi->sh->physhim);
4002 }
4003 return avg;
4004}
4005
4006u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode)
4007{
4008 u16 tempsenseval1, tempsenseval2;
4009 s32 avg = 0;
4010 bool suspend = 0;
4011 u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
4012 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
4013
4014 if (mode == 1) {
4015 suspend =
4016 (0 ==
4017 (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
4018 if (!suspend)
4019 wlapi_suspend_mac_and_wait(pi->sh->physhim);
4020 wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
4021 }
4022 tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
4023 tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
4024
4025 if (tempsenseval1 > 255)
4026 avg = (int)(tempsenseval1 - 512);
4027 else
4028 avg = (int)tempsenseval1;
4029
4030 if (pi_lcn->lcnphy_tempsense_option == 1 || pi->hwpwrctrl_capable) {
4031 if (tempsenseval2 > 255)
4032 avg = (int)(avg - tempsenseval2 + 512);
4033 else
4034 avg = (int)(avg - tempsenseval2);
4035 } else {
4036 if (tempsenseval2 > 255)
4037 avg = (int)(avg + tempsenseval2 - 512);
4038 else
4039 avg = (int)(avg + tempsenseval2);
4040 avg = avg / 2;
4041 }
4042 if (avg < 0)
4043 avg = avg + 512;
4044
4045 if (pi_lcn->lcnphy_tempsense_option == 2)
4046 avg = tempsenseval1;
4047
4048 if (mode)
4049 wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
4050
4051 if (mode == 1) {
4052
4053 mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
4054
4055 udelay(100);
4056 mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
4057
4058 if (!suspend)
4059 wlapi_enable_mac(pi->sh->physhim);
4060 }
4061 return (u16) avg;
4062}
4063
4064s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode)
4065{
4066 s32 degree = wlc_lcnphy_tempsense_new(pi, mode);
4067 degree =
4068 ((degree <<
4069 10) + LCN_TEMPSENSE_OFFSET + (LCN_TEMPSENSE_DEN >> 1))
4070 / LCN_TEMPSENSE_DEN;
4071 return (s8) degree;
4072}
4073
4074s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode)
4075{
4076 u16 vbatsenseval;
4077 s32 avg = 0;
4078 bool suspend = 0;
4079
4080 if (mode == 1) {
4081 suspend =
4082 (0 ==
4083 (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
4084 if (!suspend)
4085 wlapi_suspend_mac_and_wait(pi->sh->physhim);
4086 wlc_lcnphy_vbat_temp_sense_setup(pi, VBATSENSE);
4087 }
4088
4089 vbatsenseval = read_phy_reg(pi, 0x475) & 0x1FF;
4090
4091 if (vbatsenseval > 255)
4092 avg = (s32) (vbatsenseval - 512);
4093 else
4094 avg = (s32) vbatsenseval;
4095
4096 avg = (avg * LCN_VBAT_SCALE_NOM +
4097 (LCN_VBAT_SCALE_DEN >> 1)) / LCN_VBAT_SCALE_DEN;
4098
4099 if (mode == 1) {
4100 if (!suspend)
4101 wlapi_enable_mac(pi->sh->physhim);
4102 }
4103 return (s8) avg;
4104}
4105
4106static void wlc_lcnphy_afe_clk_init(struct brcms_phy *pi, u8 mode)
4107{
4108 u8 phybw40;
4109 phybw40 = CHSPEC_IS40(pi->radio_chanspec);
4110
4111 mod_phy_reg(pi, 0x6d1, (0x1 << 7), (1) << 7);
4112
4113 if (((mode == AFE_CLK_INIT_MODE_PAPD) && (phybw40 == 0)) ||
4114 (mode == AFE_CLK_INIT_MODE_TXRX2X))
4115 write_phy_reg(pi, 0x6d0, 0x7);
4116
4117 wlc_lcnphy_toggle_afe_pwdn(pi);
4118}
4119
4120static void wlc_lcnphy_temp_adj(struct brcms_phy *pi)
4121{
4122}
4123
4124static void wlc_lcnphy_glacial_timer_based_cal(struct brcms_phy *pi)
4125{
4126 bool suspend;
4127 s8 index;
4128 u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
4129 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
4130 suspend =
4131 (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
4132 if (!suspend)
4133 wlapi_suspend_mac_and_wait(pi->sh->physhim);
4134 wlc_lcnphy_deaf_mode(pi, true);
4135 pi->phy_lastcal = pi->sh->now;
4136 pi->phy_forcecal = false;
4137 index = pi_lcn->lcnphy_current_index;
4138
4139 wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
4140
4141 wlc_lcnphy_set_tx_pwr_by_index(pi, index);
4142 wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
4143 wlc_lcnphy_deaf_mode(pi, false);
4144 if (!suspend)
4145 wlapi_enable_mac(pi->sh->physhim);
4146
4147}
4148
4149static void wlc_lcnphy_periodic_cal(struct brcms_phy *pi)
4150{
4151 bool suspend, full_cal;
4152 const struct lcnphy_rx_iqcomp *rx_iqcomp;
4153 int rx_iqcomp_sz;
4154 u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
4155 s8 index;
4156 struct phytbl_info tab;
4157 s32 a1, b0, b1;
4158 s32 tssi, pwr, maxtargetpwr, mintargetpwr;
4159 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
4160
4161 pi->phy_lastcal = pi->sh->now;
4162 pi->phy_forcecal = false;
4163 full_cal =
4164 (pi_lcn->lcnphy_full_cal_channel !=
4165 CHSPEC_CHANNEL(pi->radio_chanspec));
4166 pi_lcn->lcnphy_full_cal_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
4167 index = pi_lcn->lcnphy_current_index;
4168
4169 suspend =
4170 (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
4171 if (!suspend) {
4172 wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
4173 wlapi_suspend_mac_and_wait(pi->sh->physhim);
4174 }
4175
4176 wlc_lcnphy_deaf_mode(pi, true);
4177
4178 wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
4179
4180 rx_iqcomp = lcnphy_rx_iqcomp_table_rev0;
4181 rx_iqcomp_sz = ARRAY_SIZE(lcnphy_rx_iqcomp_table_rev0);
4182
4183 if (LCNREV_IS(pi->pubpi.phy_rev, 1))
4184 wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 40);
4185 else
4186 wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 127);
4187
4188 if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
4189
4190 wlc_lcnphy_idle_tssi_est((struct brcms_phy_pub *) pi);
4191
4192 b0 = pi->txpa_2g[0];
4193 b1 = pi->txpa_2g[1];
4194 a1 = pi->txpa_2g[2];
4195 maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
4196 mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
4197
4198 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
4199 tab.tbl_width = 32;
4200 tab.tbl_ptr = &pwr;
4201 tab.tbl_len = 1;
4202 tab.tbl_offset = 0;
4203 for (tssi = 0; tssi < 128; tssi++) {
4204 pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
4205 pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
4206 wlc_lcnphy_write_table(pi, &tab);
4207 tab.tbl_offset++;
4208 }
4209 }
4210
4211 wlc_lcnphy_set_tx_pwr_by_index(pi, index);
4212 wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
4213 wlc_lcnphy_deaf_mode(pi, false);
4214 if (!suspend)
4215 wlapi_enable_mac(pi->sh->physhim);
4216}
4217
4218void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode)
4219{
4220 u16 temp_new;
4221 int temp1, temp2, temp_diff;
4222 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
4223
4224 switch (mode) {
4225 case PHY_PERICAL_CHAN:
4226 break;
4227 case PHY_FULLCAL:
4228 wlc_lcnphy_periodic_cal(pi);
4229 break;
4230 case PHY_PERICAL_PHYINIT:
4231 wlc_lcnphy_periodic_cal(pi);
4232 break;
4233 case PHY_PERICAL_WATCHDOG:
4234 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
4235 temp_new = wlc_lcnphy_tempsense(pi, 0);
4236 temp1 = LCNPHY_TEMPSENSE(temp_new);
4237 temp2 = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_cal_temper);
4238 temp_diff = temp1 - temp2;
4239 if ((pi_lcn->lcnphy_cal_counter > 90) ||
4240 (temp_diff > 60) || (temp_diff < -60)) {
4241 wlc_lcnphy_glacial_timer_based_cal(pi);
4242 wlc_2064_vco_cal(pi);
4243 pi_lcn->lcnphy_cal_temper = temp_new;
4244 pi_lcn->lcnphy_cal_counter = 0;
4245 } else
4246 pi_lcn->lcnphy_cal_counter++;
4247 }
4248 break;
4249 case LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL:
4250 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
4251 wlc_lcnphy_tx_power_adjustment(
4252 (struct brcms_phy_pub *) pi);
4253 break;
4254 }
4255}
4256
4257void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr, s8 *cck_pwr)
4258{
4259 s8 cck_offset;
4260 u16 status;
4261 status = (read_phy_reg(pi, 0x4ab));
4262 if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
4263 (status & (0x1 << 15))) {
4264 *ofdm_pwr = (s8) (((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
4265 >> 0) >> 1);
4266
4267 if (wlc_phy_tpc_isenabled_lcnphy(pi))
4268 cck_offset = pi->tx_power_offset[TXP_FIRST_CCK];
4269 else
4270 cck_offset = 0;
4271
4272 *cck_pwr = *ofdm_pwr + cck_offset;
4273 } else {
4274 *cck_pwr = 0;
4275 *ofdm_pwr = 0;
4276 }
4277}
4278
4279void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi)
4280{
4281 return;
4282
4283}
4284
4285void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi)
4286{
4287 s8 index;
4288 u16 index2;
4289 struct brcms_phy *pi = (struct brcms_phy *) ppi;
4290 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
4291 u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
4292 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) &&
4293 SAVE_txpwrctrl) {
4294 index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
4295 index2 = (u16) (index * 2);
4296 mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
4297
4298 pi_lcn->lcnphy_current_index =
4299 (s8)((read_phy_reg(pi, 0x4a9) & 0xFF) / 2);
4300 }
4301}
4302
4303static void
4304wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
4305 const struct lcnphy_tx_gain_tbl_entry *gain_table)
4306{
4307 u32 j;
4308 struct phytbl_info tab;
4309 u32 val;
4310 u16 pa_gain;
4311 u16 gm_gain;
4312
4313 if (CHSPEC_IS5G(pi->radio_chanspec))
4314 pa_gain = 0x70;
4315 else
4316 pa_gain = 0x70;
4317
4318 if (pi->sh->boardflags & BFL_FEM)
4319 pa_gain = 0x10;
4320 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
4321 tab.tbl_width = 32;
4322 tab.tbl_len = 1;
4323 tab.tbl_ptr = &val;
4324
4325 for (j = 0; j < 128; j++) {
4326 gm_gain = gain_table[j].gm;
4327 val = (((u32) pa_gain << 24) |
4328 (gain_table[j].pad << 16) |
4329 (gain_table[j].pga << 8) | gm_gain);
4330
4331 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + j;
4332 wlc_lcnphy_write_table(pi, &tab);
4333
4334 val = (gain_table[j].dac << 28) | (gain_table[j].bb_mult << 20);
4335 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + j;
4336 wlc_lcnphy_write_table(pi, &tab);
4337 }
4338}
4339
4340static void wlc_lcnphy_load_rfpower(struct brcms_phy *pi)
4341{
4342 struct phytbl_info tab;
4343 u32 val, bbmult, rfgain;
4344 u8 index;
4345 u8 scale_factor = 1;
4346 s16 temp, temp1, temp2, qQ, qQ1, qQ2, shift;
4347
4348 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
4349 tab.tbl_width = 32;
4350 tab.tbl_len = 1;
4351
4352 for (index = 0; index < 128; index++) {
4353 tab.tbl_ptr = &bbmult;
4354 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
4355 wlc_lcnphy_read_table(pi, &tab);
4356 bbmult = bbmult >> 20;
4357
4358 tab.tbl_ptr = &rfgain;
4359 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
4360 wlc_lcnphy_read_table(pi, &tab);
4361
4362 qm_log10((s32) (bbmult), 0, &temp1, &qQ1);
4363 qm_log10((s32) (1 << 6), 0, &temp2, &qQ2);
4364
4365 if (qQ1 < qQ2) {
4366 temp2 = qm_shr16(temp2, qQ2 - qQ1);
4367 qQ = qQ1;
4368 } else {
4369 temp1 = qm_shr16(temp1, qQ1 - qQ2);
4370 qQ = qQ2;
4371 }
4372 temp = qm_sub16(temp1, temp2);
4373
4374 if (qQ >= 4)
4375 shift = qQ - 4;
4376 else
4377 shift = 4 - qQ;
4378
4379 val = (((index << shift) + (5 * temp) +
4380 (1 << (scale_factor + shift - 3))) >> (scale_factor +
4381 shift - 2));
4382
4383 tab.tbl_ptr = &val;
4384 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
4385 wlc_lcnphy_write_table(pi, &tab);
4386 }
4387}
4388
4389static void wlc_lcnphy_bu_tweaks(struct brcms_phy *pi)
4390{
4391 or_phy_reg(pi, 0x805, 0x1);
4392
4393 mod_phy_reg(pi, 0x42f, (0x7 << 0), (0x3) << 0);
4394
4395 mod_phy_reg(pi, 0x030, (0x7 << 0), (0x3) << 0);
4396
4397 write_phy_reg(pi, 0x414, 0x1e10);
4398 write_phy_reg(pi, 0x415, 0x0640);
4399
4400 mod_phy_reg(pi, 0x4df, (0xff << 8), -9 << 8);
4401
4402 or_phy_reg(pi, 0x44a, 0x44);
4403 write_phy_reg(pi, 0x44a, 0x80);
4404 mod_phy_reg(pi, 0x434, (0xff << 0), (0xFD) << 0);
4405
4406 mod_phy_reg(pi, 0x420, (0xff << 0), (16) << 0);
4407
4408 if (!(pi->sh->boardrev < 0x1204))
4409 mod_radio_reg(pi, RADIO_2064_REG09B, 0xF0, 0xF0);
4410
4411 write_phy_reg(pi, 0x7d6, 0x0902);
4412 mod_phy_reg(pi, 0x429, (0xf << 0), (0x9) << 0);
4413
4414 mod_phy_reg(pi, 0x429, (0x3f << 4), (0xe) << 4);
4415
4416 if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
4417 mod_phy_reg(pi, 0x423, (0xff << 0), (0x46) << 0);
4418
4419 mod_phy_reg(pi, 0x411, (0xff << 0), (1) << 0);
4420
4421 mod_phy_reg(pi, 0x434, (0xff << 0), (0xFF) << 0);
4422
4423 mod_phy_reg(pi, 0x656, (0xf << 0), (2) << 0);
4424
4425 mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
4426
4427 mod_radio_reg(pi, RADIO_2064_REG0F7, 0x4, 0x4);
4428 mod_radio_reg(pi, RADIO_2064_REG0F1, 0x3, 0);
4429 mod_radio_reg(pi, RADIO_2064_REG0F2, 0xF8, 0x90);
4430 mod_radio_reg(pi, RADIO_2064_REG0F3, 0x3, 0x2);
4431 mod_radio_reg(pi, RADIO_2064_REG0F3, 0xf0, 0xa0);
4432
4433 mod_radio_reg(pi, RADIO_2064_REG11F, 0x2, 0x2);
4434
4435 wlc_lcnphy_clear_tx_power_offsets(pi);
4436 mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (10) << 6);
4437
4438 }
4439}
4440
4441static void wlc_lcnphy_rcal(struct brcms_phy *pi)
4442{
4443 u8 rcal_value;
4444
4445 and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
4446
4447 or_radio_reg(pi, RADIO_2064_REG004, 0x40);
4448 or_radio_reg(pi, RADIO_2064_REG120, 0x10);
4449
4450 or_radio_reg(pi, RADIO_2064_REG078, 0x80);
4451 or_radio_reg(pi, RADIO_2064_REG129, 0x02);
4452
4453 or_radio_reg(pi, RADIO_2064_REG057, 0x01);
4454
4455 or_radio_reg(pi, RADIO_2064_REG05B, 0x02);
4456 mdelay(5);
4457 SPINWAIT(!wlc_radio_2064_rcal_done(pi), 10 * 1000 * 1000);
4458
4459 if (wlc_radio_2064_rcal_done(pi)) {
4460 rcal_value = (u8) read_radio_reg(pi, RADIO_2064_REG05C);
4461 rcal_value = rcal_value & 0x1f;
4462 }
4463
4464 and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
4465
4466 and_radio_reg(pi, RADIO_2064_REG057, 0xFE);
4467}
4468
4469static void wlc_lcnphy_rc_cal(struct brcms_phy *pi)
4470{
4471 u8 dflt_rc_cal_val;
4472 u16 flt_val;
4473
4474 dflt_rc_cal_val = 7;
4475 if (LCNREV_IS(pi->pubpi.phy_rev, 1))
4476 dflt_rc_cal_val = 11;
4477 flt_val =
4478 (dflt_rc_cal_val << 10) | (dflt_rc_cal_val << 5) |
4479 (dflt_rc_cal_val);
4480 write_phy_reg(pi, 0x933, flt_val);
4481 write_phy_reg(pi, 0x934, flt_val);
4482 write_phy_reg(pi, 0x935, flt_val);
4483 write_phy_reg(pi, 0x936, flt_val);
4484 write_phy_reg(pi, 0x937, (flt_val & 0x1FF));
4485
4486 return;
4487}
4488
4489static void wlc_radio_2064_init(struct brcms_phy *pi)
4490{
4491 u32 i;
4492 const struct lcnphy_radio_regs *lcnphyregs = NULL;
4493
4494 lcnphyregs = lcnphy_radio_regs_2064;
4495
4496 for (i = 0; lcnphyregs[i].address != 0xffff; i++)
4497 if (CHSPEC_IS5G(pi->radio_chanspec) && lcnphyregs[i].do_init_a)
4498 write_radio_reg(pi,
4499 ((lcnphyregs[i].address & 0x3fff) |
4500 RADIO_DEFAULT_CORE),
4501 (u16) lcnphyregs[i].init_a);
4502 else if (lcnphyregs[i].do_init_g)
4503 write_radio_reg(pi,
4504 ((lcnphyregs[i].address & 0x3fff) |
4505 RADIO_DEFAULT_CORE),
4506 (u16) lcnphyregs[i].init_g);
4507
4508 write_radio_reg(pi, RADIO_2064_REG032, 0x62);
4509 write_radio_reg(pi, RADIO_2064_REG033, 0x19);
4510
4511 write_radio_reg(pi, RADIO_2064_REG090, 0x10);
4512
4513 write_radio_reg(pi, RADIO_2064_REG010, 0x00);
4514
4515 if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
4516
4517 write_radio_reg(pi, RADIO_2064_REG060, 0x7f);
4518 write_radio_reg(pi, RADIO_2064_REG061, 0x72);
4519 write_radio_reg(pi, RADIO_2064_REG062, 0x7f);
4520 }
4521
4522 write_radio_reg(pi, RADIO_2064_REG01D, 0x02);
4523 write_radio_reg(pi, RADIO_2064_REG01E, 0x06);
4524
4525 mod_phy_reg(pi, 0x4ea, (0x7 << 0), 0 << 0);
4526
4527 mod_phy_reg(pi, 0x4ea, (0x7 << 3), 1 << 3);
4528
4529 mod_phy_reg(pi, 0x4ea, (0x7 << 6), 2 << 6);
4530
4531 mod_phy_reg(pi, 0x4ea, (0x7 << 9), 3 << 9);
4532
4533 mod_phy_reg(pi, 0x4ea, (0x7 << 12), 4 << 12);
4534
4535 write_phy_reg(pi, 0x4ea, 0x4688);
4536
4537 mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
4538
4539 mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
4540
4541 mod_phy_reg(pi, 0x46a, (0xffff << 0), 25 << 0);
4542
4543 wlc_lcnphy_set_tx_locc(pi, 0);
4544
4545 wlc_lcnphy_rcal(pi);
4546
4547 wlc_lcnphy_rc_cal(pi);
4548}
4549
4550static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
4551{
4552 wlc_radio_2064_init(pi);
4553}
4554
4555static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
4556{
4557 uint idx;
4558 u8 phybw40;
4559 struct phytbl_info tab;
4560 u32 val;
4561
4562 phybw40 = CHSPEC_IS40(pi->radio_chanspec);
4563
4564 for (idx = 0; idx < dot11lcnphytbl_info_sz_rev0; idx++)
4565 wlc_lcnphy_write_table(pi, &dot11lcnphytbl_info_rev0[idx]);
4566
4567 if (pi->sh->boardflags & BFL_FEM_BT) {
4568 tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
4569 tab.tbl_width = 16;
4570 tab.tbl_ptr = &val;
4571 tab.tbl_len = 1;
4572 val = 100;
4573 tab.tbl_offset = 4;
4574 wlc_lcnphy_write_table(pi, &tab);
4575 }
4576
4577 tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
4578 tab.tbl_width = 16;
4579 tab.tbl_ptr = &val;
4580 tab.tbl_len = 1;
4581
4582 val = 114;
4583 tab.tbl_offset = 0;
4584 wlc_lcnphy_write_table(pi, &tab);
4585
4586 val = 130;
4587 tab.tbl_offset = 1;
4588 wlc_lcnphy_write_table(pi, &tab);
4589
4590 val = 6;
4591 tab.tbl_offset = 8;
4592 wlc_lcnphy_write_table(pi, &tab);
4593
4594 if (CHSPEC_IS2G(pi->radio_chanspec)) {
4595 if (pi->sh->boardflags & BFL_FEM)
4596 wlc_lcnphy_load_tx_gain_table(
4597 pi,
4598 dot11lcnphy_2GHz_extPA_gaintable_rev0);
4599 else
4600 wlc_lcnphy_load_tx_gain_table(
4601 pi,
4602 dot11lcnphy_2GHz_gaintable_rev0);
4603 }
4604
4605 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
4606 const struct phytbl_info *tb;
4607 int l;
4608
4609 if (CHSPEC_IS2G(pi->radio_chanspec)) {
4610 l = dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
4611 if (pi->sh->boardflags & BFL_EXTLNA)
4612 tb = dot11lcnphytbl_rx_gain_info_extlna_2G_rev2;
4613 else
4614 tb = dot11lcnphytbl_rx_gain_info_2G_rev2;
4615 } else {
4616 l = dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
4617 if (pi->sh->boardflags & BFL_EXTLNA_5GHz)
4618 tb = dot11lcnphytbl_rx_gain_info_extlna_5G_rev2;
4619 else
4620 tb = dot11lcnphytbl_rx_gain_info_5G_rev2;
4621 }
4622
4623 for (idx = 0; idx < l; idx++)
4624 wlc_lcnphy_write_table(pi, &tb[idx]);
4625 }
4626
4627 if ((pi->sh->boardflags & BFL_FEM)
4628 && !(pi->sh->boardflags & BFL_FEM_BT))
4629 wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313_epa);
4630 else if (pi->sh->boardflags & BFL_FEM_BT) {
4631 if (pi->sh->boardrev < 0x1250)
4632 wlc_lcnphy_write_table(
4633 pi,
4634 &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa);
4635 else
4636 wlc_lcnphy_write_table(
4637 pi,
4638 &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250);
4639 } else
4640 wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313);
4641
4642 wlc_lcnphy_load_rfpower(pi);
4643
4644 wlc_lcnphy_clear_papd_comptable(pi);
4645}
4646
4647static void wlc_lcnphy_rev0_baseband_init(struct brcms_phy *pi)
4648{
4649 u16 afectrl1;
4650 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
4651
4652 write_radio_reg(pi, RADIO_2064_REG11C, 0x0);
4653
4654 write_phy_reg(pi, 0x43b, 0x0);
4655 write_phy_reg(pi, 0x43c, 0x0);
4656 write_phy_reg(pi, 0x44c, 0x0);
4657 write_phy_reg(pi, 0x4e6, 0x0);
4658 write_phy_reg(pi, 0x4f9, 0x0);
4659 write_phy_reg(pi, 0x4b0, 0x0);
4660 write_phy_reg(pi, 0x938, 0x0);
4661 write_phy_reg(pi, 0x4b0, 0x0);
4662 write_phy_reg(pi, 0x44e, 0);
4663
4664 or_phy_reg(pi, 0x567, 0x03);
4665
4666 or_phy_reg(pi, 0x44a, 0x44);
4667 write_phy_reg(pi, 0x44a, 0x80);
4668
4669 if (!(pi->sh->boardflags & BFL_FEM))
4670 wlc_lcnphy_set_tx_pwr_by_index(pi, 52);
4671
4672 if (0) {
4673 afectrl1 = 0;
4674 afectrl1 = (u16) ((pi_lcn->lcnphy_rssi_vf) |
4675 (pi_lcn->lcnphy_rssi_vc << 4) |
4676 (pi_lcn->lcnphy_rssi_gs << 10));
4677 write_phy_reg(pi, 0x43e, afectrl1);
4678 }
4679
4680 mod_phy_reg(pi, 0x634, (0xff << 0), 0xC << 0);
4681 if (pi->sh->boardflags & BFL_FEM) {
4682 mod_phy_reg(pi, 0x634, (0xff << 0), 0xA << 0);
4683
4684 write_phy_reg(pi, 0x910, 0x1);
4685 }
4686
4687 mod_phy_reg(pi, 0x448, (0x3 << 8), 1 << 8);
4688 mod_phy_reg(pi, 0x608, (0xff << 0), 0x17 << 0);
4689 mod_phy_reg(pi, 0x604, (0x7ff << 0), 0x3EA << 0);
4690
4691}
4692
4693static void wlc_lcnphy_rev2_baseband_init(struct brcms_phy *pi)
4694{
4695 if (CHSPEC_IS5G(pi->radio_chanspec)) {
4696 mod_phy_reg(pi, 0x416, (0xff << 0), 80 << 0);
4697 mod_phy_reg(pi, 0x416, (0xff << 8), 80 << 8);
4698 }
4699}
4700
4701static void wlc_lcnphy_agc_temp_init(struct brcms_phy *pi)
4702{
4703 s16 temp;
4704 struct phytbl_info tab;
4705 u32 tableBuffer[2];
4706 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
4707
4708 temp = (s16) read_phy_reg(pi, 0x4df);
4709 pi_lcn->lcnphy_ofdmgainidxtableoffset = (temp & (0xff << 0)) >> 0;
4710
4711 if (pi_lcn->lcnphy_ofdmgainidxtableoffset > 127)
4712 pi_lcn->lcnphy_ofdmgainidxtableoffset -= 256;
4713
4714 pi_lcn->lcnphy_dsssgainidxtableoffset = (temp & (0xff << 8)) >> 8;
4715
4716 if (pi_lcn->lcnphy_dsssgainidxtableoffset > 127)
4717 pi_lcn->lcnphy_dsssgainidxtableoffset -= 256;
4718
4719 tab.tbl_ptr = tableBuffer;
4720 tab.tbl_len = 2;
4721 tab.tbl_id = 17;
4722 tab.tbl_offset = 59;
4723 tab.tbl_width = 32;
4724 wlc_lcnphy_read_table(pi, &tab);
4725
4726 if (tableBuffer[0] > 63)
4727 tableBuffer[0] -= 128;
4728 pi_lcn->lcnphy_tr_R_gain_val = tableBuffer[0];
4729
4730 if (tableBuffer[1] > 63)
4731 tableBuffer[1] -= 128;
4732 pi_lcn->lcnphy_tr_T_gain_val = tableBuffer[1];
4733
4734 temp = (s16) (read_phy_reg(pi, 0x434) & (0xff << 0));
4735 if (temp > 127)
4736 temp -= 256;
4737 pi_lcn->lcnphy_input_pwr_offset_db = (s8) temp;
4738
4739 pi_lcn->lcnphy_Med_Low_Gain_db =
4740 (read_phy_reg(pi, 0x424) & (0xff << 8)) >> 8;
4741 pi_lcn->lcnphy_Very_Low_Gain_db =
4742 (read_phy_reg(pi, 0x425) & (0xff << 0)) >> 0;
4743
4744 tab.tbl_ptr = tableBuffer;
4745 tab.tbl_len = 2;
4746 tab.tbl_id = LCNPHY_TBL_ID_GAIN_IDX;
4747 tab.tbl_offset = 28;
4748 tab.tbl_width = 32;
4749 wlc_lcnphy_read_table(pi, &tab);
4750
4751 pi_lcn->lcnphy_gain_idx_14_lowword = tableBuffer[0];
4752 pi_lcn->lcnphy_gain_idx_14_hiword = tableBuffer[1];
4753
4754}
4755
4756static void wlc_lcnphy_baseband_init(struct brcms_phy *pi)
4757{
4758
4759 wlc_lcnphy_tbl_init(pi);
4760 wlc_lcnphy_rev0_baseband_init(pi);
4761 if (LCNREV_IS(pi->pubpi.phy_rev, 2))
4762 wlc_lcnphy_rev2_baseband_init(pi);
4763 wlc_lcnphy_bu_tweaks(pi);
4764}
4765
4766void wlc_phy_init_lcnphy(struct brcms_phy *pi)
4767{
4768 u8 phybw40;
4769 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
4770 phybw40 = CHSPEC_IS40(pi->radio_chanspec);
4771
4772 pi_lcn->lcnphy_cal_counter = 0;
4773 pi_lcn->lcnphy_cal_temper = pi_lcn->lcnphy_rawtempsense;
4774
4775 or_phy_reg(pi, 0x44a, 0x80);
4776 and_phy_reg(pi, 0x44a, 0x7f);
4777
4778 wlc_lcnphy_afe_clk_init(pi, AFE_CLK_INIT_MODE_TXRX2X);
4779
4780 write_phy_reg(pi, 0x60a, 160);
4781
4782 write_phy_reg(pi, 0x46a, 25);
4783
4784 wlc_lcnphy_baseband_init(pi);
4785
4786 wlc_lcnphy_radio_init(pi);
4787
4788 if (CHSPEC_IS2G(pi->radio_chanspec))
4789 wlc_lcnphy_tx_pwr_ctrl_init((struct brcms_phy_pub *) pi);
4790
4791 wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec);
4792
4793 si_pmu_regcontrol(pi->sh->sih, 0, 0xf, 0x9);
4794
4795 si_pmu_chipcontrol(pi->sh->sih, 0, 0xffffffff, 0x03CDDDDD);
4796
4797 if ((pi->sh->boardflags & BFL_FEM)
4798 && wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
4799 wlc_lcnphy_set_tx_pwr_by_index(pi, FIXED_TXPWR);
4800
4801 wlc_lcnphy_agc_temp_init(pi);
4802
4803 wlc_lcnphy_temp_adj(pi);
4804
4805 mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
4806
4807 udelay(100);
4808 mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
4809
4810 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
4811 pi_lcn->lcnphy_noise_samples = LCNPHY_NOISE_SAMPLES_DEFAULT;
4812 wlc_lcnphy_calib_modes(pi, PHY_PERICAL_PHYINIT);
4813}
4814
4815static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
4816{
4817 s8 txpwr = 0;
4818 int i;
4819 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
4820 struct phy_shim_info *shim = pi->sh->physhim;
4821
4822 if (CHSPEC_IS2G(pi->radio_chanspec)) {
4823 u16 cckpo = 0;
4824 u32 offset_ofdm, offset_mcs;
4825
4826 pi_lcn->lcnphy_tr_isolation_mid =
4827 (u8)wlapi_getintvar(shim, BRCMS_SROM_TRISO2G);
4828
4829 pi_lcn->lcnphy_rx_power_offset =
4830 (u8)wlapi_getintvar(shim, BRCMS_SROM_RXPO2G);
4831
4832 pi->txpa_2g[0] = (s16)wlapi_getintvar(shim, BRCMS_SROM_PA0B0);
4833 pi->txpa_2g[1] = (s16)wlapi_getintvar(shim, BRCMS_SROM_PA0B1);
4834 pi->txpa_2g[2] = (s16)wlapi_getintvar(shim, BRCMS_SROM_PA0B2);
4835
4836 pi_lcn->lcnphy_rssi_vf =
4837 (u8)wlapi_getintvar(shim, BRCMS_SROM_RSSISMF2G);
4838 pi_lcn->lcnphy_rssi_vc =
4839 (u8)wlapi_getintvar(shim, BRCMS_SROM_RSSISMC2G);
4840 pi_lcn->lcnphy_rssi_gs =
4841 (u8)wlapi_getintvar(shim, BRCMS_SROM_RSSISAV2G);
4842
4843 pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf;
4844 pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc;
4845 pi_lcn->lcnphy_rssi_gs_lowtemp = pi_lcn->lcnphy_rssi_gs;
4846
4847 pi_lcn->lcnphy_rssi_vf_hightemp = pi_lcn->lcnphy_rssi_vf;
4848 pi_lcn->lcnphy_rssi_vc_hightemp = pi_lcn->lcnphy_rssi_vc;
4849 pi_lcn->lcnphy_rssi_gs_hightemp = pi_lcn->lcnphy_rssi_gs;
4850
4851 txpwr = (s8)wlapi_getintvar(shim, BRCMS_SROM_MAXP2GA0);
4852 pi->tx_srom_max_2g = txpwr;
4853
4854 for (i = 0; i < PWRTBL_NUM_COEFF; i++) {
4855 pi->txpa_2g_low_temp[i] = pi->txpa_2g[i];
4856 pi->txpa_2g_high_temp[i] = pi->txpa_2g[i];
4857 }
4858
4859 cckpo = (u16)wlapi_getintvar(shim, BRCMS_SROM_CCK2GPO);
4860 offset_ofdm = (u32)wlapi_getintvar(shim, BRCMS_SROM_OFDM2GPO);
4861 if (cckpo) {
4862 uint max_pwr_chan = txpwr;
4863
4864 for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) {
4865 pi->tx_srom_max_rate_2g[i] =
4866 max_pwr_chan - ((cckpo & 0xf) * 2);
4867 cckpo >>= 4;
4868 }
4869
4870 for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
4871 pi->tx_srom_max_rate_2g[i] =
4872 max_pwr_chan -
4873 ((offset_ofdm & 0xf) * 2);
4874 offset_ofdm >>= 4;
4875 }
4876 } else {
4877 u8 opo = 0;
4878
4879 opo = (u8)wlapi_getintvar(shim, BRCMS_SROM_OPO);
4880
4881 for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++)
4882 pi->tx_srom_max_rate_2g[i] = txpwr;
4883
4884 for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
4885 pi->tx_srom_max_rate_2g[i] = txpwr -
4886 ((offset_ofdm & 0xf) * 2);
4887 offset_ofdm >>= 4;
4888 }
4889 offset_mcs =
4890 wlapi_getintvar(shim,
4891 BRCMS_SROM_MCS2GPO1) << 16;
4892 offset_mcs |=
4893 (u16) wlapi_getintvar(shim,
4894 BRCMS_SROM_MCS2GPO0);
4895 pi_lcn->lcnphy_mcs20_po = offset_mcs;
4896 for (i = TXP_FIRST_SISO_MCS_20;
4897 i <= TXP_LAST_SISO_MCS_20; i++) {
4898 pi->tx_srom_max_rate_2g[i] =
4899 txpwr - ((offset_mcs & 0xf) * 2);
4900 offset_mcs >>= 4;
4901 }
4902 }
4903
4904 pi_lcn->lcnphy_rawtempsense =
4905 (u16)wlapi_getintvar(shim, BRCMS_SROM_RAWTEMPSENSE);
4906 pi_lcn->lcnphy_measPower =
4907 (u8)wlapi_getintvar(shim, BRCMS_SROM_MEASPOWER);
4908 pi_lcn->lcnphy_tempsense_slope =
4909 (u8)wlapi_getintvar(shim, BRCMS_SROM_TEMPSENSE_SLOPE);
4910 pi_lcn->lcnphy_hw_iqcal_en =
4911 (bool)wlapi_getintvar(shim, BRCMS_SROM_HW_IQCAL_EN);
4912 pi_lcn->lcnphy_iqcal_swp_dis =
4913 (bool)wlapi_getintvar(shim, BRCMS_SROM_IQCAL_SWP_DIS);
4914 pi_lcn->lcnphy_tempcorrx =
4915 (u8)wlapi_getintvar(shim, BRCMS_SROM_TEMPCORRX);
4916 pi_lcn->lcnphy_tempsense_option =
4917 (u8)wlapi_getintvar(shim, BRCMS_SROM_TEMPSENSE_OPTION);
4918 pi_lcn->lcnphy_freqoffset_corr =
4919 (u8)wlapi_getintvar(shim, BRCMS_SROM_FREQOFFSET_CORR);
4920 if ((u8)wlapi_getintvar(shim, BRCMS_SROM_AA2G) > 1)
4921 wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi,
4922 (u8) wlapi_getintvar(shim, BRCMS_SROM_AA2G));
4923 }
4924 pi_lcn->lcnphy_cck_dig_filt_type = -1;
4925
4926 return true;
4927}
4928
4929void wlc_2064_vco_cal(struct brcms_phy *pi)
4930{
4931 u8 calnrst;
4932
4933 mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 1 << 3);
4934 calnrst = (u8) read_radio_reg(pi, RADIO_2064_REG056) & 0xf8;
4935 write_radio_reg(pi, RADIO_2064_REG056, calnrst);
4936 udelay(1);
4937 write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x03);
4938 udelay(1);
4939 write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x07);
4940 udelay(300);
4941 mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 0);
4942}
4943
4944bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi)
4945{
4946 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
4947 return 0;
4948 else
4949 return (LCNPHY_TX_PWR_CTRL_HW ==
4950 wlc_lcnphy_get_tx_pwr_ctrl((pi)));
4951}
4952
4953void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi)
4954{
4955 u16 pwr_ctrl;
4956 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
4957 wlc_lcnphy_calib_modes(pi, LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
4958 } else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
4959 pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
4960 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
4961 wlc_lcnphy_txpower_recalc_target(pi);
4962 wlc_lcnphy_set_tx_pwr_ctrl(pi, pwr_ctrl);
4963 }
4964}
4965
4966void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
4967{
4968 kfree(pi->u.pi_lcnphy);
4969}
4970
4971bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
4972{
4973 struct brcms_phy_lcnphy *pi_lcn;
4974
4975 pi->u.pi_lcnphy = kzalloc(sizeof(struct brcms_phy_lcnphy), GFP_ATOMIC);
4976 if (pi->u.pi_lcnphy == NULL)
4977 return false;
4978
4979 pi_lcn = pi->u.pi_lcnphy;
4980
4981 if (0 == (pi->sh->boardflags & BFL_NOPA)) {
4982 pi->hwpwrctrl = true;
4983 pi->hwpwrctrl_capable = true;
4984 }
4985
4986 pi->xtalfreq = si_pmu_alp_clock(pi->sh->sih);
4987 pi_lcn->lcnphy_papd_rxGnCtrl_init = 0;
4988
4989 pi->pi_fptr.init = wlc_phy_init_lcnphy;
4990 pi->pi_fptr.calinit = wlc_phy_cal_init_lcnphy;
4991 pi->pi_fptr.chanset = wlc_phy_chanspec_set_lcnphy;
4992 pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_lcnphy;
4993 pi->pi_fptr.txiqccget = wlc_lcnphy_get_tx_iqcc;
4994 pi->pi_fptr.txiqccset = wlc_lcnphy_set_tx_iqcc;
4995 pi->pi_fptr.txloccget = wlc_lcnphy_get_tx_locc;
4996 pi->pi_fptr.radioloftget = wlc_lcnphy_get_radio_loft;
4997 pi->pi_fptr.detach = wlc_phy_detach_lcnphy;
4998
4999 if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
5000 return false;
5001
5002 if ((pi->sh->boardflags & BFL_FEM) &&
5003 (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
5004 if (pi_lcn->lcnphy_tempsense_option == 3) {
5005 pi->hwpwrctrl = true;
5006 pi->hwpwrctrl_capable = true;
5007 pi->temppwrctrl_capable = false;
5008 } else {
5009 pi->hwpwrctrl = false;
5010 pi->hwpwrctrl_capable = false;
5011 pi->temppwrctrl_capable = true;
5012 }
5013 }
5014
5015 return true;
5016}
5017
5018static void wlc_lcnphy_set_rx_gain(struct brcms_phy *pi, u32 gain)
5019{
5020 u16 trsw, ext_lna, lna1, lna2, tia, biq0, biq1, gain0_15, gain16_19;
5021
5022 trsw = (gain & ((u32) 1 << 28)) ? 0 : 1;
5023 ext_lna = (u16) (gain >> 29) & 0x01;
5024 lna1 = (u16) (gain >> 0) & 0x0f;
5025 lna2 = (u16) (gain >> 4) & 0x0f;
5026 tia = (u16) (gain >> 8) & 0xf;
5027 biq0 = (u16) (gain >> 12) & 0xf;
5028 biq1 = (u16) (gain >> 16) & 0xf;
5029
5030 gain0_15 = (u16) ((lna1 & 0x3) | ((lna1 & 0x3) << 2) |
5031 ((lna2 & 0x3) << 4) | ((lna2 & 0x3) << 6) |
5032 ((tia & 0xf) << 8) | ((biq0 & 0xf) << 12));
5033 gain16_19 = biq1;
5034
5035 mod_phy_reg(pi, 0x44d, (0x1 << 0), trsw << 0);
5036 mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
5037 mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
5038 mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
5039 mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
5040
5041 if (CHSPEC_IS2G(pi->radio_chanspec)) {
5042 mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
5043 mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
5044 }
5045 wlc_lcnphy_rx_gain_override_enable(pi, true);
5046}
5047
5048static u32 wlc_lcnphy_get_receive_power(struct brcms_phy *pi, s32 *gain_index)
5049{
5050 u32 received_power = 0;
5051 s32 max_index = 0;
5052 u32 gain_code = 0;
5053 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
5054
5055 max_index = 36;
5056 if (*gain_index >= 0)
5057 gain_code = lcnphy_23bitgaincode_table[*gain_index];
5058
5059 if (-1 == *gain_index) {
5060 *gain_index = 0;
5061 while ((*gain_index <= (s32) max_index)
5062 && (received_power < 700)) {
5063 wlc_lcnphy_set_rx_gain(pi,
5064 lcnphy_23bitgaincode_table
5065 [*gain_index]);
5066 received_power =
5067 wlc_lcnphy_measure_digital_power(
5068 pi,
5069 pi_lcn->
5070 lcnphy_noise_samples);
5071 (*gain_index)++;
5072 }
5073 (*gain_index)--;
5074 } else {
5075 wlc_lcnphy_set_rx_gain(pi, gain_code);
5076 received_power =
5077 wlc_lcnphy_measure_digital_power(pi,
5078 pi_lcn->
5079 lcnphy_noise_samples);
5080 }
5081
5082 return received_power;
5083}
5084
5085s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index)
5086{
5087 s32 gain = 0;
5088 s32 nominal_power_db;
5089 s32 log_val, gain_mismatch, desired_gain, input_power_offset_db,
5090 input_power_db;
5091 s32 received_power, temperature;
5092 u32 power;
5093 u32 msb1, msb2, val1, val2, diff1, diff2;
5094 uint freq;
5095 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
5096
5097 received_power = wlc_lcnphy_get_receive_power(pi, &gain_index);
5098
5099 gain = lcnphy_gain_table[gain_index];
5100
5101 nominal_power_db = read_phy_reg(pi, 0x425) >> 8;
5102
5103 power = (received_power * 16);
5104 msb1 = ffs(power) - 1;
5105 msb2 = msb1 + 1;
5106 val1 = 1 << msb1;
5107 val2 = 1 << msb2;
5108 diff1 = (power - val1);
5109 diff2 = (val2 - power);
5110 if (diff1 < diff2)
5111 log_val = msb1;
5112 else
5113 log_val = msb2;
5114
5115 log_val = log_val * 3;
5116
5117 gain_mismatch = (nominal_power_db / 2) - (log_val);
5118
5119 desired_gain = gain + gain_mismatch;
5120
5121 input_power_offset_db = read_phy_reg(pi, 0x434) & 0xFF;
5122
5123 if (input_power_offset_db > 127)
5124 input_power_offset_db -= 256;
5125
5126 input_power_db = input_power_offset_db - desired_gain;
5127
5128 input_power_db =
5129 input_power_db + lcnphy_gain_index_offset_for_rssi[gain_index];
5130
5131 freq = wlc_phy_channel2freq(CHSPEC_CHANNEL(pi->radio_chanspec));
5132 if ((freq > 2427) && (freq <= 2467))
5133 input_power_db = input_power_db - 1;
5134
5135 temperature = pi_lcn->lcnphy_lastsensed_temperature;
5136
5137 if ((temperature - 15) < -30)
5138 input_power_db =
5139 input_power_db +
5140 (((temperature - 10 - 25) * 286) >> 12) -
5141 7;
5142 else if ((temperature - 15) < 4)
5143 input_power_db =
5144 input_power_db +
5145 (((temperature - 10 - 25) * 286) >> 12) -
5146 3;
5147 else
5148 input_power_db = input_power_db +
5149 (((temperature - 10 - 25) * 286) >> 12);
5150
5151 wlc_lcnphy_rx_gain_override_enable(pi, 0);
5152
5153 return input_power_db;
5154}
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 000000000000..f4a8ab09da43
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
@@ -0,0 +1,121 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_PHY_LCN_H_
18#define _BRCM_PHY_LCN_H_
19
20#include <types.h>
21
22struct brcms_phy_lcnphy {
23 int lcnphy_txrf_sp_9_override;
24 u8 lcnphy_full_cal_channel;
25 u8 lcnphy_cal_counter;
26 u16 lcnphy_cal_temper;
27 bool lcnphy_recal;
28
29 u8 lcnphy_rc_cap;
30 u32 lcnphy_mcs20_po;
31
32 u8 lcnphy_tr_isolation_mid;
33 u8 lcnphy_tr_isolation_low;
34 u8 lcnphy_tr_isolation_hi;
35
36 u8 lcnphy_bx_arch;
37 u8 lcnphy_rx_power_offset;
38 u8 lcnphy_rssi_vf;
39 u8 lcnphy_rssi_vc;
40 u8 lcnphy_rssi_gs;
41 u8 lcnphy_tssi_val;
42 u8 lcnphy_rssi_vf_lowtemp;
43 u8 lcnphy_rssi_vc_lowtemp;
44 u8 lcnphy_rssi_gs_lowtemp;
45
46 u8 lcnphy_rssi_vf_hightemp;
47 u8 lcnphy_rssi_vc_hightemp;
48 u8 lcnphy_rssi_gs_hightemp;
49
50 s16 lcnphy_pa0b0;
51 s16 lcnphy_pa0b1;
52 s16 lcnphy_pa0b2;
53
54 u16 lcnphy_rawtempsense;
55 u8 lcnphy_measPower;
56 u8 lcnphy_tempsense_slope;
57 u8 lcnphy_freqoffset_corr;
58 u8 lcnphy_tempsense_option;
59 u8 lcnphy_tempcorrx;
60 bool lcnphy_iqcal_swp_dis;
61 bool lcnphy_hw_iqcal_en;
62 uint lcnphy_bandedge_corr;
63 bool lcnphy_spurmod;
64 u16 lcnphy_tssi_tx_cnt;
65 u16 lcnphy_tssi_idx;
66 u16 lcnphy_tssi_npt;
67
68 u16 lcnphy_target_tx_freq;
69 s8 lcnphy_tx_power_idx_override;
70 u16 lcnphy_noise_samples;
71
72 u32 lcnphy_papdRxGnIdx;
73 u32 lcnphy_papd_rxGnCtrl_init;
74
75 u32 lcnphy_gain_idx_14_lowword;
76 u32 lcnphy_gain_idx_14_hiword;
77 u32 lcnphy_gain_idx_27_lowword;
78 u32 lcnphy_gain_idx_27_hiword;
79 s16 lcnphy_ofdmgainidxtableoffset;
80 s16 lcnphy_dsssgainidxtableoffset;
81 u32 lcnphy_tr_R_gain_val;
82 u32 lcnphy_tr_T_gain_val;
83 s8 lcnphy_input_pwr_offset_db;
84 u16 lcnphy_Med_Low_Gain_db;
85 u16 lcnphy_Very_Low_Gain_db;
86 s8 lcnphy_lastsensed_temperature;
87 s8 lcnphy_pkteng_rssi_slope;
88 u8 lcnphy_saved_tx_user_target[TXP_NUM_RATES];
89 u8 lcnphy_volt_winner;
90 u8 lcnphy_volt_low;
91 u8 lcnphy_54_48_36_24mbps_backoff;
92 u8 lcnphy_11n_backoff;
93 u8 lcnphy_lowerofdm;
94 u8 lcnphy_cck;
95 u8 lcnphy_psat_2pt3_detected;
96 s32 lcnphy_lowest_Re_div_Im;
97 s8 lcnphy_final_papd_cal_idx;
98 u16 lcnphy_extstxctrl4;
99 u16 lcnphy_extstxctrl0;
100 u16 lcnphy_extstxctrl1;
101 s16 lcnphy_cck_dig_filt_type;
102 s16 lcnphy_ofdm_dig_filt_type;
103 struct lcnphy_cal_results lcnphy_cal_results;
104
105 u8 lcnphy_psat_pwr;
106 u8 lcnphy_psat_indx;
107 s32 lcnphy_min_phase;
108 u8 lcnphy_final_idx;
109 u8 lcnphy_start_idx;
110 u8 lcnphy_current_index;
111 u16 lcnphy_logen_buf_1;
112 u16 lcnphy_local_ovr_2;
113 u16 lcnphy_local_oval_6;
114 u16 lcnphy_local_oval_5;
115 u16 lcnphy_logen_mixer_1;
116
117 u8 lcnphy_aci_stat;
118 uint lcnphy_aci_start_time;
119 s8 lcnphy_tx_power_offset[TXP_NUM_RATES];
120};
121#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 000000000000..cd19c2f7a347
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
@@ -0,0 +1,28876 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/kernel.h>
18#include <linux/delay.h>
19#include <linux/cordic.h>
20
21#include <brcm_hw_ids.h>
22#include <aiutils.h>
23#include <chipcommon.h>
24#include <pmu.h>
25#include <d11.h>
26#include <phy_shim.h>
27#include "phy_int.h"
28#include "phy_hal.h"
29#include "phy_radio.h"
30#include "phyreg_n.h"
31#include "phytbl_n.h"
32
33#define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \
34 read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \
35 ((core == PHY_CORE_0) ? \
36 radio_type##_##jspace##0 : \
37 radio_type##_##jspace##1))
38
39#define WRITE_RADIO_REG2(pi, radio_type, jspace, core, reg_name, value) \
40 write_radio_reg(pi, radio_type##_##jspace##_##reg_name | \
41 ((core == PHY_CORE_0) ? \
42 radio_type##_##jspace##0 : \
43 radio_type##_##jspace##1), value)
44
45#define WRITE_RADIO_SYN(pi, radio_type, reg_name, value) \
46 write_radio_reg(pi, radio_type##_##SYN##_##reg_name, value)
47
48#define READ_RADIO_REG3(pi, radio_type, jspace, core, reg_name) \
49 read_radio_reg(pi, ((core == PHY_CORE_0) ? \
50 radio_type##_##jspace##0##_##reg_name : \
51 radio_type##_##jspace##1##_##reg_name))
52
53#define WRITE_RADIO_REG3(pi, radio_type, jspace, core, reg_name, value) \
54 write_radio_reg(pi, ((core == PHY_CORE_0) ? \
55 radio_type##_##jspace##0##_##reg_name : \
56 radio_type##_##jspace##1##_##reg_name), \
57 value)
58
59#define READ_RADIO_REG4(pi, radio_type, jspace, core, reg_name) \
60 read_radio_reg(pi, ((core == PHY_CORE_0) ? \
61 radio_type##_##reg_name##_##jspace##0 : \
62 radio_type##_##reg_name##_##jspace##1))
63
64#define WRITE_RADIO_REG4(pi, radio_type, jspace, core, reg_name, value) \
65 write_radio_reg(pi, ((core == PHY_CORE_0) ? \
66 radio_type##_##reg_name##_##jspace##0 : \
67 radio_type##_##reg_name##_##jspace##1), \
68 value)
69
70#define NPHY_ACI_MAX_UNDETECT_WINDOW_SZ 40
71#define NPHY_ACI_CHANNEL_DELTA 5
72#define NPHY_ACI_CHANNEL_SKIP 4
73#define NPHY_ACI_40MHZ_CHANNEL_DELTA 6
74#define NPHY_ACI_40MHZ_CHANNEL_SKIP 5
75#define NPHY_ACI_40MHZ_CHANNEL_DELTA_GE_REV3 6
76#define NPHY_ACI_40MHZ_CHANNEL_SKIP_GE_REV3 5
77#define NPHY_ACI_CHANNEL_DELTA_GE_REV3 4
78#define NPHY_ACI_CHANNEL_SKIP_GE_REV3 3
79
80#define NPHY_NOISE_NOASSOC_GLITCH_TH_UP 2
81
82#define NPHY_NOISE_NOASSOC_GLITCH_TH_DN 8
83
84#define NPHY_NOISE_ASSOC_GLITCH_TH_UP 2
85
86#define NPHY_NOISE_ASSOC_GLITCH_TH_DN 8
87
88#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_UP 2
89
90#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_DN 8
91
92#define NPHY_NOISE_NOASSOC_ENTER_TH 400
93
94#define NPHY_NOISE_ASSOC_ENTER_TH 400
95
96#define NPHY_NOISE_ASSOC_RX_GLITCH_BADPLCP_ENTER_TH 400
97
98#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX 44
99#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX_REV_7 56
100
101#define NPHY_NOISE_NOASSOC_CRSIDX_INCR 16
102
103#define NPHY_NOISE_ASSOC_CRSIDX_INCR 8
104
105#define NPHY_IS_SROM_REINTERPRET NREV_GE(pi->pubpi.phy_rev, 5)
106
107#define NPHY_RSSICAL_MAXREAD 31
108
109#define NPHY_RSSICAL_NPOLL 8
110#define NPHY_RSSICAL_MAXD (1<<20)
111#define NPHY_MIN_RXIQ_PWR 2
112
113#define NPHY_RSSICAL_W1_TARGET 25
114#define NPHY_RSSICAL_W2_TARGET NPHY_RSSICAL_W1_TARGET
115#define NPHY_RSSICAL_NB_TARGET 0
116
117#define NPHY_RSSICAL_W1_TARGET_REV3 29
118#define NPHY_RSSICAL_W2_TARGET_REV3 NPHY_RSSICAL_W1_TARGET_REV3
119
120#define NPHY_CALSANITY_RSSI_NB_MAX_POS 9
121#define NPHY_CALSANITY_RSSI_NB_MAX_NEG -9
122#define NPHY_CALSANITY_RSSI_W1_MAX_POS 12
123#define NPHY_CALSANITY_RSSI_W1_MAX_NEG (NPHY_RSSICAL_W1_TARGET - \
124 NPHY_RSSICAL_MAXREAD)
125#define NPHY_CALSANITY_RSSI_W2_MAX_POS NPHY_CALSANITY_RSSI_W1_MAX_POS
126#define NPHY_CALSANITY_RSSI_W2_MAX_NEG (NPHY_RSSICAL_W2_TARGET - \
127 NPHY_RSSICAL_MAXREAD)
128#define NPHY_RSSI_SXT(x) ((s8) (-((x) & 0x20) + ((x) & 0x1f)))
129#define NPHY_RSSI_NB_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_NB_MAX_POS) || \
130 ((x) < NPHY_CALSANITY_RSSI_NB_MAX_NEG))
131#define NPHY_RSSI_W1_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_W1_MAX_POS) || \
132 ((x) < NPHY_CALSANITY_RSSI_W1_MAX_NEG))
133#define NPHY_RSSI_W2_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_W2_MAX_POS) || \
134 ((x) < NPHY_CALSANITY_RSSI_W2_MAX_NEG))
135
136#define NPHY_IQCAL_NUMGAINS 9
137#define NPHY_N_GCTL 0x66
138
139#define NPHY_PAPD_EPS_TBL_SIZE 64
140#define NPHY_PAPD_SCL_TBL_SIZE 64
141#define NPHY_NUM_DIG_FILT_COEFFS 15
142
143#define NPHY_PAPD_COMP_OFF 0
144#define NPHY_PAPD_COMP_ON 1
145
146#define NPHY_SROM_TEMPSHIFT 32
147#define NPHY_SROM_MAXTEMPOFFSET 16
148#define NPHY_SROM_MINTEMPOFFSET -16
149
150#define NPHY_CAL_MAXTEMPDELTA 64
151
152#define NPHY_NOISEVAR_TBLLEN40 256
153#define NPHY_NOISEVAR_TBLLEN20 128
154
155#define NPHY_ANARXLPFBW_REDUCTIONFACT 7
156
157#define NPHY_ADJUSTED_MINCRSPOWER 0x1e
158
159/* 5357 Chip specific ChipControl register bits */
160#define CCTRL5357_EXTPA (1<<14) /* extPA in ChipControl 1, bit 14 */
161#define CCTRL5357_ANT_MUX_2o3 (1<<15) /* 2o3 in ChipControl 1, bit 15 */
162
163#define NPHY_CAL_TSSISAMPS 64
164#define NPHY_TEST_TONE_FREQ_40MHz 4000
165#define NPHY_TEST_TONE_FREQ_20MHz 2500
166
167#define MAX_205x_RCAL_WAITLOOPS 10000
168
169#define NPHY_RXCAL_TONEAMP 181
170#define NPHY_RXCAL_TONEFREQ_40MHz 4000
171#define NPHY_RXCAL_TONEFREQ_20MHz 2000
172
173#define TXFILT_SHAPING_OFDM20 0
174#define TXFILT_SHAPING_OFDM40 1
175#define TXFILT_SHAPING_CCK 2
176#define TXFILT_DEFAULT_OFDM20 3
177#define TXFILT_DEFAULT_OFDM40 4
178
179struct nphy_iqcal_params {
180 u16 txlpf;
181 u16 txgm;
182 u16 pga;
183 u16 pad;
184 u16 ipa;
185 u16 cal_gain;
186 u16 ncorr[5];
187};
188
189struct nphy_txiqcal_ladder {
190 u8 percent;
191 u8 g_env;
192};
193
194struct nphy_ipa_txcalgains {
195 struct nphy_txgains gains;
196 bool useindex;
197 u8 index;
198};
199
200struct nphy_papd_restore_state {
201 u16 fbmix[2];
202 u16 vga_master[2];
203 u16 intpa_master[2];
204 u16 afectrl[2];
205 u16 afeoverride[2];
206 u16 pwrup[2];
207 u16 atten[2];
208 u16 mm;
209};
210
211struct nphy_ipa_txrxgain {
212 u16 hpvga;
213 u16 lpf_biq1;
214 u16 lpf_biq0;
215 u16 lna2;
216 u16 lna1;
217 s8 txpwrindex;
218};
219
220#define NPHY_IPA_RXCAL_MAXGAININDEX (6 - 1)
221
222static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz[] = {
223 {0, 0, 0, 0, 0, 100},
224 {0, 0, 0, 0, 0, 50},
225 {0, 0, 0, 0, 0, -1},
226 {0, 0, 0, 3, 0, -1},
227 {0, 0, 3, 3, 0, -1},
228 {0, 2, 3, 3, 0, -1}
229};
230
231static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz[] = {
232 {0, 0, 0, 0, 0, 128},
233 {0, 0, 0, 0, 0, 70},
234 {0, 0, 0, 0, 0, 20},
235 {0, 0, 0, 3, 0, 20},
236 {0, 0, 3, 3, 0, 20},
237 {0, 2, 3, 3, 0, 20}
238};
239
240static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz_rev7[] = {
241 {0, 0, 0, 0, 0, 100},
242 {0, 0, 0, 0, 0, 50},
243 {0, 0, 0, 0, 0, -1},
244 {0, 0, 0, 3, 0, -1},
245 {0, 0, 3, 3, 0, -1},
246 {0, 0, 5, 3, 0, -1}
247};
248
249static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz_rev7[] = {
250 {0, 0, 0, 0, 0, 10},
251 {0, 0, 0, 1, 0, 10},
252 {0, 0, 1, 2, 0, 10},
253 {0, 0, 1, 3, 0, 10},
254 {0, 0, 4, 3, 0, 10},
255 {0, 0, 6, 3, 0, 10}
256};
257
258enum {
259 NPHY_RXCAL_GAIN_INIT = 0,
260 NPHY_RXCAL_GAIN_UP,
261 NPHY_RXCAL_GAIN_DOWN
262};
263
264#define wlc_phy_get_papd_nphy(pi) \
265 (read_phy_reg((pi), 0x1e7) & \
266 ((0x1 << 15) | \
267 (0x1 << 14) | \
268 (0x1 << 13)))
269
270static const u16 NPHY_IPA_REV4_txdigi_filtcoeffs[][NPHY_NUM_DIG_FILT_COEFFS] = {
271 {-377, 137, -407, 208, -1527, 956, 93, 186, 93,
272 230, -44, 230, 201, -191, 201},
273 {-77, 20, -98, 49, -93, 60, 56, 111, 56, 26, -5,
274 26, 34, -32, 34},
275 {-360, 164, -376, 164, -1533, 576, 308, -314, 308,
276 121, -73, 121, 91, 124, 91},
277 {-295, 200, -363, 142, -1391, 826, 151, 301, 151,
278 151, 301, 151, 602, -752, 602},
279 {-92, 58, -96, 49, -104, 44, 17, 35, 17,
280 12, 25, 12, 13, 27, 13},
281 {-375, 136, -399, 209, -1479, 949, 130, 260, 130,
282 230, -44, 230, 201, -191, 201},
283 {0xed9, 0xc8, 0xe95, 0x8e, 0xa91, 0x33a, 0x97, 0x12d, 0x97,
284 0x97, 0x12d, 0x97, 0x25a, 0xd10, 0x25a}
285};
286
287struct chan_info_nphy_2055 {
288 u16 chan;
289 u16 freq;
290 uint unknown;
291 u8 RF_pll_ref;
292 u8 RF_rf_pll_mod1;
293 u8 RF_rf_pll_mod0;
294 u8 RF_vco_cap_tail;
295 u8 RF_vco_cal1;
296 u8 RF_vco_cal2;
297 u8 RF_pll_lf_c1;
298 u8 RF_pll_lf_r1;
299 u8 RF_pll_lf_c2;
300 u8 RF_lgbuf_cen_buf;
301 u8 RF_lgen_tune1;
302 u8 RF_lgen_tune2;
303 u8 RF_core1_lgbuf_a_tune;
304 u8 RF_core1_lgbuf_g_tune;
305 u8 RF_core1_rxrf_reg1;
306 u8 RF_core1_tx_pga_pad_tn;
307 u8 RF_core1_tx_mx_bgtrim;
308 u8 RF_core2_lgbuf_a_tune;
309 u8 RF_core2_lgbuf_g_tune;
310 u8 RF_core2_rxrf_reg1;
311 u8 RF_core2_tx_pga_pad_tn;
312 u8 RF_core2_tx_mx_bgtrim;
313 u16 PHY_BW1a;
314 u16 PHY_BW2;
315 u16 PHY_BW3;
316 u16 PHY_BW4;
317 u16 PHY_BW5;
318 u16 PHY_BW6;
319};
320
321struct chan_info_nphy_radio205x {
322 u16 chan;
323 u16 freq;
324 u8 RF_SYN_pll_vcocal1;
325 u8 RF_SYN_pll_vcocal2;
326 u8 RF_SYN_pll_refdiv;
327 u8 RF_SYN_pll_mmd2;
328 u8 RF_SYN_pll_mmd1;
329 u8 RF_SYN_pll_loopfilter1;
330 u8 RF_SYN_pll_loopfilter2;
331 u8 RF_SYN_pll_loopfilter3;
332 u8 RF_SYN_pll_loopfilter4;
333 u8 RF_SYN_pll_loopfilter5;
334 u8 RF_SYN_reserved_addr27;
335 u8 RF_SYN_reserved_addr28;
336 u8 RF_SYN_reserved_addr29;
337 u8 RF_SYN_logen_VCOBUF1;
338 u8 RF_SYN_logen_MIXER2;
339 u8 RF_SYN_logen_BUF3;
340 u8 RF_SYN_logen_BUF4;
341 u8 RF_RX0_lnaa_tune;
342 u8 RF_RX0_lnag_tune;
343 u8 RF_TX0_intpaa_boost_tune;
344 u8 RF_TX0_intpag_boost_tune;
345 u8 RF_TX0_pada_boost_tune;
346 u8 RF_TX0_padg_boost_tune;
347 u8 RF_TX0_pgaa_boost_tune;
348 u8 RF_TX0_pgag_boost_tune;
349 u8 RF_TX0_mixa_boost_tune;
350 u8 RF_TX0_mixg_boost_tune;
351 u8 RF_RX1_lnaa_tune;
352 u8 RF_RX1_lnag_tune;
353 u8 RF_TX1_intpaa_boost_tune;
354 u8 RF_TX1_intpag_boost_tune;
355 u8 RF_TX1_pada_boost_tune;
356 u8 RF_TX1_padg_boost_tune;
357 u8 RF_TX1_pgaa_boost_tune;
358 u8 RF_TX1_pgag_boost_tune;
359 u8 RF_TX1_mixa_boost_tune;
360 u8 RF_TX1_mixg_boost_tune;
361 u16 PHY_BW1a;
362 u16 PHY_BW2;
363 u16 PHY_BW3;
364 u16 PHY_BW4;
365 u16 PHY_BW5;
366 u16 PHY_BW6;
367};
368
369struct chan_info_nphy_radio2057 {
370 u16 chan;
371 u16 freq;
372 u8 RF_vcocal_countval0;
373 u8 RF_vcocal_countval1;
374 u8 RF_rfpll_refmaster_sparextalsize;
375 u8 RF_rfpll_loopfilter_r1;
376 u8 RF_rfpll_loopfilter_c2;
377 u8 RF_rfpll_loopfilter_c1;
378 u8 RF_cp_kpd_idac;
379 u8 RF_rfpll_mmd0;
380 u8 RF_rfpll_mmd1;
381 u8 RF_vcobuf_tune;
382 u8 RF_logen_mx2g_tune;
383 u8 RF_logen_mx5g_tune;
384 u8 RF_logen_indbuf2g_tune;
385 u8 RF_logen_indbuf5g_tune;
386 u8 RF_txmix2g_tune_boost_pu_core0;
387 u8 RF_pad2g_tune_pus_core0;
388 u8 RF_pga_boost_tune_core0;
389 u8 RF_txmix5g_boost_tune_core0;
390 u8 RF_pad5g_tune_misc_pus_core0;
391 u8 RF_lna2g_tune_core0;
392 u8 RF_lna5g_tune_core0;
393 u8 RF_txmix2g_tune_boost_pu_core1;
394 u8 RF_pad2g_tune_pus_core1;
395 u8 RF_pga_boost_tune_core1;
396 u8 RF_txmix5g_boost_tune_core1;
397 u8 RF_pad5g_tune_misc_pus_core1;
398 u8 RF_lna2g_tune_core1;
399 u8 RF_lna5g_tune_core1;
400 u16 PHY_BW1a;
401 u16 PHY_BW2;
402 u16 PHY_BW3;
403 u16 PHY_BW4;
404 u16 PHY_BW5;
405 u16 PHY_BW6;
406};
407
408struct chan_info_nphy_radio2057_rev5 {
409 u16 chan;
410 u16 freq;
411 u8 RF_vcocal_countval0;
412 u8 RF_vcocal_countval1;
413 u8 RF_rfpll_refmaster_sparextalsize;
414 u8 RF_rfpll_loopfilter_r1;
415 u8 RF_rfpll_loopfilter_c2;
416 u8 RF_rfpll_loopfilter_c1;
417 u8 RF_cp_kpd_idac;
418 u8 RF_rfpll_mmd0;
419 u8 RF_rfpll_mmd1;
420 u8 RF_vcobuf_tune;
421 u8 RF_logen_mx2g_tune;
422 u8 RF_logen_indbuf2g_tune;
423 u8 RF_txmix2g_tune_boost_pu_core0;
424 u8 RF_pad2g_tune_pus_core0;
425 u8 RF_lna2g_tune_core0;
426 u8 RF_txmix2g_tune_boost_pu_core1;
427 u8 RF_pad2g_tune_pus_core1;
428 u8 RF_lna2g_tune_core1;
429 u16 PHY_BW1a;
430 u16 PHY_BW2;
431 u16 PHY_BW3;
432 u16 PHY_BW4;
433 u16 PHY_BW5;
434 u16 PHY_BW6;
435};
436
437struct nphy_sfo_cfg {
438 u16 PHY_BW1a;
439 u16 PHY_BW2;
440 u16 PHY_BW3;
441 u16 PHY_BW4;
442 u16 PHY_BW5;
443 u16 PHY_BW6;
444};
445
446static const struct chan_info_nphy_2055 chan_info_nphy_2055[] = {
447 {
448 184, 4920, 3280, 0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
449 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
450 0x0F, 0x8F, 0x7B4, 0x7B0, 0x7AC, 0x214, 0x215, 0x216},
451 {
452 186, 4930, 3287, 0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
453 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
454 0x0F, 0x8F, 0x7B8, 0x7B4, 0x7B0, 0x213, 0x214, 0x215},
455 {
456 188, 4940, 3293, 0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
457 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
458 0x0F, 0x8F, 0x7BC, 0x7B8, 0x7B4, 0x212, 0x213, 0x214},
459 {
460 190, 4950, 3300, 0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
461 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
462 0x0F, 0x8F, 0x7C0, 0x7BC, 0x7B8, 0x211, 0x212, 0x213},
463 {
464 192, 4960, 3307, 0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
465 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
466 0x0F, 0x8F, 0x7C4, 0x7C0, 0x7BC, 0x20F, 0x211, 0x212},
467 {
468 194, 4970, 3313, 0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
469 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
470 0x0F, 0x8F, 0x7C8, 0x7C4, 0x7C0, 0x20E, 0x20F, 0x211},
471 {
472 196, 4980, 3320, 0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
473 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
474 0x0F, 0x8F, 0x7CC, 0x7C8, 0x7C4, 0x20D, 0x20E, 0x20F},
475 {
476 198, 4990, 3327, 0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
477 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
478 0x0F, 0x8F, 0x7D0, 0x7CC, 0x7C8, 0x20C, 0x20D, 0x20E},
479 {
480 200, 5000, 3333, 0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
481 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
482 0x0F, 0x8F, 0x7D4, 0x7D0, 0x7CC, 0x20B, 0x20C, 0x20D},
483 {
484 202, 5010, 3340, 0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
485 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
486 0x0F, 0x8F, 0x7D8, 0x7D4, 0x7D0, 0x20A, 0x20B, 0x20C},
487 {
488 204, 5020, 3347, 0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
489 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
490 0x0F, 0x8F, 0x7DC, 0x7D8, 0x7D4, 0x209, 0x20A, 0x20B},
491 {
492 206, 5030, 3353, 0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
493 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
494 0x0F, 0x8F, 0x7E0, 0x7DC, 0x7D8, 0x208, 0x209, 0x20A},
495 {
496 208, 5040, 3360, 0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
497 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
498 0x0F, 0x8F, 0x7E4, 0x7E0, 0x7DC, 0x207, 0x208, 0x209},
499 {
500 210, 5050, 3367, 0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
501 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
502 0x0F, 0x8F, 0x7E8, 0x7E4, 0x7E0, 0x206, 0x207, 0x208},
503 {
504 212, 5060, 3373, 0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
505 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
506 0x0F, 0x8E, 0x7EC, 0x7E8, 0x7E4, 0x205, 0x206, 0x207},
507 {
508 214, 5070, 3380, 0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
509 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
510 0x0F, 0x8E, 0x7F0, 0x7EC, 0x7E8, 0x204, 0x205, 0x206},
511 {
512 216, 5080, 3387, 0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
513 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
514 0x0F, 0x8D, 0x7F4, 0x7F0, 0x7EC, 0x203, 0x204, 0x205},
515 {
516 218, 5090, 3393, 0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
517 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
518 0x0F, 0x8D, 0x7F8, 0x7F4, 0x7F0, 0x202, 0x203, 0x204},
519 {
520 220, 5100, 3400, 0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
521 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
522 0x0F, 0x8D, 0x7FC, 0x7F8, 0x7F4, 0x201, 0x202, 0x203},
523 {
524 222, 5110, 3407, 0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
525 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
526 0x0F, 0x8D, 0x800, 0x7FC, 0x7F8, 0x200, 0x201, 0x202},
527 {
528 224, 5120, 3413, 0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
529 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
530 0x0F, 0x8C, 0x804, 0x800, 0x7FC, 0x1FF, 0x200, 0x201},
531 {
532 226, 5130, 3420, 0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
533 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
534 0x0F, 0x8C, 0x808, 0x804, 0x800, 0x1FE, 0x1FF, 0x200},
535 {
536 228, 5140, 3427, 0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
537 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, 0x8B, 0xDD, 0x00, 0x0C,
538 0x0E, 0x8B, 0x80C, 0x808, 0x804, 0x1FD, 0x1FE, 0x1FF},
539 {
540 32, 5160, 3440, 0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
541 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
542 0x0D, 0x8A, 0x814, 0x810, 0x80C, 0x1FB, 0x1FC, 0x1FD},
543 {
544 34, 5170, 3447, 0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
545 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
546 0x0D, 0x8A, 0x818, 0x814, 0x810, 0x1FA, 0x1FB, 0x1FC},
547 {
548 36, 5180, 3453, 0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
549 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
550 0x0C, 0x89, 0x81C, 0x818, 0x814, 0x1F9, 0x1FA, 0x1FB},
551 {
552 38, 5190, 3460, 0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
553 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
554 0x0C, 0x89, 0x820, 0x81C, 0x818, 0x1F8, 0x1F9, 0x1FA},
555 {
556 40, 5200, 3467, 0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
557 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
558 0x0B, 0x89, 0x824, 0x820, 0x81C, 0x1F7, 0x1F8, 0x1F9},
559 {
560 42, 5210, 3473, 0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
561 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
562 0x0B, 0x89, 0x828, 0x824, 0x820, 0x1F6, 0x1F7, 0x1F8},
563 {
564 44, 5220, 3480, 0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
565 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
566 0x0A, 0x88, 0x82C, 0x828, 0x824, 0x1F5, 0x1F6, 0x1F7},
567 {
568 46, 5230, 3487, 0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
569 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
570 0x0A, 0x88, 0x830, 0x82C, 0x828, 0x1F4, 0x1F5, 0x1F6},
571 {
572 48, 5240, 3493, 0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
573 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
574 0x0A, 0x87, 0x834, 0x830, 0x82C, 0x1F3, 0x1F4, 0x1F5},
575 {
576 50, 5250, 3500, 0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
577 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
578 0x0A, 0x87, 0x838, 0x834, 0x830, 0x1F2, 0x1F3, 0x1F4},
579 {
580 52, 5260, 3507, 0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
581 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
582 0x09, 0x87, 0x83C, 0x838, 0x834, 0x1F1, 0x1F2, 0x1F3},
583 {
584 54, 5270, 3513, 0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
585 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
586 0x09, 0x87, 0x840, 0x83C, 0x838, 0x1F0, 0x1F1, 0x1F2},
587 {
588 56, 5280, 3520, 0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
589 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
590 0x08, 0x86, 0x844, 0x840, 0x83C, 0x1F0, 0x1F0, 0x1F1},
591 {
592 58, 5290, 3527, 0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
593 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
594 0x08, 0x86, 0x848, 0x844, 0x840, 0x1EF, 0x1F0, 0x1F0},
595 {
596 60, 5300, 3533, 0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
597 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
598 0x07, 0x85, 0x84C, 0x848, 0x844, 0x1EE, 0x1EF, 0x1F0},
599 {
600 62, 5310, 3540, 0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
601 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
602 0x07, 0x85, 0x850, 0x84C, 0x848, 0x1ED, 0x1EE, 0x1EF},
603 {
604 64, 5320, 3547, 0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
605 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
606 0x07, 0x84, 0x854, 0x850, 0x84C, 0x1EC, 0x1ED, 0x1EE},
607 {
608 66, 5330, 3553, 0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
609 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
610 0x07, 0x84, 0x858, 0x854, 0x850, 0x1EB, 0x1EC, 0x1ED},
611 {
612 68, 5340, 3560, 0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
613 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
614 0x06, 0x84, 0x85C, 0x858, 0x854, 0x1EA, 0x1EB, 0x1EC},
615 {
616 70, 5350, 3567, 0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
617 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
618 0x06, 0x84, 0x860, 0x85C, 0x858, 0x1E9, 0x1EA, 0x1EB},
619 {
620 72, 5360, 3573, 0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
621 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
622 0x05, 0x83, 0x864, 0x860, 0x85C, 0x1E8, 0x1E9, 0x1EA},
623 {
624 74, 5370, 3580, 0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
625 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
626 0x05, 0x83, 0x868, 0x864, 0x860, 0x1E7, 0x1E8, 0x1E9},
627 {
628 76, 5380, 3587, 0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
629 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
630 0x04, 0x82, 0x86C, 0x868, 0x864, 0x1E6, 0x1E7, 0x1E8},
631 {
632 78, 5390, 3593, 0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
633 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
634 0x04, 0x82, 0x870, 0x86C, 0x868, 0x1E5, 0x1E6, 0x1E7},
635 {
636 80, 5400, 3600, 0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
637 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
638 0x04, 0x81, 0x874, 0x870, 0x86C, 0x1E5, 0x1E5, 0x1E6},
639 {
640 82, 5410, 3607, 0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
641 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
642 0x04, 0x81, 0x878, 0x874, 0x870, 0x1E4, 0x1E5, 0x1E5},
643 {
644 84, 5420, 3613, 0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
645 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
646 0x03, 0x80, 0x87C, 0x878, 0x874, 0x1E3, 0x1E4, 0x1E5},
647 {
648 86, 5430, 3620, 0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
649 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
650 0x03, 0x80, 0x880, 0x87C, 0x878, 0x1E2, 0x1E3, 0x1E4},
651 {
652 88, 5440, 3627, 0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
653 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
654 0x02, 0x80, 0x884, 0x880, 0x87C, 0x1E1, 0x1E2, 0x1E3},
655 {
656 90, 5450, 3633, 0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
657 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
658 0x02, 0x80, 0x888, 0x884, 0x880, 0x1E0, 0x1E1, 0x1E2},
659 {
660 92, 5460, 3640, 0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
661 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
662 0x01, 0x80, 0x88C, 0x888, 0x884, 0x1DF, 0x1E0, 0x1E1},
663 {
664 94, 5470, 3647, 0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
665 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
666 0x01, 0x80, 0x890, 0x88C, 0x888, 0x1DE, 0x1DF, 0x1E0},
667 {
668 96, 5480, 3653, 0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
669 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
670 0x00, 0x80, 0x894, 0x890, 0x88C, 0x1DD, 0x1DE, 0x1DF},
671 {
672 98, 5490, 3660, 0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
673 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
674 0x00, 0x80, 0x898, 0x894, 0x890, 0x1DD, 0x1DD, 0x1DE},
675 {
676 100, 5500, 3667, 0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
677 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
678 0x00, 0x80, 0x89C, 0x898, 0x894, 0x1DC, 0x1DD, 0x1DD},
679 {
680 102, 5510, 3673, 0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
681 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
682 0x00, 0x80, 0x8A0, 0x89C, 0x898, 0x1DB, 0x1DC, 0x1DD},
683 {
684 104, 5520, 3680, 0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
685 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
686 0x00, 0x80, 0x8A4, 0x8A0, 0x89C, 0x1DA, 0x1DB, 0x1DC},
687 {
688 106, 5530, 3687, 0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
689 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
690 0x00, 0x80, 0x8A8, 0x8A4, 0x8A0, 0x1D9, 0x1DA, 0x1DB},
691 {
692 108, 5540, 3693, 0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
693 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
694 0x00, 0x80, 0x8AC, 0x8A8, 0x8A4, 0x1D8, 0x1D9, 0x1DA},
695 {
696 110, 5550, 3700, 0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
697 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
698 0x00, 0x80, 0x8B0, 0x8AC, 0x8A8, 0x1D7, 0x1D8, 0x1D9},
699 {
700 112, 5560, 3707, 0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
701 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
702 0x00, 0x80, 0x8B4, 0x8B0, 0x8AC, 0x1D7, 0x1D7, 0x1D8},
703 {
704 114, 5570, 3713, 0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
705 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
706 0x00, 0x80, 0x8B8, 0x8B4, 0x8B0, 0x1D6, 0x1D7, 0x1D7},
707 {
708 116, 5580, 3720, 0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
709 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
710 0x00, 0x80, 0x8BC, 0x8B8, 0x8B4, 0x1D5, 0x1D6, 0x1D7},
711 {
712 118, 5590, 3727, 0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
713 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
714 0x00, 0x80, 0x8C0, 0x8BC, 0x8B8, 0x1D4, 0x1D5, 0x1D6},
715 {
716 120, 5600, 3733, 0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
717 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
718 0x00, 0x80, 0x8C4, 0x8C0, 0x8BC, 0x1D3, 0x1D4, 0x1D5},
719 {
720 122, 5610, 3740, 0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
721 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
722 0x00, 0x80, 0x8C8, 0x8C4, 0x8C0, 0x1D2, 0x1D3, 0x1D4},
723 {
724 124, 5620, 3747, 0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
725 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
726 0x00, 0x80, 0x8CC, 0x8C8, 0x8C4, 0x1D2, 0x1D2, 0x1D3},
727 {
728 126, 5630, 3753, 0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
729 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
730 0x00, 0x80, 0x8D0, 0x8CC, 0x8C8, 0x1D1, 0x1D2, 0x1D2},
731 {
732 128, 5640, 3760, 0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
733 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
734 0x00, 0x80, 0x8D4, 0x8D0, 0x8CC, 0x1D0, 0x1D1, 0x1D2},
735 {
736 130, 5650, 3767, 0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
737 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
738 0x00, 0x80, 0x8D8, 0x8D4, 0x8D0, 0x1CF, 0x1D0, 0x1D1},
739 {
740 132, 5660, 3773, 0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
741 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
742 0x00, 0x80, 0x8DC, 0x8D8, 0x8D4, 0x1CE, 0x1CF, 0x1D0},
743 {
744 134, 5670, 3780, 0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
745 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
746 0x00, 0x80, 0x8E0, 0x8DC, 0x8D8, 0x1CE, 0x1CE, 0x1CF},
747 {
748 136, 5680, 3787, 0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
749 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
750 0x00, 0x80, 0x8E4, 0x8E0, 0x8DC, 0x1CD, 0x1CE, 0x1CE},
751 {
752 138, 5690, 3793, 0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
753 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
754 0x00, 0x80, 0x8E8, 0x8E4, 0x8E0, 0x1CC, 0x1CD, 0x1CE},
755 {
756 140, 5700, 3800, 0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
757 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
758 0x00, 0x80, 0x8EC, 0x8E8, 0x8E4, 0x1CB, 0x1CC, 0x1CD},
759 {
760 142, 5710, 3807, 0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
761 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
762 0x00, 0x80, 0x8F0, 0x8EC, 0x8E8, 0x1CA, 0x1CB, 0x1CC},
763 {
764 144, 5720, 3813, 0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
765 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
766 0x00, 0x80, 0x8F4, 0x8F0, 0x8EC, 0x1C9, 0x1CA, 0x1CB},
767 {
768 145, 5725, 3817, 0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
769 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
770 0x00, 0x80, 0x8F6, 0x8F2, 0x8EE, 0x1C9, 0x1CA, 0x1CB},
771 {
772 146, 5730, 3820, 0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
773 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
774 0x00, 0x80, 0x8F8, 0x8F4, 0x8F0, 0x1C9, 0x1C9, 0x1CA},
775 {
776 147, 5735, 3823, 0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
777 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
778 0x00, 0x80, 0x8FA, 0x8F6, 0x8F2, 0x1C8, 0x1C9, 0x1CA},
779 {
780 148, 5740, 3827, 0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
781 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
782 0x00, 0x80, 0x8FC, 0x8F8, 0x8F4, 0x1C8, 0x1C9, 0x1C9},
783 {
784 149, 5745, 3830, 0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
785 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
786 0x00, 0x80, 0x8FE, 0x8FA, 0x8F6, 0x1C8, 0x1C8, 0x1C9},
787 {
788 150, 5750, 3833, 0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
789 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
790 0x00, 0x80, 0x900, 0x8FC, 0x8F8, 0x1C7, 0x1C8, 0x1C9},
791 {
792 151, 5755, 3837, 0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
793 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
794 0x00, 0x80, 0x902, 0x8FE, 0x8FA, 0x1C7, 0x1C8, 0x1C8},
795 {
796 152, 5760, 3840, 0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
797 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
798 0x00, 0x80, 0x904, 0x900, 0x8FC, 0x1C6, 0x1C7, 0x1C8},
799 {
800 153, 5765, 3843, 0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
801 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
802 0x00, 0x80, 0x906, 0x902, 0x8FE, 0x1C6, 0x1C7, 0x1C8},
803 {
804 154, 5770, 3847, 0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
805 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
806 0x00, 0x80, 0x908, 0x904, 0x900, 0x1C6, 0x1C6, 0x1C7},
807 {
808 155, 5775, 3850, 0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
809 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
810 0x00, 0x80, 0x90A, 0x906, 0x902, 0x1C5, 0x1C6, 0x1C7},
811 {
812 156, 5780, 3853, 0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
813 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
814 0x00, 0x80, 0x90C, 0x908, 0x904, 0x1C5, 0x1C6, 0x1C6},
815 {
816 157, 5785, 3857, 0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
817 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
818 0x00, 0x80, 0x90E, 0x90A, 0x906, 0x1C4, 0x1C5, 0x1C6},
819 {
820 158, 5790, 3860, 0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
821 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
822 0x00, 0x80, 0x910, 0x90C, 0x908, 0x1C4, 0x1C5, 0x1C6},
823 {
824 159, 5795, 3863, 0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
825 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
826 0x00, 0x80, 0x912, 0x90E, 0x90A, 0x1C4, 0x1C4, 0x1C5},
827 {
828 160, 5800, 3867, 0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
829 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
830 0x00, 0x80, 0x914, 0x910, 0x90C, 0x1C3, 0x1C4, 0x1C5},
831 {
832 161, 5805, 3870, 0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
833 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
834 0x00, 0x80, 0x916, 0x912, 0x90E, 0x1C3, 0x1C4, 0x1C4},
835 {
836 162, 5810, 3873, 0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
837 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
838 0x00, 0x80, 0x918, 0x914, 0x910, 0x1C2, 0x1C3, 0x1C4},
839 {
840 163, 5815, 3877, 0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
841 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
842 0x00, 0x80, 0x91A, 0x916, 0x912, 0x1C2, 0x1C3, 0x1C4},
843 {
844 164, 5820, 3880, 0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
845 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
846 0x00, 0x80, 0x91C, 0x918, 0x914, 0x1C2, 0x1C2, 0x1C3},
847 {
848 165, 5825, 3883, 0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
849 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
850 0x00, 0x80, 0x91E, 0x91A, 0x916, 0x1C1, 0x1C2, 0x1C3},
851 {
852 166, 5830, 3887, 0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
853 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
854 0x00, 0x80, 0x920, 0x91C, 0x918, 0x1C1, 0x1C2, 0x1C2},
855 {
856 168, 5840, 3893, 0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
857 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
858 0x00, 0x80, 0x924, 0x920, 0x91C, 0x1C0, 0x1C1, 0x1C2},
859 {
860 170, 5850, 3900, 0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
861 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
862 0x00, 0x80, 0x928, 0x924, 0x920, 0x1BF, 0x1C0, 0x1C1},
863 {
864 172, 5860, 3907, 0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
865 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
866 0x00, 0x80, 0x92C, 0x928, 0x924, 0x1BF, 0x1BF, 0x1C0},
867 {
868 174, 5870, 3913, 0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
869 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
870 0x00, 0x80, 0x930, 0x92C, 0x928, 0x1BE, 0x1BF, 0x1BF},
871 {
872 176, 5880, 3920, 0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
873 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
874 0x00, 0x80, 0x934, 0x930, 0x92C, 0x1BD, 0x1BE, 0x1BF},
875 {
876 178, 5890, 3927, 0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
877 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
878 0x00, 0x80, 0x938, 0x934, 0x930, 0x1BC, 0x1BD, 0x1BE},
879 {
880 180, 5900, 3933, 0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
881 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
882 0x00, 0x80, 0x93C, 0x938, 0x934, 0x1BC, 0x1BC, 0x1BD},
883 {
884 182, 5910, 3940, 0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
885 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
886 0x00, 0x80, 0x940, 0x93C, 0x938, 0x1BB, 0x1BC, 0x1BC},
887 {
888 1, 2412, 3216, 0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
889 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, 0x80, 0xFF, 0x88, 0x0D,
890 0x0C, 0x80, 0x3C9, 0x3C5, 0x3C1, 0x43A, 0x43F, 0x443},
891 {
892 2, 2417, 3223, 0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
893 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, 0x80, 0xFF, 0x88, 0x0C,
894 0x0B, 0x80, 0x3CB, 0x3C7, 0x3C3, 0x438, 0x43D, 0x441},
895 {
896 3, 2422, 3229, 0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
897 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
898 0x0A, 0x80, 0x3CD, 0x3C9, 0x3C5, 0x436, 0x43A, 0x43F},
899 {
900 4, 2427, 3236, 0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
901 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
902 0x0A, 0x80, 0x3CF, 0x3CB, 0x3C7, 0x434, 0x438, 0x43D},
903 {
904 5, 2432, 3243, 0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
905 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, 0x80, 0xFF, 0x88, 0x0C,
906 0x09, 0x80, 0x3D1, 0x3CD, 0x3C9, 0x431, 0x436, 0x43A},
907 {
908 6, 2437, 3249, 0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
909 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, 0x80, 0xFF, 0x88, 0x0B,
910 0x08, 0x80, 0x3D3, 0x3CF, 0x3CB, 0x42F, 0x434, 0x438},
911 {
912 7, 2442, 3256, 0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
913 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, 0x80, 0xFF, 0x88, 0x0A,
914 0x07, 0x80, 0x3D5, 0x3D1, 0x3CD, 0x42D, 0x431, 0x436},
915 {
916 8, 2447, 3263, 0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
917 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, 0x80, 0xFF, 0x88, 0x0A,
918 0x06, 0x80, 0x3D7, 0x3D3, 0x3CF, 0x42B, 0x42F, 0x434},
919 {
920 9, 2452, 3269, 0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
921 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, 0x80, 0xFF, 0x88, 0x09,
922 0x06, 0x80, 0x3D9, 0x3D5, 0x3D1, 0x429, 0x42D, 0x431},
923 {
924 10, 2457, 3276, 0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
925 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, 0x80, 0xFF, 0x88, 0x08,
926 0x05, 0x80, 0x3DB, 0x3D7, 0x3D3, 0x427, 0x42B, 0x42F},
927 {
928 11, 2462, 3283, 0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
929 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, 0x80, 0xFF, 0x88, 0x08,
930 0x04, 0x80, 0x3DD, 0x3D9, 0x3D5, 0x424, 0x429, 0x42D},
931 {
932 12, 2467, 3289, 0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
933 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, 0x80, 0xFF, 0x88, 0x08,
934 0x03, 0x80, 0x3DF, 0x3DB, 0x3D7, 0x422, 0x427, 0x42B},
935 {
936 13, 2472, 3296, 0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
937 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, 0x80, 0xFF, 0x88, 0x07,
938 0x03, 0x80, 0x3E1, 0x3DD, 0x3D9, 0x420, 0x424, 0x429},
939 {
940 14, 2484, 3312, 0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
941 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, 0x80, 0xFF, 0x88, 0x07,
942 0x01, 0x80, 0x3E6, 0x3E2, 0x3DE, 0x41B, 0x41F, 0x424}
943};
944
945static const struct chan_info_nphy_radio205x chan_info_nphyrev3_2056[] = {
946 {
947 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
948 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
949 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
950 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
951 {
952 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
953 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
954 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
955 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
956 {
957 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
958 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
959 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
960 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
961 {
962 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
963 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
964 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
965 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
966 {
967 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
968 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
969 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
970 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
971 {
972 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
973 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
974 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
975 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
976 {
977 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
978 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
979 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
980 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
981 {
982 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
983 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
984 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
985 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
986 {
987 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
988 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
989 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
990 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
991 {
992 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
993 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
994 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
995 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
996 {
997 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
998 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
999 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1000 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
1001 {
1002 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
1003 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1004 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1005 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
1006 {
1007 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
1008 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1009 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1010 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
1011 {
1012 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
1013 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1014 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1015 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
1016 {
1017 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
1018 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1019 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1020 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
1021 {
1022 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
1023 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1024 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1025 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
1026 {
1027 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
1028 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1029 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1030 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
1031 {
1032 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
1033 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1034 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1035 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
1036 {
1037 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
1038 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1039 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1040 0x00, 0xff, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
1041 {
1042 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
1043 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1044 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1045 0x00, 0xfc, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
1046 {
1047 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
1048 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1049 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1050 0x00, 0xfc, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
1051 {
1052 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
1053 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1054 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1055 0x00, 0xfc, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
1056 {
1057 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
1058 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1059 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1060 0x00, 0xfc, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
1061 {
1062 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
1063 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1064 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1065 0x00, 0xfc, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
1066 {
1067 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
1068 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1069 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1070 0x00, 0xfc, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
1071 {
1072 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
1073 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
1074 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1075 0x00, 0xfc, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
1076 {
1077 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
1078 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
1079 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1080 0x00, 0xfc, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
1081 {
1082 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
1083 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x06, 0x00, 0x7f,
1084 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1085 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
1086 {
1087 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
1088 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
1089 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1090 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
1091 {
1092 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1093 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
1094 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1095 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
1096 {
1097 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1098 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
1099 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1100 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
1101 {
1102 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1103 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
1104 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1105 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
1106 {
1107 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1108 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
1109 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1110 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
1111 {
1112 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1113 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
1114 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1115 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
1116 {
1117 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1118 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
1119 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1120 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
1121 {
1122 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
1123 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
1124 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1125 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
1126 {
1127 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
1128 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
1129 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1130 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
1131 {
1132 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
1133 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
1134 0x00, 0x09, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1135 0x00, 0xfc, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
1136 {
1137 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
1138 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
1139 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1140 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
1141 {
1142 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
1143 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
1144 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1145 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
1146 {
1147 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
1148 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
1149 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1150 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
1151 {
1152 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
1153 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
1154 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1155 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
1156 {
1157 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
1158 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
1159 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1160 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
1161 {
1162 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
1163 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
1164 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1165 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
1166 {
1167 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
1168 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
1169 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1170 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
1171 {
1172 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1173 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
1174 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1175 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
1176 {
1177 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1178 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x05, 0x00, 0x7f,
1179 0x00, 0x09, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1180 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
1181 {
1182 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1183 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
1184 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1185 0x00, 0xfa, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
1186 {
1187 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1188 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
1189 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1190 0x00, 0xfa, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
1191 {
1192 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1193 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
1194 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1195 0x00, 0xfa, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
1196 {
1197 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1198 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
1199 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1200 0x00, 0xfa, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
1201 {
1202 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
1203 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x04, 0x00, 0x7f,
1204 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1205 0x00, 0xfa, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
1206 {
1207 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
1208 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x04, 0x00, 0x7f,
1209 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1210 0x00, 0xfa, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
1211 {
1212 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
1213 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
1214 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1215 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
1216 {
1217 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
1218 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
1219 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1220 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
1221 {
1222 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
1223 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x04, 0x00, 0x7f,
1224 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1225 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
1226 {
1227 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
1228 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x04, 0x00, 0x7f,
1229 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1230 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
1231 {
1232 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
1233 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x03, 0x00, 0x7f,
1234 0x00, 0x07, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1235 0x00, 0xf8, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
1236 {
1237 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
1238 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
1239 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1240 0x00, 0xf8, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
1241 {
1242 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
1243 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
1244 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1245 0x00, 0xf8, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
1246 {
1247 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
1248 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
1249 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1250 0x00, 0xf8, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
1251 {
1252 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1253 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
1254 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1255 0x00, 0xf8, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
1256 {
1257 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1258 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
1259 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1260 0x00, 0xf8, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
1261 {
1262 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1263 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x03, 0x00, 0x7f,
1264 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1265 0x00, 0xf8, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
1266 {
1267 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1268 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x03, 0x00, 0x7f,
1269 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1270 0x00, 0xf8, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
1271 {
1272 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1273 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
1274 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1275 0x00, 0xf8, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
1276 {
1277 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1278 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
1279 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1280 0x00, 0xf8, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
1281 {
1282 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
1283 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x03, 0x00, 0x7f,
1284 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1285 0x00, 0xf8, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
1286 {
1287 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
1288 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
1289 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1290 0x00, 0xf8, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
1291 {
1292 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
1293 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
1294 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1295 0x00, 0xf8, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
1296 {
1297 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
1298 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
1299 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1300 0x00, 0xf8, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
1301 {
1302 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
1303 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
1304 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1305 0x00, 0xf8, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
1306 {
1307 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
1308 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
1309 0x00, 0x07, 0x00, 0xf8, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1310 0x00, 0xf8, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
1311 {
1312 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
1313 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
1314 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1315 0x00, 0xf6, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
1316 {
1317 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
1318 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
1319 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1320 0x00, 0xf6, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
1321 {
1322 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
1323 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
1324 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1325 0x00, 0xf6, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
1326 {
1327 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
1328 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x03, 0x00, 0x7f,
1329 0x00, 0x07, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1330 0x00, 0xf6, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
1331 {
1332 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1333 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
1334 0x00, 0x06, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1335 0x00, 0xf6, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
1336 {
1337 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1338 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
1339 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1340 0x00, 0xf4, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
1341 {
1342 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1343 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
1344 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1345 0x00, 0xf4, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
1346 {
1347 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
1348 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
1349 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1350 0x00, 0xf4, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
1351 {
1352 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1353 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
1354 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1355 0x00, 0xf4, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
1356 {
1357 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
1358 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
1359 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1360 0x00, 0xf4, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
1361 {
1362 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1363 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
1364 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1365 0x00, 0xf4, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
1366 {
1367 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
1368 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
1369 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1370 0x00, 0xf4, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
1371 {
1372 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1373 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
1374 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1375 0x00, 0xf4, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
1376 {
1377 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
1378 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
1379 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1380 0x00, 0xf4, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
1381 {
1382 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
1383 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
1384 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1385 0x00, 0xf4, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
1386 {
1387 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
1388 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
1389 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1390 0x00, 0xf4, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
1391 {
1392 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
1393 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
1394 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1395 0x00, 0xf4, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
1396 {
1397 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
1398 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
1399 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1400 0x00, 0xf4, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
1401 {
1402 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
1403 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
1404 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1405 0x00, 0xf4, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
1406 {
1407 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
1408 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
1409 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1410 0x00, 0xf4, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
1411 {
1412 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
1413 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
1414 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1415 0x00, 0xf4, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
1416 {
1417 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
1418 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
1419 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1420 0x00, 0xf4, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
1421 {
1422 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
1423 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
1424 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1425 0x00, 0xf4, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
1426 {
1427 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
1428 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
1429 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1430 0x00, 0xf4, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
1431 {
1432 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
1433 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
1434 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1435 0x00, 0xf4, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
1436 {
1437 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
1438 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
1439 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1440 0x00, 0xf4, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
1441 {
1442 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
1443 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
1444 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1445 0x00, 0xf4, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
1446 {
1447 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
1448 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
1449 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1450 0x00, 0xf4, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
1451 {
1452 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
1453 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
1454 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1455 0x00, 0xf4, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
1456 {
1457 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
1458 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
1459 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1460 0x00, 0xf4, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
1461 {
1462 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
1463 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
1464 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1465 0x00, 0xf4, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
1466 {
1467 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1468 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
1469 0x00, 0x06, 0x00, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1470 0x00, 0xf2, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
1471 {
1472 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1473 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
1474 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1475 0x00, 0xf2, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
1476 {
1477 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1478 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
1479 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1480 0x00, 0xf2, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
1481 {
1482 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1483 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
1484 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1485 0x00, 0xf2, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
1486 {
1487 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1488 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
1489 0x00, 0x05, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
1490 0x00, 0xf2, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
1491 {
1492 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1493 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
1494 0x00, 0x05, 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
1495 0x00, 0xf2, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
1496 {
1497 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
1498 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
1499 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
1500 0x0f, 0x00, 0x0f, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
1501 {
1502 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
1503 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
1504 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
1505 0x0f, 0x00, 0x0f, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
1506 {
1507 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
1508 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
1509 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
1510 0x0f, 0x00, 0x0f, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
1511 {
1512 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
1513 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x05, 0x00,
1514 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0x00, 0x05, 0x00, 0x70, 0x00,
1515 0x0f, 0x00, 0x0f, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
1516 {
1517 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
1518 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x05, 0x00,
1519 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfb, 0x00, 0x05, 0x00, 0x70, 0x00,
1520 0x0f, 0x00, 0x0f, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
1521 {
1522 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
1523 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x05, 0x00,
1524 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x05, 0x00, 0x70, 0x00,
1525 0x0f, 0x00, 0x0f, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
1526 {
1527 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
1528 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x05, 0x00,
1529 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x05, 0x00, 0x70, 0x00,
1530 0x0f, 0x00, 0x0f, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
1531 {
1532 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
1533 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x05, 0x00,
1534 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf7, 0x00, 0x05, 0x00, 0x70, 0x00,
1535 0x0f, 0x00, 0x0f, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
1536 {
1537 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
1538 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x05, 0x00,
1539 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf6, 0x00, 0x05, 0x00, 0x70, 0x00,
1540 0x0f, 0x00, 0x0f, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
1541 {
1542 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
1543 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x05, 0x00,
1544 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf5, 0x00, 0x05, 0x00, 0x70, 0x00,
1545 0x0f, 0x00, 0x0d, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
1546 {
1547 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
1548 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x05, 0x00,
1549 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x70, 0x00,
1550 0x0f, 0x00, 0x0d, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
1551 {
1552 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
1553 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x05, 0x00,
1554 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf3, 0x00, 0x05, 0x00, 0x70, 0x00,
1555 0x0f, 0x00, 0x0d, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
1556 {
1557 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
1558 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x05, 0x00,
1559 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x70, 0x00,
1560 0x0f, 0x00, 0x0d, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
1561 {
1562 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
1563 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x05, 0x00,
1564 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x70, 0x00,
1565 0x0f, 0x00, 0x0d, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
1566};
1567
1568static const struct chan_info_nphy_radio205x chan_info_nphyrev4_2056_A1[] = {
1569 {
1570 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
1571 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1572 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1573 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
1574 {
1575 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
1576 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1577 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1578 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
1579 {
1580 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
1581 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1582 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1583 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
1584 {
1585 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
1586 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1587 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1588 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
1589 {
1590 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
1591 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1592 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1593 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
1594 {
1595 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
1596 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1597 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1598 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
1599 {
1600 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
1601 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1602 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1603 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
1604 {
1605 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
1606 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1607 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1608 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
1609 {
1610 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
1611 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1612 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1613 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
1614 {
1615 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
1616 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1617 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1618 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
1619 {
1620 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
1621 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1622 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1623 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
1624 {
1625 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
1626 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1627 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1628 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
1629 {
1630 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
1631 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1632 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1633 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
1634 {
1635 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
1636 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1637 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1638 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
1639 {
1640 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
1641 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1642 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1643 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
1644 {
1645 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
1646 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1647 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1648 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
1649 {
1650 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
1651 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1652 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1653 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
1654 {
1655 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
1656 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1657 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1658 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
1659 {
1660 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
1661 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
1662 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1663 0x00, 0xfe, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
1664 {
1665 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
1666 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
1667 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1668 0x00, 0xfe, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
1669 {
1670 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
1671 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
1672 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1673 0x00, 0xfe, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
1674 {
1675 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
1676 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
1677 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1678 0x00, 0xfe, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
1679 {
1680 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
1681 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
1682 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1683 0x00, 0xfe, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
1684 {
1685 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
1686 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
1687 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1688 0x00, 0xfe, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
1689 {
1690 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
1691 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
1692 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1693 0x00, 0xfe, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
1694 {
1695 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
1696 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
1697 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1698 0x00, 0xfe, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
1699 {
1700 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
1701 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
1702 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1703 0x00, 0xfe, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
1704 {
1705 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
1706 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0a, 0x00, 0x7f,
1707 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1708 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
1709 {
1710 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
1711 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
1712 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1713 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
1714 {
1715 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1716 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
1717 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1718 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
1719 {
1720 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1721 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
1722 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1723 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
1724 {
1725 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1726 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
1727 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1728 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
1729 {
1730 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1731 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
1732 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1733 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
1734 {
1735 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1736 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
1737 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1738 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
1739 {
1740 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1741 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
1742 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1743 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
1744 {
1745 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
1746 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
1747 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1748 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
1749 {
1750 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
1751 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
1752 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1753 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
1754 {
1755 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
1756 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
1757 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1758 0x00, 0xfa, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
1759 {
1760 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
1761 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
1762 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1763 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
1764 {
1765 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
1766 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
1767 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1768 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
1769 {
1770 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
1771 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
1772 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1773 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
1774 {
1775 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
1776 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
1777 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1778 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
1779 {
1780 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
1781 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
1782 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1783 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
1784 {
1785 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
1786 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
1787 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1788 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
1789 {
1790 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
1791 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
1792 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1793 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
1794 {
1795 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1796 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
1797 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1798 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
1799 {
1800 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1801 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x08, 0x00, 0x7f,
1802 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1803 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
1804 {
1805 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1806 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
1807 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1808 0x00, 0xf8, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
1809 {
1810 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1811 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
1812 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1813 0x00, 0xf8, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
1814 {
1815 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1816 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
1817 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1818 0x00, 0xf8, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
1819 {
1820 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1821 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
1822 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1823 0x00, 0xf8, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
1824 {
1825 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
1826 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x07, 0x00, 0x7f,
1827 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1828 0x00, 0xf8, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
1829 {
1830 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
1831 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x07, 0x00, 0x7f,
1832 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1833 0x00, 0xf8, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
1834 {
1835 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
1836 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
1837 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1838 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
1839 {
1840 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
1841 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
1842 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1843 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
1844 {
1845 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
1846 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x07, 0x00, 0x7f,
1847 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1848 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
1849 {
1850 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
1851 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x07, 0x00, 0x7f,
1852 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1853 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
1854 {
1855 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
1856 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x06, 0x00, 0x7f,
1857 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x5c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1858 0x00, 0xf6, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
1859 {
1860 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
1861 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
1862 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1863 0x00, 0xf6, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
1864 {
1865 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
1866 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
1867 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1868 0x00, 0xf6, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
1869 {
1870 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
1871 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
1872 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1873 0x00, 0xf6, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
1874 {
1875 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1876 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
1877 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1878 0x00, 0xf6, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
1879 {
1880 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1881 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
1882 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1883 0x00, 0xf6, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
1884 {
1885 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1886 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x06, 0x00, 0x7f,
1887 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1888 0x00, 0xf6, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
1889 {
1890 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1891 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x06, 0x00, 0x7f,
1892 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1893 0x00, 0xf6, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
1894 {
1895 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1896 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
1897 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1898 0x00, 0xf6, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
1899 {
1900 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1901 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
1902 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1903 0x00, 0xf6, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
1904 {
1905 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
1906 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x04, 0x00, 0x7f,
1907 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1908 0x00, 0xf4, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
1909 {
1910 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
1911 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
1912 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1913 0x00, 0xf4, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
1914 {
1915 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
1916 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
1917 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1918 0x00, 0xf4, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
1919 {
1920 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
1921 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
1922 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1923 0x00, 0xf4, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
1924 {
1925 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
1926 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
1927 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1928 0x00, 0xf4, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
1929 {
1930 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
1931 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
1932 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1933 0x00, 0xf4, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
1934 {
1935 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
1936 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
1937 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1938 0x00, 0xf4, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
1939 {
1940 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
1941 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
1942 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1943 0x00, 0xf4, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
1944 {
1945 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
1946 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
1947 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1948 0x00, 0xf4, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
1949 {
1950 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
1951 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x04, 0x00, 0x7f,
1952 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1953 0x00, 0xf4, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
1954 {
1955 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1956 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
1957 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1958 0x00, 0xf2, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
1959 {
1960 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1961 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
1962 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1963 0x00, 0xf2, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
1964 {
1965 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1966 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
1967 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1968 0x00, 0xf2, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
1969 {
1970 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
1971 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
1972 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1973 0x00, 0xf2, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
1974 {
1975 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1976 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
1977 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1978 0x00, 0xf2, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
1979 {
1980 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
1981 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
1982 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1983 0x00, 0xf2, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
1984 {
1985 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1986 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
1987 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1988 0x00, 0xf2, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
1989 {
1990 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
1991 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
1992 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1993 0x00, 0xf2, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
1994 {
1995 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1996 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
1997 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1998 0x00, 0xf2, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
1999 {
2000 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
2001 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
2002 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
2003 0x00, 0xf2, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
2004 {
2005 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
2006 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
2007 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
2008 0x00, 0xf2, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
2009 {
2010 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
2011 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
2012 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
2013 0x00, 0xf2, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
2014 {
2015 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
2016 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
2017 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
2018 0x00, 0xf2, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
2019 {
2020 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
2021 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
2022 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
2023 0x00, 0xf2, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
2024 {
2025 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
2026 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
2027 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
2028 0x00, 0xf2, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
2029 {
2030 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
2031 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
2032 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
2033 0x00, 0xf2, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
2034 {
2035 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
2036 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
2037 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
2038 0x00, 0xf2, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
2039 {
2040 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
2041 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
2042 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
2043 0x00, 0xf2, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
2044 {
2045 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
2046 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
2047 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2048 0x00, 0xf0, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
2049 {
2050 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
2051 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
2052 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2053 0x00, 0xf0, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
2054 {
2055 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
2056 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
2057 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2058 0x00, 0xf0, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
2059 {
2060 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
2061 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
2062 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2063 0x00, 0xf0, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
2064 {
2065 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
2066 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
2067 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2068 0x00, 0xf0, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
2069 {
2070 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
2071 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
2072 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2073 0x00, 0xf0, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
2074 {
2075 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
2076 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
2077 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2078 0x00, 0xf0, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
2079 {
2080 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
2081 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
2082 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2083 0x00, 0xf0, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
2084 {
2085 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
2086 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
2087 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2088 0x00, 0xf0, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
2089 {
2090 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
2091 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
2092 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2093 0x00, 0xf0, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
2094 {
2095 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
2096 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
2097 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2098 0x00, 0xf0, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
2099 {
2100 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
2101 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
2102 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2103 0x00, 0xf0, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
2104 {
2105 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
2106 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
2107 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2108 0x00, 0xf0, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
2109 {
2110 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
2111 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
2112 0x00, 0x07, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
2113 0x00, 0xf0, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
2114 {
2115 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
2116 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
2117 0x00, 0x07, 0x00, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
2118 0x00, 0xf0, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
2119 {
2120 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
2121 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
2122 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
2123 0x0f, 0x00, 0x0e, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
2124 {
2125 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
2126 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
2127 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
2128 0x0f, 0x00, 0x0e, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
2129 {
2130 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
2131 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
2132 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
2133 0x0f, 0x00, 0x0e, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
2134 {
2135 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
2136 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x04, 0x00,
2137 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfd, 0x00, 0x04, 0x00, 0x70, 0x00,
2138 0x0f, 0x00, 0x0e, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
2139 {
2140 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
2141 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x04, 0x00,
2142 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfb, 0x00, 0x04, 0x00, 0x70, 0x00,
2143 0x0f, 0x00, 0x0e, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
2144 {
2145 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
2146 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
2147 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x70, 0x00,
2148 0x0f, 0x00, 0x0e, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
2149 {
2150 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
2151 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x04, 0x00,
2152 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf8, 0x00, 0x04, 0x00, 0x70, 0x00,
2153 0x0f, 0x00, 0x0e, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
2154 {
2155 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
2156 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x04, 0x00,
2157 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf7, 0x00, 0x04, 0x00, 0x70, 0x00,
2158 0x0f, 0x00, 0x0e, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
2159 {
2160 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
2161 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00,
2162 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x70, 0x00,
2163 0x0f, 0x00, 0x0e, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
2164 {
2165 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
2166 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x04, 0x00,
2167 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf5, 0x00, 0x04, 0x00, 0x70, 0x00,
2168 0x0f, 0x00, 0x0e, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
2169 {
2170 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
2171 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x04, 0x00,
2172 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x70, 0x00,
2173 0x0f, 0x00, 0x0e, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
2174 {
2175 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
2176 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x04, 0x00,
2177 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf3, 0x00, 0x04, 0x00, 0x70, 0x00,
2178 0x0f, 0x00, 0x0e, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
2179 {
2180 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
2181 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x04, 0x00,
2182 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x70, 0x00,
2183 0x0f, 0x00, 0x0e, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
2184 {
2185 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
2186 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x04, 0x00,
2187 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x70, 0x00,
2188 0x0f, 0x00, 0x0e, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
2189};
2190
2191static const struct chan_info_nphy_radio205x chan_info_nphyrev5_2056v5[] = {
2192 {
2193 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
2194 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
2195 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
2196 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
2197 {
2198 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
2199 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
2200 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
2201 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
2202 {
2203 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
2204 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
2205 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
2206 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
2207 {
2208 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
2209 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
2210 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
2211 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
2212 {
2213 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
2214 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
2215 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
2216 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
2217 {
2218 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
2219 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
2220 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
2221 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
2222 {
2223 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
2224 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
2225 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
2226 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
2227 {
2228 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
2229 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
2230 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
2231 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
2232 {
2233 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
2234 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
2235 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
2236 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
2237 {
2238 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
2239 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
2240 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
2241 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
2242 {
2243 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
2244 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
2245 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
2246 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
2247 {
2248 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
2249 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
2250 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
2251 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
2252 {
2253 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
2254 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
2255 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
2256 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
2257 {
2258 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
2259 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
2260 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
2261 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
2262 {
2263 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
2264 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
2265 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
2266 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
2267 {
2268 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
2269 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
2270 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
2271 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
2272 {
2273 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
2274 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
2275 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
2276 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
2277 {
2278 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
2279 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
2280 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
2281 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
2282 {
2283 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
2284 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
2285 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
2286 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
2287 {
2288 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
2289 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
2290 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
2291 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
2292 {
2293 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
2294 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
2295 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
2296 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
2297 {
2298 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
2299 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
2300 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
2301 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
2302 {
2303 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
2304 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
2305 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
2306 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
2307 {
2308 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
2309 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
2310 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
2311 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
2312 {
2313 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
2314 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
2315 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
2316 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
2317 {
2318 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
2319 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
2320 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
2321 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
2322 {
2323 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
2324 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
2325 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
2326 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
2327 {
2328 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
2329 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
2330 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
2331 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
2332 {
2333 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
2334 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
2335 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
2336 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
2337 {
2338 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
2339 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
2340 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
2341 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
2342 {
2343 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
2344 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xea, 0x00, 0x06, 0x00, 0x70,
2345 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
2346 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
2347 {
2348 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
2349 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
2350 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
2351 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
2352 {
2353 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
2354 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
2355 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
2356 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
2357 {
2358 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
2359 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xd9, 0x00, 0x05, 0x00, 0x70,
2360 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
2361 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
2362 {
2363 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
2364 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xd8, 0x00, 0x04, 0x00, 0x70,
2365 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
2366 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
2367 {
2368 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
2369 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
2370 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
2371 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
2372 {
2373 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
2374 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
2375 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
2376 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
2377 {
2378 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
2379 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
2380 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
2381 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
2382 {
2383 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
2384 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
2385 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
2386 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
2387 {
2388 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
2389 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb8, 0x00, 0x04, 0x00, 0x70,
2390 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
2391 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
2392 {
2393 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
2394 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x04, 0x00, 0x70,
2395 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
2396 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
2397 {
2398 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
2399 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x03, 0x00, 0x70,
2400 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
2401 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
2402 {
2403 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
2404 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa7, 0x00, 0x03, 0x00, 0x70,
2405 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
2406 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
2407 {
2408 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
2409 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
2410 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
2411 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
2412 {
2413 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
2414 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
2415 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
2416 0x00, 0x5b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
2417 {
2418 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
2419 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x96, 0x00, 0x03, 0x00, 0x70,
2420 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
2421 0x00, 0x5a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
2422 {
2423 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
2424 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x95, 0x00, 0x03, 0x00, 0x70,
2425 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
2426 0x00, 0x5a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
2427 {
2428 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
2429 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
2430 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
2431 0x00, 0x5a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
2432 {
2433 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
2434 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
2435 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
2436 0x00, 0x5a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
2437 {
2438 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
2439 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
2440 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
2441 0x00, 0x5a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
2442 {
2443 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
2444 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x85, 0x00, 0x02, 0x00, 0x70,
2445 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
2446 0x00, 0x59, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
2447 {
2448 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
2449 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
2450 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
2451 0x00, 0x59, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
2452 {
2453 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
2454 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
2455 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
2456 0x00, 0x59, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
2457 {
2458 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
2459 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
2460 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
2461 0x00, 0x69, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
2462 {
2463 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
2464 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x74, 0x00, 0x01, 0x00, 0x70,
2465 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
2466 0x00, 0x69, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
2467 {
2468 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
2469 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
2470 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
2471 0x00, 0x68, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
2472 {
2473 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
2474 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
2475 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
2476 0x00, 0x68, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
2477 {
2478 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
2479 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
2480 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
2481 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
2482 {
2483 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
2484 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
2485 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
2486 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
2487 {
2488 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
2489 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
2490 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
2491 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
2492 {
2493 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
2494 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x63, 0x00, 0x01, 0x00, 0x70,
2495 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
2496 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
2497 {
2498 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
2499 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
2500 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
2501 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
2502 {
2503 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
2504 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
2505 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
2506 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
2507 {
2508 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
2509 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
2510 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
2511 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
2512 {
2513 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
2514 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
2515 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2516 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
2517 {
2518 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
2519 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
2520 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2521 0x00, 0x76, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
2522 {
2523 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
2524 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x51, 0x00, 0x00, 0x00, 0x70,
2525 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2526 0x00, 0x76, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
2527 {
2528 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
2529 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
2530 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2531 0x00, 0x76, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
2532 {
2533 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
2534 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
2535 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2536 0x00, 0x76, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
2537 {
2538 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
2539 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
2540 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2541 0x00, 0x76, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
2542 {
2543 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
2544 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
2545 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2546 0x00, 0x76, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
2547 {
2548 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
2549 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
2550 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2551 0x00, 0x75, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
2552 {
2553 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
2554 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
2555 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2556 0x00, 0x75, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
2557 {
2558 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
2559 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
2560 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2561 0x00, 0x75, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
2562 {
2563 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
2564 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
2565 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2566 0x00, 0x74, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
2567 {
2568 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
2569 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
2570 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2571 0x00, 0x74, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
2572 {
2573 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
2574 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
2575 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2576 0x00, 0x74, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
2577 {
2578 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
2579 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
2580 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2581 0x00, 0x74, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
2582 {
2583 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
2584 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
2585 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2586 0x00, 0x74, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
2587 {
2588 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
2589 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
2590 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2591 0x00, 0x74, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
2592 {
2593 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
2594 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
2595 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2596 0x00, 0x74, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
2597 {
2598 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
2599 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
2600 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2601 0x00, 0x84, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
2602 {
2603 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
2604 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
2605 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2606 0x00, 0x83, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
2607 {
2608 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
2609 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
2610 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2611 0x00, 0x83, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
2612 {
2613 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
2614 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
2615 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2616 0x00, 0x83, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
2617 {
2618 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
2619 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
2620 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2621 0x00, 0x83, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
2622 {
2623 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
2624 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
2625 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2626 0x00, 0x83, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
2627 {
2628 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
2629 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
2630 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2631 0x00, 0x83, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
2632 {
2633 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
2634 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
2635 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2636 0x00, 0x82, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
2637 {
2638 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
2639 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
2640 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2641 0x00, 0x82, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
2642 {
2643 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
2644 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
2645 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2646 0x00, 0x82, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
2647 {
2648 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
2649 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
2650 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2651 0x00, 0x82, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
2652 {
2653 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
2654 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
2655 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2656 0x00, 0x82, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
2657 {
2658 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
2659 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
2660 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2661 0x00, 0x82, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
2662 {
2663 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
2664 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
2665 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2666 0x00, 0x82, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
2667 {
2668 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
2669 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2670 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2671 0x00, 0x82, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
2672 {
2673 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
2674 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2675 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2676 0x00, 0x82, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
2677 {
2678 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
2679 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2680 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2681 0x00, 0x82, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
2682 {
2683 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
2684 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2685 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2686 0x00, 0x82, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
2687 {
2688 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
2689 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2690 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2691 0x00, 0x82, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
2692 {
2693 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
2694 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2695 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2696 0x00, 0x82, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
2697 {
2698 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
2699 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2700 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2701 0x00, 0x72, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
2702 {
2703 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
2704 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2705 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2706 0x00, 0x72, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
2707 {
2708 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
2709 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
2710 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2711 0x00, 0x72, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
2712 {
2713 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
2714 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
2715 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2716 0x00, 0x72, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
2717 {
2718 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
2719 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
2720 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2721 0x00, 0x71, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
2722 {
2723 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
2724 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
2725 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2726 0x00, 0x71, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
2727 {
2728 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
2729 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
2730 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2731 0x00, 0x71, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
2732 {
2733 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
2734 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
2735 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2736 0x00, 0x71, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
2737 {
2738 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
2739 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
2740 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2741 0x00, 0x71, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
2742 {
2743 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
2744 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
2745 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
2746 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
2747 {
2748 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
2749 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
2750 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
2751 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
2752 {
2753 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
2754 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00,
2755 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x70, 0x00,
2756 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
2757 {
2758 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
2759 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x03, 0x00,
2760 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x70, 0x00,
2761 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
2762 {
2763 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
2764 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00,
2765 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x70, 0x00,
2766 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
2767 {
2768 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
2769 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00,
2770 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x70, 0x00,
2771 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
2772 {
2773 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
2774 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00,
2775 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x03, 0x00, 0x70, 0x00,
2776 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
2777 {
2778 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
2779 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
2780 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x08, 0x00, 0x02, 0x00, 0x70, 0x00,
2781 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
2782 {
2783 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
2784 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00,
2785 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00, 0x70, 0x00,
2786 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
2787 {
2788 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
2789 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00,
2790 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x06, 0x00, 0x02, 0x00, 0x70, 0x00,
2791 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
2792 {
2793 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
2794 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00,
2795 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x05, 0x00, 0x02, 0x00, 0x70, 0x00,
2796 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
2797 {
2798 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
2799 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,
2800 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x70, 0x00,
2801 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
2802 {
2803 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
2804 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,
2805 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x03, 0x00, 0x02, 0x00, 0x70, 0x00,
2806 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
2807 {
2808 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
2809 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
2810 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
2811 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
2812};
2813
2814static const struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v6[] = {
2815 {
2816 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
2817 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2818 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2819 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
2820 {
2821 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
2822 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2823 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2824 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
2825 {
2826 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
2827 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2828 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2829 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
2830 {
2831 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
2832 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2833 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2834 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
2835 {
2836 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
2837 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2838 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2839 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
2840 {
2841 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
2842 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2843 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2844 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
2845 {
2846 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
2847 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2848 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2849 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
2850 {
2851 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
2852 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2853 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2854 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
2855 {
2856 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
2857 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2858 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2859 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
2860 {
2861 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
2862 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2863 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2864 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
2865 {
2866 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
2867 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2868 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2869 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
2870 {
2871 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
2872 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2873 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2874 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
2875 {
2876 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
2877 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2878 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2879 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
2880 {
2881 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
2882 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2883 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2884 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
2885 {
2886 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
2887 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2888 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2889 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
2890 {
2891 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
2892 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
2893 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2894 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
2895 {
2896 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
2897 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
2898 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2899 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
2900 {
2901 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
2902 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
2903 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2904 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
2905 {
2906 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
2907 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
2908 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
2909 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
2910 {
2911 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
2912 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
2913 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
2914 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
2915 {
2916 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
2917 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
2918 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
2919 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
2920 {
2921 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
2922 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
2923 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
2924 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
2925 {
2926 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
2927 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
2928 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
2929 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
2930 {
2931 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
2932 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
2933 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
2934 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
2935 {
2936 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
2937 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
2938 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
2939 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
2940 {
2941 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
2942 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
2943 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
2944 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
2945 {
2946 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
2947 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
2948 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
2949 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
2950 {
2951 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
2952 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
2953 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
2954 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
2955 {
2956 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
2957 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
2958 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
2959 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
2960 {
2961 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
2962 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
2963 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
2964 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
2965 {
2966 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
2967 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
2968 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
2969 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
2970 {
2971 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
2972 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
2973 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
2974 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
2975 {
2976 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
2977 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
2978 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
2979 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
2980 {
2981 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
2982 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
2983 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
2984 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
2985 {
2986 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
2987 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
2988 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
2989 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
2990 {
2991 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
2992 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
2993 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
2994 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
2995 {
2996 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
2997 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
2998 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
2999 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
3000 {
3001 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
3002 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
3003 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
3004 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
3005 {
3006 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
3007 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
3008 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
3009 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
3010 {
3011 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
3012 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
3013 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
3014 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
3015 {
3016 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
3017 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
3018 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
3019 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
3020 {
3021 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
3022 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
3023 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
3024 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
3025 {
3026 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
3027 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
3028 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
3029 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
3030 {
3031 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
3032 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
3033 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
3034 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
3035 {
3036 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
3037 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
3038 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
3039 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
3040 {
3041 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3042 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
3043 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
3044 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
3045 {
3046 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3047 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
3048 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
3049 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
3050 {
3051 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3052 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
3053 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
3054 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
3055 {
3056 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3057 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
3058 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
3059 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
3060 {
3061 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3062 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
3063 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
3064 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
3065 {
3066 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3067 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
3068 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
3069 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
3070 {
3071 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
3072 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
3073 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
3074 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
3075 {
3076 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
3077 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
3078 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
3079 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
3080 {
3081 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
3082 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
3083 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
3084 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
3085 {
3086 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
3087 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
3088 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
3089 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
3090 {
3091 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
3092 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
3093 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3094 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
3095 {
3096 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
3097 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
3098 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3099 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
3100 {
3101 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
3102 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
3103 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3104 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
3105 {
3106 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
3107 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
3108 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3109 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
3110 {
3111 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
3112 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
3113 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3114 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
3115 {
3116 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
3117 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
3118 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3119 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
3120 {
3121 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3122 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
3123 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3124 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
3125 {
3126 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3127 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
3128 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3129 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
3130 {
3131 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3132 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
3133 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3134 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
3135 {
3136 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3137 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
3138 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3139 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
3140 {
3141 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3142 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
3143 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
3144 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
3145 {
3146 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3147 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
3148 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
3149 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
3150 {
3151 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
3152 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
3153 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
3154 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
3155 {
3156 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
3157 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
3158 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
3159 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
3160 {
3161 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
3162 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
3163 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
3164 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
3165 {
3166 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
3167 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
3168 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
3169 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
3170 {
3171 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
3172 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
3173 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
3174 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
3175 {
3176 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
3177 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
3178 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
3179 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
3180 {
3181 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
3182 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
3183 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3184 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
3185 {
3186 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
3187 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
3188 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3189 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
3190 {
3191 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
3192 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
3193 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3194 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
3195 {
3196 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
3197 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
3198 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3199 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
3200 {
3201 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3202 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
3203 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3204 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
3205 {
3206 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3207 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
3208 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3209 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
3210 {
3211 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3212 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
3213 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3214 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
3215 {
3216 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
3217 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
3218 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3219 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
3220 {
3221 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3222 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
3223 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3224 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
3225 {
3226 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
3227 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
3228 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3229 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
3230 {
3231 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3232 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
3233 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3234 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
3235 {
3236 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
3237 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
3238 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3239 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
3240 {
3241 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3242 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
3243 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3244 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
3245 {
3246 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
3247 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
3248 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3249 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
3250 {
3251 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
3252 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
3253 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3254 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
3255 {
3256 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
3257 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
3258 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3259 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
3260 {
3261 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
3262 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
3263 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3264 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
3265 {
3266 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
3267 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
3268 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3269 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
3270 {
3271 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
3272 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
3273 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3274 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
3275 {
3276 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
3277 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
3278 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3279 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
3280 {
3281 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
3282 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
3283 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3284 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
3285 {
3286 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
3287 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3288 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3289 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
3290 {
3291 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
3292 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3293 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3294 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
3295 {
3296 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
3297 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3298 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3299 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
3300 {
3301 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
3302 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3303 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3304 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
3305 {
3306 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
3307 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3308 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3309 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
3310 {
3311 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
3312 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3313 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3314 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
3315 {
3316 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
3317 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3318 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3319 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
3320 {
3321 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
3322 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3323 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3324 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
3325 {
3326 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
3327 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3328 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3329 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
3330 {
3331 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
3332 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3333 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3334 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
3335 {
3336 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3337 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3338 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3339 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
3340 {
3341 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3342 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3343 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3344 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
3345 {
3346 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3347 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3348 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3349 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
3350 {
3351 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3352 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3353 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3354 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
3355 {
3356 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3357 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3358 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3359 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
3360 {
3361 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3362 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3363 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3364 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
3365 {
3366 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
3367 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
3368 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
3369 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
3370 {
3371 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
3372 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
3373 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
3374 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
3375 {
3376 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
3377 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
3378 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00,
3379 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
3380 {
3381 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
3382 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
3383 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00,
3384 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
3385 {
3386 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
3387 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
3388 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00,
3389 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
3390 {
3391 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
3392 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
3393 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00,
3394 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
3395 {
3396 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
3397 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
3398 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
3399 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
3400 {
3401 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
3402 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
3403 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
3404 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
3405 {
3406 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
3407 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
3408 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00,
3409 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
3410 {
3411 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
3412 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
3413 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00,
3414 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
3415 {
3416 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
3417 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
3418 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00,
3419 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
3420 {
3421 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
3422 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
3423 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
3424 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
3425 {
3426 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
3427 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
3428 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
3429 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
3430 {
3431 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
3432 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3433 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
3434 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
3435};
3436
3437static const struct chan_info_nphy_radio205x chan_info_nphyrev5n6_2056v7[] = {
3438 {
3439 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
3440 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
3441 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
3442 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
3443 {
3444 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
3445 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
3446 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
3447 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
3448 {
3449 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
3450 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
3451 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
3452 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
3453 {
3454 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
3455 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
3456 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
3457 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
3458 {
3459 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
3460 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
3461 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
3462 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
3463 {
3464 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
3465 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
3466 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
3467 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
3468 {
3469 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
3470 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
3471 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
3472 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
3473 {
3474 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
3475 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
3476 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
3477 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
3478 {
3479 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
3480 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
3481 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
3482 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
3483 {
3484 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
3485 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
3486 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
3487 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
3488 {
3489 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
3490 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
3491 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
3492 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
3493 {
3494 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
3495 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
3496 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
3497 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
3498 {
3499 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
3500 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
3501 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
3502 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
3503 {
3504 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
3505 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
3506 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
3507 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
3508 {
3509 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
3510 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
3511 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
3512 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
3513 {
3514 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
3515 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
3516 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
3517 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
3518 {
3519 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
3520 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
3521 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
3522 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
3523 {
3524 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
3525 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
3526 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
3527 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
3528 {
3529 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
3530 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
3531 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
3532 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
3533 {
3534 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
3535 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
3536 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
3537 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
3538 {
3539 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
3540 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
3541 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
3542 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
3543 {
3544 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
3545 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
3546 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
3547 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
3548 {
3549 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
3550 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
3551 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
3552 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
3553 {
3554 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
3555 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
3556 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
3557 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
3558 {
3559 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
3560 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
3561 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
3562 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
3563 {
3564 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
3565 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
3566 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
3567 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
3568 {
3569 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
3570 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
3571 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
3572 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
3573 {
3574 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
3575 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
3576 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
3577 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
3578 {
3579 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
3580 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
3581 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
3582 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
3583 {
3584 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3585 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xfa, 0x00, 0x06, 0x00, 0x70,
3586 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
3587 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
3588 {
3589 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3590 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xea, 0x00, 0x06, 0x00, 0x70,
3591 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
3592 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
3593 {
3594 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3595 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xe9, 0x00, 0x05, 0x00, 0x70,
3596 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
3597 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
3598 {
3599 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3600 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xe9, 0x00, 0x05, 0x00, 0x70,
3601 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
3602 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
3603 {
3604 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3605 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xd9, 0x00, 0x05, 0x00, 0x70,
3606 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
3607 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
3608 {
3609 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3610 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xd8, 0x00, 0x04, 0x00, 0x70,
3611 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
3612 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
3613 {
3614 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
3615 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
3616 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
3617 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
3618 {
3619 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
3620 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
3621 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
3622 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
3623 {
3624 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
3625 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
3626 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
3627 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
3628 {
3629 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
3630 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
3631 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
3632 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
3633 {
3634 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
3635 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb8, 0x00, 0x04, 0x00, 0x70,
3636 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
3637 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
3638 {
3639 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
3640 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xb7, 0x00, 0x04, 0x00, 0x70,
3641 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
3642 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
3643 {
3644 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
3645 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xb7, 0x00, 0x03, 0x00, 0x70,
3646 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
3647 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
3648 {
3649 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
3650 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa7, 0x00, 0x03, 0x00, 0x70,
3651 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
3652 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
3653 {
3654 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
3655 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
3656 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
3657 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
3658 {
3659 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
3660 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
3661 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
3662 0x00, 0x7b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
3663 {
3664 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3665 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x96, 0x00, 0x03, 0x00, 0x70,
3666 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
3667 0x00, 0x7a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
3668 {
3669 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3670 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
3671 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
3672 0x00, 0x7a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
3673 {
3674 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3675 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
3676 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
3677 0x00, 0x7a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
3678 {
3679 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3680 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x95, 0x00, 0x03, 0x00, 0x70,
3681 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
3682 0x00, 0x7a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
3683 {
3684 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3685 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x95, 0x00, 0x03, 0x00, 0x70,
3686 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
3687 0x00, 0x7a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
3688 {
3689 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3690 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x85, 0x00, 0x02, 0x00, 0x70,
3691 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
3692 0x00, 0x79, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
3693 {
3694 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
3695 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x70,
3696 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
3697 0x00, 0x79, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
3698 {
3699 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
3700 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
3701 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
3702 0x00, 0x79, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
3703 {
3704 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
3705 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
3706 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
3707 0x00, 0x79, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
3708 {
3709 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
3710 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x74, 0x00, 0x01, 0x00, 0x70,
3711 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
3712 0x00, 0x79, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
3713 {
3714 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
3715 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
3716 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
3717 0x00, 0x78, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
3718 {
3719 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
3720 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x01, 0x00, 0x70,
3721 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
3722 0x00, 0x78, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
3723 {
3724 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
3725 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
3726 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
3727 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
3728 {
3729 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
3730 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
3731 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
3732 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
3733 {
3734 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
3735 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x01, 0x00, 0x70,
3736 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
3737 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
3738 {
3739 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
3740 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x63, 0x00, 0x01, 0x00, 0x70,
3741 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
3742 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
3743 {
3744 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3745 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x62, 0x00, 0x00, 0x00, 0x70,
3746 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
3747 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
3748 {
3749 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3750 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
3751 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
3752 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
3753 {
3754 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3755 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
3756 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
3757 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
3758 {
3759 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3760 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x52, 0x00, 0x00, 0x00, 0x70,
3761 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3762 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
3763 {
3764 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3765 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x52, 0x00, 0x00, 0x00, 0x70,
3766 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3767 0x00, 0x86, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
3768 {
3769 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3770 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
3771 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3772 0x00, 0x86, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
3773 {
3774 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
3775 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
3776 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3777 0x00, 0x86, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
3778 {
3779 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
3780 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
3781 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3782 0x00, 0x86, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
3783 {
3784 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
3785 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
3786 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3787 0x00, 0x86, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
3788 {
3789 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
3790 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
3791 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3792 0x00, 0x86, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
3793 {
3794 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
3795 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x51, 0x00, 0x00, 0x00, 0x70,
3796 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3797 0x00, 0x85, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
3798 {
3799 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
3800 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
3801 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3802 0x00, 0x85, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
3803 {
3804 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
3805 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
3806 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3807 0x00, 0x85, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
3808 {
3809 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
3810 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
3811 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3812 0x00, 0x84, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
3813 {
3814 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
3815 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
3816 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3817 0x00, 0x84, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
3818 {
3819 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
3820 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
3821 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3822 0x00, 0x94, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
3823 {
3824 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3825 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
3826 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3827 0x00, 0x94, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
3828 {
3829 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3830 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
3831 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3832 0x00, 0x94, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
3833 {
3834 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3835 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
3836 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3837 0x00, 0x94, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
3838 {
3839 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
3840 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
3841 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3842 0x00, 0x94, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
3843 {
3844 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3845 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
3846 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3847 0x00, 0x94, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
3848 {
3849 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
3850 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
3851 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3852 0x00, 0x93, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
3853 {
3854 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3855 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
3856 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3857 0x00, 0x93, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
3858 {
3859 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
3860 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
3861 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3862 0x00, 0x93, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
3863 {
3864 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3865 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
3866 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3867 0x00, 0x93, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
3868 {
3869 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
3870 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x30, 0x00, 0x00, 0x00, 0x70,
3871 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3872 0x00, 0x93, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
3873 {
3874 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
3875 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
3876 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3877 0x00, 0x93, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
3878 {
3879 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
3880 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
3881 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3882 0x00, 0x92, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
3883 {
3884 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
3885 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
3886 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3887 0x00, 0x92, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
3888 {
3889 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
3890 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
3891 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3892 0x00, 0x92, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
3893 {
3894 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
3895 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x70,
3896 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3897 0x00, 0x92, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
3898 {
3899 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
3900 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3901 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3902 0x00, 0x92, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
3903 {
3904 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
3905 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3906 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3907 0x00, 0x92, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
3908 {
3909 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
3910 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3911 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3912 0x00, 0x92, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
3913 {
3914 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
3915 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3916 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3917 0x00, 0x92, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
3918 {
3919 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
3920 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3921 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3922 0x00, 0x92, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
3923 {
3924 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
3925 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3926 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3927 0x00, 0x92, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
3928 {
3929 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
3930 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3931 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3932 0x00, 0x92, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
3933 {
3934 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
3935 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3936 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3937 0x00, 0x92, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
3938 {
3939 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
3940 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3941 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3942 0x00, 0x92, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
3943 {
3944 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
3945 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3946 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3947 0x00, 0x92, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
3948 {
3949 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
3950 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3951 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3952 0x00, 0x92, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
3953 {
3954 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
3955 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
3956 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3957 0x00, 0x92, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
3958 {
3959 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3960 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
3961 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3962 0x00, 0x92, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
3963 {
3964 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3965 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
3966 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3967 0x00, 0x91, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
3968 {
3969 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3970 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
3971 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3972 0x00, 0x91, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
3973 {
3974 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3975 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
3976 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3977 0x00, 0x91, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
3978 {
3979 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3980 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
3981 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3982 0x00, 0x91, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
3983 {
3984 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3985 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
3986 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3987 0x00, 0x91, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
3988 {
3989 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
3990 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
3991 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
3992 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
3993 {
3994 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
3995 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
3996 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
3997 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
3998 {
3999 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
4000 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
4001 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
4002 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
4003 {
4004 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
4005 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
4006 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
4007 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
4008 {
4009 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
4010 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x03, 0x00,
4011 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
4012 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
4013 {
4014 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
4015 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x76, 0x00, 0x03, 0x00,
4016 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
4017 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
4018 {
4019 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
4020 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x66, 0x00, 0x03, 0x00,
4021 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x03, 0x00, 0x70, 0x00,
4022 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
4023 {
4024 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
4025 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x55, 0x00, 0x02, 0x00,
4026 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
4027 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
4028 {
4029 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
4030 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
4031 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
4032 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
4033 {
4034 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
4035 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
4036 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
4037 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
4038 {
4039 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
4040 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
4041 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
4042 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
4043 {
4044 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
4045 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x22, 0x00, 0x02, 0x00,
4046 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
4047 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
4048 {
4049 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
4050 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
4051 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
4052 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
4053 {
4054 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
4055 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
4056 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
4057 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
4058};
4059
4060static const struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v8[] = {
4061 {
4062 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
4063 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4064 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4065 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
4066 {
4067 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
4068 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4069 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4070 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
4071 {
4072 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
4073 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4074 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4075 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
4076 {
4077 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
4078 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4079 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4080 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
4081 {
4082 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
4083 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4084 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4085 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
4086 {
4087 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
4088 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4089 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4090 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
4091 {
4092 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
4093 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4094 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4095 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
4096 {
4097 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
4098 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4099 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4100 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
4101 {
4102 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
4103 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4104 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4105 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
4106 {
4107 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
4108 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4109 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4110 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
4111 {
4112 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
4113 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4114 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4115 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
4116 {
4117 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
4118 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4119 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4120 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
4121 {
4122 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
4123 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4124 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4125 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
4126 {
4127 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
4128 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4129 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4130 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
4131 {
4132 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
4133 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4134 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4135 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
4136 {
4137 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
4138 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
4139 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4140 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
4141 {
4142 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
4143 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
4144 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4145 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
4146 {
4147 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
4148 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
4149 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4150 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
4151 {
4152 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
4153 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
4154 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4155 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
4156 {
4157 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
4158 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
4159 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4160 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
4161 {
4162 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
4163 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
4164 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4165 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
4166 {
4167 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
4168 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
4169 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4170 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
4171 {
4172 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
4173 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
4174 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4175 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
4176 {
4177 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
4178 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
4179 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
4180 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
4181 {
4182 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
4183 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
4184 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
4185 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
4186 {
4187 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
4188 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
4189 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
4190 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
4191 {
4192 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
4193 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
4194 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
4195 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
4196 {
4197 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
4198 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
4199 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4200 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
4201 {
4202 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
4203 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
4204 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4205 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
4206 {
4207 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
4208 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
4209 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4210 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
4211 {
4212 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
4213 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
4214 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4215 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
4216 {
4217 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
4218 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
4219 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4220 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
4221 {
4222 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
4223 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
4224 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4225 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
4226 {
4227 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
4228 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
4229 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
4230 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
4231 {
4232 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
4233 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
4234 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
4235 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
4236 {
4237 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
4238 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4239 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4240 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
4241 {
4242 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
4243 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4244 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4245 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
4246 {
4247 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
4248 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4249 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4250 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
4251 {
4252 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
4253 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4254 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4255 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
4256 {
4257 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
4258 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
4259 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4260 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
4261 {
4262 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
4263 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
4264 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
4265 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
4266 {
4267 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
4268 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
4269 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
4270 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
4271 {
4272 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
4273 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
4274 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
4275 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
4276 {
4277 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
4278 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
4279 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4280 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
4281 {
4282 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
4283 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
4284 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4285 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
4286 {
4287 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
4288 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
4289 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4290 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
4291 {
4292 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
4293 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
4294 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4295 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
4296 {
4297 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
4298 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
4299 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4300 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
4301 {
4302 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
4303 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
4304 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
4305 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
4306 {
4307 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
4308 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
4309 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
4310 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
4311 {
4312 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
4313 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
4314 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
4315 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
4316 {
4317 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
4318 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
4319 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
4320 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
4321 {
4322 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
4323 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
4324 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
4325 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
4326 {
4327 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
4328 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
4329 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
4330 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
4331 {
4332 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
4333 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
4334 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
4335 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
4336 {
4337 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
4338 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
4339 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4340 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
4341 {
4342 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
4343 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
4344 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4345 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
4346 {
4347 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
4348 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
4349 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4350 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
4351 {
4352 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
4353 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
4354 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4355 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
4356 {
4357 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
4358 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
4359 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4360 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
4361 {
4362 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
4363 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
4364 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4365 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
4366 {
4367 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
4368 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
4369 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4370 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
4371 {
4372 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
4373 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
4374 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4375 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
4376 {
4377 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
4378 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
4379 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4380 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
4381 {
4382 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
4383 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
4384 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4385 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
4386 {
4387 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
4388 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
4389 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
4390 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
4391 {
4392 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
4393 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
4394 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
4395 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
4396 {
4397 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
4398 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
4399 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
4400 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
4401 {
4402 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
4403 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
4404 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
4405 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
4406 {
4407 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
4408 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
4409 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
4410 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
4411 {
4412 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
4413 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
4414 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
4415 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
4416 {
4417 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
4418 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
4419 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
4420 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
4421 {
4422 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
4423 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
4424 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
4425 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
4426 {
4427 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
4428 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
4429 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4430 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
4431 {
4432 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
4433 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
4434 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4435 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
4436 {
4437 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
4438 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
4439 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4440 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
4441 {
4442 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
4443 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
4444 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4445 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
4446 {
4447 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
4448 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
4449 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4450 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
4451 {
4452 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
4453 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
4454 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4455 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
4456 {
4457 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
4458 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
4459 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4460 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
4461 {
4462 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
4463 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
4464 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4465 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
4466 {
4467 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
4468 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
4469 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4470 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
4471 {
4472 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
4473 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
4474 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4475 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
4476 {
4477 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
4478 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
4479 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4480 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
4481 {
4482 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
4483 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
4484 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4485 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
4486 {
4487 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
4488 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
4489 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4490 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
4491 {
4492 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
4493 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
4494 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4495 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
4496 {
4497 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
4498 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
4499 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4500 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
4501 {
4502 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
4503 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
4504 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4505 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
4506 {
4507 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
4508 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
4509 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4510 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
4511 {
4512 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
4513 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
4514 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4515 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
4516 {
4517 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
4518 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
4519 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4520 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
4521 {
4522 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
4523 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
4524 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4525 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
4526 {
4527 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
4528 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
4529 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4530 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
4531 {
4532 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
4533 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4534 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4535 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
4536 {
4537 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
4538 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4539 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4540 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
4541 {
4542 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
4543 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4544 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4545 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
4546 {
4547 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
4548 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4549 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4550 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
4551 {
4552 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
4553 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4554 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4555 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
4556 {
4557 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
4558 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4559 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4560 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
4561 {
4562 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
4563 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4564 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4565 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
4566 {
4567 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
4568 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4569 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4570 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
4571 {
4572 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
4573 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4574 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4575 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
4576 {
4577 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
4578 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4579 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4580 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
4581 {
4582 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
4583 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4584 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4585 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
4586 {
4587 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
4588 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4589 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4590 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
4591 {
4592 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
4593 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4594 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4595 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
4596 {
4597 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
4598 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4599 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4600 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
4601 {
4602 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
4603 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4604 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4605 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
4606 {
4607 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
4608 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4609 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4610 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
4611 {
4612 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
4613 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
4614 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
4615 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
4616 {
4617 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
4618 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
4619 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
4620 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
4621 {
4622 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
4623 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
4624 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
4625 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
4626 {
4627 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
4628 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
4629 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
4630 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
4631 {
4632 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
4633 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
4634 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
4635 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
4636 {
4637 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
4638 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
4639 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
4640 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
4641 {
4642 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
4643 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
4644 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
4645 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
4646 {
4647 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
4648 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
4649 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
4650 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
4651 {
4652 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
4653 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
4654 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
4655 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
4656 {
4657 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
4658 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
4659 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
4660 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
4661 {
4662 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
4663 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
4664 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
4665 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
4666 {
4667 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
4668 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
4669 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
4670 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
4671 {
4672 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
4673 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
4674 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
4675 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
4676 {
4677 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
4678 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
4679 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
4680 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
4681};
4682
4683static const struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v11[] = {
4684 {
4685 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x02, 0x0c, 0x01,
4686 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4687 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4688 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
4689 {
4690 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x02, 0x0c, 0x01,
4691 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4692 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4693 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
4694 {
4695 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x02, 0x0c, 0x01,
4696 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4697 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4698 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
4699 {
4700 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x02, 0x0c, 0x01,
4701 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4702 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4703 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
4704 {
4705 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x02, 0x0c, 0x01,
4706 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4707 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4708 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
4709 {
4710 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x02, 0x0c, 0x01,
4711 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4712 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4713 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
4714 {
4715 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x02, 0x0c, 0x01,
4716 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4717 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4718 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
4719 {
4720 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x02, 0x0c, 0x01,
4721 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4722 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4723 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
4724 {
4725 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x02, 0x0c, 0x01,
4726 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4727 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4728 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
4729 {
4730 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x02, 0x0c, 0x01,
4731 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4732 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4733 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
4734 {
4735 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x02, 0x0c, 0x01,
4736 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4737 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4738 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
4739 {
4740 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x02, 0x0c, 0x01,
4741 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4742 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4743 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
4744 {
4745 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x02, 0x0c, 0x01,
4746 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4747 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4748 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
4749 {
4750 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x02, 0x0c, 0x01,
4751 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4752 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4753 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
4754 {
4755 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x02, 0x0c, 0x01,
4756 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4757 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4758 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
4759 {
4760 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x02, 0x0c, 0x01,
4761 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
4762 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4763 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
4764 {
4765 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x02, 0x0c, 0x01,
4766 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
4767 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4768 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
4769 {
4770 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x02, 0x0c, 0x01,
4771 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
4772 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4773 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
4774 {
4775 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x02, 0x0c, 0x01,
4776 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
4777 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4778 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
4779 {
4780 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x02, 0x0c, 0x01,
4781 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
4782 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4783 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
4784 {
4785 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x02, 0x0c, 0x01,
4786 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
4787 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4788 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
4789 {
4790 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x02, 0x0c, 0x01,
4791 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
4792 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4793 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
4794 {
4795 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x02, 0x0c, 0x01,
4796 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
4797 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4798 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
4799 {
4800 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x02, 0x0c, 0x01,
4801 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
4802 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
4803 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
4804 {
4805 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x02, 0x0c, 0x01,
4806 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
4807 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
4808 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
4809 {
4810 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x02, 0x0c, 0x01,
4811 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
4812 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
4813 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
4814 {
4815 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x02, 0x0c, 0x01,
4816 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
4817 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
4818 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
4819 {
4820 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x02, 0x0c, 0x01,
4821 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
4822 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4823 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
4824 {
4825 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x02, 0x0c, 0x01,
4826 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
4827 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4828 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
4829 {
4830 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x02, 0x0c, 0x01,
4831 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
4832 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4833 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
4834 {
4835 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x02, 0x0c, 0x01,
4836 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
4837 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4838 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
4839 {
4840 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x02, 0x0c, 0x01,
4841 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
4842 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4843 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
4844 {
4845 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x02, 0x0c, 0x01,
4846 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
4847 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4848 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
4849 {
4850 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x02, 0x0c, 0x01,
4851 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
4852 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
4853 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
4854 {
4855 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x02, 0x0c, 0x01,
4856 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
4857 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
4858 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
4859 {
4860 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x02, 0x0c, 0x01,
4861 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4862 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4863 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
4864 {
4865 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x02, 0x0c, 0x01,
4866 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4867 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4868 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
4869 {
4870 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x02, 0x0c, 0x01,
4871 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4872 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4873 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
4874 {
4875 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x02, 0x0c, 0x01,
4876 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4877 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4878 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
4879 {
4880 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x02, 0x0c, 0x01,
4881 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
4882 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4883 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
4884 {
4885 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x02, 0x0c, 0x01,
4886 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
4887 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
4888 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
4889 {
4890 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x02, 0x0c, 0x01,
4891 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
4892 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
4893 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
4894 {
4895 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x02, 0x0c, 0x01,
4896 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
4897 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
4898 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
4899 {
4900 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x02, 0x0c, 0x01,
4901 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
4902 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4903 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
4904 {
4905 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x02, 0x0c, 0x01,
4906 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
4907 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4908 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
4909 {
4910 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x02, 0x0c, 0x01,
4911 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
4912 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4913 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
4914 {
4915 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x02, 0x0c, 0x01,
4916 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
4917 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4918 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
4919 {
4920 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x02, 0x0c, 0x01,
4921 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
4922 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4923 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
4924 {
4925 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x02, 0x0c, 0x01,
4926 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
4927 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
4928 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
4929 {
4930 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x02, 0x0c, 0x01,
4931 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
4932 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
4933 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
4934 {
4935 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x02, 0x0c, 0x01,
4936 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
4937 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
4938 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
4939 {
4940 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x02, 0x0c, 0x01,
4941 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
4942 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
4943 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
4944 {
4945 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x02, 0x0c, 0x01,
4946 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
4947 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
4948 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
4949 {
4950 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x02, 0x0c, 0x01,
4951 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
4952 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
4953 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
4954 {
4955 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x02, 0x0c, 0x01,
4956 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
4957 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
4958 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
4959 {
4960 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x02, 0x0c, 0x01,
4961 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
4962 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4963 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
4964 {
4965 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x02, 0x0c, 0x01,
4966 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
4967 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4968 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
4969 {
4970 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x02, 0x0c, 0x01,
4971 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
4972 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4973 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
4974 {
4975 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x02, 0x0c, 0x01,
4976 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
4977 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4978 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
4979 {
4980 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x02, 0x0c, 0x01,
4981 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
4982 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4983 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
4984 {
4985 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x02, 0x0c, 0x01,
4986 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
4987 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4988 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
4989 {
4990 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x02, 0x0c, 0x01,
4991 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
4992 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4993 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
4994 {
4995 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x02, 0x0c, 0x01,
4996 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
4997 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4998 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
4999 {
5000 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x02, 0x0c, 0x01,
5001 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
5002 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
5003 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
5004 {
5005 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x02, 0x0c, 0x01,
5006 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
5007 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
5008 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
5009 {
5010 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x02, 0x0c, 0x01,
5011 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
5012 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
5013 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
5014 {
5015 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x02, 0x0c, 0x01,
5016 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
5017 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
5018 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
5019 {
5020 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x02, 0x0c, 0x01,
5021 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
5022 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
5023 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
5024 {
5025 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x02, 0x0c, 0x01,
5026 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
5027 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
5028 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
5029 {
5030 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x02, 0x0c, 0x01,
5031 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
5032 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
5033 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
5034 {
5035 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x02, 0x0c, 0x01,
5036 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
5037 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
5038 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
5039 {
5040 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x02, 0x0c, 0x01,
5041 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
5042 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
5043 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
5044 {
5045 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x02, 0x0c, 0x01,
5046 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
5047 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
5048 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
5049 {
5050 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x02, 0x0c, 0x01,
5051 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
5052 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5053 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
5054 {
5055 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x02, 0x0c, 0x01,
5056 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
5057 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5058 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
5059 {
5060 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x02, 0x0c, 0x01,
5061 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
5062 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5063 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
5064 {
5065 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x02, 0x0c, 0x01,
5066 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
5067 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5068 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
5069 {
5070 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x02, 0x0c, 0x01,
5071 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
5072 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5073 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
5074 {
5075 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x02, 0x0c, 0x01,
5076 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
5077 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5078 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
5079 {
5080 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x02, 0x0c, 0x01,
5081 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
5082 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5083 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
5084 {
5085 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x05, 0x05, 0x02, 0x15, 0x01,
5086 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
5087 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5088 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
5089 {
5090 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x02, 0x0c, 0x01,
5091 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
5092 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5093 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
5094 {
5095 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x05, 0x05, 0x02, 0x15, 0x01,
5096 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
5097 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5098 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
5099 {
5100 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x02, 0x0c, 0x01,
5101 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
5102 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5103 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
5104 {
5105 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x05, 0x05, 0x02, 0x15, 0x01,
5106 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
5107 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5108 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
5109 {
5110 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x02, 0x0c, 0x01,
5111 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
5112 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5113 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
5114 {
5115 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x05, 0x05, 0x02, 0x15, 0x01,
5116 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
5117 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5118 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
5119 {
5120 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x02, 0x0c, 0x01,
5121 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
5122 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5123 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
5124 {
5125 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x05, 0x05, 0x02, 0x15, 0x01,
5126 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
5127 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5128 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
5129 {
5130 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x02, 0x0c, 0x01,
5131 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
5132 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5133 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
5134 {
5135 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x05, 0x05, 0x02, 0x15, 0x01,
5136 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
5137 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5138 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
5139 {
5140 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x02, 0x0c, 0x01,
5141 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
5142 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5143 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
5144 {
5145 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x05, 0x05, 0x02, 0x15, 0x01,
5146 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
5147 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5148 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
5149 {
5150 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x02, 0x0c, 0x01,
5151 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
5152 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5153 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
5154 {
5155 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x05, 0x05, 0x02, 0x15, 0x01,
5156 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5157 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5158 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
5159 {
5160 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x02, 0x0c, 0x01,
5161 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5162 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5163 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
5164 {
5165 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x05, 0x05, 0x02, 0x15, 0x01,
5166 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5167 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5168 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
5169 {
5170 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x02, 0x0c, 0x01,
5171 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5172 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5173 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
5174 {
5175 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x05, 0x05, 0x02, 0x15, 0x01,
5176 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5177 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5178 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
5179 {
5180 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x02, 0x0c, 0x01,
5181 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5182 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5183 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
5184 {
5185 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x05, 0x05, 0x02, 0x15, 0x01,
5186 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5187 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5188 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
5189 {
5190 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x02, 0x0c, 0x01,
5191 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5192 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5193 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
5194 {
5195 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x02, 0x0c, 0x01,
5196 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5197 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5198 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
5199 {
5200 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x02, 0x0c, 0x01,
5201 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5202 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5203 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
5204 {
5205 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x02, 0x0c, 0x01,
5206 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5207 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5208 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
5209 {
5210 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x02, 0x0c, 0x01,
5211 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5212 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5213 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
5214 {
5215 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x02, 0x0c, 0x01,
5216 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5217 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5218 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
5219 {
5220 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x02, 0x0c, 0x01,
5221 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5222 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5223 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
5224 {
5225 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x02, 0x0c, 0x01,
5226 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5227 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5228 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
5229 {
5230 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x02, 0x0c, 0x01,
5231 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5232 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5233 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
5234 {
5235 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x06, 0x06, 0x04, 0x2b, 0x01,
5236 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
5237 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
5238 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
5239 {
5240 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x06, 0x06, 0x04, 0x2b, 0x01,
5241 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
5242 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
5243 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
5244 {
5245 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x06, 0x06, 0x04, 0x2b, 0x01,
5246 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
5247 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
5248 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
5249 {
5250 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x06, 0x06, 0x04, 0x2b, 0x01,
5251 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
5252 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
5253 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
5254 {
5255 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x06, 0x06, 0x04, 0x2b, 0x01,
5256 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
5257 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
5258 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
5259 {
5260 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x06, 0x06, 0x04, 0x2b, 0x01,
5261 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
5262 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
5263 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
5264 {
5265 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x06, 0x06, 0x04, 0x2b, 0x01,
5266 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
5267 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
5268 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
5269 {
5270 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x06, 0x06, 0x04, 0x2b, 0x01,
5271 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
5272 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
5273 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
5274 {
5275 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x06, 0x06, 0x04, 0x2b, 0x01,
5276 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
5277 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
5278 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
5279 {
5280 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x06, 0x06, 0x04, 0x2b, 0x01,
5281 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
5282 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
5283 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
5284 {
5285 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x06, 0x06, 0x04, 0x2b, 0x01,
5286 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
5287 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
5288 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
5289 {
5290 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x06, 0x06, 0x04, 0x2b, 0x01,
5291 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
5292 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
5293 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
5294 {
5295 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x06, 0x06, 0x04, 0x2b, 0x01,
5296 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
5297 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
5298 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
5299 {
5300 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x06, 0x06, 0x04, 0x2b, 0x01,
5301 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
5302 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
5303 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
5304};
5305
5306static const struct chan_info_nphy_radio2057 chan_info_nphyrev7_2057_rev4[] = {
5307 {
5308 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
5309 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5310 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b4, 0x07b0, 0x07ac, 0x0214,
5311 0x0215,
5312 0x0216,
5313 },
5314 {
5315 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
5316 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5317 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b8, 0x07b4, 0x07b0, 0x0213,
5318 0x0214,
5319 0x0215,
5320 },
5321 {
5322 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
5323 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5324 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07bc, 0x07b8, 0x07b4, 0x0212,
5325 0x0213,
5326 0x0214,
5327 },
5328 {
5329 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
5330 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5331 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c0, 0x07bc, 0x07b8, 0x0211,
5332 0x0212,
5333 0x0213,
5334 },
5335 {
5336 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
5337 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5338 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c4, 0x07c0, 0x07bc, 0x020f,
5339 0x0211,
5340 0x0212,
5341 },
5342 {
5343 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
5344 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5345 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c8, 0x07c4, 0x07c0, 0x020e,
5346 0x020f,
5347 0x0211,
5348 },
5349 {
5350 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
5351 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5352 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07cc, 0x07c8, 0x07c4, 0x020d,
5353 0x020e,
5354 0x020f,
5355 },
5356 {
5357 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
5358 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5359 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d0, 0x07cc, 0x07c8, 0x020c,
5360 0x020d,
5361 0x020e,
5362 },
5363 {
5364 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
5365 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5366 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d4, 0x07d0, 0x07cc, 0x020b,
5367 0x020c,
5368 0x020d,
5369 },
5370 {
5371 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
5372 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5373 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d8, 0x07d4, 0x07d0, 0x020a,
5374 0x020b,
5375 0x020c,
5376 },
5377 {
5378 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
5379 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5380 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07dc, 0x07d8, 0x07d4, 0x0209,
5381 0x020a,
5382 0x020b,
5383 },
5384 {
5385 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
5386 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5387 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e0, 0x07dc, 0x07d8, 0x0208,
5388 0x0209,
5389 0x020a,
5390 },
5391 {
5392 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
5393 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5394 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e4, 0x07e0, 0x07dc, 0x0207,
5395 0x0208,
5396 0x0209,
5397 },
5398 {
5399 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
5400 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5401 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e8, 0x07e4, 0x07e0, 0x0206,
5402 0x0207,
5403 0x0208,
5404 },
5405 {
5406 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
5407 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x00,
5408 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x07ec, 0x07e8, 0x07e4, 0x0205,
5409 0x0206,
5410 0x0207,
5411 },
5412 {
5413 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
5414 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
5415 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f0, 0x07ec, 0x07e8, 0x0204,
5416 0x0205,
5417 0x0206,
5418 },
5419 {
5420 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
5421 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
5422 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f4, 0x07f0, 0x07ec, 0x0203,
5423 0x0204,
5424 0x0205,
5425 },
5426 {
5427 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
5428 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
5429 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07f8, 0x07f4, 0x07f0, 0x0202,
5430 0x0203,
5431 0x0204,
5432 },
5433 {
5434 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
5435 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
5436 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07fc, 0x07f8, 0x07f4, 0x0201,
5437 0x0202,
5438 0x0203,
5439 },
5440 {
5441 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
5442 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
5443 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0800, 0x07fc, 0x07f8, 0x0200,
5444 0x0201,
5445 0x0202,
5446 },
5447 {
5448 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
5449 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
5450 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0804, 0x0800, 0x07fc, 0x01ff,
5451 0x0200,
5452 0x0201,
5453 },
5454 {
5455 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
5456 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
5457 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0808, 0x0804, 0x0800, 0x01fe,
5458 0x01ff,
5459 0x0200,
5460 },
5461 {
5462 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
5463 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
5464 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x080c, 0x0808, 0x0804, 0x01fd,
5465 0x01fe,
5466 0x01ff,
5467 },
5468 {
5469 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
5470 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
5471 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0814, 0x0810, 0x080c, 0x01fb,
5472 0x01fc,
5473 0x01fd,
5474 },
5475 {
5476 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
5477 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
5478 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0818, 0x0814, 0x0810, 0x01fa,
5479 0x01fb,
5480 0x01fc,
5481 },
5482 {
5483 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
5484 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5485 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x081c, 0x0818, 0x0814, 0x01f9,
5486 0x01fa,
5487 0x01fb,
5488 },
5489 {
5490 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
5491 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5492 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0820, 0x081c, 0x0818, 0x01f8,
5493 0x01f9,
5494 0x01fa,
5495 },
5496 {
5497 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
5498 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5499 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0824, 0x0820, 0x081c, 0x01f7,
5500 0x01f8,
5501 0x01f9,
5502 },
5503 {
5504 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
5505 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5506 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0828, 0x0824, 0x0820, 0x01f6,
5507 0x01f7,
5508 0x01f8,
5509 },
5510 {
5511 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
5512 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5513 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x082c, 0x0828, 0x0824, 0x01f5,
5514 0x01f6,
5515 0x01f7,
5516 },
5517 {
5518 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
5519 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5520 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0830, 0x082c, 0x0828, 0x01f4,
5521 0x01f5,
5522 0x01f6,
5523 },
5524 {
5525 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
5526 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5527 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0834, 0x0830, 0x082c, 0x01f3,
5528 0x01f4,
5529 0x01f5,
5530 },
5531 {
5532 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
5533 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5534 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0838, 0x0834, 0x0830, 0x01f2,
5535 0x01f3,
5536 0x01f4,
5537 },
5538 {
5539 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
5540 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
5541 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x083c, 0x0838, 0x0834, 0x01f1,
5542 0x01f2,
5543 0x01f3,
5544 },
5545 {
5546 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
5547 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
5548 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x0840, 0x083c, 0x0838, 0x01f0,
5549 0x01f1,
5550 0x01f2,
5551 },
5552 {
5553 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
5554 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
5555 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0844, 0x0840, 0x083c, 0x01f0,
5556 0x01f0,
5557 0x01f1,
5558 },
5559 {
5560 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
5561 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
5562 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0848, 0x0844, 0x0840, 0x01ef,
5563 0x01f0,
5564 0x01f0,
5565 },
5566 {
5567 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
5568 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
5569 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x084c, 0x0848, 0x0844, 0x01ee,
5570 0x01ef,
5571 0x01f0,
5572 },
5573 {
5574 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
5575 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
5576 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0850, 0x084c, 0x0848, 0x01ed,
5577 0x01ee,
5578 0x01ef,
5579 },
5580 {
5581 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
5582 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
5583 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0854, 0x0850, 0x084c, 0x01ec,
5584 0x01ed,
5585 0x01ee,
5586 },
5587 {
5588 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
5589 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
5590 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0858, 0x0854, 0x0850, 0x01eb,
5591 0x01ec,
5592 0x01ed,
5593 },
5594 {
5595 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
5596 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x00,
5597 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x085c, 0x0858, 0x0854, 0x01ea,
5598 0x01eb,
5599 0x01ec,
5600 },
5601 {
5602 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
5603 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
5604 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0860, 0x085c, 0x0858, 0x01e9,
5605 0x01ea,
5606 0x01eb,
5607 },
5608 {
5609 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
5610 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
5611 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0864, 0x0860, 0x085c, 0x01e8,
5612 0x01e9,
5613 0x01ea,
5614 },
5615 {
5616 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
5617 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
5618 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0868, 0x0864, 0x0860, 0x01e7,
5619 0x01e8,
5620 0x01e9,
5621 },
5622 {
5623 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
5624 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
5625 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x086c, 0x0868, 0x0864, 0x01e6,
5626 0x01e7,
5627 0x01e8,
5628 },
5629 {
5630 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
5631 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x00,
5632 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x0870, 0x086c, 0x0868, 0x01e5,
5633 0x01e6,
5634 0x01e7,
5635 },
5636 {
5637 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
5638 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
5639 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0874, 0x0870, 0x086c, 0x01e5,
5640 0x01e5,
5641 0x01e6,
5642 },
5643 {
5644 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
5645 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
5646 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0878, 0x0874, 0x0870, 0x01e4,
5647 0x01e5,
5648 0x01e5,
5649 },
5650 {
5651 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
5652 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x00,
5653 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x087c, 0x0878, 0x0874, 0x01e3,
5654 0x01e4,
5655 0x01e5,
5656 },
5657 {
5658 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
5659 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
5660 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0880, 0x087c, 0x0878, 0x01e2,
5661 0x01e3,
5662 0x01e4,
5663 },
5664 {
5665 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
5666 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
5667 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0884, 0x0880, 0x087c, 0x01e1,
5668 0x01e2,
5669 0x01e3,
5670 },
5671 {
5672 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
5673 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
5674 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0888, 0x0884, 0x0880, 0x01e0,
5675 0x01e1,
5676 0x01e2,
5677 },
5678 {
5679 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
5680 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x00,
5681 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x088c, 0x0888, 0x0884, 0x01df,
5682 0x01e0,
5683 0x01e1,
5684 },
5685 {
5686 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
5687 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x00,
5688 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x0890, 0x088c, 0x0888, 0x01de,
5689 0x01df,
5690 0x01e0,
5691 },
5692 {
5693 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
5694 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
5695 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0894, 0x0890, 0x088c, 0x01dd,
5696 0x01de,
5697 0x01df,
5698 },
5699 {
5700 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
5701 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
5702 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0898, 0x0894, 0x0890, 0x01dd,
5703 0x01dd,
5704 0x01de,
5705 },
5706 {
5707 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
5708 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
5709 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x089c, 0x0898, 0x0894, 0x01dc,
5710 0x01dd,
5711 0x01dd,
5712 },
5713 {
5714 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
5715 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
5716 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x08a0, 0x089c, 0x0898, 0x01db,
5717 0x01dc,
5718 0x01dd,
5719 },
5720 {
5721 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
5722 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
5723 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a4, 0x08a0, 0x089c, 0x01da,
5724 0x01db,
5725 0x01dc,
5726 },
5727 {
5728 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
5729 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
5730 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
5731 0x01da,
5732 0x01db,
5733 },
5734 {
5735 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
5736 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
5737 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
5738 0x01d9,
5739 0x01da,
5740 },
5741 {
5742 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
5743 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
5744 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
5745 0x01d8,
5746 0x01d9,
5747 },
5748 {
5749 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
5750 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
5751 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
5752 0x01d7,
5753 0x01d8,
5754 },
5755 {
5756 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
5757 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
5758 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
5759 0x01d7,
5760 0x01d7,
5761 },
5762 {
5763 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
5764 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x00,
5765 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
5766 0x01d6,
5767 0x01d7,
5768 },
5769 {
5770 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
5771 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x00,
5772 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
5773 0x01d5,
5774 0x01d6,
5775 },
5776 {
5777 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
5778 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x00,
5779 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
5780 0x01d4,
5781 0x01d5,
5782 },
5783 {
5784 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
5785 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
5786 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
5787 0x01d3,
5788 0x01d4,
5789 },
5790 {
5791 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
5792 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
5793 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
5794 0x01d2,
5795 0x01d3,
5796 },
5797 {
5798 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
5799 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
5800 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
5801 0x01d2,
5802 0x01d2,
5803 },
5804 {
5805 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
5806 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
5807 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
5808 0x01d1,
5809 0x01d2,
5810 },
5811 {
5812 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
5813 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
5814 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
5815 0x01d0,
5816 0x01d1,
5817 },
5818 {
5819 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
5820 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
5821 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
5822 0x01cf,
5823 0x01d0,
5824 },
5825 {
5826 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
5827 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x00,
5828 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
5829 0x01ce,
5830 0x01cf,
5831 },
5832 {
5833 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
5834 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
5835 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
5836 0x01ce,
5837 0x01ce,
5838 },
5839 {
5840 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
5841 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
5842 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
5843 0x01cd,
5844 0x01ce,
5845 },
5846 {
5847 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
5848 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
5849 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
5850 0x01cc,
5851 0x01cd,
5852 },
5853 {
5854 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
5855 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
5856 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
5857 0x01cb,
5858 0x01cc,
5859 },
5860 {
5861 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
5862 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
5863 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
5864 0x01ca,
5865 0x01cb,
5866 },
5867 {
5868 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
5869 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x00,
5870 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
5871 0x01ca,
5872 0x01cb,
5873 },
5874 {
5875 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
5876 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
5877 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
5878 0x01c9,
5879 0x01ca,
5880 },
5881 {
5882 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
5883 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
5884 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
5885 0x01c9,
5886 0x01ca,
5887 },
5888 {
5889 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
5890 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
5891 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
5892 0x01c9,
5893 0x01c9,
5894 },
5895 {
5896 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
5897 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
5898 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
5899 0x01c8,
5900 0x01c9,
5901 },
5902 {
5903 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
5904 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
5905 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
5906 0x01c8,
5907 0x01c9,
5908 },
5909 {
5910 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
5911 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
5912 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
5913 0x01c8,
5914 0x01c8,
5915 },
5916 {
5917 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
5918 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
5919 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
5920 0x01c7,
5921 0x01c8,
5922 },
5923 {
5924 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
5925 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
5926 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
5927 0x01c7,
5928 0x01c8,
5929 },
5930 {
5931 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
5932 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
5933 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
5934 0x01c6,
5935 0x01c7,
5936 },
5937 {
5938 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
5939 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
5940 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
5941 0x01c6,
5942 0x01c7,
5943 },
5944 {
5945 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
5946 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x00,
5947 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
5948 0x01c6,
5949 0x01c6,
5950 },
5951 {
5952 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
5953 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5954 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
5955 0x01c5,
5956 0x01c6,
5957 },
5958 {
5959 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
5960 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5961 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
5962 0x01c5,
5963 0x01c6,
5964 },
5965 {
5966 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
5967 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5968 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
5969 0x01c4,
5970 0x01c5,
5971 },
5972 {
5973 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
5974 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5975 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
5976 0x01c4,
5977 0x01c5,
5978 },
5979 {
5980 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
5981 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5982 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
5983 0x01c4,
5984 0x01c4,
5985 },
5986 {
5987 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
5988 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5989 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
5990 0x01c3,
5991 0x01c4,
5992 },
5993 {
5994 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
5995 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5996 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
5997 0x01c3,
5998 0x01c4,
5999 },
6000 {
6001 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
6002 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6003 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
6004 0x01c2,
6005 0x01c3,
6006 },
6007 {
6008 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
6009 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6010 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
6011 0x01c2,
6012 0x01c3,
6013 },
6014 {
6015 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
6016 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6017 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
6018 0x01c2,
6019 0x01c2,
6020 },
6021 {
6022 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
6023 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6024 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
6025 0x01c1,
6026 0x01c2,
6027 },
6028 {
6029 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
6030 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6031 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
6032 0x01c0,
6033 0x01c1,
6034 },
6035 {
6036 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
6037 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6038 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
6039 0x01bf,
6040 0x01c0,
6041 },
6042 {
6043 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
6044 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6045 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
6046 0x01bf,
6047 0x01bf,
6048 },
6049 {
6050 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
6051 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6052 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
6053 0x01be,
6054 0x01bf,
6055 },
6056 {
6057 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
6058 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6059 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
6060 0x01bd,
6061 0x01be,
6062 },
6063 {
6064 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
6065 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6066 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
6067 0x01bc,
6068 0x01bd,
6069 },
6070 {
6071 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
6072 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
6073 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
6074 0x043f,
6075 0x0443,
6076 },
6077 {
6078 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
6079 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
6080 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
6081 0x043d,
6082 0x0441,
6083 },
6084 {
6085 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
6086 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
6087 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
6088 0x043a,
6089 0x043f,
6090 },
6091 {
6092 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
6093 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
6094 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
6095 0x0438,
6096 0x043d,
6097 },
6098 {
6099 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
6100 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
6101 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
6102 0x0436,
6103 0x043a,
6104 },
6105 {
6106 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
6107 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
6108 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
6109 0x0434,
6110 0x0438,
6111 },
6112 {
6113 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
6114 0x07, 0x00, 0x07, 0x00, 0x51, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
6115 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
6116 0x0431,
6117 0x0436,
6118 },
6119 {
6120 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
6121 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
6122 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
6123 0x042f,
6124 0x0434,
6125 },
6126 {
6127 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
6128 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
6129 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
6130 0x042d,
6131 0x0431,
6132 },
6133 {
6134 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
6135 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
6136 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
6137 0x042b,
6138 0x042f,
6139 },
6140 {
6141 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
6142 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
6143 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
6144 0x0429,
6145 0x042d,
6146 },
6147 {
6148 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
6149 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
6150 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
6151 0x0427,
6152 0x042b,
6153 },
6154 {
6155 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
6156 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
6157 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
6158 0x0424,
6159 0x0429,
6160 },
6161 {
6162 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
6163 0x04, 0x00, 0x04, 0x00, 0x11, 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x11,
6164 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
6165 0x041f,
6166 0x0424}
6167};
6168
6169static const struct chan_info_nphy_radio2057_rev5
6170chan_info_nphyrev8_2057_rev5[] = {
6171 {
6172 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
6173 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
6174 0x043a, 0x043f, 0x0443},
6175 {
6176 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
6177 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
6178 0x0438, 0x043d, 0x0441},
6179 {
6180 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
6181 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
6182 0x0436, 0x043a, 0x043f},
6183 {
6184 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
6185 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
6186 0x0434, 0x0438, 0x043d},
6187 {
6188 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
6189 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
6190 0x0431, 0x0436, 0x043a},
6191 {
6192 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
6193 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
6194 0x042f, 0x0434, 0x0438},
6195 {
6196 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
6197 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
6198 0x042d, 0x0431, 0x0436},
6199 {
6200 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
6201 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
6202 0x042b, 0x042f, 0x0434},
6203 {
6204 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
6205 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
6206 0x0429, 0x042d, 0x0431},
6207 {
6208 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
6209 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
6210 0x0427, 0x042b, 0x042f},
6211 {
6212 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
6213 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
6214 0x0424, 0x0429, 0x042d},
6215 {
6216 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
6217 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
6218 0x0422, 0x0427, 0x042b},
6219 {
6220 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
6221 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
6222 0x0420, 0x0424, 0x0429},
6223 {
6224 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
6225 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
6226 0x041b, 0x041f, 0x0424}
6227};
6228
6229static const struct chan_info_nphy_radio2057_rev5
6230chan_info_nphyrev9_2057_rev5v1[] = {
6231 {
6232 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
6233 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
6234 0x043a, 0x043f, 0x0443},
6235 {
6236 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
6237 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
6238 0x0438, 0x043d, 0x0441},
6239 {
6240 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
6241 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
6242 0x0436, 0x043a, 0x043f},
6243 {
6244 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
6245 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
6246 0x0434, 0x0438, 0x043d},
6247 {
6248 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
6249 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
6250 0x0431, 0x0436, 0x043a},
6251 {
6252 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
6253 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
6254 0x042f, 0x0434, 0x0438},
6255 {
6256 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
6257 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
6258 0x042d, 0x0431, 0x0436},
6259 {
6260 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
6261 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
6262 0x042b, 0x042f, 0x0434},
6263 {
6264 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
6265 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
6266 0x0429, 0x042d, 0x0431},
6267 {
6268 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
6269 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
6270 0x0427, 0x042b, 0x042f},
6271 {
6272 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
6273 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
6274 0x0424, 0x0429, 0x042d},
6275 {
6276 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
6277 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
6278 0x0422, 0x0427, 0x042b},
6279 {
6280 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
6281 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
6282 0x0420, 0x0424, 0x0429},
6283 {
6284 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
6285 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
6286 0x041b, 0x041f, 0x0424}
6287};
6288
6289static const struct chan_info_nphy_radio2057 chan_info_nphyrev8_2057_rev7[] = {
6290 {
6291 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
6292 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6293 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b4, 0x07b0, 0x07ac, 0x0214,
6294 0x0215,
6295 0x0216},
6296 {
6297 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
6298 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6299 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
6300 0x0214,
6301 0x0215},
6302 {
6303 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
6304 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6305 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
6306 0x0213,
6307 0x0214},
6308 {
6309 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
6310 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6311 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
6312 0x0212,
6313 0x0213},
6314 {
6315 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
6316 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6317 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
6318 0x0211,
6319 0x0212},
6320 {
6321 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
6322 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6323 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
6324 0x020f,
6325 0x0211},
6326 {
6327 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
6328 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6329 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
6330 0x020e,
6331 0x020f},
6332 {
6333 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
6334 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6335 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
6336 0x020d,
6337 0x020e},
6338 {
6339 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
6340 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6341 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
6342 0x020c,
6343 0x020d},
6344 {
6345 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
6346 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6347 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
6348 0x020b,
6349 0x020c},
6350 {
6351 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
6352 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6353 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
6354 0x020a,
6355 0x020b},
6356 {
6357 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
6358 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6359 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
6360 0x0209,
6361 0x020a},
6362 {
6363 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
6364 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6365 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
6366 0x0208,
6367 0x0209},
6368 {
6369 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
6370 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6371 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
6372 0x0207,
6373 0x0208},
6374 {
6375 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
6376 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6377 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
6378 0x0206,
6379 0x0207},
6380 {
6381 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
6382 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6383 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
6384 0x0205,
6385 0x0206},
6386 {
6387 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
6388 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6389 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
6390 0x0204,
6391 0x0205},
6392 {
6393 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
6394 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6395 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
6396 0x0203,
6397 0x0204},
6398 {
6399 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
6400 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6401 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
6402 0x0202,
6403 0x0203},
6404 {
6405 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
6406 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6407 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
6408 0x0201,
6409 0x0202},
6410 {
6411 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
6412 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6413 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
6414 0x0200,
6415 0x0201},
6416 {
6417 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
6418 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6419 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
6420 0x01ff,
6421 0x0200},
6422 {
6423 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
6424 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6425 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
6426 0x01fe,
6427 0x01ff},
6428 {
6429 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
6430 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6431 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
6432 0x01fc,
6433 0x01fd},
6434 {
6435 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
6436 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6437 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
6438 0x01fb,
6439 0x01fc},
6440 {
6441 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
6442 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6443 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
6444 0x01fa,
6445 0x01fb},
6446 {
6447 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
6448 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6449 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
6450 0x01f9,
6451 0x01fa},
6452 {
6453 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
6454 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6455 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
6456 0x01f8,
6457 0x01f9},
6458 {
6459 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
6460 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6461 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
6462 0x01f7,
6463 0x01f8},
6464 {
6465 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
6466 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6467 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
6468 0x01f6,
6469 0x01f7},
6470 {
6471 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
6472 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6473 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
6474 0x01f5,
6475 0x01f6},
6476 {
6477 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
6478 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6479 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
6480 0x01f4,
6481 0x01f5},
6482 {
6483 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
6484 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6485 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
6486 0x01f3,
6487 0x01f4},
6488 {
6489 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
6490 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6491 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
6492 0x01f2,
6493 0x01f3},
6494 {
6495 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
6496 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6497 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
6498 0x01f1,
6499 0x01f2},
6500 {
6501 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
6502 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6503 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
6504 0x01f0,
6505 0x01f1},
6506 {
6507 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
6508 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6509 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
6510 0x01f0,
6511 0x01f0},
6512 {
6513 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
6514 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6515 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
6516 0x01ef,
6517 0x01f0},
6518 {
6519 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
6520 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6521 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
6522 0x01ee,
6523 0x01ef},
6524 {
6525 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
6526 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6527 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
6528 0x01ed,
6529 0x01ee},
6530 {
6531 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
6532 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6533 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
6534 0x01ec,
6535 0x01ed},
6536 {
6537 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
6538 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6539 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
6540 0x01eb,
6541 0x01ec},
6542 {
6543 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
6544 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6545 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
6546 0x01ea,
6547 0x01eb},
6548 {
6549 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
6550 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6551 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
6552 0x01e9,
6553 0x01ea},
6554 {
6555 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
6556 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6557 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
6558 0x01e8,
6559 0x01e9},
6560 {
6561 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
6562 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6563 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
6564 0x01e7,
6565 0x01e8},
6566 {
6567 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
6568 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6569 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
6570 0x01e6,
6571 0x01e7},
6572 {
6573 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
6574 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6575 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
6576 0x01e5,
6577 0x01e6},
6578 {
6579 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
6580 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6581 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
6582 0x01e5,
6583 0x01e5},
6584 {
6585 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
6586 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6587 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
6588 0x01e4,
6589 0x01e5},
6590 {
6591 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
6592 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6593 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
6594 0x01e3,
6595 0x01e4},
6596 {
6597 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
6598 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6599 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
6600 0x01e2,
6601 0x01e3},
6602 {
6603 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
6604 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6605 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
6606 0x01e1,
6607 0x01e2},
6608 {
6609 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
6610 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6611 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
6612 0x01e0,
6613 0x01e1},
6614 {
6615 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
6616 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6617 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
6618 0x01df,
6619 0x01e0},
6620 {
6621 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
6622 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6623 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
6624 0x01de,
6625 0x01df},
6626 {
6627 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
6628 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6629 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
6630 0x01dd,
6631 0x01de},
6632 {
6633 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
6634 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6635 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
6636 0x01dd,
6637 0x01dd},
6638 {
6639 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
6640 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6641 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
6642 0x01dc,
6643 0x01dd},
6644 {
6645 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
6646 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6647 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
6648 0x01db,
6649 0x01dc},
6650 {
6651 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
6652 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6653 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
6654 0x01da,
6655 0x01db},
6656 {
6657 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
6658 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6659 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
6660 0x01d9,
6661 0x01da},
6662 {
6663 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
6664 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6665 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
6666 0x01d8,
6667 0x01d9},
6668 {
6669 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
6670 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6671 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
6672 0x01d7,
6673 0x01d8},
6674 {
6675 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
6676 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6677 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
6678 0x01d7,
6679 0x01d7},
6680 {
6681 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
6682 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6683 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
6684 0x01d6,
6685 0x01d7},
6686 {
6687 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
6688 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6689 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
6690 0x01d5,
6691 0x01d6},
6692 {
6693 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
6694 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
6695 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
6696 0x01d4,
6697 0x01d5},
6698 {
6699 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
6700 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
6701 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
6702 0x01d3,
6703 0x01d4},
6704 {
6705 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
6706 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
6707 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
6708 0x01d2,
6709 0x01d3},
6710 {
6711 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
6712 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
6713 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
6714 0x01d2,
6715 0x01d2},
6716 {
6717 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
6718 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
6719 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
6720 0x01d1,
6721 0x01d2},
6722 {
6723 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
6724 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
6725 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
6726 0x01d0,
6727 0x01d1},
6728 {
6729 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
6730 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
6731 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
6732 0x01cf,
6733 0x01d0},
6734 {
6735 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
6736 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
6737 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
6738 0x01ce,
6739 0x01cf},
6740 {
6741 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
6742 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
6743 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
6744 0x01ce,
6745 0x01ce},
6746 {
6747 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
6748 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
6749 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
6750 0x01cd,
6751 0x01ce},
6752 {
6753 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
6754 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6755 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
6756 0x01cc,
6757 0x01cd},
6758 {
6759 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
6760 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6761 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
6762 0x01cb,
6763 0x01cc},
6764 {
6765 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
6766 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6767 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
6768 0x01ca,
6769 0x01cb},
6770 {
6771 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
6772 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6773 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
6774 0x01ca,
6775 0x01cb},
6776 {
6777 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
6778 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6779 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
6780 0x01c9,
6781 0x01ca},
6782 {
6783 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
6784 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6785 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
6786 0x01c9,
6787 0x01ca},
6788 {
6789 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
6790 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6791 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
6792 0x01c9,
6793 0x01c9},
6794 {
6795 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
6796 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6797 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
6798 0x01c8,
6799 0x01c9},
6800 {
6801 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
6802 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6803 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
6804 0x01c8,
6805 0x01c9},
6806 {
6807 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
6808 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6809 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
6810 0x01c8,
6811 0x01c8},
6812 {
6813 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
6814 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6815 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
6816 0x01c7,
6817 0x01c8},
6818 {
6819 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
6820 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6821 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
6822 0x01c7,
6823 0x01c8},
6824 {
6825 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
6826 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6827 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
6828 0x01c6,
6829 0x01c7},
6830 {
6831 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
6832 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6833 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
6834 0x01c6,
6835 0x01c7},
6836 {
6837 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
6838 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6839 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
6840 0x01c6,
6841 0x01c6},
6842 {
6843 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
6844 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6845 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
6846 0x01c5,
6847 0x01c6},
6848 {
6849 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
6850 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6851 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
6852 0x01c5,
6853 0x01c6},
6854 {
6855 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
6856 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6857 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
6858 0x01c4,
6859 0x01c5},
6860 {
6861 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
6862 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
6863 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
6864 0x01c4,
6865 0x01c5},
6866 {
6867 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
6868 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6869 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
6870 0x01c4,
6871 0x01c4},
6872 {
6873 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
6874 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6875 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
6876 0x01c3,
6877 0x01c4},
6878 {
6879 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
6880 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6881 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
6882 0x01c3,
6883 0x01c4},
6884 {
6885 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
6886 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6887 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
6888 0x01c2,
6889 0x01c3},
6890 {
6891 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
6892 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6893 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
6894 0x01c2,
6895 0x01c3},
6896 {
6897 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
6898 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6899 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
6900 0x01c2,
6901 0x01c2},
6902 {
6903 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
6904 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6905 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
6906 0x01c1,
6907 0x01c2},
6908 {
6909 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
6910 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6911 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
6912 0x01c0,
6913 0x01c1},
6914 {
6915 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
6916 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6917 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
6918 0x01bf,
6919 0x01c0},
6920 {
6921 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
6922 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6923 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
6924 0x01bf,
6925 0x01bf},
6926 {
6927 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
6928 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6929 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
6930 0x01be,
6931 0x01bf},
6932 {
6933 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
6934 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6935 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
6936 0x01bd,
6937 0x01be},
6938 {
6939 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
6940 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6941 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
6942 0x01bc,
6943 0x01bd},
6944 {
6945 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
6946 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6947 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
6948 0x043f,
6949 0x0443},
6950 {
6951 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
6952 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6953 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
6954 0x043d,
6955 0x0441},
6956 {
6957 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
6958 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6959 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
6960 0x043a,
6961 0x043f},
6962 {
6963 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
6964 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6965 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
6966 0x0438,
6967 0x043d},
6968 {
6969 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
6970 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6971 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
6972 0x0436,
6973 0x043a},
6974 {
6975 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
6976 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6977 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
6978 0x0434,
6979 0x0438},
6980 {
6981 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
6982 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6983 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
6984 0x0431,
6985 0x0436},
6986 {
6987 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
6988 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6989 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
6990 0x042f,
6991 0x0434},
6992 {
6993 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
6994 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6995 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
6996 0x042d,
6997 0x0431},
6998 {
6999 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
7000 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7001 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
7002 0x042b,
7003 0x042f},
7004 {
7005 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
7006 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7007 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
7008 0x0429,
7009 0x042d},
7010 {
7011 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
7012 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7013 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
7014 0x0427,
7015 0x042b},
7016 {
7017 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
7018 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7019 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
7020 0x0424,
7021 0x0429},
7022 {
7023 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
7024 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
7025 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
7026 0x041f,
7027 0x0424}
7028};
7029
7030static const struct chan_info_nphy_radio2057 chan_info_nphyrev8_2057_rev8[] = {
7031 {
7032 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
7033 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
7034 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
7035 0x0214,
7036 0x0215},
7037 {
7038 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
7039 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
7040 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
7041 0x0213,
7042 0x0214},
7043 {
7044 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
7045 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
7046 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
7047 0x0212,
7048 0x0213},
7049 {
7050 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
7051 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
7052 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
7053 0x0211,
7054 0x0212},
7055 {
7056 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
7057 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
7058 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
7059 0x020f,
7060 0x0211},
7061 {
7062 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
7063 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
7064 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
7065 0x020e,
7066 0x020f},
7067 {
7068 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
7069 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
7070 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
7071 0x020d,
7072 0x020e},
7073 {
7074 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
7075 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7076 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
7077 0x020c,
7078 0x020d},
7079 {
7080 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
7081 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7082 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
7083 0x020b,
7084 0x020c},
7085 {
7086 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
7087 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7088 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
7089 0x020a,
7090 0x020b},
7091 {
7092 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
7093 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7094 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
7095 0x0209,
7096 0x020a},
7097 {
7098 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
7099 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7100 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
7101 0x0208,
7102 0x0209},
7103 {
7104 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
7105 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7106 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
7107 0x0207,
7108 0x0208},
7109 {
7110 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
7111 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7112 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
7113 0x0206,
7114 0x0207},
7115 {
7116 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
7117 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7118 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
7119 0x0205,
7120 0x0206},
7121 {
7122 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
7123 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7124 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
7125 0x0204,
7126 0x0205},
7127 {
7128 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
7129 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7130 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
7131 0x0203,
7132 0x0204},
7133 {
7134 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
7135 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7136 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
7137 0x0202,
7138 0x0203},
7139 {
7140 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
7141 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7142 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
7143 0x0201,
7144 0x0202},
7145 {
7146 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
7147 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7148 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
7149 0x0200,
7150 0x0201},
7151 {
7152 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
7153 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7154 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
7155 0x01ff,
7156 0x0200},
7157 {
7158 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
7159 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7160 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
7161 0x01fe,
7162 0x01ff},
7163 {
7164 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
7165 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7166 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
7167 0x01fc,
7168 0x01fd},
7169 {
7170 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
7171 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7172 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
7173 0x01fb,
7174 0x01fc},
7175 {
7176 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
7177 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7178 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
7179 0x01fa,
7180 0x01fb},
7181 {
7182 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
7183 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7184 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
7185 0x01f9,
7186 0x01fa},
7187 {
7188 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
7189 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7190 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
7191 0x01f8,
7192 0x01f9},
7193 {
7194 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
7195 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7196 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
7197 0x01f7,
7198 0x01f8},
7199 {
7200 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
7201 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7202 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
7203 0x01f6,
7204 0x01f7},
7205 {
7206 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
7207 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7208 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
7209 0x01f5,
7210 0x01f6},
7211 {
7212 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
7213 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7214 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
7215 0x01f4,
7216 0x01f5},
7217 {
7218 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
7219 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7220 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
7221 0x01f3,
7222 0x01f4},
7223 {
7224 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
7225 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7226 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
7227 0x01f2,
7228 0x01f3},
7229 {
7230 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
7231 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7232 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
7233 0x01f1,
7234 0x01f2},
7235 {
7236 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
7237 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7238 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
7239 0x01f0,
7240 0x01f1},
7241 {
7242 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
7243 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7244 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
7245 0x01f0,
7246 0x01f0},
7247 {
7248 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
7249 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7250 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
7251 0x01ef,
7252 0x01f0},
7253 {
7254 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
7255 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7256 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
7257 0x01ee,
7258 0x01ef},
7259 {
7260 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
7261 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7262 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
7263 0x01ed,
7264 0x01ee},
7265 {
7266 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
7267 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7268 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
7269 0x01ec,
7270 0x01ed},
7271 {
7272 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
7273 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7274 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
7275 0x01eb,
7276 0x01ec},
7277 {
7278 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
7279 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7280 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
7281 0x01ea,
7282 0x01eb},
7283 {
7284 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
7285 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7286 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
7287 0x01e9,
7288 0x01ea},
7289 {
7290 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
7291 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7292 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
7293 0x01e8,
7294 0x01e9},
7295 {
7296 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
7297 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7298 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
7299 0x01e7,
7300 0x01e8},
7301 {
7302 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
7303 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7304 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
7305 0x01e6,
7306 0x01e7},
7307 {
7308 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
7309 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7310 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
7311 0x01e5,
7312 0x01e6},
7313 {
7314 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
7315 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7316 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
7317 0x01e5,
7318 0x01e5},
7319 {
7320 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
7321 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7322 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
7323 0x01e4,
7324 0x01e5},
7325 {
7326 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
7327 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7328 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
7329 0x01e3,
7330 0x01e4},
7331 {
7332 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
7333 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7334 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
7335 0x01e2,
7336 0x01e3},
7337 {
7338 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
7339 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7340 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
7341 0x01e1,
7342 0x01e2},
7343 {
7344 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
7345 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7346 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
7347 0x01e0,
7348 0x01e1},
7349 {
7350 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
7351 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7352 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
7353 0x01df,
7354 0x01e0},
7355 {
7356 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
7357 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7358 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
7359 0x01de,
7360 0x01df},
7361 {
7362 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
7363 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7364 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
7365 0x01dd,
7366 0x01de},
7367 {
7368 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
7369 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7370 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
7371 0x01dd,
7372 0x01dd},
7373 {
7374 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
7375 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7376 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
7377 0x01dc,
7378 0x01dd},
7379 {
7380 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
7381 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7382 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
7383 0x01db,
7384 0x01dc},
7385 {
7386 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
7387 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7388 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
7389 0x01da,
7390 0x01db},
7391 {
7392 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
7393 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7394 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
7395 0x01d9,
7396 0x01da},
7397 {
7398 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
7399 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7400 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
7401 0x01d8,
7402 0x01d9},
7403 {
7404 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
7405 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7406 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
7407 0x01d7,
7408 0x01d8},
7409 {
7410 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
7411 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7412 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
7413 0x01d7,
7414 0x01d7},
7415 {
7416 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
7417 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7418 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
7419 0x01d6,
7420 0x01d7},
7421 {
7422 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
7423 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7424 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
7425 0x01d5,
7426 0x01d6},
7427 {
7428 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
7429 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
7430 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
7431 0x01d4,
7432 0x01d5},
7433 {
7434 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
7435 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
7436 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
7437 0x01d3,
7438 0x01d4},
7439 {
7440 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
7441 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
7442 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
7443 0x01d2,
7444 0x01d3},
7445 {
7446 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
7447 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
7448 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
7449 0x01d2,
7450 0x01d2},
7451 {
7452 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
7453 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
7454 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
7455 0x01d1,
7456 0x01d2},
7457 {
7458 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
7459 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
7460 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
7461 0x01d0,
7462 0x01d1},
7463 {
7464 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
7465 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
7466 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
7467 0x01cf,
7468 0x01d0},
7469 {
7470 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
7471 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
7472 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
7473 0x01ce,
7474 0x01cf},
7475 {
7476 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
7477 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
7478 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
7479 0x01ce,
7480 0x01ce},
7481 {
7482 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
7483 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
7484 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
7485 0x01cd,
7486 0x01ce},
7487 {
7488 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
7489 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7490 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
7491 0x01cc,
7492 0x01cd},
7493 {
7494 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
7495 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7496 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
7497 0x01cb,
7498 0x01cc},
7499 {
7500 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
7501 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7502 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
7503 0x01ca,
7504 0x01cb},
7505 {
7506 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
7507 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7508 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
7509 0x01ca,
7510 0x01cb},
7511 {
7512 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
7513 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7514 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
7515 0x01c9,
7516 0x01ca},
7517 {
7518 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
7519 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7520 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
7521 0x01c9,
7522 0x01ca},
7523 {
7524 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
7525 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7526 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
7527 0x01c9,
7528 0x01c9},
7529 {
7530 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
7531 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7532 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
7533 0x01c8,
7534 0x01c9},
7535 {
7536 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
7537 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7538 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
7539 0x01c8,
7540 0x01c9},
7541 {
7542 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
7543 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7544 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
7545 0x01c8,
7546 0x01c8},
7547 {
7548 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
7549 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7550 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
7551 0x01c7,
7552 0x01c8},
7553 {
7554 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
7555 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7556 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
7557 0x01c7,
7558 0x01c8},
7559 {
7560 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
7561 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7562 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
7563 0x01c6,
7564 0x01c7},
7565 {
7566 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
7567 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7568 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
7569 0x01c6,
7570 0x01c7},
7571 {
7572 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
7573 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7574 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
7575 0x01c6,
7576 0x01c6},
7577 {
7578 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
7579 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7580 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
7581 0x01c5,
7582 0x01c6},
7583 {
7584 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
7585 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7586 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
7587 0x01c5,
7588 0x01c6},
7589 {
7590 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
7591 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7592 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
7593 0x01c4,
7594 0x01c5},
7595 {
7596 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
7597 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
7598 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
7599 0x01c4,
7600 0x01c5},
7601 {
7602 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
7603 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7604 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
7605 0x01c4,
7606 0x01c4},
7607 {
7608 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
7609 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7610 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
7611 0x01c3,
7612 0x01c4},
7613 {
7614 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
7615 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7616 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
7617 0x01c3,
7618 0x01c4},
7619 {
7620 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
7621 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7622 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
7623 0x01c2,
7624 0x01c3},
7625 {
7626 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
7627 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7628 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
7629 0x01c2,
7630 0x01c3},
7631 {
7632 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
7633 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7634 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
7635 0x01c2,
7636 0x01c2},
7637 {
7638 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
7639 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7640 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
7641 0x01c1,
7642 0x01c2},
7643 {
7644 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
7645 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7646 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
7647 0x01c0,
7648 0x01c1},
7649 {
7650 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
7651 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7652 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
7653 0x01bf,
7654 0x01c0},
7655 {
7656 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
7657 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7658 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
7659 0x01bf,
7660 0x01bf},
7661 {
7662 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
7663 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7664 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
7665 0x01be,
7666 0x01bf},
7667 {
7668 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
7669 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7670 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
7671 0x01bd,
7672 0x01be},
7673 {
7674 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
7675 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7676 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
7677 0x01bc,
7678 0x01bd},
7679 {
7680 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
7681 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7682 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
7683 0x043f,
7684 0x0443},
7685 {
7686 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
7687 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7688 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
7689 0x043d,
7690 0x0441},
7691 {
7692 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
7693 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7694 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
7695 0x043a,
7696 0x043f},
7697 {
7698 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
7699 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7700 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
7701 0x0438,
7702 0x043d},
7703 {
7704 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
7705 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7706 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
7707 0x0436,
7708 0x043a},
7709 {
7710 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
7711 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7712 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
7713 0x0434,
7714 0x0438},
7715 {
7716 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
7717 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7718 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
7719 0x0431,
7720 0x0436},
7721 {
7722 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
7723 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7724 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
7725 0x042f,
7726 0x0434},
7727 {
7728 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
7729 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7730 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
7731 0x042d,
7732 0x0431},
7733 {
7734 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
7735 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7736 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
7737 0x042b,
7738 0x042f},
7739 {
7740 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
7741 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7742 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
7743 0x0429,
7744 0x042d},
7745 {
7746 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
7747 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7748 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
7749 0x0427,
7750 0x042b},
7751 {
7752 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
7753 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7754 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
7755 0x0424,
7756 0x0429},
7757 {
7758 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
7759 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
7760 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
7761 0x041f,
7762 0x0424}
7763};
7764
7765static struct radio_regs regs_2055[] = {
7766 {0x02, 0x80, 0x80, 0, 0},
7767 {0x03, 0, 0, 0, 0},
7768 {0x04, 0x27, 0x27, 0, 0},
7769 {0x05, 0, 0, 0, 0},
7770 {0x06, 0x27, 0x27, 0, 0},
7771 {0x07, 0x7f, 0x7f, 1, 1},
7772 {0x08, 0x7, 0x7, 1, 1},
7773 {0x09, 0x7f, 0x7f, 1, 1},
7774 {0x0A, 0x7, 0x7, 1, 1},
7775 {0x0B, 0x15, 0x15, 0, 0},
7776 {0x0C, 0x15, 0x15, 0, 0},
7777 {0x0D, 0x4f, 0x4f, 1, 1},
7778 {0x0E, 0x5, 0x5, 1, 1},
7779 {0x0F, 0x4f, 0x4f, 1, 1},
7780 {0x10, 0x5, 0x5, 1, 1},
7781 {0x11, 0xd0, 0xd0, 0, 0},
7782 {0x12, 0x2, 0x2, 0, 0},
7783 {0x13, 0, 0, 0, 0},
7784 {0x14, 0x40, 0x40, 0, 0},
7785 {0x15, 0, 0, 0, 0},
7786 {0x16, 0, 0, 0, 0},
7787 {0x17, 0, 0, 0, 0},
7788 {0x18, 0, 0, 0, 0},
7789 {0x19, 0, 0, 0, 0},
7790 {0x1A, 0, 0, 0, 0},
7791 {0x1B, 0, 0, 0, 0},
7792 {0x1C, 0, 0, 0, 0},
7793 {0x1D, 0xc0, 0xc0, 0, 0},
7794 {0x1E, 0xff, 0xff, 0, 0},
7795 {0x1F, 0xc0, 0xc0, 0, 0},
7796 {0x20, 0xff, 0xff, 0, 0},
7797 {0x21, 0xc0, 0xc0, 0, 0},
7798 {0x22, 0, 0, 0, 0},
7799 {0x23, 0x2c, 0x2c, 0, 0},
7800 {0x24, 0, 0, 0, 0},
7801 {0x25, 0, 0, 0, 0},
7802 {0x26, 0, 0, 0, 0},
7803 {0x27, 0, 0, 0, 0},
7804 {0x28, 0, 0, 0, 0},
7805 {0x29, 0, 0, 0, 0},
7806 {0x2A, 0, 0, 0, 0},
7807 {0x2B, 0, 0, 0, 0},
7808 {0x2C, 0, 0, 0, 0},
7809 {0x2D, 0xa4, 0xa4, 0, 0},
7810 {0x2E, 0x38, 0x38, 0, 0},
7811 {0x2F, 0, 0, 0, 0},
7812 {0x30, 0x4, 0x4, 1, 1},
7813 {0x31, 0, 0, 0, 0},
7814 {0x32, 0xa, 0xa, 0, 0},
7815 {0x33, 0x87, 0x87, 0, 0},
7816 {0x34, 0x9, 0x9, 0, 0},
7817 {0x35, 0x70, 0x70, 0, 0},
7818 {0x36, 0x11, 0x11, 0, 0},
7819 {0x37, 0x18, 0x18, 1, 1},
7820 {0x38, 0x6, 0x6, 0, 0},
7821 {0x39, 0x4, 0x4, 1, 1},
7822 {0x3A, 0x6, 0x6, 0, 0},
7823 {0x3B, 0x9e, 0x9e, 0, 0},
7824 {0x3C, 0x9, 0x9, 0, 0},
7825 {0x3D, 0xc8, 0xc8, 1, 1},
7826 {0x3E, 0x88, 0x88, 0, 0},
7827 {0x3F, 0, 0, 0, 0},
7828 {0x40, 0, 0, 0, 0},
7829 {0x41, 0, 0, 0, 0},
7830 {0x42, 0x1, 0x1, 0, 0},
7831 {0x43, 0x2, 0x2, 0, 0},
7832 {0x44, 0x96, 0x96, 0, 0},
7833 {0x45, 0x3e, 0x3e, 0, 0},
7834 {0x46, 0x3e, 0x3e, 0, 0},
7835 {0x47, 0x13, 0x13, 0, 0},
7836 {0x48, 0x2, 0x2, 0, 0},
7837 {0x49, 0x15, 0x15, 0, 0},
7838 {0x4A, 0x7, 0x7, 0, 0},
7839 {0x4B, 0, 0, 0, 0},
7840 {0x4C, 0, 0, 0, 0},
7841 {0x4D, 0, 0, 0, 0},
7842 {0x4E, 0, 0, 0, 0},
7843 {0x4F, 0, 0, 0, 0},
7844 {0x50, 0x8, 0x8, 0, 0},
7845 {0x51, 0x8, 0x8, 0, 0},
7846 {0x52, 0x6, 0x6, 0, 0},
7847 {0x53, 0x84, 0x84, 1, 1},
7848 {0x54, 0xc3, 0xc3, 0, 0},
7849 {0x55, 0x8f, 0x8f, 0, 0},
7850 {0x56, 0xff, 0xff, 0, 0},
7851 {0x57, 0xff, 0xff, 0, 0},
7852 {0x58, 0x88, 0x88, 0, 0},
7853 {0x59, 0x88, 0x88, 0, 0},
7854 {0x5A, 0, 0, 0, 0},
7855 {0x5B, 0xcc, 0xcc, 0, 0},
7856 {0x5C, 0x6, 0x6, 0, 0},
7857 {0x5D, 0x80, 0x80, 0, 0},
7858 {0x5E, 0x80, 0x80, 0, 0},
7859 {0x5F, 0xf8, 0xf8, 0, 0},
7860 {0x60, 0x88, 0x88, 0, 0},
7861 {0x61, 0x88, 0x88, 0, 0},
7862 {0x62, 0x88, 0x8, 1, 1},
7863 {0x63, 0x88, 0x88, 0, 0},
7864 {0x64, 0, 0, 0, 0},
7865 {0x65, 0x1, 0x1, 1, 1},
7866 {0x66, 0x8a, 0x8a, 0, 0},
7867 {0x67, 0x8, 0x8, 0, 0},
7868 {0x68, 0x83, 0x83, 0, 0},
7869 {0x69, 0x6, 0x6, 0, 0},
7870 {0x6A, 0xa0, 0xa0, 0, 0},
7871 {0x6B, 0xa, 0xa, 0, 0},
7872 {0x6C, 0x87, 0x87, 1, 1},
7873 {0x6D, 0x2a, 0x2a, 0, 0},
7874 {0x6E, 0x2a, 0x2a, 0, 0},
7875 {0x6F, 0x2a, 0x2a, 0, 0},
7876 {0x70, 0x2a, 0x2a, 0, 0},
7877 {0x71, 0x18, 0x18, 0, 0},
7878 {0x72, 0x6a, 0x6a, 1, 1},
7879 {0x73, 0xab, 0xab, 1, 1},
7880 {0x74, 0x13, 0x13, 1, 1},
7881 {0x75, 0xc1, 0xc1, 1, 1},
7882 {0x76, 0xaa, 0xaa, 1, 1},
7883 {0x77, 0x87, 0x87, 1, 1},
7884 {0x78, 0, 0, 0, 0},
7885 {0x79, 0x6, 0x6, 0, 0},
7886 {0x7A, 0x7, 0x7, 0, 0},
7887 {0x7B, 0x7, 0x7, 0, 0},
7888 {0x7C, 0x15, 0x15, 0, 0},
7889 {0x7D, 0x55, 0x55, 0, 0},
7890 {0x7E, 0x97, 0x97, 1, 1},
7891 {0x7F, 0x8, 0x8, 0, 0},
7892 {0x80, 0x14, 0x14, 1, 1},
7893 {0x81, 0x33, 0x33, 0, 0},
7894 {0x82, 0x88, 0x88, 0, 0},
7895 {0x83, 0x6, 0x6, 0, 0},
7896 {0x84, 0x3, 0x3, 1, 1},
7897 {0x85, 0xa, 0xa, 0, 0},
7898 {0x86, 0x3, 0x3, 1, 1},
7899 {0x87, 0x2a, 0x2a, 0, 0},
7900 {0x88, 0xa4, 0xa4, 0, 0},
7901 {0x89, 0x18, 0x18, 0, 0},
7902 {0x8A, 0x28, 0x28, 0, 0},
7903 {0x8B, 0, 0, 0, 0},
7904 {0x8C, 0x4a, 0x4a, 0, 0},
7905 {0x8D, 0, 0, 0, 0},
7906 {0x8E, 0xf8, 0xf8, 0, 0},
7907 {0x8F, 0x88, 0x88, 0, 0},
7908 {0x90, 0x88, 0x88, 0, 0},
7909 {0x91, 0x88, 0x8, 1, 1},
7910 {0x92, 0x88, 0x88, 0, 0},
7911 {0x93, 0, 0, 0, 0},
7912 {0x94, 0x1, 0x1, 1, 1},
7913 {0x95, 0x8a, 0x8a, 0, 0},
7914 {0x96, 0x8, 0x8, 0, 0},
7915 {0x97, 0x83, 0x83, 0, 0},
7916 {0x98, 0x6, 0x6, 0, 0},
7917 {0x99, 0xa0, 0xa0, 0, 0},
7918 {0x9A, 0xa, 0xa, 0, 0},
7919 {0x9B, 0x87, 0x87, 1, 1},
7920 {0x9C, 0x2a, 0x2a, 0, 0},
7921 {0x9D, 0x2a, 0x2a, 0, 0},
7922 {0x9E, 0x2a, 0x2a, 0, 0},
7923 {0x9F, 0x2a, 0x2a, 0, 0},
7924 {0xA0, 0x18, 0x18, 0, 0},
7925 {0xA1, 0x6a, 0x6a, 1, 1},
7926 {0xA2, 0xab, 0xab, 1, 1},
7927 {0xA3, 0x13, 0x13, 1, 1},
7928 {0xA4, 0xc1, 0xc1, 1, 1},
7929 {0xA5, 0xaa, 0xaa, 1, 1},
7930 {0xA6, 0x87, 0x87, 1, 1},
7931 {0xA7, 0, 0, 0, 0},
7932 {0xA8, 0x6, 0x6, 0, 0},
7933 {0xA9, 0x7, 0x7, 0, 0},
7934 {0xAA, 0x7, 0x7, 0, 0},
7935 {0xAB, 0x15, 0x15, 0, 0},
7936 {0xAC, 0x55, 0x55, 0, 0},
7937 {0xAD, 0x97, 0x97, 1, 1},
7938 {0xAE, 0x8, 0x8, 0, 0},
7939 {0xAF, 0x14, 0x14, 1, 1},
7940 {0xB0, 0x33, 0x33, 0, 0},
7941 {0xB1, 0x88, 0x88, 0, 0},
7942 {0xB2, 0x6, 0x6, 0, 0},
7943 {0xB3, 0x3, 0x3, 1, 1},
7944 {0xB4, 0xa, 0xa, 0, 0},
7945 {0xB5, 0x3, 0x3, 1, 1},
7946 {0xB6, 0x2a, 0x2a, 0, 0},
7947 {0xB7, 0xa4, 0xa4, 0, 0},
7948 {0xB8, 0x18, 0x18, 0, 0},
7949 {0xB9, 0x28, 0x28, 0, 0},
7950 {0xBA, 0, 0, 0, 0},
7951 {0xBB, 0x4a, 0x4a, 0, 0},
7952 {0xBC, 0, 0, 0, 0},
7953 {0xBD, 0x71, 0x71, 0, 0},
7954 {0xBE, 0x72, 0x72, 0, 0},
7955 {0xBF, 0x73, 0x73, 0, 0},
7956 {0xC0, 0x74, 0x74, 0, 0},
7957 {0xC1, 0x75, 0x75, 0, 0},
7958 {0xC2, 0x76, 0x76, 0, 0},
7959 {0xC3, 0x77, 0x77, 0, 0},
7960 {0xC4, 0x78, 0x78, 0, 0},
7961 {0xC5, 0x79, 0x79, 0, 0},
7962 {0xC6, 0x7a, 0x7a, 0, 0},
7963 {0xC7, 0, 0, 0, 0},
7964 {0xC8, 0, 0, 0, 0},
7965 {0xC9, 0, 0, 0, 0},
7966 {0xCA, 0, 0, 0, 0},
7967 {0xCB, 0, 0, 0, 0},
7968 {0xCC, 0, 0, 0, 0},
7969 {0xCD, 0, 0, 0, 0},
7970 {0xCE, 0x6, 0x6, 0, 0},
7971 {0xCF, 0, 0, 0, 0},
7972 {0xD0, 0, 0, 0, 0},
7973 {0xD1, 0x18, 0x18, 0, 0},
7974 {0xD2, 0x88, 0x88, 0, 0},
7975 {0xD3, 0, 0, 0, 0},
7976 {0xD4, 0, 0, 0, 0},
7977 {0xD5, 0, 0, 0, 0},
7978 {0xD6, 0, 0, 0, 0},
7979 {0xD7, 0, 0, 0, 0},
7980 {0xD8, 0, 0, 0, 0},
7981 {0xD9, 0, 0, 0, 0},
7982 {0xDA, 0x6, 0x6, 0, 0},
7983 {0xDB, 0, 0, 0, 0},
7984 {0xDC, 0, 0, 0, 0},
7985 {0xDD, 0x18, 0x18, 0, 0},
7986 {0xDE, 0x88, 0x88, 0, 0},
7987 {0xDF, 0, 0, 0, 0},
7988 {0xE0, 0, 0, 0, 0},
7989 {0xE1, 0, 0, 0, 0},
7990 {0xE2, 0, 0, 0, 0},
7991 {0xFFFF, 0, 0, 0, 0},
7992};
7993
7994static struct radio_regs regs_SYN_2056[] = {
7995 {0x02, 0, 0, 0, 0},
7996 {0x03, 0, 0, 0, 0},
7997 {0x04, 0, 0, 0, 0},
7998 {0x05, 0, 0, 0, 0},
7999 {0x06, 0, 0, 0, 0},
8000 {0x07, 0, 0, 0, 0},
8001 {0x08, 0, 0, 0, 0},
8002 {0x09, 0x1, 0x1, 0, 0},
8003 {0x0A, 0, 0, 0, 0},
8004 {0x0B, 0, 0, 0, 0},
8005 {0x0C, 0, 0, 0, 0},
8006 {0x0D, 0, 0, 0, 0},
8007 {0x0E, 0, 0, 0, 0},
8008 {0x0F, 0, 0, 0, 0},
8009 {0x10, 0, 0, 0, 0},
8010 {0x11, 0, 0, 0, 0},
8011 {0x12, 0, 0, 0, 0},
8012 {0x13, 0, 0, 0, 0},
8013 {0x14, 0, 0, 0, 0},
8014 {0x15, 0, 0, 0, 0},
8015 {0x16, 0, 0, 0, 0},
8016 {0x17, 0, 0, 0, 0},
8017 {0x18, 0, 0, 0, 0},
8018 {0x19, 0, 0, 0, 0},
8019 {0x1A, 0, 0, 0, 0},
8020 {0x1B, 0, 0, 0, 0},
8021 {0x1C, 0, 0, 0, 0},
8022 {0x1D, 0, 0, 0, 0},
8023 {0x1E, 0, 0, 0, 0},
8024 {0x1F, 0, 0, 0, 0},
8025 {0x20, 0, 0, 0, 0},
8026 {0x21, 0, 0, 0, 0},
8027 {0x22, 0x60, 0x60, 0, 0},
8028 {0x23, 0x6, 0x6, 0, 0},
8029 {0x24, 0xc, 0xc, 0, 0},
8030 {0x25, 0, 0, 0, 0},
8031 {0x26, 0, 0, 0, 0},
8032 {0x27, 0, 0, 0, 0},
8033 {0x28, 0x1, 0x1, 0, 0},
8034 {0x29, 0, 0, 0, 0},
8035 {0x2A, 0, 0, 0, 0},
8036 {0x2B, 0, 0, 0, 0},
8037 {0x2C, 0, 0, 0, 0},
8038 {0x2D, 0, 0, 0, 0},
8039 {0x2E, 0xd, 0xd, 0, 0},
8040 {0x2F, 0x1f, 0x1f, 0, 0},
8041 {0x30, 0x15, 0x15, 0, 0},
8042 {0x31, 0xf, 0xf, 0, 0},
8043 {0x32, 0, 0, 0, 0},
8044 {0x33, 0, 0, 0, 0},
8045 {0x34, 0, 0, 0, 0},
8046 {0x35, 0, 0, 0, 0},
8047 {0x36, 0, 0, 0, 0},
8048 {0x37, 0, 0, 0, 0},
8049 {0x38, 0, 0, 0, 0},
8050 {0x39, 0, 0, 0, 0},
8051 {0x3A, 0, 0, 0, 0},
8052 {0x3B, 0, 0, 0, 0},
8053 {0x3C, 0x13, 0x13, 0, 0},
8054 {0x3D, 0xf, 0xf, 0, 0},
8055 {0x3E, 0x18, 0x18, 0, 0},
8056 {0x3F, 0, 0, 0, 0},
8057 {0x40, 0, 0, 0, 0},
8058 {0x41, 0x20, 0x20, 0, 0},
8059 {0x42, 0x20, 0x20, 0, 0},
8060 {0x43, 0, 0, 0, 0},
8061 {0x44, 0x77, 0x77, 0, 0},
8062 {0x45, 0x7, 0x7, 0, 0},
8063 {0x46, 0x1, 0x1, 0, 0},
8064 {0x47, 0x4, 0x4, 0, 0},
8065 {0x48, 0xf, 0xf, 0, 0},
8066 {0x49, 0x30, 0x30, 0, 0},
8067 {0x4A, 0x32, 0x32, 0, 0},
8068 {0x4B, 0xd, 0xd, 0, 0},
8069 {0x4C, 0xd, 0xd, 0, 0},
8070 {0x4D, 0x4, 0x4, 0, 0},
8071 {0x4E, 0x6, 0x6, 0, 0},
8072 {0x4F, 0x1, 0x1, 0, 0},
8073 {0x50, 0x1c, 0x1c, 0, 0},
8074 {0x51, 0x2, 0x2, 0, 0},
8075 {0x52, 0x2, 0x2, 0, 0},
8076 {0x53, 0xf7, 0xf7, 1, 1},
8077 {0x54, 0xb4, 0xb4, 0, 0},
8078 {0x55, 0xd2, 0xd2, 0, 0},
8079 {0x56, 0, 0, 0, 0},
8080 {0x57, 0, 0, 0, 0},
8081 {0x58, 0x4, 0x4, 0, 0},
8082 {0x59, 0x96, 0x96, 0, 0},
8083 {0x5A, 0x3e, 0x3e, 0, 0},
8084 {0x5B, 0x3e, 0x3e, 0, 0},
8085 {0x5C, 0x13, 0x13, 0, 0},
8086 {0x5D, 0x2, 0x2, 0, 0},
8087 {0x5E, 0, 0, 0, 0},
8088 {0x5F, 0x7, 0x7, 0, 0},
8089 {0x60, 0x7, 0x7, 1, 1},
8090 {0x61, 0x8, 0x8, 0, 0},
8091 {0x62, 0x3, 0x3, 0, 0},
8092 {0x63, 0, 0, 0, 0},
8093 {0x64, 0, 0, 0, 0},
8094 {0x65, 0, 0, 0, 0},
8095 {0x66, 0, 0, 0, 0},
8096 {0x67, 0, 0, 0, 0},
8097 {0x68, 0x40, 0x40, 0, 0},
8098 {0x69, 0, 0, 0, 0},
8099 {0x6A, 0, 0, 0, 0},
8100 {0x6B, 0, 0, 0, 0},
8101 {0x6C, 0, 0, 0, 0},
8102 {0x6D, 0x1, 0x1, 0, 0},
8103 {0x6E, 0, 0, 0, 0},
8104 {0x6F, 0, 0, 0, 0},
8105 {0x70, 0x60, 0x60, 0, 0},
8106 {0x71, 0x66, 0x66, 0, 0},
8107 {0x72, 0xc, 0xc, 0, 0},
8108 {0x73, 0x66, 0x66, 0, 0},
8109 {0x74, 0x8f, 0x8f, 1, 1},
8110 {0x75, 0, 0, 0, 0},
8111 {0x76, 0xcc, 0xcc, 0, 0},
8112 {0x77, 0x1, 0x1, 0, 0},
8113 {0x78, 0x66, 0x66, 0, 0},
8114 {0x79, 0x66, 0x66, 0, 0},
8115 {0x7A, 0, 0, 0, 0},
8116 {0x7B, 0, 0, 0, 0},
8117 {0x7C, 0, 0, 0, 0},
8118 {0x7D, 0, 0, 0, 0},
8119 {0x7E, 0, 0, 0, 0},
8120 {0x7F, 0, 0, 0, 0},
8121 {0x80, 0, 0, 0, 0},
8122 {0x81, 0, 0, 0, 0},
8123 {0x82, 0, 0, 0, 0},
8124 {0x83, 0, 0, 0, 0},
8125 {0x84, 0, 0, 0, 0},
8126 {0x85, 0xff, 0xff, 0, 0},
8127 {0x86, 0, 0, 0, 0},
8128 {0x87, 0, 0, 0, 0},
8129 {0x88, 0, 0, 0, 0},
8130 {0x89, 0, 0, 0, 0},
8131 {0x8A, 0, 0, 0, 0},
8132 {0x8B, 0, 0, 0, 0},
8133 {0x8C, 0, 0, 0, 0},
8134 {0x8D, 0, 0, 0, 0},
8135 {0x8E, 0, 0, 0, 0},
8136 {0x8F, 0, 0, 0, 0},
8137 {0x90, 0, 0, 0, 0},
8138 {0x91, 0, 0, 0, 0},
8139 {0x92, 0, 0, 0, 0},
8140 {0x93, 0, 0, 0, 0},
8141 {0x94, 0, 0, 0, 0},
8142 {0x95, 0, 0, 0, 0},
8143 {0x96, 0, 0, 0, 0},
8144 {0x97, 0, 0, 0, 0},
8145 {0x98, 0, 0, 0, 0},
8146 {0x99, 0, 0, 0, 0},
8147 {0x9A, 0, 0, 0, 0},
8148 {0x9B, 0, 0, 0, 0},
8149 {0x9C, 0, 0, 0, 0},
8150 {0x9D, 0, 0, 0, 0},
8151 {0x9E, 0, 0, 0, 0},
8152 {0x9F, 0x6, 0x6, 0, 0},
8153 {0xA0, 0x66, 0x66, 0, 0},
8154 {0xA1, 0x66, 0x66, 0, 0},
8155 {0xA2, 0x66, 0x66, 0, 0},
8156 {0xA3, 0x66, 0x66, 0, 0},
8157 {0xA4, 0x66, 0x66, 0, 0},
8158 {0xA5, 0x66, 0x66, 0, 0},
8159 {0xA6, 0x66, 0x66, 0, 0},
8160 {0xA7, 0x66, 0x66, 0, 0},
8161 {0xA8, 0x66, 0x66, 0, 0},
8162 {0xA9, 0x66, 0x66, 0, 0},
8163 {0xAA, 0x66, 0x66, 0, 0},
8164 {0xAB, 0x66, 0x66, 0, 0},
8165 {0xAC, 0x66, 0x66, 0, 0},
8166 {0xAD, 0x66, 0x66, 0, 0},
8167 {0xAE, 0x66, 0x66, 0, 0},
8168 {0xAF, 0x66, 0x66, 0, 0},
8169 {0xB0, 0x66, 0x66, 0, 0},
8170 {0xB1, 0x66, 0x66, 0, 0},
8171 {0xB2, 0x66, 0x66, 0, 0},
8172 {0xB3, 0xa, 0xa, 0, 0},
8173 {0xB4, 0, 0, 0, 0},
8174 {0xB5, 0, 0, 0, 0},
8175 {0xB6, 0, 0, 0, 0},
8176 {0xFFFF, 0, 0, 0, 0}
8177};
8178
8179static struct radio_regs regs_TX_2056[] = {
8180 {0x02, 0, 0, 0, 0},
8181 {0x03, 0, 0, 0, 0},
8182 {0x04, 0, 0, 0, 0},
8183 {0x05, 0, 0, 0, 0},
8184 {0x06, 0, 0, 0, 0},
8185 {0x07, 0, 0, 0, 0},
8186 {0x08, 0, 0, 0, 0},
8187 {0x09, 0, 0, 0, 0},
8188 {0x0A, 0, 0, 0, 0},
8189 {0x0B, 0, 0, 0, 0},
8190 {0x0C, 0, 0, 0, 0},
8191 {0x0D, 0, 0, 0, 0},
8192 {0x0E, 0, 0, 0, 0},
8193 {0x0F, 0, 0, 0, 0},
8194 {0x10, 0, 0, 0, 0},
8195 {0x11, 0, 0, 0, 0},
8196 {0x12, 0, 0, 0, 0},
8197 {0x13, 0, 0, 0, 0},
8198 {0x14, 0, 0, 0, 0},
8199 {0x15, 0, 0, 0, 0},
8200 {0x16, 0, 0, 0, 0},
8201 {0x17, 0, 0, 0, 0},
8202 {0x18, 0, 0, 0, 0},
8203 {0x19, 0, 0, 0, 0},
8204 {0x1A, 0, 0, 0, 0},
8205 {0x1B, 0, 0, 0, 0},
8206 {0x1C, 0, 0, 0, 0},
8207 {0x1D, 0, 0, 0, 0},
8208 {0x1E, 0, 0, 0, 0},
8209 {0x1F, 0, 0, 0, 0},
8210 {0x20, 0, 0, 0, 0},
8211 {0x21, 0x88, 0x88, 0, 0},
8212 {0x22, 0x88, 0x88, 0, 0},
8213 {0x23, 0x88, 0x88, 0, 0},
8214 {0x24, 0x88, 0x88, 0, 0},
8215 {0x25, 0xc, 0xc, 0, 0},
8216 {0x26, 0, 0, 0, 0},
8217 {0x27, 0x3, 0x3, 0, 0},
8218 {0x28, 0, 0, 0, 0},
8219 {0x29, 0x3, 0x3, 0, 0},
8220 {0x2A, 0x37, 0x37, 0, 0},
8221 {0x2B, 0x3, 0x3, 0, 0},
8222 {0x2C, 0, 0, 0, 0},
8223 {0x2D, 0, 0, 0, 0},
8224 {0x2E, 0x1, 0x1, 0, 0},
8225 {0x2F, 0x1, 0x1, 0, 0},
8226 {0x30, 0, 0, 0, 0},
8227 {0x31, 0, 0, 0, 0},
8228 {0x32, 0, 0, 0, 0},
8229 {0x33, 0x11, 0x11, 0, 0},
8230 {0x34, 0x11, 0x11, 0, 0},
8231 {0x35, 0, 0, 0, 0},
8232 {0x36, 0, 0, 0, 0},
8233 {0x37, 0x3, 0x3, 0, 0},
8234 {0x38, 0xf, 0xf, 0, 0},
8235 {0x39, 0, 0, 0, 0},
8236 {0x3A, 0x2d, 0x2d, 0, 0},
8237 {0x3B, 0, 0, 0, 0},
8238 {0x3C, 0x6e, 0x6e, 0, 0},
8239 {0x3D, 0xf0, 0xf0, 1, 1},
8240 {0x3E, 0, 0, 0, 0},
8241 {0x3F, 0, 0, 0, 0},
8242 {0x40, 0, 0, 0, 0},
8243 {0x41, 0x3, 0x3, 0, 0},
8244 {0x42, 0x3, 0x3, 0, 0},
8245 {0x43, 0, 0, 0, 0},
8246 {0x44, 0x1e, 0x1e, 0, 0},
8247 {0x45, 0, 0, 0, 0},
8248 {0x46, 0x6e, 0x6e, 0, 0},
8249 {0x47, 0xf0, 0xf0, 1, 1},
8250 {0x48, 0, 0, 0, 0},
8251 {0x49, 0x2, 0x2, 0, 0},
8252 {0x4A, 0xff, 0xff, 1, 1},
8253 {0x4B, 0xc, 0xc, 0, 0},
8254 {0x4C, 0, 0, 0, 0},
8255 {0x4D, 0x38, 0x38, 0, 0},
8256 {0x4E, 0x70, 0x70, 1, 1},
8257 {0x4F, 0x2, 0x2, 0, 0},
8258 {0x50, 0x88, 0x88, 0, 0},
8259 {0x51, 0xc, 0xc, 0, 0},
8260 {0x52, 0, 0, 0, 0},
8261 {0x53, 0x8, 0x8, 0, 0},
8262 {0x54, 0x70, 0x70, 1, 1},
8263 {0x55, 0x2, 0x2, 0, 0},
8264 {0x56, 0xff, 0xff, 1, 1},
8265 {0x57, 0, 0, 0, 0},
8266 {0x58, 0x83, 0x83, 0, 0},
8267 {0x59, 0x77, 0x77, 1, 1},
8268 {0x5A, 0, 0, 0, 0},
8269 {0x5B, 0x2, 0x2, 0, 0},
8270 {0x5C, 0x88, 0x88, 0, 0},
8271 {0x5D, 0, 0, 0, 0},
8272 {0x5E, 0x8, 0x8, 0, 0},
8273 {0x5F, 0x77, 0x77, 1, 1},
8274 {0x60, 0x1, 0x1, 0, 0},
8275 {0x61, 0, 0, 0, 0},
8276 {0x62, 0x7, 0x7, 0, 0},
8277 {0x63, 0, 0, 0, 0},
8278 {0x64, 0x7, 0x7, 0, 0},
8279 {0x65, 0, 0, 0, 0},
8280 {0x66, 0, 0, 0, 0},
8281 {0x67, 0x74, 0x74, 1, 1},
8282 {0x68, 0, 0, 0, 0},
8283 {0x69, 0xa, 0xa, 0, 0},
8284 {0x6A, 0, 0, 0, 0},
8285 {0x6B, 0, 0, 0, 0},
8286 {0x6C, 0, 0, 0, 0},
8287 {0x6D, 0, 0, 0, 0},
8288 {0x6E, 0, 0, 0, 0},
8289 {0x6F, 0, 0, 0, 0},
8290 {0x70, 0, 0, 0, 0},
8291 {0x71, 0x2, 0x2, 0, 0},
8292 {0x72, 0, 0, 0, 0},
8293 {0x73, 0, 0, 0, 0},
8294 {0x74, 0xe, 0xe, 0, 0},
8295 {0x75, 0xe, 0xe, 0, 0},
8296 {0x76, 0xe, 0xe, 0, 0},
8297 {0x77, 0x13, 0x13, 0, 0},
8298 {0x78, 0x13, 0x13, 0, 0},
8299 {0x79, 0x1b, 0x1b, 0, 0},
8300 {0x7A, 0x1b, 0x1b, 0, 0},
8301 {0x7B, 0x55, 0x55, 0, 0},
8302 {0x7C, 0x5b, 0x5b, 0, 0},
8303 {0x7D, 0, 0, 0, 0},
8304 {0x7E, 0, 0, 0, 0},
8305 {0x7F, 0, 0, 0, 0},
8306 {0x80, 0, 0, 0, 0},
8307 {0x81, 0, 0, 0, 0},
8308 {0x82, 0, 0, 0, 0},
8309 {0x83, 0, 0, 0, 0},
8310 {0x84, 0, 0, 0, 0},
8311 {0x85, 0, 0, 0, 0},
8312 {0x86, 0, 0, 0, 0},
8313 {0x87, 0, 0, 0, 0},
8314 {0x88, 0, 0, 0, 0},
8315 {0x89, 0, 0, 0, 0},
8316 {0x8A, 0, 0, 0, 0},
8317 {0x8B, 0, 0, 0, 0},
8318 {0x8C, 0, 0, 0, 0},
8319 {0x8D, 0, 0, 0, 0},
8320 {0x8E, 0, 0, 0, 0},
8321 {0x8F, 0, 0, 0, 0},
8322 {0x90, 0, 0, 0, 0},
8323 {0x91, 0, 0, 0, 0},
8324 {0x92, 0, 0, 0, 0},
8325 {0xFFFF, 0, 0, 0, 0}
8326};
8327
8328static struct radio_regs regs_RX_2056[] = {
8329 {0x02, 0, 0, 0, 0},
8330 {0x03, 0, 0, 0, 0},
8331 {0x04, 0, 0, 0, 0},
8332 {0x05, 0, 0, 0, 0},
8333 {0x06, 0, 0, 0, 0},
8334 {0x07, 0, 0, 0, 0},
8335 {0x08, 0, 0, 0, 0},
8336 {0x09, 0, 0, 0, 0},
8337 {0x0A, 0, 0, 0, 0},
8338 {0x0B, 0, 0, 0, 0},
8339 {0x0C, 0, 0, 0, 0},
8340 {0x0D, 0, 0, 0, 0},
8341 {0x0E, 0, 0, 0, 0},
8342 {0x0F, 0, 0, 0, 0},
8343 {0x10, 0, 0, 0, 0},
8344 {0x11, 0, 0, 0, 0},
8345 {0x12, 0, 0, 0, 0},
8346 {0x13, 0, 0, 0, 0},
8347 {0x14, 0, 0, 0, 0},
8348 {0x15, 0, 0, 0, 0},
8349 {0x16, 0, 0, 0, 0},
8350 {0x17, 0, 0, 0, 0},
8351 {0x18, 0, 0, 0, 0},
8352 {0x19, 0, 0, 0, 0},
8353 {0x1A, 0, 0, 0, 0},
8354 {0x1B, 0, 0, 0, 0},
8355 {0x1C, 0, 0, 0, 0},
8356 {0x1D, 0, 0, 0, 0},
8357 {0x1E, 0, 0, 0, 0},
8358 {0x1F, 0, 0, 0, 0},
8359 {0x20, 0x3, 0x3, 0, 0},
8360 {0x21, 0, 0, 0, 0},
8361 {0x22, 0, 0, 0, 0},
8362 {0x23, 0x90, 0x90, 0, 0},
8363 {0x24, 0x55, 0x55, 0, 0},
8364 {0x25, 0x15, 0x15, 0, 0},
8365 {0x26, 0x5, 0x5, 0, 0},
8366 {0x27, 0x15, 0x15, 0, 0},
8367 {0x28, 0x5, 0x5, 0, 0},
8368 {0x29, 0x20, 0x20, 0, 0},
8369 {0x2A, 0x11, 0x11, 0, 0},
8370 {0x2B, 0x90, 0x90, 0, 0},
8371 {0x2C, 0, 0, 0, 0},
8372 {0x2D, 0x88, 0x88, 0, 0},
8373 {0x2E, 0x32, 0x32, 0, 0},
8374 {0x2F, 0x77, 0x77, 0, 0},
8375 {0x30, 0x17, 0x17, 1, 1},
8376 {0x31, 0xff, 0xff, 1, 1},
8377 {0x32, 0x20, 0x20, 0, 0},
8378 {0x33, 0, 0, 0, 0},
8379 {0x34, 0x88, 0x88, 0, 0},
8380 {0x35, 0x32, 0x32, 0, 0},
8381 {0x36, 0x77, 0x77, 0, 0},
8382 {0x37, 0x17, 0x17, 1, 1},
8383 {0x38, 0xf0, 0xf0, 1, 1},
8384 {0x39, 0x20, 0x20, 0, 0},
8385 {0x3A, 0x8, 0x8, 0, 0},
8386 {0x3B, 0x99, 0x99, 0, 0},
8387 {0x3C, 0, 0, 0, 0},
8388 {0x3D, 0x44, 0x44, 1, 1},
8389 {0x3E, 0, 0, 0, 0},
8390 {0x3F, 0x44, 0x44, 0, 0},
8391 {0x40, 0xf, 0xf, 1, 1},
8392 {0x41, 0x6, 0x6, 0, 0},
8393 {0x42, 0x4, 0x4, 0, 0},
8394 {0x43, 0x50, 0x50, 1, 1},
8395 {0x44, 0x8, 0x8, 0, 0},
8396 {0x45, 0x99, 0x99, 0, 0},
8397 {0x46, 0, 0, 0, 0},
8398 {0x47, 0x11, 0x11, 0, 0},
8399 {0x48, 0, 0, 0, 0},
8400 {0x49, 0x44, 0x44, 0, 0},
8401 {0x4A, 0x7, 0x7, 0, 0},
8402 {0x4B, 0x6, 0x6, 0, 0},
8403 {0x4C, 0x4, 0x4, 0, 0},
8404 {0x4D, 0, 0, 0, 0},
8405 {0x4E, 0, 0, 0, 0},
8406 {0x4F, 0x66, 0x66, 0, 0},
8407 {0x50, 0x66, 0x66, 0, 0},
8408 {0x51, 0x57, 0x57, 0, 0},
8409 {0x52, 0x57, 0x57, 0, 0},
8410 {0x53, 0x44, 0x44, 0, 0},
8411 {0x54, 0, 0, 0, 0},
8412 {0x55, 0, 0, 0, 0},
8413 {0x56, 0x8, 0x8, 0, 0},
8414 {0x57, 0x8, 0x8, 0, 0},
8415 {0x58, 0x7, 0x7, 0, 0},
8416 {0x59, 0x22, 0x22, 0, 0},
8417 {0x5A, 0x22, 0x22, 0, 0},
8418 {0x5B, 0x2, 0x2, 0, 0},
8419 {0x5C, 0x23, 0x23, 0, 0},
8420 {0x5D, 0x7, 0x7, 0, 0},
8421 {0x5E, 0x55, 0x55, 0, 0},
8422 {0x5F, 0x23, 0x23, 0, 0},
8423 {0x60, 0x41, 0x41, 0, 0},
8424 {0x61, 0x1, 0x1, 0, 0},
8425 {0x62, 0xa, 0xa, 0, 0},
8426 {0x63, 0, 0, 0, 0},
8427 {0x64, 0, 0, 0, 0},
8428 {0x65, 0, 0, 0, 0},
8429 {0x66, 0, 0, 0, 0},
8430 {0x67, 0, 0, 0, 0},
8431 {0x68, 0, 0, 0, 0},
8432 {0x69, 0, 0, 0, 0},
8433 {0x6A, 0, 0, 0, 0},
8434 {0x6B, 0xc, 0xc, 0, 0},
8435 {0x6C, 0, 0, 0, 0},
8436 {0x6D, 0, 0, 0, 0},
8437 {0x6E, 0, 0, 0, 0},
8438 {0x6F, 0, 0, 0, 0},
8439 {0x70, 0, 0, 0, 0},
8440 {0x71, 0, 0, 0, 0},
8441 {0x72, 0x22, 0x22, 0, 0},
8442 {0x73, 0x22, 0x22, 0, 0},
8443 {0x74, 0x2, 0x2, 0, 0},
8444 {0x75, 0xa, 0xa, 0, 0},
8445 {0x76, 0x1, 0x1, 0, 0},
8446 {0x77, 0x22, 0x22, 0, 0},
8447 {0x78, 0x30, 0x30, 0, 0},
8448 {0x79, 0, 0, 0, 0},
8449 {0x7A, 0, 0, 0, 0},
8450 {0x7B, 0, 0, 0, 0},
8451 {0x7C, 0, 0, 0, 0},
8452 {0x7D, 0, 0, 0, 0},
8453 {0x7E, 0, 0, 0, 0},
8454 {0x7F, 0, 0, 0, 0},
8455 {0x80, 0, 0, 0, 0},
8456 {0x81, 0, 0, 0, 0},
8457 {0x82, 0, 0, 0, 0},
8458 {0x83, 0, 0, 0, 0},
8459 {0x84, 0, 0, 0, 0},
8460 {0x85, 0, 0, 0, 0},
8461 {0x86, 0, 0, 0, 0},
8462 {0x87, 0, 0, 0, 0},
8463 {0x88, 0, 0, 0, 0},
8464 {0x89, 0, 0, 0, 0},
8465 {0x8A, 0, 0, 0, 0},
8466 {0x8B, 0, 0, 0, 0},
8467 {0x8C, 0, 0, 0, 0},
8468 {0x8D, 0, 0, 0, 0},
8469 {0x8E, 0, 0, 0, 0},
8470 {0x8F, 0, 0, 0, 0},
8471 {0x90, 0, 0, 0, 0},
8472 {0x91, 0, 0, 0, 0},
8473 {0x92, 0, 0, 0, 0},
8474 {0x93, 0, 0, 0, 0},
8475 {0x94, 0, 0, 0, 0},
8476 {0xFFFF, 0, 0, 0, 0}
8477};
8478
8479static struct radio_regs regs_SYN_2056_A1[] = {
8480 {0x02, 0, 0, 0, 0},
8481 {0x03, 0, 0, 0, 0},
8482 {0x04, 0, 0, 0, 0},
8483 {0x05, 0, 0, 0, 0},
8484 {0x06, 0, 0, 0, 0},
8485 {0x07, 0, 0, 0, 0},
8486 {0x08, 0, 0, 0, 0},
8487 {0x09, 0x1, 0x1, 0, 0},
8488 {0x0A, 0, 0, 0, 0},
8489 {0x0B, 0, 0, 0, 0},
8490 {0x0C, 0, 0, 0, 0},
8491 {0x0D, 0, 0, 0, 0},
8492 {0x0E, 0, 0, 0, 0},
8493 {0x0F, 0, 0, 0, 0},
8494 {0x10, 0, 0, 0, 0},
8495 {0x11, 0, 0, 0, 0},
8496 {0x12, 0, 0, 0, 0},
8497 {0x13, 0, 0, 0, 0},
8498 {0x14, 0, 0, 0, 0},
8499 {0x15, 0, 0, 0, 0},
8500 {0x16, 0, 0, 0, 0},
8501 {0x17, 0, 0, 0, 0},
8502 {0x18, 0, 0, 0, 0},
8503 {0x19, 0, 0, 0, 0},
8504 {0x1A, 0, 0, 0, 0},
8505 {0x1B, 0, 0, 0, 0},
8506 {0x1C, 0, 0, 0, 0},
8507 {0x1D, 0, 0, 0, 0},
8508 {0x1E, 0, 0, 0, 0},
8509 {0x1F, 0, 0, 0, 0},
8510 {0x20, 0, 0, 0, 0},
8511 {0x21, 0, 0, 0, 0},
8512 {0x22, 0x60, 0x60, 0, 0},
8513 {0x23, 0x6, 0x6, 0, 0},
8514 {0x24, 0xc, 0xc, 0, 0},
8515 {0x25, 0, 0, 0, 0},
8516 {0x26, 0, 0, 0, 0},
8517 {0x27, 0, 0, 0, 0},
8518 {0x28, 0x1, 0x1, 0, 0},
8519 {0x29, 0, 0, 0, 0},
8520 {0x2A, 0, 0, 0, 0},
8521 {0x2B, 0, 0, 0, 0},
8522 {0x2C, 0, 0, 0, 0},
8523 {0x2D, 0, 0, 0, 0},
8524 {0x2E, 0xd, 0xd, 0, 0},
8525 {0x2F, 0x1f, 0x1f, 0, 0},
8526 {0x30, 0x15, 0x15, 0, 0},
8527 {0x31, 0xf, 0xf, 0, 0},
8528 {0x32, 0, 0, 0, 0},
8529 {0x33, 0, 0, 0, 0},
8530 {0x34, 0, 0, 0, 0},
8531 {0x35, 0, 0, 0, 0},
8532 {0x36, 0, 0, 0, 0},
8533 {0x37, 0, 0, 0, 0},
8534 {0x38, 0, 0, 0, 0},
8535 {0x39, 0, 0, 0, 0},
8536 {0x3A, 0, 0, 0, 0},
8537 {0x3B, 0, 0, 0, 0},
8538 {0x3C, 0x13, 0x13, 0, 0},
8539 {0x3D, 0xf, 0xf, 0, 0},
8540 {0x3E, 0x18, 0x18, 0, 0},
8541 {0x3F, 0, 0, 0, 0},
8542 {0x40, 0, 0, 0, 0},
8543 {0x41, 0x20, 0x20, 0, 0},
8544 {0x42, 0x20, 0x20, 0, 0},
8545 {0x43, 0, 0, 0, 0},
8546 {0x44, 0x77, 0x77, 0, 0},
8547 {0x45, 0x7, 0x7, 0, 0},
8548 {0x46, 0x1, 0x1, 0, 0},
8549 {0x47, 0x4, 0x4, 0, 0},
8550 {0x48, 0xf, 0xf, 0, 0},
8551 {0x49, 0x30, 0x30, 0, 0},
8552 {0x4A, 0x32, 0x32, 0, 0},
8553 {0x4B, 0xd, 0xd, 0, 0},
8554 {0x4C, 0xd, 0xd, 0, 0},
8555 {0x4D, 0x4, 0x4, 0, 0},
8556 {0x4E, 0x6, 0x6, 0, 0},
8557 {0x4F, 0x1, 0x1, 0, 0},
8558 {0x50, 0x1c, 0x1c, 0, 0},
8559 {0x51, 0x2, 0x2, 0, 0},
8560 {0x52, 0x2, 0x2, 0, 0},
8561 {0x53, 0xf7, 0xf7, 1, 1},
8562 {0x54, 0xb4, 0xb4, 0, 0},
8563 {0x55, 0xd2, 0xd2, 0, 0},
8564 {0x56, 0, 0, 0, 0},
8565 {0x57, 0, 0, 0, 0},
8566 {0x58, 0x4, 0x4, 0, 0},
8567 {0x59, 0x96, 0x96, 0, 0},
8568 {0x5A, 0x3e, 0x3e, 0, 0},
8569 {0x5B, 0x3e, 0x3e, 0, 0},
8570 {0x5C, 0x13, 0x13, 0, 0},
8571 {0x5D, 0x2, 0x2, 0, 0},
8572 {0x5E, 0, 0, 0, 0},
8573 {0x5F, 0x7, 0x7, 0, 0},
8574 {0x60, 0x7, 0x7, 1, 1},
8575 {0x61, 0x8, 0x8, 0, 0},
8576 {0x62, 0x3, 0x3, 0, 0},
8577 {0x63, 0, 0, 0, 0},
8578 {0x64, 0, 0, 0, 0},
8579 {0x65, 0, 0, 0, 0},
8580 {0x66, 0, 0, 0, 0},
8581 {0x67, 0, 0, 0, 0},
8582 {0x68, 0x40, 0x40, 0, 0},
8583 {0x69, 0, 0, 0, 0},
8584 {0x6A, 0, 0, 0, 0},
8585 {0x6B, 0, 0, 0, 0},
8586 {0x6C, 0, 0, 0, 0},
8587 {0x6D, 0x1, 0x1, 0, 0},
8588 {0x6E, 0, 0, 0, 0},
8589 {0x6F, 0, 0, 0, 0},
8590 {0x70, 0x60, 0x60, 0, 0},
8591 {0x71, 0x66, 0x66, 0, 0},
8592 {0x72, 0xc, 0xc, 0, 0},
8593 {0x73, 0x66, 0x66, 0, 0},
8594 {0x74, 0x8f, 0x8f, 1, 1},
8595 {0x75, 0, 0, 0, 0},
8596 {0x76, 0xcc, 0xcc, 0, 0},
8597 {0x77, 0x1, 0x1, 0, 0},
8598 {0x78, 0x66, 0x66, 0, 0},
8599 {0x79, 0x66, 0x66, 0, 0},
8600 {0x7A, 0, 0, 0, 0},
8601 {0x7B, 0, 0, 0, 0},
8602 {0x7C, 0, 0, 0, 0},
8603 {0x7D, 0, 0, 0, 0},
8604 {0x7E, 0, 0, 0, 0},
8605 {0x7F, 0, 0, 0, 0},
8606 {0x80, 0, 0, 0, 0},
8607 {0x81, 0, 0, 0, 0},
8608 {0x82, 0, 0, 0, 0},
8609 {0x83, 0, 0, 0, 0},
8610 {0x84, 0, 0, 0, 0},
8611 {0x85, 0xff, 0xff, 0, 0},
8612 {0x86, 0, 0, 0, 0},
8613 {0x87, 0, 0, 0, 0},
8614 {0x88, 0, 0, 0, 0},
8615 {0x89, 0, 0, 0, 0},
8616 {0x8A, 0, 0, 0, 0},
8617 {0x8B, 0, 0, 0, 0},
8618 {0x8C, 0, 0, 0, 0},
8619 {0x8D, 0, 0, 0, 0},
8620 {0x8E, 0, 0, 0, 0},
8621 {0x8F, 0, 0, 0, 0},
8622 {0x90, 0, 0, 0, 0},
8623 {0x91, 0, 0, 0, 0},
8624 {0x92, 0, 0, 0, 0},
8625 {0x93, 0, 0, 0, 0},
8626 {0x94, 0, 0, 0, 0},
8627 {0x95, 0, 0, 0, 0},
8628 {0x96, 0, 0, 0, 0},
8629 {0x97, 0, 0, 0, 0},
8630 {0x98, 0, 0, 0, 0},
8631 {0x99, 0, 0, 0, 0},
8632 {0x9A, 0, 0, 0, 0},
8633 {0x9B, 0, 0, 0, 0},
8634 {0x9C, 0, 0, 0, 0},
8635 {0x9D, 0, 0, 0, 0},
8636 {0x9E, 0, 0, 0, 0},
8637 {0x9F, 0x6, 0x6, 0, 0},
8638 {0xA0, 0x66, 0x66, 0, 0},
8639 {0xA1, 0x66, 0x66, 0, 0},
8640 {0xA2, 0x66, 0x66, 0, 0},
8641 {0xA3, 0x66, 0x66, 0, 0},
8642 {0xA4, 0x66, 0x66, 0, 0},
8643 {0xA5, 0x66, 0x66, 0, 0},
8644 {0xA6, 0x66, 0x66, 0, 0},
8645 {0xA7, 0x66, 0x66, 0, 0},
8646 {0xA8, 0x66, 0x66, 0, 0},
8647 {0xA9, 0x66, 0x66, 0, 0},
8648 {0xAA, 0x66, 0x66, 0, 0},
8649 {0xAB, 0x66, 0x66, 0, 0},
8650 {0xAC, 0x66, 0x66, 0, 0},
8651 {0xAD, 0x66, 0x66, 0, 0},
8652 {0xAE, 0x66, 0x66, 0, 0},
8653 {0xAF, 0x66, 0x66, 0, 0},
8654 {0xB0, 0x66, 0x66, 0, 0},
8655 {0xB1, 0x66, 0x66, 0, 0},
8656 {0xB2, 0x66, 0x66, 0, 0},
8657 {0xB3, 0xa, 0xa, 0, 0},
8658 {0xB4, 0, 0, 0, 0},
8659 {0xB5, 0, 0, 0, 0},
8660 {0xB6, 0, 0, 0, 0},
8661 {0xFFFF, 0, 0, 0, 0}
8662};
8663
8664static struct radio_regs regs_TX_2056_A1[] = {
8665 {0x02, 0, 0, 0, 0},
8666 {0x03, 0, 0, 0, 0},
8667 {0x04, 0, 0, 0, 0},
8668 {0x05, 0, 0, 0, 0},
8669 {0x06, 0, 0, 0, 0},
8670 {0x07, 0, 0, 0, 0},
8671 {0x08, 0, 0, 0, 0},
8672 {0x09, 0, 0, 0, 0},
8673 {0x0A, 0, 0, 0, 0},
8674 {0x0B, 0, 0, 0, 0},
8675 {0x0C, 0, 0, 0, 0},
8676 {0x0D, 0, 0, 0, 0},
8677 {0x0E, 0, 0, 0, 0},
8678 {0x0F, 0, 0, 0, 0},
8679 {0x10, 0, 0, 0, 0},
8680 {0x11, 0, 0, 0, 0},
8681 {0x12, 0, 0, 0, 0},
8682 {0x13, 0, 0, 0, 0},
8683 {0x14, 0, 0, 0, 0},
8684 {0x15, 0, 0, 0, 0},
8685 {0x16, 0, 0, 0, 0},
8686 {0x17, 0, 0, 0, 0},
8687 {0x18, 0, 0, 0, 0},
8688 {0x19, 0, 0, 0, 0},
8689 {0x1A, 0, 0, 0, 0},
8690 {0x1B, 0, 0, 0, 0},
8691 {0x1C, 0, 0, 0, 0},
8692 {0x1D, 0, 0, 0, 0},
8693 {0x1E, 0, 0, 0, 0},
8694 {0x1F, 0, 0, 0, 0},
8695 {0x20, 0, 0, 0, 0},
8696 {0x21, 0x88, 0x88, 0, 0},
8697 {0x22, 0x88, 0x88, 0, 0},
8698 {0x23, 0x88, 0x88, 0, 0},
8699 {0x24, 0x88, 0x88, 0, 0},
8700 {0x25, 0xc, 0xc, 0, 0},
8701 {0x26, 0, 0, 0, 0},
8702 {0x27, 0x3, 0x3, 0, 0},
8703 {0x28, 0, 0, 0, 0},
8704 {0x29, 0x3, 0x3, 0, 0},
8705 {0x2A, 0x37, 0x37, 0, 0},
8706 {0x2B, 0x3, 0x3, 0, 0},
8707 {0x2C, 0, 0, 0, 0},
8708 {0x2D, 0, 0, 0, 0},
8709 {0x2E, 0x1, 0x1, 0, 0},
8710 {0x2F, 0x1, 0x1, 0, 0},
8711 {0x30, 0, 0, 0, 0},
8712 {0x31, 0, 0, 0, 0},
8713 {0x32, 0, 0, 0, 0},
8714 {0x33, 0x11, 0x11, 0, 0},
8715 {0x34, 0x11, 0x11, 0, 0},
8716 {0x35, 0, 0, 0, 0},
8717 {0x36, 0, 0, 0, 0},
8718 {0x37, 0x3, 0x3, 0, 0},
8719 {0x38, 0xf, 0xf, 0, 0},
8720 {0x39, 0, 0, 0, 0},
8721 {0x3A, 0x2d, 0x2d, 0, 0},
8722 {0x3B, 0, 0, 0, 0},
8723 {0x3C, 0x6e, 0x6e, 0, 0},
8724 {0x3D, 0xf0, 0xf0, 1, 1},
8725 {0x3E, 0, 0, 0, 0},
8726 {0x3F, 0, 0, 0, 0},
8727 {0x40, 0, 0, 0, 0},
8728 {0x41, 0x3, 0x3, 0, 0},
8729 {0x42, 0x3, 0x3, 0, 0},
8730 {0x43, 0, 0, 0, 0},
8731 {0x44, 0x1e, 0x1e, 0, 0},
8732 {0x45, 0, 0, 0, 0},
8733 {0x46, 0x6e, 0x6e, 0, 0},
8734 {0x47, 0xf0, 0xf0, 1, 1},
8735 {0x48, 0, 0, 0, 0},
8736 {0x49, 0x2, 0x2, 0, 0},
8737 {0x4A, 0xff, 0xff, 1, 1},
8738 {0x4B, 0xc, 0xc, 0, 0},
8739 {0x4C, 0, 0, 0, 0},
8740 {0x4D, 0x38, 0x38, 0, 0},
8741 {0x4E, 0x70, 0x70, 1, 1},
8742 {0x4F, 0x2, 0x2, 0, 0},
8743 {0x50, 0x88, 0x88, 0, 0},
8744 {0x51, 0xc, 0xc, 0, 0},
8745 {0x52, 0, 0, 0, 0},
8746 {0x53, 0x8, 0x8, 0, 0},
8747 {0x54, 0x70, 0x70, 1, 1},
8748 {0x55, 0x2, 0x2, 0, 0},
8749 {0x56, 0xff, 0xff, 1, 1},
8750 {0x57, 0, 0, 0, 0},
8751 {0x58, 0x83, 0x83, 0, 0},
8752 {0x59, 0x77, 0x77, 1, 1},
8753 {0x5A, 0, 0, 0, 0},
8754 {0x5B, 0x2, 0x2, 0, 0},
8755 {0x5C, 0x88, 0x88, 0, 0},
8756 {0x5D, 0, 0, 0, 0},
8757 {0x5E, 0x8, 0x8, 0, 0},
8758 {0x5F, 0x77, 0x77, 1, 1},
8759 {0x60, 0x1, 0x1, 0, 0},
8760 {0x61, 0, 0, 0, 0},
8761 {0x62, 0x7, 0x7, 0, 0},
8762 {0x63, 0, 0, 0, 0},
8763 {0x64, 0x7, 0x7, 0, 0},
8764 {0x65, 0, 0, 0, 0},
8765 {0x66, 0, 0, 0, 0},
8766 {0x67, 0x72, 0x72, 1, 1},
8767 {0x68, 0, 0, 0, 0},
8768 {0x69, 0xa, 0xa, 0, 0},
8769 {0x6A, 0, 0, 0, 0},
8770 {0x6B, 0, 0, 0, 0},
8771 {0x6C, 0, 0, 0, 0},
8772 {0x6D, 0, 0, 0, 0},
8773 {0x6E, 0, 0, 0, 0},
8774 {0x6F, 0, 0, 0, 0},
8775 {0x70, 0, 0, 0, 0},
8776 {0x71, 0x2, 0x2, 0, 0},
8777 {0x72, 0, 0, 0, 0},
8778 {0x73, 0, 0, 0, 0},
8779 {0x74, 0xe, 0xe, 0, 0},
8780 {0x75, 0xe, 0xe, 0, 0},
8781 {0x76, 0xe, 0xe, 0, 0},
8782 {0x77, 0x13, 0x13, 0, 0},
8783 {0x78, 0x13, 0x13, 0, 0},
8784 {0x79, 0x1b, 0x1b, 0, 0},
8785 {0x7A, 0x1b, 0x1b, 0, 0},
8786 {0x7B, 0x55, 0x55, 0, 0},
8787 {0x7C, 0x5b, 0x5b, 0, 0},
8788 {0x7D, 0, 0, 0, 0},
8789 {0x7E, 0, 0, 0, 0},
8790 {0x7F, 0, 0, 0, 0},
8791 {0x80, 0, 0, 0, 0},
8792 {0x81, 0, 0, 0, 0},
8793 {0x82, 0, 0, 0, 0},
8794 {0x83, 0, 0, 0, 0},
8795 {0x84, 0, 0, 0, 0},
8796 {0x85, 0, 0, 0, 0},
8797 {0x86, 0, 0, 0, 0},
8798 {0x87, 0, 0, 0, 0},
8799 {0x88, 0, 0, 0, 0},
8800 {0x89, 0, 0, 0, 0},
8801 {0x8A, 0, 0, 0, 0},
8802 {0x8B, 0, 0, 0, 0},
8803 {0x8C, 0, 0, 0, 0},
8804 {0x8D, 0, 0, 0, 0},
8805 {0x8E, 0, 0, 0, 0},
8806 {0x8F, 0, 0, 0, 0},
8807 {0x90, 0, 0, 0, 0},
8808 {0x91, 0, 0, 0, 0},
8809 {0x92, 0, 0, 0, 0},
8810 {0xFFFF, 0, 0, 0, 0}
8811};
8812
8813static struct radio_regs regs_RX_2056_A1[] = {
8814 {0x02, 0, 0, 0, 0},
8815 {0x03, 0, 0, 0, 0},
8816 {0x04, 0, 0, 0, 0},
8817 {0x05, 0, 0, 0, 0},
8818 {0x06, 0, 0, 0, 0},
8819 {0x07, 0, 0, 0, 0},
8820 {0x08, 0, 0, 0, 0},
8821 {0x09, 0, 0, 0, 0},
8822 {0x0A, 0, 0, 0, 0},
8823 {0x0B, 0, 0, 0, 0},
8824 {0x0C, 0, 0, 0, 0},
8825 {0x0D, 0, 0, 0, 0},
8826 {0x0E, 0, 0, 0, 0},
8827 {0x0F, 0, 0, 0, 0},
8828 {0x10, 0, 0, 0, 0},
8829 {0x11, 0, 0, 0, 0},
8830 {0x12, 0, 0, 0, 0},
8831 {0x13, 0, 0, 0, 0},
8832 {0x14, 0, 0, 0, 0},
8833 {0x15, 0, 0, 0, 0},
8834 {0x16, 0, 0, 0, 0},
8835 {0x17, 0, 0, 0, 0},
8836 {0x18, 0, 0, 0, 0},
8837 {0x19, 0, 0, 0, 0},
8838 {0x1A, 0, 0, 0, 0},
8839 {0x1B, 0, 0, 0, 0},
8840 {0x1C, 0, 0, 0, 0},
8841 {0x1D, 0, 0, 0, 0},
8842 {0x1E, 0, 0, 0, 0},
8843 {0x1F, 0, 0, 0, 0},
8844 {0x20, 0x3, 0x3, 0, 0},
8845 {0x21, 0, 0, 0, 0},
8846 {0x22, 0, 0, 0, 0},
8847 {0x23, 0x90, 0x90, 0, 0},
8848 {0x24, 0x55, 0x55, 0, 0},
8849 {0x25, 0x15, 0x15, 0, 0},
8850 {0x26, 0x5, 0x5, 0, 0},
8851 {0x27, 0x15, 0x15, 0, 0},
8852 {0x28, 0x5, 0x5, 0, 0},
8853 {0x29, 0x20, 0x20, 0, 0},
8854 {0x2A, 0x11, 0x11, 0, 0},
8855 {0x2B, 0x90, 0x90, 0, 0},
8856 {0x2C, 0, 0, 0, 0},
8857 {0x2D, 0x88, 0x88, 0, 0},
8858 {0x2E, 0x32, 0x32, 0, 0},
8859 {0x2F, 0x77, 0x77, 0, 0},
8860 {0x30, 0x17, 0x17, 1, 1},
8861 {0x31, 0xff, 0xff, 1, 1},
8862 {0x32, 0x20, 0x20, 0, 0},
8863 {0x33, 0, 0, 0, 0},
8864 {0x34, 0x88, 0x88, 0, 0},
8865 {0x35, 0x32, 0x32, 0, 0},
8866 {0x36, 0x77, 0x77, 0, 0},
8867 {0x37, 0x17, 0x17, 1, 1},
8868 {0x38, 0xf0, 0xf0, 1, 1},
8869 {0x39, 0x20, 0x20, 0, 0},
8870 {0x3A, 0x8, 0x8, 0, 0},
8871 {0x3B, 0x55, 0x55, 1, 1},
8872 {0x3C, 0, 0, 0, 0},
8873 {0x3D, 0x44, 0x44, 1, 1},
8874 {0x3E, 0, 0, 0, 0},
8875 {0x3F, 0x44, 0x44, 0, 0},
8876 {0x40, 0xf, 0xf, 1, 1},
8877 {0x41, 0x6, 0x6, 0, 0},
8878 {0x42, 0x4, 0x4, 0, 0},
8879 {0x43, 0x50, 0x50, 1, 1},
8880 {0x44, 0x8, 0x8, 0, 0},
8881 {0x45, 0x55, 0x55, 1, 1},
8882 {0x46, 0, 0, 0, 0},
8883 {0x47, 0x11, 0x11, 0, 0},
8884 {0x48, 0, 0, 0, 0},
8885 {0x49, 0x44, 0x44, 0, 0},
8886 {0x4A, 0x7, 0x7, 0, 0},
8887 {0x4B, 0x6, 0x6, 0, 0},
8888 {0x4C, 0x4, 0x4, 0, 0},
8889 {0x4D, 0, 0, 0, 0},
8890 {0x4E, 0, 0, 0, 0},
8891 {0x4F, 0x26, 0x26, 1, 1},
8892 {0x50, 0x26, 0x26, 1, 1},
8893 {0x51, 0xf, 0xf, 1, 1},
8894 {0x52, 0xf, 0xf, 1, 1},
8895 {0x53, 0x44, 0x44, 0, 0},
8896 {0x54, 0, 0, 0, 0},
8897 {0x55, 0, 0, 0, 0},
8898 {0x56, 0x8, 0x8, 0, 0},
8899 {0x57, 0x8, 0x8, 0, 0},
8900 {0x58, 0x7, 0x7, 0, 0},
8901 {0x59, 0x22, 0x22, 0, 0},
8902 {0x5A, 0x22, 0x22, 0, 0},
8903 {0x5B, 0x2, 0x2, 0, 0},
8904 {0x5C, 0x2f, 0x2f, 1, 1},
8905 {0x5D, 0x7, 0x7, 0, 0},
8906 {0x5E, 0x55, 0x55, 0, 0},
8907 {0x5F, 0x23, 0x23, 0, 0},
8908 {0x60, 0x41, 0x41, 0, 0},
8909 {0x61, 0x1, 0x1, 0, 0},
8910 {0x62, 0xa, 0xa, 0, 0},
8911 {0x63, 0, 0, 0, 0},
8912 {0x64, 0, 0, 0, 0},
8913 {0x65, 0, 0, 0, 0},
8914 {0x66, 0, 0, 0, 0},
8915 {0x67, 0, 0, 0, 0},
8916 {0x68, 0, 0, 0, 0},
8917 {0x69, 0, 0, 0, 0},
8918 {0x6A, 0, 0, 0, 0},
8919 {0x6B, 0xc, 0xc, 0, 0},
8920 {0x6C, 0, 0, 0, 0},
8921 {0x6D, 0, 0, 0, 0},
8922 {0x6E, 0, 0, 0, 0},
8923 {0x6F, 0, 0, 0, 0},
8924 {0x70, 0, 0, 0, 0},
8925 {0x71, 0, 0, 0, 0},
8926 {0x72, 0x22, 0x22, 0, 0},
8927 {0x73, 0x22, 0x22, 0, 0},
8928 {0x74, 0, 0, 1, 1},
8929 {0x75, 0xa, 0xa, 0, 0},
8930 {0x76, 0x1, 0x1, 0, 0},
8931 {0x77, 0x22, 0x22, 0, 0},
8932 {0x78, 0x30, 0x30, 0, 0},
8933 {0x79, 0, 0, 0, 0},
8934 {0x7A, 0, 0, 0, 0},
8935 {0x7B, 0, 0, 0, 0},
8936 {0x7C, 0, 0, 0, 0},
8937 {0x7D, 0, 0, 0, 0},
8938 {0x7E, 0, 0, 0, 0},
8939 {0x7F, 0, 0, 0, 0},
8940 {0x80, 0, 0, 0, 0},
8941 {0x81, 0, 0, 0, 0},
8942 {0x82, 0, 0, 0, 0},
8943 {0x83, 0, 0, 0, 0},
8944 {0x84, 0, 0, 0, 0},
8945 {0x85, 0, 0, 0, 0},
8946 {0x86, 0, 0, 0, 0},
8947 {0x87, 0, 0, 0, 0},
8948 {0x88, 0, 0, 0, 0},
8949 {0x89, 0, 0, 0, 0},
8950 {0x8A, 0, 0, 0, 0},
8951 {0x8B, 0, 0, 0, 0},
8952 {0x8C, 0, 0, 0, 0},
8953 {0x8D, 0, 0, 0, 0},
8954 {0x8E, 0, 0, 0, 0},
8955 {0x8F, 0, 0, 0, 0},
8956 {0x90, 0, 0, 0, 0},
8957 {0x91, 0, 0, 0, 0},
8958 {0x92, 0, 0, 0, 0},
8959 {0x93, 0, 0, 0, 0},
8960 {0x94, 0, 0, 0, 0},
8961 {0xFFFF, 0, 0, 0, 0}
8962};
8963
8964static struct radio_regs regs_SYN_2056_rev5[] = {
8965 {0x02, 0, 0, 0, 0},
8966 {0x03, 0, 0, 0, 0},
8967 {0x04, 0, 0, 0, 0},
8968 {0x05, 0, 0, 0, 0},
8969 {0x06, 0, 0, 0, 0},
8970 {0x07, 0, 0, 0, 0},
8971 {0x08, 0, 0, 0, 0},
8972 {0x09, 0x1, 0x1, 0, 0},
8973 {0x0A, 0, 0, 0, 0},
8974 {0x0B, 0, 0, 0, 0},
8975 {0x0C, 0, 0, 0, 0},
8976 {0x0D, 0, 0, 0, 0},
8977 {0x0E, 0, 0, 0, 0},
8978 {0x0F, 0, 0, 0, 0},
8979 {0x10, 0, 0, 0, 0},
8980 {0x11, 0, 0, 0, 0},
8981 {0x12, 0, 0, 0, 0},
8982 {0x13, 0, 0, 0, 0},
8983 {0x14, 0, 0, 0, 0},
8984 {0x15, 0, 0, 0, 0},
8985 {0x16, 0, 0, 0, 0},
8986 {0x17, 0, 0, 0, 0},
8987 {0x18, 0, 0, 0, 0},
8988 {0x19, 0, 0, 0, 0},
8989 {0x1A, 0, 0, 0, 0},
8990 {0x1B, 0, 0, 0, 0},
8991 {0x1C, 0, 0, 0, 0},
8992 {0x1D, 0, 0, 0, 0},
8993 {0x1E, 0, 0, 0, 0},
8994 {0x1F, 0, 0, 0, 0},
8995 {0x20, 0, 0, 0, 0},
8996 {0x21, 0, 0, 0, 0},
8997 {0x22, 0x60, 0x60, 0, 0},
8998 {0x23, 0x6, 0x6, 0, 0},
8999 {0x24, 0xc, 0xc, 0, 0},
9000 {0x25, 0, 0, 0, 0},
9001 {0x26, 0, 0, 0, 0},
9002 {0x27, 0, 0, 0, 0},
9003 {0x28, 0x1, 0x1, 0, 0},
9004 {0x29, 0, 0, 0, 0},
9005 {0x2A, 0, 0, 0, 0},
9006 {0x2B, 0, 0, 0, 0},
9007 {0x2C, 0, 0, 0, 0},
9008 {0x2D, 0, 0, 0, 0},
9009 {0x2E, 0, 0, 0, 0},
9010 {0x2F, 0x1f, 0x1f, 0, 0},
9011 {0x30, 0x15, 0x15, 0, 0},
9012 {0x31, 0xf, 0xf, 0, 0},
9013 {0x32, 0, 0, 0, 0},
9014 {0x33, 0, 0, 0, 0},
9015 {0x34, 0, 0, 0, 0},
9016 {0x35, 0, 0, 0, 0},
9017 {0x36, 0, 0, 0, 0},
9018 {0x37, 0, 0, 0, 0},
9019 {0x38, 0, 0, 0, 0},
9020 {0x39, 0, 0, 0, 0},
9021 {0x3A, 0, 0, 0, 0},
9022 {0x3B, 0, 0, 0, 0},
9023 {0x3C, 0x13, 0x13, 0, 0},
9024 {0x3D, 0xf, 0xf, 0, 0},
9025 {0x3E, 0x18, 0x18, 0, 0},
9026 {0x3F, 0, 0, 0, 0},
9027 {0x40, 0, 0, 0, 0},
9028 {0x41, 0x20, 0x20, 0, 0},
9029 {0x42, 0x20, 0x20, 0, 0},
9030 {0x43, 0, 0, 0, 0},
9031 {0x44, 0x77, 0x77, 0, 0},
9032 {0x45, 0x7, 0x7, 0, 0},
9033 {0x46, 0x1, 0x1, 0, 0},
9034 {0x47, 0x4, 0x4, 0, 0},
9035 {0x48, 0xf, 0xf, 0, 0},
9036 {0x49, 0x30, 0x30, 0, 0},
9037 {0x4A, 0x32, 0x32, 0, 0},
9038 {0x4B, 0xd, 0xd, 0, 0},
9039 {0x4C, 0xd, 0xd, 0, 0},
9040 {0x4D, 0x4, 0x4, 0, 0},
9041 {0x4E, 0x6, 0x6, 0, 0},
9042 {0x4F, 0x1, 0x1, 0, 0},
9043 {0x50, 0x1c, 0x1c, 0, 0},
9044 {0x51, 0x2, 0x2, 0, 0},
9045 {0x52, 0x2, 0x2, 0, 0},
9046 {0x53, 0xf7, 0xf7, 1, 1},
9047 {0x54, 0xb4, 0xb4, 0, 0},
9048 {0x55, 0xd2, 0xd2, 0, 0},
9049 {0x56, 0, 0, 0, 0},
9050 {0x57, 0, 0, 0, 0},
9051 {0x58, 0x4, 0x4, 0, 0},
9052 {0x59, 0x96, 0x96, 0, 0},
9053 {0x5A, 0x3e, 0x3e, 0, 0},
9054 {0x5B, 0x3e, 0x3e, 0, 0},
9055 {0x5C, 0x13, 0x13, 0, 0},
9056 {0x5D, 0x2, 0x2, 0, 0},
9057 {0x5E, 0, 0, 0, 0},
9058 {0x5F, 0x7, 0x7, 0, 0},
9059 {0x60, 0x7, 0x7, 1, 1},
9060 {0x61, 0x8, 0x8, 0, 0},
9061 {0x62, 0x3, 0x3, 0, 0},
9062 {0x63, 0, 0, 0, 0},
9063 {0x64, 0, 0, 0, 0},
9064 {0x65, 0, 0, 0, 0},
9065 {0x66, 0, 0, 0, 0},
9066 {0x67, 0, 0, 0, 0},
9067 {0x68, 0x40, 0x40, 0, 0},
9068 {0x69, 0, 0, 0, 0},
9069 {0x6A, 0, 0, 0, 0},
9070 {0x6B, 0, 0, 0, 0},
9071 {0x6C, 0, 0, 0, 0},
9072 {0x6D, 0x1, 0x1, 0, 0},
9073 {0x6E, 0, 0, 0, 0},
9074 {0x6F, 0, 0, 0, 0},
9075 {0x70, 0x60, 0x60, 0, 0},
9076 {0x71, 0x66, 0x66, 0, 0},
9077 {0x72, 0xc, 0xc, 0, 0},
9078 {0x73, 0x66, 0x66, 0, 0},
9079 {0x74, 0x8f, 0x8f, 1, 1},
9080 {0x75, 0, 0, 0, 0},
9081 {0x76, 0xcc, 0xcc, 0, 0},
9082 {0x77, 0x1, 0x1, 0, 0},
9083 {0x78, 0x66, 0x66, 0, 0},
9084 {0x79, 0x66, 0x66, 0, 0},
9085 {0x7A, 0, 0, 0, 0},
9086 {0x7B, 0, 0, 0, 0},
9087 {0x7C, 0, 0, 0, 0},
9088 {0x7D, 0, 0, 0, 0},
9089 {0x7E, 0, 0, 0, 0},
9090 {0x7F, 0, 0, 0, 0},
9091 {0x80, 0, 0, 0, 0},
9092 {0x81, 0, 0, 0, 0},
9093 {0x82, 0, 0, 0, 0},
9094 {0x83, 0, 0, 0, 0},
9095 {0x84, 0, 0, 0, 0},
9096 {0x85, 0xff, 0xff, 0, 0},
9097 {0x86, 0, 0, 0, 0},
9098 {0x87, 0, 0, 0, 0},
9099 {0x88, 0, 0, 0, 0},
9100 {0x89, 0, 0, 0, 0},
9101 {0x8A, 0, 0, 0, 0},
9102 {0x8B, 0, 0, 0, 0},
9103 {0x8C, 0, 0, 0, 0},
9104 {0x8D, 0, 0, 0, 0},
9105 {0x8E, 0, 0, 0, 0},
9106 {0x8F, 0, 0, 0, 0},
9107 {0x90, 0, 0, 0, 0},
9108 {0x91, 0, 0, 0, 0},
9109 {0x92, 0, 0, 0, 0},
9110 {0x93, 0, 0, 0, 0},
9111 {0x94, 0, 0, 0, 0},
9112 {0x95, 0, 0, 0, 0},
9113 {0x96, 0, 0, 0, 0},
9114 {0x97, 0, 0, 0, 0},
9115 {0x98, 0, 0, 0, 0},
9116 {0x99, 0, 0, 0, 0},
9117 {0x9A, 0, 0, 0, 0},
9118 {0x9B, 0, 0, 0, 0},
9119 {0x9C, 0, 0, 0, 0},
9120 {0x9D, 0, 0, 0, 0},
9121 {0x9E, 0, 0, 0, 0},
9122 {0x9F, 0x6, 0x6, 0, 0},
9123 {0xA0, 0x66, 0x66, 0, 0},
9124 {0xA1, 0x66, 0x66, 0, 0},
9125 {0xA2, 0x66, 0x66, 0, 0},
9126 {0xA3, 0x66, 0x66, 0, 0},
9127 {0xA4, 0x66, 0x66, 0, 0},
9128 {0xA5, 0x66, 0x66, 0, 0},
9129 {0xA6, 0x66, 0x66, 0, 0},
9130 {0xA7, 0x66, 0x66, 0, 0},
9131 {0xA8, 0x66, 0x66, 0, 0},
9132 {0xA9, 0x66, 0x66, 0, 0},
9133 {0xAA, 0x66, 0x66, 0, 0},
9134 {0xAB, 0x66, 0x66, 0, 0},
9135 {0xAC, 0x66, 0x66, 0, 0},
9136 {0xAD, 0x66, 0x66, 0, 0},
9137 {0xAE, 0x66, 0x66, 0, 0},
9138 {0xAF, 0x66, 0x66, 0, 0},
9139 {0xB0, 0x66, 0x66, 0, 0},
9140 {0xB1, 0x66, 0x66, 0, 0},
9141 {0xB2, 0x66, 0x66, 0, 0},
9142 {0xB3, 0xa, 0xa, 0, 0},
9143 {0xB4, 0, 0, 0, 0},
9144 {0xB5, 0, 0, 0, 0},
9145 {0xB6, 0, 0, 0, 0},
9146 {0xFFFF, 0, 0, 0, 0}
9147};
9148
9149static struct radio_regs regs_TX_2056_rev5[] = {
9150 {0x02, 0, 0, 0, 0},
9151 {0x03, 0, 0, 0, 0},
9152 {0x04, 0, 0, 0, 0},
9153 {0x05, 0, 0, 0, 0},
9154 {0x06, 0, 0, 0, 0},
9155 {0x07, 0, 0, 0, 0},
9156 {0x08, 0, 0, 0, 0},
9157 {0x09, 0, 0, 0, 0},
9158 {0x0A, 0, 0, 0, 0},
9159 {0x0B, 0, 0, 0, 0},
9160 {0x0C, 0, 0, 0, 0},
9161 {0x0D, 0, 0, 0, 0},
9162 {0x0E, 0, 0, 0, 0},
9163 {0x0F, 0, 0, 0, 0},
9164 {0x10, 0, 0, 0, 0},
9165 {0x11, 0, 0, 0, 0},
9166 {0x12, 0, 0, 0, 0},
9167 {0x13, 0, 0, 0, 0},
9168 {0x14, 0, 0, 0, 0},
9169 {0x15, 0, 0, 0, 0},
9170 {0x16, 0, 0, 0, 0},
9171 {0x17, 0, 0, 0, 0},
9172 {0x18, 0, 0, 0, 0},
9173 {0x19, 0, 0, 0, 0},
9174 {0x1A, 0, 0, 0, 0},
9175 {0x1B, 0, 0, 0, 0},
9176 {0x1C, 0, 0, 0, 0},
9177 {0x1D, 0, 0, 0, 0},
9178 {0x1E, 0, 0, 0, 0},
9179 {0x1F, 0, 0, 0, 0},
9180 {0x20, 0, 0, 0, 0},
9181 {0x21, 0x88, 0x88, 0, 0},
9182 {0x22, 0x88, 0x88, 0, 0},
9183 {0x23, 0x88, 0x88, 0, 0},
9184 {0x24, 0x88, 0x88, 0, 0},
9185 {0x25, 0xc, 0xc, 0, 0},
9186 {0x26, 0, 0, 0, 0},
9187 {0x27, 0x3, 0x3, 0, 0},
9188 {0x28, 0, 0, 0, 0},
9189 {0x29, 0x3, 0x3, 0, 0},
9190 {0x2A, 0x37, 0x37, 0, 0},
9191 {0x2B, 0x3, 0x3, 0, 0},
9192 {0x2C, 0, 0, 0, 0},
9193 {0x2D, 0, 0, 0, 0},
9194 {0x2E, 0x1, 0x1, 0, 0},
9195 {0x2F, 0x1, 0x1, 0, 0},
9196 {0x30, 0, 0, 0, 0},
9197 {0x31, 0, 0, 0, 0},
9198 {0x32, 0, 0, 0, 0},
9199 {0x33, 0x11, 0x11, 0, 0},
9200 {0x34, 0x11, 0x11, 0, 0},
9201 {0x35, 0, 0, 0, 0},
9202 {0x36, 0, 0, 0, 0},
9203 {0x37, 0x3, 0x3, 0, 0},
9204 {0x38, 0xf, 0xf, 0, 0},
9205 {0x39, 0, 0, 0, 0},
9206 {0x3A, 0x2d, 0x2d, 0, 0},
9207 {0x3B, 0, 0, 0, 0},
9208 {0x3C, 0x6e, 0x6e, 0, 0},
9209 {0x3D, 0xf0, 0xf0, 1, 1},
9210 {0x3E, 0, 0, 0, 0},
9211 {0x3F, 0, 0, 0, 0},
9212 {0x40, 0, 0, 0, 0},
9213 {0x41, 0x3, 0x3, 0, 0},
9214 {0x42, 0x3, 0x3, 0, 0},
9215 {0x43, 0, 0, 0, 0},
9216 {0x44, 0x1e, 0x1e, 0, 0},
9217 {0x45, 0, 0, 0, 0},
9218 {0x46, 0x6e, 0x6e, 0, 0},
9219 {0x47, 0xf0, 0xf0, 1, 1},
9220 {0x48, 0, 0, 0, 0},
9221 {0x49, 0x2, 0x2, 0, 0},
9222 {0x4A, 0xff, 0xff, 1, 1},
9223 {0x4B, 0xc, 0xc, 0, 0},
9224 {0x4C, 0, 0, 0, 0},
9225 {0x4D, 0x38, 0x38, 0, 0},
9226 {0x4E, 0x70, 0x70, 1, 1},
9227 {0x4F, 0x2, 0x2, 0, 0},
9228 {0x50, 0x88, 0x88, 0, 0},
9229 {0x51, 0xc, 0xc, 0, 0},
9230 {0x52, 0, 0, 0, 0},
9231 {0x53, 0x8, 0x8, 0, 0},
9232 {0x54, 0x70, 0x70, 1, 1},
9233 {0x55, 0x2, 0x2, 0, 0},
9234 {0x56, 0xff, 0xff, 1, 1},
9235 {0x57, 0, 0, 0, 0},
9236 {0x58, 0x83, 0x83, 0, 0},
9237 {0x59, 0x77, 0x77, 1, 1},
9238 {0x5A, 0, 0, 0, 0},
9239 {0x5B, 0x2, 0x2, 0, 0},
9240 {0x5C, 0x88, 0x88, 0, 0},
9241 {0x5D, 0, 0, 0, 0},
9242 {0x5E, 0x8, 0x8, 0, 0},
9243 {0x5F, 0x77, 0x77, 1, 1},
9244 {0x60, 0x1, 0x1, 0, 0},
9245 {0x61, 0, 0, 0, 0},
9246 {0x62, 0x7, 0x7, 0, 0},
9247 {0x63, 0, 0, 0, 0},
9248 {0x64, 0x7, 0x7, 0, 0},
9249 {0x65, 0, 0, 0, 0},
9250 {0x66, 0, 0, 0, 0},
9251 {0x67, 0, 0, 1, 1},
9252 {0x68, 0, 0, 0, 0},
9253 {0x69, 0xa, 0xa, 0, 0},
9254 {0x6A, 0, 0, 0, 0},
9255 {0x6B, 0, 0, 0, 0},
9256 {0x6C, 0, 0, 0, 0},
9257 {0x6D, 0, 0, 0, 0},
9258 {0x6E, 0, 0, 0, 0},
9259 {0x6F, 0, 0, 0, 0},
9260 {0x70, 0, 0, 0, 0},
9261 {0x71, 0x2, 0x2, 0, 0},
9262 {0x72, 0, 0, 0, 0},
9263 {0x73, 0, 0, 0, 0},
9264 {0x74, 0xe, 0xe, 0, 0},
9265 {0x75, 0xe, 0xe, 0, 0},
9266 {0x76, 0xe, 0xe, 0, 0},
9267 {0x77, 0x13, 0x13, 0, 0},
9268 {0x78, 0x13, 0x13, 0, 0},
9269 {0x79, 0x1b, 0x1b, 0, 0},
9270 {0x7A, 0x1b, 0x1b, 0, 0},
9271 {0x7B, 0x55, 0x55, 0, 0},
9272 {0x7C, 0x5b, 0x5b, 0, 0},
9273 {0x7D, 0, 0, 0, 0},
9274 {0x7E, 0, 0, 0, 0},
9275 {0x7F, 0, 0, 0, 0},
9276 {0x80, 0, 0, 0, 0},
9277 {0x81, 0, 0, 0, 0},
9278 {0x82, 0, 0, 0, 0},
9279 {0x83, 0, 0, 0, 0},
9280 {0x84, 0, 0, 0, 0},
9281 {0x85, 0, 0, 0, 0},
9282 {0x86, 0, 0, 0, 0},
9283 {0x87, 0, 0, 0, 0},
9284 {0x88, 0, 0, 0, 0},
9285 {0x89, 0, 0, 0, 0},
9286 {0x8A, 0, 0, 0, 0},
9287 {0x8B, 0, 0, 0, 0},
9288 {0x8C, 0, 0, 0, 0},
9289 {0x8D, 0, 0, 0, 0},
9290 {0x8E, 0, 0, 0, 0},
9291 {0x8F, 0, 0, 0, 0},
9292 {0x90, 0, 0, 0, 0},
9293 {0x91, 0, 0, 0, 0},
9294 {0x92, 0, 0, 0, 0},
9295 {0x93, 0x70, 0x70, 0, 0},
9296 {0x94, 0x70, 0x70, 0, 0},
9297 {0x95, 0x71, 0x71, 1, 1},
9298 {0x96, 0x71, 0x71, 1, 1},
9299 {0x97, 0x72, 0x72, 1, 1},
9300 {0x98, 0x73, 0x73, 1, 1},
9301 {0x99, 0x74, 0x74, 1, 1},
9302 {0x9A, 0x75, 0x75, 1, 1},
9303 {0xFFFF, 0, 0, 0, 0}
9304};
9305
9306static struct radio_regs regs_RX_2056_rev5[] = {
9307 {0x02, 0, 0, 0, 0},
9308 {0x03, 0, 0, 0, 0},
9309 {0x04, 0, 0, 0, 0},
9310 {0x05, 0, 0, 0, 0},
9311 {0x06, 0, 0, 0, 0},
9312 {0x07, 0, 0, 0, 0},
9313 {0x08, 0, 0, 0, 0},
9314 {0x09, 0, 0, 0, 0},
9315 {0x0A, 0, 0, 0, 0},
9316 {0x0B, 0, 0, 0, 0},
9317 {0x0C, 0, 0, 0, 0},
9318 {0x0D, 0, 0, 0, 0},
9319 {0x0E, 0, 0, 0, 0},
9320 {0x0F, 0, 0, 0, 0},
9321 {0x10, 0, 0, 0, 0},
9322 {0x11, 0, 0, 0, 0},
9323 {0x12, 0, 0, 0, 0},
9324 {0x13, 0, 0, 0, 0},
9325 {0x14, 0, 0, 0, 0},
9326 {0x15, 0, 0, 0, 0},
9327 {0x16, 0, 0, 0, 0},
9328 {0x17, 0, 0, 0, 0},
9329 {0x18, 0, 0, 0, 0},
9330 {0x19, 0, 0, 0, 0},
9331 {0x1A, 0, 0, 0, 0},
9332 {0x1B, 0, 0, 0, 0},
9333 {0x1C, 0, 0, 0, 0},
9334 {0x1D, 0, 0, 0, 0},
9335 {0x1E, 0, 0, 0, 0},
9336 {0x1F, 0, 0, 0, 0},
9337 {0x20, 0x3, 0x3, 0, 0},
9338 {0x21, 0, 0, 0, 0},
9339 {0x22, 0, 0, 0, 0},
9340 {0x23, 0x90, 0x90, 0, 0},
9341 {0x24, 0x55, 0x55, 0, 0},
9342 {0x25, 0x15, 0x15, 0, 0},
9343 {0x26, 0x5, 0x5, 0, 0},
9344 {0x27, 0x15, 0x15, 0, 0},
9345 {0x28, 0x5, 0x5, 0, 0},
9346 {0x29, 0x20, 0x20, 0, 0},
9347 {0x2A, 0x11, 0x11, 0, 0},
9348 {0x2B, 0x90, 0x90, 0, 0},
9349 {0x2C, 0, 0, 0, 0},
9350 {0x2D, 0x88, 0x88, 0, 0},
9351 {0x2E, 0x32, 0x32, 0, 0},
9352 {0x2F, 0x77, 0x77, 0, 0},
9353 {0x30, 0x17, 0x17, 1, 1},
9354 {0x31, 0xff, 0xff, 1, 1},
9355 {0x32, 0x20, 0x20, 0, 0},
9356 {0x33, 0, 0, 0, 0},
9357 {0x34, 0x88, 0x88, 0, 0},
9358 {0x35, 0x32, 0x32, 0, 0},
9359 {0x36, 0x77, 0x77, 0, 0},
9360 {0x37, 0x17, 0x17, 1, 1},
9361 {0x38, 0xf0, 0xf0, 1, 1},
9362 {0x39, 0x20, 0x20, 0, 0},
9363 {0x3A, 0x8, 0x8, 0, 0},
9364 {0x3B, 0x55, 0x55, 1, 1},
9365 {0x3C, 0, 0, 0, 0},
9366 {0x3D, 0x88, 0x88, 1, 1},
9367 {0x3E, 0, 0, 0, 0},
9368 {0x3F, 0, 0, 1, 1},
9369 {0x40, 0x7, 0x7, 1, 1},
9370 {0x41, 0x6, 0x6, 0, 0},
9371 {0x42, 0x4, 0x4, 0, 0},
9372 {0x43, 0, 0, 0, 0},
9373 {0x44, 0x8, 0x8, 0, 0},
9374 {0x45, 0x55, 0x55, 1, 1},
9375 {0x46, 0, 0, 0, 0},
9376 {0x47, 0x11, 0x11, 0, 0},
9377 {0x48, 0, 0, 0, 0},
9378 {0x49, 0, 0, 1, 1},
9379 {0x4A, 0x7, 0x7, 0, 0},
9380 {0x4B, 0x6, 0x6, 0, 0},
9381 {0x4C, 0x4, 0x4, 0, 0},
9382 {0x4D, 0, 0, 0, 0},
9383 {0x4E, 0, 0, 0, 0},
9384 {0x4F, 0x26, 0x26, 1, 1},
9385 {0x50, 0x26, 0x26, 1, 1},
9386 {0x51, 0xf, 0xf, 1, 1},
9387 {0x52, 0xf, 0xf, 1, 1},
9388 {0x53, 0x44, 0x44, 0, 0},
9389 {0x54, 0, 0, 0, 0},
9390 {0x55, 0, 0, 0, 0},
9391 {0x56, 0x8, 0x8, 0, 0},
9392 {0x57, 0x8, 0x8, 0, 0},
9393 {0x58, 0x7, 0x7, 0, 0},
9394 {0x59, 0x22, 0x22, 0, 0},
9395 {0x5A, 0x22, 0x22, 0, 0},
9396 {0x5B, 0x2, 0x2, 0, 0},
9397 {0x5C, 0x4, 0x4, 1, 1},
9398 {0x5D, 0x7, 0x7, 0, 0},
9399 {0x5E, 0x55, 0x55, 0, 0},
9400 {0x5F, 0x23, 0x23, 0, 0},
9401 {0x60, 0x41, 0x41, 0, 0},
9402 {0x61, 0x1, 0x1, 0, 0},
9403 {0x62, 0xa, 0xa, 0, 0},
9404 {0x63, 0, 0, 0, 0},
9405 {0x64, 0, 0, 0, 0},
9406 {0x65, 0, 0, 0, 0},
9407 {0x66, 0, 0, 0, 0},
9408 {0x67, 0, 0, 0, 0},
9409 {0x68, 0, 0, 0, 0},
9410 {0x69, 0, 0, 0, 0},
9411 {0x6A, 0, 0, 0, 0},
9412 {0x6B, 0xc, 0xc, 0, 0},
9413 {0x6C, 0, 0, 0, 0},
9414 {0x6D, 0, 0, 0, 0},
9415 {0x6E, 0, 0, 0, 0},
9416 {0x6F, 0, 0, 0, 0},
9417 {0x70, 0, 0, 0, 0},
9418 {0x71, 0, 0, 0, 0},
9419 {0x72, 0x22, 0x22, 0, 0},
9420 {0x73, 0x22, 0x22, 0, 0},
9421 {0x74, 0, 0, 1, 1},
9422 {0x75, 0xa, 0xa, 0, 0},
9423 {0x76, 0x1, 0x1, 0, 0},
9424 {0x77, 0x22, 0x22, 0, 0},
9425 {0x78, 0x30, 0x30, 0, 0},
9426 {0x79, 0, 0, 0, 0},
9427 {0x7A, 0, 0, 0, 0},
9428 {0x7B, 0, 0, 0, 0},
9429 {0x7C, 0, 0, 0, 0},
9430 {0x7D, 0, 0, 0, 0},
9431 {0x7E, 0, 0, 0, 0},
9432 {0x7F, 0, 0, 0, 0},
9433 {0x80, 0, 0, 0, 0},
9434 {0x81, 0, 0, 0, 0},
9435 {0x82, 0, 0, 0, 0},
9436 {0x83, 0, 0, 0, 0},
9437 {0x84, 0, 0, 0, 0},
9438 {0x85, 0, 0, 0, 0},
9439 {0x86, 0, 0, 0, 0},
9440 {0x87, 0, 0, 0, 0},
9441 {0x88, 0, 0, 0, 0},
9442 {0x89, 0, 0, 0, 0},
9443 {0x8A, 0, 0, 0, 0},
9444 {0x8B, 0, 0, 0, 0},
9445 {0x8C, 0, 0, 0, 0},
9446 {0x8D, 0, 0, 0, 0},
9447 {0x8E, 0, 0, 0, 0},
9448 {0x8F, 0, 0, 0, 0},
9449 {0x90, 0, 0, 0, 0},
9450 {0x91, 0, 0, 0, 0},
9451 {0x92, 0, 0, 0, 0},
9452 {0x93, 0, 0, 0, 0},
9453 {0x94, 0, 0, 0, 0},
9454 {0xFFFF, 0, 0, 0, 0}
9455};
9456
9457static struct radio_regs regs_SYN_2056_rev6[] = {
9458 {0x02, 0, 0, 0, 0},
9459 {0x03, 0, 0, 0, 0},
9460 {0x04, 0, 0, 0, 0},
9461 {0x05, 0, 0, 0, 0},
9462 {0x06, 0, 0, 0, 0},
9463 {0x07, 0, 0, 0, 0},
9464 {0x08, 0, 0, 0, 0},
9465 {0x09, 0x1, 0x1, 0, 0},
9466 {0x0A, 0, 0, 0, 0},
9467 {0x0B, 0, 0, 0, 0},
9468 {0x0C, 0, 0, 0, 0},
9469 {0x0D, 0, 0, 0, 0},
9470 {0x0E, 0, 0, 0, 0},
9471 {0x0F, 0, 0, 0, 0},
9472 {0x10, 0, 0, 0, 0},
9473 {0x11, 0, 0, 0, 0},
9474 {0x12, 0, 0, 0, 0},
9475 {0x13, 0, 0, 0, 0},
9476 {0x14, 0, 0, 0, 0},
9477 {0x15, 0, 0, 0, 0},
9478 {0x16, 0, 0, 0, 0},
9479 {0x17, 0, 0, 0, 0},
9480 {0x18, 0, 0, 0, 0},
9481 {0x19, 0, 0, 0, 0},
9482 {0x1A, 0, 0, 0, 0},
9483 {0x1B, 0, 0, 0, 0},
9484 {0x1C, 0, 0, 0, 0},
9485 {0x1D, 0, 0, 0, 0},
9486 {0x1E, 0, 0, 0, 0},
9487 {0x1F, 0, 0, 0, 0},
9488 {0x20, 0, 0, 0, 0},
9489 {0x21, 0, 0, 0, 0},
9490 {0x22, 0x60, 0x60, 0, 0},
9491 {0x23, 0x6, 0x6, 0, 0},
9492 {0x24, 0xc, 0xc, 0, 0},
9493 {0x25, 0, 0, 0, 0},
9494 {0x26, 0, 0, 0, 0},
9495 {0x27, 0, 0, 0, 0},
9496 {0x28, 0x1, 0x1, 0, 0},
9497 {0x29, 0, 0, 0, 0},
9498 {0x2A, 0, 0, 0, 0},
9499 {0x2B, 0, 0, 0, 0},
9500 {0x2C, 0, 0, 0, 0},
9501 {0x2D, 0, 0, 0, 0},
9502 {0x2E, 0, 0, 0, 0},
9503 {0x2F, 0x1f, 0x1f, 0, 0},
9504 {0x30, 0x15, 0x15, 0, 0},
9505 {0x31, 0xf, 0xf, 0, 0},
9506 {0x32, 0, 0, 0, 0},
9507 {0x33, 0, 0, 0, 0},
9508 {0x34, 0, 0, 0, 0},
9509 {0x35, 0, 0, 0, 0},
9510 {0x36, 0, 0, 0, 0},
9511 {0x37, 0, 0, 0, 0},
9512 {0x38, 0, 0, 0, 0},
9513 {0x39, 0, 0, 0, 0},
9514 {0x3A, 0, 0, 0, 0},
9515 {0x3B, 0, 0, 0, 0},
9516 {0x3C, 0x13, 0x13, 0, 0},
9517 {0x3D, 0xf, 0xf, 0, 0},
9518 {0x3E, 0x18, 0x18, 0, 0},
9519 {0x3F, 0, 0, 0, 0},
9520 {0x40, 0, 0, 0, 0},
9521 {0x41, 0x20, 0x20, 0, 0},
9522 {0x42, 0x20, 0x20, 0, 0},
9523 {0x43, 0, 0, 0, 0},
9524 {0x44, 0x77, 0x77, 0, 0},
9525 {0x45, 0x7, 0x7, 0, 0},
9526 {0x46, 0x1, 0x1, 0, 0},
9527 {0x47, 0x4, 0x4, 0, 0},
9528 {0x48, 0xf, 0xf, 0, 0},
9529 {0x49, 0x30, 0x30, 0, 0},
9530 {0x4A, 0x32, 0x32, 0, 0},
9531 {0x4B, 0xd, 0xd, 0, 0},
9532 {0x4C, 0xd, 0xd, 0, 0},
9533 {0x4D, 0x4, 0x4, 0, 0},
9534 {0x4E, 0x6, 0x6, 0, 0},
9535 {0x4F, 0x1, 0x1, 0, 0},
9536 {0x50, 0x1c, 0x1c, 0, 0},
9537 {0x51, 0x2, 0x2, 0, 0},
9538 {0x52, 0x2, 0x2, 0, 0},
9539 {0x53, 0xf7, 0xf7, 1, 1},
9540 {0x54, 0xb4, 0xb4, 0, 0},
9541 {0x55, 0xd2, 0xd2, 0, 0},
9542 {0x56, 0, 0, 0, 0},
9543 {0x57, 0, 0, 0, 0},
9544 {0x58, 0x4, 0x4, 0, 0},
9545 {0x59, 0x96, 0x96, 0, 0},
9546 {0x5A, 0x3e, 0x3e, 0, 0},
9547 {0x5B, 0x3e, 0x3e, 0, 0},
9548 {0x5C, 0x13, 0x13, 0, 0},
9549 {0x5D, 0x2, 0x2, 0, 0},
9550 {0x5E, 0, 0, 0, 0},
9551 {0x5F, 0x7, 0x7, 0, 0},
9552 {0x60, 0x7, 0x7, 1, 1},
9553 {0x61, 0x8, 0x8, 0, 0},
9554 {0x62, 0x3, 0x3, 0, 0},
9555 {0x63, 0, 0, 0, 0},
9556 {0x64, 0, 0, 0, 0},
9557 {0x65, 0, 0, 0, 0},
9558 {0x66, 0, 0, 0, 0},
9559 {0x67, 0, 0, 0, 0},
9560 {0x68, 0x40, 0x40, 0, 0},
9561 {0x69, 0, 0, 0, 0},
9562 {0x6A, 0, 0, 0, 0},
9563 {0x6B, 0, 0, 0, 0},
9564 {0x6C, 0, 0, 0, 0},
9565 {0x6D, 0x1, 0x1, 0, 0},
9566 {0x6E, 0, 0, 0, 0},
9567 {0x6F, 0, 0, 0, 0},
9568 {0x70, 0x60, 0x60, 0, 0},
9569 {0x71, 0x66, 0x66, 0, 0},
9570 {0x72, 0xc, 0xc, 0, 0},
9571 {0x73, 0x66, 0x66, 0, 0},
9572 {0x74, 0x8f, 0x8f, 1, 1},
9573 {0x75, 0, 0, 0, 0},
9574 {0x76, 0xcc, 0xcc, 0, 0},
9575 {0x77, 0x1, 0x1, 0, 0},
9576 {0x78, 0x66, 0x66, 0, 0},
9577 {0x79, 0x66, 0x66, 0, 0},
9578 {0x7A, 0, 0, 0, 0},
9579 {0x7B, 0, 0, 0, 0},
9580 {0x7C, 0, 0, 0, 0},
9581 {0x7D, 0, 0, 0, 0},
9582 {0x7E, 0, 0, 0, 0},
9583 {0x7F, 0, 0, 0, 0},
9584 {0x80, 0, 0, 0, 0},
9585 {0x81, 0, 0, 0, 0},
9586 {0x82, 0, 0, 0, 0},
9587 {0x83, 0, 0, 0, 0},
9588 {0x84, 0, 0, 0, 0},
9589 {0x85, 0xff, 0xff, 0, 0},
9590 {0x86, 0, 0, 0, 0},
9591 {0x87, 0, 0, 0, 0},
9592 {0x88, 0, 0, 0, 0},
9593 {0x89, 0, 0, 0, 0},
9594 {0x8A, 0, 0, 0, 0},
9595 {0x8B, 0, 0, 0, 0},
9596 {0x8C, 0, 0, 0, 0},
9597 {0x8D, 0, 0, 0, 0},
9598 {0x8E, 0, 0, 0, 0},
9599 {0x8F, 0, 0, 0, 0},
9600 {0x90, 0, 0, 0, 0},
9601 {0x91, 0, 0, 0, 0},
9602 {0x92, 0, 0, 0, 0},
9603 {0x93, 0, 0, 0, 0},
9604 {0x94, 0, 0, 0, 0},
9605 {0x95, 0, 0, 0, 0},
9606 {0x96, 0, 0, 0, 0},
9607 {0x97, 0, 0, 0, 0},
9608 {0x98, 0, 0, 0, 0},
9609 {0x99, 0, 0, 0, 0},
9610 {0x9A, 0, 0, 0, 0},
9611 {0x9B, 0, 0, 0, 0},
9612 {0x9C, 0, 0, 0, 0},
9613 {0x9D, 0, 0, 0, 0},
9614 {0x9E, 0, 0, 0, 0},
9615 {0x9F, 0x6, 0x6, 0, 0},
9616 {0xA0, 0x66, 0x66, 0, 0},
9617 {0xA1, 0x66, 0x66, 0, 0},
9618 {0xA2, 0x66, 0x66, 0, 0},
9619 {0xA3, 0x66, 0x66, 0, 0},
9620 {0xA4, 0x66, 0x66, 0, 0},
9621 {0xA5, 0x66, 0x66, 0, 0},
9622 {0xA6, 0x66, 0x66, 0, 0},
9623 {0xA7, 0x66, 0x66, 0, 0},
9624 {0xA8, 0x66, 0x66, 0, 0},
9625 {0xA9, 0x66, 0x66, 0, 0},
9626 {0xAA, 0x66, 0x66, 0, 0},
9627 {0xAB, 0x66, 0x66, 0, 0},
9628 {0xAC, 0x66, 0x66, 0, 0},
9629 {0xAD, 0x66, 0x66, 0, 0},
9630 {0xAE, 0x66, 0x66, 0, 0},
9631 {0xAF, 0x66, 0x66, 0, 0},
9632 {0xB0, 0x66, 0x66, 0, 0},
9633 {0xB1, 0x66, 0x66, 0, 0},
9634 {0xB2, 0x66, 0x66, 0, 0},
9635 {0xB3, 0xa, 0xa, 0, 0},
9636 {0xB4, 0, 0, 0, 0},
9637 {0xB5, 0, 0, 0, 0},
9638 {0xB6, 0, 0, 0, 0},
9639 {0xFFFF, 0, 0, 0, 0}
9640};
9641
9642static struct radio_regs regs_TX_2056_rev6[] = {
9643 {0x02, 0, 0, 0, 0},
9644 {0x03, 0, 0, 0, 0},
9645 {0x04, 0, 0, 0, 0},
9646 {0x05, 0, 0, 0, 0},
9647 {0x06, 0, 0, 0, 0},
9648 {0x07, 0, 0, 0, 0},
9649 {0x08, 0, 0, 0, 0},
9650 {0x09, 0, 0, 0, 0},
9651 {0x0A, 0, 0, 0, 0},
9652 {0x0B, 0, 0, 0, 0},
9653 {0x0C, 0, 0, 0, 0},
9654 {0x0D, 0, 0, 0, 0},
9655 {0x0E, 0, 0, 0, 0},
9656 {0x0F, 0, 0, 0, 0},
9657 {0x10, 0, 0, 0, 0},
9658 {0x11, 0, 0, 0, 0},
9659 {0x12, 0, 0, 0, 0},
9660 {0x13, 0, 0, 0, 0},
9661 {0x14, 0, 0, 0, 0},
9662 {0x15, 0, 0, 0, 0},
9663 {0x16, 0, 0, 0, 0},
9664 {0x17, 0, 0, 0, 0},
9665 {0x18, 0, 0, 0, 0},
9666 {0x19, 0, 0, 0, 0},
9667 {0x1A, 0, 0, 0, 0},
9668 {0x1B, 0, 0, 0, 0},
9669 {0x1C, 0, 0, 0, 0},
9670 {0x1D, 0, 0, 0, 0},
9671 {0x1E, 0, 0, 0, 0},
9672 {0x1F, 0, 0, 0, 0},
9673 {0x20, 0, 0, 0, 0},
9674 {0x21, 0x88, 0x88, 0, 0},
9675 {0x22, 0x88, 0x88, 0, 0},
9676 {0x23, 0x88, 0x88, 0, 0},
9677 {0x24, 0x88, 0x88, 0, 0},
9678 {0x25, 0xc, 0xc, 0, 0},
9679 {0x26, 0, 0, 0, 0},
9680 {0x27, 0x3, 0x3, 0, 0},
9681 {0x28, 0, 0, 0, 0},
9682 {0x29, 0x3, 0x3, 0, 0},
9683 {0x2A, 0x37, 0x37, 0, 0},
9684 {0x2B, 0x3, 0x3, 0, 0},
9685 {0x2C, 0, 0, 0, 0},
9686 {0x2D, 0, 0, 0, 0},
9687 {0x2E, 0x1, 0x1, 0, 0},
9688 {0x2F, 0x1, 0x1, 0, 0},
9689 {0x30, 0, 0, 0, 0},
9690 {0x31, 0, 0, 0, 0},
9691 {0x32, 0, 0, 0, 0},
9692 {0x33, 0x11, 0x11, 0, 0},
9693 {0x34, 0xee, 0xee, 1, 1},
9694 {0x35, 0, 0, 0, 0},
9695 {0x36, 0, 0, 0, 0},
9696 {0x37, 0x3, 0x3, 0, 0},
9697 {0x38, 0x50, 0x50, 1, 1},
9698 {0x39, 0, 0, 0, 0},
9699 {0x3A, 0x50, 0x50, 1, 1},
9700 {0x3B, 0, 0, 0, 0},
9701 {0x3C, 0x6e, 0x6e, 0, 0},
9702 {0x3D, 0xf0, 0xf0, 1, 1},
9703 {0x3E, 0, 0, 0, 0},
9704 {0x3F, 0, 0, 0, 0},
9705 {0x40, 0, 0, 0, 0},
9706 {0x41, 0x3, 0x3, 0, 0},
9707 {0x42, 0x3, 0x3, 0, 0},
9708 {0x43, 0, 0, 0, 0},
9709 {0x44, 0x1e, 0x1e, 0, 0},
9710 {0x45, 0, 0, 0, 0},
9711 {0x46, 0x6e, 0x6e, 0, 0},
9712 {0x47, 0xf0, 0xf0, 1, 1},
9713 {0x48, 0, 0, 0, 0},
9714 {0x49, 0x2, 0x2, 0, 0},
9715 {0x4A, 0xff, 0xff, 1, 1},
9716 {0x4B, 0xc, 0xc, 0, 0},
9717 {0x4C, 0, 0, 0, 0},
9718 {0x4D, 0x38, 0x38, 0, 0},
9719 {0x4E, 0x70, 0x70, 1, 1},
9720 {0x4F, 0x2, 0x2, 0, 0},
9721 {0x50, 0x88, 0x88, 0, 0},
9722 {0x51, 0xc, 0xc, 0, 0},
9723 {0x52, 0, 0, 0, 0},
9724 {0x53, 0x8, 0x8, 0, 0},
9725 {0x54, 0x70, 0x70, 1, 1},
9726 {0x55, 0x2, 0x2, 0, 0},
9727 {0x56, 0xff, 0xff, 1, 1},
9728 {0x57, 0, 0, 0, 0},
9729 {0x58, 0x83, 0x83, 0, 0},
9730 {0x59, 0x77, 0x77, 1, 1},
9731 {0x5A, 0, 0, 0, 0},
9732 {0x5B, 0x2, 0x2, 0, 0},
9733 {0x5C, 0x88, 0x88, 0, 0},
9734 {0x5D, 0, 0, 0, 0},
9735 {0x5E, 0x8, 0x8, 0, 0},
9736 {0x5F, 0x77, 0x77, 1, 1},
9737 {0x60, 0x1, 0x1, 0, 0},
9738 {0x61, 0, 0, 0, 0},
9739 {0x62, 0x7, 0x7, 0, 0},
9740 {0x63, 0, 0, 0, 0},
9741 {0x64, 0x7, 0x7, 0, 0},
9742 {0x65, 0, 0, 0, 0},
9743 {0x66, 0, 0, 0, 0},
9744 {0x67, 0, 0, 1, 1},
9745 {0x68, 0, 0, 0, 0},
9746 {0x69, 0xa, 0xa, 0, 0},
9747 {0x6A, 0, 0, 0, 0},
9748 {0x6B, 0, 0, 0, 0},
9749 {0x6C, 0, 0, 0, 0},
9750 {0x6D, 0, 0, 0, 0},
9751 {0x6E, 0, 0, 0, 0},
9752 {0x6F, 0, 0, 0, 0},
9753 {0x70, 0, 0, 0, 0},
9754 {0x71, 0x2, 0x2, 0, 0},
9755 {0x72, 0, 0, 0, 0},
9756 {0x73, 0, 0, 0, 0},
9757 {0x74, 0xe, 0xe, 0, 0},
9758 {0x75, 0xe, 0xe, 0, 0},
9759 {0x76, 0xe, 0xe, 0, 0},
9760 {0x77, 0x13, 0x13, 0, 0},
9761 {0x78, 0x13, 0x13, 0, 0},
9762 {0x79, 0x1b, 0x1b, 0, 0},
9763 {0x7A, 0x1b, 0x1b, 0, 0},
9764 {0x7B, 0x55, 0x55, 0, 0},
9765 {0x7C, 0x5b, 0x5b, 0, 0},
9766 {0x7D, 0x30, 0x30, 1, 1},
9767 {0x7E, 0, 0, 0, 0},
9768 {0x7F, 0, 0, 0, 0},
9769 {0x80, 0, 0, 0, 0},
9770 {0x81, 0, 0, 0, 0},
9771 {0x82, 0, 0, 0, 0},
9772 {0x83, 0, 0, 0, 0},
9773 {0x84, 0, 0, 0, 0},
9774 {0x85, 0, 0, 0, 0},
9775 {0x86, 0, 0, 0, 0},
9776 {0x87, 0, 0, 0, 0},
9777 {0x88, 0, 0, 0, 0},
9778 {0x89, 0, 0, 0, 0},
9779 {0x8A, 0, 0, 0, 0},
9780 {0x8B, 0, 0, 0, 0},
9781 {0x8C, 0, 0, 0, 0},
9782 {0x8D, 0, 0, 0, 0},
9783 {0x8E, 0, 0, 0, 0},
9784 {0x8F, 0, 0, 0, 0},
9785 {0x90, 0, 0, 0, 0},
9786 {0x91, 0, 0, 0, 0},
9787 {0x92, 0, 0, 0, 0},
9788 {0x93, 0x70, 0x70, 0, 0},
9789 {0x94, 0x70, 0x70, 0, 0},
9790 {0x95, 0x70, 0x70, 0, 0},
9791 {0x96, 0x70, 0x70, 0, 0},
9792 {0x97, 0x70, 0x70, 0, 0},
9793 {0x98, 0x70, 0x70, 0, 0},
9794 {0x99, 0x70, 0x70, 0, 0},
9795 {0x9A, 0x70, 0x70, 0, 0},
9796 {0xFFFF, 0, 0, 0, 0}
9797};
9798
9799static struct radio_regs regs_RX_2056_rev6[] = {
9800 {0x02, 0, 0, 0, 0},
9801 {0x03, 0, 0, 0, 0},
9802 {0x04, 0, 0, 0, 0},
9803 {0x05, 0, 0, 0, 0},
9804 {0x06, 0, 0, 0, 0},
9805 {0x07, 0, 0, 0, 0},
9806 {0x08, 0, 0, 0, 0},
9807 {0x09, 0, 0, 0, 0},
9808 {0x0A, 0, 0, 0, 0},
9809 {0x0B, 0, 0, 0, 0},
9810 {0x0C, 0, 0, 0, 0},
9811 {0x0D, 0, 0, 0, 0},
9812 {0x0E, 0, 0, 0, 0},
9813 {0x0F, 0, 0, 0, 0},
9814 {0x10, 0, 0, 0, 0},
9815 {0x11, 0, 0, 0, 0},
9816 {0x12, 0, 0, 0, 0},
9817 {0x13, 0, 0, 0, 0},
9818 {0x14, 0, 0, 0, 0},
9819 {0x15, 0, 0, 0, 0},
9820 {0x16, 0, 0, 0, 0},
9821 {0x17, 0, 0, 0, 0},
9822 {0x18, 0, 0, 0, 0},
9823 {0x19, 0, 0, 0, 0},
9824 {0x1A, 0, 0, 0, 0},
9825 {0x1B, 0, 0, 0, 0},
9826 {0x1C, 0, 0, 0, 0},
9827 {0x1D, 0, 0, 0, 0},
9828 {0x1E, 0, 0, 0, 0},
9829 {0x1F, 0, 0, 0, 0},
9830 {0x20, 0x3, 0x3, 0, 0},
9831 {0x21, 0, 0, 0, 0},
9832 {0x22, 0, 0, 0, 0},
9833 {0x23, 0x90, 0x90, 0, 0},
9834 {0x24, 0x55, 0x55, 0, 0},
9835 {0x25, 0x15, 0x15, 0, 0},
9836 {0x26, 0x5, 0x5, 0, 0},
9837 {0x27, 0x15, 0x15, 0, 0},
9838 {0x28, 0x5, 0x5, 0, 0},
9839 {0x29, 0x20, 0x20, 0, 0},
9840 {0x2A, 0x11, 0x11, 0, 0},
9841 {0x2B, 0x90, 0x90, 0, 0},
9842 {0x2C, 0, 0, 0, 0},
9843 {0x2D, 0x88, 0x88, 0, 0},
9844 {0x2E, 0x32, 0x32, 0, 0},
9845 {0x2F, 0x77, 0x77, 0, 0},
9846 {0x30, 0x17, 0x17, 1, 1},
9847 {0x31, 0xff, 0xff, 1, 1},
9848 {0x32, 0x20, 0x20, 0, 0},
9849 {0x33, 0, 0, 0, 0},
9850 {0x34, 0x88, 0x88, 0, 0},
9851 {0x35, 0x32, 0x32, 0, 0},
9852 {0x36, 0x77, 0x77, 0, 0},
9853 {0x37, 0x17, 0x17, 1, 1},
9854 {0x38, 0xf0, 0xf0, 1, 1},
9855 {0x39, 0x20, 0x20, 0, 0},
9856 {0x3A, 0x8, 0x8, 0, 0},
9857 {0x3B, 0x55, 0x55, 1, 1},
9858 {0x3C, 0, 0, 0, 0},
9859 {0x3D, 0x88, 0x88, 1, 1},
9860 {0x3E, 0, 0, 0, 0},
9861 {0x3F, 0x44, 0x44, 0, 0},
9862 {0x40, 0x7, 0x7, 1, 1},
9863 {0x41, 0x6, 0x6, 0, 0},
9864 {0x42, 0x4, 0x4, 0, 0},
9865 {0x43, 0, 0, 0, 0},
9866 {0x44, 0x8, 0x8, 0, 0},
9867 {0x45, 0x55, 0x55, 1, 1},
9868 {0x46, 0, 0, 0, 0},
9869 {0x47, 0x11, 0x11, 0, 0},
9870 {0x48, 0, 0, 0, 0},
9871 {0x49, 0x44, 0x44, 0, 0},
9872 {0x4A, 0x7, 0x7, 0, 0},
9873 {0x4B, 0x6, 0x6, 0, 0},
9874 {0x4C, 0x4, 0x4, 0, 0},
9875 {0x4D, 0, 0, 0, 0},
9876 {0x4E, 0, 0, 0, 0},
9877 {0x4F, 0x26, 0x26, 1, 1},
9878 {0x50, 0x26, 0x26, 1, 1},
9879 {0x51, 0xf, 0xf, 1, 1},
9880 {0x52, 0xf, 0xf, 1, 1},
9881 {0x53, 0x44, 0x44, 0, 0},
9882 {0x54, 0, 0, 0, 0},
9883 {0x55, 0, 0, 0, 0},
9884 {0x56, 0x8, 0x8, 0, 0},
9885 {0x57, 0x8, 0x8, 0, 0},
9886 {0x58, 0x7, 0x7, 0, 0},
9887 {0x59, 0x22, 0x22, 0, 0},
9888 {0x5A, 0x22, 0x22, 0, 0},
9889 {0x5B, 0x2, 0x2, 0, 0},
9890 {0x5C, 0x4, 0x4, 1, 1},
9891 {0x5D, 0x7, 0x7, 0, 0},
9892 {0x5E, 0x55, 0x55, 0, 0},
9893 {0x5F, 0x23, 0x23, 0, 0},
9894 {0x60, 0x41, 0x41, 0, 0},
9895 {0x61, 0x1, 0x1, 0, 0},
9896 {0x62, 0xa, 0xa, 0, 0},
9897 {0x63, 0, 0, 0, 0},
9898 {0x64, 0, 0, 0, 0},
9899 {0x65, 0, 0, 0, 0},
9900 {0x66, 0, 0, 0, 0},
9901 {0x67, 0, 0, 0, 0},
9902 {0x68, 0, 0, 0, 0},
9903 {0x69, 0, 0, 0, 0},
9904 {0x6A, 0, 0, 0, 0},
9905 {0x6B, 0xc, 0xc, 0, 0},
9906 {0x6C, 0, 0, 0, 0},
9907 {0x6D, 0, 0, 0, 0},
9908 {0x6E, 0, 0, 0, 0},
9909 {0x6F, 0, 0, 0, 0},
9910 {0x70, 0, 0, 0, 0},
9911 {0x71, 0, 0, 0, 0},
9912 {0x72, 0x22, 0x22, 0, 0},
9913 {0x73, 0x22, 0x22, 0, 0},
9914 {0x74, 0, 0, 1, 1},
9915 {0x75, 0xa, 0xa, 0, 0},
9916 {0x76, 0x1, 0x1, 0, 0},
9917 {0x77, 0x22, 0x22, 0, 0},
9918 {0x78, 0x30, 0x30, 0, 0},
9919 {0x79, 0, 0, 0, 0},
9920 {0x7A, 0, 0, 0, 0},
9921 {0x7B, 0, 0, 0, 0},
9922 {0x7C, 0, 0, 0, 0},
9923 {0x7D, 0x5, 0x5, 1, 1},
9924 {0x7E, 0, 0, 0, 0},
9925 {0x7F, 0, 0, 0, 0},
9926 {0x80, 0, 0, 0, 0},
9927 {0x81, 0, 0, 0, 0},
9928 {0x82, 0, 0, 0, 0},
9929 {0x83, 0, 0, 0, 0},
9930 {0x84, 0, 0, 0, 0},
9931 {0x85, 0, 0, 0, 0},
9932 {0x86, 0, 0, 0, 0},
9933 {0x87, 0, 0, 0, 0},
9934 {0x88, 0, 0, 0, 0},
9935 {0x89, 0, 0, 0, 0},
9936 {0x8A, 0, 0, 0, 0},
9937 {0x8B, 0, 0, 0, 0},
9938 {0x8C, 0, 0, 0, 0},
9939 {0x8D, 0, 0, 0, 0},
9940 {0x8E, 0, 0, 0, 0},
9941 {0x8F, 0, 0, 0, 0},
9942 {0x90, 0, 0, 0, 0},
9943 {0x91, 0, 0, 0, 0},
9944 {0x92, 0, 0, 0, 0},
9945 {0x93, 0, 0, 0, 0},
9946 {0x94, 0, 0, 0, 0},
9947 {0xFFFF, 0, 0, 0, 0}
9948};
9949
9950static struct radio_regs regs_SYN_2056_rev7[] = {
9951 {0x02, 0, 0, 0, 0},
9952 {0x03, 0, 0, 0, 0},
9953 {0x04, 0, 0, 0, 0},
9954 {0x05, 0, 0, 0, 0},
9955 {0x06, 0, 0, 0, 0},
9956 {0x07, 0, 0, 0, 0},
9957 {0x08, 0, 0, 0, 0},
9958 {0x09, 0x1, 0x1, 0, 0},
9959 {0x0A, 0, 0, 0, 0},
9960 {0x0B, 0, 0, 0, 0},
9961 {0x0C, 0, 0, 0, 0},
9962 {0x0D, 0, 0, 0, 0},
9963 {0x0E, 0, 0, 0, 0},
9964 {0x0F, 0, 0, 0, 0},
9965 {0x10, 0, 0, 0, 0},
9966 {0x11, 0, 0, 0, 0},
9967 {0x12, 0, 0, 0, 0},
9968 {0x13, 0, 0, 0, 0},
9969 {0x14, 0, 0, 0, 0},
9970 {0x15, 0, 0, 0, 0},
9971 {0x16, 0, 0, 0, 0},
9972 {0x17, 0, 0, 0, 0},
9973 {0x18, 0, 0, 0, 0},
9974 {0x19, 0, 0, 0, 0},
9975 {0x1A, 0, 0, 0, 0},
9976 {0x1B, 0, 0, 0, 0},
9977 {0x1C, 0, 0, 0, 0},
9978 {0x1D, 0, 0, 0, 0},
9979 {0x1E, 0, 0, 0, 0},
9980 {0x1F, 0, 0, 0, 0},
9981 {0x20, 0, 0, 0, 0},
9982 {0x21, 0, 0, 0, 0},
9983 {0x22, 0x60, 0x60, 0, 0},
9984 {0x23, 0x6, 0x6, 0, 0},
9985 {0x24, 0xc, 0xc, 0, 0},
9986 {0x25, 0, 0, 0, 0},
9987 {0x26, 0, 0, 0, 0},
9988 {0x27, 0, 0, 0, 0},
9989 {0x28, 0x1, 0x1, 0, 0},
9990 {0x29, 0, 0, 0, 0},
9991 {0x2A, 0, 0, 0, 0},
9992 {0x2B, 0, 0, 0, 0},
9993 {0x2C, 0, 0, 0, 0},
9994 {0x2D, 0, 0, 0, 0},
9995 {0x2E, 0, 0, 0, 0},
9996 {0x2F, 0x1f, 0x1f, 0, 0},
9997 {0x30, 0x15, 0x15, 0, 0},
9998 {0x31, 0xf, 0xf, 0, 0},
9999 {0x32, 0, 0, 0, 0},
10000 {0x33, 0, 0, 0, 0},
10001 {0x34, 0, 0, 0, 0},
10002 {0x35, 0, 0, 0, 0},
10003 {0x36, 0, 0, 0, 0},
10004 {0x37, 0, 0, 0, 0},
10005 {0x38, 0, 0, 0, 0},
10006 {0x39, 0, 0, 0, 0},
10007 {0x3A, 0, 0, 0, 0},
10008 {0x3B, 0, 0, 0, 0},
10009 {0x3C, 0x13, 0x13, 0, 0},
10010 {0x3D, 0xf, 0xf, 0, 0},
10011 {0x3E, 0x18, 0x18, 0, 0},
10012 {0x3F, 0, 0, 0, 0},
10013 {0x40, 0, 0, 0, 0},
10014 {0x41, 0x20, 0x20, 0, 0},
10015 {0x42, 0x20, 0x20, 0, 0},
10016 {0x43, 0, 0, 0, 0},
10017 {0x44, 0x77, 0x77, 0, 0},
10018 {0x45, 0x7, 0x7, 0, 0},
10019 {0x46, 0x1, 0x1, 0, 0},
10020 {0x47, 0x4, 0x4, 0, 0},
10021 {0x48, 0xf, 0xf, 0, 0},
10022 {0x49, 0x30, 0x30, 0, 0},
10023 {0x4A, 0x32, 0x32, 0, 0},
10024 {0x4B, 0xd, 0xd, 0, 0},
10025 {0x4C, 0xd, 0xd, 0, 0},
10026 {0x4D, 0x4, 0x4, 0, 0},
10027 {0x4E, 0x6, 0x6, 0, 0},
10028 {0x4F, 0x1, 0x1, 0, 0},
10029 {0x50, 0x1c, 0x1c, 0, 0},
10030 {0x51, 0x2, 0x2, 0, 0},
10031 {0x52, 0x2, 0x2, 0, 0},
10032 {0x53, 0xf7, 0xf7, 1, 1},
10033 {0x54, 0xb4, 0xb4, 0, 0},
10034 {0x55, 0xd2, 0xd2, 0, 0},
10035 {0x56, 0, 0, 0, 0},
10036 {0x57, 0, 0, 0, 0},
10037 {0x58, 0x4, 0x4, 0, 0},
10038 {0x59, 0x96, 0x96, 0, 0},
10039 {0x5A, 0x3e, 0x3e, 0, 0},
10040 {0x5B, 0x3e, 0x3e, 0, 0},
10041 {0x5C, 0x13, 0x13, 0, 0},
10042 {0x5D, 0x2, 0x2, 0, 0},
10043 {0x5E, 0, 0, 0, 0},
10044 {0x5F, 0x7, 0x7, 0, 0},
10045 {0x60, 0x7, 0x7, 1, 1},
10046 {0x61, 0x8, 0x8, 0, 0},
10047 {0x62, 0x3, 0x3, 0, 0},
10048 {0x63, 0, 0, 0, 0},
10049 {0x64, 0, 0, 0, 0},
10050 {0x65, 0, 0, 0, 0},
10051 {0x66, 0, 0, 0, 0},
10052 {0x67, 0, 0, 0, 0},
10053 {0x68, 0x40, 0x40, 0, 0},
10054 {0x69, 0, 0, 0, 0},
10055 {0x6A, 0, 0, 0, 0},
10056 {0x6B, 0, 0, 0, 0},
10057 {0x6C, 0, 0, 0, 0},
10058 {0x6D, 0x1, 0x1, 0, 0},
10059 {0x6E, 0, 0, 0, 0},
10060 {0x6F, 0, 0, 0, 0},
10061 {0x70, 0x60, 0x60, 0, 0},
10062 {0x71, 0x66, 0x66, 0, 0},
10063 {0x72, 0xc, 0xc, 0, 0},
10064 {0x73, 0x66, 0x66, 0, 0},
10065 {0x74, 0x8f, 0x8f, 1, 1},
10066 {0x75, 0, 0, 0, 0},
10067 {0x76, 0xcc, 0xcc, 0, 0},
10068 {0x77, 0x1, 0x1, 0, 0},
10069 {0x78, 0x66, 0x66, 0, 0},
10070 {0x79, 0x66, 0x66, 0, 0},
10071 {0x7A, 0, 0, 0, 0},
10072 {0x7B, 0, 0, 0, 0},
10073 {0x7C, 0, 0, 0, 0},
10074 {0x7D, 0, 0, 0, 0},
10075 {0x7E, 0, 0, 0, 0},
10076 {0x7F, 0, 0, 0, 0},
10077 {0x80, 0, 0, 0, 0},
10078 {0x81, 0, 0, 0, 0},
10079 {0x82, 0, 0, 0, 0},
10080 {0x83, 0, 0, 0, 0},
10081 {0x84, 0, 0, 0, 0},
10082 {0x85, 0xff, 0xff, 0, 0},
10083 {0x86, 0, 0, 0, 0},
10084 {0x87, 0, 0, 0, 0},
10085 {0x88, 0, 0, 0, 0},
10086 {0x89, 0, 0, 0, 0},
10087 {0x8A, 0, 0, 0, 0},
10088 {0x8B, 0, 0, 0, 0},
10089 {0x8C, 0, 0, 0, 0},
10090 {0x8D, 0, 0, 0, 0},
10091 {0x8E, 0, 0, 0, 0},
10092 {0x8F, 0, 0, 0, 0},
10093 {0x90, 0, 0, 0, 0},
10094 {0x91, 0, 0, 0, 0},
10095 {0x92, 0, 0, 0, 0},
10096 {0x93, 0, 0, 0, 0},
10097 {0x94, 0, 0, 0, 0},
10098 {0x95, 0, 0, 0, 0},
10099 {0x96, 0, 0, 0, 0},
10100 {0x97, 0, 0, 0, 0},
10101 {0x98, 0, 0, 0, 0},
10102 {0x99, 0, 0, 0, 0},
10103 {0x9A, 0, 0, 0, 0},
10104 {0x9B, 0, 0, 0, 0},
10105 {0x9C, 0, 0, 0, 0},
10106 {0x9D, 0, 0, 0, 0},
10107 {0x9E, 0, 0, 0, 0},
10108 {0x9F, 0x6, 0x6, 0, 0},
10109 {0xA0, 0x66, 0x66, 0, 0},
10110 {0xA1, 0x66, 0x66, 0, 0},
10111 {0xA2, 0x66, 0x66, 0, 0},
10112 {0xA3, 0x66, 0x66, 0, 0},
10113 {0xA4, 0x66, 0x66, 0, 0},
10114 {0xA5, 0x66, 0x66, 0, 0},
10115 {0xA6, 0x66, 0x66, 0, 0},
10116 {0xA7, 0x66, 0x66, 0, 0},
10117 {0xA8, 0x66, 0x66, 0, 0},
10118 {0xA9, 0x66, 0x66, 0, 0},
10119 {0xAA, 0x66, 0x66, 0, 0},
10120 {0xAB, 0x66, 0x66, 0, 0},
10121 {0xAC, 0x66, 0x66, 0, 0},
10122 {0xAD, 0x66, 0x66, 0, 0},
10123 {0xAE, 0x66, 0x66, 0, 0},
10124 {0xAF, 0x66, 0x66, 0, 0},
10125 {0xB0, 0x66, 0x66, 0, 0},
10126 {0xB1, 0x66, 0x66, 0, 0},
10127 {0xB2, 0x66, 0x66, 0, 0},
10128 {0xB3, 0xa, 0xa, 0, 0},
10129 {0xB4, 0, 0, 0, 0},
10130 {0xB5, 0, 0, 0, 0},
10131 {0xB6, 0, 0, 0, 0},
10132 {0xFFFF, 0, 0, 0, 0},
10133};
10134
10135static struct radio_regs regs_TX_2056_rev7[] = {
10136 {0x02, 0, 0, 0, 0},
10137 {0x03, 0, 0, 0, 0},
10138 {0x04, 0, 0, 0, 0},
10139 {0x05, 0, 0, 0, 0},
10140 {0x06, 0, 0, 0, 0},
10141 {0x07, 0, 0, 0, 0},
10142 {0x08, 0, 0, 0, 0},
10143 {0x09, 0, 0, 0, 0},
10144 {0x0A, 0, 0, 0, 0},
10145 {0x0B, 0, 0, 0, 0},
10146 {0x0C, 0, 0, 0, 0},
10147 {0x0D, 0, 0, 0, 0},
10148 {0x0E, 0, 0, 0, 0},
10149 {0x0F, 0, 0, 0, 0},
10150 {0x10, 0, 0, 0, 0},
10151 {0x11, 0, 0, 0, 0},
10152 {0x12, 0, 0, 0, 0},
10153 {0x13, 0, 0, 0, 0},
10154 {0x14, 0, 0, 0, 0},
10155 {0x15, 0, 0, 0, 0},
10156 {0x16, 0, 0, 0, 0},
10157 {0x17, 0, 0, 0, 0},
10158 {0x18, 0, 0, 0, 0},
10159 {0x19, 0, 0, 0, 0},
10160 {0x1A, 0, 0, 0, 0},
10161 {0x1B, 0, 0, 0, 0},
10162 {0x1C, 0, 0, 0, 0},
10163 {0x1D, 0, 0, 0, 0},
10164 {0x1E, 0, 0, 0, 0},
10165 {0x1F, 0, 0, 0, 0},
10166 {0x20, 0, 0, 0, 0},
10167 {0x21, 0x88, 0x88, 0, 0},
10168 {0x22, 0x88, 0x88, 0, 0},
10169 {0x23, 0x88, 0x88, 0, 0},
10170 {0x24, 0x88, 0x88, 0, 0},
10171 {0x25, 0xc, 0xc, 0, 0},
10172 {0x26, 0, 0, 0, 0},
10173 {0x27, 0x3, 0x3, 0, 0},
10174 {0x28, 0, 0, 0, 0},
10175 {0x29, 0x3, 0x3, 0, 0},
10176 {0x2A, 0x37, 0x37, 0, 0},
10177 {0x2B, 0x3, 0x3, 0, 0},
10178 {0x2C, 0, 0, 0, 0},
10179 {0x2D, 0, 0, 0, 0},
10180 {0x2E, 0x1, 0x1, 0, 0},
10181 {0x2F, 0x1, 0x1, 0, 0},
10182 {0x30, 0, 0, 0, 0},
10183 {0x31, 0, 0, 0, 0},
10184 {0x32, 0, 0, 0, 0},
10185 {0x33, 0x11, 0x11, 0, 0},
10186 {0x34, 0xee, 0xee, 1, 1},
10187 {0x35, 0, 0, 0, 0},
10188 {0x36, 0, 0, 0, 0},
10189 {0x37, 0x3, 0x3, 0, 0},
10190 {0x38, 0x50, 0x50, 1, 1},
10191 {0x39, 0, 0, 0, 0},
10192 {0x3A, 0x50, 0x50, 1, 1},
10193 {0x3B, 0, 0, 0, 0},
10194 {0x3C, 0x6e, 0x6e, 0, 0},
10195 {0x3D, 0xf0, 0xf0, 1, 1},
10196 {0x3E, 0, 0, 0, 0},
10197 {0x3F, 0, 0, 0, 0},
10198 {0x40, 0, 0, 0, 0},
10199 {0x41, 0x3, 0x3, 0, 0},
10200 {0x42, 0x3, 0x3, 0, 0},
10201 {0x43, 0, 0, 0, 0},
10202 {0x44, 0x1e, 0x1e, 0, 0},
10203 {0x45, 0, 0, 0, 0},
10204 {0x46, 0x6e, 0x6e, 0, 0},
10205 {0x47, 0xf0, 0xf0, 1, 1},
10206 {0x48, 0, 0, 0, 0},
10207 {0x49, 0x2, 0x2, 0, 0},
10208 {0x4A, 0xff, 0xff, 1, 1},
10209 {0x4B, 0xc, 0xc, 0, 0},
10210 {0x4C, 0, 0, 0, 0},
10211 {0x4D, 0x38, 0x38, 0, 0},
10212 {0x4E, 0x70, 0x70, 1, 1},
10213 {0x4F, 0x2, 0x2, 0, 0},
10214 {0x50, 0x88, 0x88, 0, 0},
10215 {0x51, 0xc, 0xc, 0, 0},
10216 {0x52, 0, 0, 0, 0},
10217 {0x53, 0x8, 0x8, 0, 0},
10218 {0x54, 0x70, 0x70, 1, 1},
10219 {0x55, 0x2, 0x2, 0, 0},
10220 {0x56, 0xff, 0xff, 1, 1},
10221 {0x57, 0, 0, 0, 0},
10222 {0x58, 0x83, 0x83, 0, 0},
10223 {0x59, 0x77, 0x77, 1, 1},
10224 {0x5A, 0, 0, 0, 0},
10225 {0x5B, 0x2, 0x2, 0, 0},
10226 {0x5C, 0x88, 0x88, 0, 0},
10227 {0x5D, 0, 0, 0, 0},
10228 {0x5E, 0x8, 0x8, 0, 0},
10229 {0x5F, 0x77, 0x77, 1, 1},
10230 {0x60, 0x1, 0x1, 0, 0},
10231 {0x61, 0, 0, 0, 0},
10232 {0x62, 0x7, 0x7, 0, 0},
10233 {0x63, 0, 0, 0, 0},
10234 {0x64, 0x7, 0x7, 0, 0},
10235 {0x65, 0, 0, 0, 0},
10236 {0x66, 0, 0, 0, 0},
10237 {0x67, 0, 0, 1, 1},
10238 {0x68, 0, 0, 0, 0},
10239 {0x69, 0xa, 0xa, 0, 0},
10240 {0x6A, 0, 0, 0, 0},
10241 {0x6B, 0, 0, 0, 0},
10242 {0x6C, 0, 0, 0, 0},
10243 {0x6D, 0, 0, 0, 0},
10244 {0x6E, 0, 0, 0, 0},
10245 {0x6F, 0, 0, 0, 0},
10246 {0x70, 0, 0, 0, 0},
10247 {0x71, 0x2, 0x2, 0, 0},
10248 {0x72, 0, 0, 0, 0},
10249 {0x73, 0, 0, 0, 0},
10250 {0x74, 0xe, 0xe, 0, 0},
10251 {0x75, 0xe, 0xe, 0, 0},
10252 {0x76, 0xe, 0xe, 0, 0},
10253 {0x77, 0x13, 0x13, 0, 0},
10254 {0x78, 0x13, 0x13, 0, 0},
10255 {0x79, 0x1b, 0x1b, 0, 0},
10256 {0x7A, 0x1b, 0x1b, 0, 0},
10257 {0x7B, 0x55, 0x55, 0, 0},
10258 {0x7C, 0x5b, 0x5b, 0, 0},
10259 {0x7D, 0x30, 0x30, 1, 1},
10260 {0x7E, 0, 0, 0, 0},
10261 {0x7F, 0, 0, 0, 0},
10262 {0x80, 0, 0, 0, 0},
10263 {0x81, 0, 0, 0, 0},
10264 {0x82, 0, 0, 0, 0},
10265 {0x83, 0, 0, 0, 0},
10266 {0x84, 0, 0, 0, 0},
10267 {0x85, 0, 0, 0, 0},
10268 {0x86, 0, 0, 0, 0},
10269 {0x87, 0, 0, 0, 0},
10270 {0x88, 0, 0, 0, 0},
10271 {0x89, 0, 0, 0, 0},
10272 {0x8A, 0, 0, 0, 0},
10273 {0x8B, 0, 0, 0, 0},
10274 {0x8C, 0, 0, 0, 0},
10275 {0x8D, 0, 0, 0, 0},
10276 {0x8E, 0, 0, 0, 0},
10277 {0x8F, 0, 0, 0, 0},
10278 {0x90, 0, 0, 0, 0},
10279 {0x91, 0, 0, 0, 0},
10280 {0x92, 0, 0, 0, 0},
10281 {0x93, 0x70, 0x70, 0, 0},
10282 {0x94, 0x70, 0x70, 0, 0},
10283 {0x95, 0x71, 0x71, 1, 1},
10284 {0x96, 0x71, 0x71, 1, 1},
10285 {0x97, 0x72, 0x72, 1, 1},
10286 {0x98, 0x73, 0x73, 1, 1},
10287 {0x99, 0x74, 0x74, 1, 1},
10288 {0x9A, 0x75, 0x75, 1, 1},
10289 {0xFFFF, 0, 0, 0, 0},
10290};
10291
10292static struct radio_regs regs_RX_2056_rev7[] = {
10293 {0x02, 0, 0, 0, 0},
10294 {0x03, 0, 0, 0, 0},
10295 {0x04, 0, 0, 0, 0},
10296 {0x05, 0, 0, 0, 0},
10297 {0x06, 0, 0, 0, 0},
10298 {0x07, 0, 0, 0, 0},
10299 {0x08, 0, 0, 0, 0},
10300 {0x09, 0, 0, 0, 0},
10301 {0x0A, 0, 0, 0, 0},
10302 {0x0B, 0, 0, 0, 0},
10303 {0x0C, 0, 0, 0, 0},
10304 {0x0D, 0, 0, 0, 0},
10305 {0x0E, 0, 0, 0, 0},
10306 {0x0F, 0, 0, 0, 0},
10307 {0x10, 0, 0, 0, 0},
10308 {0x11, 0, 0, 0, 0},
10309 {0x12, 0, 0, 0, 0},
10310 {0x13, 0, 0, 0, 0},
10311 {0x14, 0, 0, 0, 0},
10312 {0x15, 0, 0, 0, 0},
10313 {0x16, 0, 0, 0, 0},
10314 {0x17, 0, 0, 0, 0},
10315 {0x18, 0, 0, 0, 0},
10316 {0x19, 0, 0, 0, 0},
10317 {0x1A, 0, 0, 0, 0},
10318 {0x1B, 0, 0, 0, 0},
10319 {0x1C, 0, 0, 0, 0},
10320 {0x1D, 0, 0, 0, 0},
10321 {0x1E, 0, 0, 0, 0},
10322 {0x1F, 0, 0, 0, 0},
10323 {0x20, 0x3, 0x3, 0, 0},
10324 {0x21, 0, 0, 0, 0},
10325 {0x22, 0, 0, 0, 0},
10326 {0x23, 0x90, 0x90, 0, 0},
10327 {0x24, 0x55, 0x55, 0, 0},
10328 {0x25, 0x15, 0x15, 0, 0},
10329 {0x26, 0x5, 0x5, 0, 0},
10330 {0x27, 0x15, 0x15, 0, 0},
10331 {0x28, 0x5, 0x5, 0, 0},
10332 {0x29, 0x20, 0x20, 0, 0},
10333 {0x2A, 0x11, 0x11, 0, 0},
10334 {0x2B, 0x90, 0x90, 0, 0},
10335 {0x2C, 0, 0, 0, 0},
10336 {0x2D, 0x88, 0x88, 0, 0},
10337 {0x2E, 0x32, 0x32, 0, 0},
10338 {0x2F, 0x77, 0x77, 0, 0},
10339 {0x30, 0x17, 0x17, 1, 1},
10340 {0x31, 0xff, 0xff, 1, 1},
10341 {0x32, 0x20, 0x20, 0, 0},
10342 {0x33, 0, 0, 0, 0},
10343 {0x34, 0x88, 0x88, 0, 0},
10344 {0x35, 0x32, 0x32, 0, 0},
10345 {0x36, 0x77, 0x77, 0, 0},
10346 {0x37, 0x17, 0x17, 1, 1},
10347 {0x38, 0xf0, 0xf0, 1, 1},
10348 {0x39, 0x20, 0x20, 0, 0},
10349 {0x3A, 0x8, 0x8, 0, 0},
10350 {0x3B, 0x55, 0x55, 1, 1},
10351 {0x3C, 0, 0, 0, 0},
10352 {0x3D, 0x88, 0x88, 1, 1},
10353 {0x3E, 0, 0, 0, 0},
10354 {0x3F, 0, 0, 1, 1},
10355 {0x40, 0x7, 0x7, 1, 1},
10356 {0x41, 0x6, 0x6, 0, 0},
10357 {0x42, 0x4, 0x4, 0, 0},
10358 {0x43, 0, 0, 0, 0},
10359 {0x44, 0x8, 0x8, 0, 0},
10360 {0x45, 0x55, 0x55, 1, 1},
10361 {0x46, 0, 0, 0, 0},
10362 {0x47, 0x11, 0x11, 0, 0},
10363 {0x48, 0, 0, 0, 0},
10364 {0x49, 0, 0, 1, 1},
10365 {0x4A, 0x7, 0x7, 0, 0},
10366 {0x4B, 0x6, 0x6, 0, 0},
10367 {0x4C, 0x4, 0x4, 0, 0},
10368 {0x4D, 0, 0, 0, 0},
10369 {0x4E, 0, 0, 0, 0},
10370 {0x4F, 0x26, 0x26, 1, 1},
10371 {0x50, 0x26, 0x26, 1, 1},
10372 {0x51, 0xf, 0xf, 1, 1},
10373 {0x52, 0xf, 0xf, 1, 1},
10374 {0x53, 0x44, 0x44, 0, 0},
10375 {0x54, 0, 0, 0, 0},
10376 {0x55, 0, 0, 0, 0},
10377 {0x56, 0x8, 0x8, 0, 0},
10378 {0x57, 0x8, 0x8, 0, 0},
10379 {0x58, 0x7, 0x7, 0, 0},
10380 {0x59, 0x22, 0x22, 0, 0},
10381 {0x5A, 0x22, 0x22, 0, 0},
10382 {0x5B, 0x2, 0x2, 0, 0},
10383 {0x5C, 0x4, 0x4, 1, 1},
10384 {0x5D, 0x7, 0x7, 0, 0},
10385 {0x5E, 0x55, 0x55, 0, 0},
10386 {0x5F, 0x23, 0x23, 0, 0},
10387 {0x60, 0x41, 0x41, 0, 0},
10388 {0x61, 0x1, 0x1, 0, 0},
10389 {0x62, 0xa, 0xa, 0, 0},
10390 {0x63, 0, 0, 0, 0},
10391 {0x64, 0, 0, 0, 0},
10392 {0x65, 0, 0, 0, 0},
10393 {0x66, 0, 0, 0, 0},
10394 {0x67, 0, 0, 0, 0},
10395 {0x68, 0, 0, 0, 0},
10396 {0x69, 0, 0, 0, 0},
10397 {0x6A, 0, 0, 0, 0},
10398 {0x6B, 0xc, 0xc, 0, 0},
10399 {0x6C, 0, 0, 0, 0},
10400 {0x6D, 0, 0, 0, 0},
10401 {0x6E, 0, 0, 0, 0},
10402 {0x6F, 0, 0, 0, 0},
10403 {0x70, 0, 0, 0, 0},
10404 {0x71, 0, 0, 0, 0},
10405 {0x72, 0x22, 0x22, 0, 0},
10406 {0x73, 0x22, 0x22, 0, 0},
10407 {0x74, 0, 0, 1, 1},
10408 {0x75, 0xa, 0xa, 0, 0},
10409 {0x76, 0x1, 0x1, 0, 0},
10410 {0x77, 0x22, 0x22, 0, 0},
10411 {0x78, 0x30, 0x30, 0, 0},
10412 {0x79, 0, 0, 0, 0},
10413 {0x7A, 0, 0, 0, 0},
10414 {0x7B, 0, 0, 0, 0},
10415 {0x7C, 0, 0, 0, 0},
10416 {0x7D, 0, 0, 0, 0},
10417 {0x7E, 0, 0, 0, 0},
10418 {0x7F, 0, 0, 0, 0},
10419 {0x80, 0, 0, 0, 0},
10420 {0x81, 0, 0, 0, 0},
10421 {0x82, 0, 0, 0, 0},
10422 {0x83, 0, 0, 0, 0},
10423 {0x84, 0, 0, 0, 0},
10424 {0x85, 0, 0, 0, 0},
10425 {0x86, 0, 0, 0, 0},
10426 {0x87, 0, 0, 0, 0},
10427 {0x88, 0, 0, 0, 0},
10428 {0x89, 0, 0, 0, 0},
10429 {0x8A, 0, 0, 0, 0},
10430 {0x8B, 0, 0, 0, 0},
10431 {0x8C, 0, 0, 0, 0},
10432 {0x8D, 0, 0, 0, 0},
10433 {0x8E, 0, 0, 0, 0},
10434 {0x8F, 0, 0, 0, 0},
10435 {0x90, 0, 0, 0, 0},
10436 {0x91, 0, 0, 0, 0},
10437 {0x92, 0, 0, 0, 0},
10438 {0x93, 0, 0, 0, 0},
10439 {0x94, 0, 0, 0, 0},
10440 {0xFFFF, 0, 0, 0, 0},
10441};
10442
10443static struct radio_regs regs_SYN_2056_rev8[] = {
10444 {0x02, 0, 0, 0, 0},
10445 {0x03, 0, 0, 0, 0},
10446 {0x04, 0, 0, 0, 0},
10447 {0x05, 0, 0, 0, 0},
10448 {0x06, 0, 0, 0, 0},
10449 {0x07, 0, 0, 0, 0},
10450 {0x08, 0, 0, 0, 0},
10451 {0x09, 0x1, 0x1, 0, 0},
10452 {0x0A, 0, 0, 0, 0},
10453 {0x0B, 0, 0, 0, 0},
10454 {0x0C, 0, 0, 0, 0},
10455 {0x0D, 0, 0, 0, 0},
10456 {0x0E, 0, 0, 0, 0},
10457 {0x0F, 0, 0, 0, 0},
10458 {0x10, 0, 0, 0, 0},
10459 {0x11, 0, 0, 0, 0},
10460 {0x12, 0, 0, 0, 0},
10461 {0x13, 0, 0, 0, 0},
10462 {0x14, 0, 0, 0, 0},
10463 {0x15, 0, 0, 0, 0},
10464 {0x16, 0, 0, 0, 0},
10465 {0x17, 0, 0, 0, 0},
10466 {0x18, 0, 0, 0, 0},
10467 {0x19, 0, 0, 0, 0},
10468 {0x1A, 0, 0, 0, 0},
10469 {0x1B, 0, 0, 0, 0},
10470 {0x1C, 0, 0, 0, 0},
10471 {0x1D, 0, 0, 0, 0},
10472 {0x1E, 0, 0, 0, 0},
10473 {0x1F, 0, 0, 0, 0},
10474 {0x20, 0, 0, 0, 0},
10475 {0x21, 0, 0, 0, 0},
10476 {0x22, 0x60, 0x60, 0, 0},
10477 {0x23, 0x6, 0x6, 0, 0},
10478 {0x24, 0xc, 0xc, 0, 0},
10479 {0x25, 0, 0, 0, 0},
10480 {0x26, 0, 0, 0, 0},
10481 {0x27, 0, 0, 0, 0},
10482 {0x28, 0x1, 0x1, 0, 0},
10483 {0x29, 0, 0, 0, 0},
10484 {0x2A, 0, 0, 0, 0},
10485 {0x2B, 0, 0, 0, 0},
10486 {0x2C, 0, 0, 0, 0},
10487 {0x2D, 0, 0, 0, 0},
10488 {0x2E, 0, 0, 0, 0},
10489 {0x2F, 0x1f, 0x1f, 0, 0},
10490 {0x30, 0x15, 0x15, 0, 0},
10491 {0x31, 0xf, 0xf, 0, 0},
10492 {0x32, 0, 0, 0, 0},
10493 {0x33, 0, 0, 0, 0},
10494 {0x34, 0, 0, 0, 0},
10495 {0x35, 0, 0, 0, 0},
10496 {0x36, 0, 0, 0, 0},
10497 {0x37, 0, 0, 0, 0},
10498 {0x38, 0, 0, 0, 0},
10499 {0x39, 0, 0, 0, 0},
10500 {0x3A, 0, 0, 0, 0},
10501 {0x3B, 0, 0, 0, 0},
10502 {0x3C, 0x13, 0x13, 0, 0},
10503 {0x3D, 0xf, 0xf, 0, 0},
10504 {0x3E, 0x18, 0x18, 0, 0},
10505 {0x3F, 0, 0, 0, 0},
10506 {0x40, 0, 0, 0, 0},
10507 {0x41, 0x20, 0x20, 0, 0},
10508 {0x42, 0x20, 0x20, 0, 0},
10509 {0x43, 0, 0, 0, 0},
10510 {0x44, 0x77, 0x77, 0, 0},
10511 {0x45, 0x7, 0x7, 0, 0},
10512 {0x46, 0x1, 0x1, 0, 0},
10513 {0x47, 0x4, 0x4, 0, 0},
10514 {0x48, 0xf, 0xf, 0, 0},
10515 {0x49, 0x30, 0x30, 0, 0},
10516 {0x4A, 0x32, 0x32, 0, 0},
10517 {0x4B, 0xd, 0xd, 0, 0},
10518 {0x4C, 0xd, 0xd, 0, 0},
10519 {0x4D, 0x4, 0x4, 0, 0},
10520 {0x4E, 0x6, 0x6, 0, 0},
10521 {0x4F, 0x1, 0x1, 0, 0},
10522 {0x50, 0x1c, 0x1c, 0, 0},
10523 {0x51, 0x2, 0x2, 0, 0},
10524 {0x52, 0x2, 0x2, 0, 0},
10525 {0x53, 0xf7, 0xf7, 1, 1},
10526 {0x54, 0xb4, 0xb4, 0, 0},
10527 {0x55, 0xd2, 0xd2, 0, 0},
10528 {0x56, 0, 0, 0, 0},
10529 {0x57, 0, 0, 0, 0},
10530 {0x58, 0x4, 0x4, 0, 0},
10531 {0x59, 0x96, 0x96, 0, 0},
10532 {0x5A, 0x3e, 0x3e, 0, 0},
10533 {0x5B, 0x3e, 0x3e, 0, 0},
10534 {0x5C, 0x13, 0x13, 0, 0},
10535 {0x5D, 0x2, 0x2, 0, 0},
10536 {0x5E, 0, 0, 0, 0},
10537 {0x5F, 0x7, 0x7, 0, 0},
10538 {0x60, 0x7, 0x7, 1, 1},
10539 {0x61, 0x8, 0x8, 0, 0},
10540 {0x62, 0x3, 0x3, 0, 0},
10541 {0x63, 0, 0, 0, 0},
10542 {0x64, 0, 0, 0, 0},
10543 {0x65, 0, 0, 0, 0},
10544 {0x66, 0, 0, 0, 0},
10545 {0x67, 0, 0, 0, 0},
10546 {0x68, 0x40, 0x40, 0, 0},
10547 {0x69, 0, 0, 0, 0},
10548 {0x6A, 0, 0, 0, 0},
10549 {0x6B, 0, 0, 0, 0},
10550 {0x6C, 0, 0, 0, 0},
10551 {0x6D, 0x1, 0x1, 0, 0},
10552 {0x6E, 0, 0, 0, 0},
10553 {0x6F, 0, 0, 0, 0},
10554 {0x70, 0x60, 0x60, 0, 0},
10555 {0x71, 0x66, 0x66, 0, 0},
10556 {0x72, 0xc, 0xc, 0, 0},
10557 {0x73, 0x66, 0x66, 0, 0},
10558 {0x74, 0x8f, 0x8f, 1, 1},
10559 {0x75, 0, 0, 0, 0},
10560 {0x76, 0xcc, 0xcc, 0, 0},
10561 {0x77, 0x1, 0x1, 0, 0},
10562 {0x78, 0x66, 0x66, 0, 0},
10563 {0x79, 0x66, 0x66, 0, 0},
10564 {0x7A, 0, 0, 0, 0},
10565 {0x7B, 0, 0, 0, 0},
10566 {0x7C, 0, 0, 0, 0},
10567 {0x7D, 0, 0, 0, 0},
10568 {0x7E, 0, 0, 0, 0},
10569 {0x7F, 0, 0, 0, 0},
10570 {0x80, 0, 0, 0, 0},
10571 {0x81, 0, 0, 0, 0},
10572 {0x82, 0, 0, 0, 0},
10573 {0x83, 0, 0, 0, 0},
10574 {0x84, 0, 0, 0, 0},
10575 {0x85, 0xff, 0xff, 0, 0},
10576 {0x86, 0, 0, 0, 0},
10577 {0x87, 0, 0, 0, 0},
10578 {0x88, 0, 0, 0, 0},
10579 {0x89, 0, 0, 0, 0},
10580 {0x8A, 0, 0, 0, 0},
10581 {0x8B, 0, 0, 0, 0},
10582 {0x8C, 0, 0, 0, 0},
10583 {0x8D, 0, 0, 0, 0},
10584 {0x8E, 0, 0, 0, 0},
10585 {0x8F, 0, 0, 0, 0},
10586 {0x90, 0, 0, 0, 0},
10587 {0x91, 0, 0, 0, 0},
10588 {0x92, 0, 0, 0, 0},
10589 {0x93, 0, 0, 0, 0},
10590 {0x94, 0, 0, 0, 0},
10591 {0x95, 0, 0, 0, 0},
10592 {0x96, 0, 0, 0, 0},
10593 {0x97, 0, 0, 0, 0},
10594 {0x98, 0, 0, 0, 0},
10595 {0x99, 0, 0, 0, 0},
10596 {0x9A, 0, 0, 0, 0},
10597 {0x9B, 0, 0, 0, 0},
10598 {0x9C, 0, 0, 0, 0},
10599 {0x9D, 0, 0, 0, 0},
10600 {0x9E, 0, 0, 0, 0},
10601 {0x9F, 0x6, 0x6, 0, 0},
10602 {0xA0, 0x66, 0x66, 0, 0},
10603 {0xA1, 0x66, 0x66, 0, 0},
10604 {0xA2, 0x66, 0x66, 0, 0},
10605 {0xA3, 0x66, 0x66, 0, 0},
10606 {0xA4, 0x66, 0x66, 0, 0},
10607 {0xA5, 0x66, 0x66, 0, 0},
10608 {0xA6, 0x66, 0x66, 0, 0},
10609 {0xA7, 0x66, 0x66, 0, 0},
10610 {0xA8, 0x66, 0x66, 0, 0},
10611 {0xA9, 0x66, 0x66, 0, 0},
10612 {0xAA, 0x66, 0x66, 0, 0},
10613 {0xAB, 0x66, 0x66, 0, 0},
10614 {0xAC, 0x66, 0x66, 0, 0},
10615 {0xAD, 0x66, 0x66, 0, 0},
10616 {0xAE, 0x66, 0x66, 0, 0},
10617 {0xAF, 0x66, 0x66, 0, 0},
10618 {0xB0, 0x66, 0x66, 0, 0},
10619 {0xB1, 0x66, 0x66, 0, 0},
10620 {0xB2, 0x66, 0x66, 0, 0},
10621 {0xB3, 0xa, 0xa, 0, 0},
10622 {0xB4, 0, 0, 0, 0},
10623 {0xB5, 0, 0, 0, 0},
10624 {0xB6, 0, 0, 0, 0},
10625 {0xFFFF, 0, 0, 0, 0},
10626};
10627
10628static struct radio_regs regs_TX_2056_rev8[] = {
10629 {0x02, 0, 0, 0, 0},
10630 {0x03, 0, 0, 0, 0},
10631 {0x04, 0, 0, 0, 0},
10632 {0x05, 0, 0, 0, 0},
10633 {0x06, 0, 0, 0, 0},
10634 {0x07, 0, 0, 0, 0},
10635 {0x08, 0, 0, 0, 0},
10636 {0x09, 0, 0, 0, 0},
10637 {0x0A, 0, 0, 0, 0},
10638 {0x0B, 0, 0, 0, 0},
10639 {0x0C, 0, 0, 0, 0},
10640 {0x0D, 0, 0, 0, 0},
10641 {0x0E, 0, 0, 0, 0},
10642 {0x0F, 0, 0, 0, 0},
10643 {0x10, 0, 0, 0, 0},
10644 {0x11, 0, 0, 0, 0},
10645 {0x12, 0, 0, 0, 0},
10646 {0x13, 0, 0, 0, 0},
10647 {0x14, 0, 0, 0, 0},
10648 {0x15, 0, 0, 0, 0},
10649 {0x16, 0, 0, 0, 0},
10650 {0x17, 0, 0, 0, 0},
10651 {0x18, 0, 0, 0, 0},
10652 {0x19, 0, 0, 0, 0},
10653 {0x1A, 0, 0, 0, 0},
10654 {0x1B, 0, 0, 0, 0},
10655 {0x1C, 0, 0, 0, 0},
10656 {0x1D, 0, 0, 0, 0},
10657 {0x1E, 0, 0, 0, 0},
10658 {0x1F, 0, 0, 0, 0},
10659 {0x20, 0, 0, 0, 0},
10660 {0x21, 0x88, 0x88, 0, 0},
10661 {0x22, 0x88, 0x88, 0, 0},
10662 {0x23, 0x88, 0x88, 0, 0},
10663 {0x24, 0x88, 0x88, 0, 0},
10664 {0x25, 0xc, 0xc, 0, 0},
10665 {0x26, 0, 0, 0, 0},
10666 {0x27, 0x3, 0x3, 0, 0},
10667 {0x28, 0, 0, 0, 0},
10668 {0x29, 0x3, 0x3, 0, 0},
10669 {0x2A, 0x37, 0x37, 0, 0},
10670 {0x2B, 0x3, 0x3, 0, 0},
10671 {0x2C, 0, 0, 0, 0},
10672 {0x2D, 0, 0, 0, 0},
10673 {0x2E, 0x1, 0x1, 0, 0},
10674 {0x2F, 0x1, 0x1, 0, 0},
10675 {0x30, 0, 0, 0, 0},
10676 {0x31, 0, 0, 0, 0},
10677 {0x32, 0, 0, 0, 0},
10678 {0x33, 0x11, 0x11, 0, 0},
10679 {0x34, 0xee, 0xee, 1, 1},
10680 {0x35, 0, 0, 0, 0},
10681 {0x36, 0, 0, 0, 0},
10682 {0x37, 0x3, 0x3, 0, 0},
10683 {0x38, 0x50, 0x50, 1, 1},
10684 {0x39, 0, 0, 0, 0},
10685 {0x3A, 0x50, 0x50, 1, 1},
10686 {0x3B, 0, 0, 0, 0},
10687 {0x3C, 0x6e, 0x6e, 0, 0},
10688 {0x3D, 0xf0, 0xf0, 1, 1},
10689 {0x3E, 0, 0, 0, 0},
10690 {0x3F, 0, 0, 0, 0},
10691 {0x40, 0, 0, 0, 0},
10692 {0x41, 0x3, 0x3, 0, 0},
10693 {0x42, 0x3, 0x3, 0, 0},
10694 {0x43, 0, 0, 0, 0},
10695 {0x44, 0x1e, 0x1e, 0, 0},
10696 {0x45, 0, 0, 0, 0},
10697 {0x46, 0x6e, 0x6e, 0, 0},
10698 {0x47, 0xf0, 0xf0, 1, 1},
10699 {0x48, 0, 0, 0, 0},
10700 {0x49, 0x2, 0x2, 0, 0},
10701 {0x4A, 0xff, 0xff, 1, 1},
10702 {0x4B, 0xc, 0xc, 0, 0},
10703 {0x4C, 0, 0, 0, 0},
10704 {0x4D, 0x38, 0x38, 0, 0},
10705 {0x4E, 0x70, 0x70, 1, 1},
10706 {0x4F, 0x2, 0x2, 0, 0},
10707 {0x50, 0x88, 0x88, 0, 0},
10708 {0x51, 0xc, 0xc, 0, 0},
10709 {0x52, 0, 0, 0, 0},
10710 {0x53, 0x8, 0x8, 0, 0},
10711 {0x54, 0x70, 0x70, 1, 1},
10712 {0x55, 0x2, 0x2, 0, 0},
10713 {0x56, 0xff, 0xff, 1, 1},
10714 {0x57, 0, 0, 0, 0},
10715 {0x58, 0x83, 0x83, 0, 0},
10716 {0x59, 0x77, 0x77, 1, 1},
10717 {0x5A, 0, 0, 0, 0},
10718 {0x5B, 0x2, 0x2, 0, 0},
10719 {0x5C, 0x88, 0x88, 0, 0},
10720 {0x5D, 0, 0, 0, 0},
10721 {0x5E, 0x8, 0x8, 0, 0},
10722 {0x5F, 0x77, 0x77, 1, 1},
10723 {0x60, 0x1, 0x1, 0, 0},
10724 {0x61, 0, 0, 0, 0},
10725 {0x62, 0x7, 0x7, 0, 0},
10726 {0x63, 0, 0, 0, 0},
10727 {0x64, 0x7, 0x7, 0, 0},
10728 {0x65, 0, 0, 0, 0},
10729 {0x66, 0, 0, 0, 0},
10730 {0x67, 0, 0, 1, 1},
10731 {0x68, 0, 0, 0, 0},
10732 {0x69, 0xa, 0xa, 0, 0},
10733 {0x6A, 0, 0, 0, 0},
10734 {0x6B, 0, 0, 0, 0},
10735 {0x6C, 0, 0, 0, 0},
10736 {0x6D, 0, 0, 0, 0},
10737 {0x6E, 0, 0, 0, 0},
10738 {0x6F, 0, 0, 0, 0},
10739 {0x70, 0, 0, 0, 0},
10740 {0x71, 0x2, 0x2, 0, 0},
10741 {0x72, 0, 0, 0, 0},
10742 {0x73, 0, 0, 0, 0},
10743 {0x74, 0xe, 0xe, 0, 0},
10744 {0x75, 0xe, 0xe, 0, 0},
10745 {0x76, 0xe, 0xe, 0, 0},
10746 {0x77, 0x13, 0x13, 0, 0},
10747 {0x78, 0x13, 0x13, 0, 0},
10748 {0x79, 0x1b, 0x1b, 0, 0},
10749 {0x7A, 0x1b, 0x1b, 0, 0},
10750 {0x7B, 0x55, 0x55, 0, 0},
10751 {0x7C, 0x5b, 0x5b, 0, 0},
10752 {0x7D, 0x30, 0x30, 1, 1},
10753 {0x7E, 0, 0, 0, 0},
10754 {0x7F, 0, 0, 0, 0},
10755 {0x80, 0, 0, 0, 0},
10756 {0x81, 0, 0, 0, 0},
10757 {0x82, 0, 0, 0, 0},
10758 {0x83, 0, 0, 0, 0},
10759 {0x84, 0, 0, 0, 0},
10760 {0x85, 0, 0, 0, 0},
10761 {0x86, 0, 0, 0, 0},
10762 {0x87, 0, 0, 0, 0},
10763 {0x88, 0, 0, 0, 0},
10764 {0x89, 0, 0, 0, 0},
10765 {0x8A, 0, 0, 0, 0},
10766 {0x8B, 0, 0, 0, 0},
10767 {0x8C, 0, 0, 0, 0},
10768 {0x8D, 0, 0, 0, 0},
10769 {0x8E, 0, 0, 0, 0},
10770 {0x8F, 0, 0, 0, 0},
10771 {0x90, 0, 0, 0, 0},
10772 {0x91, 0, 0, 0, 0},
10773 {0x92, 0, 0, 0, 0},
10774 {0x93, 0x70, 0x70, 0, 0},
10775 {0x94, 0x70, 0x70, 0, 0},
10776 {0x95, 0x70, 0x70, 0, 0},
10777 {0x96, 0x70, 0x70, 0, 0},
10778 {0x97, 0x70, 0x70, 0, 0},
10779 {0x98, 0x70, 0x70, 0, 0},
10780 {0x99, 0x70, 0x70, 0, 0},
10781 {0x9A, 0x70, 0x70, 0, 0},
10782 {0xFFFF, 0, 0, 0, 0},
10783};
10784
10785static struct radio_regs regs_RX_2056_rev8[] = {
10786 {0x02, 0, 0, 0, 0},
10787 {0x03, 0, 0, 0, 0},
10788 {0x04, 0, 0, 0, 0},
10789 {0x05, 0, 0, 0, 0},
10790 {0x06, 0, 0, 0, 0},
10791 {0x07, 0, 0, 0, 0},
10792 {0x08, 0, 0, 0, 0},
10793 {0x09, 0, 0, 0, 0},
10794 {0x0A, 0, 0, 0, 0},
10795 {0x0B, 0, 0, 0, 0},
10796 {0x0C, 0, 0, 0, 0},
10797 {0x0D, 0, 0, 0, 0},
10798 {0x0E, 0, 0, 0, 0},
10799 {0x0F, 0, 0, 0, 0},
10800 {0x10, 0, 0, 0, 0},
10801 {0x11, 0, 0, 0, 0},
10802 {0x12, 0, 0, 0, 0},
10803 {0x13, 0, 0, 0, 0},
10804 {0x14, 0, 0, 0, 0},
10805 {0x15, 0, 0, 0, 0},
10806 {0x16, 0, 0, 0, 0},
10807 {0x17, 0, 0, 0, 0},
10808 {0x18, 0, 0, 0, 0},
10809 {0x19, 0, 0, 0, 0},
10810 {0x1A, 0, 0, 0, 0},
10811 {0x1B, 0, 0, 0, 0},
10812 {0x1C, 0, 0, 0, 0},
10813 {0x1D, 0, 0, 0, 0},
10814 {0x1E, 0, 0, 0, 0},
10815 {0x1F, 0, 0, 0, 0},
10816 {0x20, 0x3, 0x3, 0, 0},
10817 {0x21, 0, 0, 0, 0},
10818 {0x22, 0, 0, 0, 0},
10819 {0x23, 0x90, 0x90, 0, 0},
10820 {0x24, 0x55, 0x55, 0, 0},
10821 {0x25, 0x15, 0x15, 0, 0},
10822 {0x26, 0x5, 0x5, 0, 0},
10823 {0x27, 0x15, 0x15, 0, 0},
10824 {0x28, 0x5, 0x5, 0, 0},
10825 {0x29, 0x20, 0x20, 0, 0},
10826 {0x2A, 0x11, 0x11, 0, 0},
10827 {0x2B, 0x90, 0x90, 0, 0},
10828 {0x2C, 0, 0, 0, 0},
10829 {0x2D, 0x88, 0x88, 0, 0},
10830 {0x2E, 0x32, 0x32, 0, 0},
10831 {0x2F, 0x77, 0x77, 0, 0},
10832 {0x30, 0x17, 0x17, 1, 1},
10833 {0x31, 0xff, 0xff, 1, 1},
10834 {0x32, 0x20, 0x20, 0, 0},
10835 {0x33, 0, 0, 0, 0},
10836 {0x34, 0x88, 0x88, 0, 0},
10837 {0x35, 0x32, 0x32, 0, 0},
10838 {0x36, 0x77, 0x77, 0, 0},
10839 {0x37, 0x17, 0x17, 1, 1},
10840 {0x38, 0xf0, 0xf0, 1, 1},
10841 {0x39, 0x20, 0x20, 0, 0},
10842 {0x3A, 0x8, 0x8, 0, 0},
10843 {0x3B, 0x55, 0x55, 1, 1},
10844 {0x3C, 0, 0, 0, 0},
10845 {0x3D, 0x88, 0x88, 1, 1},
10846 {0x3E, 0, 0, 0, 0},
10847 {0x3F, 0x44, 0x44, 0, 0},
10848 {0x40, 0x7, 0x7, 1, 1},
10849 {0x41, 0x6, 0x6, 0, 0},
10850 {0x42, 0x4, 0x4, 0, 0},
10851 {0x43, 0, 0, 0, 0},
10852 {0x44, 0x8, 0x8, 0, 0},
10853 {0x45, 0x55, 0x55, 1, 1},
10854 {0x46, 0, 0, 0, 0},
10855 {0x47, 0x11, 0x11, 0, 0},
10856 {0x48, 0, 0, 0, 0},
10857 {0x49, 0x44, 0x44, 0, 0},
10858 {0x4A, 0x7, 0x7, 0, 0},
10859 {0x4B, 0x6, 0x6, 0, 0},
10860 {0x4C, 0x4, 0x4, 0, 0},
10861 {0x4D, 0, 0, 0, 0},
10862 {0x4E, 0, 0, 0, 0},
10863 {0x4F, 0x26, 0x26, 1, 1},
10864 {0x50, 0x26, 0x26, 1, 1},
10865 {0x51, 0xf, 0xf, 1, 1},
10866 {0x52, 0xf, 0xf, 1, 1},
10867 {0x53, 0x44, 0x44, 0, 0},
10868 {0x54, 0, 0, 0, 0},
10869 {0x55, 0, 0, 0, 0},
10870 {0x56, 0x8, 0x8, 0, 0},
10871 {0x57, 0x8, 0x8, 0, 0},
10872 {0x58, 0x7, 0x7, 0, 0},
10873 {0x59, 0x22, 0x22, 0, 0},
10874 {0x5A, 0x22, 0x22, 0, 0},
10875 {0x5B, 0x2, 0x2, 0, 0},
10876 {0x5C, 0x4, 0x4, 1, 1},
10877 {0x5D, 0x7, 0x7, 0, 0},
10878 {0x5E, 0x55, 0x55, 0, 0},
10879 {0x5F, 0x23, 0x23, 0, 0},
10880 {0x60, 0x41, 0x41, 0, 0},
10881 {0x61, 0x1, 0x1, 0, 0},
10882 {0x62, 0xa, 0xa, 0, 0},
10883 {0x63, 0, 0, 0, 0},
10884 {0x64, 0, 0, 0, 0},
10885 {0x65, 0, 0, 0, 0},
10886 {0x66, 0, 0, 0, 0},
10887 {0x67, 0, 0, 0, 0},
10888 {0x68, 0, 0, 0, 0},
10889 {0x69, 0, 0, 0, 0},
10890 {0x6A, 0, 0, 0, 0},
10891 {0x6B, 0xc, 0xc, 0, 0},
10892 {0x6C, 0, 0, 0, 0},
10893 {0x6D, 0, 0, 0, 0},
10894 {0x6E, 0, 0, 0, 0},
10895 {0x6F, 0, 0, 0, 0},
10896 {0x70, 0, 0, 0, 0},
10897 {0x71, 0, 0, 0, 0},
10898 {0x72, 0x22, 0x22, 0, 0},
10899 {0x73, 0x22, 0x22, 0, 0},
10900 {0x74, 0, 0, 1, 1},
10901 {0x75, 0xa, 0xa, 0, 0},
10902 {0x76, 0x1, 0x1, 0, 0},
10903 {0x77, 0x22, 0x22, 0, 0},
10904 {0x78, 0x30, 0x30, 0, 0},
10905 {0x79, 0, 0, 0, 0},
10906 {0x7A, 0, 0, 0, 0},
10907 {0x7B, 0, 0, 0, 0},
10908 {0x7C, 0, 0, 0, 0},
10909 {0x7D, 0x5, 0x5, 1, 1},
10910 {0x7E, 0, 0, 0, 0},
10911 {0x7F, 0, 0, 0, 0},
10912 {0x80, 0, 0, 0, 0},
10913 {0x81, 0, 0, 0, 0},
10914 {0x82, 0, 0, 0, 0},
10915 {0x83, 0, 0, 0, 0},
10916 {0x84, 0, 0, 0, 0},
10917 {0x85, 0, 0, 0, 0},
10918 {0x86, 0, 0, 0, 0},
10919 {0x87, 0, 0, 0, 0},
10920 {0x88, 0, 0, 0, 0},
10921 {0x89, 0, 0, 0, 0},
10922 {0x8A, 0, 0, 0, 0},
10923 {0x8B, 0, 0, 0, 0},
10924 {0x8C, 0, 0, 0, 0},
10925 {0x8D, 0, 0, 0, 0},
10926 {0x8E, 0, 0, 0, 0},
10927 {0x8F, 0, 0, 0, 0},
10928 {0x90, 0, 0, 0, 0},
10929 {0x91, 0, 0, 0, 0},
10930 {0x92, 0, 0, 0, 0},
10931 {0x93, 0, 0, 0, 0},
10932 {0x94, 0, 0, 0, 0},
10933 {0xFFFF, 0, 0, 0, 0},
10934};
10935
10936static const struct radio_regs regs_SYN_2056_rev11[] = {
10937 {0x02, 0, 0, 0, 0},
10938 {0x03, 0, 0, 0, 0},
10939 {0x04, 0, 0, 0, 0},
10940 {0x05, 0, 0, 0, 0},
10941 {0x06, 0, 0, 0, 0},
10942 {0x07, 0, 0, 0, 0},
10943 {0x08, 0, 0, 0, 0},
10944 {0x09, 0x1, 0x1, 0, 0},
10945 {0x0A, 0, 0, 0, 0},
10946 {0x0B, 0, 0, 0, 0},
10947 {0x0C, 0, 0, 0, 0},
10948 {0x0D, 0, 0, 0, 0},
10949 {0x0E, 0, 0, 0, 0},
10950 {0x0F, 0, 0, 0, 0},
10951 {0x10, 0, 0, 0, 0},
10952 {0x11, 0, 0, 0, 0},
10953 {0x12, 0, 0, 0, 0},
10954 {0x13, 0, 0, 0, 0},
10955 {0x14, 0, 0, 0, 0},
10956 {0x15, 0, 0, 0, 0},
10957 {0x16, 0, 0, 0, 0},
10958 {0x17, 0, 0, 0, 0},
10959 {0x18, 0, 0, 0, 0},
10960 {0x19, 0, 0, 0, 0},
10961 {0x1A, 0, 0, 0, 0},
10962 {0x1B, 0, 0, 0, 0},
10963 {0x1C, 0, 0, 0, 0},
10964 {0x1D, 0, 0, 0, 0},
10965 {0x1E, 0, 0, 0, 0},
10966 {0x1F, 0, 0, 0, 0},
10967 {0x20, 0, 0, 0, 0},
10968 {0x21, 0, 0, 0, 0},
10969 {0x22, 0x60, 0x60, 0, 0},
10970 {0x23, 0x6, 0x6, 0, 0},
10971 {0x24, 0xc, 0xc, 0, 0},
10972 {0x25, 0, 0, 0, 0},
10973 {0x26, 0, 0, 0, 0},
10974 {0x27, 0, 0, 0, 0},
10975 {0x28, 0x1, 0x1, 0, 0},
10976 {0x29, 0, 0, 0, 0},
10977 {0x2A, 0, 0, 0, 0},
10978 {0x2B, 0, 0, 0, 0},
10979 {0x2C, 0, 0, 0, 0},
10980 {0x2D, 0, 0, 0, 0},
10981 {0x2E, 0, 0, 0, 0},
10982 {0x2F, 0x1f, 0x1f, 0, 0},
10983 {0x30, 0x15, 0x15, 0, 0},
10984 {0x31, 0xf, 0xf, 0, 0},
10985 {0x32, 0, 0, 0, 0},
10986 {0x33, 0, 0, 0, 0},
10987 {0x34, 0, 0, 0, 0},
10988 {0x35, 0, 0, 0, 0},
10989 {0x36, 0, 0, 0, 0},
10990 {0x37, 0, 0, 0, 0},
10991 {0x38, 0, 0, 0, 0},
10992 {0x39, 0, 0, 0, 0},
10993 {0x3A, 0, 0, 0, 0},
10994 {0x3B, 0, 0, 0, 0},
10995 {0x3C, 0x13, 0x13, 0, 0},
10996 {0x3D, 0xf, 0xf, 0, 0},
10997 {0x3E, 0x18, 0x18, 0, 0},
10998 {0x3F, 0, 0, 0, 0},
10999 {0x40, 0, 0, 0, 0},
11000 {0x41, 0x20, 0x20, 0, 0},
11001 {0x42, 0x20, 0x20, 0, 0},
11002 {0x43, 0, 0, 0, 0},
11003 {0x44, 0x77, 0x77, 0, 0},
11004 {0x45, 0x7, 0x7, 0, 0},
11005 {0x46, 0x1, 0x1, 0, 0},
11006 {0x47, 0x6, 0x6, 1, 1},
11007 {0x48, 0xf, 0xf, 0, 0},
11008 {0x49, 0x3f, 0x3f, 1, 1},
11009 {0x4A, 0x32, 0x32, 0, 0},
11010 {0x4B, 0x6, 0x6, 1, 1},
11011 {0x4C, 0x6, 0x6, 1, 1},
11012 {0x4D, 0x4, 0x4, 0, 0},
11013 {0x4E, 0x2b, 0x2b, 1, 1},
11014 {0x4F, 0x1, 0x1, 0, 0},
11015 {0x50, 0x1c, 0x1c, 0, 0},
11016 {0x51, 0x2, 0x2, 0, 0},
11017 {0x52, 0x2, 0x2, 0, 0},
11018 {0x53, 0xf7, 0xf7, 1, 1},
11019 {0x54, 0xb4, 0xb4, 0, 0},
11020 {0x55, 0xd2, 0xd2, 0, 0},
11021 {0x56, 0, 0, 0, 0},
11022 {0x57, 0, 0, 0, 0},
11023 {0x58, 0x4, 0x4, 0, 0},
11024 {0x59, 0x96, 0x96, 0, 0},
11025 {0x5A, 0x3e, 0x3e, 0, 0},
11026 {0x5B, 0x3e, 0x3e, 0, 0},
11027 {0x5C, 0x13, 0x13, 0, 0},
11028 {0x5D, 0x2, 0x2, 0, 0},
11029 {0x5E, 0, 0, 0, 0},
11030 {0x5F, 0x7, 0x7, 0, 0},
11031 {0x60, 0x7, 0x7, 1, 1},
11032 {0x61, 0x8, 0x8, 0, 0},
11033 {0x62, 0x3, 0x3, 0, 0},
11034 {0x63, 0, 0, 0, 0},
11035 {0x64, 0, 0, 0, 0},
11036 {0x65, 0, 0, 0, 0},
11037 {0x66, 0, 0, 0, 0},
11038 {0x67, 0, 0, 0, 0},
11039 {0x68, 0x40, 0x40, 0, 0},
11040 {0x69, 0, 0, 0, 0},
11041 {0x6A, 0, 0, 0, 0},
11042 {0x6B, 0, 0, 0, 0},
11043 {0x6C, 0, 0, 0, 0},
11044 {0x6D, 0x1, 0x1, 0, 0},
11045 {0x6E, 0, 0, 0, 0},
11046 {0x6F, 0, 0, 0, 0},
11047 {0x70, 0x60, 0x60, 0, 0},
11048 {0x71, 0x66, 0x66, 0, 0},
11049 {0x72, 0xc, 0xc, 0, 0},
11050 {0x73, 0x66, 0x66, 0, 0},
11051 {0x74, 0x8f, 0x8f, 1, 1},
11052 {0x75, 0, 0, 0, 0},
11053 {0x76, 0xcc, 0xcc, 0, 0},
11054 {0x77, 0x1, 0x1, 0, 0},
11055 {0x78, 0x66, 0x66, 0, 0},
11056 {0x79, 0x66, 0x66, 0, 0},
11057 {0x7A, 0, 0, 0, 0},
11058 {0x7B, 0, 0, 0, 0},
11059 {0x7C, 0, 0, 0, 0},
11060 {0x7D, 0, 0, 0, 0},
11061 {0x7E, 0, 0, 0, 0},
11062 {0x7F, 0, 0, 0, 0},
11063 {0x80, 0, 0, 0, 0},
11064 {0x81, 0, 0, 0, 0},
11065 {0x82, 0, 0, 0, 0},
11066 {0x83, 0, 0, 0, 0},
11067 {0x84, 0, 0, 0, 0},
11068 {0x85, 0xff, 0xff, 0, 0},
11069 {0x86, 0, 0, 0, 0},
11070 {0x87, 0, 0, 0, 0},
11071 {0x88, 0, 0, 0, 0},
11072 {0x89, 0, 0, 0, 0},
11073 {0x8A, 0, 0, 0, 0},
11074 {0x8B, 0, 0, 0, 0},
11075 {0x8C, 0, 0, 0, 0},
11076 {0x8D, 0, 0, 0, 0},
11077 {0x8E, 0, 0, 0, 0},
11078 {0x8F, 0, 0, 0, 0},
11079 {0x90, 0, 0, 0, 0},
11080 {0x91, 0, 0, 0, 0},
11081 {0x92, 0, 0, 0, 0},
11082 {0x93, 0, 0, 0, 0},
11083 {0x94, 0, 0, 0, 0},
11084 {0x95, 0, 0, 0, 0},
11085 {0x96, 0, 0, 0, 0},
11086 {0x97, 0, 0, 0, 0},
11087 {0x98, 0, 0, 0, 0},
11088 {0x99, 0, 0, 0, 0},
11089 {0x9A, 0, 0, 0, 0},
11090 {0x9B, 0, 0, 0, 0},
11091 {0x9C, 0, 0, 0, 0},
11092 {0x9D, 0, 0, 0, 0},
11093 {0x9E, 0, 0, 0, 0},
11094 {0x9F, 0x6, 0x6, 0, 0},
11095 {0xA0, 0x66, 0x66, 0, 0},
11096 {0xA1, 0x66, 0x66, 0, 0},
11097 {0xA2, 0x66, 0x66, 0, 0},
11098 {0xA3, 0x66, 0x66, 0, 0},
11099 {0xA4, 0x66, 0x66, 0, 0},
11100 {0xA5, 0x66, 0x66, 0, 0},
11101 {0xA6, 0x66, 0x66, 0, 0},
11102 {0xA7, 0x66, 0x66, 0, 0},
11103 {0xA8, 0x66, 0x66, 0, 0},
11104 {0xA9, 0x66, 0x66, 0, 0},
11105 {0xAA, 0x66, 0x66, 0, 0},
11106 {0xAB, 0x66, 0x66, 0, 0},
11107 {0xAC, 0x66, 0x66, 0, 0},
11108 {0xAD, 0x66, 0x66, 0, 0},
11109 {0xAE, 0x66, 0x66, 0, 0},
11110 {0xAF, 0x66, 0x66, 0, 0},
11111 {0xB0, 0x66, 0x66, 0, 0},
11112 {0xB1, 0x66, 0x66, 0, 0},
11113 {0xB2, 0x66, 0x66, 0, 0},
11114 {0xB3, 0xa, 0xa, 0, 0},
11115 {0xB4, 0, 0, 0, 0},
11116 {0xB5, 0, 0, 0, 0},
11117 {0xB6, 0, 0, 0, 0},
11118 {0xFFFF, 0, 0, 0, 0},
11119};
11120
11121static const struct radio_regs regs_TX_2056_rev11[] = {
11122 {0x02, 0, 0, 0, 0},
11123 {0x03, 0, 0, 0, 0},
11124 {0x04, 0, 0, 0, 0},
11125 {0x05, 0, 0, 0, 0},
11126 {0x06, 0, 0, 0, 0},
11127 {0x07, 0, 0, 0, 0},
11128 {0x08, 0, 0, 0, 0},
11129 {0x09, 0, 0, 0, 0},
11130 {0x0A, 0, 0, 0, 0},
11131 {0x0B, 0, 0, 0, 0},
11132 {0x0C, 0, 0, 0, 0},
11133 {0x0D, 0, 0, 0, 0},
11134 {0x0E, 0, 0, 0, 0},
11135 {0x0F, 0, 0, 0, 0},
11136 {0x10, 0, 0, 0, 0},
11137 {0x11, 0, 0, 0, 0},
11138 {0x12, 0, 0, 0, 0},
11139 {0x13, 0, 0, 0, 0},
11140 {0x14, 0, 0, 0, 0},
11141 {0x15, 0, 0, 0, 0},
11142 {0x16, 0, 0, 0, 0},
11143 {0x17, 0, 0, 0, 0},
11144 {0x18, 0, 0, 0, 0},
11145 {0x19, 0, 0, 0, 0},
11146 {0x1A, 0, 0, 0, 0},
11147 {0x1B, 0, 0, 0, 0},
11148 {0x1C, 0, 0, 0, 0},
11149 {0x1D, 0, 0, 0, 0},
11150 {0x1E, 0, 0, 0, 0},
11151 {0x1F, 0, 0, 0, 0},
11152 {0x20, 0, 0, 0, 0},
11153 {0x21, 0x88, 0x88, 0, 0},
11154 {0x22, 0x88, 0x88, 0, 0},
11155 {0x23, 0x88, 0x88, 0, 0},
11156 {0x24, 0x88, 0x88, 0, 0},
11157 {0x25, 0xc, 0xc, 0, 0},
11158 {0x26, 0, 0, 0, 0},
11159 {0x27, 0x3, 0x3, 0, 0},
11160 {0x28, 0, 0, 0, 0},
11161 {0x29, 0x3, 0x3, 0, 0},
11162 {0x2A, 0x37, 0x37, 0, 0},
11163 {0x2B, 0x3, 0x3, 0, 0},
11164 {0x2C, 0, 0, 0, 0},
11165 {0x2D, 0, 0, 0, 0},
11166 {0x2E, 0x1, 0x1, 0, 0},
11167 {0x2F, 0x1, 0x1, 0, 0},
11168 {0x30, 0, 0, 0, 0},
11169 {0x31, 0, 0, 0, 0},
11170 {0x32, 0, 0, 0, 0},
11171 {0x33, 0x11, 0x11, 0, 0},
11172 {0x34, 0xee, 0xee, 1, 1},
11173 {0x35, 0, 0, 0, 0},
11174 {0x36, 0, 0, 0, 0},
11175 {0x37, 0x3, 0x3, 0, 0},
11176 {0x38, 0x50, 0x50, 1, 1},
11177 {0x39, 0, 0, 0, 0},
11178 {0x3A, 0x50, 0x50, 1, 1},
11179 {0x3B, 0, 0, 0, 0},
11180 {0x3C, 0x6e, 0x6e, 0, 0},
11181 {0x3D, 0xf0, 0xf0, 1, 1},
11182 {0x3E, 0, 0, 0, 0},
11183 {0x3F, 0, 0, 0, 0},
11184 {0x40, 0, 0, 0, 0},
11185 {0x41, 0x3, 0x3, 0, 0},
11186 {0x42, 0x3, 0x3, 0, 0},
11187 {0x43, 0, 0, 0, 0},
11188 {0x44, 0x1e, 0x1e, 0, 0},
11189 {0x45, 0, 0, 0, 0},
11190 {0x46, 0x6e, 0x6e, 0, 0},
11191 {0x47, 0xf0, 0xf0, 1, 1},
11192 {0x48, 0, 0, 0, 0},
11193 {0x49, 0x2, 0x2, 0, 0},
11194 {0x4A, 0xff, 0xff, 1, 1},
11195 {0x4B, 0xc, 0xc, 0, 0},
11196 {0x4C, 0, 0, 0, 0},
11197 {0x4D, 0x38, 0x38, 0, 0},
11198 {0x4E, 0x70, 0x70, 1, 1},
11199 {0x4F, 0x2, 0x2, 0, 0},
11200 {0x50, 0x88, 0x88, 0, 0},
11201 {0x51, 0xc, 0xc, 0, 0},
11202 {0x52, 0, 0, 0, 0},
11203 {0x53, 0x8, 0x8, 0, 0},
11204 {0x54, 0x70, 0x70, 1, 1},
11205 {0x55, 0x2, 0x2, 0, 0},
11206 {0x56, 0xff, 0xff, 1, 1},
11207 {0x57, 0, 0, 0, 0},
11208 {0x58, 0x83, 0x83, 0, 0},
11209 {0x59, 0x77, 0x77, 1, 1},
11210 {0x5A, 0, 0, 0, 0},
11211 {0x5B, 0x2, 0x2, 0, 0},
11212 {0x5C, 0x88, 0x88, 0, 0},
11213 {0x5D, 0, 0, 0, 0},
11214 {0x5E, 0x8, 0x8, 0, 0},
11215 {0x5F, 0x77, 0x77, 1, 1},
11216 {0x60, 0x1, 0x1, 0, 0},
11217 {0x61, 0, 0, 0, 0},
11218 {0x62, 0x7, 0x7, 0, 0},
11219 {0x63, 0, 0, 0, 0},
11220 {0x64, 0x7, 0x7, 0, 0},
11221 {0x65, 0, 0, 0, 0},
11222 {0x66, 0, 0, 0, 0},
11223 {0x67, 0, 0, 1, 1},
11224 {0x68, 0, 0, 0, 0},
11225 {0x69, 0xa, 0xa, 0, 0},
11226 {0x6A, 0, 0, 0, 0},
11227 {0x6B, 0, 0, 0, 0},
11228 {0x6C, 0, 0, 0, 0},
11229 {0x6D, 0, 0, 0, 0},
11230 {0x6E, 0, 0, 0, 0},
11231 {0x6F, 0, 0, 0, 0},
11232 {0x70, 0, 0, 0, 0},
11233 {0x71, 0x2, 0x2, 0, 0},
11234 {0x72, 0, 0, 0, 0},
11235 {0x73, 0, 0, 0, 0},
11236 {0x74, 0xe, 0xe, 0, 0},
11237 {0x75, 0xe, 0xe, 0, 0},
11238 {0x76, 0xe, 0xe, 0, 0},
11239 {0x77, 0x13, 0x13, 0, 0},
11240 {0x78, 0x13, 0x13, 0, 0},
11241 {0x79, 0x1b, 0x1b, 0, 0},
11242 {0x7A, 0x1b, 0x1b, 0, 0},
11243 {0x7B, 0x55, 0x55, 0, 0},
11244 {0x7C, 0x5b, 0x5b, 0, 0},
11245 {0x7D, 0x30, 0x30, 1, 1},
11246 {0x7E, 0, 0, 0, 0},
11247 {0x7F, 0, 0, 0, 0},
11248 {0x80, 0, 0, 0, 0},
11249 {0x81, 0, 0, 0, 0},
11250 {0x82, 0, 0, 0, 0},
11251 {0x83, 0, 0, 0, 0},
11252 {0x84, 0, 0, 0, 0},
11253 {0x85, 0, 0, 0, 0},
11254 {0x86, 0, 0, 0, 0},
11255 {0x87, 0, 0, 0, 0},
11256 {0x88, 0, 0, 0, 0},
11257 {0x89, 0, 0, 0, 0},
11258 {0x8A, 0, 0, 0, 0},
11259 {0x8B, 0, 0, 0, 0},
11260 {0x8C, 0, 0, 0, 0},
11261 {0x8D, 0, 0, 0, 0},
11262 {0x8E, 0, 0, 0, 0},
11263 {0x8F, 0, 0, 0, 0},
11264 {0x90, 0, 0, 0, 0},
11265 {0x91, 0, 0, 0, 0},
11266 {0x92, 0, 0, 0, 0},
11267 {0x93, 0x70, 0x70, 0, 0},
11268 {0x94, 0x70, 0x70, 0, 0},
11269 {0x95, 0x70, 0x70, 0, 0},
11270 {0x96, 0x70, 0x70, 0, 0},
11271 {0x97, 0x70, 0x70, 0, 0},
11272 {0x98, 0x70, 0x70, 0, 0},
11273 {0x99, 0x70, 0x70, 0, 0},
11274 {0x9A, 0x70, 0x70, 0, 0},
11275 {0xFFFF, 0, 0, 0, 0},
11276};
11277
11278static const struct radio_regs regs_RX_2056_rev11[] = {
11279 {0x02, 0, 0, 0, 0},
11280 {0x03, 0, 0, 0, 0},
11281 {0x04, 0, 0, 0, 0},
11282 {0x05, 0, 0, 0, 0},
11283 {0x06, 0, 0, 0, 0},
11284 {0x07, 0, 0, 0, 0},
11285 {0x08, 0, 0, 0, 0},
11286 {0x09, 0, 0, 0, 0},
11287 {0x0A, 0, 0, 0, 0},
11288 {0x0B, 0, 0, 0, 0},
11289 {0x0C, 0, 0, 0, 0},
11290 {0x0D, 0, 0, 0, 0},
11291 {0x0E, 0, 0, 0, 0},
11292 {0x0F, 0, 0, 0, 0},
11293 {0x10, 0, 0, 0, 0},
11294 {0x11, 0, 0, 0, 0},
11295 {0x12, 0, 0, 0, 0},
11296 {0x13, 0, 0, 0, 0},
11297 {0x14, 0, 0, 0, 0},
11298 {0x15, 0, 0, 0, 0},
11299 {0x16, 0, 0, 0, 0},
11300 {0x17, 0, 0, 0, 0},
11301 {0x18, 0, 0, 0, 0},
11302 {0x19, 0, 0, 0, 0},
11303 {0x1A, 0, 0, 0, 0},
11304 {0x1B, 0, 0, 0, 0},
11305 {0x1C, 0, 0, 0, 0},
11306 {0x1D, 0, 0, 0, 0},
11307 {0x1E, 0, 0, 0, 0},
11308 {0x1F, 0, 0, 0, 0},
11309 {0x20, 0x3, 0x3, 0, 0},
11310 {0x21, 0, 0, 0, 0},
11311 {0x22, 0, 0, 0, 0},
11312 {0x23, 0x90, 0x90, 0, 0},
11313 {0x24, 0x55, 0x55, 0, 0},
11314 {0x25, 0x15, 0x15, 0, 0},
11315 {0x26, 0x5, 0x5, 0, 0},
11316 {0x27, 0x15, 0x15, 0, 0},
11317 {0x28, 0x5, 0x5, 0, 0},
11318 {0x29, 0x20, 0x20, 0, 0},
11319 {0x2A, 0x11, 0x11, 0, 0},
11320 {0x2B, 0x90, 0x90, 0, 0},
11321 {0x2C, 0, 0, 0, 0},
11322 {0x2D, 0x88, 0x88, 0, 0},
11323 {0x2E, 0x32, 0x32, 0, 0},
11324 {0x2F, 0x77, 0x77, 0, 0},
11325 {0x30, 0x17, 0x17, 1, 1},
11326 {0x31, 0xff, 0xff, 1, 1},
11327 {0x32, 0x20, 0x20, 0, 0},
11328 {0x33, 0, 0, 0, 0},
11329 {0x34, 0x88, 0x88, 0, 0},
11330 {0x35, 0x32, 0x32, 0, 0},
11331 {0x36, 0x77, 0x77, 0, 0},
11332 {0x37, 0x17, 0x17, 1, 1},
11333 {0x38, 0xf0, 0xf0, 1, 1},
11334 {0x39, 0x20, 0x20, 0, 0},
11335 {0x3A, 0x8, 0x8, 0, 0},
11336 {0x3B, 0x55, 0x55, 1, 1},
11337 {0x3C, 0, 0, 0, 0},
11338 {0x3D, 0x88, 0x88, 1, 1},
11339 {0x3E, 0, 0, 0, 0},
11340 {0x3F, 0x44, 0x44, 0, 0},
11341 {0x40, 0x7, 0x7, 1, 1},
11342 {0x41, 0x6, 0x6, 0, 0},
11343 {0x42, 0x4, 0x4, 0, 0},
11344 {0x43, 0, 0, 0, 0},
11345 {0x44, 0x8, 0x8, 0, 0},
11346 {0x45, 0x55, 0x55, 1, 1},
11347 {0x46, 0, 0, 0, 0},
11348 {0x47, 0x11, 0x11, 0, 0},
11349 {0x48, 0, 0, 0, 0},
11350 {0x49, 0x44, 0x44, 0, 0},
11351 {0x4A, 0x7, 0x7, 0, 0},
11352 {0x4B, 0x6, 0x6, 0, 0},
11353 {0x4C, 0x4, 0x4, 0, 0},
11354 {0x4D, 0, 0, 0, 0},
11355 {0x4E, 0, 0, 0, 0},
11356 {0x4F, 0x26, 0x26, 1, 1},
11357 {0x50, 0x26, 0x26, 1, 1},
11358 {0x51, 0xf, 0xf, 1, 1},
11359 {0x52, 0xf, 0xf, 1, 1},
11360 {0x53, 0x44, 0x44, 0, 0},
11361 {0x54, 0, 0, 0, 0},
11362 {0x55, 0, 0, 0, 0},
11363 {0x56, 0x8, 0x8, 0, 0},
11364 {0x57, 0x8, 0x8, 0, 0},
11365 {0x58, 0x7, 0x7, 0, 0},
11366 {0x59, 0x22, 0x22, 0, 0},
11367 {0x5A, 0x22, 0x22, 0, 0},
11368 {0x5B, 0x2, 0x2, 0, 0},
11369 {0x5C, 0x4, 0x4, 1, 1},
11370 {0x5D, 0x7, 0x7, 0, 0},
11371 {0x5E, 0x55, 0x55, 0, 0},
11372 {0x5F, 0x23, 0x23, 0, 0},
11373 {0x60, 0x41, 0x41, 0, 0},
11374 {0x61, 0x1, 0x1, 0, 0},
11375 {0x62, 0xa, 0xa, 0, 0},
11376 {0x63, 0, 0, 0, 0},
11377 {0x64, 0, 0, 0, 0},
11378 {0x65, 0, 0, 0, 0},
11379 {0x66, 0, 0, 0, 0},
11380 {0x67, 0, 0, 0, 0},
11381 {0x68, 0, 0, 0, 0},
11382 {0x69, 0, 0, 0, 0},
11383 {0x6A, 0, 0, 0, 0},
11384 {0x6B, 0xc, 0xc, 0, 0},
11385 {0x6C, 0, 0, 0, 0},
11386 {0x6D, 0, 0, 0, 0},
11387 {0x6E, 0, 0, 0, 0},
11388 {0x6F, 0, 0, 0, 0},
11389 {0x70, 0, 0, 0, 0},
11390 {0x71, 0, 0, 0, 0},
11391 {0x72, 0x22, 0x22, 0, 0},
11392 {0x73, 0x22, 0x22, 0, 0},
11393 {0x74, 0, 0, 1, 1},
11394 {0x75, 0xa, 0xa, 0, 0},
11395 {0x76, 0x1, 0x1, 0, 0},
11396 {0x77, 0x22, 0x22, 0, 0},
11397 {0x78, 0x30, 0x30, 0, 0},
11398 {0x79, 0, 0, 0, 0},
11399 {0x7A, 0, 0, 0, 0},
11400 {0x7B, 0, 0, 0, 0},
11401 {0x7C, 0, 0, 0, 0},
11402 {0x7D, 0x5, 0x5, 1, 1},
11403 {0x7E, 0, 0, 0, 0},
11404 {0x7F, 0, 0, 0, 0},
11405 {0x80, 0, 0, 0, 0},
11406 {0x81, 0, 0, 0, 0},
11407 {0x82, 0, 0, 0, 0},
11408 {0x83, 0, 0, 0, 0},
11409 {0x84, 0, 0, 0, 0},
11410 {0x85, 0, 0, 0, 0},
11411 {0x86, 0, 0, 0, 0},
11412 {0x87, 0, 0, 0, 0},
11413 {0x88, 0, 0, 0, 0},
11414 {0x89, 0, 0, 0, 0},
11415 {0x8A, 0, 0, 0, 0},
11416 {0x8B, 0, 0, 0, 0},
11417 {0x8C, 0, 0, 0, 0},
11418 {0x8D, 0, 0, 0, 0},
11419 {0x8E, 0, 0, 0, 0},
11420 {0x8F, 0, 0, 0, 0},
11421 {0x90, 0, 0, 0, 0},
11422 {0x91, 0, 0, 0, 0},
11423 {0x92, 0, 0, 0, 0},
11424 {0x93, 0, 0, 0, 0},
11425 {0x94, 0, 0, 0, 0},
11426 {0xFFFF, 0, 0, 0, 0},
11427};
11428
11429static struct radio_20xx_regs regs_2057_rev4[] = {
11430 {0x00, 0x84, 0},
11431 {0x01, 0, 0},
11432 {0x02, 0x60, 0},
11433 {0x03, 0x1f, 0},
11434 {0x04, 0x4, 0},
11435 {0x05, 0x2, 0},
11436 {0x06, 0x1, 0},
11437 {0x07, 0x1, 0},
11438 {0x08, 0x1, 0},
11439 {0x09, 0x69, 0},
11440 {0x0A, 0x66, 0},
11441 {0x0B, 0x6, 0},
11442 {0x0C, 0x18, 0},
11443 {0x0D, 0x3, 0},
11444 {0x0E, 0x20, 1},
11445 {0x0F, 0x20, 0},
11446 {0x10, 0, 0},
11447 {0x11, 0x7c, 0},
11448 {0x12, 0x42, 0},
11449 {0x13, 0xbd, 0},
11450 {0x14, 0x7, 0},
11451 {0x15, 0xf7, 0},
11452 {0x16, 0x8, 0},
11453 {0x17, 0x17, 0},
11454 {0x18, 0x7, 0},
11455 {0x19, 0, 0},
11456 {0x1A, 0x2, 0},
11457 {0x1B, 0x13, 0},
11458 {0x1C, 0x3e, 0},
11459 {0x1D, 0x3e, 0},
11460 {0x1E, 0x96, 0},
11461 {0x1F, 0x4, 0},
11462 {0x20, 0, 0},
11463 {0x21, 0, 0},
11464 {0x22, 0x17, 0},
11465 {0x23, 0x4, 0},
11466 {0x24, 0x1, 0},
11467 {0x25, 0x6, 0},
11468 {0x26, 0x4, 0},
11469 {0x27, 0xd, 0},
11470 {0x28, 0xd, 0},
11471 {0x29, 0x30, 0},
11472 {0x2A, 0x32, 0},
11473 {0x2B, 0x8, 0},
11474 {0x2C, 0x1c, 0},
11475 {0x2D, 0x2, 0},
11476 {0x2E, 0x4, 0},
11477 {0x2F, 0x7f, 0},
11478 {0x30, 0x27, 0},
11479 {0x31, 0, 1},
11480 {0x32, 0, 1},
11481 {0x33, 0, 1},
11482 {0x34, 0, 0},
11483 {0x35, 0x26, 1},
11484 {0x36, 0x18, 0},
11485 {0x37, 0x7, 0},
11486 {0x38, 0x66, 0},
11487 {0x39, 0x66, 0},
11488 {0x3A, 0x66, 0},
11489 {0x3B, 0x66, 0},
11490 {0x3C, 0xff, 1},
11491 {0x3D, 0xff, 1},
11492 {0x3E, 0xff, 1},
11493 {0x3F, 0xff, 1},
11494 {0x40, 0x16, 0},
11495 {0x41, 0x7, 0},
11496 {0x42, 0x19, 0},
11497 {0x43, 0x7, 0},
11498 {0x44, 0x6, 0},
11499 {0x45, 0x3, 0},
11500 {0x46, 0x1, 0},
11501 {0x47, 0x7, 0},
11502 {0x48, 0x33, 0},
11503 {0x49, 0x5, 0},
11504 {0x4A, 0x77, 0},
11505 {0x4B, 0x66, 0},
11506 {0x4C, 0x66, 0},
11507 {0x4D, 0, 0},
11508 {0x4E, 0x4, 0},
11509 {0x4F, 0xc, 0},
11510 {0x50, 0, 0},
11511 {0x51, 0x75, 0},
11512 {0x56, 0x7, 0},
11513 {0x57, 0, 0},
11514 {0x58, 0, 0},
11515 {0x59, 0xa8, 0},
11516 {0x5A, 0, 0},
11517 {0x5B, 0x1f, 0},
11518 {0x5C, 0x30, 0},
11519 {0x5D, 0x1, 0},
11520 {0x5E, 0x30, 0},
11521 {0x5F, 0x70, 0},
11522 {0x60, 0, 0},
11523 {0x61, 0, 0},
11524 {0x62, 0x33, 1},
11525 {0x63, 0x19, 0},
11526 {0x64, 0x62, 0},
11527 {0x65, 0, 0},
11528 {0x66, 0x11, 0},
11529 {0x69, 0, 0},
11530 {0x6A, 0x7e, 0},
11531 {0x6B, 0x3f, 0},
11532 {0x6C, 0x7f, 0},
11533 {0x6D, 0x78, 0},
11534 {0x6E, 0xc8, 0},
11535 {0x6F, 0x88, 0},
11536 {0x70, 0x8, 0},
11537 {0x71, 0xf, 0},
11538 {0x72, 0xbc, 0},
11539 {0x73, 0x8, 0},
11540 {0x74, 0x60, 0},
11541 {0x75, 0x1e, 0},
11542 {0x76, 0x70, 0},
11543 {0x77, 0, 0},
11544 {0x78, 0, 0},
11545 {0x79, 0, 0},
11546 {0x7A, 0x33, 0},
11547 {0x7B, 0x1e, 0},
11548 {0x7C, 0x62, 0},
11549 {0x7D, 0x11, 0},
11550 {0x80, 0x3c, 0},
11551 {0x81, 0x9c, 0},
11552 {0x82, 0xa, 0},
11553 {0x83, 0x9d, 0},
11554 {0x84, 0xa, 0},
11555 {0x85, 0, 0},
11556 {0x86, 0x40, 0},
11557 {0x87, 0x40, 0},
11558 {0x88, 0x88, 0},
11559 {0x89, 0x10, 0},
11560 {0x8A, 0xf0, 1},
11561 {0x8B, 0x10, 1},
11562 {0x8C, 0xf0, 1},
11563 {0x8D, 0, 0},
11564 {0x8E, 0, 0},
11565 {0x8F, 0x10, 0},
11566 {0x90, 0x55, 0},
11567 {0x91, 0x3f, 1},
11568 {0x92, 0x36, 1},
11569 {0x93, 0, 0},
11570 {0x94, 0, 0},
11571 {0x95, 0, 0},
11572 {0x96, 0x87, 0},
11573 {0x97, 0x11, 0},
11574 {0x98, 0, 0},
11575 {0x99, 0x33, 0},
11576 {0x9A, 0x88, 0},
11577 {0x9B, 0, 0},
11578 {0x9C, 0x87, 0},
11579 {0x9D, 0x11, 0},
11580 {0x9E, 0, 0},
11581 {0x9F, 0x33, 0},
11582 {0xA0, 0x88, 0},
11583 {0xA1, 0xe1, 0},
11584 {0xA2, 0x3f, 0},
11585 {0xA3, 0x44, 0},
11586 {0xA4, 0x8c, 1},
11587 {0xA5, 0x6d, 0},
11588 {0xA6, 0x22, 0},
11589 {0xA7, 0xbe, 0},
11590 {0xA8, 0x55, 1},
11591 {0xA9, 0xc, 0},
11592 {0xAA, 0xc, 0},
11593 {0xAB, 0xaa, 0},
11594 {0xAC, 0x2, 0},
11595 {0xAD, 0, 0},
11596 {0xAE, 0x10, 0},
11597 {0xAF, 0x1, 1},
11598 {0xB0, 0, 0},
11599 {0xB1, 0, 0},
11600 {0xB2, 0x80, 0},
11601 {0xB3, 0x60, 0},
11602 {0xB4, 0x44, 0},
11603 {0xB5, 0x55, 0},
11604 {0xB6, 0x1, 0},
11605 {0xB7, 0x55, 0},
11606 {0xB8, 0x1, 0},
11607 {0xB9, 0x5, 0},
11608 {0xBA, 0x55, 0},
11609 {0xBB, 0x55, 0},
11610 {0xC1, 0, 0},
11611 {0xC2, 0, 0},
11612 {0xC3, 0, 0},
11613 {0xC4, 0, 0},
11614 {0xC5, 0, 0},
11615 {0xC6, 0, 0},
11616 {0xC7, 0, 0},
11617 {0xC8, 0, 0},
11618 {0xC9, 0, 0},
11619 {0xCA, 0, 0},
11620 {0xCB, 0, 0},
11621 {0xCC, 0, 0},
11622 {0xCD, 0, 0},
11623 {0xCE, 0x5e, 0},
11624 {0xCF, 0xc, 0},
11625 {0xD0, 0xc, 0},
11626 {0xD1, 0xc, 0},
11627 {0xD2, 0, 0},
11628 {0xD3, 0x2b, 0},
11629 {0xD4, 0xc, 0},
11630 {0xD5, 0, 0},
11631 {0xD6, 0x75, 0},
11632 {0xDB, 0x7, 0},
11633 {0xDC, 0, 0},
11634 {0xDD, 0, 0},
11635 {0xDE, 0xa8, 0},
11636 {0xDF, 0, 0},
11637 {0xE0, 0x1f, 0},
11638 {0xE1, 0x30, 0},
11639 {0xE2, 0x1, 0},
11640 {0xE3, 0x30, 0},
11641 {0xE4, 0x70, 0},
11642 {0xE5, 0, 0},
11643 {0xE6, 0, 0},
11644 {0xE7, 0x33, 0},
11645 {0xE8, 0x19, 0},
11646 {0xE9, 0x62, 0},
11647 {0xEA, 0, 0},
11648 {0xEB, 0x11, 0},
11649 {0xEE, 0, 0},
11650 {0xEF, 0x7e, 0},
11651 {0xF0, 0x3f, 0},
11652 {0xF1, 0x7f, 0},
11653 {0xF2, 0x78, 0},
11654 {0xF3, 0xc8, 0},
11655 {0xF4, 0x88, 0},
11656 {0xF5, 0x8, 0},
11657 {0xF6, 0xf, 0},
11658 {0xF7, 0xbc, 0},
11659 {0xF8, 0x8, 0},
11660 {0xF9, 0x60, 0},
11661 {0xFA, 0x1e, 0},
11662 {0xFB, 0x70, 0},
11663 {0xFC, 0, 0},
11664 {0xFD, 0, 0},
11665 {0xFE, 0, 0},
11666 {0xFF, 0x33, 0},
11667 {0x100, 0x1e, 0},
11668 {0x101, 0x62, 0},
11669 {0x102, 0x11, 0},
11670 {0x105, 0x3c, 0},
11671 {0x106, 0x9c, 0},
11672 {0x107, 0xa, 0},
11673 {0x108, 0x9d, 0},
11674 {0x109, 0xa, 0},
11675 {0x10A, 0, 0},
11676 {0x10B, 0x40, 0},
11677 {0x10C, 0x40, 0},
11678 {0x10D, 0x88, 0},
11679 {0x10E, 0x10, 0},
11680 {0x10F, 0xf0, 1},
11681 {0x110, 0x10, 1},
11682 {0x111, 0xf0, 1},
11683 {0x112, 0, 0},
11684 {0x113, 0, 0},
11685 {0x114, 0x10, 0},
11686 {0x115, 0x55, 0},
11687 {0x116, 0x3f, 1},
11688 {0x117, 0x36, 1},
11689 {0x118, 0, 0},
11690 {0x119, 0, 0},
11691 {0x11A, 0, 0},
11692 {0x11B, 0x87, 0},
11693 {0x11C, 0x11, 0},
11694 {0x11D, 0, 0},
11695 {0x11E, 0x33, 0},
11696 {0x11F, 0x88, 0},
11697 {0x120, 0, 0},
11698 {0x121, 0x87, 0},
11699 {0x122, 0x11, 0},
11700 {0x123, 0, 0},
11701 {0x124, 0x33, 0},
11702 {0x125, 0x88, 0},
11703 {0x126, 0xe1, 0},
11704 {0x127, 0x3f, 0},
11705 {0x128, 0x44, 0},
11706 {0x129, 0x8c, 1},
11707 {0x12A, 0x6d, 0},
11708 {0x12B, 0x22, 0},
11709 {0x12C, 0xbe, 0},
11710 {0x12D, 0x55, 1},
11711 {0x12E, 0xc, 0},
11712 {0x12F, 0xc, 0},
11713 {0x130, 0xaa, 0},
11714 {0x131, 0x2, 0},
11715 {0x132, 0, 0},
11716 {0x133, 0x10, 0},
11717 {0x134, 0x1, 1},
11718 {0x135, 0, 0},
11719 {0x136, 0, 0},
11720 {0x137, 0x80, 0},
11721 {0x138, 0x60, 0},
11722 {0x139, 0x44, 0},
11723 {0x13A, 0x55, 0},
11724 {0x13B, 0x1, 0},
11725 {0x13C, 0x55, 0},
11726 {0x13D, 0x1, 0},
11727 {0x13E, 0x5, 0},
11728 {0x13F, 0x55, 0},
11729 {0x140, 0x55, 0},
11730 {0x146, 0, 0},
11731 {0x147, 0, 0},
11732 {0x148, 0, 0},
11733 {0x149, 0, 0},
11734 {0x14A, 0, 0},
11735 {0x14B, 0, 0},
11736 {0x14C, 0, 0},
11737 {0x14D, 0, 0},
11738 {0x14E, 0, 0},
11739 {0x14F, 0, 0},
11740 {0x150, 0, 0},
11741 {0x151, 0, 0},
11742 {0x152, 0, 0},
11743 {0x153, 0, 0},
11744 {0x154, 0xc, 0},
11745 {0x155, 0xc, 0},
11746 {0x156, 0xc, 0},
11747 {0x157, 0, 0},
11748 {0x158, 0x2b, 0},
11749 {0x159, 0x84, 0},
11750 {0x15A, 0x15, 0},
11751 {0x15B, 0xf, 0},
11752 {0x15C, 0, 0},
11753 {0x15D, 0, 0},
11754 {0x15E, 0, 1},
11755 {0x15F, 0, 1},
11756 {0x160, 0, 1},
11757 {0x161, 0, 1},
11758 {0x162, 0, 1},
11759 {0x163, 0, 1},
11760 {0x164, 0, 0},
11761 {0x165, 0, 0},
11762 {0x166, 0, 0},
11763 {0x167, 0, 0},
11764 {0x168, 0, 0},
11765 {0x169, 0x2, 1},
11766 {0x16A, 0, 1},
11767 {0x16B, 0, 1},
11768 {0x16C, 0, 1},
11769 {0x16D, 0, 0},
11770 {0x170, 0, 0},
11771 {0x171, 0x77, 0},
11772 {0x172, 0x77, 0},
11773 {0x173, 0x77, 0},
11774 {0x174, 0x77, 0},
11775 {0x175, 0, 0},
11776 {0x176, 0x3, 0},
11777 {0x177, 0x37, 0},
11778 {0x178, 0x3, 0},
11779 {0x179, 0, 0},
11780 {0x17A, 0x21, 0},
11781 {0x17B, 0x21, 0},
11782 {0x17C, 0, 0},
11783 {0x17D, 0xaa, 0},
11784 {0x17E, 0, 0},
11785 {0x17F, 0xaa, 0},
11786 {0x180, 0, 0},
11787 {0x190, 0, 0},
11788 {0x191, 0x77, 0},
11789 {0x192, 0x77, 0},
11790 {0x193, 0x77, 0},
11791 {0x194, 0x77, 0},
11792 {0x195, 0, 0},
11793 {0x196, 0x3, 0},
11794 {0x197, 0x37, 0},
11795 {0x198, 0x3, 0},
11796 {0x199, 0, 0},
11797 {0x19A, 0x21, 0},
11798 {0x19B, 0x21, 0},
11799 {0x19C, 0, 0},
11800 {0x19D, 0xaa, 0},
11801 {0x19E, 0, 0},
11802 {0x19F, 0xaa, 0},
11803 {0x1A0, 0, 0},
11804 {0x1A1, 0x2, 0},
11805 {0x1A2, 0xf, 0},
11806 {0x1A3, 0xf, 0},
11807 {0x1A4, 0, 1},
11808 {0x1A5, 0, 1},
11809 {0x1A6, 0, 1},
11810 {0x1A7, 0x2, 0},
11811 {0x1A8, 0xf, 0},
11812 {0x1A9, 0xf, 0},
11813 {0x1AA, 0, 1},
11814 {0x1AB, 0, 1},
11815 {0x1AC, 0, 1},
11816 {0xFFFF, 0, 0},
11817};
11818
11819static struct radio_20xx_regs regs_2057_rev5[] = {
11820 {0x00, 0, 1},
11821 {0x01, 0x57, 1},
11822 {0x02, 0x20, 1},
11823 {0x03, 0x1f, 0},
11824 {0x04, 0x4, 0},
11825 {0x05, 0x2, 0},
11826 {0x06, 0x1, 0},
11827 {0x07, 0x1, 0},
11828 {0x08, 0x1, 0},
11829 {0x09, 0x69, 0},
11830 {0x0A, 0x66, 0},
11831 {0x0B, 0x6, 0},
11832 {0x0C, 0x18, 0},
11833 {0x0D, 0x3, 0},
11834 {0x0E, 0x20, 0},
11835 {0x0F, 0x20, 0},
11836 {0x10, 0, 0},
11837 {0x11, 0x7c, 0},
11838 {0x12, 0x42, 0},
11839 {0x13, 0xbd, 0},
11840 {0x14, 0x7, 0},
11841 {0x15, 0x87, 0},
11842 {0x16, 0x8, 0},
11843 {0x17, 0x17, 0},
11844 {0x18, 0x7, 0},
11845 {0x19, 0, 0},
11846 {0x1A, 0x2, 0},
11847 {0x1B, 0x13, 0},
11848 {0x1C, 0x3e, 0},
11849 {0x1D, 0x3e, 0},
11850 {0x1E, 0x96, 0},
11851 {0x1F, 0x4, 0},
11852 {0x20, 0, 0},
11853 {0x21, 0, 0},
11854 {0x22, 0x17, 0},
11855 {0x23, 0x6, 1},
11856 {0x24, 0x1, 0},
11857 {0x25, 0x6, 0},
11858 {0x26, 0x4, 0},
11859 {0x27, 0xd, 0},
11860 {0x28, 0xd, 0},
11861 {0x29, 0x30, 0},
11862 {0x2A, 0x32, 0},
11863 {0x2B, 0x8, 0},
11864 {0x2C, 0x1c, 0},
11865 {0x2D, 0x2, 0},
11866 {0x2E, 0x4, 0},
11867 {0x2F, 0x7f, 0},
11868 {0x30, 0x27, 0},
11869 {0x31, 0, 1},
11870 {0x32, 0, 1},
11871 {0x33, 0, 1},
11872 {0x34, 0, 0},
11873 {0x35, 0x20, 0},
11874 {0x36, 0x18, 0},
11875 {0x37, 0x7, 0},
11876 {0x38, 0x66, 0},
11877 {0x39, 0x66, 0},
11878 {0x3C, 0xff, 0},
11879 {0x3D, 0xff, 0},
11880 {0x40, 0x16, 0},
11881 {0x41, 0x7, 0},
11882 {0x45, 0x3, 0},
11883 {0x46, 0x1, 0},
11884 {0x47, 0x7, 0},
11885 {0x4B, 0x66, 0},
11886 {0x4C, 0x66, 0},
11887 {0x4D, 0, 0},
11888 {0x4E, 0x4, 0},
11889 {0x4F, 0xc, 0},
11890 {0x50, 0, 0},
11891 {0x51, 0x70, 1},
11892 {0x56, 0x7, 0},
11893 {0x57, 0, 0},
11894 {0x58, 0, 0},
11895 {0x59, 0x88, 1},
11896 {0x5A, 0, 0},
11897 {0x5B, 0x1f, 0},
11898 {0x5C, 0x20, 1},
11899 {0x5D, 0x1, 0},
11900 {0x5E, 0x30, 0},
11901 {0x5F, 0x70, 0},
11902 {0x60, 0, 0},
11903 {0x61, 0, 0},
11904 {0x62, 0x33, 1},
11905 {0x63, 0xf, 1},
11906 {0x64, 0xf, 1},
11907 {0x65, 0, 0},
11908 {0x66, 0x11, 0},
11909 {0x80, 0x3c, 0},
11910 {0x81, 0x1, 1},
11911 {0x82, 0xa, 0},
11912 {0x85, 0, 0},
11913 {0x86, 0x40, 0},
11914 {0x87, 0x40, 0},
11915 {0x88, 0x88, 0},
11916 {0x89, 0x10, 0},
11917 {0x8A, 0xf0, 0},
11918 {0x8B, 0x10, 0},
11919 {0x8C, 0xf0, 0},
11920 {0x8F, 0x10, 0},
11921 {0x90, 0x55, 0},
11922 {0x91, 0x3f, 1},
11923 {0x92, 0x36, 1},
11924 {0x93, 0, 0},
11925 {0x94, 0, 0},
11926 {0x95, 0, 0},
11927 {0x96, 0x87, 0},
11928 {0x97, 0x11, 0},
11929 {0x98, 0, 0},
11930 {0x99, 0x33, 0},
11931 {0x9A, 0x88, 0},
11932 {0xA1, 0x20, 1},
11933 {0xA2, 0x3f, 0},
11934 {0xA3, 0x44, 0},
11935 {0xA4, 0x8c, 0},
11936 {0xA5, 0x6c, 0},
11937 {0xA6, 0x22, 0},
11938 {0xA7, 0xbe, 0},
11939 {0xA8, 0x55, 0},
11940 {0xAA, 0xc, 0},
11941 {0xAB, 0xaa, 0},
11942 {0xAC, 0x2, 0},
11943 {0xAD, 0, 0},
11944 {0xAE, 0x10, 0},
11945 {0xAF, 0x1, 0},
11946 {0xB0, 0, 0},
11947 {0xB1, 0, 0},
11948 {0xB2, 0x80, 0},
11949 {0xB3, 0x60, 0},
11950 {0xB4, 0x44, 0},
11951 {0xB5, 0x55, 0},
11952 {0xB6, 0x1, 0},
11953 {0xB7, 0x55, 0},
11954 {0xB8, 0x1, 0},
11955 {0xB9, 0x5, 0},
11956 {0xBA, 0x55, 0},
11957 {0xBB, 0x55, 0},
11958 {0xC3, 0, 0},
11959 {0xC4, 0, 0},
11960 {0xC5, 0, 0},
11961 {0xC6, 0, 0},
11962 {0xC7, 0, 0},
11963 {0xC8, 0, 0},
11964 {0xC9, 0, 0},
11965 {0xCA, 0, 0},
11966 {0xCB, 0, 0},
11967 {0xCD, 0, 0},
11968 {0xCE, 0x5e, 0},
11969 {0xCF, 0xc, 0},
11970 {0xD0, 0xc, 0},
11971 {0xD1, 0xc, 0},
11972 {0xD2, 0, 0},
11973 {0xD3, 0x2b, 0},
11974 {0xD4, 0xc, 0},
11975 {0xD5, 0, 0},
11976 {0xD6, 0x70, 1},
11977 {0xDB, 0x7, 0},
11978 {0xDC, 0, 0},
11979 {0xDD, 0, 0},
11980 {0xDE, 0x88, 1},
11981 {0xDF, 0, 0},
11982 {0xE0, 0x1f, 0},
11983 {0xE1, 0x20, 1},
11984 {0xE2, 0x1, 0},
11985 {0xE3, 0x30, 0},
11986 {0xE4, 0x70, 0},
11987 {0xE5, 0, 0},
11988 {0xE6, 0, 0},
11989 {0xE7, 0x33, 0},
11990 {0xE8, 0xf, 1},
11991 {0xE9, 0xf, 1},
11992 {0xEA, 0, 0},
11993 {0xEB, 0x11, 0},
11994 {0x105, 0x3c, 0},
11995 {0x106, 0x1, 1},
11996 {0x107, 0xa, 0},
11997 {0x10A, 0, 0},
11998 {0x10B, 0x40, 0},
11999 {0x10C, 0x40, 0},
12000 {0x10D, 0x88, 0},
12001 {0x10E, 0x10, 0},
12002 {0x10F, 0xf0, 0},
12003 {0x110, 0x10, 0},
12004 {0x111, 0xf0, 0},
12005 {0x114, 0x10, 0},
12006 {0x115, 0x55, 0},
12007 {0x116, 0x3f, 1},
12008 {0x117, 0x36, 1},
12009 {0x118, 0, 0},
12010 {0x119, 0, 0},
12011 {0x11A, 0, 0},
12012 {0x11B, 0x87, 0},
12013 {0x11C, 0x11, 0},
12014 {0x11D, 0, 0},
12015 {0x11E, 0x33, 0},
12016 {0x11F, 0x88, 0},
12017 {0x126, 0x20, 1},
12018 {0x127, 0x3f, 0},
12019 {0x128, 0x44, 0},
12020 {0x129, 0x8c, 0},
12021 {0x12A, 0x6c, 0},
12022 {0x12B, 0x22, 0},
12023 {0x12C, 0xbe, 0},
12024 {0x12D, 0x55, 0},
12025 {0x12F, 0xc, 0},
12026 {0x130, 0xaa, 0},
12027 {0x131, 0x2, 0},
12028 {0x132, 0, 0},
12029 {0x133, 0x10, 0},
12030 {0x134, 0x1, 0},
12031 {0x135, 0, 0},
12032 {0x136, 0, 0},
12033 {0x137, 0x80, 0},
12034 {0x138, 0x60, 0},
12035 {0x139, 0x44, 0},
12036 {0x13A, 0x55, 0},
12037 {0x13B, 0x1, 0},
12038 {0x13C, 0x55, 0},
12039 {0x13D, 0x1, 0},
12040 {0x13E, 0x5, 0},
12041 {0x13F, 0x55, 0},
12042 {0x140, 0x55, 0},
12043 {0x148, 0, 0},
12044 {0x149, 0, 0},
12045 {0x14A, 0, 0},
12046 {0x14B, 0, 0},
12047 {0x14C, 0, 0},
12048 {0x14D, 0, 0},
12049 {0x14E, 0, 0},
12050 {0x14F, 0, 0},
12051 {0x150, 0, 0},
12052 {0x154, 0xc, 0},
12053 {0x155, 0xc, 0},
12054 {0x156, 0xc, 0},
12055 {0x157, 0, 0},
12056 {0x158, 0x2b, 0},
12057 {0x159, 0x84, 0},
12058 {0x15A, 0x15, 0},
12059 {0x15B, 0xf, 0},
12060 {0x15C, 0, 0},
12061 {0x15D, 0, 0},
12062 {0x15E, 0, 1},
12063 {0x15F, 0, 1},
12064 {0x160, 0, 1},
12065 {0x161, 0, 1},
12066 {0x162, 0, 1},
12067 {0x163, 0, 1},
12068 {0x164, 0, 0},
12069 {0x165, 0, 0},
12070 {0x166, 0, 0},
12071 {0x167, 0, 0},
12072 {0x168, 0, 0},
12073 {0x169, 0, 0},
12074 {0x16A, 0, 1},
12075 {0x16B, 0, 1},
12076 {0x16C, 0, 1},
12077 {0x16D, 0, 0},
12078 {0x170, 0, 0},
12079 {0x171, 0x77, 0},
12080 {0x172, 0x77, 0},
12081 {0x173, 0x77, 0},
12082 {0x174, 0x77, 0},
12083 {0x175, 0, 0},
12084 {0x176, 0x3, 0},
12085 {0x177, 0x37, 0},
12086 {0x178, 0x3, 0},
12087 {0x179, 0, 0},
12088 {0x17B, 0x21, 0},
12089 {0x17C, 0, 0},
12090 {0x17D, 0xaa, 0},
12091 {0x17E, 0, 0},
12092 {0x190, 0, 0},
12093 {0x191, 0x77, 0},
12094 {0x192, 0x77, 0},
12095 {0x193, 0x77, 0},
12096 {0x194, 0x77, 0},
12097 {0x195, 0, 0},
12098 {0x196, 0x3, 0},
12099 {0x197, 0x37, 0},
12100 {0x198, 0x3, 0},
12101 {0x199, 0, 0},
12102 {0x19B, 0x21, 0},
12103 {0x19C, 0, 0},
12104 {0x19D, 0xaa, 0},
12105 {0x19E, 0, 0},
12106 {0x1A1, 0x2, 0},
12107 {0x1A2, 0xf, 0},
12108 {0x1A3, 0xf, 0},
12109 {0x1A4, 0, 1},
12110 {0x1A5, 0, 1},
12111 {0x1A6, 0, 1},
12112 {0x1A7, 0x2, 0},
12113 {0x1A8, 0xf, 0},
12114 {0x1A9, 0xf, 0},
12115 {0x1AA, 0, 1},
12116 {0x1AB, 0, 1},
12117 {0x1AC, 0, 1},
12118 {0x1AD, 0x84, 0},
12119 {0x1AE, 0x60, 0},
12120 {0x1AF, 0x47, 0},
12121 {0x1B0, 0x47, 0},
12122 {0x1B1, 0, 0},
12123 {0x1B2, 0, 0},
12124 {0x1B3, 0, 0},
12125 {0x1B4, 0, 0},
12126 {0x1B5, 0, 0},
12127 {0x1B6, 0, 0},
12128 {0x1B7, 0xc, 1},
12129 {0x1B8, 0, 0},
12130 {0x1B9, 0, 0},
12131 {0x1BA, 0, 0},
12132 {0x1BB, 0, 0},
12133 {0x1BC, 0, 0},
12134 {0x1BD, 0, 0},
12135 {0x1BE, 0, 0},
12136 {0x1BF, 0, 0},
12137 {0x1C0, 0, 0},
12138 {0x1C1, 0x1, 1},
12139 {0x1C2, 0x80, 1},
12140 {0x1C3, 0, 0},
12141 {0x1C4, 0, 0},
12142 {0x1C5, 0, 0},
12143 {0x1C6, 0, 0},
12144 {0x1C7, 0, 0},
12145 {0x1C8, 0, 0},
12146 {0x1C9, 0, 0},
12147 {0x1CA, 0, 0},
12148 {0xFFFF, 0, 0}
12149};
12150
12151static struct radio_20xx_regs regs_2057_rev5v1[] = {
12152 {0x00, 0x15, 1},
12153 {0x01, 0x57, 1},
12154 {0x02, 0x20, 1},
12155 {0x03, 0x1f, 0},
12156 {0x04, 0x4, 0},
12157 {0x05, 0x2, 0},
12158 {0x06, 0x1, 0},
12159 {0x07, 0x1, 0},
12160 {0x08, 0x1, 0},
12161 {0x09, 0x69, 0},
12162 {0x0A, 0x66, 0},
12163 {0x0B, 0x6, 0},
12164 {0x0C, 0x18, 0},
12165 {0x0D, 0x3, 0},
12166 {0x0E, 0x20, 0},
12167 {0x0F, 0x20, 0},
12168 {0x10, 0, 0},
12169 {0x11, 0x7c, 0},
12170 {0x12, 0x42, 0},
12171 {0x13, 0xbd, 0},
12172 {0x14, 0x7, 0},
12173 {0x15, 0x87, 0},
12174 {0x16, 0x8, 0},
12175 {0x17, 0x17, 0},
12176 {0x18, 0x7, 0},
12177 {0x19, 0, 0},
12178 {0x1A, 0x2, 0},
12179 {0x1B, 0x13, 0},
12180 {0x1C, 0x3e, 0},
12181 {0x1D, 0x3e, 0},
12182 {0x1E, 0x96, 0},
12183 {0x1F, 0x4, 0},
12184 {0x20, 0, 0},
12185 {0x21, 0, 0},
12186 {0x22, 0x17, 0},
12187 {0x23, 0x6, 1},
12188 {0x24, 0x1, 0},
12189 {0x25, 0x6, 0},
12190 {0x26, 0x4, 0},
12191 {0x27, 0xd, 0},
12192 {0x28, 0xd, 0},
12193 {0x29, 0x30, 0},
12194 {0x2A, 0x32, 0},
12195 {0x2B, 0x8, 0},
12196 {0x2C, 0x1c, 0},
12197 {0x2D, 0x2, 0},
12198 {0x2E, 0x4, 0},
12199 {0x2F, 0x7f, 0},
12200 {0x30, 0x27, 0},
12201 {0x31, 0, 1},
12202 {0x32, 0, 1},
12203 {0x33, 0, 1},
12204 {0x34, 0, 0},
12205 {0x35, 0x20, 0},
12206 {0x36, 0x18, 0},
12207 {0x37, 0x7, 0},
12208 {0x38, 0x66, 0},
12209 {0x39, 0x66, 0},
12210 {0x3C, 0xff, 0},
12211 {0x3D, 0xff, 0},
12212 {0x40, 0x16, 0},
12213 {0x41, 0x7, 0},
12214 {0x45, 0x3, 0},
12215 {0x46, 0x1, 0},
12216 {0x47, 0x7, 0},
12217 {0x4B, 0x66, 0},
12218 {0x4C, 0x66, 0},
12219 {0x4D, 0, 0},
12220 {0x4E, 0x4, 0},
12221 {0x4F, 0xc, 0},
12222 {0x50, 0, 0},
12223 {0x51, 0x70, 1},
12224 {0x56, 0x7, 0},
12225 {0x57, 0, 0},
12226 {0x58, 0, 0},
12227 {0x59, 0x88, 1},
12228 {0x5A, 0, 0},
12229 {0x5B, 0x1f, 0},
12230 {0x5C, 0x20, 1},
12231 {0x5D, 0x1, 0},
12232 {0x5E, 0x30, 0},
12233 {0x5F, 0x70, 0},
12234 {0x60, 0, 0},
12235 {0x61, 0, 0},
12236 {0x62, 0x33, 1},
12237 {0x63, 0xf, 1},
12238 {0x64, 0xf, 1},
12239 {0x65, 0, 0},
12240 {0x66, 0x11, 0},
12241 {0x80, 0x3c, 0},
12242 {0x81, 0x1, 1},
12243 {0x82, 0xa, 0},
12244 {0x85, 0, 0},
12245 {0x86, 0x40, 0},
12246 {0x87, 0x40, 0},
12247 {0x88, 0x88, 0},
12248 {0x89, 0x10, 0},
12249 {0x8A, 0xf0, 0},
12250 {0x8B, 0x10, 0},
12251 {0x8C, 0xf0, 0},
12252 {0x8F, 0x10, 0},
12253 {0x90, 0x55, 0},
12254 {0x91, 0x3f, 1},
12255 {0x92, 0x36, 1},
12256 {0x93, 0, 0},
12257 {0x94, 0, 0},
12258 {0x95, 0, 0},
12259 {0x96, 0x87, 0},
12260 {0x97, 0x11, 0},
12261 {0x98, 0, 0},
12262 {0x99, 0x33, 0},
12263 {0x9A, 0x88, 0},
12264 {0xA1, 0x20, 1},
12265 {0xA2, 0x3f, 0},
12266 {0xA3, 0x44, 0},
12267 {0xA4, 0x8c, 0},
12268 {0xA5, 0x6c, 0},
12269 {0xA6, 0x22, 0},
12270 {0xA7, 0xbe, 0},
12271 {0xA8, 0x55, 0},
12272 {0xAA, 0xc, 0},
12273 {0xAB, 0xaa, 0},
12274 {0xAC, 0x2, 0},
12275 {0xAD, 0, 0},
12276 {0xAE, 0x10, 0},
12277 {0xAF, 0x1, 0},
12278 {0xB0, 0, 0},
12279 {0xB1, 0, 0},
12280 {0xB2, 0x80, 0},
12281 {0xB3, 0x60, 0},
12282 {0xB4, 0x44, 0},
12283 {0xB5, 0x55, 0},
12284 {0xB6, 0x1, 0},
12285 {0xB7, 0x55, 0},
12286 {0xB8, 0x1, 0},
12287 {0xB9, 0x5, 0},
12288 {0xBA, 0x55, 0},
12289 {0xBB, 0x55, 0},
12290 {0xC3, 0, 0},
12291 {0xC4, 0, 0},
12292 {0xC5, 0, 0},
12293 {0xC6, 0, 0},
12294 {0xC7, 0, 0},
12295 {0xC8, 0, 0},
12296 {0xC9, 0x1, 1},
12297 {0xCA, 0, 0},
12298 {0xCB, 0, 0},
12299 {0xCD, 0, 0},
12300 {0xCE, 0x5e, 0},
12301 {0xCF, 0xc, 0},
12302 {0xD0, 0xc, 0},
12303 {0xD1, 0xc, 0},
12304 {0xD2, 0, 0},
12305 {0xD3, 0x2b, 0},
12306 {0xD4, 0xc, 0},
12307 {0xD5, 0, 0},
12308 {0xD6, 0x70, 1},
12309 {0xDB, 0x7, 0},
12310 {0xDC, 0, 0},
12311 {0xDD, 0, 0},
12312 {0xDE, 0x88, 1},
12313 {0xDF, 0, 0},
12314 {0xE0, 0x1f, 0},
12315 {0xE1, 0x20, 1},
12316 {0xE2, 0x1, 0},
12317 {0xE3, 0x30, 0},
12318 {0xE4, 0x70, 0},
12319 {0xE5, 0, 0},
12320 {0xE6, 0, 0},
12321 {0xE7, 0x33, 0},
12322 {0xE8, 0xf, 1},
12323 {0xE9, 0xf, 1},
12324 {0xEA, 0, 0},
12325 {0xEB, 0x11, 0},
12326 {0x105, 0x3c, 0},
12327 {0x106, 0x1, 1},
12328 {0x107, 0xa, 0},
12329 {0x10A, 0, 0},
12330 {0x10B, 0x40, 0},
12331 {0x10C, 0x40, 0},
12332 {0x10D, 0x88, 0},
12333 {0x10E, 0x10, 0},
12334 {0x10F, 0xf0, 0},
12335 {0x110, 0x10, 0},
12336 {0x111, 0xf0, 0},
12337 {0x114, 0x10, 0},
12338 {0x115, 0x55, 0},
12339 {0x116, 0x3f, 1},
12340 {0x117, 0x36, 1},
12341 {0x118, 0, 0},
12342 {0x119, 0, 0},
12343 {0x11A, 0, 0},
12344 {0x11B, 0x87, 0},
12345 {0x11C, 0x11, 0},
12346 {0x11D, 0, 0},
12347 {0x11E, 0x33, 0},
12348 {0x11F, 0x88, 0},
12349 {0x126, 0x20, 1},
12350 {0x127, 0x3f, 0},
12351 {0x128, 0x44, 0},
12352 {0x129, 0x8c, 0},
12353 {0x12A, 0x6c, 0},
12354 {0x12B, 0x22, 0},
12355 {0x12C, 0xbe, 0},
12356 {0x12D, 0x55, 0},
12357 {0x12F, 0xc, 0},
12358 {0x130, 0xaa, 0},
12359 {0x131, 0x2, 0},
12360 {0x132, 0, 0},
12361 {0x133, 0x10, 0},
12362 {0x134, 0x1, 0},
12363 {0x135, 0, 0},
12364 {0x136, 0, 0},
12365 {0x137, 0x80, 0},
12366 {0x138, 0x60, 0},
12367 {0x139, 0x44, 0},
12368 {0x13A, 0x55, 0},
12369 {0x13B, 0x1, 0},
12370 {0x13C, 0x55, 0},
12371 {0x13D, 0x1, 0},
12372 {0x13E, 0x5, 0},
12373 {0x13F, 0x55, 0},
12374 {0x140, 0x55, 0},
12375 {0x148, 0, 0},
12376 {0x149, 0, 0},
12377 {0x14A, 0, 0},
12378 {0x14B, 0, 0},
12379 {0x14C, 0, 0},
12380 {0x14D, 0, 0},
12381 {0x14E, 0x1, 1},
12382 {0x14F, 0, 0},
12383 {0x150, 0, 0},
12384 {0x154, 0xc, 0},
12385 {0x155, 0xc, 0},
12386 {0x156, 0xc, 0},
12387 {0x157, 0, 0},
12388 {0x158, 0x2b, 0},
12389 {0x159, 0x84, 0},
12390 {0x15A, 0x15, 0},
12391 {0x15B, 0xf, 0},
12392 {0x15C, 0, 0},
12393 {0x15D, 0, 0},
12394 {0x15E, 0, 1},
12395 {0x15F, 0, 1},
12396 {0x160, 0, 1},
12397 {0x161, 0, 1},
12398 {0x162, 0, 1},
12399 {0x163, 0, 1},
12400 {0x164, 0, 0},
12401 {0x165, 0, 0},
12402 {0x166, 0, 0},
12403 {0x167, 0, 0},
12404 {0x168, 0, 0},
12405 {0x169, 0, 0},
12406 {0x16A, 0, 1},
12407 {0x16B, 0, 1},
12408 {0x16C, 0, 1},
12409 {0x16D, 0, 0},
12410 {0x170, 0, 0},
12411 {0x171, 0x77, 0},
12412 {0x172, 0x77, 0},
12413 {0x173, 0x77, 0},
12414 {0x174, 0x77, 0},
12415 {0x175, 0, 0},
12416 {0x176, 0x3, 0},
12417 {0x177, 0x37, 0},
12418 {0x178, 0x3, 0},
12419 {0x179, 0, 0},
12420 {0x17B, 0x21, 0},
12421 {0x17C, 0, 0},
12422 {0x17D, 0xaa, 0},
12423 {0x17E, 0, 0},
12424 {0x190, 0, 0},
12425 {0x191, 0x77, 0},
12426 {0x192, 0x77, 0},
12427 {0x193, 0x77, 0},
12428 {0x194, 0x77, 0},
12429 {0x195, 0, 0},
12430 {0x196, 0x3, 0},
12431 {0x197, 0x37, 0},
12432 {0x198, 0x3, 0},
12433 {0x199, 0, 0},
12434 {0x19B, 0x21, 0},
12435 {0x19C, 0, 0},
12436 {0x19D, 0xaa, 0},
12437 {0x19E, 0, 0},
12438 {0x1A1, 0x2, 0},
12439 {0x1A2, 0xf, 0},
12440 {0x1A3, 0xf, 0},
12441 {0x1A4, 0, 1},
12442 {0x1A5, 0, 1},
12443 {0x1A6, 0, 1},
12444 {0x1A7, 0x2, 0},
12445 {0x1A8, 0xf, 0},
12446 {0x1A9, 0xf, 0},
12447 {0x1AA, 0, 1},
12448 {0x1AB, 0, 1},
12449 {0x1AC, 0, 1},
12450 {0x1AD, 0x84, 0},
12451 {0x1AE, 0x60, 0},
12452 {0x1AF, 0x47, 0},
12453 {0x1B0, 0x47, 0},
12454 {0x1B1, 0, 0},
12455 {0x1B2, 0, 0},
12456 {0x1B3, 0, 0},
12457 {0x1B4, 0, 0},
12458 {0x1B5, 0, 0},
12459 {0x1B6, 0, 0},
12460 {0x1B7, 0xc, 1},
12461 {0x1B8, 0, 0},
12462 {0x1B9, 0, 0},
12463 {0x1BA, 0, 0},
12464 {0x1BB, 0, 0},
12465 {0x1BC, 0, 0},
12466 {0x1BD, 0, 0},
12467 {0x1BE, 0, 0},
12468 {0x1BF, 0, 0},
12469 {0x1C0, 0, 0},
12470 {0x1C1, 0x1, 1},
12471 {0x1C2, 0x80, 1},
12472 {0x1C3, 0, 0},
12473 {0x1C4, 0, 0},
12474 {0x1C5, 0, 0},
12475 {0x1C6, 0, 0},
12476 {0x1C7, 0, 0},
12477 {0x1C8, 0, 0},
12478 {0x1C9, 0, 0},
12479 {0x1CA, 0, 0},
12480 {0xFFFF, 0, 0}
12481};
12482
12483static struct radio_20xx_regs regs_2057_rev7[] = {
12484 {0x00, 0, 1},
12485 {0x01, 0x57, 1},
12486 {0x02, 0x20, 1},
12487 {0x03, 0x1f, 0},
12488 {0x04, 0x4, 0},
12489 {0x05, 0x2, 0},
12490 {0x06, 0x1, 0},
12491 {0x07, 0x1, 0},
12492 {0x08, 0x1, 0},
12493 {0x09, 0x69, 0},
12494 {0x0A, 0x66, 0},
12495 {0x0B, 0x6, 0},
12496 {0x0C, 0x18, 0},
12497 {0x0D, 0x3, 0},
12498 {0x0E, 0x20, 0},
12499 {0x0F, 0x20, 0},
12500 {0x10, 0, 0},
12501 {0x11, 0x7c, 0},
12502 {0x12, 0x42, 0},
12503 {0x13, 0xbd, 0},
12504 {0x14, 0x7, 0},
12505 {0x15, 0x87, 0},
12506 {0x16, 0x8, 0},
12507 {0x17, 0x17, 0},
12508 {0x18, 0x7, 0},
12509 {0x19, 0, 0},
12510 {0x1A, 0x2, 0},
12511 {0x1B, 0x13, 0},
12512 {0x1C, 0x3e, 0},
12513 {0x1D, 0x3e, 0},
12514 {0x1E, 0x96, 0},
12515 {0x1F, 0x4, 0},
12516 {0x20, 0, 0},
12517 {0x21, 0, 0},
12518 {0x22, 0x17, 0},
12519 {0x23, 0x6, 0},
12520 {0x24, 0x1, 0},
12521 {0x25, 0x6, 0},
12522 {0x26, 0x4, 0},
12523 {0x27, 0xd, 0},
12524 {0x28, 0xd, 0},
12525 {0x29, 0x30, 0},
12526 {0x2A, 0x32, 0},
12527 {0x2B, 0x8, 0},
12528 {0x2C, 0x1c, 0},
12529 {0x2D, 0x2, 0},
12530 {0x2E, 0x4, 0},
12531 {0x2F, 0x7f, 0},
12532 {0x30, 0x27, 0},
12533 {0x31, 0, 1},
12534 {0x32, 0, 1},
12535 {0x33, 0, 1},
12536 {0x34, 0, 0},
12537 {0x35, 0x20, 0},
12538 {0x36, 0x18, 0},
12539 {0x37, 0x7, 0},
12540 {0x38, 0x66, 0},
12541 {0x39, 0x66, 0},
12542 {0x3A, 0x66, 0},
12543 {0x3B, 0x66, 0},
12544 {0x3C, 0xff, 0},
12545 {0x3D, 0xff, 0},
12546 {0x3E, 0xff, 0},
12547 {0x3F, 0xff, 0},
12548 {0x40, 0x16, 0},
12549 {0x41, 0x7, 0},
12550 {0x42, 0x19, 0},
12551 {0x43, 0x7, 0},
12552 {0x44, 0x6, 0},
12553 {0x45, 0x3, 0},
12554 {0x46, 0x1, 0},
12555 {0x47, 0x7, 0},
12556 {0x48, 0x33, 0},
12557 {0x49, 0x5, 0},
12558 {0x4A, 0x77, 0},
12559 {0x4B, 0x66, 0},
12560 {0x4C, 0x66, 0},
12561 {0x4D, 0, 0},
12562 {0x4E, 0x4, 0},
12563 {0x4F, 0xc, 0},
12564 {0x50, 0, 0},
12565 {0x51, 0x70, 1},
12566 {0x56, 0x7, 0},
12567 {0x57, 0, 0},
12568 {0x58, 0, 0},
12569 {0x59, 0x88, 1},
12570 {0x5A, 0, 0},
12571 {0x5B, 0x1f, 0},
12572 {0x5C, 0x20, 1},
12573 {0x5D, 0x1, 0},
12574 {0x5E, 0x30, 0},
12575 {0x5F, 0x70, 0},
12576 {0x60, 0, 0},
12577 {0x61, 0, 0},
12578 {0x62, 0x33, 1},
12579 {0x63, 0xf, 1},
12580 {0x64, 0x13, 1},
12581 {0x65, 0, 0},
12582 {0x66, 0xee, 1},
12583 {0x69, 0, 0},
12584 {0x6A, 0x7e, 0},
12585 {0x6B, 0x3f, 0},
12586 {0x6C, 0x7f, 0},
12587 {0x6D, 0x78, 0},
12588 {0x6E, 0x58, 1},
12589 {0x6F, 0x88, 0},
12590 {0x70, 0x8, 0},
12591 {0x71, 0xf, 0},
12592 {0x72, 0xbc, 0},
12593 {0x73, 0x8, 0},
12594 {0x74, 0x60, 0},
12595 {0x75, 0x13, 1},
12596 {0x76, 0x70, 0},
12597 {0x77, 0, 0},
12598 {0x78, 0, 0},
12599 {0x79, 0, 0},
12600 {0x7A, 0x33, 0},
12601 {0x7B, 0x13, 1},
12602 {0x7C, 0x14, 1},
12603 {0x7D, 0xee, 1},
12604 {0x80, 0x3c, 0},
12605 {0x81, 0x1, 1},
12606 {0x82, 0xa, 0},
12607 {0x83, 0x9d, 0},
12608 {0x84, 0xa, 0},
12609 {0x85, 0, 0},
12610 {0x86, 0x40, 0},
12611 {0x87, 0x40, 0},
12612 {0x88, 0x88, 0},
12613 {0x89, 0x10, 0},
12614 {0x8A, 0xf0, 0},
12615 {0x8B, 0x10, 0},
12616 {0x8C, 0xf0, 0},
12617 {0x8D, 0, 0},
12618 {0x8E, 0, 0},
12619 {0x8F, 0x10, 0},
12620 {0x90, 0x55, 0},
12621 {0x91, 0x3f, 1},
12622 {0x92, 0x36, 1},
12623 {0x93, 0, 0},
12624 {0x94, 0, 0},
12625 {0x95, 0, 0},
12626 {0x96, 0x87, 0},
12627 {0x97, 0x11, 0},
12628 {0x98, 0, 0},
12629 {0x99, 0x33, 0},
12630 {0x9A, 0x88, 0},
12631 {0x9B, 0, 0},
12632 {0x9C, 0x87, 0},
12633 {0x9D, 0x11, 0},
12634 {0x9E, 0, 0},
12635 {0x9F, 0x33, 0},
12636 {0xA0, 0x88, 0},
12637 {0xA1, 0x20, 1},
12638 {0xA2, 0x3f, 0},
12639 {0xA3, 0x44, 0},
12640 {0xA4, 0x8c, 0},
12641 {0xA5, 0x6c, 0},
12642 {0xA6, 0x22, 0},
12643 {0xA7, 0xbe, 0},
12644 {0xA8, 0x55, 0},
12645 {0xAA, 0xc, 0},
12646 {0xAB, 0xaa, 0},
12647 {0xAC, 0x2, 0},
12648 {0xAD, 0, 0},
12649 {0xAE, 0x10, 0},
12650 {0xAF, 0x1, 0},
12651 {0xB0, 0, 0},
12652 {0xB1, 0, 0},
12653 {0xB2, 0x80, 0},
12654 {0xB3, 0x60, 0},
12655 {0xB4, 0x44, 0},
12656 {0xB5, 0x55, 0},
12657 {0xB6, 0x1, 0},
12658 {0xB7, 0x55, 0},
12659 {0xB8, 0x1, 0},
12660 {0xB9, 0x5, 0},
12661 {0xBA, 0x55, 0},
12662 {0xBB, 0x55, 0},
12663 {0xC1, 0, 0},
12664 {0xC2, 0, 0},
12665 {0xC3, 0, 0},
12666 {0xC4, 0, 0},
12667 {0xC5, 0, 0},
12668 {0xC6, 0, 0},
12669 {0xC7, 0, 0},
12670 {0xC8, 0, 0},
12671 {0xC9, 0, 0},
12672 {0xCA, 0, 0},
12673 {0xCB, 0, 0},
12674 {0xCC, 0, 0},
12675 {0xCD, 0, 0},
12676 {0xCE, 0x5e, 0},
12677 {0xCF, 0xc, 0},
12678 {0xD0, 0xc, 0},
12679 {0xD1, 0xc, 0},
12680 {0xD2, 0, 0},
12681 {0xD3, 0x2b, 0},
12682 {0xD4, 0xc, 0},
12683 {0xD5, 0, 0},
12684 {0xD6, 0x70, 1},
12685 {0xDB, 0x7, 0},
12686 {0xDC, 0, 0},
12687 {0xDD, 0, 0},
12688 {0xDE, 0x88, 1},
12689 {0xDF, 0, 0},
12690 {0xE0, 0x1f, 0},
12691 {0xE1, 0x20, 1},
12692 {0xE2, 0x1, 0},
12693 {0xE3, 0x30, 0},
12694 {0xE4, 0x70, 0},
12695 {0xE5, 0, 0},
12696 {0xE6, 0, 0},
12697 {0xE7, 0x33, 0},
12698 {0xE8, 0xf, 1},
12699 {0xE9, 0x13, 1},
12700 {0xEA, 0, 0},
12701 {0xEB, 0xee, 1},
12702 {0xEE, 0, 0},
12703 {0xEF, 0x7e, 0},
12704 {0xF0, 0x3f, 0},
12705 {0xF1, 0x7f, 0},
12706 {0xF2, 0x78, 0},
12707 {0xF3, 0x58, 1},
12708 {0xF4, 0x88, 0},
12709 {0xF5, 0x8, 0},
12710 {0xF6, 0xf, 0},
12711 {0xF7, 0xbc, 0},
12712 {0xF8, 0x8, 0},
12713 {0xF9, 0x60, 0},
12714 {0xFA, 0x13, 1},
12715 {0xFB, 0x70, 0},
12716 {0xFC, 0, 0},
12717 {0xFD, 0, 0},
12718 {0xFE, 0, 0},
12719 {0xFF, 0x33, 0},
12720 {0x100, 0x13, 1},
12721 {0x101, 0x14, 1},
12722 {0x102, 0xee, 1},
12723 {0x105, 0x3c, 0},
12724 {0x106, 0x1, 1},
12725 {0x107, 0xa, 0},
12726 {0x108, 0x9d, 0},
12727 {0x109, 0xa, 0},
12728 {0x10A, 0, 0},
12729 {0x10B, 0x40, 0},
12730 {0x10C, 0x40, 0},
12731 {0x10D, 0x88, 0},
12732 {0x10E, 0x10, 0},
12733 {0x10F, 0xf0, 0},
12734 {0x110, 0x10, 0},
12735 {0x111, 0xf0, 0},
12736 {0x112, 0, 0},
12737 {0x113, 0, 0},
12738 {0x114, 0x10, 0},
12739 {0x115, 0x55, 0},
12740 {0x116, 0x3f, 1},
12741 {0x117, 0x36, 1},
12742 {0x118, 0, 0},
12743 {0x119, 0, 0},
12744 {0x11A, 0, 0},
12745 {0x11B, 0x87, 0},
12746 {0x11C, 0x11, 0},
12747 {0x11D, 0, 0},
12748 {0x11E, 0x33, 0},
12749 {0x11F, 0x88, 0},
12750 {0x120, 0, 0},
12751 {0x121, 0x87, 0},
12752 {0x122, 0x11, 0},
12753 {0x123, 0, 0},
12754 {0x124, 0x33, 0},
12755 {0x125, 0x88, 0},
12756 {0x126, 0x20, 1},
12757 {0x127, 0x3f, 0},
12758 {0x128, 0x44, 0},
12759 {0x129, 0x8c, 0},
12760 {0x12A, 0x6c, 0},
12761 {0x12B, 0x22, 0},
12762 {0x12C, 0xbe, 0},
12763 {0x12D, 0x55, 0},
12764 {0x12F, 0xc, 0},
12765 {0x130, 0xaa, 0},
12766 {0x131, 0x2, 0},
12767 {0x132, 0, 0},
12768 {0x133, 0x10, 0},
12769 {0x134, 0x1, 0},
12770 {0x135, 0, 0},
12771 {0x136, 0, 0},
12772 {0x137, 0x80, 0},
12773 {0x138, 0x60, 0},
12774 {0x139, 0x44, 0},
12775 {0x13A, 0x55, 0},
12776 {0x13B, 0x1, 0},
12777 {0x13C, 0x55, 0},
12778 {0x13D, 0x1, 0},
12779 {0x13E, 0x5, 0},
12780 {0x13F, 0x55, 0},
12781 {0x140, 0x55, 0},
12782 {0x146, 0, 0},
12783 {0x147, 0, 0},
12784 {0x148, 0, 0},
12785 {0x149, 0, 0},
12786 {0x14A, 0, 0},
12787 {0x14B, 0, 0},
12788 {0x14C, 0, 0},
12789 {0x14D, 0, 0},
12790 {0x14E, 0, 0},
12791 {0x14F, 0, 0},
12792 {0x150, 0, 0},
12793 {0x151, 0, 0},
12794 {0x154, 0xc, 0},
12795 {0x155, 0xc, 0},
12796 {0x156, 0xc, 0},
12797 {0x157, 0, 0},
12798 {0x158, 0x2b, 0},
12799 {0x159, 0x84, 0},
12800 {0x15A, 0x15, 0},
12801 {0x15B, 0xf, 0},
12802 {0x15C, 0, 0},
12803 {0x15D, 0, 0},
12804 {0x15E, 0, 1},
12805 {0x15F, 0, 1},
12806 {0x160, 0, 1},
12807 {0x161, 0, 1},
12808 {0x162, 0, 1},
12809 {0x163, 0, 1},
12810 {0x164, 0, 0},
12811 {0x165, 0, 0},
12812 {0x166, 0, 0},
12813 {0x167, 0, 0},
12814 {0x168, 0, 0},
12815 {0x169, 0, 0},
12816 {0x16A, 0, 1},
12817 {0x16B, 0, 1},
12818 {0x16C, 0, 1},
12819 {0x16D, 0, 0},
12820 {0x170, 0, 0},
12821 {0x171, 0x77, 0},
12822 {0x172, 0x77, 0},
12823 {0x173, 0x77, 0},
12824 {0x174, 0x77, 0},
12825 {0x175, 0, 0},
12826 {0x176, 0x3, 0},
12827 {0x177, 0x37, 0},
12828 {0x178, 0x3, 0},
12829 {0x179, 0, 0},
12830 {0x17A, 0x21, 0},
12831 {0x17B, 0x21, 0},
12832 {0x17C, 0, 0},
12833 {0x17D, 0xaa, 0},
12834 {0x17E, 0, 0},
12835 {0x17F, 0xaa, 0},
12836 {0x180, 0, 0},
12837 {0x190, 0, 0},
12838 {0x191, 0x77, 0},
12839 {0x192, 0x77, 0},
12840 {0x193, 0x77, 0},
12841 {0x194, 0x77, 0},
12842 {0x195, 0, 0},
12843 {0x196, 0x3, 0},
12844 {0x197, 0x37, 0},
12845 {0x198, 0x3, 0},
12846 {0x199, 0, 0},
12847 {0x19A, 0x21, 0},
12848 {0x19B, 0x21, 0},
12849 {0x19C, 0, 0},
12850 {0x19D, 0xaa, 0},
12851 {0x19E, 0, 0},
12852 {0x19F, 0xaa, 0},
12853 {0x1A0, 0, 0},
12854 {0x1A1, 0x2, 0},
12855 {0x1A2, 0xf, 0},
12856 {0x1A3, 0xf, 0},
12857 {0x1A4, 0, 1},
12858 {0x1A5, 0, 1},
12859 {0x1A6, 0, 1},
12860 {0x1A7, 0x2, 0},
12861 {0x1A8, 0xf, 0},
12862 {0x1A9, 0xf, 0},
12863 {0x1AA, 0, 1},
12864 {0x1AB, 0, 1},
12865 {0x1AC, 0, 1},
12866 {0x1AD, 0x84, 0},
12867 {0x1AE, 0x60, 0},
12868 {0x1AF, 0x47, 0},
12869 {0x1B0, 0x47, 0},
12870 {0x1B1, 0, 0},
12871 {0x1B2, 0, 0},
12872 {0x1B3, 0, 0},
12873 {0x1B4, 0, 0},
12874 {0x1B5, 0, 0},
12875 {0x1B6, 0, 0},
12876 {0x1B7, 0x5, 1},
12877 {0x1B8, 0, 0},
12878 {0x1B9, 0, 0},
12879 {0x1BA, 0, 0},
12880 {0x1BB, 0, 0},
12881 {0x1BC, 0, 0},
12882 {0x1BD, 0, 0},
12883 {0x1BE, 0, 0},
12884 {0x1BF, 0, 0},
12885 {0x1C0, 0, 0},
12886 {0x1C1, 0, 0},
12887 {0x1C2, 0xa0, 1},
12888 {0x1C3, 0, 0},
12889 {0x1C4, 0, 0},
12890 {0x1C5, 0, 0},
12891 {0x1C6, 0, 0},
12892 {0x1C7, 0, 0},
12893 {0x1C8, 0, 0},
12894 {0x1C9, 0, 0},
12895 {0x1CA, 0, 0},
12896 {0xFFFF, 0, 0}
12897};
12898
12899static struct radio_20xx_regs regs_2057_rev8[] = {
12900 {0x00, 0x8, 1},
12901 {0x01, 0x57, 1},
12902 {0x02, 0x20, 1},
12903 {0x03, 0x1f, 0},
12904 {0x04, 0x4, 0},
12905 {0x05, 0x2, 0},
12906 {0x06, 0x1, 0},
12907 {0x07, 0x1, 0},
12908 {0x08, 0x1, 0},
12909 {0x09, 0x69, 0},
12910 {0x0A, 0x66, 0},
12911 {0x0B, 0x6, 0},
12912 {0x0C, 0x18, 0},
12913 {0x0D, 0x3, 0},
12914 {0x0E, 0x20, 0},
12915 {0x0F, 0x20, 0},
12916 {0x10, 0, 0},
12917 {0x11, 0x7c, 0},
12918 {0x12, 0x42, 0},
12919 {0x13, 0xbd, 0},
12920 {0x14, 0x7, 0},
12921 {0x15, 0x87, 0},
12922 {0x16, 0x8, 0},
12923 {0x17, 0x17, 0},
12924 {0x18, 0x7, 0},
12925 {0x19, 0, 0},
12926 {0x1A, 0x2, 0},
12927 {0x1B, 0x13, 0},
12928 {0x1C, 0x3e, 0},
12929 {0x1D, 0x3e, 0},
12930 {0x1E, 0x96, 0},
12931 {0x1F, 0x4, 0},
12932 {0x20, 0, 0},
12933 {0x21, 0, 0},
12934 {0x22, 0x17, 0},
12935 {0x23, 0x6, 0},
12936 {0x24, 0x1, 0},
12937 {0x25, 0x6, 0},
12938 {0x26, 0x4, 0},
12939 {0x27, 0xd, 0},
12940 {0x28, 0xd, 0},
12941 {0x29, 0x30, 0},
12942 {0x2A, 0x32, 0},
12943 {0x2B, 0x8, 0},
12944 {0x2C, 0x1c, 0},
12945 {0x2D, 0x2, 0},
12946 {0x2E, 0x4, 0},
12947 {0x2F, 0x7f, 0},
12948 {0x30, 0x27, 0},
12949 {0x31, 0, 1},
12950 {0x32, 0, 1},
12951 {0x33, 0, 1},
12952 {0x34, 0, 0},
12953 {0x35, 0x20, 0},
12954 {0x36, 0x18, 0},
12955 {0x37, 0x7, 0},
12956 {0x38, 0x66, 0},
12957 {0x39, 0x66, 0},
12958 {0x3A, 0x66, 0},
12959 {0x3B, 0x66, 0},
12960 {0x3C, 0xff, 0},
12961 {0x3D, 0xff, 0},
12962 {0x3E, 0xff, 0},
12963 {0x3F, 0xff, 0},
12964 {0x40, 0x16, 0},
12965 {0x41, 0x7, 0},
12966 {0x42, 0x19, 0},
12967 {0x43, 0x7, 0},
12968 {0x44, 0x6, 0},
12969 {0x45, 0x3, 0},
12970 {0x46, 0x1, 0},
12971 {0x47, 0x7, 0},
12972 {0x48, 0x33, 0},
12973 {0x49, 0x5, 0},
12974 {0x4A, 0x77, 0},
12975 {0x4B, 0x66, 0},
12976 {0x4C, 0x66, 0},
12977 {0x4D, 0, 0},
12978 {0x4E, 0x4, 0},
12979 {0x4F, 0xc, 0},
12980 {0x50, 0, 0},
12981 {0x51, 0x70, 1},
12982 {0x56, 0x7, 0},
12983 {0x57, 0, 0},
12984 {0x58, 0, 0},
12985 {0x59, 0x88, 1},
12986 {0x5A, 0, 0},
12987 {0x5B, 0x1f, 0},
12988 {0x5C, 0x20, 1},
12989 {0x5D, 0x1, 0},
12990 {0x5E, 0x30, 0},
12991 {0x5F, 0x70, 0},
12992 {0x60, 0, 0},
12993 {0x61, 0, 0},
12994 {0x62, 0x33, 1},
12995 {0x63, 0xf, 1},
12996 {0x64, 0xf, 1},
12997 {0x65, 0, 0},
12998 {0x66, 0x11, 0},
12999 {0x69, 0, 0},
13000 {0x6A, 0x7e, 0},
13001 {0x6B, 0x3f, 0},
13002 {0x6C, 0x7f, 0},
13003 {0x6D, 0x78, 0},
13004 {0x6E, 0x58, 1},
13005 {0x6F, 0x88, 0},
13006 {0x70, 0x8, 0},
13007 {0x71, 0xf, 0},
13008 {0x72, 0xbc, 0},
13009 {0x73, 0x8, 0},
13010 {0x74, 0x60, 0},
13011 {0x75, 0x13, 1},
13012 {0x76, 0x70, 0},
13013 {0x77, 0, 0},
13014 {0x78, 0, 0},
13015 {0x79, 0, 0},
13016 {0x7A, 0x33, 0},
13017 {0x7B, 0x13, 1},
13018 {0x7C, 0xf, 1},
13019 {0x7D, 0xee, 1},
13020 {0x80, 0x3c, 0},
13021 {0x81, 0x1, 1},
13022 {0x82, 0xa, 0},
13023 {0x83, 0x9d, 0},
13024 {0x84, 0xa, 0},
13025 {0x85, 0, 0},
13026 {0x86, 0x40, 0},
13027 {0x87, 0x40, 0},
13028 {0x88, 0x88, 0},
13029 {0x89, 0x10, 0},
13030 {0x8A, 0xf0, 0},
13031 {0x8B, 0x10, 0},
13032 {0x8C, 0xf0, 0},
13033 {0x8D, 0, 0},
13034 {0x8E, 0, 0},
13035 {0x8F, 0x10, 0},
13036 {0x90, 0x55, 0},
13037 {0x91, 0x3f, 1},
13038 {0x92, 0x36, 1},
13039 {0x93, 0, 0},
13040 {0x94, 0, 0},
13041 {0x95, 0, 0},
13042 {0x96, 0x87, 0},
13043 {0x97, 0x11, 0},
13044 {0x98, 0, 0},
13045 {0x99, 0x33, 0},
13046 {0x9A, 0x88, 0},
13047 {0x9B, 0, 0},
13048 {0x9C, 0x87, 0},
13049 {0x9D, 0x11, 0},
13050 {0x9E, 0, 0},
13051 {0x9F, 0x33, 0},
13052 {0xA0, 0x88, 0},
13053 {0xA1, 0x20, 1},
13054 {0xA2, 0x3f, 0},
13055 {0xA3, 0x44, 0},
13056 {0xA4, 0x8c, 0},
13057 {0xA5, 0x6c, 0},
13058 {0xA6, 0x22, 0},
13059 {0xA7, 0xbe, 0},
13060 {0xA8, 0x55, 0},
13061 {0xAA, 0xc, 0},
13062 {0xAB, 0xaa, 0},
13063 {0xAC, 0x2, 0},
13064 {0xAD, 0, 0},
13065 {0xAE, 0x10, 0},
13066 {0xAF, 0x1, 0},
13067 {0xB0, 0, 0},
13068 {0xB1, 0, 0},
13069 {0xB2, 0x80, 0},
13070 {0xB3, 0x60, 0},
13071 {0xB4, 0x44, 0},
13072 {0xB5, 0x55, 0},
13073 {0xB6, 0x1, 0},
13074 {0xB7, 0x55, 0},
13075 {0xB8, 0x1, 0},
13076 {0xB9, 0x5, 0},
13077 {0xBA, 0x55, 0},
13078 {0xBB, 0x55, 0},
13079 {0xC1, 0, 0},
13080 {0xC2, 0, 0},
13081 {0xC3, 0, 0},
13082 {0xC4, 0, 0},
13083 {0xC5, 0, 0},
13084 {0xC6, 0, 0},
13085 {0xC7, 0, 0},
13086 {0xC8, 0, 0},
13087 {0xC9, 0x1, 1},
13088 {0xCA, 0, 0},
13089 {0xCB, 0, 0},
13090 {0xCC, 0, 0},
13091 {0xCD, 0, 0},
13092 {0xCE, 0x5e, 0},
13093 {0xCF, 0xc, 0},
13094 {0xD0, 0xc, 0},
13095 {0xD1, 0xc, 0},
13096 {0xD2, 0, 0},
13097 {0xD3, 0x2b, 0},
13098 {0xD4, 0xc, 0},
13099 {0xD5, 0, 0},
13100 {0xD6, 0x70, 1},
13101 {0xDB, 0x7, 0},
13102 {0xDC, 0, 0},
13103 {0xDD, 0, 0},
13104 {0xDE, 0x88, 1},
13105 {0xDF, 0, 0},
13106 {0xE0, 0x1f, 0},
13107 {0xE1, 0x20, 1},
13108 {0xE2, 0x1, 0},
13109 {0xE3, 0x30, 0},
13110 {0xE4, 0x70, 0},
13111 {0xE5, 0, 0},
13112 {0xE6, 0, 0},
13113 {0xE7, 0x33, 0},
13114 {0xE8, 0xf, 1},
13115 {0xE9, 0xf, 1},
13116 {0xEA, 0, 0},
13117 {0xEB, 0x11, 0},
13118 {0xEE, 0, 0},
13119 {0xEF, 0x7e, 0},
13120 {0xF0, 0x3f, 0},
13121 {0xF1, 0x7f, 0},
13122 {0xF2, 0x78, 0},
13123 {0xF3, 0x58, 1},
13124 {0xF4, 0x88, 0},
13125 {0xF5, 0x8, 0},
13126 {0xF6, 0xf, 0},
13127 {0xF7, 0xbc, 0},
13128 {0xF8, 0x8, 0},
13129 {0xF9, 0x60, 0},
13130 {0xFA, 0x13, 1},
13131 {0xFB, 0x70, 0},
13132 {0xFC, 0, 0},
13133 {0xFD, 0, 0},
13134 {0xFE, 0, 0},
13135 {0xFF, 0x33, 0},
13136 {0x100, 0x13, 1},
13137 {0x101, 0xf, 1},
13138 {0x102, 0xee, 1},
13139 {0x105, 0x3c, 0},
13140 {0x106, 0x1, 1},
13141 {0x107, 0xa, 0},
13142 {0x108, 0x9d, 0},
13143 {0x109, 0xa, 0},
13144 {0x10A, 0, 0},
13145 {0x10B, 0x40, 0},
13146 {0x10C, 0x40, 0},
13147 {0x10D, 0x88, 0},
13148 {0x10E, 0x10, 0},
13149 {0x10F, 0xf0, 0},
13150 {0x110, 0x10, 0},
13151 {0x111, 0xf0, 0},
13152 {0x112, 0, 0},
13153 {0x113, 0, 0},
13154 {0x114, 0x10, 0},
13155 {0x115, 0x55, 0},
13156 {0x116, 0x3f, 1},
13157 {0x117, 0x36, 1},
13158 {0x118, 0, 0},
13159 {0x119, 0, 0},
13160 {0x11A, 0, 0},
13161 {0x11B, 0x87, 0},
13162 {0x11C, 0x11, 0},
13163 {0x11D, 0, 0},
13164 {0x11E, 0x33, 0},
13165 {0x11F, 0x88, 0},
13166 {0x120, 0, 0},
13167 {0x121, 0x87, 0},
13168 {0x122, 0x11, 0},
13169 {0x123, 0, 0},
13170 {0x124, 0x33, 0},
13171 {0x125, 0x88, 0},
13172 {0x126, 0x20, 1},
13173 {0x127, 0x3f, 0},
13174 {0x128, 0x44, 0},
13175 {0x129, 0x8c, 0},
13176 {0x12A, 0x6c, 0},
13177 {0x12B, 0x22, 0},
13178 {0x12C, 0xbe, 0},
13179 {0x12D, 0x55, 0},
13180 {0x12F, 0xc, 0},
13181 {0x130, 0xaa, 0},
13182 {0x131, 0x2, 0},
13183 {0x132, 0, 0},
13184 {0x133, 0x10, 0},
13185 {0x134, 0x1, 0},
13186 {0x135, 0, 0},
13187 {0x136, 0, 0},
13188 {0x137, 0x80, 0},
13189 {0x138, 0x60, 0},
13190 {0x139, 0x44, 0},
13191 {0x13A, 0x55, 0},
13192 {0x13B, 0x1, 0},
13193 {0x13C, 0x55, 0},
13194 {0x13D, 0x1, 0},
13195 {0x13E, 0x5, 0},
13196 {0x13F, 0x55, 0},
13197 {0x140, 0x55, 0},
13198 {0x146, 0, 0},
13199 {0x147, 0, 0},
13200 {0x148, 0, 0},
13201 {0x149, 0, 0},
13202 {0x14A, 0, 0},
13203 {0x14B, 0, 0},
13204 {0x14C, 0, 0},
13205 {0x14D, 0, 0},
13206 {0x14E, 0x1, 1},
13207 {0x14F, 0, 0},
13208 {0x150, 0, 0},
13209 {0x151, 0, 0},
13210 {0x154, 0xc, 0},
13211 {0x155, 0xc, 0},
13212 {0x156, 0xc, 0},
13213 {0x157, 0, 0},
13214 {0x158, 0x2b, 0},
13215 {0x159, 0x84, 0},
13216 {0x15A, 0x15, 0},
13217 {0x15B, 0xf, 0},
13218 {0x15C, 0, 0},
13219 {0x15D, 0, 0},
13220 {0x15E, 0, 1},
13221 {0x15F, 0, 1},
13222 {0x160, 0, 1},
13223 {0x161, 0, 1},
13224 {0x162, 0, 1},
13225 {0x163, 0, 1},
13226 {0x164, 0, 0},
13227 {0x165, 0, 0},
13228 {0x166, 0, 0},
13229 {0x167, 0, 0},
13230 {0x168, 0, 0},
13231 {0x169, 0, 0},
13232 {0x16A, 0, 1},
13233 {0x16B, 0, 1},
13234 {0x16C, 0, 1},
13235 {0x16D, 0, 0},
13236 {0x170, 0, 0},
13237 {0x171, 0x77, 0},
13238 {0x172, 0x77, 0},
13239 {0x173, 0x77, 0},
13240 {0x174, 0x77, 0},
13241 {0x175, 0, 0},
13242 {0x176, 0x3, 0},
13243 {0x177, 0x37, 0},
13244 {0x178, 0x3, 0},
13245 {0x179, 0, 0},
13246 {0x17A, 0x21, 0},
13247 {0x17B, 0x21, 0},
13248 {0x17C, 0, 0},
13249 {0x17D, 0xaa, 0},
13250 {0x17E, 0, 0},
13251 {0x17F, 0xaa, 0},
13252 {0x180, 0, 0},
13253 {0x190, 0, 0},
13254 {0x191, 0x77, 0},
13255 {0x192, 0x77, 0},
13256 {0x193, 0x77, 0},
13257 {0x194, 0x77, 0},
13258 {0x195, 0, 0},
13259 {0x196, 0x3, 0},
13260 {0x197, 0x37, 0},
13261 {0x198, 0x3, 0},
13262 {0x199, 0, 0},
13263 {0x19A, 0x21, 0},
13264 {0x19B, 0x21, 0},
13265 {0x19C, 0, 0},
13266 {0x19D, 0xaa, 0},
13267 {0x19E, 0, 0},
13268 {0x19F, 0xaa, 0},
13269 {0x1A0, 0, 0},
13270 {0x1A1, 0x2, 0},
13271 {0x1A2, 0xf, 0},
13272 {0x1A3, 0xf, 0},
13273 {0x1A4, 0, 1},
13274 {0x1A5, 0, 1},
13275 {0x1A6, 0, 1},
13276 {0x1A7, 0x2, 0},
13277 {0x1A8, 0xf, 0},
13278 {0x1A9, 0xf, 0},
13279 {0x1AA, 0, 1},
13280 {0x1AB, 0, 1},
13281 {0x1AC, 0, 1},
13282 {0x1AD, 0x84, 0},
13283 {0x1AE, 0x60, 0},
13284 {0x1AF, 0x47, 0},
13285 {0x1B0, 0x47, 0},
13286 {0x1B1, 0, 0},
13287 {0x1B2, 0, 0},
13288 {0x1B3, 0, 0},
13289 {0x1B4, 0, 0},
13290 {0x1B5, 0, 0},
13291 {0x1B6, 0, 0},
13292 {0x1B7, 0x5, 1},
13293 {0x1B8, 0, 0},
13294 {0x1B9, 0, 0},
13295 {0x1BA, 0, 0},
13296 {0x1BB, 0, 0},
13297 {0x1BC, 0, 0},
13298 {0x1BD, 0, 0},
13299 {0x1BE, 0, 0},
13300 {0x1BF, 0, 0},
13301 {0x1C0, 0, 0},
13302 {0x1C1, 0, 0},
13303 {0x1C2, 0xa0, 1},
13304 {0x1C3, 0, 0},
13305 {0x1C4, 0, 0},
13306 {0x1C5, 0, 0},
13307 {0x1C6, 0, 0},
13308 {0x1C7, 0, 0},
13309 {0x1C8, 0, 0},
13310 {0x1C9, 0, 0},
13311 {0x1CA, 0, 0},
13312 {0xFFFF, 0, 0}
13313};
13314
13315static s16 nphy_def_lnagains[] = { -2, 10, 19, 25 };
13316
13317static s32 nphy_lnagain_est0[] = { -315, 40370 };
13318static s32 nphy_lnagain_est1[] = { -224, 23242 };
13319
13320static const u16 tbl_iqcal_gainparams_nphy[2][NPHY_IQCAL_NUMGAINS][8] = {
13321 {
13322 {0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69},
13323 {0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69},
13324 {0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68},
13325 {0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67},
13326 {0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66},
13327 {0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65},
13328 {0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65},
13329 {0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65},
13330 {0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65}
13331 },
13332 {
13333 {0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
13334 {0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
13335 {0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79},
13336 {0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78},
13337 {0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78},
13338 {0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78},
13339 {0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78},
13340 {0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78},
13341 {0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78}
13342 }
13343};
13344
13345static const u32 nphy_tpc_txgain[] = {
13346 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
13347 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
13348 0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844,
13349 0x03c82842, 0x03c42b44, 0x03c42b42, 0x03c42a44,
13350 0x03c42a42, 0x03c42944, 0x03c42942, 0x03c42844,
13351 0x03c42842, 0x03c42744, 0x03c42742, 0x03c42644,
13352 0x03c42642, 0x03c42544, 0x03c42542, 0x03c42444,
13353 0x03c42442, 0x03c02b44, 0x03c02b42, 0x03c02a44,
13354 0x03c02a42, 0x03c02944, 0x03c02942, 0x03c02844,
13355 0x03c02842, 0x03c02744, 0x03c02742, 0x03b02b44,
13356 0x03b02b42, 0x03b02a44, 0x03b02a42, 0x03b02944,
13357 0x03b02942, 0x03b02844, 0x03b02842, 0x03b02744,
13358 0x03b02742, 0x03b02644, 0x03b02642, 0x03b02544,
13359 0x03b02542, 0x03a02b44, 0x03a02b42, 0x03a02a44,
13360 0x03a02a42, 0x03a02944, 0x03a02942, 0x03a02844,
13361 0x03a02842, 0x03a02744, 0x03a02742, 0x03902b44,
13362 0x03902b42, 0x03902a44, 0x03902a42, 0x03902944,
13363 0x03902942, 0x03902844, 0x03902842, 0x03902744,
13364 0x03902742, 0x03902644, 0x03902642, 0x03902544,
13365 0x03902542, 0x03802b44, 0x03802b42, 0x03802a44,
13366 0x03802a42, 0x03802944, 0x03802942, 0x03802844,
13367 0x03802842, 0x03802744, 0x03802742, 0x03802644,
13368 0x03802642, 0x03802544, 0x03802542, 0x03802444,
13369 0x03802442, 0x03802344, 0x03802342, 0x03802244,
13370 0x03802242, 0x03802144, 0x03802142, 0x03802044,
13371 0x03802042, 0x03801f44, 0x03801f42, 0x03801e44,
13372 0x03801e42, 0x03801d44, 0x03801d42, 0x03801c44,
13373 0x03801c42, 0x03801b44, 0x03801b42, 0x03801a44,
13374 0x03801a42, 0x03801944, 0x03801942, 0x03801844,
13375 0x03801842, 0x03801744, 0x03801742, 0x03801644,
13376 0x03801642, 0x03801544, 0x03801542, 0x03801444,
13377 0x03801442, 0x03801344, 0x03801342, 0x00002b00
13378};
13379
13380static const u16 nphy_tpc_loscale[] = {
13381 256, 256, 271, 271, 287, 256, 256, 271,
13382 271, 287, 287, 304, 304, 256, 256, 271,
13383 271, 287, 287, 304, 304, 322, 322, 341,
13384 341, 362, 362, 383, 383, 256, 256, 271,
13385 271, 287, 287, 304, 304, 322, 322, 256,
13386 256, 271, 271, 287, 287, 304, 304, 322,
13387 322, 341, 341, 362, 362, 256, 256, 271,
13388 271, 287, 287, 304, 304, 322, 322, 256,
13389 256, 271, 271, 287, 287, 304, 304, 322,
13390 322, 341, 341, 362, 362, 256, 256, 271,
13391 271, 287, 287, 304, 304, 322, 322, 341,
13392 341, 362, 362, 383, 383, 406, 406, 430,
13393 430, 455, 455, 482, 482, 511, 511, 541,
13394 541, 573, 573, 607, 607, 643, 643, 681,
13395 681, 722, 722, 764, 764, 810, 810, 858,
13396 858, 908, 908, 962, 962, 1019, 1019, 256
13397};
13398
13399static u32 nphy_tpc_txgain_ipa[] = {
13400 0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
13401 0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
13402 0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
13403 0x5ef70028, 0x5ef70027, 0x5ef70026, 0x5ef70025,
13404 0x5df7002d, 0x5df7002b, 0x5df7002a, 0x5df70029,
13405 0x5df70028, 0x5df70027, 0x5df70026, 0x5df70025,
13406 0x5cf7002d, 0x5cf7002b, 0x5cf7002a, 0x5cf70029,
13407 0x5cf70028, 0x5cf70027, 0x5cf70026, 0x5cf70025,
13408 0x5bf7002d, 0x5bf7002b, 0x5bf7002a, 0x5bf70029,
13409 0x5bf70028, 0x5bf70027, 0x5bf70026, 0x5bf70025,
13410 0x5af7002d, 0x5af7002b, 0x5af7002a, 0x5af70029,
13411 0x5af70028, 0x5af70027, 0x5af70026, 0x5af70025,
13412 0x59f7002d, 0x59f7002b, 0x59f7002a, 0x59f70029,
13413 0x59f70028, 0x59f70027, 0x59f70026, 0x59f70025,
13414 0x58f7002d, 0x58f7002b, 0x58f7002a, 0x58f70029,
13415 0x58f70028, 0x58f70027, 0x58f70026, 0x58f70025,
13416 0x57f7002d, 0x57f7002b, 0x57f7002a, 0x57f70029,
13417 0x57f70028, 0x57f70027, 0x57f70026, 0x57f70025,
13418 0x56f7002d, 0x56f7002b, 0x56f7002a, 0x56f70029,
13419 0x56f70028, 0x56f70027, 0x56f70026, 0x56f70025,
13420 0x55f7002d, 0x55f7002b, 0x55f7002a, 0x55f70029,
13421 0x55f70028, 0x55f70027, 0x55f70026, 0x55f70025,
13422 0x54f7002d, 0x54f7002b, 0x54f7002a, 0x54f70029,
13423 0x54f70028, 0x54f70027, 0x54f70026, 0x54f70025,
13424 0x53f7002d, 0x53f7002b, 0x53f7002a, 0x53f70029,
13425 0x53f70028, 0x53f70027, 0x53f70026, 0x53f70025,
13426 0x52f7002d, 0x52f7002b, 0x52f7002a, 0x52f70029,
13427 0x52f70028, 0x52f70027, 0x52f70026, 0x52f70025,
13428 0x51f7002d, 0x51f7002b, 0x51f7002a, 0x51f70029,
13429 0x51f70028, 0x51f70027, 0x51f70026, 0x51f70025,
13430 0x50f7002d, 0x50f7002b, 0x50f7002a, 0x50f70029,
13431 0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025
13432};
13433
13434static u32 nphy_tpc_txgain_ipa_rev5[] = {
13435 0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
13436 0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
13437 0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
13438 0x1ef70028, 0x1ef70027, 0x1ef70026, 0x1ef70025,
13439 0x1df7002d, 0x1df7002b, 0x1df7002a, 0x1df70029,
13440 0x1df70028, 0x1df70027, 0x1df70026, 0x1df70025,
13441 0x1cf7002d, 0x1cf7002b, 0x1cf7002a, 0x1cf70029,
13442 0x1cf70028, 0x1cf70027, 0x1cf70026, 0x1cf70025,
13443 0x1bf7002d, 0x1bf7002b, 0x1bf7002a, 0x1bf70029,
13444 0x1bf70028, 0x1bf70027, 0x1bf70026, 0x1bf70025,
13445 0x1af7002d, 0x1af7002b, 0x1af7002a, 0x1af70029,
13446 0x1af70028, 0x1af70027, 0x1af70026, 0x1af70025,
13447 0x19f7002d, 0x19f7002b, 0x19f7002a, 0x19f70029,
13448 0x19f70028, 0x19f70027, 0x19f70026, 0x19f70025,
13449 0x18f7002d, 0x18f7002b, 0x18f7002a, 0x18f70029,
13450 0x18f70028, 0x18f70027, 0x18f70026, 0x18f70025,
13451 0x17f7002d, 0x17f7002b, 0x17f7002a, 0x17f70029,
13452 0x17f70028, 0x17f70027, 0x17f70026, 0x17f70025,
13453 0x16f7002d, 0x16f7002b, 0x16f7002a, 0x16f70029,
13454 0x16f70028, 0x16f70027, 0x16f70026, 0x16f70025,
13455 0x15f7002d, 0x15f7002b, 0x15f7002a, 0x15f70029,
13456 0x15f70028, 0x15f70027, 0x15f70026, 0x15f70025,
13457 0x14f7002d, 0x14f7002b, 0x14f7002a, 0x14f70029,
13458 0x14f70028, 0x14f70027, 0x14f70026, 0x14f70025,
13459 0x13f7002d, 0x13f7002b, 0x13f7002a, 0x13f70029,
13460 0x13f70028, 0x13f70027, 0x13f70026, 0x13f70025,
13461 0x12f7002d, 0x12f7002b, 0x12f7002a, 0x12f70029,
13462 0x12f70028, 0x12f70027, 0x12f70026, 0x12f70025,
13463 0x11f7002d, 0x11f7002b, 0x11f7002a, 0x11f70029,
13464 0x11f70028, 0x11f70027, 0x11f70026, 0x11f70025,
13465 0x10f7002d, 0x10f7002b, 0x10f7002a, 0x10f70029,
13466 0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025
13467};
13468
13469static u32 nphy_tpc_txgain_ipa_rev6[] = {
13470 0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
13471 0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
13472 0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
13473 0x0ef70028, 0x0ef70027, 0x0ef70026, 0x0ef70025,
13474 0x0df7002d, 0x0df7002b, 0x0df7002a, 0x0df70029,
13475 0x0df70028, 0x0df70027, 0x0df70026, 0x0df70025,
13476 0x0cf7002d, 0x0cf7002b, 0x0cf7002a, 0x0cf70029,
13477 0x0cf70028, 0x0cf70027, 0x0cf70026, 0x0cf70025,
13478 0x0bf7002d, 0x0bf7002b, 0x0bf7002a, 0x0bf70029,
13479 0x0bf70028, 0x0bf70027, 0x0bf70026, 0x0bf70025,
13480 0x0af7002d, 0x0af7002b, 0x0af7002a, 0x0af70029,
13481 0x0af70028, 0x0af70027, 0x0af70026, 0x0af70025,
13482 0x09f7002d, 0x09f7002b, 0x09f7002a, 0x09f70029,
13483 0x09f70028, 0x09f70027, 0x09f70026, 0x09f70025,
13484 0x08f7002d, 0x08f7002b, 0x08f7002a, 0x08f70029,
13485 0x08f70028, 0x08f70027, 0x08f70026, 0x08f70025,
13486 0x07f7002d, 0x07f7002b, 0x07f7002a, 0x07f70029,
13487 0x07f70028, 0x07f70027, 0x07f70026, 0x07f70025,
13488 0x06f7002d, 0x06f7002b, 0x06f7002a, 0x06f70029,
13489 0x06f70028, 0x06f70027, 0x06f70026, 0x06f70025,
13490 0x05f7002d, 0x05f7002b, 0x05f7002a, 0x05f70029,
13491 0x05f70028, 0x05f70027, 0x05f70026, 0x05f70025,
13492 0x04f7002d, 0x04f7002b, 0x04f7002a, 0x04f70029,
13493 0x04f70028, 0x04f70027, 0x04f70026, 0x04f70025,
13494 0x03f7002d, 0x03f7002b, 0x03f7002a, 0x03f70029,
13495 0x03f70028, 0x03f70027, 0x03f70026, 0x03f70025,
13496 0x02f7002d, 0x02f7002b, 0x02f7002a, 0x02f70029,
13497 0x02f70028, 0x02f70027, 0x02f70026, 0x02f70025,
13498 0x01f7002d, 0x01f7002b, 0x01f7002a, 0x01f70029,
13499 0x01f70028, 0x01f70027, 0x01f70026, 0x01f70025,
13500 0x00f7002d, 0x00f7002b, 0x00f7002a, 0x00f70029,
13501 0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025
13502};
13503
13504static u32 nphy_tpc_txgain_ipa_2g_2057rev3[] = {
13505 0x70ff0040, 0x70f7003e, 0x70ef003b, 0x70e70039,
13506 0x70df0037, 0x70d70036, 0x70cf0033, 0x70c70032,
13507 0x70bf0031, 0x70b7002f, 0x70af002e, 0x70a7002d,
13508 0x709f002d, 0x7097002c, 0x708f002c, 0x7087002c,
13509 0x707f002b, 0x7077002c, 0x706f002c, 0x7067002d,
13510 0x705f002e, 0x705f002b, 0x705f0029, 0x7057002a,
13511 0x70570028, 0x704f002a, 0x7047002c, 0x7047002a,
13512 0x70470028, 0x70470026, 0x70470024, 0x70470022,
13513 0x7047001f, 0x70370027, 0x70370024, 0x70370022,
13514 0x70370020, 0x7037001f, 0x7037001d, 0x7037001b,
13515 0x7037001a, 0x70370018, 0x70370017, 0x7027001e,
13516 0x7027001d, 0x7027001a, 0x701f0024, 0x701f0022,
13517 0x701f0020, 0x701f001f, 0x701f001d, 0x701f001b,
13518 0x701f001a, 0x701f0018, 0x701f0017, 0x701f0015,
13519 0x701f0014, 0x701f0013, 0x701f0012, 0x701f0011,
13520 0x70170019, 0x70170018, 0x70170016, 0x70170015,
13521 0x70170014, 0x70170013, 0x70170012, 0x70170010,
13522 0x70170010, 0x7017000f, 0x700f001d, 0x700f001b,
13523 0x700f001a, 0x700f0018, 0x700f0017, 0x700f0015,
13524 0x700f0015, 0x700f0013, 0x700f0013, 0x700f0011,
13525 0x700f0010, 0x700f0010, 0x700f000f, 0x700f000e,
13526 0x700f000d, 0x700f000c, 0x700f000b, 0x700f000b,
13527 0x700f000b, 0x700f000a, 0x700f0009, 0x700f0009,
13528 0x700f0009, 0x700f0008, 0x700f0007, 0x700f0007,
13529 0x700f0006, 0x700f0006, 0x700f0006, 0x700f0006,
13530 0x700f0005, 0x700f0005, 0x700f0005, 0x700f0004,
13531 0x700f0004, 0x700f0004, 0x700f0004, 0x700f0004,
13532 0x700f0004, 0x700f0003, 0x700f0003, 0x700f0003,
13533 0x700f0003, 0x700f0002, 0x700f0002, 0x700f0002,
13534 0x700f0002, 0x700f0002, 0x700f0002, 0x700f0001,
13535 0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001,
13536 0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001
13537};
13538
13539static u32 nphy_tpc_txgain_ipa_2g_2057rev4n6[] = {
13540 0xf0ff0040, 0xf0f7003e, 0xf0ef003b, 0xf0e70039,
13541 0xf0df0037, 0xf0d70036, 0xf0cf0033, 0xf0c70032,
13542 0xf0bf0031, 0xf0b7002f, 0xf0af002e, 0xf0a7002d,
13543 0xf09f002d, 0xf097002c, 0xf08f002c, 0xf087002c,
13544 0xf07f002b, 0xf077002c, 0xf06f002c, 0xf067002d,
13545 0xf05f002e, 0xf05f002b, 0xf05f0029, 0xf057002a,
13546 0xf0570028, 0xf04f002a, 0xf047002c, 0xf047002a,
13547 0xf0470028, 0xf0470026, 0xf0470024, 0xf0470022,
13548 0xf047001f, 0xf0370027, 0xf0370024, 0xf0370022,
13549 0xf0370020, 0xf037001f, 0xf037001d, 0xf037001b,
13550 0xf037001a, 0xf0370018, 0xf0370017, 0xf027001e,
13551 0xf027001d, 0xf027001a, 0xf01f0024, 0xf01f0022,
13552 0xf01f0020, 0xf01f001f, 0xf01f001d, 0xf01f001b,
13553 0xf01f001a, 0xf01f0018, 0xf01f0017, 0xf01f0015,
13554 0xf01f0014, 0xf01f0013, 0xf01f0012, 0xf01f0011,
13555 0xf0170019, 0xf0170018, 0xf0170016, 0xf0170015,
13556 0xf0170014, 0xf0170013, 0xf0170012, 0xf0170010,
13557 0xf0170010, 0xf017000f, 0xf00f001d, 0xf00f001b,
13558 0xf00f001a, 0xf00f0018, 0xf00f0017, 0xf00f0015,
13559 0xf00f0015, 0xf00f0013, 0xf00f0013, 0xf00f0011,
13560 0xf00f0010, 0xf00f0010, 0xf00f000f, 0xf00f000e,
13561 0xf00f000d, 0xf00f000c, 0xf00f000b, 0xf00f000b,
13562 0xf00f000b, 0xf00f000a, 0xf00f0009, 0xf00f0009,
13563 0xf00f0009, 0xf00f0008, 0xf00f0007, 0xf00f0007,
13564 0xf00f0006, 0xf00f0006, 0xf00f0006, 0xf00f0006,
13565 0xf00f0005, 0xf00f0005, 0xf00f0005, 0xf00f0004,
13566 0xf00f0004, 0xf00f0004, 0xf00f0004, 0xf00f0004,
13567 0xf00f0004, 0xf00f0003, 0xf00f0003, 0xf00f0003,
13568 0xf00f0003, 0xf00f0002, 0xf00f0002, 0xf00f0002,
13569 0xf00f0002, 0xf00f0002, 0xf00f0002, 0xf00f0001,
13570 0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001,
13571 0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001
13572};
13573
13574static u32 nphy_tpc_txgain_ipa_2g_2057rev5[] = {
13575 0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
13576 0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
13577 0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
13578 0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
13579 0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
13580 0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
13581 0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
13582 0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
13583 0x30270027, 0x30270025, 0x30270023, 0x301f002c,
13584 0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
13585 0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
13586 0x30170028, 0x30170026, 0x30170024, 0x30170022,
13587 0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
13588 0x3017001a, 0x30170018, 0x30170017, 0x30170015,
13589 0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
13590 0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
13591 0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
13592 0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
13593 0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
13594 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13595 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13596 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13597 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13598 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13599 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13600 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13601 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13602 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13603 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13604 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13605 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13606 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
13607};
13608
13609static u32 nphy_tpc_txgain_ipa_2g_2057rev7[] = {
13610 0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
13611 0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
13612 0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
13613 0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
13614 0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
13615 0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
13616 0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
13617 0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
13618 0x30270027, 0x30270025, 0x30270023, 0x301f002c,
13619 0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
13620 0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
13621 0x30170028, 0x30170026, 0x30170024, 0x30170022,
13622 0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
13623 0x3017001a, 0x30170018, 0x30170017, 0x30170015,
13624 0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
13625 0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
13626 0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
13627 0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
13628 0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
13629 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13630 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13631 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13632 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13633 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13634 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13635 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13636 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13637 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13638 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13639 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13640 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13641 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
13642};
13643
13644static u32 nphy_tpc_txgain_ipa_5g[] = {
13645 0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
13646 0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
13647 0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
13648 0x7ff70026, 0x7ff70024, 0x7ff70023, 0x7ff70022,
13649 0x7ef70028, 0x7ef70027, 0x7ef70026, 0x7ef70025,
13650 0x7ef70024, 0x7ef70023, 0x7df70028, 0x7df70027,
13651 0x7df70026, 0x7df70025, 0x7df70024, 0x7df70023,
13652 0x7df70022, 0x7cf70029, 0x7cf70028, 0x7cf70027,
13653 0x7cf70026, 0x7cf70025, 0x7cf70023, 0x7cf70022,
13654 0x7bf70029, 0x7bf70028, 0x7bf70026, 0x7bf70025,
13655 0x7bf70024, 0x7bf70023, 0x7bf70022, 0x7bf70021,
13656 0x7af70029, 0x7af70028, 0x7af70027, 0x7af70026,
13657 0x7af70025, 0x7af70024, 0x7af70023, 0x7af70022,
13658 0x79f70029, 0x79f70028, 0x79f70027, 0x79f70026,
13659 0x79f70025, 0x79f70024, 0x79f70023, 0x79f70022,
13660 0x78f70029, 0x78f70028, 0x78f70027, 0x78f70026,
13661 0x78f70025, 0x78f70024, 0x78f70023, 0x78f70022,
13662 0x77f70029, 0x77f70028, 0x77f70027, 0x77f70026,
13663 0x77f70025, 0x77f70024, 0x77f70023, 0x77f70022,
13664 0x76f70029, 0x76f70028, 0x76f70027, 0x76f70026,
13665 0x76f70024, 0x76f70023, 0x76f70022, 0x76f70021,
13666 0x75f70029, 0x75f70028, 0x75f70027, 0x75f70026,
13667 0x75f70025, 0x75f70024, 0x75f70023, 0x74f70029,
13668 0x74f70028, 0x74f70026, 0x74f70025, 0x74f70024,
13669 0x74f70023, 0x74f70022, 0x73f70029, 0x73f70027,
13670 0x73f70026, 0x73f70025, 0x73f70024, 0x73f70023,
13671 0x73f70022, 0x72f70028, 0x72f70027, 0x72f70026,
13672 0x72f70025, 0x72f70024, 0x72f70023, 0x72f70022,
13673 0x71f70028, 0x71f70027, 0x71f70026, 0x71f70025,
13674 0x71f70024, 0x71f70023, 0x70f70028, 0x70f70027,
13675 0x70f70026, 0x70f70024, 0x70f70023, 0x70f70022,
13676 0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f
13677};
13678
13679static u32 nphy_tpc_txgain_ipa_5g_2057[] = {
13680 0x7f7f0044, 0x7f7f0040, 0x7f7f003c, 0x7f7f0039,
13681 0x7f7f0036, 0x7e7f003c, 0x7e7f0038, 0x7e7f0035,
13682 0x7d7f003c, 0x7d7f0039, 0x7d7f0036, 0x7d7f0033,
13683 0x7c7f003b, 0x7c7f0037, 0x7c7f0034, 0x7b7f003a,
13684 0x7b7f0036, 0x7b7f0033, 0x7a7f003c, 0x7a7f0039,
13685 0x7a7f0036, 0x7a7f0033, 0x797f003b, 0x797f0038,
13686 0x797f0035, 0x797f0032, 0x787f003b, 0x787f0038,
13687 0x787f0035, 0x787f0032, 0x777f003a, 0x777f0037,
13688 0x777f0034, 0x777f0031, 0x767f003a, 0x767f0036,
13689 0x767f0033, 0x767f0031, 0x757f003a, 0x757f0037,
13690 0x757f0034, 0x747f003c, 0x747f0039, 0x747f0036,
13691 0x747f0033, 0x737f003b, 0x737f0038, 0x737f0035,
13692 0x737f0032, 0x727f0039, 0x727f0036, 0x727f0033,
13693 0x727f0030, 0x717f003a, 0x717f0037, 0x717f0034,
13694 0x707f003b, 0x707f0038, 0x707f0035, 0x707f0032,
13695 0x707f002f, 0x707f002d, 0x707f002a, 0x707f0028,
13696 0x707f0025, 0x707f0023, 0x707f0021, 0x707f0020,
13697 0x707f001e, 0x707f001c, 0x707f001b, 0x707f0019,
13698 0x707f0018, 0x707f0016, 0x707f0015, 0x707f0014,
13699 0x707f0013, 0x707f0012, 0x707f0011, 0x707f0010,
13700 0x707f000f, 0x707f000e, 0x707f000d, 0x707f000d,
13701 0x707f000c, 0x707f000b, 0x707f000b, 0x707f000a,
13702 0x707f0009, 0x707f0009, 0x707f0008, 0x707f0008,
13703 0x707f0007, 0x707f0007, 0x707f0007, 0x707f0006,
13704 0x707f0006, 0x707f0006, 0x707f0005, 0x707f0005,
13705 0x707f0005, 0x707f0004, 0x707f0004, 0x707f0004,
13706 0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
13707 0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
13708 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
13709 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
13710 0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
13711 0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001
13712};
13713
13714static u32 nphy_tpc_txgain_ipa_5g_2057rev7[] = {
13715 0x6f7f0031, 0x6f7f002e, 0x6f7f002c, 0x6f7f002a,
13716 0x6f7f0027, 0x6e7f002e, 0x6e7f002c, 0x6e7f002a,
13717 0x6d7f0030, 0x6d7f002d, 0x6d7f002a, 0x6d7f0028,
13718 0x6c7f0030, 0x6c7f002d, 0x6c7f002b, 0x6b7f002e,
13719 0x6b7f002c, 0x6b7f002a, 0x6b7f0027, 0x6a7f002e,
13720 0x6a7f002c, 0x6a7f002a, 0x697f0030, 0x697f002e,
13721 0x697f002b, 0x697f0029, 0x687f002f, 0x687f002d,
13722 0x687f002a, 0x687f0027, 0x677f002f, 0x677f002d,
13723 0x677f002a, 0x667f0031, 0x667f002e, 0x667f002c,
13724 0x667f002a, 0x657f0030, 0x657f002e, 0x657f002b,
13725 0x657f0029, 0x647f0030, 0x647f002d, 0x647f002b,
13726 0x647f0029, 0x637f002f, 0x637f002d, 0x637f002a,
13727 0x627f0030, 0x627f002d, 0x627f002b, 0x627f0029,
13728 0x617f0030, 0x617f002e, 0x617f002b, 0x617f0029,
13729 0x607f002f, 0x607f002d, 0x607f002a, 0x607f0027,
13730 0x607f0026, 0x607f0023, 0x607f0021, 0x607f0020,
13731 0x607f001e, 0x607f001c, 0x607f001a, 0x607f0019,
13732 0x607f0018, 0x607f0016, 0x607f0015, 0x607f0014,
13733 0x607f0012, 0x607f0012, 0x607f0011, 0x607f000f,
13734 0x607f000f, 0x607f000e, 0x607f000d, 0x607f000c,
13735 0x607f000c, 0x607f000b, 0x607f000b, 0x607f000a,
13736 0x607f0009, 0x607f0009, 0x607f0008, 0x607f0008,
13737 0x607f0008, 0x607f0007, 0x607f0007, 0x607f0006,
13738 0x607f0006, 0x607f0005, 0x607f0005, 0x607f0005,
13739 0x607f0005, 0x607f0005, 0x607f0004, 0x607f0004,
13740 0x607f0004, 0x607f0004, 0x607f0003, 0x607f0003,
13741 0x607f0003, 0x607f0003, 0x607f0002, 0x607f0002,
13742 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
13743 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
13744 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
13745 0x607f0002, 0x607f0001, 0x607f0001, 0x607f0001,
13746 0x607f0001, 0x607f0001, 0x607f0001, 0x607f0001
13747};
13748
13749static s8 nphy_papd_pga_gain_delta_ipa_2g[] = {
13750 -114, -108, -98, -91, -84, -78, -70, -62,
13751 -54, -46, -39, -31, -23, -15, -8, 0
13752};
13753
13754static s8 nphy_papd_pga_gain_delta_ipa_5g[] = {
13755 -100, -95, -89, -83, -77, -70, -63, -56,
13756 -48, -41, -33, -25, -19, -12, -6, 0
13757};
13758
13759static s16 nphy_papd_padgain_dlt_2g_2057rev3n4[] = {
13760 -159, -113, -86, -72, -62, -54, -48, -43,
13761 -39, -35, -31, -28, -25, -23, -20, -18,
13762 -17, -15, -13, -11, -10, -8, -7, -6,
13763 -5, -4, -3, -3, -2, -1, -1, 0
13764};
13765
13766static s16 nphy_papd_padgain_dlt_2g_2057rev5[] = {
13767 -109, -109, -82, -68, -58, -50, -44, -39,
13768 -35, -31, -28, -26, -23, -21, -19, -17,
13769 -16, -14, -13, -11, -10, -9, -8, -7,
13770 -5, -5, -4, -3, -2, -1, -1, 0
13771};
13772
13773static s16 nphy_papd_padgain_dlt_2g_2057rev7[] = {
13774 -122, -122, -95, -80, -69, -61, -54, -49,
13775 -43, -39, -35, -32, -28, -26, -23, -21,
13776 -18, -16, -15, -13, -11, -10, -8, -7,
13777 -6, -5, -4, -3, -2, -1, -1, 0
13778};
13779
13780static s8 nphy_papd_pgagain_dlt_5g_2057[] = {
13781 -107, -101, -92, -85, -78, -71, -62, -55,
13782 -47, -39, -32, -24, -19, -12, -6, 0
13783};
13784
13785static s8 nphy_papd_pgagain_dlt_5g_2057rev7[] = {
13786 -110, -104, -95, -88, -81, -74, -66, -58,
13787 -50, -44, -36, -28, -23, -15, -8, 0
13788};
13789
13790static u8 pad_gain_codes_used_2057rev5[] = {
13791 20, 19, 18, 17, 16, 15, 14, 13, 12, 11,
13792 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
13793};
13794
13795static u8 pad_gain_codes_used_2057rev7[] = {
13796 15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
13797 5, 4, 3, 2, 1
13798};
13799
13800static u8 pad_all_gain_codes_2057[] = {
13801 31, 30, 29, 28, 27, 26, 25, 24, 23, 22,
13802 21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
13803 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
13804 1, 0
13805};
13806
13807static u8 pga_all_gain_codes_2057[] = {
13808 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
13809};
13810
13811static u32 nphy_papd_scaltbl[] = {
13812 0x0ae2002f, 0x0a3b0032, 0x09a70035, 0x09220038,
13813 0x0887003c, 0x081f003f, 0x07a20043, 0x07340047,
13814 0x06d2004b, 0x067a004f, 0x06170054, 0x05bf0059,
13815 0x0571005e, 0x051e0064, 0x04d3006a, 0x04910070,
13816 0x044c0077, 0x040f007e, 0x03d90085, 0x03a1008d,
13817 0x036f0095, 0x033d009e, 0x030b00a8, 0x02e000b2,
13818 0x02b900bc, 0x029200c7, 0x026d00d3, 0x024900e0,
13819 0x022900ed, 0x020a00fb, 0x01ec010a, 0x01d0011a,
13820 0x01b7012a, 0x019e013c, 0x0187014f, 0x01720162,
13821 0x015d0177, 0x0149018e, 0x013701a5, 0x012601be,
13822 0x011501d9, 0x010501f5, 0x00f70212, 0x00e90232,
13823 0x00dc0253, 0x00d00276, 0x00c4029c, 0x00b902c3,
13824 0x00af02ed, 0x00a5031a, 0x009c0349, 0x0093037a,
13825 0x008b03af, 0x008303e7, 0x007c0422, 0x00750461,
13826 0x006e04a3, 0x006804ea, 0x00620534, 0x005d0583,
13827 0x005805d7, 0x0053062f, 0x004e068d, 0x004a06f1
13828};
13829
13830static u32 nphy_tpc_txgain_rev3[] = {
13831 0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
13832 0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
13833 0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
13834 0x1e41003c, 0x1e41003b, 0x1e410039, 0x1e410037,
13835 0x1d410044, 0x1d410042, 0x1d410040, 0x1d41003e,
13836 0x1d41003c, 0x1d41003b, 0x1d410039, 0x1d410037,
13837 0x1c410044, 0x1c410042, 0x1c410040, 0x1c41003e,
13838 0x1c41003c, 0x1c41003b, 0x1c410039, 0x1c410037,
13839 0x1b410044, 0x1b410042, 0x1b410040, 0x1b41003e,
13840 0x1b41003c, 0x1b41003b, 0x1b410039, 0x1b410037,
13841 0x1a410044, 0x1a410042, 0x1a410040, 0x1a41003e,
13842 0x1a41003c, 0x1a41003b, 0x1a410039, 0x1a410037,
13843 0x19410044, 0x19410042, 0x19410040, 0x1941003e,
13844 0x1941003c, 0x1941003b, 0x19410039, 0x19410037,
13845 0x18410044, 0x18410042, 0x18410040, 0x1841003e,
13846 0x1841003c, 0x1841003b, 0x18410039, 0x18410037,
13847 0x17410044, 0x17410042, 0x17410040, 0x1741003e,
13848 0x1741003c, 0x1741003b, 0x17410039, 0x17410037,
13849 0x16410044, 0x16410042, 0x16410040, 0x1641003e,
13850 0x1641003c, 0x1641003b, 0x16410039, 0x16410037,
13851 0x15410044, 0x15410042, 0x15410040, 0x1541003e,
13852 0x1541003c, 0x1541003b, 0x15410039, 0x15410037,
13853 0x14410044, 0x14410042, 0x14410040, 0x1441003e,
13854 0x1441003c, 0x1441003b, 0x14410039, 0x14410037,
13855 0x13410044, 0x13410042, 0x13410040, 0x1341003e,
13856 0x1341003c, 0x1341003b, 0x13410039, 0x13410037,
13857 0x12410044, 0x12410042, 0x12410040, 0x1241003e,
13858 0x1241003c, 0x1241003b, 0x12410039, 0x12410037,
13859 0x11410044, 0x11410042, 0x11410040, 0x1141003e,
13860 0x1141003c, 0x1141003b, 0x11410039, 0x11410037,
13861 0x10410044, 0x10410042, 0x10410040, 0x1041003e,
13862 0x1041003c, 0x1041003b, 0x10410039, 0x10410037
13863};
13864
13865static u32 nphy_tpc_txgain_HiPwrEPA[] = {
13866 0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e,
13867 0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037,
13868 0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e,
13869 0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037,
13870 0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e,
13871 0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037,
13872 0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e,
13873 0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037,
13874 0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e,
13875 0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037,
13876 0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e,
13877 0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037,
13878 0x09410044, 0x09410042, 0x09410040, 0x0941003e,
13879 0x0941003c, 0x0941003b, 0x09410039, 0x09410037,
13880 0x08410044, 0x08410042, 0x08410040, 0x0841003e,
13881 0x0841003c, 0x0841003b, 0x08410039, 0x08410037,
13882 0x07410044, 0x07410042, 0x07410040, 0x0741003e,
13883 0x0741003c, 0x0741003b, 0x07410039, 0x07410037,
13884 0x06410044, 0x06410042, 0x06410040, 0x0641003e,
13885 0x0641003c, 0x0641003b, 0x06410039, 0x06410037,
13886 0x05410044, 0x05410042, 0x05410040, 0x0541003e,
13887 0x0541003c, 0x0541003b, 0x05410039, 0x05410037,
13888 0x04410044, 0x04410042, 0x04410040, 0x0441003e,
13889 0x0441003c, 0x0441003b, 0x04410039, 0x04410037,
13890 0x03410044, 0x03410042, 0x03410040, 0x0341003e,
13891 0x0341003c, 0x0341003b, 0x03410039, 0x03410037,
13892 0x02410044, 0x02410042, 0x02410040, 0x0241003e,
13893 0x0241003c, 0x0241003b, 0x02410039, 0x02410037,
13894 0x01410044, 0x01410042, 0x01410040, 0x0141003e,
13895 0x0141003c, 0x0141003b, 0x01410039, 0x01410037,
13896 0x00410044, 0x00410042, 0x00410040, 0x0041003e,
13897 0x0041003c, 0x0041003b, 0x00410039, 0x00410037
13898};
13899
13900static u32 nphy_tpc_txgain_epa_2057rev3[] = {
13901 0x80f90040, 0x80e10040, 0x80e1003c, 0x80c9003d,
13902 0x80b9003c, 0x80a9003d, 0x80a1003c, 0x8099003b,
13903 0x8091003b, 0x8089003a, 0x8081003a, 0x80790039,
13904 0x80710039, 0x8069003a, 0x8061003b, 0x8059003d,
13905 0x8051003f, 0x80490042, 0x8049003e, 0x8049003b,
13906 0x8041003e, 0x8041003b, 0x8039003e, 0x8039003b,
13907 0x80390038, 0x80390035, 0x8031003a, 0x80310036,
13908 0x80310033, 0x8029003a, 0x80290037, 0x80290034,
13909 0x80290031, 0x80210039, 0x80210036, 0x80210033,
13910 0x80210030, 0x8019003c, 0x80190039, 0x80190036,
13911 0x80190033, 0x80190030, 0x8019002d, 0x8019002b,
13912 0x80190028, 0x8011003a, 0x80110036, 0x80110033,
13913 0x80110030, 0x8011002e, 0x8011002b, 0x80110029,
13914 0x80110027, 0x80110024, 0x80110022, 0x80110020,
13915 0x8011001f, 0x8011001d, 0x8009003a, 0x80090037,
13916 0x80090034, 0x80090031, 0x8009002e, 0x8009002c,
13917 0x80090029, 0x80090027, 0x80090025, 0x80090023,
13918 0x80090021, 0x8009001f, 0x8009001d, 0x8009011d,
13919 0x8009021d, 0x8009031d, 0x8009041d, 0x8009051d,
13920 0x8009061d, 0x8009071d, 0x8009071d, 0x8009071d,
13921 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13922 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13923 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13924 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13925 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13926 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13927 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13928 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13929 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13930 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13931 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13932 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d
13933};
13934
13935static u32 nphy_tpc_txgain_epa_2057rev5[] = {
13936 0x10f90040, 0x10e10040, 0x10e1003c, 0x10c9003d,
13937 0x10b9003c, 0x10a9003d, 0x10a1003c, 0x1099003b,
13938 0x1091003b, 0x1089003a, 0x1081003a, 0x10790039,
13939 0x10710039, 0x1069003a, 0x1061003b, 0x1059003d,
13940 0x1051003f, 0x10490042, 0x1049003e, 0x1049003b,
13941 0x1041003e, 0x1041003b, 0x1039003e, 0x1039003b,
13942 0x10390038, 0x10390035, 0x1031003a, 0x10310036,
13943 0x10310033, 0x1029003a, 0x10290037, 0x10290034,
13944 0x10290031, 0x10210039, 0x10210036, 0x10210033,
13945 0x10210030, 0x1019003c, 0x10190039, 0x10190036,
13946 0x10190033, 0x10190030, 0x1019002d, 0x1019002b,
13947 0x10190028, 0x1011003a, 0x10110036, 0x10110033,
13948 0x10110030, 0x1011002e, 0x1011002b, 0x10110029,
13949 0x10110027, 0x10110024, 0x10110022, 0x10110020,
13950 0x1011001f, 0x1011001d, 0x1009003a, 0x10090037,
13951 0x10090034, 0x10090031, 0x1009002e, 0x1009002c,
13952 0x10090029, 0x10090027, 0x10090025, 0x10090023,
13953 0x10090021, 0x1009001f, 0x1009001d, 0x1009001b,
13954 0x1009001a, 0x10090018, 0x10090017, 0x10090016,
13955 0x10090015, 0x10090013, 0x10090012, 0x10090011,
13956 0x10090010, 0x1009000f, 0x1009000f, 0x1009000e,
13957 0x1009000d, 0x1009000c, 0x1009000c, 0x1009000b,
13958 0x1009000a, 0x1009000a, 0x10090009, 0x10090009,
13959 0x10090008, 0x10090008, 0x10090007, 0x10090007,
13960 0x10090007, 0x10090006, 0x10090006, 0x10090005,
13961 0x10090005, 0x10090005, 0x10090005, 0x10090004,
13962 0x10090004, 0x10090004, 0x10090004, 0x10090003,
13963 0x10090003, 0x10090003, 0x10090003, 0x10090003,
13964 0x10090003, 0x10090002, 0x10090002, 0x10090002,
13965 0x10090002, 0x10090002, 0x10090002, 0x10090002,
13966 0x10090002, 0x10090002, 0x10090001, 0x10090001,
13967 0x10090001, 0x10090001, 0x10090001, 0x10090001
13968};
13969
13970static u32 nphy_tpc_5GHz_txgain_rev3[] = {
13971 0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
13972 0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
13973 0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
13974 0xcef7003c, 0xcef7003b, 0xcef70039, 0xcef70037,
13975 0xcdf70044, 0xcdf70042, 0xcdf70040, 0xcdf7003e,
13976 0xcdf7003c, 0xcdf7003b, 0xcdf70039, 0xcdf70037,
13977 0xccf70044, 0xccf70042, 0xccf70040, 0xccf7003e,
13978 0xccf7003c, 0xccf7003b, 0xccf70039, 0xccf70037,
13979 0xcbf70044, 0xcbf70042, 0xcbf70040, 0xcbf7003e,
13980 0xcbf7003c, 0xcbf7003b, 0xcbf70039, 0xcbf70037,
13981 0xcaf70044, 0xcaf70042, 0xcaf70040, 0xcaf7003e,
13982 0xcaf7003c, 0xcaf7003b, 0xcaf70039, 0xcaf70037,
13983 0xc9f70044, 0xc9f70042, 0xc9f70040, 0xc9f7003e,
13984 0xc9f7003c, 0xc9f7003b, 0xc9f70039, 0xc9f70037,
13985 0xc8f70044, 0xc8f70042, 0xc8f70040, 0xc8f7003e,
13986 0xc8f7003c, 0xc8f7003b, 0xc8f70039, 0xc8f70037,
13987 0xc7f70044, 0xc7f70042, 0xc7f70040, 0xc7f7003e,
13988 0xc7f7003c, 0xc7f7003b, 0xc7f70039, 0xc7f70037,
13989 0xc6f70044, 0xc6f70042, 0xc6f70040, 0xc6f7003e,
13990 0xc6f7003c, 0xc6f7003b, 0xc6f70039, 0xc6f70037,
13991 0xc5f70044, 0xc5f70042, 0xc5f70040, 0xc5f7003e,
13992 0xc5f7003c, 0xc5f7003b, 0xc5f70039, 0xc5f70037,
13993 0xc4f70044, 0xc4f70042, 0xc4f70040, 0xc4f7003e,
13994 0xc4f7003c, 0xc4f7003b, 0xc4f70039, 0xc4f70037,
13995 0xc3f70044, 0xc3f70042, 0xc3f70040, 0xc3f7003e,
13996 0xc3f7003c, 0xc3f7003b, 0xc3f70039, 0xc3f70037,
13997 0xc2f70044, 0xc2f70042, 0xc2f70040, 0xc2f7003e,
13998 0xc2f7003c, 0xc2f7003b, 0xc2f70039, 0xc2f70037,
13999 0xc1f70044, 0xc1f70042, 0xc1f70040, 0xc1f7003e,
14000 0xc1f7003c, 0xc1f7003b, 0xc1f70039, 0xc1f70037,
14001 0xc0f70044, 0xc0f70042, 0xc0f70040, 0xc0f7003e,
14002 0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037
14003};
14004
14005static u32 nphy_tpc_5GHz_txgain_rev4[] = {
14006 0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
14007 0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
14008 0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
14009 0x2ef2003c, 0x2ef2003b, 0x2ef20039, 0x2ef20037,
14010 0x2df20044, 0x2df20042, 0x2df20040, 0x2df2003e,
14011 0x2df2003c, 0x2df2003b, 0x2df20039, 0x2df20037,
14012 0x2cf20044, 0x2cf20042, 0x2cf20040, 0x2cf2003e,
14013 0x2cf2003c, 0x2cf2003b, 0x2cf20039, 0x2cf20037,
14014 0x2bf20044, 0x2bf20042, 0x2bf20040, 0x2bf2003e,
14015 0x2bf2003c, 0x2bf2003b, 0x2bf20039, 0x2bf20037,
14016 0x2af20044, 0x2af20042, 0x2af20040, 0x2af2003e,
14017 0x2af2003c, 0x2af2003b, 0x2af20039, 0x2af20037,
14018 0x29f20044, 0x29f20042, 0x29f20040, 0x29f2003e,
14019 0x29f2003c, 0x29f2003b, 0x29f20039, 0x29f20037,
14020 0x28f20044, 0x28f20042, 0x28f20040, 0x28f2003e,
14021 0x28f2003c, 0x28f2003b, 0x28f20039, 0x28f20037,
14022 0x27f20044, 0x27f20042, 0x27f20040, 0x27f2003e,
14023 0x27f2003c, 0x27f2003b, 0x27f20039, 0x27f20037,
14024 0x26f20044, 0x26f20042, 0x26f20040, 0x26f2003e,
14025 0x26f2003c, 0x26f2003b, 0x26f20039, 0x26f20037,
14026 0x25f20044, 0x25f20042, 0x25f20040, 0x25f2003e,
14027 0x25f2003c, 0x25f2003b, 0x25f20039, 0x25f20037,
14028 0x24f20044, 0x24f20042, 0x24f20040, 0x24f2003e,
14029 0x24f2003c, 0x24f2003b, 0x24f20039, 0x24f20038,
14030 0x23f20041, 0x23f20040, 0x23f2003f, 0x23f2003e,
14031 0x23f2003c, 0x23f2003b, 0x23f20039, 0x23f20037,
14032 0x22f20044, 0x22f20042, 0x22f20040, 0x22f2003e,
14033 0x22f2003c, 0x22f2003b, 0x22f20039, 0x22f20037,
14034 0x21f20044, 0x21f20042, 0x21f20040, 0x21f2003e,
14035 0x21f2003c, 0x21f2003b, 0x21f20039, 0x21f20037,
14036 0x20d20043, 0x20d20041, 0x20d2003e, 0x20d2003c,
14037 0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034
14038};
14039
14040static u32 nphy_tpc_5GHz_txgain_rev5[] = {
14041 0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
14042 0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
14043 0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
14044 0x0e62003c, 0x0e62003d, 0x0e62003b, 0x0e62003a,
14045 0x0d620043, 0x0d620041, 0x0d620040, 0x0d62003e,
14046 0x0d62003d, 0x0d62003c, 0x0d62003b, 0x0d62003a,
14047 0x0c620041, 0x0c620040, 0x0c62003f, 0x0c62003e,
14048 0x0c62003c, 0x0c62003b, 0x0c620039, 0x0c620037,
14049 0x0b620046, 0x0b620044, 0x0b620042, 0x0b620040,
14050 0x0b62003e, 0x0b62003c, 0x0b62003b, 0x0b62003a,
14051 0x0a620041, 0x0a620040, 0x0a62003e, 0x0a62003c,
14052 0x0a62003b, 0x0a62003a, 0x0a620039, 0x0a620038,
14053 0x0962003e, 0x0962003d, 0x0962003c, 0x0962003b,
14054 0x09620039, 0x09620037, 0x09620035, 0x09620033,
14055 0x08620044, 0x08620042, 0x08620040, 0x0862003e,
14056 0x0862003c, 0x0862003b, 0x0862003a, 0x08620039,
14057 0x07620043, 0x07620042, 0x07620040, 0x0762003f,
14058 0x0762003d, 0x0762003b, 0x0762003a, 0x07620039,
14059 0x0662003e, 0x0662003d, 0x0662003c, 0x0662003b,
14060 0x06620039, 0x06620037, 0x06620035, 0x06620033,
14061 0x05620046, 0x05620044, 0x05620042, 0x05620040,
14062 0x0562003e, 0x0562003c, 0x0562003b, 0x05620039,
14063 0x04620044, 0x04620042, 0x04620040, 0x0462003e,
14064 0x0462003c, 0x0462003b, 0x04620039, 0x04620038,
14065 0x0362003c, 0x0362003b, 0x0362003a, 0x03620039,
14066 0x03620038, 0x03620037, 0x03620035, 0x03620033,
14067 0x0262004c, 0x0262004a, 0x02620048, 0x02620047,
14068 0x02620046, 0x02620044, 0x02620043, 0x02620042,
14069 0x0162004a, 0x01620048, 0x01620046, 0x01620044,
14070 0x01620043, 0x01620042, 0x01620041, 0x01620040,
14071 0x00620042, 0x00620040, 0x0062003e, 0x0062003c,
14072 0x0062003b, 0x00620039, 0x00620037, 0x00620035
14073};
14074
14075static u32 nphy_tpc_5GHz_txgain_HiPwrEPA[] = {
14076 0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e,
14077 0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037,
14078 0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e,
14079 0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037,
14080 0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e,
14081 0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037,
14082 0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e,
14083 0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037,
14084 0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e,
14085 0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037,
14086 0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e,
14087 0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037,
14088 0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e,
14089 0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037,
14090 0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e,
14091 0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037,
14092 0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e,
14093 0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037,
14094 0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e,
14095 0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037,
14096 0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e,
14097 0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037,
14098 0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e,
14099 0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038,
14100 0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e,
14101 0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037,
14102 0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e,
14103 0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037,
14104 0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e,
14105 0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037,
14106 0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c,
14107 0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034
14108};
14109
14110static u8 ant_sw_ctrl_tbl_rev8_2o3[] = { 0x14, 0x18 };
14111static u8 ant_sw_ctrl_tbl_rev8[] = { 0x4, 0x8, 0x4, 0x8, 0x11, 0x12 };
14112static u8 ant_sw_ctrl_tbl_rev8_2057v7_core0[] = {
14113 0x09, 0x0a, 0x15, 0x16, 0x09, 0x0a
14114};
14115static u8 ant_sw_ctrl_tbl_rev8_2057v7_core1[] = {
14116 0x09, 0x0a, 0x09, 0x0a, 0x15, 0x16
14117};
14118
14119bool wlc_phy_bist_check_phy(struct brcms_phy_pub *pih)
14120{
14121 struct brcms_phy *pi = (struct brcms_phy *) pih;
14122 u32 phybist0, phybist1, phybist2, phybist3, phybist4;
14123
14124 if (NREV_GE(pi->pubpi.phy_rev, 16))
14125 return true;
14126
14127 phybist0 = read_phy_reg(pi, 0x0e);
14128 phybist1 = read_phy_reg(pi, 0x0f);
14129 phybist2 = read_phy_reg(pi, 0xea);
14130 phybist3 = read_phy_reg(pi, 0xeb);
14131 phybist4 = read_phy_reg(pi, 0x156);
14132
14133 if ((phybist0 == 0) && (phybist1 == 0x4000) && (phybist2 == 0x1fe0) &&
14134 (phybist3 == 0) && (phybist4 == 0))
14135 return true;
14136
14137 return false;
14138}
14139
14140static void wlc_phy_bphy_init_nphy(struct brcms_phy *pi)
14141{
14142 u16 addr, val;
14143
14144 val = 0x1e1f;
14145 for (addr = (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT);
14146 addr <= (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT_END); addr++) {
14147 write_phy_reg(pi, addr, val);
14148 if (addr == (NPHY_TO_BPHY_OFF + 0x97))
14149 val = 0x3e3f;
14150 else
14151 val -= 0x0202;
14152 }
14153
14154 write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_STEP, 0x668);
14155}
14156
14157void
14158wlc_phy_table_write_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
14159 u32 width, const void *data)
14160{
14161 struct phytbl_info tbl;
14162
14163 tbl.tbl_id = id;
14164 tbl.tbl_len = len;
14165 tbl.tbl_offset = offset;
14166 tbl.tbl_width = width;
14167 tbl.tbl_ptr = data;
14168 wlc_phy_write_table_nphy(pi, &tbl);
14169}
14170
14171void
14172wlc_phy_table_read_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
14173 u32 width, void *data)
14174{
14175 struct phytbl_info tbl;
14176
14177 tbl.tbl_id = id;
14178 tbl.tbl_len = len;
14179 tbl.tbl_offset = offset;
14180 tbl.tbl_width = width;
14181 tbl.tbl_ptr = data;
14182 wlc_phy_read_table_nphy(pi, &tbl);
14183}
14184
14185static void
14186wlc_phy_static_table_download_nphy(struct brcms_phy *pi)
14187{
14188 uint idx;
14189
14190 if (NREV_GE(pi->pubpi.phy_rev, 16)) {
14191 for (idx = 0; idx < mimophytbl_info_sz_rev16; idx++)
14192 wlc_phy_write_table_nphy(pi,
14193 &mimophytbl_info_rev16[idx]);
14194 } else if (NREV_GE(pi->pubpi.phy_rev, 7)) {
14195 for (idx = 0; idx < mimophytbl_info_sz_rev7; idx++)
14196 wlc_phy_write_table_nphy(pi,
14197 &mimophytbl_info_rev7[idx]);
14198 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
14199 for (idx = 0; idx < mimophytbl_info_sz_rev3; idx++)
14200 wlc_phy_write_table_nphy(pi,
14201 &mimophytbl_info_rev3[idx]);
14202 } else {
14203 for (idx = 0; idx < mimophytbl_info_sz_rev0; idx++)
14204 wlc_phy_write_table_nphy(pi,
14205 &mimophytbl_info_rev0[idx]);
14206 }
14207}
14208
14209static void wlc_phy_tbl_init_nphy(struct brcms_phy *pi)
14210{
14211 uint idx = 0;
14212 u8 antswctrllut;
14213
14214 if (pi->phy_init_por)
14215 wlc_phy_static_table_download_nphy(pi);
14216
14217 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
14218
14219 antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ?
14220 pi->srom_fem2g.antswctrllut : pi->srom_fem5g.
14221 antswctrllut;
14222
14223 switch (antswctrllut) {
14224 case 0:
14225
14226 break;
14227
14228 case 1:
14229
14230 if (pi->aa2g == 7)
14231 wlc_phy_table_write_nphy(
14232 pi,
14233 NPHY_TBL_ID_ANTSWCTRLLUT,
14234 2, 0x21, 8,
14235 &ant_sw_ctrl_tbl_rev8_2o3[0]);
14236 else
14237 wlc_phy_table_write_nphy(
14238 pi,
14239 NPHY_TBL_ID_ANTSWCTRLLUT,
14240 2, 0x21, 8,
14241 &ant_sw_ctrl_tbl_rev8
14242 [0]);
14243
14244 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14245 2, 0x25, 8,
14246 &ant_sw_ctrl_tbl_rev8[2]);
14247 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14248 2, 0x29, 8,
14249 &ant_sw_ctrl_tbl_rev8[4]);
14250 break;
14251
14252 case 2:
14253
14254 wlc_phy_table_write_nphy(
14255 pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14256 2, 0x1, 8,
14257 &ant_sw_ctrl_tbl_rev8_2057v7_core0[0]);
14258 wlc_phy_table_write_nphy(
14259 pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14260 2, 0x5, 8,
14261 &ant_sw_ctrl_tbl_rev8_2057v7_core0[2]);
14262 wlc_phy_table_write_nphy(
14263 pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14264 2, 0x9, 8,
14265 &ant_sw_ctrl_tbl_rev8_2057v7_core0[4]);
14266
14267 wlc_phy_table_write_nphy(
14268 pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14269 2, 0x21, 8,
14270 &ant_sw_ctrl_tbl_rev8_2057v7_core1[0]);
14271 wlc_phy_table_write_nphy(
14272 pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14273 2, 0x25, 8,
14274 &ant_sw_ctrl_tbl_rev8_2057v7_core1[2]);
14275 wlc_phy_table_write_nphy(
14276 pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14277 2, 0x29, 8,
14278 &ant_sw_ctrl_tbl_rev8_2057v7_core1[4]);
14279 break;
14280
14281 default:
14282 break;
14283 }
14284
14285 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
14286 for (idx = 0; idx < mimophytbl_info_sz_rev3_volatile; idx++) {
14287
14288 if (idx == ANT_SWCTRL_TBL_REV3_IDX) {
14289 antswctrllut =
14290 CHSPEC_IS2G(pi->radio_chanspec) ?
14291 pi->srom_fem2g.antswctrllut :
14292 pi->srom_fem5g.antswctrllut;
14293 switch (antswctrllut) {
14294 case 0:
14295 wlc_phy_write_table_nphy(
14296 pi,
14297 &mimophytbl_info_rev3_volatile
14298 [idx]);
14299 break;
14300 case 1:
14301 wlc_phy_write_table_nphy(
14302 pi,
14303 &mimophytbl_info_rev3_volatile1
14304 [idx]);
14305 break;
14306 case 2:
14307 wlc_phy_write_table_nphy(
14308 pi,
14309 &mimophytbl_info_rev3_volatile2
14310 [idx]);
14311 break;
14312 case 3:
14313 wlc_phy_write_table_nphy(
14314 pi,
14315 &mimophytbl_info_rev3_volatile3
14316 [idx]);
14317 break;
14318 default:
14319 break;
14320 }
14321 } else {
14322 wlc_phy_write_table_nphy(
14323 pi,
14324 &mimophytbl_info_rev3_volatile[idx]);
14325 }
14326 }
14327 } else {
14328 for (idx = 0; idx < mimophytbl_info_sz_rev0_volatile; idx++)
14329 wlc_phy_write_table_nphy(pi,
14330 &mimophytbl_info_rev0_volatile
14331 [idx]);
14332 }
14333}
14334
14335static void
14336wlc_phy_write_txmacreg_nphy(struct brcms_phy *pi, u16 holdoff, u16 delay)
14337{
14338 write_phy_reg(pi, 0x77, holdoff);
14339 write_phy_reg(pi, 0xb4, delay);
14340}
14341
14342void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs)
14343{
14344 u16 holdoff, delay;
14345
14346 if (rifs) {
14347
14348 holdoff = 0x10;
14349 delay = 0x258;
14350 } else {
14351
14352 holdoff = 0x15;
14353 delay = 0x320;
14354 }
14355
14356 wlc_phy_write_txmacreg_nphy(pi, holdoff, delay);
14357
14358 if (pi && pi->sh && (pi->sh->_rifs_phy != rifs))
14359 pi->sh->_rifs_phy = rifs;
14360}
14361
14362static void wlc_phy_txpwrctrl_config_nphy(struct brcms_phy *pi)
14363{
14364
14365 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
14366 pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
14367 pi->phy_5g_pwrgain = true;
14368 return;
14369 }
14370
14371 pi->nphy_txpwrctrl = PHY_TPC_HW_OFF;
14372 pi->phy_5g_pwrgain = false;
14373
14374 if ((pi->sh->boardflags2 & BFL2_TXPWRCTRL_EN) &&
14375 NREV_GE(pi->pubpi.phy_rev, 2) && (pi->sh->sromrev >= 4))
14376 pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
14377 else if ((pi->sh->sromrev >= 4)
14378 && (pi->sh->boardflags2 & BFL2_5G_PWRGAIN))
14379 pi->phy_5g_pwrgain = true;
14380}
14381
14382static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi)
14383{
14384 u16 bw40po, cddpo, stbcpo, bwduppo;
14385 uint band_num;
14386 struct phy_shim_info *shim = pi->sh->physhim;
14387
14388 if (pi->sh->sromrev >= 9)
14389 return;
14390
14391 bw40po = (u16) wlapi_getintvar(shim, BRCMS_SROM_BW40PO);
14392 pi->bw402gpo = bw40po & 0xf;
14393 pi->bw405gpo = (bw40po & 0xf0) >> 4;
14394 pi->bw405glpo = (bw40po & 0xf00) >> 8;
14395 pi->bw405ghpo = (bw40po & 0xf000) >> 12;
14396
14397 cddpo = (u16) wlapi_getintvar(shim, BRCMS_SROM_CDDPO);
14398 pi->cdd2gpo = cddpo & 0xf;
14399 pi->cdd5gpo = (cddpo & 0xf0) >> 4;
14400 pi->cdd5glpo = (cddpo & 0xf00) >> 8;
14401 pi->cdd5ghpo = (cddpo & 0xf000) >> 12;
14402
14403 stbcpo = (u16) wlapi_getintvar(shim, BRCMS_SROM_STBCPO);
14404 pi->stbc2gpo = stbcpo & 0xf;
14405 pi->stbc5gpo = (stbcpo & 0xf0) >> 4;
14406 pi->stbc5glpo = (stbcpo & 0xf00) >> 8;
14407 pi->stbc5ghpo = (stbcpo & 0xf000) >> 12;
14408
14409 bwduppo = (u16) wlapi_getintvar(shim, BRCMS_SROM_BWDUPPO);
14410 pi->bwdup2gpo = bwduppo & 0xf;
14411 pi->bwdup5gpo = (bwduppo & 0xf0) >> 4;
14412 pi->bwdup5glpo = (bwduppo & 0xf00) >> 8;
14413 pi->bwdup5ghpo = (bwduppo & 0xf000) >> 12;
14414
14415 for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP);
14416 band_num++) {
14417 switch (band_num) {
14418 case 0:
14419
14420 pi->nphy_txpid2g[PHY_CORE_0] =
14421 (u8) wlapi_getintvar(shim,
14422 BRCMS_SROM_TXPID2GA0);
14423 pi->nphy_txpid2g[PHY_CORE_1] =
14424 (u8) wlapi_getintvar(shim,
14425 BRCMS_SROM_TXPID2GA1);
14426 pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g =
14427 (s8) wlapi_getintvar(shim,
14428 BRCMS_SROM_MAXP2GA0);
14429 pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g =
14430 (s8) wlapi_getintvar(shim,
14431 BRCMS_SROM_MAXP2GA1);
14432 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 =
14433 (s16) wlapi_getintvar(shim,
14434 BRCMS_SROM_PA2GW0A0);
14435 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 =
14436 (s16) wlapi_getintvar(shim,
14437 BRCMS_SROM_PA2GW0A1);
14438 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 =
14439 (s16) wlapi_getintvar(shim,
14440 BRCMS_SROM_PA2GW1A0);
14441 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 =
14442 (s16) wlapi_getintvar(shim,
14443 BRCMS_SROM_PA2GW1A1);
14444 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 =
14445 (s16) wlapi_getintvar(shim,
14446 BRCMS_SROM_PA2GW2A0);
14447 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 =
14448 (s16) wlapi_getintvar(shim,
14449 BRCMS_SROM_PA2GW2A1);
14450 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g =
14451 (s8) wlapi_getintvar(shim, BRCMS_SROM_ITT2GA0);
14452 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g =
14453 (s8) wlapi_getintvar(shim, BRCMS_SROM_ITT2GA1);
14454
14455 pi->cck2gpo = (u16) wlapi_getintvar(shim,
14456 BRCMS_SROM_CCK2GPO);
14457
14458 pi->ofdm2gpo =
14459 (u32) wlapi_getintvar(shim,
14460 BRCMS_SROM_OFDM2GPO);
14461
14462 pi->mcs2gpo[0] =
14463 (u16) wlapi_getintvar(shim,
14464 BRCMS_SROM_MCS2GPO0);
14465 pi->mcs2gpo[1] =
14466 (u16) wlapi_getintvar(shim,
14467 BRCMS_SROM_MCS2GPO1);
14468 pi->mcs2gpo[2] =
14469 (u16) wlapi_getintvar(shim,
14470 BRCMS_SROM_MCS2GPO2);
14471 pi->mcs2gpo[3] =
14472 (u16) wlapi_getintvar(shim,
14473 BRCMS_SROM_MCS2GPO3);
14474 pi->mcs2gpo[4] =
14475 (u16) wlapi_getintvar(shim,
14476 BRCMS_SROM_MCS2GPO4);
14477 pi->mcs2gpo[5] =
14478 (u16) wlapi_getintvar(shim,
14479 BRCMS_SROM_MCS2GPO5);
14480 pi->mcs2gpo[6] =
14481 (u16) wlapi_getintvar(shim,
14482 BRCMS_SROM_MCS2GPO6);
14483 pi->mcs2gpo[7] =
14484 (u16) wlapi_getintvar(shim,
14485 BRCMS_SROM_MCS2GPO7);
14486 break;
14487 case 1:
14488
14489 pi->nphy_txpid5g[PHY_CORE_0] =
14490 (u8) wlapi_getintvar(shim,
14491 BRCMS_SROM_TXPID5GA0);
14492 pi->nphy_txpid5g[PHY_CORE_1] =
14493 (u8) wlapi_getintvar(shim,
14494 BRCMS_SROM_TXPID5GA1);
14495 pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm =
14496 (s8) wlapi_getintvar(shim, BRCMS_SROM_MAXP5GA0);
14497 pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm =
14498 (s8) wlapi_getintvar(shim,
14499 BRCMS_SROM_MAXP5GA1);
14500 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 =
14501 (s16) wlapi_getintvar(shim,
14502 BRCMS_SROM_PA5GW0A0);
14503 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 =
14504 (s16) wlapi_getintvar(shim,
14505 BRCMS_SROM_PA5GW0A1);
14506 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 =
14507 (s16) wlapi_getintvar(shim,
14508 BRCMS_SROM_PA5GW1A0);
14509 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 =
14510 (s16) wlapi_getintvar(shim,
14511 BRCMS_SROM_PA5GW1A1);
14512 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 =
14513 (s16) wlapi_getintvar(shim,
14514 BRCMS_SROM_PA5GW2A0);
14515 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 =
14516 (s16) wlapi_getintvar(shim,
14517 BRCMS_SROM_PA5GW2A1);
14518 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm =
14519 (s8) wlapi_getintvar(shim, BRCMS_SROM_ITT5GA0);
14520 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm =
14521 (s8) wlapi_getintvar(shim, BRCMS_SROM_ITT5GA1);
14522
14523 pi->ofdm5gpo =
14524 (u32) wlapi_getintvar(shim,
14525 BRCMS_SROM_OFDM5GPO);
14526
14527 pi->mcs5gpo[0] =
14528 (u16) wlapi_getintvar(shim,
14529 BRCMS_SROM_MCS5GPO0);
14530 pi->mcs5gpo[1] =
14531 (u16) wlapi_getintvar(shim,
14532 BRCMS_SROM_MCS5GPO1);
14533 pi->mcs5gpo[2] =
14534 (u16) wlapi_getintvar(shim,
14535 BRCMS_SROM_MCS5GPO2);
14536 pi->mcs5gpo[3] =
14537 (u16) wlapi_getintvar(shim,
14538 BRCMS_SROM_MCS5GPO3);
14539 pi->mcs5gpo[4] =
14540 (u16) wlapi_getintvar(shim,
14541 BRCMS_SROM_MCS5GPO4);
14542 pi->mcs5gpo[5] =
14543 (u16) wlapi_getintvar(shim,
14544 BRCMS_SROM_MCS5GPO5);
14545 pi->mcs5gpo[6] =
14546 (u16) wlapi_getintvar(shim,
14547 BRCMS_SROM_MCS5GPO6);
14548 pi->mcs5gpo[7] =
14549 (u16) wlapi_getintvar(shim,
14550 BRCMS_SROM_MCS5GPO7);
14551 break;
14552 case 2:
14553
14554 pi->nphy_txpid5gl[0] =
14555 (u8) wlapi_getintvar(shim,
14556 BRCMS_SROM_TXPID5GLA0);
14557 pi->nphy_txpid5gl[1] =
14558 (u8) wlapi_getintvar(shim,
14559 BRCMS_SROM_TXPID5GLA1);
14560 pi->nphy_pwrctrl_info[0].max_pwr_5gl =
14561 (s8) wlapi_getintvar(shim,
14562 BRCMS_SROM_MAXP5GLA0);
14563 pi->nphy_pwrctrl_info[1].max_pwr_5gl =
14564 (s8) wlapi_getintvar(shim,
14565 BRCMS_SROM_MAXP5GLA1);
14566 pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 =
14567 (s16) wlapi_getintvar(shim,
14568 BRCMS_SROM_PA5GLW0A0);
14569 pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 =
14570 (s16) wlapi_getintvar(shim,
14571 BRCMS_SROM_PA5GLW0A1);
14572 pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 =
14573 (s16) wlapi_getintvar(shim,
14574 BRCMS_SROM_PA5GLW1A0);
14575 pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 =
14576 (s16) wlapi_getintvar(shim,
14577 BRCMS_SROM_PA5GLW1A1);
14578 pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 =
14579 (s16) wlapi_getintvar(shim,
14580 BRCMS_SROM_PA5GLW2A0);
14581 pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 =
14582 (s16) wlapi_getintvar(shim,
14583 BRCMS_SROM_PA5GLW2A1);
14584 pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0;
14585 pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0;
14586
14587 pi->ofdm5glpo =
14588 (u32) wlapi_getintvar(shim,
14589 BRCMS_SROM_OFDM5GLPO);
14590
14591 pi->mcs5glpo[0] =
14592 (u16) wlapi_getintvar(shim,
14593 BRCMS_SROM_MCS5GLPO0);
14594 pi->mcs5glpo[1] =
14595 (u16) wlapi_getintvar(shim,
14596 BRCMS_SROM_MCS5GLPO1);
14597 pi->mcs5glpo[2] =
14598 (u16) wlapi_getintvar(shim,
14599 BRCMS_SROM_MCS5GLPO2);
14600 pi->mcs5glpo[3] =
14601 (u16) wlapi_getintvar(shim,
14602 BRCMS_SROM_MCS5GLPO3);
14603 pi->mcs5glpo[4] =
14604 (u16) wlapi_getintvar(shim,
14605 BRCMS_SROM_MCS5GLPO4);
14606 pi->mcs5glpo[5] =
14607 (u16) wlapi_getintvar(shim,
14608 BRCMS_SROM_MCS5GLPO5);
14609 pi->mcs5glpo[6] =
14610 (u16) wlapi_getintvar(shim,
14611 BRCMS_SROM_MCS5GLPO6);
14612 pi->mcs5glpo[7] =
14613 (u16) wlapi_getintvar(shim,
14614 BRCMS_SROM_MCS5GLPO7);
14615 break;
14616 case 3:
14617
14618 pi->nphy_txpid5gh[0] =
14619 (u8) wlapi_getintvar(shim,
14620 BRCMS_SROM_TXPID5GHA0);
14621 pi->nphy_txpid5gh[1] =
14622 (u8) wlapi_getintvar(shim,
14623 BRCMS_SROM_TXPID5GHA1);
14624 pi->nphy_pwrctrl_info[0].max_pwr_5gh =
14625 (s8) wlapi_getintvar(shim,
14626 BRCMS_SROM_MAXP5GHA0);
14627 pi->nphy_pwrctrl_info[1].max_pwr_5gh =
14628 (s8) wlapi_getintvar(shim,
14629 BRCMS_SROM_MAXP5GHA1);
14630 pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 =
14631 (s16) wlapi_getintvar(shim,
14632 BRCMS_SROM_PA5GHW0A0);
14633 pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 =
14634 (s16) wlapi_getintvar(shim,
14635 BRCMS_SROM_PA5GHW0A1);
14636 pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 =
14637 (s16) wlapi_getintvar(shim,
14638 BRCMS_SROM_PA5GHW1A0);
14639 pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 =
14640 (s16) wlapi_getintvar(shim,
14641 BRCMS_SROM_PA5GHW1A1);
14642 pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 =
14643 (s16) wlapi_getintvar(shim,
14644 BRCMS_SROM_PA5GHW2A0);
14645 pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 =
14646 (s16) wlapi_getintvar(shim,
14647 BRCMS_SROM_PA5GHW2A1);
14648 pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0;
14649 pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0;
14650
14651 pi->ofdm5ghpo =
14652 (u32) wlapi_getintvar(shim,
14653 BRCMS_SROM_OFDM5GHPO);
14654
14655 pi->mcs5ghpo[0] =
14656 (u16) wlapi_getintvar(shim,
14657 BRCMS_SROM_MCS5GHPO0);
14658 pi->mcs5ghpo[1] =
14659 (u16) wlapi_getintvar(shim,
14660 BRCMS_SROM_MCS5GHPO1);
14661 pi->mcs5ghpo[2] =
14662 (u16) wlapi_getintvar(shim,
14663 BRCMS_SROM_MCS5GHPO2);
14664 pi->mcs5ghpo[3] =
14665 (u16) wlapi_getintvar(shim,
14666 BRCMS_SROM_MCS5GHPO3);
14667 pi->mcs5ghpo[4] =
14668 (u16) wlapi_getintvar(shim,
14669 BRCMS_SROM_MCS5GHPO4);
14670 pi->mcs5ghpo[5] =
14671 (u16) wlapi_getintvar(shim,
14672 BRCMS_SROM_MCS5GHPO5);
14673 pi->mcs5ghpo[6] =
14674 (u16) wlapi_getintvar(shim,
14675 BRCMS_SROM_MCS5GHPO6);
14676 pi->mcs5ghpo[7] =
14677 (u16) wlapi_getintvar(shim,
14678 BRCMS_SROM_MCS5GHPO7);
14679 break;
14680 }
14681 }
14682
14683 wlc_phy_txpwr_apply_nphy(pi);
14684}
14685
14686static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi)
14687{
14688 struct phy_shim_info *shim = pi->sh->physhim;
14689
14690 pi->antswitch = (u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWITCH);
14691 pi->aa2g = (u8) wlapi_getintvar(shim, BRCMS_SROM_AA2G);
14692 pi->aa5g = (u8) wlapi_getintvar(shim, BRCMS_SROM_AA5G);
14693
14694 pi->srom_fem2g.tssipos = (u8) wlapi_getintvar(shim,
14695 BRCMS_SROM_TSSIPOS2G);
14696 pi->srom_fem2g.extpagain = (u8) wlapi_getintvar(shim,
14697 BRCMS_SROM_EXTPAGAIN2G);
14698 pi->srom_fem2g.pdetrange = (u8) wlapi_getintvar(shim,
14699 BRCMS_SROM_PDETRANGE2G);
14700 pi->srom_fem2g.triso = (u8) wlapi_getintvar(shim, BRCMS_SROM_TRISO2G);
14701 pi->srom_fem2g.antswctrllut =
14702 (u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWCTL2G);
14703
14704 pi->srom_fem5g.tssipos = (u8) wlapi_getintvar(shim,
14705 BRCMS_SROM_TSSIPOS5G);
14706 pi->srom_fem5g.extpagain = (u8) wlapi_getintvar(shim,
14707 BRCMS_SROM_EXTPAGAIN5G);
14708 pi->srom_fem5g.pdetrange = (u8) wlapi_getintvar(shim,
14709 BRCMS_SROM_PDETRANGE5G);
14710 pi->srom_fem5g.triso = (u8) wlapi_getintvar(shim, BRCMS_SROM_TRISO5G);
14711 if (wlapi_getvar(shim, BRCMS_SROM_ANTSWCTL5G))
14712 pi->srom_fem5g.antswctrllut =
14713 (u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWCTL5G);
14714 else
14715 pi->srom_fem5g.antswctrllut =
14716 (u8) wlapi_getintvar(shim, BRCMS_SROM_ANTSWCTL2G);
14717
14718 wlc_phy_txpower_ipa_upd(pi);
14719
14720 pi->phy_txcore_disable_temp =
14721 (s16) wlapi_getintvar(shim, BRCMS_SROM_TEMPTHRESH);
14722 if (pi->phy_txcore_disable_temp == 0)
14723 pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
14724
14725 pi->phy_tempsense_offset = (s8) wlapi_getintvar(shim,
14726 BRCMS_SROM_TEMPOFFSET);
14727 if (pi->phy_tempsense_offset != 0) {
14728 if (pi->phy_tempsense_offset >
14729 (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET))
14730 pi->phy_tempsense_offset = NPHY_SROM_MAXTEMPOFFSET;
14731 else if (pi->phy_tempsense_offset < (NPHY_SROM_TEMPSHIFT +
14732 NPHY_SROM_MINTEMPOFFSET))
14733 pi->phy_tempsense_offset = NPHY_SROM_MINTEMPOFFSET;
14734 else
14735 pi->phy_tempsense_offset -= NPHY_SROM_TEMPSHIFT;
14736 }
14737
14738 pi->phy_txcore_enable_temp =
14739 pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP;
14740
14741 pi->phycal_tempdelta =
14742 (u8) wlapi_getintvar(shim, BRCMS_SROM_PHYCAL_TEMPDELTA);
14743 if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA)
14744 pi->phycal_tempdelta = 0;
14745
14746 wlc_phy_txpwr_srom_read_ppr_nphy(pi);
14747
14748 return true;
14749}
14750
14751bool wlc_phy_attach_nphy(struct brcms_phy *pi)
14752{
14753 uint i;
14754
14755 if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 6))
14756 pi->phyhang_avoid = true;
14757
14758 if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
14759 pi->nphy_gband_spurwar_en = true;
14760 if (pi->sh->boardflags2 & BFL2_SPUR_WAR)
14761 pi->nphy_aband_spurwar_en = true;
14762 }
14763 if (NREV_GE(pi->pubpi.phy_rev, 6) && NREV_LT(pi->pubpi.phy_rev, 7)) {
14764 if (pi->sh->boardflags2 & BFL2_2G_SPUR_WAR)
14765 pi->nphy_gband_spurwar2_en = true;
14766 }
14767
14768 pi->n_preamble_override = AUTO;
14769 if (NREV_IS(pi->pubpi.phy_rev, 3) || NREV_IS(pi->pubpi.phy_rev, 4))
14770 pi->n_preamble_override = BRCMS_N_PREAMBLE_MIXEDMODE;
14771
14772 pi->nphy_txrx_chain = AUTO;
14773 pi->phy_scraminit = AUTO;
14774
14775 pi->nphy_rxcalparams = 0x010100B5;
14776
14777 pi->nphy_perical = PHY_PERICAL_MPHASE;
14778 pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
14779 pi->mphase_txcal_numcmds = MPHASE_TXCAL_NUMCMDS;
14780
14781 pi->nphy_gain_boost = true;
14782 pi->nphy_elna_gain_config = false;
14783 pi->radio_is_on = false;
14784
14785 for (i = 0; i < pi->pubpi.phy_corenum; i++)
14786 pi->nphy_txpwrindex[i].index = AUTO;
14787
14788 wlc_phy_txpwrctrl_config_nphy(pi);
14789 if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
14790 pi->hwpwrctrl_capable = true;
14791
14792 pi->pi_fptr.init = wlc_phy_init_nphy;
14793 pi->pi_fptr.calinit = wlc_phy_cal_init_nphy;
14794 pi->pi_fptr.chanset = wlc_phy_chanspec_set_nphy;
14795 pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_nphy;
14796
14797 if (!wlc_phy_txpwr_srom_read_nphy(pi))
14798 return false;
14799
14800 return true;
14801}
14802
14803static s32 get_rf_pwr_offset(struct brcms_phy *pi, s16 pga_gn, s16 pad_gn)
14804{
14805 s32 rfpwr_offset = 0;
14806
14807 if (CHSPEC_IS2G(pi->radio_chanspec)) {
14808 if ((pi->pubpi.radiorev == 3) ||
14809 (pi->pubpi.radiorev == 4) ||
14810 (pi->pubpi.radiorev == 6))
14811 rfpwr_offset = (s16)
14812 nphy_papd_padgain_dlt_2g_2057rev3n4
14813 [pad_gn];
14814 else if (pi->pubpi.radiorev == 5)
14815 rfpwr_offset = (s16)
14816 nphy_papd_padgain_dlt_2g_2057rev5
14817 [pad_gn];
14818 else if ((pi->pubpi.radiorev == 7)
14819 || (pi->pubpi.radiorev ==
14820 8))
14821 rfpwr_offset = (s16)
14822 nphy_papd_padgain_dlt_2g_2057rev7
14823 [pad_gn];
14824 } else {
14825 if ((pi->pubpi.radiorev == 3) ||
14826 (pi->pubpi.radiorev == 4) ||
14827 (pi->pubpi.radiorev == 6))
14828 rfpwr_offset = (s16)
14829 nphy_papd_pgagain_dlt_5g_2057
14830 [pga_gn];
14831 else if ((pi->pubpi.radiorev == 7)
14832 || (pi->pubpi.radiorev ==
14833 8))
14834 rfpwr_offset = (s16)
14835 nphy_papd_pgagain_dlt_5g_2057rev7
14836 [pga_gn];
14837 }
14838 return rfpwr_offset;
14839}
14840
14841static void wlc_phy_update_mimoconfig_nphy(struct brcms_phy *pi, s32 preamble)
14842{
14843 bool gf_preamble = false;
14844 u16 val;
14845
14846 if (preamble == BRCMS_N_PREAMBLE_GF)
14847 gf_preamble = true;
14848
14849 val = read_phy_reg(pi, 0xed);
14850
14851 val |= RX_GF_MM_AUTO;
14852 val &= ~RX_GF_OR_MM;
14853 if (gf_preamble)
14854 val |= RX_GF_OR_MM;
14855
14856 write_phy_reg(pi, 0xed, val);
14857}
14858
14859static void wlc_phy_ipa_set_tx_digi_filts_nphy(struct brcms_phy *pi)
14860{
14861 int j, type;
14862 u16 addr_offset[] = { 0x186, 0x195, 0x2c5};
14863
14864 for (type = 0; type < 3; type++) {
14865 for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
14866 write_phy_reg(pi, addr_offset[type] + j,
14867 NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
14868 }
14869
14870 if (pi->bw == WL_CHANSPEC_BW_40) {
14871 for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
14872 write_phy_reg(pi, 0x186 + j,
14873 NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
14874 } else {
14875 if (CHSPEC_IS5G(pi->radio_chanspec)) {
14876 for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
14877 write_phy_reg(pi, 0x186 + j,
14878 NPHY_IPA_REV4_txdigi_filtcoeffs[5][j]);
14879 }
14880
14881 if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
14882 for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
14883 write_phy_reg(pi, 0x2c5 + j,
14884 NPHY_IPA_REV4_txdigi_filtcoeffs[6][j]);
14885 }
14886 }
14887}
14888
14889static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi)
14890{
14891 int j;
14892
14893 if (pi->bw == WL_CHANSPEC_BW_40) {
14894 for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
14895 write_phy_reg(pi, 0x195 + j,
14896 NPHY_IPA_REV4_txdigi_filtcoeffs[4][j]);
14897 } else {
14898 for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
14899 write_phy_reg(pi, 0x186 + j,
14900 NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
14901 }
14902}
14903
14904static void
14905wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys,
14906 u8 len)
14907{
14908 u32 t1_offset, t2_offset;
14909 u8 ctr;
14910 u8 end_event =
14911 NREV_GE(pi->pubpi.phy_rev,
14912 3) ? NPHY_REV3_RFSEQ_CMD_END : NPHY_RFSEQ_CMD_END;
14913 u8 end_dly = 1;
14914
14915 if (pi->phyhang_avoid)
14916 wlc_phy_stay_in_carriersearch_nphy(pi, true);
14917
14918 t1_offset = cmd << 4;
14919 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t1_offset, 8,
14920 events);
14921 t2_offset = t1_offset + 0x080;
14922 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t2_offset, 8,
14923 dlys);
14924
14925 for (ctr = len; ctr < 16; ctr++) {
14926 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
14927 t1_offset + ctr, 8, &end_event);
14928 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
14929 t2_offset + ctr, 8, &end_dly);
14930 }
14931
14932 if (pi->phyhang_avoid)
14933 wlc_phy_stay_in_carriersearch_nphy(pi, false);
14934}
14935
14936static u16 wlc_phy_read_lpf_bw_ctl_nphy(struct brcms_phy *pi, u16 offset)
14937{
14938 u16 lpf_bw_ctl_val = 0;
14939 u16 rx2tx_lpf_rc_lut_offset = 0;
14940
14941 if (offset == 0) {
14942 if (CHSPEC_IS40(pi->radio_chanspec))
14943 rx2tx_lpf_rc_lut_offset = 0x159;
14944 else
14945 rx2tx_lpf_rc_lut_offset = 0x154;
14946 } else {
14947 rx2tx_lpf_rc_lut_offset = offset;
14948 }
14949 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
14950 (u32) rx2tx_lpf_rc_lut_offset, 16,
14951 &lpf_bw_ctl_val);
14952
14953 lpf_bw_ctl_val = lpf_bw_ctl_val & 0x7;
14954
14955 return lpf_bw_ctl_val;
14956}
14957
14958static void
14959wlc_phy_rfctrl_override_nphy_rev7(struct brcms_phy *pi, u16 field, u16 value,
14960 u8 core_mask, u8 off, u8 override_id)
14961{
14962 u8 core_num;
14963 u16 addr = 0, en_addr = 0, val_addr = 0, en_mask = 0, val_mask = 0;
14964 u8 val_shift = 0;
14965
14966 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
14967 en_mask = field;
14968 for (core_num = 0; core_num < 2; core_num++) {
14969 if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID0) {
14970
14971 switch (field) {
14972 case (0x1 << 2):
14973 en_addr = (core_num == 0) ? 0xe7 : 0xec;
14974 val_addr = (core_num == 0) ? 0x7a :
14975 0x7d;
14976 val_mask = (0x1 << 1);
14977 val_shift = 1;
14978 break;
14979 case (0x1 << 3):
14980 en_addr = (core_num == 0) ? 0xe7 : 0xec;
14981 val_addr = (core_num == 0) ? 0x7a :
14982 0x7d;
14983 val_mask = (0x1 << 2);
14984 val_shift = 2;
14985 break;
14986 case (0x1 << 4):
14987 en_addr = (core_num == 0) ? 0xe7 : 0xec;
14988 val_addr = (core_num == 0) ? 0x7a :
14989 0x7d;
14990 val_mask = (0x1 << 4);
14991 val_shift = 4;
14992 break;
14993 case (0x1 << 5):
14994 en_addr = (core_num == 0) ? 0xe7 : 0xec;
14995 val_addr = (core_num == 0) ? 0x7a :
14996 0x7d;
14997 val_mask = (0x1 << 5);
14998 val_shift = 5;
14999 break;
15000 case (0x1 << 6):
15001 en_addr = (core_num == 0) ? 0xe7 : 0xec;
15002 val_addr = (core_num == 0) ? 0x7a :
15003 0x7d;
15004 val_mask = (0x1 << 6);
15005 val_shift = 6;
15006 break;
15007 case (0x1 << 7):
15008 en_addr = (core_num == 0) ? 0xe7 : 0xec;
15009 val_addr = (core_num == 0) ? 0x7a :
15010 0x7d;
15011 val_mask = (0x1 << 7);
15012 val_shift = 7;
15013 break;
15014 case (0x1 << 10):
15015 en_addr = (core_num == 0) ? 0xe7 : 0xec;
15016 val_addr = (core_num == 0) ? 0xf8 :
15017 0xfa;
15018 val_mask = (0x7 << 4);
15019 val_shift = 4;
15020 break;
15021 case (0x1 << 11):
15022 en_addr = (core_num == 0) ? 0xe7 : 0xec;
15023 val_addr = (core_num == 0) ? 0x7b :
15024 0x7e;
15025 val_mask = (0xffff << 0);
15026 val_shift = 0;
15027 break;
15028 case (0x1 << 12):
15029 en_addr = (core_num == 0) ? 0xe7 : 0xec;
15030 val_addr = (core_num == 0) ? 0x7c :
15031 0x7f;
15032 val_mask = (0xffff << 0);
15033 val_shift = 0;
15034 break;
15035 case (0x3 << 13):
15036 en_addr = (core_num == 0) ? 0xe7 : 0xec;
15037 val_addr = (core_num == 0) ? 0x348 :
15038 0x349;
15039 val_mask = (0xff << 0);
15040 val_shift = 0;
15041 break;
15042 case (0x1 << 13):
15043 en_addr = (core_num == 0) ? 0xe7 : 0xec;
15044 val_addr = (core_num == 0) ? 0x348 :
15045 0x349;
15046 val_mask = (0xf << 0);
15047 val_shift = 0;
15048 break;
15049 default:
15050 addr = 0xffff;
15051 break;
15052 }
15053 } else if (override_id ==
15054 NPHY_REV7_RFCTRLOVERRIDE_ID1) {
15055
15056 switch (field) {
15057 case (0x1 << 1):
15058 en_addr = (core_num == 0) ? 0x342 :
15059 0x343;
15060 val_addr = (core_num == 0) ? 0x340 :
15061 0x341;
15062 val_mask = (0x1 << 1);
15063 val_shift = 1;
15064 break;
15065 case (0x1 << 3):
15066 en_addr = (core_num == 0) ? 0x342 :
15067 0x343;
15068 val_addr = (core_num == 0) ? 0x340 :
15069 0x341;
15070 val_mask = (0x1 << 3);
15071 val_shift = 3;
15072 break;
15073 case (0x1 << 5):
15074 en_addr = (core_num == 0) ? 0x342 :
15075 0x343;
15076 val_addr = (core_num == 0) ? 0x340 :
15077 0x341;
15078 val_mask = (0x1 << 5);
15079 val_shift = 5;
15080 break;
15081 case (0x1 << 4):
15082 en_addr = (core_num == 0) ? 0x342 :
15083 0x343;
15084 val_addr = (core_num == 0) ? 0x340 :
15085 0x341;
15086 val_mask = (0x1 << 4);
15087 val_shift = 4;
15088 break;
15089 case (0x1 << 2):
15090
15091 en_addr = (core_num == 0) ? 0x342 :
15092 0x343;
15093 val_addr = (core_num == 0) ? 0x340 :
15094 0x341;
15095 val_mask = (0x1 << 2);
15096 val_shift = 2;
15097 break;
15098 case (0x1 << 7):
15099
15100 en_addr = (core_num == 0) ? 0x342 :
15101 0x343;
15102 val_addr = (core_num == 0) ? 0x340 :
15103 0x341;
15104 val_mask = (0x7 << 8);
15105 val_shift = 8;
15106 break;
15107 case (0x1 << 11):
15108 en_addr = (core_num == 0) ? 0x342 :
15109 0x343;
15110 val_addr = (core_num == 0) ? 0x340 :
15111 0x341;
15112 val_mask = (0x1 << 14);
15113 val_shift = 14;
15114 break;
15115 case (0x1 << 10):
15116 en_addr = (core_num == 0) ? 0x342 :
15117 0x343;
15118 val_addr = (core_num == 0) ? 0x340 :
15119 0x341;
15120 val_mask = (0x1 << 13);
15121 val_shift = 13;
15122 break;
15123 case (0x1 << 9):
15124 en_addr = (core_num == 0) ? 0x342 :
15125 0x343;
15126 val_addr = (core_num == 0) ? 0x340 :
15127 0x341;
15128 val_mask = (0x1 << 12);
15129 val_shift = 12;
15130 break;
15131 case (0x1 << 8):
15132 en_addr = (core_num == 0) ? 0x342 :
15133 0x343;
15134 val_addr = (core_num == 0) ? 0x340 :
15135 0x341;
15136 val_mask = (0x1 << 11);
15137 val_shift = 11;
15138 break;
15139 case (0x1 << 6):
15140 en_addr = (core_num == 0) ? 0x342 :
15141 0x343;
15142 val_addr = (core_num == 0) ? 0x340 :
15143 0x341;
15144 val_mask = (0x1 << 6);
15145 val_shift = 6;
15146 break;
15147 case (0x1 << 0):
15148 en_addr = (core_num == 0) ? 0x342 :
15149 0x343;
15150 val_addr = (core_num == 0) ? 0x340 :
15151 0x341;
15152 val_mask = (0x1 << 0);
15153 val_shift = 0;
15154 break;
15155 default:
15156 addr = 0xffff;
15157 break;
15158 }
15159 } else if (override_id ==
15160 NPHY_REV7_RFCTRLOVERRIDE_ID2) {
15161
15162 switch (field) {
15163 case (0x1 << 3):
15164 en_addr = (core_num == 0) ? 0x346 :
15165 0x347;
15166 val_addr = (core_num == 0) ? 0x344 :
15167 0x345;
15168 val_mask = (0x1 << 3);
15169 val_shift = 3;
15170 break;
15171 case (0x1 << 1):
15172 en_addr = (core_num == 0) ? 0x346 :
15173 0x347;
15174 val_addr = (core_num == 0) ? 0x344 :
15175 0x345;
15176 val_mask = (0x1 << 1);
15177 val_shift = 1;
15178 break;
15179 case (0x1 << 0):
15180 en_addr = (core_num == 0) ? 0x346 :
15181 0x347;
15182 val_addr = (core_num == 0) ? 0x344 :
15183 0x345;
15184 val_mask = (0x1 << 0);
15185 val_shift = 0;
15186 break;
15187 case (0x1 << 2):
15188 en_addr = (core_num == 0) ? 0x346 :
15189 0x347;
15190 val_addr = (core_num == 0) ? 0x344 :
15191 0x345;
15192 val_mask = (0x1 << 2);
15193 val_shift = 2;
15194 break;
15195 case (0x1 << 4):
15196 en_addr = (core_num == 0) ? 0x346 :
15197 0x347;
15198 val_addr = (core_num == 0) ? 0x344 :
15199 0x345;
15200 val_mask = (0x1 << 4);
15201 val_shift = 4;
15202 break;
15203 default:
15204 addr = 0xffff;
15205 break;
15206 }
15207 }
15208
15209 if (off) {
15210 and_phy_reg(pi, en_addr, ~en_mask);
15211 and_phy_reg(pi, val_addr, ~val_mask);
15212 } else {
15213
15214 if ((core_mask == 0)
15215 || (core_mask & (1 << core_num))) {
15216 or_phy_reg(pi, en_addr, en_mask);
15217
15218 if (addr != 0xffff)
15219 mod_phy_reg(pi, val_addr,
15220 val_mask,
15221 (value <<
15222 val_shift));
15223 }
15224 }
15225 }
15226 }
15227}
15228
15229static void wlc_phy_adjust_lnagaintbl_nphy(struct brcms_phy *pi)
15230{
15231 uint core;
15232 int ctr;
15233 s16 gain_delta[2];
15234 u8 curr_channel;
15235 u16 minmax_gain[2];
15236 u16 regval[4];
15237
15238 if (pi->phyhang_avoid)
15239 wlc_phy_stay_in_carriersearch_nphy(pi, true);
15240
15241 if (pi->nphy_gain_boost) {
15242 if ((CHSPEC_IS2G(pi->radio_chanspec))) {
15243
15244 gain_delta[0] = 6;
15245 gain_delta[1] = 6;
15246 } else {
15247
15248 curr_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
15249 gain_delta[0] =
15250 (s16)
15251 PHY_HW_ROUND(((nphy_lnagain_est0[0] *
15252 curr_channel) +
15253 nphy_lnagain_est0[1]), 13);
15254 gain_delta[1] =
15255 (s16)
15256 PHY_HW_ROUND(((nphy_lnagain_est1[0] *
15257 curr_channel) +
15258 nphy_lnagain_est1[1]), 13);
15259 }
15260 } else {
15261
15262 gain_delta[0] = 0;
15263 gain_delta[1] = 0;
15264 }
15265
15266 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
15267 if (pi->nphy_elna_gain_config) {
15268
15269 regval[0] = nphy_def_lnagains[2] + gain_delta[core];
15270 regval[1] = nphy_def_lnagains[3] + gain_delta[core];
15271 regval[2] = nphy_def_lnagains[3] + gain_delta[core];
15272 regval[3] = nphy_def_lnagains[3] + gain_delta[core];
15273 } else {
15274 for (ctr = 0; ctr < 4; ctr++)
15275 regval[ctr] =
15276 nphy_def_lnagains[ctr] +
15277 gain_delta[core];
15278 }
15279 wlc_phy_table_write_nphy(pi, core, 4, 8, 16, regval);
15280
15281 minmax_gain[core] =
15282 (u16) (nphy_def_lnagains[2] + gain_delta[core] + 4);
15283 }
15284
15285 mod_phy_reg(pi, 0x1e, (0xff << 0), (minmax_gain[0] << 0));
15286 mod_phy_reg(pi, 0x34, (0xff << 0), (minmax_gain[1] << 0));
15287
15288 if (pi->phyhang_avoid)
15289 wlc_phy_stay_in_carriersearch_nphy(pi, false);
15290}
15291
15292static void
15293wlc_phy_war_force_trsw_to_R_cliplo_nphy(struct brcms_phy *pi, u8 core)
15294{
15295 if (core == PHY_CORE_0) {
15296 write_phy_reg(pi, 0x38, 0x4);
15297 if (CHSPEC_IS2G(pi->radio_chanspec))
15298 write_phy_reg(pi, 0x37, 0x0060);
15299 else
15300 write_phy_reg(pi, 0x37, 0x1080);
15301 } else if (core == PHY_CORE_1) {
15302 write_phy_reg(pi, 0x2ae, 0x4);
15303 if (CHSPEC_IS2G(pi->radio_chanspec))
15304 write_phy_reg(pi, 0x2ad, 0x0060);
15305 else
15306 write_phy_reg(pi, 0x2ad, 0x1080);
15307 }
15308}
15309
15310static void wlc_phy_war_txchain_upd_nphy(struct brcms_phy *pi, u8 txchain)
15311{
15312 u8 txchain0, txchain1;
15313
15314 txchain0 = txchain & 0x1;
15315 txchain1 = (txchain & 0x2) >> 1;
15316 if (!txchain0)
15317 wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
15318
15319 if (!txchain1)
15320 wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
15321}
15322
15323static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi)
15324{
15325 s8 lna1_gain_db[] = { 8, 13, 17, 22 };
15326 s8 lna2_gain_db[] = { -2, 7, 11, 15 };
15327 s8 tia_gain_db[] = { -4, -1, 2, 5, 5, 5, 5, 5, 5, 5 };
15328 s8 tia_gainbits[] = {
15329 0x0, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
15330
15331 mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
15332 mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
15333
15334 mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
15335
15336 mod_phy_reg(pi, 0x283, (0xff << 0), (0x3c << 0));
15337 mod_phy_reg(pi, 0x280, (0xff << 0), (0x3c << 0));
15338
15339 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x8, 8,
15340 lna1_gain_db);
15341 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x8, 8,
15342 lna1_gain_db);
15343
15344 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, 8,
15345 lna2_gain_db);
15346 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, 8,
15347 lna2_gain_db);
15348
15349 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
15350 tia_gain_db);
15351 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
15352 tia_gain_db);
15353
15354 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
15355 tia_gainbits);
15356 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
15357 tia_gainbits);
15358
15359 write_phy_reg(pi, 0x37, 0x74);
15360 write_phy_reg(pi, 0x2ad, 0x74);
15361 write_phy_reg(pi, 0x38, 0x18);
15362 write_phy_reg(pi, 0x2ae, 0x18);
15363
15364 write_phy_reg(pi, 0x2b, 0xe8);
15365 write_phy_reg(pi, 0x41, 0xe8);
15366
15367 if (CHSPEC_IS20(pi->radio_chanspec)) {
15368
15369 mod_phy_reg(pi, 0x300, (0x3f << 0), (0x12 << 0));
15370 mod_phy_reg(pi, 0x301, (0x3f << 0), (0x12 << 0));
15371 } else {
15372
15373 mod_phy_reg(pi, 0x300, (0x3f << 0), (0x10 << 0));
15374 mod_phy_reg(pi, 0x301, (0x3f << 0), (0x10 << 0));
15375 }
15376}
15377
15378static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
15379{
15380 u16 currband;
15381 s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
15382 s8 *lna1_gain_db = NULL;
15383 s8 *lna1_gain_db_2 = NULL;
15384 s8 *lna2_gain_db = NULL;
15385 s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
15386 s8 *tia_gain_db;
15387 s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
15388 s8 *tia_gainbits;
15389 u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
15390 u16 *rfseq_init_gain;
15391 u16 init_gaincode;
15392 u16 clip1hi_gaincode;
15393 u16 clip1md_gaincode = 0;
15394 u16 clip1md_gaincode_B;
15395 u16 clip1lo_gaincode;
15396 u16 clip1lo_gaincode_B;
15397 u8 crsminl_th = 0;
15398 u8 crsminu_th;
15399 u16 nbclip_th = 0;
15400 u8 w1clip_th;
15401 u16 freq;
15402 s8 nvar_baseline_offset0 = 0, nvar_baseline_offset1 = 0;
15403 u8 chg_nbclip_th = 0;
15404
15405 mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
15406 mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
15407
15408 currband = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
15409 if (currband == 0) {
15410
15411 lna1_gain_db = lna1G_gain_db_rev7;
15412
15413 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
15414 lna1_gain_db);
15415 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
15416 lna1_gain_db);
15417
15418 mod_phy_reg(pi, 0x283, (0xff << 0), (0x40 << 0));
15419
15420 if (CHSPEC_IS40(pi->radio_chanspec)) {
15421 mod_phy_reg(pi, 0x280, (0xff << 0), (0x3e << 0));
15422 mod_phy_reg(pi, 0x283, (0xff << 0), (0x3e << 0));
15423 }
15424
15425 mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
15426
15427 if (CHSPEC_IS20(pi->radio_chanspec)) {
15428 mod_phy_reg(pi, 0x300, (0x3f << 0), (13 << 0));
15429 mod_phy_reg(pi, 0x301, (0x3f << 0), (13 << 0));
15430 }
15431 } else {
15432
15433 init_gaincode = 0x9e;
15434 clip1hi_gaincode = 0x9e;
15435 clip1md_gaincode_B = 0x24;
15436 clip1lo_gaincode = 0x8a;
15437 clip1lo_gaincode_B = 8;
15438 rfseq_init_gain = rfseqA_init_gain_rev7;
15439
15440 tia_gain_db = tiaA_gain_db_rev7;
15441 tia_gainbits = tiaA_gainbits_rev7;
15442
15443 freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
15444 if (CHSPEC_IS20(pi->radio_chanspec)) {
15445
15446 w1clip_th = 25;
15447 clip1md_gaincode = 0x82;
15448
15449 if ((freq <= 5080) || (freq == 5825)) {
15450
15451 s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
15452 s8 lna1A_gain_db_2_rev7[] = {
15453 11, 17, 22, 25};
15454 s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
15455
15456 crsminu_th = 0x3e;
15457 lna1_gain_db = lna1A_gain_db_rev7;
15458 lna1_gain_db_2 = lna1A_gain_db_2_rev7;
15459 lna2_gain_db = lna2A_gain_db_rev7;
15460 } else if ((freq >= 5500) && (freq <= 5700)) {
15461
15462 s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
15463 s8 lna1A_gain_db_2_rev7[] = {
15464 12, 18, 22, 26};
15465 s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
15466
15467 crsminu_th = 0x45;
15468 clip1md_gaincode_B = 0x14;
15469 nbclip_th = 0xff;
15470 chg_nbclip_th = 1;
15471 lna1_gain_db = lna1A_gain_db_rev7;
15472 lna1_gain_db_2 = lna1A_gain_db_2_rev7;
15473 lna2_gain_db = lna2A_gain_db_rev7;
15474 } else {
15475
15476 s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
15477 s8 lna1A_gain_db_2_rev7[] = {
15478 12, 18, 22, 26};
15479 s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
15480
15481 crsminu_th = 0x41;
15482 lna1_gain_db = lna1A_gain_db_rev7;
15483 lna1_gain_db_2 = lna1A_gain_db_2_rev7;
15484 lna2_gain_db = lna2A_gain_db_rev7;
15485 }
15486
15487 if (freq <= 4920) {
15488 nvar_baseline_offset0 = 5;
15489 nvar_baseline_offset1 = 5;
15490 } else if ((freq > 4920) && (freq <= 5320)) {
15491 nvar_baseline_offset0 = 3;
15492 nvar_baseline_offset1 = 5;
15493 } else if ((freq > 5320) && (freq <= 5700)) {
15494 nvar_baseline_offset0 = 3;
15495 nvar_baseline_offset1 = 2;
15496 } else {
15497 nvar_baseline_offset0 = 4;
15498 nvar_baseline_offset1 = 0;
15499 }
15500 } else {
15501
15502 crsminu_th = 0x3a;
15503 crsminl_th = 0x3a;
15504 w1clip_th = 20;
15505
15506 if ((freq >= 4920) && (freq <= 5320)) {
15507 nvar_baseline_offset0 = 4;
15508 nvar_baseline_offset1 = 5;
15509 } else if ((freq > 5320) && (freq <= 5550)) {
15510 nvar_baseline_offset0 = 4;
15511 nvar_baseline_offset1 = 2;
15512 } else {
15513 nvar_baseline_offset0 = 5;
15514 nvar_baseline_offset1 = 3;
15515 }
15516 }
15517
15518 write_phy_reg(pi, 0x20, init_gaincode);
15519 write_phy_reg(pi, 0x2a7, init_gaincode);
15520
15521 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
15522 pi->pubpi.phy_corenum, 0x106, 16,
15523 rfseq_init_gain);
15524
15525 write_phy_reg(pi, 0x22, clip1hi_gaincode);
15526 write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
15527
15528 write_phy_reg(pi, 0x36, clip1md_gaincode_B);
15529 write_phy_reg(pi, 0x2ac, clip1md_gaincode_B);
15530
15531 write_phy_reg(pi, 0x37, clip1lo_gaincode);
15532 write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
15533 write_phy_reg(pi, 0x38, clip1lo_gaincode_B);
15534 write_phy_reg(pi, 0x2ae, clip1lo_gaincode_B);
15535
15536 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
15537 tia_gain_db);
15538 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
15539 tia_gain_db);
15540
15541 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
15542 tia_gainbits);
15543 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
15544 tia_gainbits);
15545
15546 mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
15547
15548 if (chg_nbclip_th == 1) {
15549 write_phy_reg(pi, 0x2b, nbclip_th);
15550 write_phy_reg(pi, 0x41, nbclip_th);
15551 }
15552
15553 mod_phy_reg(pi, 0x300, (0x3f << 0), (w1clip_th << 0));
15554 mod_phy_reg(pi, 0x301, (0x3f << 0), (w1clip_th << 0));
15555
15556 mod_phy_reg(pi, 0x2e4,
15557 (0x3f << 0), (nvar_baseline_offset0 << 0));
15558
15559 mod_phy_reg(pi, 0x2e4,
15560 (0x3f << 6), (nvar_baseline_offset1 << 6));
15561
15562 if (CHSPEC_IS20(pi->radio_chanspec)) {
15563
15564 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
15565 lna1_gain_db);
15566 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
15567 lna1_gain_db_2);
15568
15569 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
15570 8, lna2_gain_db);
15571 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
15572 8, lna2_gain_db);
15573
15574 write_phy_reg(pi, 0x24, clip1md_gaincode);
15575 write_phy_reg(pi, 0x2ab, clip1md_gaincode);
15576 } else {
15577 mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
15578 }
15579 }
15580}
15581
15582static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
15583{
15584 u16 w1th, hpf_code, currband;
15585 int ctr;
15586 u8 rfseq_updategainu_events[] = {
15587 NPHY_RFSEQ_CMD_RX_GAIN,
15588 NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
15589 NPHY_RFSEQ_CMD_SET_HPF_BW
15590 };
15591 u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
15592 s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
15593 s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
15594 s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
15595 s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
15596 s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
15597 s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
15598 s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
15599 s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
15600 s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
15601 s8 *lna1_gain_db = NULL;
15602 s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
15603 s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
15604 s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
15605 s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
15606 s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
15607 s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
15608 s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
15609 s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
15610 s8 *lna2_gain_db = NULL;
15611 s8 tiaG_gain_db[] = {
15612 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A };
15613 s8 tiaA_gain_db[] = {
15614 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 };
15615 s8 tiaA_gain_db_rev4[] = {
15616 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
15617 s8 tiaA_gain_db_rev5[] = {
15618 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
15619 s8 tiaA_gain_db_rev6[] = {
15620 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
15621 s8 *tia_gain_db;
15622 s8 tiaG_gainbits[] = {
15623 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
15624 s8 tiaA_gainbits[] = {
15625 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 };
15626 s8 tiaA_gainbits_rev4[] = {
15627 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
15628 s8 tiaA_gainbits_rev5[] = {
15629 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
15630 s8 tiaA_gainbits_rev6[] = {
15631 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
15632 s8 *tia_gainbits;
15633 s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
15634 s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
15635 u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
15636 u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
15637 u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
15638 u16 rfseqG_init_gain_rev5_elna[] = {
15639 0x013f, 0x013f, 0x013f, 0x013f };
15640 u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
15641 u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
15642 u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
15643 u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
15644 u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
15645 u16 rfseqA_init_gain_rev4_elna[] = {
15646 0x314f, 0x314f, 0x314f, 0x314f };
15647 u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
15648 u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
15649 u16 *rfseq_init_gain;
15650 u16 initG_gaincode = 0x627e;
15651 u16 initG_gaincode_rev4 = 0x527e;
15652 u16 initG_gaincode_rev5 = 0x427e;
15653 u16 initG_gaincode_rev5_elna = 0x027e;
15654 u16 initG_gaincode_rev6 = 0x527e;
15655 u16 initG_gaincode_rev6_224B0 = 0x427e;
15656 u16 initG_gaincode_rev6_elna = 0x127e;
15657 u16 initA_gaincode = 0x52de;
15658 u16 initA_gaincode_rev4 = 0x629e;
15659 u16 initA_gaincode_rev4_elna = 0x329e;
15660 u16 initA_gaincode_rev5 = 0x729e;
15661 u16 initA_gaincode_rev6 = 0x729e;
15662 u16 init_gaincode;
15663 u16 clip1hiG_gaincode = 0x107e;
15664 u16 clip1hiG_gaincode_rev4 = 0x007e;
15665 u16 clip1hiG_gaincode_rev5 = 0x1076;
15666 u16 clip1hiG_gaincode_rev6 = 0x007e;
15667 u16 clip1hiA_gaincode = 0x00de;
15668 u16 clip1hiA_gaincode_rev4 = 0x029e;
15669 u16 clip1hiA_gaincode_rev5 = 0x029e;
15670 u16 clip1hiA_gaincode_rev6 = 0x029e;
15671 u16 clip1hi_gaincode;
15672 u16 clip1mdG_gaincode = 0x0066;
15673 u16 clip1mdA_gaincode = 0x00ca;
15674 u16 clip1mdA_gaincode_rev4 = 0x1084;
15675 u16 clip1mdA_gaincode_rev5 = 0x2084;
15676 u16 clip1mdA_gaincode_rev6 = 0x2084;
15677 u16 clip1md_gaincode = 0;
15678 u16 clip1loG_gaincode = 0x0074;
15679 u16 clip1loG_gaincode_rev5[] = {
15680 0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c
15681 };
15682 u16 clip1loG_gaincode_rev6[] = {
15683 0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e
15684 };
15685 u16 clip1loG_gaincode_rev6_224B0 = 0x1074;
15686 u16 clip1loA_gaincode = 0x00cc;
15687 u16 clip1loA_gaincode_rev4 = 0x0086;
15688 u16 clip1loA_gaincode_rev5 = 0x2086;
15689 u16 clip1loA_gaincode_rev6 = 0x2086;
15690 u16 clip1lo_gaincode;
15691 u8 crsminG_th = 0x18;
15692 u8 crsminG_th_rev5 = 0x18;
15693 u8 crsminG_th_rev6 = 0x18;
15694 u8 crsminA_th = 0x1e;
15695 u8 crsminA_th_rev4 = 0x24;
15696 u8 crsminA_th_rev5 = 0x24;
15697 u8 crsminA_th_rev6 = 0x24;
15698 u8 crsmin_th;
15699 u8 crsminlG_th = 0x18;
15700 u8 crsminlG_th_rev5 = 0x18;
15701 u8 crsminlG_th_rev6 = 0x18;
15702 u8 crsminlA_th = 0x1e;
15703 u8 crsminlA_th_rev4 = 0x24;
15704 u8 crsminlA_th_rev5 = 0x24;
15705 u8 crsminlA_th_rev6 = 0x24;
15706 u8 crsminl_th = 0;
15707 u8 crsminuG_th = 0x18;
15708 u8 crsminuG_th_rev5 = 0x18;
15709 u8 crsminuG_th_rev6 = 0x18;
15710 u8 crsminuA_th = 0x1e;
15711 u8 crsminuA_th_rev4 = 0x24;
15712 u8 crsminuA_th_rev5 = 0x24;
15713 u8 crsminuA_th_rev6 = 0x24;
15714 u8 crsminuA_th_rev6_224B0 = 0x2d;
15715 u8 crsminu_th;
15716 u16 nbclipG_th = 0x20d;
15717 u16 nbclipG_th_rev4 = 0x1a1;
15718 u16 nbclipG_th_rev5 = 0x1d0;
15719 u16 nbclipG_th_rev6 = 0x1d0;
15720 u16 nbclipA_th = 0x1a1;
15721 u16 nbclipA_th_rev4 = 0x107;
15722 u16 nbclipA_th_rev5 = 0x0a9;
15723 u16 nbclipA_th_rev6 = 0x0f0;
15724 u16 nbclip_th = 0;
15725 u8 w1clipG_th = 5;
15726 u8 w1clipG_th_rev5 = 9;
15727 u8 w1clipG_th_rev6 = 5;
15728 u8 w1clipA_th = 25, w1clip_th;
15729 u8 rssi_gain_default = 0x50;
15730 u8 rssiG_gain_rev6_224B0 = 0x50;
15731 u8 rssiA_gain_rev5 = 0x90;
15732 u8 rssiA_gain_rev6 = 0x90;
15733 u8 rssi_gain;
15734 u16 regval[21];
15735 u8 triso;
15736
15737 triso = (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.triso :
15738 pi->srom_fem2g.triso;
15739
15740 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
15741 if (pi->pubpi.radiorev == 5) {
15742 wlc_phy_workarounds_nphy_gainctrl_2057_rev5(pi);
15743 } else if (pi->pubpi.radiorev == 7) {
15744 wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
15745
15746 mod_phy_reg(pi, 0x283, (0xff << 0), (0x44 << 0));
15747 mod_phy_reg(pi, 0x280, (0xff << 0), (0x44 << 0));
15748
15749 } else if ((pi->pubpi.radiorev == 3)
15750 || (pi->pubpi.radiorev == 8)) {
15751 wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
15752
15753 if (pi->pubpi.radiorev == 8) {
15754 mod_phy_reg(pi, 0x283,
15755 (0xff << 0), (0x44 << 0));
15756 mod_phy_reg(pi, 0x280,
15757 (0xff << 0), (0x44 << 0));
15758 }
15759 } else {
15760 wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
15761 }
15762 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
15763
15764 mod_phy_reg(pi, 0xa0, (0x1 << 6), (1 << 6));
15765
15766 mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
15767 mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
15768
15769 currband =
15770 read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
15771 if (currband == 0) {
15772 if (NREV_GE(pi->pubpi.phy_rev, 6)) {
15773 if (pi->pubpi.radiorev == 11) {
15774 lna1_gain_db = lna1G_gain_db_rev6_224B0;
15775 lna2_gain_db = lna2G_gain_db_rev6_224B0;
15776 rfseq_init_gain =
15777 rfseqG_init_gain_rev6_224B0;
15778 init_gaincode =
15779 initG_gaincode_rev6_224B0;
15780 clip1hi_gaincode =
15781 clip1hiG_gaincode_rev6;
15782 clip1lo_gaincode =
15783 clip1loG_gaincode_rev6_224B0;
15784 nbclip_th = nbclipG_th_rev6;
15785 w1clip_th = w1clipG_th_rev6;
15786 crsmin_th = crsminG_th_rev6;
15787 crsminl_th = crsminlG_th_rev6;
15788 crsminu_th = crsminuG_th_rev6;
15789 rssi_gain = rssiG_gain_rev6_224B0;
15790 } else {
15791 lna1_gain_db = lna1G_gain_db_rev6;
15792 lna2_gain_db = lna2G_gain_db_rev6;
15793 if (pi->sh->boardflags & BFL_EXTLNA) {
15794
15795 rfseq_init_gain =
15796 rfseqG_init_gain_rev6_elna;
15797 init_gaincode =
15798 initG_gaincode_rev6_elna;
15799 } else {
15800 rfseq_init_gain =
15801 rfseqG_init_gain_rev6;
15802 init_gaincode =
15803 initG_gaincode_rev6;
15804 }
15805 clip1hi_gaincode =
15806 clip1hiG_gaincode_rev6;
15807 switch (triso) {
15808 case 0:
15809 clip1lo_gaincode =
15810 clip1loG_gaincode_rev6
15811 [0];
15812 break;
15813 case 1:
15814 clip1lo_gaincode =
15815 clip1loG_gaincode_rev6
15816 [1];
15817 break;
15818 case 2:
15819 clip1lo_gaincode =
15820 clip1loG_gaincode_rev6
15821 [2];
15822 break;
15823 case 3:
15824 default:
15825
15826 clip1lo_gaincode =
15827 clip1loG_gaincode_rev6
15828 [3];
15829 break;
15830 case 4:
15831 clip1lo_gaincode =
15832 clip1loG_gaincode_rev6
15833 [4];
15834 break;
15835 case 5:
15836 clip1lo_gaincode =
15837 clip1loG_gaincode_rev6
15838 [5];
15839 break;
15840 case 6:
15841 clip1lo_gaincode =
15842 clip1loG_gaincode_rev6
15843 [6];
15844 break;
15845 case 7:
15846 clip1lo_gaincode =
15847 clip1loG_gaincode_rev6
15848 [7];
15849 break;
15850 }
15851 nbclip_th = nbclipG_th_rev6;
15852 w1clip_th = w1clipG_th_rev6;
15853 crsmin_th = crsminG_th_rev6;
15854 crsminl_th = crsminlG_th_rev6;
15855 crsminu_th = crsminuG_th_rev6;
15856 rssi_gain = rssi_gain_default;
15857 }
15858 } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
15859 lna1_gain_db = lna1G_gain_db_rev5;
15860 lna2_gain_db = lna2G_gain_db_rev5;
15861 if (pi->sh->boardflags & BFL_EXTLNA) {
15862
15863 rfseq_init_gain =
15864 rfseqG_init_gain_rev5_elna;
15865 init_gaincode =
15866 initG_gaincode_rev5_elna;
15867 } else {
15868 rfseq_init_gain = rfseqG_init_gain_rev5;
15869 init_gaincode = initG_gaincode_rev5;
15870 }
15871 clip1hi_gaincode = clip1hiG_gaincode_rev5;
15872 switch (triso) {
15873 case 0:
15874 clip1lo_gaincode =
15875 clip1loG_gaincode_rev5[0];
15876 break;
15877 case 1:
15878 clip1lo_gaincode =
15879 clip1loG_gaincode_rev5[1];
15880 break;
15881 case 2:
15882 clip1lo_gaincode =
15883 clip1loG_gaincode_rev5[2];
15884 break;
15885 case 3:
15886
15887 clip1lo_gaincode =
15888 clip1loG_gaincode_rev5[3];
15889 break;
15890 case 4:
15891 clip1lo_gaincode =
15892 clip1loG_gaincode_rev5[4];
15893 break;
15894 case 5:
15895 clip1lo_gaincode =
15896 clip1loG_gaincode_rev5[5];
15897 break;
15898 case 6:
15899 clip1lo_gaincode =
15900 clip1loG_gaincode_rev5[6];
15901 break;
15902 case 7:
15903 clip1lo_gaincode =
15904 clip1loG_gaincode_rev5[7];
15905 break;
15906 default:
15907 clip1lo_gaincode =
15908 clip1loG_gaincode_rev5[3];
15909 break;
15910 }
15911 nbclip_th = nbclipG_th_rev5;
15912 w1clip_th = w1clipG_th_rev5;
15913 crsmin_th = crsminG_th_rev5;
15914 crsminl_th = crsminlG_th_rev5;
15915 crsminu_th = crsminuG_th_rev5;
15916 rssi_gain = rssi_gain_default;
15917 } else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
15918 lna1_gain_db = lna1G_gain_db_rev4;
15919 lna2_gain_db = lna2G_gain_db;
15920 rfseq_init_gain = rfseqG_init_gain_rev4;
15921 init_gaincode = initG_gaincode_rev4;
15922 clip1hi_gaincode = clip1hiG_gaincode_rev4;
15923 clip1lo_gaincode = clip1loG_gaincode;
15924 nbclip_th = nbclipG_th_rev4;
15925 w1clip_th = w1clipG_th;
15926 crsmin_th = crsminG_th;
15927 crsminl_th = crsminlG_th;
15928 crsminu_th = crsminuG_th;
15929 rssi_gain = rssi_gain_default;
15930 } else {
15931 lna1_gain_db = lna1G_gain_db;
15932 lna2_gain_db = lna2G_gain_db;
15933 rfseq_init_gain = rfseqG_init_gain;
15934 init_gaincode = initG_gaincode;
15935 clip1hi_gaincode = clip1hiG_gaincode;
15936 clip1lo_gaincode = clip1loG_gaincode;
15937 nbclip_th = nbclipG_th;
15938 w1clip_th = w1clipG_th;
15939 crsmin_th = crsminG_th;
15940 crsminl_th = crsminlG_th;
15941 crsminu_th = crsminuG_th;
15942 rssi_gain = rssi_gain_default;
15943 }
15944 tia_gain_db = tiaG_gain_db;
15945 tia_gainbits = tiaG_gainbits;
15946 clip1md_gaincode = clip1mdG_gaincode;
15947 } else {
15948 if (NREV_GE(pi->pubpi.phy_rev, 6)) {
15949 lna1_gain_db = lna1A_gain_db_rev6;
15950 lna2_gain_db = lna2A_gain_db_rev6;
15951 tia_gain_db = tiaA_gain_db_rev6;
15952 tia_gainbits = tiaA_gainbits_rev6;
15953 rfseq_init_gain = rfseqA_init_gain_rev6;
15954 init_gaincode = initA_gaincode_rev6;
15955 clip1hi_gaincode = clip1hiA_gaincode_rev6;
15956 clip1md_gaincode = clip1mdA_gaincode_rev6;
15957 clip1lo_gaincode = clip1loA_gaincode_rev6;
15958 crsmin_th = crsminA_th_rev6;
15959 crsminl_th = crsminlA_th_rev6;
15960 if ((pi->pubpi.radiorev == 11) &&
15961 (CHSPEC_IS40(pi->radio_chanspec) == 0))
15962 crsminu_th = crsminuA_th_rev6_224B0;
15963 else
15964 crsminu_th = crsminuA_th_rev6;
15965
15966 nbclip_th = nbclipA_th_rev6;
15967 rssi_gain = rssiA_gain_rev6;
15968 } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
15969 lna1_gain_db = lna1A_gain_db_rev5;
15970 lna2_gain_db = lna2A_gain_db_rev5;
15971 tia_gain_db = tiaA_gain_db_rev5;
15972 tia_gainbits = tiaA_gainbits_rev5;
15973 rfseq_init_gain = rfseqA_init_gain_rev5;
15974 init_gaincode = initA_gaincode_rev5;
15975 clip1hi_gaincode = clip1hiA_gaincode_rev5;
15976 clip1md_gaincode = clip1mdA_gaincode_rev5;
15977 clip1lo_gaincode = clip1loA_gaincode_rev5;
15978 crsmin_th = crsminA_th_rev5;
15979 crsminl_th = crsminlA_th_rev5;
15980 crsminu_th = crsminuA_th_rev5;
15981 nbclip_th = nbclipA_th_rev5;
15982 rssi_gain = rssiA_gain_rev5;
15983 } else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
15984 lna1_gain_db = lna1A_gain_db_rev4;
15985 lna2_gain_db = lna2A_gain_db_rev4;
15986 tia_gain_db = tiaA_gain_db_rev4;
15987 tia_gainbits = tiaA_gainbits_rev4;
15988 if (pi->sh->boardflags & BFL_EXTLNA_5GHz) {
15989
15990 rfseq_init_gain =
15991 rfseqA_init_gain_rev4_elna;
15992 init_gaincode =
15993 initA_gaincode_rev4_elna;
15994 } else {
15995 rfseq_init_gain = rfseqA_init_gain_rev4;
15996 init_gaincode = initA_gaincode_rev4;
15997 }
15998 clip1hi_gaincode = clip1hiA_gaincode_rev4;
15999 clip1md_gaincode = clip1mdA_gaincode_rev4;
16000 clip1lo_gaincode = clip1loA_gaincode_rev4;
16001 crsmin_th = crsminA_th_rev4;
16002 crsminl_th = crsminlA_th_rev4;
16003 crsminu_th = crsminuA_th_rev4;
16004 nbclip_th = nbclipA_th_rev4;
16005 rssi_gain = rssi_gain_default;
16006 } else {
16007 lna1_gain_db = lna1A_gain_db;
16008 lna2_gain_db = lna2A_gain_db;
16009 tia_gain_db = tiaA_gain_db;
16010 tia_gainbits = tiaA_gainbits;
16011 rfseq_init_gain = rfseqA_init_gain;
16012 init_gaincode = initA_gaincode;
16013 clip1hi_gaincode = clip1hiA_gaincode;
16014 clip1md_gaincode = clip1mdA_gaincode;
16015 clip1lo_gaincode = clip1loA_gaincode;
16016 crsmin_th = crsminA_th;
16017 crsminl_th = crsminlA_th;
16018 crsminu_th = crsminuA_th;
16019 nbclip_th = nbclipA_th;
16020 rssi_gain = rssi_gain_default;
16021 }
16022 w1clip_th = w1clipA_th;
16023 }
16024
16025 write_radio_reg(pi,
16026 (RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
16027 RADIO_2056_RX0), 0x17);
16028 write_radio_reg(pi,
16029 (RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
16030 RADIO_2056_RX1), 0x17);
16031
16032 write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX0),
16033 0xf0);
16034 write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX1),
16035 0xf0);
16036
16037 write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX0),
16038 0x0);
16039 write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX1),
16040 0x0);
16041
16042 write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX0),
16043 rssi_gain);
16044 write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX1),
16045 rssi_gain);
16046
16047 write_radio_reg(pi,
16048 (RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
16049 RADIO_2056_RX0), 0x17);
16050 write_radio_reg(pi,
16051 (RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
16052 RADIO_2056_RX1), 0x17);
16053
16054 write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX0),
16055 0xFF);
16056 write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX1),
16057 0xFF);
16058
16059 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8,
16060 8, lna1_gain_db);
16061 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8,
16062 8, lna1_gain_db);
16063
16064 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
16065 8, lna2_gain_db);
16066 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
16067 8, lna2_gain_db);
16068
16069 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20,
16070 8, tia_gain_db);
16071 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20,
16072 8, tia_gain_db);
16073
16074 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20,
16075 8, tia_gainbits);
16076 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20,
16077 8, tia_gainbits);
16078
16079 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 6, 0x40,
16080 8, &lpf_gain_db);
16081 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 6, 0x40,
16082 8, &lpf_gain_db);
16083 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 6, 0x40,
16084 8, &lpf_gainbits);
16085 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 6, 0x40,
16086 8, &lpf_gainbits);
16087
16088 write_phy_reg(pi, 0x20, init_gaincode);
16089 write_phy_reg(pi, 0x2a7, init_gaincode);
16090
16091 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
16092 pi->pubpi.phy_corenum, 0x106, 16,
16093 rfseq_init_gain);
16094
16095 write_phy_reg(pi, 0x22, clip1hi_gaincode);
16096 write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
16097
16098 write_phy_reg(pi, 0x24, clip1md_gaincode);
16099 write_phy_reg(pi, 0x2ab, clip1md_gaincode);
16100
16101 write_phy_reg(pi, 0x37, clip1lo_gaincode);
16102 write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
16103
16104 mod_phy_reg(pi, 0x27d, (0xff << 0), (crsmin_th << 0));
16105 mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
16106 mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
16107
16108 write_phy_reg(pi, 0x2b, nbclip_th);
16109 write_phy_reg(pi, 0x41, nbclip_th);
16110
16111 mod_phy_reg(pi, 0x27, (0x3f << 0), (w1clip_th << 0));
16112 mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1clip_th << 0));
16113
16114 write_phy_reg(pi, 0x150, 0x809c);
16115
16116 } else {
16117
16118 mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
16119 mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
16120
16121 write_phy_reg(pi, 0x2b, 0x84);
16122 write_phy_reg(pi, 0x41, 0x84);
16123
16124 if (CHSPEC_IS20(pi->radio_chanspec)) {
16125 write_phy_reg(pi, 0x6b, 0x2b);
16126 write_phy_reg(pi, 0x6c, 0x2b);
16127 write_phy_reg(pi, 0x6d, 0x9);
16128 write_phy_reg(pi, 0x6e, 0x9);
16129 }
16130
16131 w1th = NPHY_RSSICAL_W1_TARGET - 4;
16132 mod_phy_reg(pi, 0x27, (0x3f << 0), (w1th << 0));
16133 mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1th << 0));
16134
16135 if (CHSPEC_IS20(pi->radio_chanspec)) {
16136 mod_phy_reg(pi, 0x1c, (0x1f << 0), (0x1 << 0));
16137 mod_phy_reg(pi, 0x32, (0x1f << 0), (0x1 << 0));
16138
16139 mod_phy_reg(pi, 0x1d, (0x1f << 0), (0x1 << 0));
16140 mod_phy_reg(pi, 0x33, (0x1f << 0), (0x1 << 0));
16141 }
16142
16143 write_phy_reg(pi, 0x150, 0x809c);
16144
16145 if (pi->nphy_gain_boost)
16146 if ((CHSPEC_IS2G(pi->radio_chanspec)) &&
16147 (CHSPEC_IS40(pi->radio_chanspec)))
16148 hpf_code = 4;
16149 else
16150 hpf_code = 5;
16151 else if (CHSPEC_IS40(pi->radio_chanspec))
16152 hpf_code = 6;
16153 else
16154 hpf_code = 7;
16155
16156 mod_phy_reg(pi, 0x20, (0x1f << 7), (hpf_code << 7));
16157 mod_phy_reg(pi, 0x36, (0x1f << 7), (hpf_code << 7));
16158
16159 for (ctr = 0; ctr < 4; ctr++)
16160 regval[ctr] = (hpf_code << 8) | 0x7c;
16161 wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
16162
16163 wlc_phy_adjust_lnagaintbl_nphy(pi);
16164
16165 if (pi->nphy_elna_gain_config) {
16166 regval[0] = 0;
16167 regval[1] = 1;
16168 regval[2] = 1;
16169 regval[3] = 1;
16170 wlc_phy_table_write_nphy(pi, 2, 4, 8, 16, regval);
16171 wlc_phy_table_write_nphy(pi, 3, 4, 8, 16, regval);
16172
16173 for (ctr = 0; ctr < 4; ctr++)
16174 regval[ctr] = (hpf_code << 8) | 0x74;
16175 wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
16176 }
16177
16178 if (NREV_IS(pi->pubpi.phy_rev, 2)) {
16179 for (ctr = 0; ctr < 21; ctr++)
16180 regval[ctr] = 3 * ctr;
16181 wlc_phy_table_write_nphy(pi, 0, 21, 32, 16, regval);
16182 wlc_phy_table_write_nphy(pi, 1, 21, 32, 16, regval);
16183
16184 for (ctr = 0; ctr < 21; ctr++)
16185 regval[ctr] = (u16) ctr;
16186 wlc_phy_table_write_nphy(pi, 2, 21, 32, 16, regval);
16187 wlc_phy_table_write_nphy(pi, 3, 21, 32, 16, regval);
16188 }
16189
16190 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_UPDATEGAINU,
16191 rfseq_updategainu_events,
16192 rfseq_updategainu_dlys,
16193 sizeof(rfseq_updategainu_events) /
16194 sizeof(rfseq_updategainu_events[0]));
16195
16196 mod_phy_reg(pi, 0x153, (0xff << 8), (90 << 8));
16197
16198 if (CHSPEC_IS2G(pi->radio_chanspec))
16199 mod_phy_reg(pi,
16200 (NPHY_TO_BPHY_OFF + BPHY_OPTIONAL_MODES),
16201 0x7f, 0x4);
16202 }
16203}
16204
16205static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
16206{
16207 u8 rfseq_rx2tx_events[] = {
16208 NPHY_RFSEQ_CMD_NOP,
16209 NPHY_RFSEQ_CMD_RXG_FBW,
16210 NPHY_RFSEQ_CMD_TR_SWITCH,
16211 NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
16212 NPHY_RFSEQ_CMD_RXPD_TXPD,
16213 NPHY_RFSEQ_CMD_TX_GAIN,
16214 NPHY_RFSEQ_CMD_EXT_PA
16215 };
16216 u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
16217 u8 rfseq_tx2rx_events[] = {
16218 NPHY_RFSEQ_CMD_NOP,
16219 NPHY_RFSEQ_CMD_EXT_PA,
16220 NPHY_RFSEQ_CMD_TX_GAIN,
16221 NPHY_RFSEQ_CMD_RXPD_TXPD,
16222 NPHY_RFSEQ_CMD_TR_SWITCH,
16223 NPHY_RFSEQ_CMD_RXG_FBW,
16224 NPHY_RFSEQ_CMD_CLR_HIQ_DIS
16225 };
16226 u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
16227 u8 rfseq_tx2rx_events_rev3[] = {
16228 NPHY_REV3_RFSEQ_CMD_EXT_PA,
16229 NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
16230 NPHY_REV3_RFSEQ_CMD_TX_GAIN,
16231 NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
16232 NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
16233 NPHY_REV3_RFSEQ_CMD_RXG_FBW,
16234 NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
16235 NPHY_REV3_RFSEQ_CMD_END
16236 };
16237 u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
16238 u8 rfseq_rx2tx_events_rev3[] = {
16239 NPHY_REV3_RFSEQ_CMD_NOP,
16240 NPHY_REV3_RFSEQ_CMD_RXG_FBW,
16241 NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
16242 NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
16243 NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
16244 NPHY_REV3_RFSEQ_CMD_TX_GAIN,
16245 NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
16246 NPHY_REV3_RFSEQ_CMD_EXT_PA,
16247 NPHY_REV3_RFSEQ_CMD_END
16248 };
16249 u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
16250
16251 u8 rfseq_rx2tx_events_rev3_ipa[] = {
16252 NPHY_REV3_RFSEQ_CMD_NOP,
16253 NPHY_REV3_RFSEQ_CMD_RXG_FBW,
16254 NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
16255 NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
16256 NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
16257 NPHY_REV3_RFSEQ_CMD_TX_GAIN,
16258 NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS,
16259 NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
16260 NPHY_REV3_RFSEQ_CMD_END
16261 };
16262 u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
16263 u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
16264
16265 s16 alpha0, alpha1, alpha2;
16266 s16 beta0, beta1, beta2;
16267 u32 leg_data_weights, ht_data_weights, nss1_data_weights,
16268 stbc_data_weights;
16269 u8 chan_freq_range = 0;
16270 u16 dac_control = 0x0002;
16271 u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 };
16272 u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 };
16273 u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
16274 u16 aux_adc_vmid_rev3[] = { 0xa2, 0xb4, 0xb4, 0x89 };
16275 u16 *aux_adc_vmid;
16276 u16 aux_adc_gain_rev7[] = { 0x02, 0x02, 0x02, 0x02 };
16277 u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
16278 u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
16279 u16 *aux_adc_gain;
16280 u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
16281 u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
16282 s32 min_nvar_val = 0x18d;
16283 s32 min_nvar_offset_6mbps = 20;
16284 u8 pdetrange;
16285 u8 triso;
16286 u16 regval;
16287 u16 afectrl_adc_ctrl1_rev7 = 0x20;
16288 u16 afectrl_adc_ctrl2_rev7 = 0x0;
16289 u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77;
16290 u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77;
16291 u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77;
16292 u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
16293 u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
16294 u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
16295 u16 ipalvlshift_3p3_war_en = 0;
16296 u16 rccal_bcap_val, rccal_scap_val;
16297 u16 rccal_tx20_11b_bcap = 0;
16298 u16 rccal_tx20_11b_scap = 0;
16299 u16 rccal_tx20_11n_bcap = 0;
16300 u16 rccal_tx20_11n_scap = 0;
16301 u16 rccal_tx40_11n_bcap = 0;
16302 u16 rccal_tx40_11n_scap = 0;
16303 u16 rx2tx_lpf_rc_lut_tx20_11b = 0;
16304 u16 rx2tx_lpf_rc_lut_tx20_11n = 0;
16305 u16 rx2tx_lpf_rc_lut_tx40_11n = 0;
16306 u16 tx_lpf_bw_ofdm_20mhz = 0;
16307 u16 tx_lpf_bw_ofdm_40mhz = 0;
16308 u16 tx_lpf_bw_11b = 0;
16309 u16 ipa2g_mainbias, ipa2g_casconv, ipa2g_biasfilt;
16310 u16 txgm_idac_bleed = 0;
16311 bool rccal_ovrd = false;
16312 u16 freq;
16313 int coreNum;
16314
16315 if (CHSPEC_IS5G(pi->radio_chanspec))
16316 wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0);
16317 else
16318 wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1);
16319
16320 if (pi->phyhang_avoid)
16321 wlc_phy_stay_in_carriersearch_nphy(pi, true);
16322
16323 or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2);
16324
16325 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
16326
16327 if (NREV_IS(pi->pubpi.phy_rev, 7)) {
16328 mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4));
16329
16330 mod_phy_reg(pi, 0x160, (0x7f << 0), (32 << 0));
16331 mod_phy_reg(pi, 0x160, (0x7f << 8), (39 << 8));
16332 mod_phy_reg(pi, 0x161, (0x7f << 0), (46 << 0));
16333 mod_phy_reg(pi, 0x161, (0x7f << 8), (51 << 8));
16334 mod_phy_reg(pi, 0x162, (0x7f << 0), (55 << 0));
16335 mod_phy_reg(pi, 0x162, (0x7f << 8), (58 << 8));
16336 mod_phy_reg(pi, 0x163, (0x7f << 0), (60 << 0));
16337 mod_phy_reg(pi, 0x163, (0x7f << 8), (62 << 8));
16338 mod_phy_reg(pi, 0x164, (0x7f << 0), (62 << 0));
16339 mod_phy_reg(pi, 0x164, (0x7f << 8), (63 << 8));
16340 mod_phy_reg(pi, 0x165, (0x7f << 0), (63 << 0));
16341 mod_phy_reg(pi, 0x165, (0x7f << 8), (64 << 8));
16342 mod_phy_reg(pi, 0x166, (0x7f << 0), (64 << 0));
16343 mod_phy_reg(pi, 0x166, (0x7f << 8), (64 << 8));
16344 mod_phy_reg(pi, 0x167, (0x7f << 0), (64 << 0));
16345 mod_phy_reg(pi, 0x167, (0x7f << 8), (64 << 8));
16346 }
16347
16348 if (NREV_LE(pi->pubpi.phy_rev, 8)) {
16349 write_phy_reg(pi, 0x23f, 0x1b0);
16350 write_phy_reg(pi, 0x240, 0x1b0);
16351 }
16352
16353 if (NREV_GE(pi->pubpi.phy_rev, 8))
16354 mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0));
16355
16356 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
16357 &dac_control);
16358 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
16359 &dac_control);
16360
16361 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
16362 1, 0, 32, &leg_data_weights);
16363 leg_data_weights = leg_data_weights & 0xffffff;
16364 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
16365 1, 0, 32, &leg_data_weights);
16366
16367 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
16368 2, 0x15e, 16,
16369 rfseq_rx2tx_dacbufpu_rev7);
16370 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16,
16371 rfseq_rx2tx_dacbufpu_rev7);
16372
16373 if (PHY_IPA(pi))
16374 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
16375 rfseq_rx2tx_events_rev3_ipa,
16376 rfseq_rx2tx_dlys_rev3_ipa,
16377 sizeof
16378 (rfseq_rx2tx_events_rev3_ipa) /
16379 sizeof
16380 (rfseq_rx2tx_events_rev3_ipa
16381 [0]));
16382
16383 mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14));
16384 mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14));
16385
16386 tx_lpf_bw_ofdm_20mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x154);
16387 tx_lpf_bw_ofdm_40mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x159);
16388 tx_lpf_bw_11b = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x152);
16389
16390 if (PHY_IPA(pi)) {
16391
16392 if (((pi->pubpi.radiorev == 5)
16393 && (CHSPEC_IS40(pi->radio_chanspec) == 1))
16394 || (pi->pubpi.radiorev == 7)
16395 || (pi->pubpi.radiorev == 8)) {
16396
16397 rccal_bcap_val =
16398 read_radio_reg(
16399 pi,
16400 RADIO_2057_RCCAL_BCAP_VAL);
16401 rccal_scap_val =
16402 read_radio_reg(
16403 pi,
16404 RADIO_2057_RCCAL_SCAP_VAL);
16405
16406 rccal_tx20_11b_bcap = rccal_bcap_val;
16407 rccal_tx20_11b_scap = rccal_scap_val;
16408
16409 if ((pi->pubpi.radiorev == 5) &&
16410 (CHSPEC_IS40(pi->radio_chanspec) == 1)) {
16411
16412 rccal_tx20_11n_bcap = rccal_bcap_val;
16413 rccal_tx20_11n_scap = rccal_scap_val;
16414 rccal_tx40_11n_bcap = 0xc;
16415 rccal_tx40_11n_scap = 0xc;
16416
16417 rccal_ovrd = true;
16418
16419 } else if ((pi->pubpi.radiorev == 7)
16420 || (pi->pubpi.radiorev == 8)) {
16421
16422 tx_lpf_bw_ofdm_20mhz = 4;
16423 tx_lpf_bw_11b = 1;
16424
16425 if (CHSPEC_IS2G(pi->radio_chanspec)) {
16426 rccal_tx20_11n_bcap = 0xc;
16427 rccal_tx20_11n_scap = 0xc;
16428 rccal_tx40_11n_bcap = 0xa;
16429 rccal_tx40_11n_scap = 0xa;
16430 } else {
16431 rccal_tx20_11n_bcap = 0x14;
16432 rccal_tx20_11n_scap = 0x14;
16433 rccal_tx40_11n_bcap = 0xf;
16434 rccal_tx40_11n_scap = 0xf;
16435 }
16436
16437 rccal_ovrd = true;
16438 }
16439 }
16440
16441 } else {
16442
16443 if (pi->pubpi.radiorev == 5) {
16444
16445 tx_lpf_bw_ofdm_20mhz = 1;
16446 tx_lpf_bw_ofdm_40mhz = 3;
16447
16448 rccal_bcap_val =
16449 read_radio_reg(
16450 pi,
16451 RADIO_2057_RCCAL_BCAP_VAL);
16452 rccal_scap_val =
16453 read_radio_reg(
16454 pi,
16455 RADIO_2057_RCCAL_SCAP_VAL);
16456
16457 rccal_tx20_11b_bcap = rccal_bcap_val;
16458 rccal_tx20_11b_scap = rccal_scap_val;
16459
16460 rccal_tx20_11n_bcap = 0x13;
16461 rccal_tx20_11n_scap = 0x11;
16462 rccal_tx40_11n_bcap = 0x13;
16463 rccal_tx40_11n_scap = 0x11;
16464
16465 rccal_ovrd = true;
16466 }
16467 }
16468
16469 if (rccal_ovrd) {
16470
16471 rx2tx_lpf_rc_lut_tx20_11b =
16472 (rccal_tx20_11b_bcap << 8) |
16473 (rccal_tx20_11b_scap << 3) |
16474 tx_lpf_bw_11b;
16475 rx2tx_lpf_rc_lut_tx20_11n =
16476 (rccal_tx20_11n_bcap << 8) |
16477 (rccal_tx20_11n_scap << 3) |
16478 tx_lpf_bw_ofdm_20mhz;
16479 rx2tx_lpf_rc_lut_tx40_11n =
16480 (rccal_tx40_11n_bcap << 8) |
16481 (rccal_tx40_11n_scap << 3) |
16482 tx_lpf_bw_ofdm_40mhz;
16483
16484 for (coreNum = 0; coreNum <= 1; coreNum++) {
16485 wlc_phy_table_write_nphy(
16486 pi, NPHY_TBL_ID_RFSEQ,
16487 1,
16488 0x152 + coreNum * 0x10,
16489 16,
16490 &rx2tx_lpf_rc_lut_tx20_11b);
16491 wlc_phy_table_write_nphy(
16492 pi, NPHY_TBL_ID_RFSEQ,
16493 1,
16494 0x153 + coreNum * 0x10,
16495 16,
16496 &rx2tx_lpf_rc_lut_tx20_11n);
16497 wlc_phy_table_write_nphy(
16498 pi, NPHY_TBL_ID_RFSEQ,
16499 1,
16500 0x154 + coreNum * 0x10,
16501 16,
16502 &rx2tx_lpf_rc_lut_tx20_11n);
16503 wlc_phy_table_write_nphy(
16504 pi, NPHY_TBL_ID_RFSEQ,
16505 1,
16506 0x155 + coreNum * 0x10,
16507 16,
16508 &rx2tx_lpf_rc_lut_tx40_11n);
16509 wlc_phy_table_write_nphy(
16510 pi, NPHY_TBL_ID_RFSEQ,
16511 1,
16512 0x156 + coreNum * 0x10,
16513 16,
16514 &rx2tx_lpf_rc_lut_tx40_11n);
16515 wlc_phy_table_write_nphy(
16516 pi, NPHY_TBL_ID_RFSEQ,
16517 1,
16518 0x157 + coreNum * 0x10,
16519 16,
16520 &rx2tx_lpf_rc_lut_tx40_11n);
16521 wlc_phy_table_write_nphy(
16522 pi, NPHY_TBL_ID_RFSEQ,
16523 1,
16524 0x158 + coreNum * 0x10,
16525 16,
16526 &rx2tx_lpf_rc_lut_tx40_11n);
16527 wlc_phy_table_write_nphy(
16528 pi, NPHY_TBL_ID_RFSEQ,
16529 1,
16530 0x159 + coreNum * 0x10,
16531 16,
16532 &rx2tx_lpf_rc_lut_tx40_11n);
16533 }
16534
16535 wlc_phy_rfctrl_override_nphy_rev7(
16536 pi, (0x1 << 4),
16537 1, 0x3, 0,
16538 NPHY_REV7_RFCTRLOVERRIDE_ID2);
16539 }
16540
16541 write_phy_reg(pi, 0x32f, 0x3);
16542
16543 if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6))
16544 wlc_phy_rfctrl_override_nphy_rev7(
16545 pi, (0x1 << 2),
16546 1, 0x3, 0,
16547 NPHY_REV7_RFCTRLOVERRIDE_ID0);
16548
16549 if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) ||
16550 (pi->pubpi.radiorev == 6)) {
16551 if ((pi->sh->sromrev >= 8)
16552 && (pi->sh->boardflags2 & BFL2_IPALVLSHIFT_3P3))
16553 ipalvlshift_3p3_war_en = 1;
16554
16555 if (ipalvlshift_3p3_war_en) {
16556 write_radio_reg(pi, RADIO_2057_GPAIO_CONFIG,
16557 0x5);
16558 write_radio_reg(pi, RADIO_2057_GPAIO_SEL1,
16559 0x30);
16560 write_radio_reg(pi, RADIO_2057_GPAIO_SEL0, 0x0);
16561 or_radio_reg(pi,
16562 RADIO_2057_RXTXBIAS_CONFIG_CORE0,
16563 0x1);
16564 or_radio_reg(pi,
16565 RADIO_2057_RXTXBIAS_CONFIG_CORE1,
16566 0x1);
16567
16568 ipa2g_mainbias = 0x1f;
16569
16570 ipa2g_casconv = 0x6f;
16571
16572 ipa2g_biasfilt = 0xaa;
16573 } else {
16574
16575 ipa2g_mainbias = 0x2b;
16576
16577 ipa2g_casconv = 0x7f;
16578
16579 ipa2g_biasfilt = 0xee;
16580 }
16581
16582 if (CHSPEC_IS2G(pi->radio_chanspec)) {
16583 for (coreNum = 0; coreNum <= 1; coreNum++) {
16584 WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
16585 coreNum, IPA2G_IMAIN,
16586 ipa2g_mainbias);
16587 WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
16588 coreNum, IPA2G_CASCONV,
16589 ipa2g_casconv);
16590 WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
16591 coreNum,
16592 IPA2G_BIAS_FILTER,
16593 ipa2g_biasfilt);
16594 }
16595 }
16596 }
16597
16598 if (PHY_IPA(pi)) {
16599 if (CHSPEC_IS2G(pi->radio_chanspec)) {
16600 if ((pi->pubpi.radiorev == 3)
16601 || (pi->pubpi.radiorev == 4)
16602 || (pi->pubpi.radiorev == 6))
16603 txgm_idac_bleed = 0x7f;
16604
16605 for (coreNum = 0; coreNum <= 1; coreNum++) {
16606 if (txgm_idac_bleed != 0)
16607 WRITE_RADIO_REG4(
16608 pi, RADIO_2057,
16609 CORE, coreNum,
16610 TXGM_IDAC_BLEED,
16611 txgm_idac_bleed);
16612 }
16613
16614 if (pi->pubpi.radiorev == 5) {
16615
16616 for (coreNum = 0; coreNum <= 1;
16617 coreNum++) {
16618 WRITE_RADIO_REG4(pi, RADIO_2057,
16619 CORE, coreNum,
16620 IPA2G_CASCONV,
16621 0x13);
16622 WRITE_RADIO_REG4(pi, RADIO_2057,
16623 CORE, coreNum,
16624 IPA2G_IMAIN,
16625 0x1f);
16626 WRITE_RADIO_REG4(
16627 pi, RADIO_2057,
16628 CORE, coreNum,
16629 IPA2G_BIAS_FILTER,
16630 0xee);
16631 WRITE_RADIO_REG4(pi, RADIO_2057,
16632 CORE, coreNum,
16633 PAD2G_IDACS,
16634 0x8a);
16635 WRITE_RADIO_REG4(
16636 pi, RADIO_2057,
16637 CORE, coreNum,
16638 PAD_BIAS_FILTER_BWS,
16639 0x3e);
16640 }
16641
16642 } else if ((pi->pubpi.radiorev == 7)
16643 || (pi->pubpi.radiorev == 8)) {
16644
16645 if (CHSPEC_IS40(pi->radio_chanspec) ==
16646 0) {
16647 WRITE_RADIO_REG4(pi, RADIO_2057,
16648 CORE, 0,
16649 IPA2G_IMAIN,
16650 0x14);
16651 WRITE_RADIO_REG4(pi, RADIO_2057,
16652 CORE, 1,
16653 IPA2G_IMAIN,
16654 0x12);
16655 } else {
16656 WRITE_RADIO_REG4(pi, RADIO_2057,
16657 CORE, 0,
16658 IPA2G_IMAIN,
16659 0x16);
16660 WRITE_RADIO_REG4(pi, RADIO_2057,
16661 CORE, 1,
16662 IPA2G_IMAIN,
16663 0x16);
16664 }
16665 }
16666
16667 } else {
16668 freq = CHAN5G_FREQ(CHSPEC_CHANNEL(
16669 pi->radio_chanspec));
16670 if (((freq >= 5180) && (freq <= 5230))
16671 || ((freq >= 5745) && (freq <= 5805))) {
16672 WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
16673 0, IPA5G_BIAS_FILTER,
16674 0xff);
16675 WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
16676 1, IPA5G_BIAS_FILTER,
16677 0xff);
16678 }
16679 }
16680 } else {
16681
16682 if (pi->pubpi.radiorev != 5) {
16683 for (coreNum = 0; coreNum <= 1; coreNum++) {
16684 WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
16685 coreNum,
16686 TXMIX2G_TUNE_BOOST_PU,
16687 0x61);
16688 WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
16689 coreNum,
16690 TXGM_IDAC_BLEED, 0x70);
16691 }
16692 }
16693 }
16694
16695 if (pi->pubpi.radiorev == 4) {
16696 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
16697 0x05, 16,
16698 &afectrl_adc_ctrl1_rev7);
16699 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
16700 0x15, 16,
16701 &afectrl_adc_ctrl1_rev7);
16702
16703 for (coreNum = 0; coreNum <= 1; coreNum++) {
16704 WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
16705 AFE_VCM_CAL_MASTER, 0x0);
16706 WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
16707 AFE_SET_VCM_I, 0x3f);
16708 WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
16709 AFE_SET_VCM_Q, 0x3f);
16710 }
16711 } else {
16712 mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
16713 mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
16714 mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
16715 mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
16716
16717 mod_phy_reg(pi, 0xa6, (0x1 << 0), 0);
16718 mod_phy_reg(pi, 0x8f, (0x1 << 0), (0x1 << 0));
16719 mod_phy_reg(pi, 0xa7, (0x1 << 0), 0);
16720 mod_phy_reg(pi, 0xa5, (0x1 << 0), (0x1 << 0));
16721
16722 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
16723 0x05, 16,
16724 &afectrl_adc_ctrl2_rev7);
16725 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
16726 0x15, 16,
16727 &afectrl_adc_ctrl2_rev7);
16728
16729 mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
16730 mod_phy_reg(pi, 0x8f, (0x1 << 2), 0);
16731 mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
16732 mod_phy_reg(pi, 0xa5, (0x1 << 2), 0);
16733 }
16734
16735 write_phy_reg(pi, 0x6a, 0x2);
16736
16737 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 256, 32,
16738 &min_nvar_offset_6mbps);
16739
16740 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x138, 16,
16741 &rfseq_pktgn_lpf_hpc_rev7);
16742
16743 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x141, 16,
16744 &rfseq_pktgn_lpf_h_hpc_rev7);
16745
16746 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 3, 0x133, 16,
16747 &rfseq_htpktgn_lpf_hpc_rev7);
16748
16749 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x146, 16,
16750 &rfseq_cckpktgn_lpf_hpc_rev7);
16751
16752 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x123, 16,
16753 &rfseq_tx2rx_lpf_h_hpc_rev7);
16754
16755 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x12A, 16,
16756 &rfseq_rx2tx_lpf_h_hpc_rev7);
16757
16758 if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
16759 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
16760 32, &min_nvar_val);
16761 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
16762 127, 32, &min_nvar_val);
16763 } else {
16764 min_nvar_val = noise_var_tbl_rev7[3];
16765 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
16766 32, &min_nvar_val);
16767
16768 min_nvar_val = noise_var_tbl_rev7[127];
16769 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
16770 127, 32, &min_nvar_val);
16771 }
16772
16773 wlc_phy_workarounds_nphy_gainctrl(pi);
16774
16775 pdetrange =
16776 (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
16777 pdetrange : pi->srom_fem2g.pdetrange;
16778
16779 if (pdetrange == 0) {
16780 chan_freq_range =
16781 wlc_phy_get_chan_freq_range_nphy(pi, 0);
16782 if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
16783 aux_adc_vmid_rev7_core0[3] = 0x70;
16784 aux_adc_vmid_rev7_core1[3] = 0x70;
16785 aux_adc_gain_rev7[3] = 2;
16786 } else {
16787 aux_adc_vmid_rev7_core0[3] = 0x80;
16788 aux_adc_vmid_rev7_core1[3] = 0x80;
16789 aux_adc_gain_rev7[3] = 3;
16790 }
16791 } else if (pdetrange == 1) {
16792 if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
16793 aux_adc_vmid_rev7_core0[3] = 0x7c;
16794 aux_adc_vmid_rev7_core1[3] = 0x7c;
16795 aux_adc_gain_rev7[3] = 2;
16796 } else {
16797 aux_adc_vmid_rev7_core0[3] = 0x8c;
16798 aux_adc_vmid_rev7_core1[3] = 0x8c;
16799 aux_adc_gain_rev7[3] = 1;
16800 }
16801 } else if (pdetrange == 2) {
16802 if (pi->pubpi.radioid == BCM2057_ID) {
16803 if ((pi->pubpi.radiorev == 5)
16804 || (pi->pubpi.radiorev == 7)
16805 || (pi->pubpi.radiorev == 8)) {
16806 if (chan_freq_range ==
16807 WL_CHAN_FREQ_RANGE_2G) {
16808 aux_adc_vmid_rev7_core0[3] =
16809 0x8c;
16810 aux_adc_vmid_rev7_core1[3] =
16811 0x8c;
16812 aux_adc_gain_rev7[3] = 0;
16813 } else {
16814 aux_adc_vmid_rev7_core0[3] =
16815 0x96;
16816 aux_adc_vmid_rev7_core1[3] =
16817 0x96;
16818 aux_adc_gain_rev7[3] = 0;
16819 }
16820 }
16821 }
16822
16823 } else if (pdetrange == 3) {
16824 if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) {
16825 aux_adc_vmid_rev7_core0[3] = 0x89;
16826 aux_adc_vmid_rev7_core1[3] = 0x89;
16827 aux_adc_gain_rev7[3] = 0;
16828 }
16829
16830 } else if (pdetrange == 5) {
16831
16832 if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
16833 aux_adc_vmid_rev7_core0[3] = 0x80;
16834 aux_adc_vmid_rev7_core1[3] = 0x80;
16835 aux_adc_gain_rev7[3] = 3;
16836 } else {
16837 aux_adc_vmid_rev7_core0[3] = 0x70;
16838 aux_adc_vmid_rev7_core1[3] = 0x70;
16839 aux_adc_gain_rev7[3] = 2;
16840 }
16841 }
16842
16843 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x08, 16,
16844 &aux_adc_vmid_rev7_core0);
16845 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x18, 16,
16846 &aux_adc_vmid_rev7_core1);
16847 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x0c, 16,
16848 &aux_adc_gain_rev7);
16849 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16,
16850 &aux_adc_gain_rev7);
16851
16852 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
16853
16854 write_phy_reg(pi, 0x23f, 0x1f8);
16855 write_phy_reg(pi, 0x240, 0x1f8);
16856
16857 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
16858 1, 0, 32, &leg_data_weights);
16859 leg_data_weights = leg_data_weights & 0xffffff;
16860 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
16861 1, 0, 32, &leg_data_weights);
16862
16863 alpha0 = 293;
16864 alpha1 = 435;
16865 alpha2 = 261;
16866 beta0 = 366;
16867 beta1 = 205;
16868 beta2 = 32;
16869 write_phy_reg(pi, 0x145, alpha0);
16870 write_phy_reg(pi, 0x146, alpha1);
16871 write_phy_reg(pi, 0x147, alpha2);
16872 write_phy_reg(pi, 0x148, beta0);
16873 write_phy_reg(pi, 0x149, beta1);
16874 write_phy_reg(pi, 0x14a, beta2);
16875
16876 write_phy_reg(pi, 0x38, 0xC);
16877 write_phy_reg(pi, 0x2ae, 0xC);
16878
16879 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX,
16880 rfseq_tx2rx_events_rev3,
16881 rfseq_tx2rx_dlys_rev3,
16882 sizeof(rfseq_tx2rx_events_rev3) /
16883 sizeof(rfseq_tx2rx_events_rev3[0]));
16884
16885 if (PHY_IPA(pi))
16886 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
16887 rfseq_rx2tx_events_rev3_ipa,
16888 rfseq_rx2tx_dlys_rev3_ipa,
16889 sizeof
16890 (rfseq_rx2tx_events_rev3_ipa) /
16891 sizeof
16892 (rfseq_rx2tx_events_rev3_ipa
16893 [0]));
16894
16895 if ((pi->sh->hw_phyrxchain != 0x3) &&
16896 (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) {
16897
16898 if (PHY_IPA(pi)) {
16899 rfseq_rx2tx_dlys_rev3[5] = 59;
16900 rfseq_rx2tx_dlys_rev3[6] = 1;
16901 rfseq_rx2tx_events_rev3[7] =
16902 NPHY_REV3_RFSEQ_CMD_END;
16903 }
16904
16905 wlc_phy_set_rfseq_nphy(
16906 pi, NPHY_RFSEQ_RX2TX,
16907 rfseq_rx2tx_events_rev3,
16908 rfseq_rx2tx_dlys_rev3,
16909 sizeof(rfseq_rx2tx_events_rev3) /
16910 sizeof(rfseq_rx2tx_events_rev3[0]));
16911 }
16912
16913 if (CHSPEC_IS2G(pi->radio_chanspec))
16914 write_phy_reg(pi, 0x6a, 0x2);
16915 else
16916 write_phy_reg(pi, 0x6a, 0x9c40);
16917
16918 mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8));
16919
16920 if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
16921 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
16922 32, &min_nvar_val);
16923 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
16924 127, 32, &min_nvar_val);
16925 } else {
16926 min_nvar_val = noise_var_tbl_rev3[3];
16927 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
16928 32, &min_nvar_val);
16929
16930 min_nvar_val = noise_var_tbl_rev3[127];
16931 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
16932 127, 32, &min_nvar_val);
16933 }
16934
16935 wlc_phy_workarounds_nphy_gainctrl(pi);
16936
16937 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
16938 &dac_control);
16939 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
16940 &dac_control);
16941
16942 pdetrange =
16943 (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
16944 pdetrange : pi->srom_fem2g.pdetrange;
16945
16946 if (pdetrange == 0) {
16947 if (NREV_GE(pi->pubpi.phy_rev, 4)) {
16948 aux_adc_vmid = aux_adc_vmid_rev4;
16949 aux_adc_gain = aux_adc_gain_rev4;
16950 } else {
16951 aux_adc_vmid = aux_adc_vmid_rev3;
16952 aux_adc_gain = aux_adc_gain_rev3;
16953 }
16954 chan_freq_range =
16955 wlc_phy_get_chan_freq_range_nphy(pi, 0);
16956 if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
16957 switch (chan_freq_range) {
16958 case WL_CHAN_FREQ_RANGE_5GL:
16959 aux_adc_vmid[3] = 0x89;
16960 aux_adc_gain[3] = 0;
16961 break;
16962 case WL_CHAN_FREQ_RANGE_5GM:
16963 aux_adc_vmid[3] = 0x89;
16964 aux_adc_gain[3] = 0;
16965 break;
16966 case WL_CHAN_FREQ_RANGE_5GH:
16967 aux_adc_vmid[3] = 0x89;
16968 aux_adc_gain[3] = 0;
16969 break;
16970 default:
16971 break;
16972 }
16973 }
16974 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16975 0x08, 16, aux_adc_vmid);
16976 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16977 0x18, 16, aux_adc_vmid);
16978 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16979 0x0c, 16, aux_adc_gain);
16980 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16981 0x1c, 16, aux_adc_gain);
16982 } else if (pdetrange == 1) {
16983 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16984 0x08, 16, sk_adc_vmid);
16985 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16986 0x18, 16, sk_adc_vmid);
16987 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16988 0x0c, 16, sk_adc_gain);
16989 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16990 0x1c, 16, sk_adc_gain);
16991 } else if (pdetrange == 2) {
16992
16993 u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x74 };
16994 u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x04 };
16995
16996 if (NREV_GE(pi->pubpi.phy_rev, 6)) {
16997 chan_freq_range =
16998 wlc_phy_get_chan_freq_range_nphy(pi, 0);
16999 if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
17000 bcm_adc_vmid[3] = 0x8e;
17001 bcm_adc_gain[3] = 0x03;
17002 } else {
17003 bcm_adc_vmid[3] = 0x94;
17004 bcm_adc_gain[3] = 0x03;
17005 }
17006 } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
17007 bcm_adc_vmid[3] = 0x84;
17008 bcm_adc_gain[3] = 0x02;
17009 }
17010
17011 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
17012 0x08, 16, bcm_adc_vmid);
17013 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
17014 0x18, 16, bcm_adc_vmid);
17015 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
17016 0x0c, 16, bcm_adc_gain);
17017 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
17018 0x1c, 16, bcm_adc_gain);
17019 } else if (pdetrange == 3) {
17020 chan_freq_range =
17021 wlc_phy_get_chan_freq_range_nphy(pi, 0);
17022 if ((NREV_GE(pi->pubpi.phy_rev, 4))
17023 && (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) {
17024
17025 u16 auxadc_vmid[] = {
17026 0xa2, 0xb4, 0xb4, 0x270
17027 };
17028 u16 auxadc_gain[] = {
17029 0x02, 0x02, 0x02, 0x00
17030 };
17031
17032 wlc_phy_table_write_nphy(pi,
17033 NPHY_TBL_ID_AFECTRL, 4,
17034 0x08, 16, auxadc_vmid);
17035 wlc_phy_table_write_nphy(pi,
17036 NPHY_TBL_ID_AFECTRL, 4,
17037 0x18, 16, auxadc_vmid);
17038 wlc_phy_table_write_nphy(pi,
17039 NPHY_TBL_ID_AFECTRL, 4,
17040 0x0c, 16, auxadc_gain);
17041 wlc_phy_table_write_nphy(pi,
17042 NPHY_TBL_ID_AFECTRL, 4,
17043 0x1c, 16, auxadc_gain);
17044 }
17045 } else if ((pdetrange == 4) || (pdetrange == 5)) {
17046 u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x0 };
17047 u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x0 };
17048 u16 Vmid[2], Av[2];
17049
17050 chan_freq_range =
17051 wlc_phy_get_chan_freq_range_nphy(pi, 0);
17052 if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
17053 Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89;
17054 Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89;
17055 Av[0] = (pdetrange == 4) ? 2 : 0;
17056 Av[1] = (pdetrange == 4) ? 2 : 0;
17057 } else {
17058 Vmid[0] = (pdetrange == 4) ? 0x89 : 0x74;
17059 Vmid[1] = (pdetrange == 4) ? 0x8b : 0x70;
17060 Av[0] = (pdetrange == 4) ? 2 : 0;
17061 Av[1] = (pdetrange == 4) ? 2 : 0;
17062 }
17063
17064 bcm_adc_vmid[3] = Vmid[0];
17065 bcm_adc_gain[3] = Av[0];
17066 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
17067 0x08, 16, bcm_adc_vmid);
17068 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
17069 0x0c, 16, bcm_adc_gain);
17070
17071 bcm_adc_vmid[3] = Vmid[1];
17072 bcm_adc_gain[3] = Av[1];
17073 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
17074 0x18, 16, bcm_adc_vmid);
17075 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
17076 0x1c, 16, bcm_adc_gain);
17077 }
17078
17079 write_radio_reg(pi,
17080 (RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX0),
17081 0x0);
17082 write_radio_reg(pi,
17083 (RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX1),
17084 0x0);
17085
17086 write_radio_reg(pi,
17087 (RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX0),
17088 0x6);
17089 write_radio_reg(pi,
17090 (RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX1),
17091 0x6);
17092
17093 write_radio_reg(pi,
17094 (RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX0),
17095 0x7);
17096 write_radio_reg(pi,
17097 (RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX1),
17098 0x7);
17099
17100 write_radio_reg(pi,
17101 (RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX0),
17102 0x88);
17103 write_radio_reg(pi,
17104 (RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX1),
17105 0x88);
17106
17107 write_radio_reg(pi,
17108 (RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX0),
17109 0x0);
17110 write_radio_reg(pi,
17111 (RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX1),
17112 0x0);
17113
17114 write_radio_reg(pi,
17115 (RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX0),
17116 0x0);
17117 write_radio_reg(pi,
17118 (RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX1),
17119 0x0);
17120
17121 triso =
17122 (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
17123 triso : pi->srom_fem2g.triso;
17124 if (triso == 7) {
17125 wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
17126 wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
17127 }
17128
17129 wlc_phy_war_txchain_upd_nphy(pi, pi->sh->hw_phytxchain);
17130
17131 if (((pi->sh->boardflags2 & BFL2_APLL_WAR) &&
17132 (CHSPEC_IS5G(pi->radio_chanspec))) ||
17133 (((pi->sh->boardflags2 & BFL2_GPLL_WAR) ||
17134 (pi->sh->boardflags2 & BFL2_GPLL_WAR2)) &&
17135 (CHSPEC_IS2G(pi->radio_chanspec)))) {
17136 nss1_data_weights = 0x00088888;
17137 ht_data_weights = 0x00088888;
17138 stbc_data_weights = 0x00088888;
17139 } else {
17140 nss1_data_weights = 0x88888888;
17141 ht_data_weights = 0x88888888;
17142 stbc_data_weights = 0x88888888;
17143 }
17144 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
17145 1, 1, 32, &nss1_data_weights);
17146 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
17147 1, 2, 32, &ht_data_weights);
17148 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
17149 1, 3, 32, &stbc_data_weights);
17150
17151 if (NREV_IS(pi->pubpi.phy_rev, 4)) {
17152 if (CHSPEC_IS5G(pi->radio_chanspec)) {
17153 write_radio_reg(pi,
17154 RADIO_2056_TX_GMBB_IDAC |
17155 RADIO_2056_TX0, 0x70);
17156 write_radio_reg(pi,
17157 RADIO_2056_TX_GMBB_IDAC |
17158 RADIO_2056_TX1, 0x70);
17159 }
17160 }
17161
17162 if (!pi->edcrs_threshold_lock) {
17163 write_phy_reg(pi, 0x224, 0x3eb);
17164 write_phy_reg(pi, 0x225, 0x3eb);
17165 write_phy_reg(pi, 0x226, 0x341);
17166 write_phy_reg(pi, 0x227, 0x341);
17167 write_phy_reg(pi, 0x228, 0x42b);
17168 write_phy_reg(pi, 0x229, 0x42b);
17169 write_phy_reg(pi, 0x22a, 0x381);
17170 write_phy_reg(pi, 0x22b, 0x381);
17171 write_phy_reg(pi, 0x22c, 0x42b);
17172 write_phy_reg(pi, 0x22d, 0x42b);
17173 write_phy_reg(pi, 0x22e, 0x381);
17174 write_phy_reg(pi, 0x22f, 0x381);
17175 }
17176
17177 if (NREV_GE(pi->pubpi.phy_rev, 6)) {
17178
17179 if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK)
17180 wlapi_bmac_mhf(pi->sh->physhim, MHF4,
17181 MHF4_BPHY_TXCORE0,
17182 MHF4_BPHY_TXCORE0, BRCM_BAND_ALL);
17183 }
17184 } else {
17185
17186 if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD ||
17187 (pi->sh->boardtype == 0x8b)) {
17188 uint i;
17189 u8 war_dlys[] = { 1, 6, 6, 2, 4, 20, 1 };
17190 for (i = 0; i < ARRAY_SIZE(rfseq_rx2tx_dlys); i++)
17191 rfseq_rx2tx_dlys[i] = war_dlys[i];
17192 }
17193
17194 if (CHSPEC_IS5G(pi->radio_chanspec) && pi->phy_5g_pwrgain) {
17195 and_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0xf7);
17196 and_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0xf7);
17197 } else {
17198 or_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0x8);
17199 or_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0x8);
17200 }
17201
17202 regval = 0x000a;
17203 wlc_phy_table_write_nphy(pi, 8, 1, 0, 16, &regval);
17204 wlc_phy_table_write_nphy(pi, 8, 1, 0x10, 16, &regval);
17205
17206 if (NREV_LT(pi->pubpi.phy_rev, 3)) {
17207 regval = 0xcdaa;
17208 wlc_phy_table_write_nphy(pi, 8, 1, 0x02, 16, &regval);
17209 wlc_phy_table_write_nphy(pi, 8, 1, 0x12, 16, &regval);
17210 }
17211
17212 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
17213 regval = 0x0000;
17214 wlc_phy_table_write_nphy(pi, 8, 1, 0x08, 16, &regval);
17215 wlc_phy_table_write_nphy(pi, 8, 1, 0x18, 16, &regval);
17216
17217 regval = 0x7aab;
17218 wlc_phy_table_write_nphy(pi, 8, 1, 0x07, 16, &regval);
17219 wlc_phy_table_write_nphy(pi, 8, 1, 0x17, 16, &regval);
17220
17221 regval = 0x0800;
17222 wlc_phy_table_write_nphy(pi, 8, 1, 0x06, 16, &regval);
17223 wlc_phy_table_write_nphy(pi, 8, 1, 0x16, 16, &regval);
17224 }
17225
17226 write_phy_reg(pi, 0xf8, 0x02d8);
17227 write_phy_reg(pi, 0xf9, 0x0301);
17228 write_phy_reg(pi, 0xfa, 0x02d8);
17229 write_phy_reg(pi, 0xfb, 0x0301);
17230
17231 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events,
17232 rfseq_rx2tx_dlys,
17233 sizeof(rfseq_rx2tx_events) /
17234 sizeof(rfseq_rx2tx_events[0]));
17235
17236 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events,
17237 rfseq_tx2rx_dlys,
17238 sizeof(rfseq_tx2rx_events) /
17239 sizeof(rfseq_tx2rx_events[0]));
17240
17241 wlc_phy_workarounds_nphy_gainctrl(pi);
17242
17243 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
17244
17245 if (read_phy_reg(pi, 0xa0) & NPHY_MLenable)
17246 wlapi_bmac_mhf(pi->sh->physhim, MHF3,
17247 MHF3_NPHY_MLADV_WAR,
17248 MHF3_NPHY_MLADV_WAR,
17249 BRCM_BAND_ALL);
17250
17251 } else if (NREV_IS(pi->pubpi.phy_rev, 2)) {
17252 write_phy_reg(pi, 0x1e3, 0x0);
17253 write_phy_reg(pi, 0x1e4, 0x0);
17254 }
17255
17256 if (NREV_LT(pi->pubpi.phy_rev, 2))
17257 mod_phy_reg(pi, 0x90, (0x1 << 7), 0);
17258
17259 alpha0 = 293;
17260 alpha1 = 435;
17261 alpha2 = 261;
17262 beta0 = 366;
17263 beta1 = 205;
17264 beta2 = 32;
17265 write_phy_reg(pi, 0x145, alpha0);
17266 write_phy_reg(pi, 0x146, alpha1);
17267 write_phy_reg(pi, 0x147, alpha2);
17268 write_phy_reg(pi, 0x148, beta0);
17269 write_phy_reg(pi, 0x149, beta1);
17270 write_phy_reg(pi, 0x14a, beta2);
17271
17272 if (NREV_LT(pi->pubpi.phy_rev, 3)) {
17273 mod_phy_reg(pi, 0x142, (0xf << 12), 0);
17274
17275 write_phy_reg(pi, 0x192, 0xb5);
17276 write_phy_reg(pi, 0x193, 0xa4);
17277 write_phy_reg(pi, 0x194, 0x0);
17278 }
17279
17280 if (NREV_IS(pi->pubpi.phy_rev, 2))
17281 mod_phy_reg(pi, 0x221,
17282 NPHY_FORCESIG_DECODEGATEDCLKS,
17283 NPHY_FORCESIG_DECODEGATEDCLKS);
17284 }
17285
17286 if (pi->phyhang_avoid)
17287 wlc_phy_stay_in_carriersearch_nphy(pi, false);
17288}
17289
17290static void wlc_phy_extpa_set_tx_digi_filts_nphy(struct brcms_phy *pi)
17291{
17292 int j, type = 2;
17293 u16 addr_offset = 0x2c5;
17294
17295 for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
17296 write_phy_reg(pi, addr_offset + j,
17297 NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
17298}
17299
17300static void wlc_phy_clip_det_nphy(struct brcms_phy *pi, u8 write, u16 *vals)
17301{
17302
17303 if (write == 0) {
17304 vals[0] = read_phy_reg(pi, 0x2c);
17305 vals[1] = read_phy_reg(pi, 0x42);
17306 } else {
17307 write_phy_reg(pi, 0x2c, vals[0]);
17308 write_phy_reg(pi, 0x42, vals[1]);
17309 }
17310}
17311
17312static void wlc_phy_ipa_internal_tssi_setup_nphy(struct brcms_phy *pi)
17313{
17314 u8 core;
17315
17316 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
17317 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
17318 if (CHSPEC_IS2G(pi->radio_chanspec)) {
17319 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
17320 TX_SSI_MASTER, 0x5);
17321 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
17322 TX_SSI_MUX, 0xe);
17323
17324 if (pi->pubpi.radiorev != 5)
17325 WRITE_RADIO_REG3(pi, RADIO_2057, TX,
17326 core, TSSIA, 0);
17327
17328 if (!NREV_IS(pi->pubpi.phy_rev, 7))
17329 WRITE_RADIO_REG3(pi, RADIO_2057, TX,
17330 core, TSSIG, 0x1);
17331 else
17332 WRITE_RADIO_REG3(pi, RADIO_2057, TX,
17333 core, TSSIG, 0x31);
17334 } else {
17335 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
17336 TX_SSI_MASTER, 0x9);
17337 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
17338 TX_SSI_MUX, 0xc);
17339 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
17340 TSSIG, 0);
17341
17342 if (pi->pubpi.radiorev != 5) {
17343 if (!NREV_IS(pi->pubpi.phy_rev, 7))
17344 WRITE_RADIO_REG3(pi, RADIO_2057,
17345 TX, core,
17346 TSSIA, 0x1);
17347 else
17348 WRITE_RADIO_REG3(pi, RADIO_2057,
17349 TX, core,
17350 TSSIA, 0x31);
17351 }
17352 }
17353 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
17354 0);
17355 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
17356 0);
17357 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
17358 0x3);
17359 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
17360 0x0);
17361 }
17362 } else {
17363 WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR31,
17364 (CHSPEC_IS2G(pi->radio_chanspec)) ? 0x128 :
17365 0x80);
17366 WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR30, 0x0);
17367 WRITE_RADIO_SYN(pi, RADIO_2056, GPIO_MASTER1, 0x29);
17368
17369 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
17370 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_VCM_HG,
17371 0x0);
17372 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_IDAC,
17373 0x0);
17374 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_VCM,
17375 0x3);
17376 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TX_AMP_DET,
17377 0x0);
17378 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC1,
17379 0x8);
17380 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC2,
17381 0x0);
17382 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC3,
17383 0x0);
17384
17385 if (CHSPEC_IS2G(pi->radio_chanspec)) {
17386 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
17387 TX_SSI_MASTER, 0x5);
17388
17389 if (pi->pubpi.radiorev != 5)
17390 WRITE_RADIO_REG2(pi, RADIO_2056, TX,
17391 core, TSSIA, 0x0);
17392 if (NREV_GE(pi->pubpi.phy_rev, 5))
17393 WRITE_RADIO_REG2(pi, RADIO_2056, TX,
17394 core, TSSIG, 0x31);
17395 else
17396 WRITE_RADIO_REG2(pi, RADIO_2056, TX,
17397 core, TSSIG, 0x11);
17398 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
17399 TX_SSI_MUX, 0xe);
17400 } else {
17401 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
17402 TX_SSI_MASTER, 0x9);
17403 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
17404 TSSIA, 0x31);
17405 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
17406 TSSIG, 0x0);
17407 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
17408 TX_SSI_MUX, 0xc);
17409 }
17410 }
17411 }
17412}
17413
17414static void
17415wlc_phy_rfctrl_override_nphy(struct brcms_phy *pi, u16 field, u16 value,
17416 u8 core_mask, u8 off)
17417{
17418 u8 core_num;
17419 u16 addr = 0, mask = 0, en_addr = 0, val_addr = 0, en_mask =
17420 0, val_mask = 0;
17421 u8 shift = 0, val_shift = 0;
17422
17423 if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
17424
17425 en_mask = field;
17426 for (core_num = 0; core_num < 2; core_num++) {
17427
17428 switch (field) {
17429 case (0x1 << 1):
17430 en_addr = (core_num == 0) ? 0xe7 : 0xec;
17431 val_addr = (core_num == 0) ? 0x7a : 0x7d;
17432 val_mask = (0x1 << 0);
17433 val_shift = 0;
17434 break;
17435 case (0x1 << 2):
17436 en_addr = (core_num == 0) ? 0xe7 : 0xec;
17437 val_addr = (core_num == 0) ? 0x7a : 0x7d;
17438 val_mask = (0x1 << 1);
17439 val_shift = 1;
17440 break;
17441 case (0x1 << 3):
17442 en_addr = (core_num == 0) ? 0xe7 : 0xec;
17443 val_addr = (core_num == 0) ? 0x7a : 0x7d;
17444 val_mask = (0x1 << 2);
17445 val_shift = 2;
17446 break;
17447 case (0x1 << 4):
17448 en_addr = (core_num == 0) ? 0xe7 : 0xec;
17449 val_addr = (core_num == 0) ? 0x7a : 0x7d;
17450 val_mask = (0x1 << 4);
17451 val_shift = 4;
17452 break;
17453 case (0x1 << 5):
17454 en_addr = (core_num == 0) ? 0xe7 : 0xec;
17455 val_addr = (core_num == 0) ? 0x7a : 0x7d;
17456 val_mask = (0x1 << 5);
17457 val_shift = 5;
17458 break;
17459 case (0x1 << 6):
17460 en_addr = (core_num == 0) ? 0xe7 : 0xec;
17461 val_addr = (core_num == 0) ? 0x7a : 0x7d;
17462 val_mask = (0x1 << 6);
17463 val_shift = 6;
17464 break;
17465 case (0x1 << 7):
17466 en_addr = (core_num == 0) ? 0xe7 : 0xec;
17467 val_addr = (core_num == 0) ? 0x7a : 0x7d;
17468 val_mask = (0x1 << 7);
17469 val_shift = 7;
17470 break;
17471 case (0x1 << 8):
17472 en_addr = (core_num == 0) ? 0xe7 : 0xec;
17473 val_addr = (core_num == 0) ? 0x7a : 0x7d;
17474 val_mask = (0x7 << 8);
17475 val_shift = 8;
17476 break;
17477 case (0x1 << 11):
17478 en_addr = (core_num == 0) ? 0xe7 : 0xec;
17479 val_addr = (core_num == 0) ? 0x7a : 0x7d;
17480 val_mask = (0x7 << 13);
17481 val_shift = 13;
17482 break;
17483
17484 case (0x1 << 9):
17485 en_addr = (core_num == 0) ? 0xe7 : 0xec;
17486 val_addr = (core_num == 0) ? 0xf8 : 0xfa;
17487 val_mask = (0x7 << 0);
17488 val_shift = 0;
17489 break;
17490
17491 case (0x1 << 10):
17492 en_addr = (core_num == 0) ? 0xe7 : 0xec;
17493 val_addr = (core_num == 0) ? 0xf8 : 0xfa;
17494 val_mask = (0x7 << 4);
17495 val_shift = 4;
17496 break;
17497
17498 case (0x1 << 12):
17499 en_addr = (core_num == 0) ? 0xe7 : 0xec;
17500 val_addr = (core_num == 0) ? 0x7b : 0x7e;
17501 val_mask = (0xffff << 0);
17502 val_shift = 0;
17503 break;
17504 case (0x1 << 13):
17505 en_addr = (core_num == 0) ? 0xe7 : 0xec;
17506 val_addr = (core_num == 0) ? 0x7c : 0x7f;
17507 val_mask = (0xffff << 0);
17508 val_shift = 0;
17509 break;
17510 case (0x1 << 14):
17511 en_addr = (core_num == 0) ? 0xe7 : 0xec;
17512 val_addr = (core_num == 0) ? 0xf9 : 0xfb;
17513 val_mask = (0x3 << 6);
17514 val_shift = 6;
17515 break;
17516 case (0x1 << 0):
17517 en_addr = (core_num == 0) ? 0xe5 : 0xe6;
17518 val_addr = (core_num == 0) ? 0xf9 : 0xfb;
17519 val_mask = (0x1 << 15);
17520 val_shift = 15;
17521 break;
17522 default:
17523 addr = 0xffff;
17524 break;
17525 }
17526
17527 if (off) {
17528 and_phy_reg(pi, en_addr, ~en_mask);
17529 and_phy_reg(pi, val_addr, ~val_mask);
17530 } else {
17531
17532 if ((core_mask == 0)
17533 || (core_mask & (1 << core_num))) {
17534 or_phy_reg(pi, en_addr, en_mask);
17535
17536 if (addr != 0xffff)
17537 mod_phy_reg(pi, val_addr,
17538 val_mask,
17539 (value <<
17540 val_shift));
17541 }
17542 }
17543 }
17544 } else {
17545
17546 if (off) {
17547 and_phy_reg(pi, 0xec, ~field);
17548 value = 0x0;
17549 } else {
17550 or_phy_reg(pi, 0xec, field);
17551 }
17552
17553 for (core_num = 0; core_num < 2; core_num++) {
17554
17555 switch (field) {
17556 case (0x1 << 1):
17557 case (0x1 << 9):
17558 case (0x1 << 12):
17559 case (0x1 << 13):
17560 case (0x1 << 14):
17561 addr = 0x78;
17562
17563 core_mask = 0x1;
17564 break;
17565 case (0x1 << 2):
17566 case (0x1 << 3):
17567 case (0x1 << 4):
17568 case (0x1 << 5):
17569 case (0x1 << 6):
17570 case (0x1 << 7):
17571 case (0x1 << 8):
17572 addr = (core_num == 0) ? 0x7a : 0x7d;
17573 break;
17574 case (0x1 << 10):
17575 addr = (core_num == 0) ? 0x7b : 0x7e;
17576 break;
17577 case (0x1 << 11):
17578 addr = (core_num == 0) ? 0x7c : 0x7f;
17579 break;
17580 default:
17581 addr = 0xffff;
17582 }
17583
17584 switch (field) {
17585 case (0x1 << 1):
17586 mask = (0x7 << 3);
17587 shift = 3;
17588 break;
17589 case (0x1 << 9):
17590 mask = (0x1 << 2);
17591 shift = 2;
17592 break;
17593 case (0x1 << 12):
17594 mask = (0x1 << 8);
17595 shift = 8;
17596 break;
17597 case (0x1 << 13):
17598 mask = (0x1 << 9);
17599 shift = 9;
17600 break;
17601 case (0x1 << 14):
17602 mask = (0xf << 12);
17603 shift = 12;
17604 break;
17605 case (0x1 << 2):
17606 mask = (0x1 << 0);
17607 shift = 0;
17608 break;
17609 case (0x1 << 3):
17610 mask = (0x1 << 1);
17611 shift = 1;
17612 break;
17613 case (0x1 << 4):
17614 mask = (0x1 << 2);
17615 shift = 2;
17616 break;
17617 case (0x1 << 5):
17618 mask = (0x3 << 4);
17619 shift = 4;
17620 break;
17621 case (0x1 << 6):
17622 mask = (0x3 << 6);
17623 shift = 6;
17624 break;
17625 case (0x1 << 7):
17626 mask = (0x1 << 8);
17627 shift = 8;
17628 break;
17629 case (0x1 << 8):
17630 mask = (0x1 << 9);
17631 shift = 9;
17632 break;
17633 case (0x1 << 10):
17634 mask = 0x1fff;
17635 shift = 0x0;
17636 break;
17637 case (0x1 << 11):
17638 mask = 0x1fff;
17639 shift = 0x0;
17640 break;
17641 default:
17642 mask = 0x0;
17643 shift = 0x0;
17644 break;
17645 }
17646
17647 if ((addr != 0xffff) && (core_mask & (1 << core_num)))
17648 mod_phy_reg(pi, addr, mask, (value << shift));
17649 }
17650
17651 or_phy_reg(pi, 0xec, (0x1 << 0));
17652 or_phy_reg(pi, 0x78, (0x1 << 0));
17653 udelay(1);
17654 and_phy_reg(pi, 0xec, ~(0x1 << 0));
17655 }
17656}
17657
17658static void wlc_phy_txpwrctrl_idle_tssi_nphy(struct brcms_phy *pi)
17659{
17660 s32 rssi_buf[4];
17661 s32 int_val;
17662
17663 if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) || PHY_MUTED(pi))
17664
17665 return;
17666
17667 if (PHY_IPA(pi))
17668 wlc_phy_ipa_internal_tssi_setup_nphy(pi);
17669
17670 if (NREV_GE(pi->pubpi.phy_rev, 7))
17671 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
17672 0, 0x3, 0,
17673 NPHY_REV7_RFCTRLOVERRIDE_ID0);
17674 else if (NREV_GE(pi->pubpi.phy_rev, 3))
17675 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 0);
17676
17677 wlc_phy_stopplayback_nphy(pi);
17678
17679 wlc_phy_tx_tone_nphy(pi, 4000, 0, 0, 0, false);
17680
17681 udelay(20);
17682 int_val =
17683 wlc_phy_poll_rssi_nphy(pi, (u8) NPHY_RSSI_SEL_TSSI_2G, rssi_buf,
17684 1);
17685 wlc_phy_stopplayback_nphy(pi);
17686 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, 0);
17687
17688 if (NREV_GE(pi->pubpi.phy_rev, 7))
17689 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
17690 0, 0x3, 1,
17691 NPHY_REV7_RFCTRLOVERRIDE_ID0);
17692 else if (NREV_GE(pi->pubpi.phy_rev, 3))
17693 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 1);
17694
17695 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
17696
17697 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
17698 (u8) ((int_val >> 24) & 0xff);
17699 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
17700 (u8) ((int_val >> 24) & 0xff);
17701
17702 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
17703 (u8) ((int_val >> 8) & 0xff);
17704 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
17705 (u8) ((int_val >> 8) & 0xff);
17706 } else {
17707 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
17708 (u8) ((int_val >> 24) & 0xff);
17709
17710 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
17711 (u8) ((int_val >> 8) & 0xff);
17712
17713 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
17714 (u8) ((int_val >> 16) & 0xff);
17715 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
17716 (u8) ((int_val) & 0xff);
17717 }
17718
17719}
17720
17721static void wlc_phy_txpwr_limit_to_tbl_nphy(struct brcms_phy *pi)
17722{
17723 u8 idx, idx2, i, delta_ind;
17724
17725 for (idx = TXP_FIRST_CCK; idx <= TXP_LAST_CCK; idx++)
17726 pi->adj_pwr_tbl_nphy[idx] = pi->tx_power_offset[idx];
17727
17728 for (i = 0; i < 4; i++) {
17729 idx2 = 0;
17730
17731 delta_ind = 0;
17732
17733 switch (i) {
17734 case 0:
17735
17736 if (CHSPEC_IS40(pi->radio_chanspec)
17737 && NPHY_IS_SROM_REINTERPRET) {
17738 idx = TXP_FIRST_MCS_40_SISO;
17739 } else {
17740 idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
17741 TXP_FIRST_OFDM_40_SISO : TXP_FIRST_OFDM;
17742 delta_ind = 1;
17743 }
17744 break;
17745
17746 case 1:
17747
17748 idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
17749 TXP_FIRST_MCS_40_CDD : TXP_FIRST_MCS_20_CDD;
17750 break;
17751
17752 case 2:
17753
17754 idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
17755 TXP_FIRST_MCS_40_STBC : TXP_FIRST_MCS_20_STBC;
17756 break;
17757
17758 case 3:
17759
17760 idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
17761 TXP_FIRST_MCS_40_SDM : TXP_FIRST_MCS_20_SDM;
17762 break;
17763 }
17764
17765 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17766 pi->tx_power_offset[idx];
17767 idx = idx + delta_ind;
17768 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17769 pi->tx_power_offset[idx];
17770 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17771 pi->tx_power_offset[idx];
17772 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17773 pi->tx_power_offset[idx++];
17774
17775 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17776 pi->tx_power_offset[idx++];
17777 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17778 pi->tx_power_offset[idx];
17779 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17780 pi->tx_power_offset[idx];
17781 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17782 pi->tx_power_offset[idx++];
17783
17784 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17785 pi->tx_power_offset[idx++];
17786 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17787 pi->tx_power_offset[idx];
17788 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17789 pi->tx_power_offset[idx];
17790 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17791 pi->tx_power_offset[idx++];
17792
17793 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17794 pi->tx_power_offset[idx];
17795 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17796 pi->tx_power_offset[idx++];
17797 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17798 pi->tx_power_offset[idx];
17799 idx = idx + 1 - delta_ind;
17800 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17801 pi->tx_power_offset[idx];
17802
17803 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17804 pi->tx_power_offset[idx];
17805 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17806 pi->tx_power_offset[idx];
17807 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17808 pi->tx_power_offset[idx];
17809 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
17810 pi->tx_power_offset[idx];
17811 }
17812}
17813
17814static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
17815{
17816 u32 idx;
17817 s16 a1[2], b0[2], b1[2];
17818 s8 target_pwr_qtrdbm[2];
17819 s32 num, den, pwr_est;
17820 u8 chan_freq_range;
17821 u8 idle_tssi[2];
17822 u32 tbl_id, tbl_len, tbl_offset;
17823 u32 regval[64];
17824 u8 core;
17825
17826 if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
17827 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
17828 (void)R_REG(&pi->regs->maccontrol);
17829 udelay(1);
17830 }
17831
17832 if (pi->phyhang_avoid)
17833 wlc_phy_stay_in_carriersearch_nphy(pi, true);
17834
17835 or_phy_reg(pi, 0x122, (0x1 << 0));
17836
17837 if (NREV_GE(pi->pubpi.phy_rev, 3))
17838 and_phy_reg(pi, 0x1e7, (u16) (~(0x1 << 15)));
17839 else
17840 or_phy_reg(pi, 0x1e7, (0x1 << 15));
17841
17842 if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
17843 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
17844
17845 if (pi->sh->sromrev < 4) {
17846 idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
17847 idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
17848 target_pwr_qtrdbm[0] = 13 * 4;
17849 target_pwr_qtrdbm[1] = 13 * 4;
17850 a1[0] = -424;
17851 a1[1] = -424;
17852 b0[0] = 5612;
17853 b0[1] = 5612;
17854 b1[1] = -1393;
17855 b1[0] = -1393;
17856 } else {
17857
17858 chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
17859 switch (chan_freq_range) {
17860 case WL_CHAN_FREQ_RANGE_2G:
17861 idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
17862 idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
17863 target_pwr_qtrdbm[0] =
17864 pi->nphy_pwrctrl_info[0].max_pwr_2g;
17865 target_pwr_qtrdbm[1] =
17866 pi->nphy_pwrctrl_info[1].max_pwr_2g;
17867 a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1;
17868 a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1;
17869 b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0;
17870 b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b0;
17871 b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b1;
17872 b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b1;
17873 break;
17874 case WL_CHAN_FREQ_RANGE_5GL:
17875 idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
17876 idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
17877 target_pwr_qtrdbm[0] =
17878 pi->nphy_pwrctrl_info[0].max_pwr_5gl;
17879 target_pwr_qtrdbm[1] =
17880 pi->nphy_pwrctrl_info[1].max_pwr_5gl;
17881 a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1;
17882 a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1;
17883 b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0;
17884 b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0;
17885 b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1;
17886 b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1;
17887 break;
17888 case WL_CHAN_FREQ_RANGE_5GM:
17889 idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
17890 idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
17891 target_pwr_qtrdbm[0] =
17892 pi->nphy_pwrctrl_info[0].max_pwr_5gm;
17893 target_pwr_qtrdbm[1] =
17894 pi->nphy_pwrctrl_info[1].max_pwr_5gm;
17895 a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1;
17896 a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1;
17897 b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0;
17898 b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b0;
17899 b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b1;
17900 b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b1;
17901 break;
17902 case WL_CHAN_FREQ_RANGE_5GH:
17903 idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
17904 idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
17905 target_pwr_qtrdbm[0] =
17906 pi->nphy_pwrctrl_info[0].max_pwr_5gh;
17907 target_pwr_qtrdbm[1] =
17908 pi->nphy_pwrctrl_info[1].max_pwr_5gh;
17909 a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1;
17910 a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1;
17911 b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0;
17912 b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0;
17913 b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1;
17914 b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1;
17915 break;
17916 default:
17917 idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
17918 idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
17919 target_pwr_qtrdbm[0] = 13 * 4;
17920 target_pwr_qtrdbm[1] = 13 * 4;
17921 a1[0] = -424;
17922 a1[1] = -424;
17923 b0[0] = 5612;
17924 b0[1] = 5612;
17925 b1[1] = -1393;
17926 b1[0] = -1393;
17927 break;
17928 }
17929 }
17930
17931 target_pwr_qtrdbm[0] = (s8) pi->tx_power_max;
17932 target_pwr_qtrdbm[1] = (s8) pi->tx_power_max;
17933
17934 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
17935 if (pi->srom_fem2g.tssipos)
17936 or_phy_reg(pi, 0x1e9, (0x1 << 14));
17937
17938 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
17939 for (core = 0; core <= 1; core++) {
17940 if (PHY_IPA(pi)) {
17941 if (CHSPEC_IS2G(pi->radio_chanspec))
17942 WRITE_RADIO_REG3(pi, RADIO_2057,
17943 TX, core,
17944 TX_SSI_MUX,
17945 0xe);
17946 else
17947 WRITE_RADIO_REG3(pi, RADIO_2057,
17948 TX, core,
17949 TX_SSI_MUX,
17950 0xc);
17951 }
17952 }
17953 } else {
17954 if (PHY_IPA(pi)) {
17955
17956 write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
17957 RADIO_2056_TX0,
17958 (CHSPEC_IS5G
17959 (pi->radio_chanspec)) ?
17960 0xc : 0xe);
17961 write_radio_reg(pi,
17962 RADIO_2056_TX_TX_SSI_MUX |
17963 RADIO_2056_TX1,
17964 (CHSPEC_IS5G
17965 (pi->radio_chanspec)) ?
17966 0xc : 0xe);
17967 } else {
17968
17969 write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
17970 RADIO_2056_TX0, 0x11);
17971 write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
17972 RADIO_2056_TX1, 0x11);
17973 }
17974 }
17975 }
17976
17977 if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
17978 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
17979 (void)R_REG(&pi->regs->maccontrol);
17980 udelay(1);
17981 }
17982
17983 if (NREV_GE(pi->pubpi.phy_rev, 7))
17984 mod_phy_reg(pi, 0x1e7, (0x7f << 0),
17985 (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
17986 else
17987 mod_phy_reg(pi, 0x1e7, (0x7f << 0),
17988 (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
17989
17990 if (NREV_GE(pi->pubpi.phy_rev, 7))
17991 mod_phy_reg(pi, 0x222, (0xff << 0),
17992 (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
17993 else if (NREV_GT(pi->pubpi.phy_rev, 1))
17994 mod_phy_reg(pi, 0x222, (0xff << 0),
17995 (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
17996
17997 if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
17998 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
17999
18000 write_phy_reg(pi, 0x1e8, (0x3 << 8) | (240 << 0));
18001
18002 write_phy_reg(pi, 0x1e9,
18003 (1 << 15) | (idle_tssi[0] << 0) | (idle_tssi[1] << 8));
18004
18005 write_phy_reg(pi, 0x1ea,
18006 (target_pwr_qtrdbm[0] << 0) |
18007 (target_pwr_qtrdbm[1] << 8));
18008
18009 tbl_len = 64;
18010 tbl_offset = 0;
18011 for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
18012 tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
18013
18014 for (idx = 0; idx < tbl_len; idx++) {
18015 num = 8 *
18016 (16 * b0[tbl_id - 26] + b1[tbl_id - 26] * idx);
18017 den = 32768 + a1[tbl_id - 26] * idx;
18018 pwr_est = max(((4 * num + den / 2) / den), -8);
18019 if (NREV_LT(pi->pubpi.phy_rev, 3)) {
18020 if (idx <=
18021 (uint) (31 - idle_tssi[tbl_id - 26] + 1))
18022 pwr_est =
18023 max(pwr_est,
18024 target_pwr_qtrdbm
18025 [tbl_id - 26] + 1);
18026 }
18027 regval[idx] = (u32) pwr_est;
18028 }
18029 wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
18030 regval);
18031 }
18032
18033 wlc_phy_txpwr_limit_to_tbl_nphy(pi);
18034 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64, 8,
18035 pi->adj_pwr_tbl_nphy);
18036 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64, 8,
18037 pi->adj_pwr_tbl_nphy);
18038
18039 if (pi->phyhang_avoid)
18040 wlc_phy_stay_in_carriersearch_nphy(pi, false);
18041}
18042
18043static u32 *wlc_phy_get_ipa_gaintbl_nphy(struct brcms_phy *pi)
18044{
18045 u32 *tx_pwrctrl_tbl = NULL;
18046
18047 if (CHSPEC_IS2G(pi->radio_chanspec)) {
18048 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18049 if ((pi->pubpi.radiorev == 4)
18050 || (pi->pubpi.radiorev == 6))
18051 tx_pwrctrl_tbl =
18052 nphy_tpc_txgain_ipa_2g_2057rev4n6;
18053 else if (pi->pubpi.radiorev == 3)
18054 tx_pwrctrl_tbl =
18055 nphy_tpc_txgain_ipa_2g_2057rev3;
18056 else if (pi->pubpi.radiorev == 5)
18057 tx_pwrctrl_tbl =
18058 nphy_tpc_txgain_ipa_2g_2057rev5;
18059 else if ((pi->pubpi.radiorev == 7)
18060 || (pi->pubpi.radiorev == 8))
18061 tx_pwrctrl_tbl =
18062 nphy_tpc_txgain_ipa_2g_2057rev7;
18063 } else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
18064 tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev6;
18065 } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
18066 tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5;
18067 } else {
18068 tx_pwrctrl_tbl = nphy_tpc_txgain_ipa;
18069 }
18070 } else {
18071
18072 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18073 if ((pi->pubpi.radiorev == 3) ||
18074 (pi->pubpi.radiorev == 4) ||
18075 (pi->pubpi.radiorev == 6))
18076 tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g_2057;
18077 else if ((pi->pubpi.radiorev == 7)
18078 || (pi->pubpi.radiorev == 8))
18079 tx_pwrctrl_tbl =
18080 nphy_tpc_txgain_ipa_5g_2057rev7;
18081 } else {
18082 tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g;
18083 }
18084 }
18085
18086 return tx_pwrctrl_tbl;
18087}
18088
18089static void wlc_phy_restore_rssical_nphy(struct brcms_phy *pi)
18090{
18091 if (CHSPEC_IS2G(pi->radio_chanspec)) {
18092 if (pi->nphy_rssical_chanspec_2G == 0)
18093 return;
18094
18095 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18096 mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
18097 RADIO_2057_VCM_MASK,
18098 pi->rssical_cache.
18099 rssical_radio_regs_2G[0]);
18100 mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
18101 RADIO_2057_VCM_MASK,
18102 pi->rssical_cache.
18103 rssical_radio_regs_2G[1]);
18104 } else {
18105 mod_radio_reg(pi,
18106 RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
18107 RADIO_2056_VCM_MASK,
18108 pi->rssical_cache.
18109 rssical_radio_regs_2G[0]);
18110 mod_radio_reg(pi,
18111 RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
18112 RADIO_2056_VCM_MASK,
18113 pi->rssical_cache.
18114 rssical_radio_regs_2G[1]);
18115 }
18116
18117 write_phy_reg(pi, 0x1a6,
18118 pi->rssical_cache.rssical_phyregs_2G[0]);
18119 write_phy_reg(pi, 0x1ac,
18120 pi->rssical_cache.rssical_phyregs_2G[1]);
18121 write_phy_reg(pi, 0x1b2,
18122 pi->rssical_cache.rssical_phyregs_2G[2]);
18123 write_phy_reg(pi, 0x1b8,
18124 pi->rssical_cache.rssical_phyregs_2G[3]);
18125 write_phy_reg(pi, 0x1a4,
18126 pi->rssical_cache.rssical_phyregs_2G[4]);
18127 write_phy_reg(pi, 0x1aa,
18128 pi->rssical_cache.rssical_phyregs_2G[5]);
18129 write_phy_reg(pi, 0x1b0,
18130 pi->rssical_cache.rssical_phyregs_2G[6]);
18131 write_phy_reg(pi, 0x1b6,
18132 pi->rssical_cache.rssical_phyregs_2G[7]);
18133 write_phy_reg(pi, 0x1a5,
18134 pi->rssical_cache.rssical_phyregs_2G[8]);
18135 write_phy_reg(pi, 0x1ab,
18136 pi->rssical_cache.rssical_phyregs_2G[9]);
18137 write_phy_reg(pi, 0x1b1,
18138 pi->rssical_cache.rssical_phyregs_2G[10]);
18139 write_phy_reg(pi, 0x1b7,
18140 pi->rssical_cache.rssical_phyregs_2G[11]);
18141
18142 } else {
18143 if (pi->nphy_rssical_chanspec_5G == 0)
18144 return;
18145
18146 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18147 mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
18148 RADIO_2057_VCM_MASK,
18149 pi->rssical_cache.
18150 rssical_radio_regs_5G[0]);
18151 mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
18152 RADIO_2057_VCM_MASK,
18153 pi->rssical_cache.
18154 rssical_radio_regs_5G[1]);
18155 } else {
18156 mod_radio_reg(pi,
18157 RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
18158 RADIO_2056_VCM_MASK,
18159 pi->rssical_cache.
18160 rssical_radio_regs_5G[0]);
18161 mod_radio_reg(pi,
18162 RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
18163 RADIO_2056_VCM_MASK,
18164 pi->rssical_cache.
18165 rssical_radio_regs_5G[1]);
18166 }
18167
18168 write_phy_reg(pi, 0x1a6,
18169 pi->rssical_cache.rssical_phyregs_5G[0]);
18170 write_phy_reg(pi, 0x1ac,
18171 pi->rssical_cache.rssical_phyregs_5G[1]);
18172 write_phy_reg(pi, 0x1b2,
18173 pi->rssical_cache.rssical_phyregs_5G[2]);
18174 write_phy_reg(pi, 0x1b8,
18175 pi->rssical_cache.rssical_phyregs_5G[3]);
18176 write_phy_reg(pi, 0x1a4,
18177 pi->rssical_cache.rssical_phyregs_5G[4]);
18178 write_phy_reg(pi, 0x1aa,
18179 pi->rssical_cache.rssical_phyregs_5G[5]);
18180 write_phy_reg(pi, 0x1b0,
18181 pi->rssical_cache.rssical_phyregs_5G[6]);
18182 write_phy_reg(pi, 0x1b6,
18183 pi->rssical_cache.rssical_phyregs_5G[7]);
18184 write_phy_reg(pi, 0x1a5,
18185 pi->rssical_cache.rssical_phyregs_5G[8]);
18186 write_phy_reg(pi, 0x1ab,
18187 pi->rssical_cache.rssical_phyregs_5G[9]);
18188 write_phy_reg(pi, 0x1b1,
18189 pi->rssical_cache.rssical_phyregs_5G[10]);
18190 write_phy_reg(pi, 0x1b7,
18191 pi->rssical_cache.rssical_phyregs_5G[11]);
18192 }
18193}
18194
18195static void wlc_phy_internal_cal_txgain_nphy(struct brcms_phy *pi)
18196{
18197 u16 txcal_gain[2];
18198
18199 pi->nphy_txcal_pwr_idx[0] = pi->nphy_cal_orig_pwr_idx[0];
18200 pi->nphy_txcal_pwr_idx[1] = pi->nphy_cal_orig_pwr_idx[0];
18201 wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true);
18202 wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true);
18203
18204 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
18205 txcal_gain);
18206
18207 if (CHSPEC_IS2G(pi->radio_chanspec)) {
18208 txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F40;
18209 txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F40;
18210 } else {
18211 txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F60;
18212 txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F60;
18213 }
18214
18215 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
18216 txcal_gain);
18217}
18218
18219static void wlc_phy_precal_txgain_nphy(struct brcms_phy *pi)
18220{
18221 bool save_bbmult = false;
18222 u8 txcal_index_2057_rev5n7 = 0;
18223 u8 txcal_index_2057_rev3n4n6 = 10;
18224
18225 if (pi->use_int_tx_iqlo_cal_nphy) {
18226 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18227 if ((pi->pubpi.radiorev == 3) ||
18228 (pi->pubpi.radiorev == 4) ||
18229 (pi->pubpi.radiorev == 6)) {
18230
18231 pi->nphy_txcal_pwr_idx[0] =
18232 txcal_index_2057_rev3n4n6;
18233 pi->nphy_txcal_pwr_idx[1] =
18234 txcal_index_2057_rev3n4n6;
18235 wlc_phy_txpwr_index_nphy(
18236 pi, 3,
18237 txcal_index_2057_rev3n4n6,
18238 false);
18239 } else {
18240
18241 pi->nphy_txcal_pwr_idx[0] =
18242 txcal_index_2057_rev5n7;
18243 pi->nphy_txcal_pwr_idx[1] =
18244 txcal_index_2057_rev5n7;
18245 wlc_phy_txpwr_index_nphy(
18246 pi, 3,
18247 txcal_index_2057_rev5n7,
18248 false);
18249 }
18250 save_bbmult = true;
18251
18252 } else if (NREV_LT(pi->pubpi.phy_rev, 5)) {
18253 wlc_phy_cal_txgainctrl_nphy(pi, 11, false);
18254 if (pi->sh->hw_phytxchain != 3) {
18255 pi->nphy_txcal_pwr_idx[1] =
18256 pi->nphy_txcal_pwr_idx[0];
18257 wlc_phy_txpwr_index_nphy(pi, 3,
18258 pi->
18259 nphy_txcal_pwr_idx[0],
18260 true);
18261 save_bbmult = true;
18262 }
18263
18264 } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
18265 if (PHY_IPA(pi)) {
18266 if (CHSPEC_IS2G(pi->radio_chanspec)) {
18267 wlc_phy_cal_txgainctrl_nphy(pi, 12,
18268 false);
18269 } else {
18270 pi->nphy_txcal_pwr_idx[0] = 80;
18271 pi->nphy_txcal_pwr_idx[1] = 80;
18272 wlc_phy_txpwr_index_nphy(pi, 3, 80,
18273 false);
18274 save_bbmult = true;
18275 }
18276 } else {
18277 wlc_phy_internal_cal_txgain_nphy(pi);
18278 save_bbmult = true;
18279 }
18280
18281 } else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
18282 if (PHY_IPA(pi)) {
18283 if (CHSPEC_IS2G(pi->radio_chanspec))
18284 wlc_phy_cal_txgainctrl_nphy(pi, 12,
18285 false);
18286 else
18287 wlc_phy_cal_txgainctrl_nphy(pi, 14,
18288 false);
18289 } else {
18290 wlc_phy_internal_cal_txgain_nphy(pi);
18291 save_bbmult = true;
18292 }
18293 }
18294
18295 } else {
18296 wlc_phy_cal_txgainctrl_nphy(pi, 10, false);
18297 }
18298
18299 if (save_bbmult)
18300 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
18301 &pi->nphy_txcal_bbmult);
18302}
18303
18304static void
18305wlc_phy_rfctrlintc_override_nphy(struct brcms_phy *pi, u8 field, u16 value,
18306 u8 core_code)
18307{
18308 u16 mask;
18309 u16 val;
18310 u8 core;
18311
18312 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
18313 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
18314 if (core_code == RADIO_MIMO_CORESEL_CORE1
18315 && core == PHY_CORE_1)
18316 continue;
18317 else if (core_code == RADIO_MIMO_CORESEL_CORE2
18318 && core == PHY_CORE_0)
18319 continue;
18320
18321 if (NREV_LT(pi->pubpi.phy_rev, 7)) {
18322
18323 mask = (0x1 << 10);
18324 val = 1 << 10;
18325 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
18326 0x92, mask, val);
18327 }
18328
18329 if (field == NPHY_RfctrlIntc_override_OFF) {
18330
18331 write_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
18332 0x92, 0);
18333
18334 wlc_phy_force_rfseq_nphy(pi,
18335 NPHY_RFSEQ_RESET2RX);
18336 } else if (field == NPHY_RfctrlIntc_override_TRSW) {
18337
18338 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18339
18340 mask = (0x1 << 6) | (0x1 << 7);
18341
18342 val = value << 6;
18343 mod_phy_reg(pi,
18344 (core ==
18345 PHY_CORE_0) ? 0x91 : 0x92,
18346 mask, val);
18347
18348 or_phy_reg(pi,
18349 (core ==
18350 PHY_CORE_0) ? 0x91 : 0x92,
18351 (0x1 << 10));
18352
18353 and_phy_reg(pi, 0x2ff, (u16)
18354 ~(0x3 << 14));
18355 or_phy_reg(pi, 0x2ff, (0x1 << 13));
18356 or_phy_reg(pi, 0x2ff, (0x1 << 0));
18357 } else {
18358
18359 mask = (0x1 << 6) |
18360 (0x1 << 7) |
18361 (0x1 << 8) | (0x1 << 9);
18362 val = value << 6;
18363 mod_phy_reg(pi,
18364 (core ==
18365 PHY_CORE_0) ? 0x91 : 0x92,
18366 mask, val);
18367
18368 mask = (0x1 << 0);
18369 val = 1 << 0;
18370 mod_phy_reg(pi,
18371 (core ==
18372 PHY_CORE_0) ? 0xe7 : 0xec,
18373 mask, val);
18374
18375 mask = (core == PHY_CORE_0) ?
18376 (0x1 << 0) : (0x1 << 1);
18377 val = 1 << ((core == PHY_CORE_0) ?
18378 0 : 1);
18379 mod_phy_reg(pi, 0x78, mask, val);
18380
18381 SPINWAIT(((read_phy_reg(pi, 0x78) & val)
18382 != 0), 10000);
18383 if (WARN(read_phy_reg(pi, 0x78) & val,
18384 "HW error: override failed"))
18385 return;
18386
18387 mask = (0x1 << 0);
18388 val = 0 << 0;
18389 mod_phy_reg(pi,
18390 (core ==
18391 PHY_CORE_0) ? 0xe7 : 0xec,
18392 mask, val);
18393 }
18394 } else if (field == NPHY_RfctrlIntc_override_PA) {
18395 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18396
18397 mask = (0x1 << 4) | (0x1 << 5);
18398
18399 if (CHSPEC_IS5G(pi->radio_chanspec))
18400 val = value << 5;
18401 else
18402 val = value << 4;
18403
18404 mod_phy_reg(pi,
18405 (core ==
18406 PHY_CORE_0) ? 0x91 : 0x92,
18407 mask, val);
18408
18409 or_phy_reg(pi,
18410 (core ==
18411 PHY_CORE_0) ? 0x91 : 0x92,
18412 (0x1 << 12));
18413 } else {
18414
18415 if (CHSPEC_IS5G(pi->radio_chanspec)) {
18416 mask = (0x1 << 5);
18417 val = value << 5;
18418 } else {
18419 mask = (0x1 << 4);
18420 val = value << 4;
18421 }
18422 mod_phy_reg(pi,
18423 (core ==
18424 PHY_CORE_0) ? 0x91 : 0x92,
18425 mask, val);
18426 }
18427 } else if (field ==
18428 NPHY_RfctrlIntc_override_EXT_LNA_PU) {
18429 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18430 if (CHSPEC_IS5G(pi->radio_chanspec)) {
18431
18432 mask = (0x1 << 0);
18433 val = value << 0;
18434 mod_phy_reg(pi,
18435 (core ==
18436 PHY_CORE_0) ? 0x91
18437 : 0x92, mask, val);
18438
18439 mask = (0x1 << 2);
18440 mod_phy_reg(pi,
18441 (core ==
18442 PHY_CORE_0) ? 0x91
18443 : 0x92, mask, 0);
18444 } else {
18445
18446 mask = (0x1 << 2);
18447 val = value << 2;
18448 mod_phy_reg(pi,
18449 (core ==
18450 PHY_CORE_0) ? 0x91
18451 : 0x92, mask, val);
18452
18453 mask = (0x1 << 0);
18454 mod_phy_reg(pi,
18455 (core ==
18456 PHY_CORE_0) ? 0x91
18457 : 0x92, mask, 0);
18458 }
18459
18460 mask = (0x1 << 11);
18461 val = 1 << 11;
18462 mod_phy_reg(pi,
18463 (core ==
18464 PHY_CORE_0) ? 0x91 : 0x92,
18465 mask, val);
18466 } else {
18467
18468 if (CHSPEC_IS5G(pi->radio_chanspec)) {
18469 mask = (0x1 << 0);
18470 val = value << 0;
18471 } else {
18472 mask = (0x1 << 2);
18473 val = value << 2;
18474 }
18475 mod_phy_reg(pi,
18476 (core ==
18477 PHY_CORE_0) ? 0x91 : 0x92,
18478 mask, val);
18479 }
18480 } else if (field ==
18481 NPHY_RfctrlIntc_override_EXT_LNA_GAIN) {
18482 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18483 if (CHSPEC_IS5G(pi->radio_chanspec)) {
18484
18485 mask = (0x1 << 1);
18486 val = value << 1;
18487 mod_phy_reg(pi,
18488 (core ==
18489 PHY_CORE_0) ? 0x91
18490 : 0x92, mask, val);
18491
18492 mask = (0x1 << 3);
18493 mod_phy_reg(pi,
18494 (core ==
18495 PHY_CORE_0) ? 0x91
18496 : 0x92, mask, 0);
18497 } else {
18498
18499 mask = (0x1 << 3);
18500 val = value << 3;
18501 mod_phy_reg(pi,
18502 (core ==
18503 PHY_CORE_0) ? 0x91
18504 : 0x92, mask, val);
18505
18506 mask = (0x1 << 1);
18507 mod_phy_reg(pi,
18508 (core ==
18509 PHY_CORE_0) ? 0x91
18510 : 0x92, mask, 0);
18511 }
18512
18513 mask = (0x1 << 11);
18514 val = 1 << 11;
18515 mod_phy_reg(pi,
18516 (core ==
18517 PHY_CORE_0) ? 0x91 : 0x92,
18518 mask, val);
18519 } else {
18520
18521 if (CHSPEC_IS5G(pi->radio_chanspec)) {
18522 mask = (0x1 << 1);
18523 val = value << 1;
18524 } else {
18525 mask = (0x1 << 3);
18526 val = value << 3;
18527 }
18528 mod_phy_reg(pi,
18529 (core ==
18530 PHY_CORE_0) ? 0x91 : 0x92,
18531 mask, val);
18532 }
18533 }
18534 }
18535 }
18536}
18537
18538void
18539wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi, s32 dBm_targetpower,
18540 bool debug)
18541{
18542 int gainctrl_loopidx;
18543 uint core;
18544 u16 m0m1, curr_m0m1;
18545 s32 delta_power;
18546 s32 txpwrindex;
18547 s32 qdBm_power[2];
18548 u16 orig_BBConfig;
18549 u16 phy_saveregs[4];
18550 u32 freq_test;
18551 u16 ampl_test = 250;
18552 uint stepsize;
18553 bool phyhang_avoid_state = false;
18554
18555 if (NREV_GE(pi->pubpi.phy_rev, 7))
18556 stepsize = 2;
18557 else
18558 stepsize = 1;
18559
18560 if (CHSPEC_IS40(pi->radio_chanspec))
18561 freq_test = 5000;
18562 else
18563 freq_test = 2500;
18564
18565 wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true);
18566 wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true);
18567
18568 if (pi->phyhang_avoid)
18569 wlc_phy_stay_in_carriersearch_nphy(pi, true);
18570
18571 phyhang_avoid_state = pi->phyhang_avoid;
18572 pi->phyhang_avoid = false;
18573
18574 phy_saveregs[0] = read_phy_reg(pi, 0x91);
18575 phy_saveregs[1] = read_phy_reg(pi, 0x92);
18576 phy_saveregs[2] = read_phy_reg(pi, 0xe7);
18577 phy_saveregs[3] = read_phy_reg(pi, 0xec);
18578 wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 1,
18579 RADIO_MIMO_CORESEL_CORE1 |
18580 RADIO_MIMO_CORESEL_CORE2);
18581
18582 if (!debug) {
18583 wlc_phy_rfctrlintc_override_nphy(pi,
18584 NPHY_RfctrlIntc_override_TRSW,
18585 0x2, RADIO_MIMO_CORESEL_CORE1);
18586 wlc_phy_rfctrlintc_override_nphy(pi,
18587 NPHY_RfctrlIntc_override_TRSW,
18588 0x8, RADIO_MIMO_CORESEL_CORE2);
18589 } else {
18590 wlc_phy_rfctrlintc_override_nphy(pi,
18591 NPHY_RfctrlIntc_override_TRSW,
18592 0x1, RADIO_MIMO_CORESEL_CORE1);
18593 wlc_phy_rfctrlintc_override_nphy(pi,
18594 NPHY_RfctrlIntc_override_TRSW,
18595 0x7, RADIO_MIMO_CORESEL_CORE2);
18596 }
18597
18598 orig_BBConfig = read_phy_reg(pi, 0x01);
18599 mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
18600
18601 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
18602
18603 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
18604 txpwrindex = (s32) pi->nphy_cal_orig_pwr_idx[core];
18605
18606 for (gainctrl_loopidx = 0; gainctrl_loopidx < 2;
18607 gainctrl_loopidx++) {
18608 wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
18609 false);
18610
18611 if (core == PHY_CORE_0)
18612 curr_m0m1 = m0m1 & 0xff00;
18613 else
18614 curr_m0m1 = m0m1 & 0x00ff;
18615
18616 wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &curr_m0m1);
18617 wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &curr_m0m1);
18618
18619 udelay(50);
18620
18621 wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
18622 NPHY_CAL_TSSISAMPS);
18623
18624 pi->nphy_bb_mult_save = 0;
18625 wlc_phy_stopplayback_nphy(pi);
18626
18627 delta_power = (dBm_targetpower * 4) - qdBm_power[core];
18628
18629 txpwrindex -= stepsize * delta_power;
18630 if (txpwrindex < 0)
18631 txpwrindex = 0;
18632 else if (txpwrindex > 127)
18633 txpwrindex = 127;
18634
18635 if (CHSPEC_IS5G(pi->radio_chanspec)) {
18636 if (NREV_IS(pi->pubpi.phy_rev, 4) &&
18637 (pi->srom_fem5g.extpagain == 3)) {
18638 if (txpwrindex < 30)
18639 txpwrindex = 30;
18640 }
18641 } else {
18642 if (NREV_GE(pi->pubpi.phy_rev, 5) &&
18643 (pi->srom_fem2g.extpagain == 3)) {
18644 if (txpwrindex < 50)
18645 txpwrindex = 50;
18646 }
18647 }
18648
18649 wlc_phy_txpwr_index_nphy(pi, (1 << core),
18650 (u8) txpwrindex, true);
18651 }
18652
18653 pi->nphy_txcal_pwr_idx[core] = (u8) txpwrindex;
18654
18655 if (debug) {
18656 u16 radio_gain;
18657 u16 dbg_m0m1;
18658
18659 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
18660
18661 wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
18662 false);
18663
18664 wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
18665 wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &dbg_m0m1);
18666
18667 udelay(100);
18668
18669 wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
18670 NPHY_CAL_TSSISAMPS);
18671
18672 wlc_phy_table_read_nphy(pi, 7, 1, (0x110 + core), 16,
18673 &radio_gain);
18674
18675 mdelay(4000);
18676 pi->nphy_bb_mult_save = 0;
18677 wlc_phy_stopplayback_nphy(pi);
18678 }
18679 }
18680
18681 wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_txcal_pwr_idx[0], true);
18682 wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_txcal_pwr_idx[1], true);
18683
18684 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &pi->nphy_txcal_bbmult);
18685
18686 write_phy_reg(pi, 0x01, orig_BBConfig);
18687
18688 write_phy_reg(pi, 0x91, phy_saveregs[0]);
18689 write_phy_reg(pi, 0x92, phy_saveregs[1]);
18690 write_phy_reg(pi, 0xe7, phy_saveregs[2]);
18691 write_phy_reg(pi, 0xec, phy_saveregs[3]);
18692
18693 pi->phyhang_avoid = phyhang_avoid_state;
18694
18695 if (pi->phyhang_avoid)
18696 wlc_phy_stay_in_carriersearch_nphy(pi, false);
18697}
18698
18699static void wlc_phy_savecal_nphy(struct brcms_phy *pi)
18700{
18701 void *tbl_ptr;
18702 int coreNum;
18703 u16 *txcal_radio_regs = NULL;
18704
18705 if (pi->phyhang_avoid)
18706 wlc_phy_stay_in_carriersearch_nphy(pi, true);
18707
18708 if (CHSPEC_IS2G(pi->radio_chanspec)) {
18709
18710 wlc_phy_rx_iq_coeffs_nphy(pi, 0,
18711 &pi->calibration_cache.
18712 rxcal_coeffs_2G);
18713
18714 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18715 txcal_radio_regs =
18716 pi->calibration_cache.txcal_radio_regs_2G;
18717 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
18718
18719 pi->calibration_cache.txcal_radio_regs_2G[0] =
18720 read_radio_reg(pi,
18721 RADIO_2056_TX_LOFT_FINE_I |
18722 RADIO_2056_TX0);
18723 pi->calibration_cache.txcal_radio_regs_2G[1] =
18724 read_radio_reg(pi,
18725 RADIO_2056_TX_LOFT_FINE_Q |
18726 RADIO_2056_TX0);
18727 pi->calibration_cache.txcal_radio_regs_2G[2] =
18728 read_radio_reg(pi,
18729 RADIO_2056_TX_LOFT_FINE_I |
18730 RADIO_2056_TX1);
18731 pi->calibration_cache.txcal_radio_regs_2G[3] =
18732 read_radio_reg(pi,
18733 RADIO_2056_TX_LOFT_FINE_Q |
18734 RADIO_2056_TX1);
18735
18736 pi->calibration_cache.txcal_radio_regs_2G[4] =
18737 read_radio_reg(pi,
18738 RADIO_2056_TX_LOFT_COARSE_I |
18739 RADIO_2056_TX0);
18740 pi->calibration_cache.txcal_radio_regs_2G[5] =
18741 read_radio_reg(pi,
18742 RADIO_2056_TX_LOFT_COARSE_Q |
18743 RADIO_2056_TX0);
18744 pi->calibration_cache.txcal_radio_regs_2G[6] =
18745 read_radio_reg(pi,
18746 RADIO_2056_TX_LOFT_COARSE_I |
18747 RADIO_2056_TX1);
18748 pi->calibration_cache.txcal_radio_regs_2G[7] =
18749 read_radio_reg(pi,
18750 RADIO_2056_TX_LOFT_COARSE_Q |
18751 RADIO_2056_TX1);
18752 } else {
18753 pi->calibration_cache.txcal_radio_regs_2G[0] =
18754 read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
18755 pi->calibration_cache.txcal_radio_regs_2G[1] =
18756 read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
18757 pi->calibration_cache.txcal_radio_regs_2G[2] =
18758 read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
18759 pi->calibration_cache.txcal_radio_regs_2G[3] =
18760 read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
18761 }
18762
18763 pi->nphy_iqcal_chanspec_2G = pi->radio_chanspec;
18764 tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
18765 } else {
18766
18767 wlc_phy_rx_iq_coeffs_nphy(pi, 0,
18768 &pi->calibration_cache.
18769 rxcal_coeffs_5G);
18770
18771 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18772 txcal_radio_regs =
18773 pi->calibration_cache.txcal_radio_regs_5G;
18774 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
18775
18776 pi->calibration_cache.txcal_radio_regs_5G[0] =
18777 read_radio_reg(pi,
18778 RADIO_2056_TX_LOFT_FINE_I |
18779 RADIO_2056_TX0);
18780 pi->calibration_cache.txcal_radio_regs_5G[1] =
18781 read_radio_reg(pi,
18782 RADIO_2056_TX_LOFT_FINE_Q |
18783 RADIO_2056_TX0);
18784 pi->calibration_cache.txcal_radio_regs_5G[2] =
18785 read_radio_reg(pi,
18786 RADIO_2056_TX_LOFT_FINE_I |
18787 RADIO_2056_TX1);
18788 pi->calibration_cache.txcal_radio_regs_5G[3] =
18789 read_radio_reg(pi,
18790 RADIO_2056_TX_LOFT_FINE_Q |
18791 RADIO_2056_TX1);
18792
18793 pi->calibration_cache.txcal_radio_regs_5G[4] =
18794 read_radio_reg(pi,
18795 RADIO_2056_TX_LOFT_COARSE_I |
18796 RADIO_2056_TX0);
18797 pi->calibration_cache.txcal_radio_regs_5G[5] =
18798 read_radio_reg(pi,
18799 RADIO_2056_TX_LOFT_COARSE_Q |
18800 RADIO_2056_TX0);
18801 pi->calibration_cache.txcal_radio_regs_5G[6] =
18802 read_radio_reg(pi,
18803 RADIO_2056_TX_LOFT_COARSE_I |
18804 RADIO_2056_TX1);
18805 pi->calibration_cache.txcal_radio_regs_5G[7] =
18806 read_radio_reg(pi,
18807 RADIO_2056_TX_LOFT_COARSE_Q |
18808 RADIO_2056_TX1);
18809 } else {
18810 pi->calibration_cache.txcal_radio_regs_5G[0] =
18811 read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
18812 pi->calibration_cache.txcal_radio_regs_5G[1] =
18813 read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
18814 pi->calibration_cache.txcal_radio_regs_5G[2] =
18815 read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
18816 pi->calibration_cache.txcal_radio_regs_5G[3] =
18817 read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
18818 }
18819
18820 pi->nphy_iqcal_chanspec_5G = pi->radio_chanspec;
18821 tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
18822 }
18823 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18824 for (coreNum = 0; coreNum <= 1; coreNum++) {
18825
18826 txcal_radio_regs[2 * coreNum] =
18827 READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
18828 LOFT_FINE_I);
18829 txcal_radio_regs[2 * coreNum + 1] =
18830 READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
18831 LOFT_FINE_Q);
18832
18833 txcal_radio_regs[2 * coreNum + 4] =
18834 READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
18835 LOFT_COARSE_I);
18836 txcal_radio_regs[2 * coreNum + 5] =
18837 READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
18838 LOFT_COARSE_Q);
18839 }
18840 }
18841
18842 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 8, 80, 16, tbl_ptr);
18843
18844 if (pi->phyhang_avoid)
18845 wlc_phy_stay_in_carriersearch_nphy(pi, false);
18846}
18847
18848static void wlc_phy_tx_iq_war_nphy(struct brcms_phy *pi)
18849{
18850 struct nphy_iq_comp tx_comp;
18851
18852 wlc_phy_table_read_nphy(pi, 15, 4, 0x50, 16, &tx_comp);
18853
18854 wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ, tx_comp.a0);
18855 wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 2, tx_comp.b0);
18856 wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 4, tx_comp.a1);
18857 wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 6, tx_comp.b1);
18858}
18859
18860static void wlc_phy_restorecal_nphy(struct brcms_phy *pi)
18861{
18862 u16 *loft_comp;
18863 u16 txcal_coeffs_bphy[4];
18864 u16 *tbl_ptr;
18865 int coreNum;
18866 u16 *txcal_radio_regs = NULL;
18867
18868 if (CHSPEC_IS2G(pi->radio_chanspec)) {
18869 if (pi->nphy_iqcal_chanspec_2G == 0)
18870 return;
18871
18872 tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
18873 loft_comp = &pi->calibration_cache.txcal_coeffs_2G[5];
18874 } else {
18875 if (pi->nphy_iqcal_chanspec_5G == 0)
18876 return;
18877
18878 tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
18879 loft_comp = &pi->calibration_cache.txcal_coeffs_5G[5];
18880 }
18881
18882 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, 16, tbl_ptr);
18883
18884 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
18885 txcal_coeffs_bphy[0] = tbl_ptr[0];
18886 txcal_coeffs_bphy[1] = tbl_ptr[1];
18887 txcal_coeffs_bphy[2] = tbl_ptr[2];
18888 txcal_coeffs_bphy[3] = tbl_ptr[3];
18889 } else {
18890 txcal_coeffs_bphy[0] = 0;
18891 txcal_coeffs_bphy[1] = 0;
18892 txcal_coeffs_bphy[2] = 0;
18893 txcal_coeffs_bphy[3] = 0;
18894 }
18895
18896 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, 16,
18897 txcal_coeffs_bphy);
18898
18899 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, 16, loft_comp);
18900
18901 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, 16, loft_comp);
18902
18903 if (NREV_LT(pi->pubpi.phy_rev, 2))
18904 wlc_phy_tx_iq_war_nphy(pi);
18905
18906 if (CHSPEC_IS2G(pi->radio_chanspec)) {
18907 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18908 txcal_radio_regs =
18909 pi->calibration_cache.txcal_radio_regs_2G;
18910 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
18911
18912 write_radio_reg(pi,
18913 RADIO_2056_TX_LOFT_FINE_I |
18914 RADIO_2056_TX0,
18915 pi->calibration_cache.
18916 txcal_radio_regs_2G[0]);
18917 write_radio_reg(pi,
18918 RADIO_2056_TX_LOFT_FINE_Q |
18919 RADIO_2056_TX0,
18920 pi->calibration_cache.
18921 txcal_radio_regs_2G[1]);
18922 write_radio_reg(pi,
18923 RADIO_2056_TX_LOFT_FINE_I |
18924 RADIO_2056_TX1,
18925 pi->calibration_cache.
18926 txcal_radio_regs_2G[2]);
18927 write_radio_reg(pi,
18928 RADIO_2056_TX_LOFT_FINE_Q |
18929 RADIO_2056_TX1,
18930 pi->calibration_cache.
18931 txcal_radio_regs_2G[3]);
18932
18933 write_radio_reg(pi,
18934 RADIO_2056_TX_LOFT_COARSE_I |
18935 RADIO_2056_TX0,
18936 pi->calibration_cache.
18937 txcal_radio_regs_2G[4]);
18938 write_radio_reg(pi,
18939 RADIO_2056_TX_LOFT_COARSE_Q |
18940 RADIO_2056_TX0,
18941 pi->calibration_cache.
18942 txcal_radio_regs_2G[5]);
18943 write_radio_reg(pi,
18944 RADIO_2056_TX_LOFT_COARSE_I |
18945 RADIO_2056_TX1,
18946 pi->calibration_cache.
18947 txcal_radio_regs_2G[6]);
18948 write_radio_reg(pi,
18949 RADIO_2056_TX_LOFT_COARSE_Q |
18950 RADIO_2056_TX1,
18951 pi->calibration_cache.
18952 txcal_radio_regs_2G[7]);
18953 } else {
18954 write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
18955 pi->calibration_cache.
18956 txcal_radio_regs_2G[0]);
18957 write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
18958 pi->calibration_cache.
18959 txcal_radio_regs_2G[1]);
18960 write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
18961 pi->calibration_cache.
18962 txcal_radio_regs_2G[2]);
18963 write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
18964 pi->calibration_cache.
18965 txcal_radio_regs_2G[3]);
18966 }
18967
18968 wlc_phy_rx_iq_coeffs_nphy(pi, 1,
18969 &pi->calibration_cache.
18970 rxcal_coeffs_2G);
18971 } else {
18972 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18973 txcal_radio_regs =
18974 pi->calibration_cache.txcal_radio_regs_5G;
18975 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
18976
18977 write_radio_reg(pi,
18978 RADIO_2056_TX_LOFT_FINE_I |
18979 RADIO_2056_TX0,
18980 pi->calibration_cache.
18981 txcal_radio_regs_5G[0]);
18982 write_radio_reg(pi,
18983 RADIO_2056_TX_LOFT_FINE_Q |
18984 RADIO_2056_TX0,
18985 pi->calibration_cache.
18986 txcal_radio_regs_5G[1]);
18987 write_radio_reg(pi,
18988 RADIO_2056_TX_LOFT_FINE_I |
18989 RADIO_2056_TX1,
18990 pi->calibration_cache.
18991 txcal_radio_regs_5G[2]);
18992 write_radio_reg(pi,
18993 RADIO_2056_TX_LOFT_FINE_Q |
18994 RADIO_2056_TX1,
18995 pi->calibration_cache.
18996 txcal_radio_regs_5G[3]);
18997
18998 write_radio_reg(pi,
18999 RADIO_2056_TX_LOFT_COARSE_I |
19000 RADIO_2056_TX0,
19001 pi->calibration_cache.
19002 txcal_radio_regs_5G[4]);
19003 write_radio_reg(pi,
19004 RADIO_2056_TX_LOFT_COARSE_Q |
19005 RADIO_2056_TX0,
19006 pi->calibration_cache.
19007 txcal_radio_regs_5G[5]);
19008 write_radio_reg(pi,
19009 RADIO_2056_TX_LOFT_COARSE_I |
19010 RADIO_2056_TX1,
19011 pi->calibration_cache.
19012 txcal_radio_regs_5G[6]);
19013 write_radio_reg(pi,
19014 RADIO_2056_TX_LOFT_COARSE_Q |
19015 RADIO_2056_TX1,
19016 pi->calibration_cache.
19017 txcal_radio_regs_5G[7]);
19018 } else {
19019 write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
19020 pi->calibration_cache.
19021 txcal_radio_regs_5G[0]);
19022 write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
19023 pi->calibration_cache.
19024 txcal_radio_regs_5G[1]);
19025 write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
19026 pi->calibration_cache.
19027 txcal_radio_regs_5G[2]);
19028 write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
19029 pi->calibration_cache.
19030 txcal_radio_regs_5G[3]);
19031 }
19032
19033 wlc_phy_rx_iq_coeffs_nphy(pi, 1,
19034 &pi->calibration_cache.
19035 rxcal_coeffs_5G);
19036 }
19037
19038 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
19039 for (coreNum = 0; coreNum <= 1; coreNum++) {
19040
19041 WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
19042 LOFT_FINE_I,
19043 txcal_radio_regs[2 * coreNum]);
19044 WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
19045 LOFT_FINE_Q,
19046 txcal_radio_regs[2 * coreNum + 1]);
19047
19048 WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
19049 LOFT_COARSE_I,
19050 txcal_radio_regs[2 * coreNum + 4]);
19051 WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
19052 LOFT_COARSE_Q,
19053 txcal_radio_regs[2 * coreNum + 5]);
19054 }
19055 }
19056}
19057
19058static void wlc_phy_txpwrctrl_coeff_setup_nphy(struct brcms_phy *pi)
19059{
19060 u32 idx;
19061 u16 iqloCalbuf[7];
19062 u32 iqcomp, locomp, curr_locomp;
19063 s8 locomp_i, locomp_q;
19064 s8 curr_locomp_i, curr_locomp_q;
19065 u32 tbl_id, tbl_len, tbl_offset;
19066 u32 regval[128];
19067
19068 if (pi->phyhang_avoid)
19069 wlc_phy_stay_in_carriersearch_nphy(pi, true);
19070
19071 wlc_phy_table_read_nphy(pi, 15, 7, 80, 16, iqloCalbuf);
19072
19073 tbl_len = 128;
19074 tbl_offset = 320;
19075 for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
19076 tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
19077 iqcomp =
19078 (tbl_id ==
19079 26) ? (((u32) (iqloCalbuf[0] & 0x3ff)) << 10) |
19080 (iqloCalbuf[1] & 0x3ff)
19081 : (((u32) (iqloCalbuf[2] & 0x3ff)) << 10) |
19082 (iqloCalbuf[3] & 0x3ff);
19083
19084 for (idx = 0; idx < tbl_len; idx++)
19085 regval[idx] = iqcomp;
19086 wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
19087 regval);
19088 }
19089
19090 tbl_offset = 448;
19091 for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
19092 tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
19093
19094 locomp =
19095 (u32) ((tbl_id == 26) ? iqloCalbuf[5] : iqloCalbuf[6]);
19096 locomp_i = (s8) ((locomp >> 8) & 0xff);
19097 locomp_q = (s8) ((locomp) & 0xff);
19098 for (idx = 0; idx < tbl_len; idx++) {
19099 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19100 curr_locomp_i = locomp_i;
19101 curr_locomp_q = locomp_q;
19102 } else {
19103 curr_locomp_i = (s8) ((locomp_i *
19104 nphy_tpc_loscale[idx] +
19105 128) >> 8);
19106 curr_locomp_q =
19107 (s8) ((locomp_q *
19108 nphy_tpc_loscale[idx] +
19109 128) >> 8);
19110 }
19111 curr_locomp = (u32) ((curr_locomp_i & 0xff) << 8);
19112 curr_locomp |= (u32) (curr_locomp_q & 0xff);
19113 regval[idx] = curr_locomp;
19114 }
19115 wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
19116 regval);
19117 }
19118
19119 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
19120
19121 wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX1, 0xFFFF);
19122 wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX2, 0xFFFF);
19123 }
19124
19125 if (pi->phyhang_avoid)
19126 wlc_phy_stay_in_carriersearch_nphy(pi, false);
19127}
19128
19129static void wlc_phy_txlpfbw_nphy(struct brcms_phy *pi)
19130{
19131 u8 tx_lpf_bw = 0;
19132
19133 if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
19134 if (CHSPEC_IS40(pi->radio_chanspec))
19135 tx_lpf_bw = 3;
19136 else
19137 tx_lpf_bw = 1;
19138
19139 if (PHY_IPA(pi)) {
19140 if (CHSPEC_IS40(pi->radio_chanspec))
19141 tx_lpf_bw = 5;
19142 else
19143 tx_lpf_bw = 4;
19144 }
19145
19146 write_phy_reg(pi, 0xe8,
19147 (tx_lpf_bw << 0) |
19148 (tx_lpf_bw << 3) |
19149 (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
19150
19151 if (PHY_IPA(pi)) {
19152
19153 if (CHSPEC_IS40(pi->radio_chanspec))
19154 tx_lpf_bw = 4;
19155 else
19156 tx_lpf_bw = 1;
19157
19158 write_phy_reg(pi, 0xe9,
19159 (tx_lpf_bw << 0) |
19160 (tx_lpf_bw << 3) |
19161 (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
19162 }
19163 }
19164}
19165
19166static void
19167wlc_phy_adjust_rx_analpfbw_nphy(struct brcms_phy *pi, u16 reduction_factr)
19168{
19169 if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
19170 if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
19171 CHSPEC_IS40(pi->radio_chanspec)) {
19172 if (!pi->nphy_anarxlpf_adjusted) {
19173 write_radio_reg(pi,
19174 (RADIO_2056_RX_RXLPF_RCCAL_LPC |
19175 RADIO_2056_RX0),
19176 ((pi->nphy_rccal_value +
19177 reduction_factr) | 0x80));
19178
19179 pi->nphy_anarxlpf_adjusted = true;
19180 }
19181 } else {
19182 if (pi->nphy_anarxlpf_adjusted) {
19183 write_radio_reg(pi,
19184 (RADIO_2056_RX_RXLPF_RCCAL_LPC |
19185 RADIO_2056_RX0),
19186 (pi->nphy_rccal_value | 0x80));
19187
19188 pi->nphy_anarxlpf_adjusted = false;
19189 }
19190 }
19191 }
19192}
19193
19194static void
19195wlc_phy_adjust_min_noisevar_nphy(struct brcms_phy *pi, int ntones,
19196 int *tone_id_buf, u32 *noise_var_buf)
19197{
19198 int i;
19199 u32 offset;
19200 int tone_id;
19201 int tbllen =
19202 CHSPEC_IS40(pi->radio_chanspec) ?
19203 NPHY_NOISEVAR_TBLLEN40 : NPHY_NOISEVAR_TBLLEN20;
19204
19205 if (pi->nphy_noisevars_adjusted) {
19206 for (i = 0; i < pi->nphy_saved_noisevars.bufcount; i++) {
19207 tone_id = pi->nphy_saved_noisevars.tone_id[i];
19208 offset = (tone_id >= 0) ?
19209 ((tone_id *
19210 2) + 1) : (tbllen + (tone_id * 2) + 1);
19211 wlc_phy_table_write_nphy(
19212 pi, NPHY_TBL_ID_NOISEVAR, 1,
19213 offset, 32,
19214 &pi->nphy_saved_noisevars.min_noise_vars[i]);
19215 }
19216
19217 pi->nphy_saved_noisevars.bufcount = 0;
19218 pi->nphy_noisevars_adjusted = false;
19219 }
19220
19221 if ((noise_var_buf != NULL) && (tone_id_buf != NULL)) {
19222 pi->nphy_saved_noisevars.bufcount = 0;
19223
19224 for (i = 0; i < ntones; i++) {
19225 tone_id = tone_id_buf[i];
19226 offset = (tone_id >= 0) ?
19227 ((tone_id * 2) + 1) :
19228 (tbllen + (tone_id * 2) + 1);
19229 pi->nphy_saved_noisevars.tone_id[i] = tone_id;
19230 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
19231 offset, 32,
19232 &pi->nphy_saved_noisevars.
19233 min_noise_vars[i]);
19234 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
19235 offset, 32, &noise_var_buf[i]);
19236 pi->nphy_saved_noisevars.bufcount++;
19237 }
19238
19239 pi->nphy_noisevars_adjusted = true;
19240 }
19241}
19242
19243static void wlc_phy_adjust_crsminpwr_nphy(struct brcms_phy *pi, u8 minpwr)
19244{
19245 u16 regval;
19246
19247 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19248 if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
19249 CHSPEC_IS40(pi->radio_chanspec)) {
19250 if (!pi->nphy_crsminpwr_adjusted) {
19251 regval = read_phy_reg(pi, 0x27d);
19252 pi->nphy_crsminpwr[0] = regval & 0xff;
19253 regval &= 0xff00;
19254 regval |= (u16) minpwr;
19255 write_phy_reg(pi, 0x27d, regval);
19256
19257 regval = read_phy_reg(pi, 0x280);
19258 pi->nphy_crsminpwr[1] = regval & 0xff;
19259 regval &= 0xff00;
19260 regval |= (u16) minpwr;
19261 write_phy_reg(pi, 0x280, regval);
19262
19263 regval = read_phy_reg(pi, 0x283);
19264 pi->nphy_crsminpwr[2] = regval & 0xff;
19265 regval &= 0xff00;
19266 regval |= (u16) minpwr;
19267 write_phy_reg(pi, 0x283, regval);
19268
19269 pi->nphy_crsminpwr_adjusted = true;
19270 }
19271 } else {
19272 if (pi->nphy_crsminpwr_adjusted) {
19273 regval = read_phy_reg(pi, 0x27d);
19274 regval &= 0xff00;
19275 regval |= pi->nphy_crsminpwr[0];
19276 write_phy_reg(pi, 0x27d, regval);
19277
19278 regval = read_phy_reg(pi, 0x280);
19279 regval &= 0xff00;
19280 regval |= pi->nphy_crsminpwr[1];
19281 write_phy_reg(pi, 0x280, regval);
19282
19283 regval = read_phy_reg(pi, 0x283);
19284 regval &= 0xff00;
19285 regval |= pi->nphy_crsminpwr[2];
19286 write_phy_reg(pi, 0x283, regval);
19287
19288 pi->nphy_crsminpwr_adjusted = false;
19289 }
19290 }
19291 }
19292}
19293
19294static void wlc_phy_spurwar_nphy(struct brcms_phy *pi)
19295{
19296 u16 cur_channel = 0;
19297 int nphy_adj_tone_id_buf[] = { 57, 58 };
19298 u32 nphy_adj_noise_var_buf[] = { 0x3ff, 0x3ff };
19299 bool isAdjustNoiseVar = false;
19300 uint numTonesAdjust = 0;
19301 u32 tempval = 0;
19302
19303 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19304 if (pi->phyhang_avoid)
19305 wlc_phy_stay_in_carriersearch_nphy(pi, true);
19306
19307 cur_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
19308
19309 if (pi->nphy_gband_spurwar_en) {
19310
19311 wlc_phy_adjust_rx_analpfbw_nphy(
19312 pi,
19313 NPHY_ANARXLPFBW_REDUCTIONFACT);
19314
19315 if (CHSPEC_IS2G(pi->radio_chanspec)) {
19316 if ((cur_channel == 11)
19317 && CHSPEC_IS40(pi->radio_chanspec))
19318 wlc_phy_adjust_min_noisevar_nphy(
19319 pi, 2,
19320 nphy_adj_tone_id_buf,
19321 nphy_adj_noise_var_buf);
19322 else
19323 wlc_phy_adjust_min_noisevar_nphy(pi, 0,
19324 NULL,
19325 NULL);
19326 }
19327
19328 wlc_phy_adjust_crsminpwr_nphy(pi,
19329 NPHY_ADJUSTED_MINCRSPOWER);
19330 }
19331
19332 if ((pi->nphy_gband_spurwar2_en)
19333 && CHSPEC_IS2G(pi->radio_chanspec)) {
19334
19335 if (CHSPEC_IS40(pi->radio_chanspec)) {
19336 switch (cur_channel) {
19337 case 3:
19338 nphy_adj_tone_id_buf[0] = 57;
19339 nphy_adj_tone_id_buf[1] = 58;
19340 nphy_adj_noise_var_buf[0] = 0x22f;
19341 nphy_adj_noise_var_buf[1] = 0x25f;
19342 isAdjustNoiseVar = true;
19343 break;
19344 case 4:
19345 nphy_adj_tone_id_buf[0] = 41;
19346 nphy_adj_tone_id_buf[1] = 42;
19347 nphy_adj_noise_var_buf[0] = 0x22f;
19348 nphy_adj_noise_var_buf[1] = 0x25f;
19349 isAdjustNoiseVar = true;
19350 break;
19351 case 5:
19352 nphy_adj_tone_id_buf[0] = 25;
19353 nphy_adj_tone_id_buf[1] = 26;
19354 nphy_adj_noise_var_buf[0] = 0x24f;
19355 nphy_adj_noise_var_buf[1] = 0x25f;
19356 isAdjustNoiseVar = true;
19357 break;
19358 case 6:
19359 nphy_adj_tone_id_buf[0] = 9;
19360 nphy_adj_tone_id_buf[1] = 10;
19361 nphy_adj_noise_var_buf[0] = 0x22f;
19362 nphy_adj_noise_var_buf[1] = 0x24f;
19363 isAdjustNoiseVar = true;
19364 break;
19365 case 7:
19366 nphy_adj_tone_id_buf[0] = 121;
19367 nphy_adj_tone_id_buf[1] = 122;
19368 nphy_adj_noise_var_buf[0] = 0x18f;
19369 nphy_adj_noise_var_buf[1] = 0x24f;
19370 isAdjustNoiseVar = true;
19371 break;
19372 case 8:
19373 nphy_adj_tone_id_buf[0] = 105;
19374 nphy_adj_tone_id_buf[1] = 106;
19375 nphy_adj_noise_var_buf[0] = 0x22f;
19376 nphy_adj_noise_var_buf[1] = 0x25f;
19377 isAdjustNoiseVar = true;
19378 break;
19379 case 9:
19380 nphy_adj_tone_id_buf[0] = 89;
19381 nphy_adj_tone_id_buf[1] = 90;
19382 nphy_adj_noise_var_buf[0] = 0x22f;
19383 nphy_adj_noise_var_buf[1] = 0x24f;
19384 isAdjustNoiseVar = true;
19385 break;
19386 case 10:
19387 nphy_adj_tone_id_buf[0] = 73;
19388 nphy_adj_tone_id_buf[1] = 74;
19389 nphy_adj_noise_var_buf[0] = 0x22f;
19390 nphy_adj_noise_var_buf[1] = 0x24f;
19391 isAdjustNoiseVar = true;
19392 break;
19393 default:
19394 isAdjustNoiseVar = false;
19395 break;
19396 }
19397 }
19398
19399 if (isAdjustNoiseVar) {
19400 numTonesAdjust = sizeof(nphy_adj_tone_id_buf) /
19401 sizeof(nphy_adj_tone_id_buf[0]);
19402
19403 wlc_phy_adjust_min_noisevar_nphy(
19404 pi,
19405 numTonesAdjust,
19406 nphy_adj_tone_id_buf,
19407 nphy_adj_noise_var_buf);
19408
19409 tempval = 0;
19410
19411 } else {
19412 wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
19413 NULL);
19414 }
19415 }
19416
19417 if ((pi->nphy_aband_spurwar_en) &&
19418 (CHSPEC_IS5G(pi->radio_chanspec))) {
19419 switch (cur_channel) {
19420 case 54:
19421 nphy_adj_tone_id_buf[0] = 32;
19422 nphy_adj_noise_var_buf[0] = 0x25f;
19423 break;
19424 case 38:
19425 case 102:
19426 case 118:
19427 nphy_adj_tone_id_buf[0] = 0;
19428 nphy_adj_noise_var_buf[0] = 0x0;
19429 break;
19430 case 134:
19431 nphy_adj_tone_id_buf[0] = 32;
19432 nphy_adj_noise_var_buf[0] = 0x21f;
19433 break;
19434 case 151:
19435 nphy_adj_tone_id_buf[0] = 16;
19436 nphy_adj_noise_var_buf[0] = 0x23f;
19437 break;
19438 case 153:
19439 case 161:
19440 nphy_adj_tone_id_buf[0] = 48;
19441 nphy_adj_noise_var_buf[0] = 0x23f;
19442 break;
19443 default:
19444 nphy_adj_tone_id_buf[0] = 0;
19445 nphy_adj_noise_var_buf[0] = 0x0;
19446 break;
19447 }
19448
19449 if (nphy_adj_tone_id_buf[0]
19450 && nphy_adj_noise_var_buf[0])
19451 wlc_phy_adjust_min_noisevar_nphy(
19452 pi, 1,
19453 nphy_adj_tone_id_buf,
19454 nphy_adj_noise_var_buf);
19455 else
19456 wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
19457 NULL);
19458 }
19459
19460 if (pi->phyhang_avoid)
19461 wlc_phy_stay_in_carriersearch_nphy(pi, false);
19462 }
19463}
19464
19465void wlc_phy_init_nphy(struct brcms_phy *pi)
19466{
19467 u16 val;
19468 u16 clip1_ths[2];
19469 struct nphy_txgains target_gain;
19470 u8 tx_pwr_ctrl_state;
19471 bool do_nphy_cal = false;
19472 uint core;
19473 uint origidx, intr_val;
19474 struct d11regs __iomem *regs;
19475 u32 d11_clk_ctl_st;
19476 bool do_rssi_cal = false;
19477
19478 core = 0;
19479
19480 if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN))
19481 pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
19482
19483 if ((ISNPHY(pi)) && (NREV_GE(pi->pubpi.phy_rev, 5)) &&
19484 ((pi->sh->chippkg == BCM4717_PKG_ID) ||
19485 (pi->sh->chippkg == BCM4718_PKG_ID))) {
19486 if ((pi->sh->boardflags & BFL_EXTLNA) &&
19487 (CHSPEC_IS2G(pi->radio_chanspec)))
19488 ai_corereg(pi->sh->sih, SI_CC_IDX,
19489 offsetof(struct chipcregs, chipcontrol),
19490 0x40, 0x40);
19491 }
19492
19493 if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) &&
19494 CHSPEC_IS40(pi->radio_chanspec)) {
19495
19496 regs = (struct d11regs __iomem *)
19497 ai_switch_core(pi->sh->sih,
19498 D11_CORE_ID, &origidx,
19499 &intr_val);
19500 d11_clk_ctl_st = R_REG(&regs->clk_ctl_st);
19501 AND_REG(&regs->clk_ctl_st,
19502 ~(CCS_FORCEHT | CCS_HTAREQ));
19503
19504 W_REG(&regs->clk_ctl_st, d11_clk_ctl_st);
19505
19506 ai_restore_core(pi->sh->sih, origidx, intr_val);
19507 }
19508
19509 pi->use_int_tx_iqlo_cal_nphy =
19510 (PHY_IPA(pi) ||
19511 (NREV_GE(pi->pubpi.phy_rev, 7) ||
19512 (NREV_GE(pi->pubpi.phy_rev, 5)
19513 && pi->sh->boardflags2 & BFL2_INTERNDET_TXIQCAL)));
19514
19515 pi->internal_tx_iqlo_cal_tapoff_intpa_nphy = false;
19516
19517 pi->nphy_deaf_count = 0;
19518
19519 wlc_phy_tbl_init_nphy(pi);
19520
19521 pi->nphy_crsminpwr_adjusted = false;
19522 pi->nphy_noisevars_adjusted = false;
19523
19524 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19525 write_phy_reg(pi, 0xe7, 0);
19526 write_phy_reg(pi, 0xec, 0);
19527 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
19528 write_phy_reg(pi, 0x342, 0);
19529 write_phy_reg(pi, 0x343, 0);
19530 write_phy_reg(pi, 0x346, 0);
19531 write_phy_reg(pi, 0x347, 0);
19532 }
19533 write_phy_reg(pi, 0xe5, 0);
19534 write_phy_reg(pi, 0xe6, 0);
19535 } else {
19536 write_phy_reg(pi, 0xec, 0);
19537 }
19538
19539 write_phy_reg(pi, 0x91, 0);
19540 write_phy_reg(pi, 0x92, 0);
19541 if (NREV_LT(pi->pubpi.phy_rev, 6)) {
19542 write_phy_reg(pi, 0x93, 0);
19543 write_phy_reg(pi, 0x94, 0);
19544 }
19545
19546 and_phy_reg(pi, 0xa1, ~3);
19547
19548 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19549 write_phy_reg(pi, 0x8f, 0);
19550 write_phy_reg(pi, 0xa5, 0);
19551 } else {
19552 write_phy_reg(pi, 0xa5, 0);
19553 }
19554
19555 if (NREV_IS(pi->pubpi.phy_rev, 2))
19556 mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
19557 else if (NREV_LT(pi->pubpi.phy_rev, 2))
19558 mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
19559
19560 write_phy_reg(pi, 0x203, 32);
19561 write_phy_reg(pi, 0x201, 32);
19562
19563 if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD)
19564 write_phy_reg(pi, 0x20d, 160);
19565 else
19566 write_phy_reg(pi, 0x20d, 184);
19567
19568 write_phy_reg(pi, 0x13a, 200);
19569
19570 write_phy_reg(pi, 0x70, 80);
19571
19572 write_phy_reg(pi, 0x1ff, 48);
19573
19574 if (NREV_LT(pi->pubpi.phy_rev, 8))
19575 wlc_phy_update_mimoconfig_nphy(pi, pi->n_preamble_override);
19576
19577 wlc_phy_stf_chain_upd_nphy(pi);
19578
19579 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
19580 write_phy_reg(pi, 0x180, 0xaa8);
19581 write_phy_reg(pi, 0x181, 0x9a4);
19582 }
19583
19584 if (PHY_IPA(pi)) {
19585 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
19586
19587 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
19588 0x29b, (0x1 << 0), (1) << 0);
19589
19590 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x298 :
19591 0x29c, (0x1ff << 7),
19592 (pi->nphy_papd_epsilon_offset[core]) << 7);
19593
19594 }
19595
19596 wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
19597 } else if (NREV_GE(pi->pubpi.phy_rev, 5)) {
19598 wlc_phy_extpa_set_tx_digi_filts_nphy(pi);
19599 }
19600
19601 wlc_phy_workarounds_nphy(pi);
19602
19603 wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
19604
19605 val = read_phy_reg(pi, 0x01);
19606 write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
19607 write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
19608 wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
19609
19610 wlapi_bmac_macphyclk_set(pi->sh->physhim, ON);
19611
19612 wlc_phy_pa_override_nphy(pi, OFF);
19613 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
19614 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
19615 wlc_phy_pa_override_nphy(pi, ON);
19616
19617 wlc_phy_classifier_nphy(pi, 0, 0);
19618 wlc_phy_clip_det_nphy(pi, 0, clip1_ths);
19619
19620 if (CHSPEC_IS2G(pi->radio_chanspec))
19621 wlc_phy_bphy_init_nphy(pi);
19622
19623 tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
19624 wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
19625
19626 wlc_phy_txpwr_fixpower_nphy(pi);
19627
19628 wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
19629
19630 wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
19631
19632 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19633 u32 *tx_pwrctrl_tbl = NULL;
19634 u16 idx;
19635 s16 pga_gn = 0;
19636 s16 pad_gn = 0;
19637 s32 rfpwr_offset;
19638
19639 if (PHY_IPA(pi)) {
19640 tx_pwrctrl_tbl = wlc_phy_get_ipa_gaintbl_nphy(pi);
19641 } else {
19642 if (CHSPEC_IS5G(pi->radio_chanspec)) {
19643 if (NREV_IS(pi->pubpi.phy_rev, 3))
19644 tx_pwrctrl_tbl =
19645 nphy_tpc_5GHz_txgain_rev3;
19646 else if (NREV_IS(pi->pubpi.phy_rev, 4))
19647 tx_pwrctrl_tbl =
19648 (pi->srom_fem5g.extpagain ==
19649 3) ?
19650 nphy_tpc_5GHz_txgain_HiPwrEPA :
19651 nphy_tpc_5GHz_txgain_rev4;
19652 else
19653 tx_pwrctrl_tbl =
19654 nphy_tpc_5GHz_txgain_rev5;
19655 } else {
19656 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
19657 if (pi->pubpi.radiorev == 5)
19658 tx_pwrctrl_tbl =
19659 nphy_tpc_txgain_epa_2057rev5;
19660 else if (pi->pubpi.radiorev == 3)
19661 tx_pwrctrl_tbl =
19662 nphy_tpc_txgain_epa_2057rev3;
19663 } else {
19664 if (NREV_GE(pi->pubpi.phy_rev, 5) &&
19665 (pi->srom_fem2g.extpagain == 3))
19666 tx_pwrctrl_tbl =
19667 nphy_tpc_txgain_HiPwrEPA;
19668 else
19669 tx_pwrctrl_tbl =
19670 nphy_tpc_txgain_rev3;
19671 }
19672 }
19673 }
19674
19675 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
19676 192, 32, tx_pwrctrl_tbl);
19677 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
19678 192, 32, tx_pwrctrl_tbl);
19679
19680 pi->nphy_gmval = (u16) ((*tx_pwrctrl_tbl >> 16) & 0x7000);
19681
19682 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
19683
19684 for (idx = 0; idx < 128; idx++) {
19685 pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
19686 pad_gn = (tx_pwrctrl_tbl[idx] >> 19) & 0x1f;
19687 rfpwr_offset = get_rf_pwr_offset(pi, pga_gn,
19688 pad_gn);
19689 wlc_phy_table_write_nphy(
19690 pi,
19691 NPHY_TBL_ID_CORE1TXPWRCTL,
19692 1, 576 + idx, 32,
19693 &rfpwr_offset);
19694 wlc_phy_table_write_nphy(
19695 pi,
19696 NPHY_TBL_ID_CORE2TXPWRCTL,
19697 1, 576 + idx, 32,
19698 &rfpwr_offset);
19699 }
19700 } else {
19701
19702 for (idx = 0; idx < 128; idx++) {
19703 pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
19704 if (CHSPEC_IS2G(pi->radio_chanspec))
19705 rfpwr_offset = (s16)
19706 nphy_papd_pga_gain_delta_ipa_2g
19707 [pga_gn];
19708 else
19709 rfpwr_offset = (s16)
19710 nphy_papd_pga_gain_delta_ipa_5g
19711 [pga_gn];
19712
19713 wlc_phy_table_write_nphy(
19714 pi,
19715 NPHY_TBL_ID_CORE1TXPWRCTL,
19716 1, 576 + idx, 32,
19717 &rfpwr_offset);
19718 wlc_phy_table_write_nphy(
19719 pi,
19720 NPHY_TBL_ID_CORE2TXPWRCTL,
19721 1, 576 + idx, 32,
19722 &rfpwr_offset);
19723 }
19724
19725 }
19726 } else {
19727
19728 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
19729 192, 32, nphy_tpc_txgain);
19730 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
19731 192, 32, nphy_tpc_txgain);
19732 }
19733
19734 if (pi->sh->phyrxchain != 0x3)
19735 wlc_phy_rxcore_setstate_nphy((struct brcms_phy_pub *) pi,
19736 pi->sh->phyrxchain);
19737
19738 if (PHY_PERICAL_MPHASE_PENDING(pi))
19739 wlc_phy_cal_perical_mphase_restart(pi);
19740
19741 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19742 do_rssi_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
19743 (pi->nphy_rssical_chanspec_2G == 0) :
19744 (pi->nphy_rssical_chanspec_5G == 0);
19745
19746 if (do_rssi_cal)
19747 wlc_phy_rssi_cal_nphy(pi);
19748 else
19749 wlc_phy_restore_rssical_nphy(pi);
19750 } else {
19751 wlc_phy_rssi_cal_nphy(pi);
19752 }
19753
19754 if (!SCAN_RM_IN_PROGRESS(pi))
19755 do_nphy_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
19756 (pi->nphy_iqcal_chanspec_2G == 0) :
19757 (pi->nphy_iqcal_chanspec_5G == 0);
19758
19759 if (!pi->do_initcal)
19760 do_nphy_cal = false;
19761
19762 if (do_nphy_cal) {
19763
19764 target_gain = wlc_phy_get_tx_gain_nphy(pi);
19765
19766 if (pi->antsel_type == ANTSEL_2x3)
19767 wlc_phy_antsel_init((struct brcms_phy_pub *) pi,
19768 true);
19769
19770 if (pi->nphy_perical != PHY_PERICAL_MPHASE) {
19771 wlc_phy_rssi_cal_nphy(pi);
19772
19773 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19774 pi->nphy_cal_orig_pwr_idx[0] =
19775 pi->nphy_txpwrindex[PHY_CORE_0]
19776 .
19777 index_internal;
19778 pi->nphy_cal_orig_pwr_idx[1] =
19779 pi->nphy_txpwrindex[PHY_CORE_1]
19780 .
19781 index_internal;
19782
19783 wlc_phy_precal_txgain_nphy(pi);
19784 target_gain =
19785 wlc_phy_get_tx_gain_nphy(pi);
19786 }
19787
19788 if (wlc_phy_cal_txiqlo_nphy
19789 (pi, target_gain, true,
19790 false) == 0) {
19791 if (wlc_phy_cal_rxiq_nphy
19792 (pi, target_gain, 2,
19793 false) == 0)
19794 wlc_phy_savecal_nphy(pi);
19795
19796 }
19797 } else if (pi->mphase_cal_phase_id ==
19798 MPHASE_CAL_STATE_IDLE) {
19799 wlc_phy_cal_perical((struct brcms_phy_pub *) pi,
19800 PHY_PERICAL_PHYINIT);
19801 }
19802 } else {
19803 wlc_phy_restorecal_nphy(pi);
19804 }
19805
19806 wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
19807
19808 wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
19809
19810 wlc_phy_nphy_tkip_rifs_war(pi, pi->sh->_rifs_phy);
19811
19812 if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LE(pi->pubpi.phy_rev, 6))
19813
19814 write_phy_reg(pi, 0x70, 50);
19815
19816 wlc_phy_txlpfbw_nphy(pi);
19817
19818 wlc_phy_spurwar_nphy(pi);
19819
19820}
19821
19822static void wlc_phy_resetcca_nphy(struct brcms_phy *pi)
19823{
19824 u16 val;
19825
19826 wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
19827
19828 val = read_phy_reg(pi, 0x01);
19829 write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
19830 udelay(1);
19831 write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
19832
19833 wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
19834
19835 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
19836}
19837
19838void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en)
19839{
19840 u16 rfctrlintc_override_val;
19841
19842 if (!en) {
19843
19844 pi->rfctrlIntc1_save = read_phy_reg(pi, 0x91);
19845 pi->rfctrlIntc2_save = read_phy_reg(pi, 0x92);
19846
19847 if (NREV_GE(pi->pubpi.phy_rev, 7))
19848 rfctrlintc_override_val = 0x1480;
19849 else if (NREV_GE(pi->pubpi.phy_rev, 3))
19850 rfctrlintc_override_val =
19851 CHSPEC_IS5G(pi->radio_chanspec) ? 0x600 : 0x480;
19852 else
19853 rfctrlintc_override_val =
19854 CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
19855
19856 write_phy_reg(pi, 0x91, rfctrlintc_override_val);
19857 write_phy_reg(pi, 0x92, rfctrlintc_override_val);
19858 } else {
19859 write_phy_reg(pi, 0x91, pi->rfctrlIntc1_save);
19860 write_phy_reg(pi, 0x92, pi->rfctrlIntc2_save);
19861 }
19862
19863}
19864
19865void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi)
19866{
19867
19868 u16 txrx_chain =
19869 (NPHY_RfseqCoreActv_TxRxChain0 | NPHY_RfseqCoreActv_TxRxChain1);
19870 bool CoreActv_override = false;
19871
19872 if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN0) {
19873 txrx_chain = NPHY_RfseqCoreActv_TxRxChain0;
19874 CoreActv_override = true;
19875
19876 if (NREV_LE(pi->pubpi.phy_rev, 2))
19877 and_phy_reg(pi, 0xa0, ~0x20);
19878 } else if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN1) {
19879 txrx_chain = NPHY_RfseqCoreActv_TxRxChain1;
19880 CoreActv_override = true;
19881
19882 if (NREV_LE(pi->pubpi.phy_rev, 2))
19883 or_phy_reg(pi, 0xa0, 0x20);
19884 }
19885
19886 mod_phy_reg(pi, 0xa2, ((0xf << 0) | (0xf << 4)), txrx_chain);
19887
19888 if (CoreActv_override) {
19889 pi->nphy_perical = PHY_PERICAL_DISABLE;
19890 or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
19891 } else {
19892 pi->nphy_perical = PHY_PERICAL_MPHASE;
19893 and_phy_reg(pi, 0xa1, ~NPHY_RfseqMode_CoreActv_override);
19894 }
19895}
19896
19897void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask)
19898{
19899 u16 regval;
19900 u16 tbl_buf[16];
19901 uint i;
19902 struct brcms_phy *pi = (struct brcms_phy *) pih;
19903 u16 tbl_opcode;
19904 bool suspend;
19905
19906 pi->sh->phyrxchain = rxcore_bitmask;
19907
19908 if (!pi->sh->clk)
19909 return;
19910
19911 suspend = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
19912 if (!suspend)
19913 wlapi_suspend_mac_and_wait(pi->sh->physhim);
19914
19915 if (pi->phyhang_avoid)
19916 wlc_phy_stay_in_carriersearch_nphy(pi, true);
19917
19918 regval = read_phy_reg(pi, 0xa2);
19919 regval &= ~(0xf << 4);
19920 regval |= ((u16) (rxcore_bitmask & 0x3)) << 4;
19921 write_phy_reg(pi, 0xa2, regval);
19922
19923 if ((rxcore_bitmask & 0x3) != 0x3) {
19924
19925 write_phy_reg(pi, 0x20e, 1);
19926
19927 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19928 if (pi->rx2tx_biasentry == -1) {
19929 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ,
19930 ARRAY_SIZE(tbl_buf), 80,
19931 16, tbl_buf);
19932
19933 for (i = 0; i < ARRAY_SIZE(tbl_buf); i++) {
19934 if (tbl_buf[i] ==
19935 NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS) {
19936 pi->rx2tx_biasentry = (u8) i;
19937 tbl_opcode =
19938 NPHY_REV3_RFSEQ_CMD_NOP;
19939 wlc_phy_table_write_nphy(
19940 pi,
19941 NPHY_TBL_ID_RFSEQ,
19942 1, i,
19943 16,
19944 &tbl_opcode);
19945 break;
19946 } else if (tbl_buf[i] ==
19947 NPHY_REV3_RFSEQ_CMD_END)
19948 break;
19949 }
19950 }
19951 }
19952 } else {
19953
19954 write_phy_reg(pi, 0x20e, 30);
19955
19956 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19957 if (pi->rx2tx_biasentry != -1) {
19958 tbl_opcode = NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS;
19959 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
19960 1, pi->rx2tx_biasentry,
19961 16, &tbl_opcode);
19962 pi->rx2tx_biasentry = -1;
19963 }
19964 }
19965 }
19966
19967 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
19968
19969 if (pi->phyhang_avoid)
19970 wlc_phy_stay_in_carriersearch_nphy(pi, false);
19971
19972 if (!suspend)
19973 wlapi_enable_mac(pi->sh->physhim);
19974}
19975
19976u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih)
19977{
19978 u16 regval, rxen_bits;
19979 struct brcms_phy *pi = (struct brcms_phy *) pih;
19980
19981 regval = read_phy_reg(pi, 0xa2);
19982 rxen_bits = (regval >> 4) & 0xf;
19983
19984 return (u8) rxen_bits;
19985}
19986
19987bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pi)
19988{
19989 return PHY_IPA(pi);
19990}
19991
19992void wlc_phy_cal_init_nphy(struct brcms_phy *pi)
19993{
19994}
19995
19996static void wlc_phy_radio_preinit_205x(struct brcms_phy *pi)
19997{
19998
19999 and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
20000 and_phy_reg(pi, 0x78, RFCC_OE_POR_FORCE);
20001
20002 or_phy_reg(pi, 0x78, ~RFCC_OE_POR_FORCE);
20003 or_phy_reg(pi, 0x78, RFCC_CHIP0_PU);
20004
20005}
20006
20007static void wlc_phy_radio_init_2057(struct brcms_phy *pi)
20008{
20009 struct radio_20xx_regs *regs_2057_ptr = NULL;
20010
20011 if (NREV_IS(pi->pubpi.phy_rev, 7)) {
20012 regs_2057_ptr = regs_2057_rev4;
20013 } else if (NREV_IS(pi->pubpi.phy_rev, 8)
20014 || NREV_IS(pi->pubpi.phy_rev, 9)) {
20015 switch (pi->pubpi.radiorev) {
20016 case 5:
20017
20018 if (pi->pubpi.radiover == 0x0)
20019 regs_2057_ptr = regs_2057_rev5;
20020 else if (pi->pubpi.radiover == 0x1)
20021 regs_2057_ptr = regs_2057_rev5v1;
20022 else
20023 break;
20024
20025 case 7:
20026
20027 regs_2057_ptr = regs_2057_rev7;
20028 break;
20029
20030 case 8:
20031
20032 regs_2057_ptr = regs_2057_rev8;
20033 break;
20034
20035 default:
20036 break;
20037 }
20038 }
20039
20040 wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr);
20041}
20042
20043static u16 wlc_phy_radio205x_rcal(struct brcms_phy *pi)
20044{
20045 u16 rcal_reg = 0;
20046 int i;
20047
20048 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
20049
20050 if (pi->pubpi.radiorev == 5) {
20051
20052 and_phy_reg(pi, 0x342, ~(0x1 << 1));
20053
20054 udelay(10);
20055
20056 mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x1);
20057 mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
20058 0x1);
20059 }
20060 mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x1);
20061
20062 udelay(10);
20063
20064 mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x3, 0x3);
20065
20066 for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
20067 rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS);
20068 if (rcal_reg & 0x1)
20069 break;
20070
20071 udelay(100);
20072 }
20073
20074 if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
20075 "HW error: radio calib2"))
20076 return 0;
20077
20078 mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x2, 0x0);
20079
20080 rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS) & 0x3e;
20081
20082 mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x0);
20083 if (pi->pubpi.radiorev == 5) {
20084
20085 mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x0);
20086 mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
20087 0x0);
20088 }
20089
20090 if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
20091
20092 mod_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x3c,
20093 rcal_reg);
20094 mod_radio_reg(pi, RADIO_2057_BANDGAP_RCAL_TRIM, 0xf0,
20095 rcal_reg << 2);
20096 }
20097
20098 } else if (NREV_IS(pi->pubpi.phy_rev, 3)) {
20099 u16 savereg;
20100
20101 savereg =
20102 read_radio_reg(
20103 pi,
20104 RADIO_2056_SYN_PLL_MAST2 |
20105 RADIO_2056_SYN);
20106 write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
20107 savereg | 0x7);
20108 udelay(10);
20109
20110 write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
20111 0x1);
20112 udelay(10);
20113
20114 write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
20115 0x9);
20116
20117 for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
20118 rcal_reg = read_radio_reg(
20119 pi,
20120 RADIO_2056_SYN_RCAL_CODE_OUT |
20121 RADIO_2056_SYN);
20122 if (rcal_reg & 0x80)
20123 break;
20124
20125 udelay(100);
20126 }
20127
20128 if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
20129 "HW error: radio calib3"))
20130 return 0;
20131
20132 write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
20133 0x1);
20134
20135 rcal_reg =
20136 read_radio_reg(pi,
20137 RADIO_2056_SYN_RCAL_CODE_OUT |
20138 RADIO_2056_SYN);
20139
20140 write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
20141 0x0);
20142
20143 write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
20144 savereg);
20145
20146 return rcal_reg & 0x1f;
20147 }
20148 return rcal_reg & 0x3e;
20149}
20150
20151static u16 wlc_phy_radio2057_rccal(struct brcms_phy *pi)
20152{
20153 u16 rccal_valid;
20154 int i;
20155 bool chip43226_6362A0;
20156
20157 chip43226_6362A0 = ((pi->pubpi.radiorev == 3)
20158 || (pi->pubpi.radiorev == 4)
20159 || (pi->pubpi.radiorev == 6));
20160
20161 rccal_valid = 0;
20162 if (chip43226_6362A0) {
20163 write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x61);
20164 write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xc0);
20165 } else {
20166 write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x61);
20167
20168 write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xe9);
20169 }
20170 write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
20171 write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
20172
20173 for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
20174 rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
20175 if (rccal_valid & 0x2)
20176 break;
20177
20178 udelay(500);
20179 }
20180
20181 write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
20182
20183 rccal_valid = 0;
20184 if (chip43226_6362A0) {
20185 write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x69);
20186 write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
20187 } else {
20188 write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x69);
20189
20190 write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xd5);
20191 }
20192 write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
20193 write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
20194
20195 for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
20196 rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
20197 if (rccal_valid & 0x2)
20198 break;
20199
20200 udelay(500);
20201 }
20202
20203 write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
20204
20205 rccal_valid = 0;
20206 if (chip43226_6362A0) {
20207 write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x73);
20208
20209 write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x28);
20210 write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
20211 } else {
20212 write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x73);
20213 write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
20214 write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0x99);
20215 }
20216 write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
20217
20218 for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
20219 rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
20220 if (rccal_valid & 0x2)
20221 break;
20222
20223 udelay(500);
20224 }
20225
20226 if (WARN(!(rccal_valid & 0x2), "HW error: radio calib4"))
20227 return 0;
20228
20229 write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
20230
20231 return rccal_valid;
20232}
20233
20234static void wlc_phy_radio_postinit_2057(struct brcms_phy *pi)
20235{
20236
20237 mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x1, 0x1);
20238
20239 mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x78);
20240 mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x80);
20241 mdelay(2);
20242 mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x0);
20243 mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x0);
20244
20245 if (pi->phy_init_por) {
20246 wlc_phy_radio205x_rcal(pi);
20247 wlc_phy_radio2057_rccal(pi);
20248 }
20249
20250 mod_radio_reg(pi, RADIO_2057_RFPLL_MASTER, 0x8, 0x0);
20251}
20252
20253static void wlc_phy_radio_init_2056(struct brcms_phy *pi)
20254{
20255 const struct radio_regs *regs_SYN_2056_ptr = NULL;
20256 const struct radio_regs *regs_TX_2056_ptr = NULL;
20257 const struct radio_regs *regs_RX_2056_ptr = NULL;
20258
20259 if (NREV_IS(pi->pubpi.phy_rev, 3)) {
20260 regs_SYN_2056_ptr = regs_SYN_2056;
20261 regs_TX_2056_ptr = regs_TX_2056;
20262 regs_RX_2056_ptr = regs_RX_2056;
20263 } else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
20264 regs_SYN_2056_ptr = regs_SYN_2056_A1;
20265 regs_TX_2056_ptr = regs_TX_2056_A1;
20266 regs_RX_2056_ptr = regs_RX_2056_A1;
20267 } else {
20268 switch (pi->pubpi.radiorev) {
20269 case 5:
20270 regs_SYN_2056_ptr = regs_SYN_2056_rev5;
20271 regs_TX_2056_ptr = regs_TX_2056_rev5;
20272 regs_RX_2056_ptr = regs_RX_2056_rev5;
20273 break;
20274
20275 case 6:
20276 regs_SYN_2056_ptr = regs_SYN_2056_rev6;
20277 regs_TX_2056_ptr = regs_TX_2056_rev6;
20278 regs_RX_2056_ptr = regs_RX_2056_rev6;
20279 break;
20280
20281 case 7:
20282 case 9:
20283 regs_SYN_2056_ptr = regs_SYN_2056_rev7;
20284 regs_TX_2056_ptr = regs_TX_2056_rev7;
20285 regs_RX_2056_ptr = regs_RX_2056_rev7;
20286 break;
20287
20288 case 8:
20289 regs_SYN_2056_ptr = regs_SYN_2056_rev8;
20290 regs_TX_2056_ptr = regs_TX_2056_rev8;
20291 regs_RX_2056_ptr = regs_RX_2056_rev8;
20292 break;
20293
20294 case 11:
20295 regs_SYN_2056_ptr = regs_SYN_2056_rev11;
20296 regs_TX_2056_ptr = regs_TX_2056_rev11;
20297 regs_RX_2056_ptr = regs_RX_2056_rev11;
20298 break;
20299
20300 default:
20301 break;
20302 }
20303 }
20304
20305 wlc_phy_init_radio_regs(pi, regs_SYN_2056_ptr, (u16) RADIO_2056_SYN);
20306
20307 wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX0);
20308
20309 wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX1);
20310
20311 wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX0);
20312
20313 wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX1);
20314}
20315
20316static void wlc_phy_radio_postinit_2056(struct brcms_phy *pi)
20317{
20318 mod_radio_reg(pi, RADIO_2056_SYN_COM_CTRL, 0xb, 0xb);
20319
20320 mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x2);
20321 mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x2);
20322 udelay(1000);
20323 mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x0);
20324
20325 if ((pi->sh->boardflags2 & BFL2_LEGACY)
20326 || (pi->sh->boardflags2 & BFL2_XTALBUFOUTEN))
20327 mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xf4, 0x0);
20328 else
20329 mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xfc, 0x0);
20330
20331 mod_radio_reg(pi, RADIO_2056_SYN_RCCAL_CTRL0, 0x1, 0x0);
20332
20333 if (pi->phy_init_por)
20334 wlc_phy_radio205x_rcal(pi);
20335}
20336
20337static void wlc_phy_radio_preinit_2055(struct brcms_phy *pi)
20338{
20339
20340 and_phy_reg(pi, 0x78, ~RFCC_POR_FORCE);
20341 or_phy_reg(pi, 0x78, RFCC_CHIP0_PU | RFCC_OE_POR_FORCE);
20342
20343 or_phy_reg(pi, 0x78, RFCC_POR_FORCE);
20344}
20345
20346static void wlc_phy_radio_init_2055(struct brcms_phy *pi)
20347{
20348 wlc_phy_init_radio_regs(pi, regs_2055, RADIO_DEFAULT_CORE);
20349}
20350
20351static void wlc_phy_radio_postinit_2055(struct brcms_phy *pi)
20352{
20353
20354 and_radio_reg(pi, RADIO_2055_MASTER_CNTRL1,
20355 ~(RADIO_2055_JTAGCTRL_MASK | RADIO_2055_JTAGSYNC_MASK));
20356
20357 if (((pi->sh->sromrev >= 4)
20358 && !(pi->sh->boardflags2 & BFL2_RXBB_INT_REG_DIS))
20359 || ((pi->sh->sromrev < 4))) {
20360 and_radio_reg(pi, RADIO_2055_CORE1_RXBB_REGULATOR, 0x7F);
20361 and_radio_reg(pi, RADIO_2055_CORE2_RXBB_REGULATOR, 0x7F);
20362 }
20363
20364 mod_radio_reg(pi, RADIO_2055_RRCCAL_N_OPT_SEL, 0x3F, 0x2C);
20365 write_radio_reg(pi, RADIO_2055_CAL_MISC, 0x3C);
20366
20367 and_radio_reg(pi, RADIO_2055_CAL_MISC,
20368 ~(RADIO_2055_RRCAL_START | RADIO_2055_RRCAL_RST_N));
20369
20370 or_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, RADIO_2055_CAL_LPO_ENABLE);
20371
20372 or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_RST_N);
20373
20374 udelay(1000);
20375
20376 or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_START);
20377
20378 SPINWAIT(((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
20379 RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE), 2000);
20380
20381 if (WARN((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
20382 RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE,
20383 "HW error: radio calibration1\n"))
20384 return;
20385
20386 and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL,
20387 ~(RADIO_2055_CAL_LPO_ENABLE));
20388
20389 wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec);
20390
20391 write_radio_reg(pi, RADIO_2055_CORE1_RXBB_LPF, 9);
20392 write_radio_reg(pi, RADIO_2055_CORE2_RXBB_LPF, 9);
20393
20394 write_radio_reg(pi, RADIO_2055_CORE1_RXBB_MIDAC_HIPAS, 0x83);
20395 write_radio_reg(pi, RADIO_2055_CORE2_RXBB_MIDAC_HIPAS, 0x83);
20396
20397 mod_radio_reg(pi, RADIO_2055_CORE1_LNA_GAINBST,
20398 RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
20399 mod_radio_reg(pi, RADIO_2055_CORE2_LNA_GAINBST,
20400 RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
20401 if (pi->nphy_gain_boost) {
20402 and_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
20403 ~(RADIO_2055_GAINBST_DISABLE));
20404 and_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
20405 ~(RADIO_2055_GAINBST_DISABLE));
20406 } else {
20407 or_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
20408 RADIO_2055_GAINBST_DISABLE);
20409 or_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
20410 RADIO_2055_GAINBST_DISABLE);
20411 }
20412
20413 udelay(2);
20414}
20415
20416void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on)
20417{
20418 if (on) {
20419 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
20420 if (!pi->radio_is_on) {
20421 wlc_phy_radio_preinit_205x(pi);
20422 wlc_phy_radio_init_2057(pi);
20423 wlc_phy_radio_postinit_2057(pi);
20424 }
20425
20426 wlc_phy_chanspec_set((struct brcms_phy_pub *) pi,
20427 pi->radio_chanspec);
20428 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
20429 wlc_phy_radio_preinit_205x(pi);
20430 wlc_phy_radio_init_2056(pi);
20431 wlc_phy_radio_postinit_2056(pi);
20432
20433 wlc_phy_chanspec_set((struct brcms_phy_pub *) pi,
20434 pi->radio_chanspec);
20435 } else {
20436 wlc_phy_radio_preinit_2055(pi);
20437 wlc_phy_radio_init_2055(pi);
20438 wlc_phy_radio_postinit_2055(pi);
20439 }
20440
20441 pi->radio_is_on = true;
20442
20443 } else {
20444
20445 if (NREV_GE(pi->pubpi.phy_rev, 3)
20446 && NREV_LT(pi->pubpi.phy_rev, 7)) {
20447 and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
20448 mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x0);
20449
20450 write_radio_reg(pi,
20451 RADIO_2056_TX_PADA_BOOST_TUNE |
20452 RADIO_2056_TX0, 0);
20453 write_radio_reg(pi,
20454 RADIO_2056_TX_PADG_BOOST_TUNE |
20455 RADIO_2056_TX0, 0);
20456 write_radio_reg(pi,
20457 RADIO_2056_TX_PGAA_BOOST_TUNE |
20458 RADIO_2056_TX0, 0);
20459 write_radio_reg(pi,
20460 RADIO_2056_TX_PGAG_BOOST_TUNE |
20461 RADIO_2056_TX0, 0);
20462 mod_radio_reg(pi,
20463 RADIO_2056_TX_MIXA_BOOST_TUNE |
20464 RADIO_2056_TX0, 0xf0, 0);
20465 write_radio_reg(pi,
20466 RADIO_2056_TX_MIXG_BOOST_TUNE |
20467 RADIO_2056_TX0, 0);
20468
20469 write_radio_reg(pi,
20470 RADIO_2056_TX_PADA_BOOST_TUNE |
20471 RADIO_2056_TX1, 0);
20472 write_radio_reg(pi,
20473 RADIO_2056_TX_PADG_BOOST_TUNE |
20474 RADIO_2056_TX1, 0);
20475 write_radio_reg(pi,
20476 RADIO_2056_TX_PGAA_BOOST_TUNE |
20477 RADIO_2056_TX1, 0);
20478 write_radio_reg(pi,
20479 RADIO_2056_TX_PGAG_BOOST_TUNE |
20480 RADIO_2056_TX1, 0);
20481 mod_radio_reg(pi,
20482 RADIO_2056_TX_MIXA_BOOST_TUNE |
20483 RADIO_2056_TX1, 0xf0, 0);
20484 write_radio_reg(pi,
20485 RADIO_2056_TX_MIXG_BOOST_TUNE |
20486 RADIO_2056_TX1, 0);
20487
20488 pi->radio_is_on = false;
20489 }
20490
20491 if (NREV_GE(pi->pubpi.phy_rev, 8)) {
20492 and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
20493 pi->radio_is_on = false;
20494 }
20495
20496 }
20497}
20498
20499static bool
20500wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f,
20501 const struct chan_info_nphy_radio2057 **t0,
20502 const struct chan_info_nphy_radio205x **t1,
20503 const struct chan_info_nphy_radio2057_rev5 **t2,
20504 const struct chan_info_nphy_2055 **t3)
20505{
20506 uint i;
20507 const struct chan_info_nphy_radio2057 *chan_info_tbl_p_0 = NULL;
20508 const struct chan_info_nphy_radio205x *chan_info_tbl_p_1 = NULL;
20509 const struct chan_info_nphy_radio2057_rev5 *chan_info_tbl_p_2 = NULL;
20510 u32 tbl_len = 0;
20511
20512 int freq = 0;
20513
20514 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
20515
20516 if (NREV_IS(pi->pubpi.phy_rev, 7)) {
20517
20518 chan_info_tbl_p_0 = chan_info_nphyrev7_2057_rev4;
20519 tbl_len = ARRAY_SIZE(chan_info_nphyrev7_2057_rev4);
20520
20521 } else if (NREV_IS(pi->pubpi.phy_rev, 8)
20522 || NREV_IS(pi->pubpi.phy_rev, 9)) {
20523 switch (pi->pubpi.radiorev) {
20524
20525 case 5:
20526
20527 if (pi->pubpi.radiover == 0x0) {
20528
20529 chan_info_tbl_p_2 =
20530 chan_info_nphyrev8_2057_rev5;
20531 tbl_len = ARRAY_SIZE(
20532 chan_info_nphyrev8_2057_rev5);
20533
20534 } else if (pi->pubpi.radiover == 0x1) {
20535
20536 chan_info_tbl_p_2 =
20537 chan_info_nphyrev9_2057_rev5v1;
20538 tbl_len = ARRAY_SIZE(
20539 chan_info_nphyrev9_2057_rev5v1);
20540
20541 }
20542 break;
20543
20544 case 7:
20545 chan_info_tbl_p_0 =
20546 chan_info_nphyrev8_2057_rev7;
20547 tbl_len = ARRAY_SIZE(
20548 chan_info_nphyrev8_2057_rev7);
20549 break;
20550
20551 case 8:
20552 chan_info_tbl_p_0 =
20553 chan_info_nphyrev8_2057_rev8;
20554 tbl_len = ARRAY_SIZE(
20555 chan_info_nphyrev8_2057_rev8);
20556 break;
20557
20558 default:
20559 break;
20560 }
20561 } else if (NREV_IS(pi->pubpi.phy_rev, 16)) {
20562
20563 chan_info_tbl_p_0 = chan_info_nphyrev8_2057_rev8;
20564 tbl_len = ARRAY_SIZE(chan_info_nphyrev8_2057_rev8);
20565 } else {
20566 goto fail;
20567 }
20568
20569 for (i = 0; i < tbl_len; i++) {
20570 if (pi->pubpi.radiorev == 5) {
20571
20572 if (chan_info_tbl_p_2[i].chan == channel)
20573 break;
20574 } else {
20575
20576 if (chan_info_tbl_p_0[i].chan == channel)
20577 break;
20578 }
20579 }
20580
20581 if (i >= tbl_len)
20582 goto fail;
20583
20584 if (pi->pubpi.radiorev == 5) {
20585 *t2 = &chan_info_tbl_p_2[i];
20586 freq = chan_info_tbl_p_2[i].freq;
20587 } else {
20588 *t0 = &chan_info_tbl_p_0[i];
20589 freq = chan_info_tbl_p_0[i].freq;
20590 }
20591
20592 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
20593 if (NREV_IS(pi->pubpi.phy_rev, 3)) {
20594 chan_info_tbl_p_1 = chan_info_nphyrev3_2056;
20595 tbl_len = ARRAY_SIZE(chan_info_nphyrev3_2056);
20596 } else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
20597 chan_info_tbl_p_1 = chan_info_nphyrev4_2056_A1;
20598 tbl_len = ARRAY_SIZE(chan_info_nphyrev4_2056_A1);
20599 } else if (NREV_IS(pi->pubpi.phy_rev, 5)
20600 || NREV_IS(pi->pubpi.phy_rev, 6)) {
20601 switch (pi->pubpi.radiorev) {
20602 case 5:
20603 chan_info_tbl_p_1 = chan_info_nphyrev5_2056v5;
20604 tbl_len = ARRAY_SIZE(chan_info_nphyrev5_2056v5);
20605 break;
20606 case 6:
20607 chan_info_tbl_p_1 = chan_info_nphyrev6_2056v6;
20608 tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v6);
20609 break;
20610 case 7:
20611 case 9:
20612 chan_info_tbl_p_1 = chan_info_nphyrev5n6_2056v7;
20613 tbl_len =
20614 ARRAY_SIZE(chan_info_nphyrev5n6_2056v7);
20615 break;
20616 case 8:
20617 chan_info_tbl_p_1 = chan_info_nphyrev6_2056v8;
20618 tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v8);
20619 break;
20620 case 11:
20621 chan_info_tbl_p_1 = chan_info_nphyrev6_2056v11;
20622 tbl_len = ARRAY_SIZE(
20623 chan_info_nphyrev6_2056v11);
20624 break;
20625 default:
20626 break;
20627 }
20628 }
20629
20630 for (i = 0; i < tbl_len; i++) {
20631 if (chan_info_tbl_p_1[i].chan == channel)
20632 break;
20633 }
20634
20635 if (i >= tbl_len)
20636 goto fail;
20637
20638 *t1 = &chan_info_tbl_p_1[i];
20639 freq = chan_info_tbl_p_1[i].freq;
20640
20641 } else {
20642 for (i = 0; i < ARRAY_SIZE(chan_info_nphy_2055); i++)
20643 if (chan_info_nphy_2055[i].chan == channel)
20644 break;
20645
20646 if (i >= ARRAY_SIZE(chan_info_nphy_2055))
20647 goto fail;
20648
20649 *t3 = &chan_info_nphy_2055[i];
20650 freq = chan_info_nphy_2055[i].freq;
20651 }
20652
20653 *f = freq;
20654 return true;
20655
20656fail:
20657 *f = WL_CHAN_FREQ_RANGE_2G;
20658 return false;
20659}
20660
20661u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint channel)
20662{
20663 int freq;
20664 const struct chan_info_nphy_radio2057 *t0 = NULL;
20665 const struct chan_info_nphy_radio205x *t1 = NULL;
20666 const struct chan_info_nphy_radio2057_rev5 *t2 = NULL;
20667 const struct chan_info_nphy_2055 *t3 = NULL;
20668
20669 if (channel == 0)
20670 channel = CHSPEC_CHANNEL(pi->radio_chanspec);
20671
20672 wlc_phy_chan2freq_nphy(pi, channel, &freq, &t0, &t1, &t2, &t3);
20673
20674 if (CHSPEC_IS2G(pi->radio_chanspec))
20675 return WL_CHAN_FREQ_RANGE_2G;
20676
20677 if ((freq >= BASE_LOW_5G_CHAN) && (freq < BASE_MID_5G_CHAN))
20678 return WL_CHAN_FREQ_RANGE_5GL;
20679 else if ((freq >= BASE_MID_5G_CHAN) && (freq < BASE_HIGH_5G_CHAN))
20680 return WL_CHAN_FREQ_RANGE_5GM;
20681 else
20682 return WL_CHAN_FREQ_RANGE_5GH;
20683}
20684
20685static void
20686wlc_phy_chanspec_radio2055_setup(struct brcms_phy *pi,
20687 const struct chan_info_nphy_2055 *ci)
20688{
20689
20690 write_radio_reg(pi, RADIO_2055_PLL_REF, ci->RF_pll_ref);
20691 write_radio_reg(pi, RADIO_2055_RF_PLL_MOD0, ci->RF_rf_pll_mod0);
20692 write_radio_reg(pi, RADIO_2055_RF_PLL_MOD1, ci->RF_rf_pll_mod1);
20693 write_radio_reg(pi, RADIO_2055_VCO_CAP_TAIL, ci->RF_vco_cap_tail);
20694
20695 BRCMS_PHY_WAR_PR51571(pi);
20696
20697 write_radio_reg(pi, RADIO_2055_VCO_CAL1, ci->RF_vco_cal1);
20698 write_radio_reg(pi, RADIO_2055_VCO_CAL2, ci->RF_vco_cal2);
20699 write_radio_reg(pi, RADIO_2055_PLL_LF_C1, ci->RF_pll_lf_c1);
20700 write_radio_reg(pi, RADIO_2055_PLL_LF_R1, ci->RF_pll_lf_r1);
20701
20702 BRCMS_PHY_WAR_PR51571(pi);
20703
20704 write_radio_reg(pi, RADIO_2055_PLL_LF_C2, ci->RF_pll_lf_c2);
20705 write_radio_reg(pi, RADIO_2055_LGBUF_CEN_BUF, ci->RF_lgbuf_cen_buf);
20706 write_radio_reg(pi, RADIO_2055_LGEN_TUNE1, ci->RF_lgen_tune1);
20707 write_radio_reg(pi, RADIO_2055_LGEN_TUNE2, ci->RF_lgen_tune2);
20708
20709 BRCMS_PHY_WAR_PR51571(pi);
20710
20711 write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_A_TUNE,
20712 ci->RF_core1_lgbuf_a_tune);
20713 write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_G_TUNE,
20714 ci->RF_core1_lgbuf_g_tune);
20715 write_radio_reg(pi, RADIO_2055_CORE1_RXRF_REG1, ci->RF_core1_rxrf_reg1);
20716 write_radio_reg(pi, RADIO_2055_CORE1_TX_PGA_PAD_TN,
20717 ci->RF_core1_tx_pga_pad_tn);
20718
20719 BRCMS_PHY_WAR_PR51571(pi);
20720
20721 write_radio_reg(pi, RADIO_2055_CORE1_TX_MX_BGTRIM,
20722 ci->RF_core1_tx_mx_bgtrim);
20723 write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_A_TUNE,
20724 ci->RF_core2_lgbuf_a_tune);
20725 write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_G_TUNE,
20726 ci->RF_core2_lgbuf_g_tune);
20727 write_radio_reg(pi, RADIO_2055_CORE2_RXRF_REG1, ci->RF_core2_rxrf_reg1);
20728
20729 BRCMS_PHY_WAR_PR51571(pi);
20730
20731 write_radio_reg(pi, RADIO_2055_CORE2_TX_PGA_PAD_TN,
20732 ci->RF_core2_tx_pga_pad_tn);
20733 write_radio_reg(pi, RADIO_2055_CORE2_TX_MX_BGTRIM,
20734 ci->RF_core2_tx_mx_bgtrim);
20735
20736 udelay(50);
20737
20738 write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x05);
20739 write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x45);
20740
20741 BRCMS_PHY_WAR_PR51571(pi);
20742
20743 write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x65);
20744
20745 udelay(300);
20746}
20747
20748static void
20749wlc_phy_chanspec_radio2056_setup(struct brcms_phy *pi,
20750 const struct chan_info_nphy_radio205x *ci)
20751{
20752 const struct radio_regs *regs_SYN_2056_ptr = NULL;
20753
20754 write_radio_reg(pi,
20755 RADIO_2056_SYN_PLL_VCOCAL1 | RADIO_2056_SYN,
20756 ci->RF_SYN_pll_vcocal1);
20757 write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL2 | RADIO_2056_SYN,
20758 ci->RF_SYN_pll_vcocal2);
20759 write_radio_reg(pi, RADIO_2056_SYN_PLL_REFDIV | RADIO_2056_SYN,
20760 ci->RF_SYN_pll_refdiv);
20761 write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD2 | RADIO_2056_SYN,
20762 ci->RF_SYN_pll_mmd2);
20763 write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD1 | RADIO_2056_SYN,
20764 ci->RF_SYN_pll_mmd1);
20765 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
20766 ci->RF_SYN_pll_loopfilter1);
20767 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
20768 ci->RF_SYN_pll_loopfilter2);
20769 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER3 | RADIO_2056_SYN,
20770 ci->RF_SYN_pll_loopfilter3);
20771 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
20772 ci->RF_SYN_pll_loopfilter4);
20773 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER5 | RADIO_2056_SYN,
20774 ci->RF_SYN_pll_loopfilter5);
20775 write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR27 | RADIO_2056_SYN,
20776 ci->RF_SYN_reserved_addr27);
20777 write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR28 | RADIO_2056_SYN,
20778 ci->RF_SYN_reserved_addr28);
20779 write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR29 | RADIO_2056_SYN,
20780 ci->RF_SYN_reserved_addr29);
20781 write_radio_reg(pi, RADIO_2056_SYN_LOGEN_VCOBUF1 | RADIO_2056_SYN,
20782 ci->RF_SYN_logen_VCOBUF1);
20783 write_radio_reg(pi, RADIO_2056_SYN_LOGEN_MIXER2 | RADIO_2056_SYN,
20784 ci->RF_SYN_logen_MIXER2);
20785 write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF3 | RADIO_2056_SYN,
20786 ci->RF_SYN_logen_BUF3);
20787 write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF4 | RADIO_2056_SYN,
20788 ci->RF_SYN_logen_BUF4);
20789
20790 write_radio_reg(pi,
20791 RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX0,
20792 ci->RF_RX0_lnaa_tune);
20793 write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX0,
20794 ci->RF_RX0_lnag_tune);
20795 write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX0,
20796 ci->RF_TX0_intpaa_boost_tune);
20797 write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX0,
20798 ci->RF_TX0_intpag_boost_tune);
20799 write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX0,
20800 ci->RF_TX0_pada_boost_tune);
20801 write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX0,
20802 ci->RF_TX0_padg_boost_tune);
20803 write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX0,
20804 ci->RF_TX0_pgaa_boost_tune);
20805 write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX0,
20806 ci->RF_TX0_pgag_boost_tune);
20807 write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX0,
20808 ci->RF_TX0_mixa_boost_tune);
20809 write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX0,
20810 ci->RF_TX0_mixg_boost_tune);
20811
20812 write_radio_reg(pi,
20813 RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX1,
20814 ci->RF_RX1_lnaa_tune);
20815 write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX1,
20816 ci->RF_RX1_lnag_tune);
20817 write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX1,
20818 ci->RF_TX1_intpaa_boost_tune);
20819 write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX1,
20820 ci->RF_TX1_intpag_boost_tune);
20821 write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX1,
20822 ci->RF_TX1_pada_boost_tune);
20823 write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX1,
20824 ci->RF_TX1_padg_boost_tune);
20825 write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX1,
20826 ci->RF_TX1_pgaa_boost_tune);
20827 write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX1,
20828 ci->RF_TX1_pgag_boost_tune);
20829 write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX1,
20830 ci->RF_TX1_mixa_boost_tune);
20831 write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX1,
20832 ci->RF_TX1_mixg_boost_tune);
20833
20834 if (NREV_IS(pi->pubpi.phy_rev, 3))
20835 regs_SYN_2056_ptr = regs_SYN_2056;
20836 else if (NREV_IS(pi->pubpi.phy_rev, 4))
20837 regs_SYN_2056_ptr = regs_SYN_2056_A1;
20838 else {
20839 switch (pi->pubpi.radiorev) {
20840 case 5:
20841 regs_SYN_2056_ptr = regs_SYN_2056_rev5;
20842 break;
20843 case 6:
20844 regs_SYN_2056_ptr = regs_SYN_2056_rev6;
20845 break;
20846 case 7:
20847 case 9:
20848 regs_SYN_2056_ptr = regs_SYN_2056_rev7;
20849 break;
20850 case 8:
20851 regs_SYN_2056_ptr = regs_SYN_2056_rev8;
20852 break;
20853 case 11:
20854 regs_SYN_2056_ptr = regs_SYN_2056_rev11;
20855 break;
20856 }
20857 }
20858 if (CHSPEC_IS2G(pi->radio_chanspec))
20859 write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
20860 RADIO_2056_SYN,
20861 (u16) regs_SYN_2056_ptr[0x49 - 2].init_g);
20862 else
20863 write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
20864 RADIO_2056_SYN,
20865 (u16) regs_SYN_2056_ptr[0x49 - 2].init_a);
20866
20867 if (pi->sh->boardflags2 & BFL2_GPLL_WAR) {
20868 if (CHSPEC_IS2G(pi->radio_chanspec)) {
20869 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
20870 RADIO_2056_SYN, 0x1f);
20871 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
20872 RADIO_2056_SYN, 0x1f);
20873
20874 write_radio_reg(pi,
20875 RADIO_2056_SYN_PLL_LOOPFILTER4 |
20876 RADIO_2056_SYN, 0xb);
20877 write_radio_reg(pi,
20878 RADIO_2056_SYN_PLL_CP2 |
20879 RADIO_2056_SYN, 0x14);
20880 }
20881 }
20882
20883 if ((pi->sh->boardflags2 & BFL2_GPLL_WAR2) &&
20884 (CHSPEC_IS2G(pi->radio_chanspec))) {
20885 write_radio_reg(pi,
20886 RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
20887 0x1f);
20888 write_radio_reg(pi,
20889 RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
20890 0x1f);
20891 write_radio_reg(pi,
20892 RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
20893 0xb);
20894 write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | RADIO_2056_SYN,
20895 0x20);
20896 }
20897
20898 if (pi->sh->boardflags2 & BFL2_APLL_WAR) {
20899 if (CHSPEC_IS5G(pi->radio_chanspec)) {
20900 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
20901 RADIO_2056_SYN, 0x1f);
20902 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
20903 RADIO_2056_SYN, 0x1f);
20904 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 |
20905 RADIO_2056_SYN, 0x5);
20906 write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
20907 RADIO_2056_SYN, 0xc);
20908 }
20909 }
20910
20911 if (PHY_IPA(pi) && CHSPEC_IS2G(pi->radio_chanspec)) {
20912 u16 pag_boost_tune;
20913 u16 padg_boost_tune;
20914 u16 pgag_boost_tune;
20915 u16 mixg_boost_tune;
20916 u16 bias, cascbias;
20917 uint core;
20918
20919 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
20920
20921 if (NREV_GE(pi->pubpi.phy_rev, 5)) {
20922
20923 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
20924 PADG_IDAC, 0xcc);
20925
20926 bias = 0x25;
20927 cascbias = 0x20;
20928
20929 if ((pi->sh->chip ==
20930 BCM43224_CHIP_ID)
20931 || (pi->sh->chip ==
20932 BCM43225_CHIP_ID)) {
20933 if (pi->sh->chippkg ==
20934 BCM43224_FAB_SMIC) {
20935 bias = 0x2a;
20936 cascbias = 0x38;
20937 }
20938 }
20939
20940 pag_boost_tune = 0x4;
20941 pgag_boost_tune = 0x03;
20942 padg_boost_tune = 0x77;
20943 mixg_boost_tune = 0x65;
20944
20945 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
20946 INTPAG_IMAIN_STAT, bias);
20947 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
20948 INTPAG_IAUX_STAT, bias);
20949 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
20950 INTPAG_CASCBIAS, cascbias);
20951
20952 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
20953 INTPAG_BOOST_TUNE,
20954 pag_boost_tune);
20955 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
20956 PGAG_BOOST_TUNE,
20957 pgag_boost_tune);
20958 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
20959 PADG_BOOST_TUNE,
20960 padg_boost_tune);
20961 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
20962 MIXG_BOOST_TUNE,
20963 mixg_boost_tune);
20964 } else {
20965
20966 bias = (pi->bw == WL_CHANSPEC_BW_40) ?
20967 0x40 : 0x20;
20968
20969 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
20970 INTPAG_IMAIN_STAT, bias);
20971 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
20972 INTPAG_IAUX_STAT, bias);
20973 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
20974 INTPAG_CASCBIAS, 0x30);
20975 }
20976 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, PA_SPARE1,
20977 0xee);
20978 }
20979 }
20980
20981 if (PHY_IPA(pi) && NREV_IS(pi->pubpi.phy_rev, 6)
20982 && CHSPEC_IS5G(pi->radio_chanspec)) {
20983 u16 paa_boost_tune;
20984 u16 pada_boost_tune;
20985 u16 pgaa_boost_tune;
20986 u16 mixa_boost_tune;
20987 u16 freq, pabias, cascbias;
20988 uint core;
20989
20990 freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
20991
20992 if (freq < 5150) {
20993
20994 paa_boost_tune = 0xa;
20995 pada_boost_tune = 0x77;
20996 pgaa_boost_tune = 0xf;
20997 mixa_boost_tune = 0xf;
20998 } else if (freq < 5340) {
20999
21000 paa_boost_tune = 0x8;
21001 pada_boost_tune = 0x77;
21002 pgaa_boost_tune = 0xfb;
21003 mixa_boost_tune = 0xf;
21004 } else if (freq < 5650) {
21005
21006 paa_boost_tune = 0x0;
21007 pada_boost_tune = 0x77;
21008 pgaa_boost_tune = 0xb;
21009 mixa_boost_tune = 0xf;
21010 } else {
21011
21012 paa_boost_tune = 0x0;
21013 pada_boost_tune = 0x77;
21014 if (freq != 5825)
21015 pgaa_boost_tune = -(int)(freq - 18) / 36 + 168;
21016 else
21017 pgaa_boost_tune = 6;
21018
21019 mixa_boost_tune = 0xf;
21020 }
21021
21022 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
21023 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
21024 INTPAA_BOOST_TUNE, paa_boost_tune);
21025 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
21026 PADA_BOOST_TUNE, pada_boost_tune);
21027 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
21028 PGAA_BOOST_TUNE, pgaa_boost_tune);
21029 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
21030 MIXA_BOOST_TUNE, mixa_boost_tune);
21031
21032 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
21033 TXSPARE1, 0x30);
21034 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
21035 PA_SPARE2, 0xee);
21036
21037 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
21038 PADA_CASCBIAS, 0x3);
21039
21040 cascbias = 0x30;
21041
21042 if ((pi->sh->chip == BCM43224_CHIP_ID) ||
21043 (pi->sh->chip == BCM43225_CHIP_ID)) {
21044 if (pi->sh->chippkg == BCM43224_FAB_SMIC)
21045 cascbias = 0x35;
21046 }
21047
21048 pabias = (pi->phy_pabias == 0) ? 0x30 : pi->phy_pabias;
21049
21050 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
21051 INTPAA_IAUX_STAT, pabias);
21052 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
21053 INTPAA_IMAIN_STAT, pabias);
21054 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
21055 INTPAA_CASCBIAS, cascbias);
21056 }
21057 }
21058
21059 udelay(50);
21060
21061 wlc_phy_radio205x_vcocal_nphy(pi);
21062}
21063
21064void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi)
21065{
21066 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21067 mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x0);
21068 mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04, 0x0);
21069 mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04,
21070 (1 << 2));
21071 mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x01);
21072 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
21073 write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL12, 0x0);
21074 write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
21075 write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x18);
21076 write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
21077 write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x39);
21078 }
21079
21080 udelay(300);
21081}
21082
21083static void
21084wlc_phy_chanspec_radio2057_setup(
21085 struct brcms_phy *pi,
21086 const struct chan_info_nphy_radio2057 *ci,
21087 const struct chan_info_nphy_radio2057_rev5 *
21088 ci2)
21089{
21090 int coreNum;
21091 u16 txmix2g_tune_boost_pu = 0;
21092 u16 pad2g_tune_pus = 0;
21093
21094 if (pi->pubpi.radiorev == 5) {
21095
21096 write_radio_reg(pi,
21097 RADIO_2057_VCOCAL_COUNTVAL0,
21098 ci2->RF_vcocal_countval0);
21099 write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
21100 ci2->RF_vcocal_countval1);
21101 write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
21102 ci2->RF_rfpll_refmaster_sparextalsize);
21103 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
21104 ci2->RF_rfpll_loopfilter_r1);
21105 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
21106 ci2->RF_rfpll_loopfilter_c2);
21107 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
21108 ci2->RF_rfpll_loopfilter_c1);
21109 write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC,
21110 ci2->RF_cp_kpd_idac);
21111 write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci2->RF_rfpll_mmd0);
21112 write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci2->RF_rfpll_mmd1);
21113 write_radio_reg(pi,
21114 RADIO_2057_VCOBUF_TUNE, ci2->RF_vcobuf_tune);
21115 write_radio_reg(pi,
21116 RADIO_2057_LOGEN_MX2G_TUNE,
21117 ci2->RF_logen_mx2g_tune);
21118 write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
21119 ci2->RF_logen_indbuf2g_tune);
21120
21121 write_radio_reg(pi,
21122 RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
21123 ci2->RF_txmix2g_tune_boost_pu_core0);
21124 write_radio_reg(pi,
21125 RADIO_2057_PAD2G_TUNE_PUS_CORE0,
21126 ci2->RF_pad2g_tune_pus_core0);
21127 write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
21128 ci2->RF_lna2g_tune_core0);
21129
21130 write_radio_reg(pi,
21131 RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
21132 ci2->RF_txmix2g_tune_boost_pu_core1);
21133 write_radio_reg(pi,
21134 RADIO_2057_PAD2G_TUNE_PUS_CORE1,
21135 ci2->RF_pad2g_tune_pus_core1);
21136 write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
21137 ci2->RF_lna2g_tune_core1);
21138
21139 } else {
21140
21141 write_radio_reg(pi,
21142 RADIO_2057_VCOCAL_COUNTVAL0,
21143 ci->RF_vcocal_countval0);
21144 write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
21145 ci->RF_vcocal_countval1);
21146 write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
21147 ci->RF_rfpll_refmaster_sparextalsize);
21148 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
21149 ci->RF_rfpll_loopfilter_r1);
21150 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
21151 ci->RF_rfpll_loopfilter_c2);
21152 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
21153 ci->RF_rfpll_loopfilter_c1);
21154 write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, ci->RF_cp_kpd_idac);
21155 write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci->RF_rfpll_mmd0);
21156 write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci->RF_rfpll_mmd1);
21157 write_radio_reg(pi, RADIO_2057_VCOBUF_TUNE, ci->RF_vcobuf_tune);
21158 write_radio_reg(pi,
21159 RADIO_2057_LOGEN_MX2G_TUNE,
21160 ci->RF_logen_mx2g_tune);
21161 write_radio_reg(pi, RADIO_2057_LOGEN_MX5G_TUNE,
21162 ci->RF_logen_mx5g_tune);
21163 write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
21164 ci->RF_logen_indbuf2g_tune);
21165 write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF5G_TUNE,
21166 ci->RF_logen_indbuf5g_tune);
21167
21168 write_radio_reg(pi,
21169 RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
21170 ci->RF_txmix2g_tune_boost_pu_core0);
21171 write_radio_reg(pi,
21172 RADIO_2057_PAD2G_TUNE_PUS_CORE0,
21173 ci->RF_pad2g_tune_pus_core0);
21174 write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE0,
21175 ci->RF_pga_boost_tune_core0);
21176 write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0,
21177 ci->RF_txmix5g_boost_tune_core0);
21178 write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0,
21179 ci->RF_pad5g_tune_misc_pus_core0);
21180 write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
21181 ci->RF_lna2g_tune_core0);
21182 write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE0,
21183 ci->RF_lna5g_tune_core0);
21184
21185 write_radio_reg(pi,
21186 RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
21187 ci->RF_txmix2g_tune_boost_pu_core1);
21188 write_radio_reg(pi,
21189 RADIO_2057_PAD2G_TUNE_PUS_CORE1,
21190 ci->RF_pad2g_tune_pus_core1);
21191 write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE1,
21192 ci->RF_pga_boost_tune_core1);
21193 write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1,
21194 ci->RF_txmix5g_boost_tune_core1);
21195 write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1,
21196 ci->RF_pad5g_tune_misc_pus_core1);
21197 write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
21198 ci->RF_lna2g_tune_core1);
21199 write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE1,
21200 ci->RF_lna5g_tune_core1);
21201 }
21202
21203 if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
21204
21205 if (CHSPEC_IS2G(pi->radio_chanspec)) {
21206 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
21207 0x3f);
21208 write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
21209 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
21210 0x8);
21211 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
21212 0x8);
21213 } else {
21214 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
21215 0x1f);
21216 write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
21217 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
21218 0x8);
21219 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
21220 0x8);
21221 }
21222 } else if ((pi->pubpi.radiorev == 5) || (pi->pubpi.radiorev == 7) ||
21223 (pi->pubpi.radiorev == 8)) {
21224
21225 if (CHSPEC_IS2G(pi->radio_chanspec)) {
21226 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
21227 0x1b);
21228 write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x30);
21229 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
21230 0xa);
21231 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
21232 0xa);
21233 } else {
21234 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
21235 0x1f);
21236 write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
21237 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
21238 0x8);
21239 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
21240 0x8);
21241 }
21242
21243 }
21244
21245 if (CHSPEC_IS2G(pi->radio_chanspec)) {
21246 if (PHY_IPA(pi)) {
21247 if (pi->pubpi.radiorev == 3)
21248 txmix2g_tune_boost_pu = 0x6b;
21249
21250 if (pi->pubpi.radiorev == 5)
21251 pad2g_tune_pus = 0x73;
21252
21253 } else {
21254 if (pi->pubpi.radiorev != 5) {
21255 pad2g_tune_pus = 0x3;
21256
21257 txmix2g_tune_boost_pu = 0x61;
21258 }
21259 }
21260
21261 for (coreNum = 0; coreNum <= 1; coreNum++) {
21262
21263 if (txmix2g_tune_boost_pu != 0)
21264 WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
21265 TXMIX2G_TUNE_BOOST_PU,
21266 txmix2g_tune_boost_pu);
21267
21268 if (pad2g_tune_pus != 0)
21269 WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
21270 PAD2G_TUNE_PUS,
21271 pad2g_tune_pus);
21272 }
21273 }
21274
21275 udelay(50);
21276
21277 wlc_phy_radio205x_vcocal_nphy(pi);
21278}
21279
21280static void
21281wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, u16 chanspec,
21282 const struct nphy_sfo_cfg *ci)
21283{
21284 u16 val;
21285
21286 val = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
21287 if (CHSPEC_IS5G(chanspec) && !val) {
21288
21289 val = R_REG(&pi->regs->psm_phy_hdr_param);
21290 W_REG(&pi->regs->psm_phy_hdr_param,
21291 (val | MAC_PHY_FORCE_CLK));
21292
21293 or_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
21294 (BBCFG_RESETCCA | BBCFG_RESETRX));
21295
21296 W_REG(&pi->regs->psm_phy_hdr_param, val);
21297
21298 or_phy_reg(pi, 0x09, NPHY_BandControl_currentBand);
21299 } else if (!CHSPEC_IS5G(chanspec) && val) {
21300
21301 and_phy_reg(pi, 0x09, ~NPHY_BandControl_currentBand);
21302
21303 val = R_REG(&pi->regs->psm_phy_hdr_param);
21304 W_REG(&pi->regs->psm_phy_hdr_param,
21305 (val | MAC_PHY_FORCE_CLK));
21306
21307 and_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
21308 (u16) (~(BBCFG_RESETCCA | BBCFG_RESETRX)));
21309
21310 W_REG(&pi->regs->psm_phy_hdr_param, val);
21311 }
21312
21313 write_phy_reg(pi, 0x1ce, ci->PHY_BW1a);
21314 write_phy_reg(pi, 0x1cf, ci->PHY_BW2);
21315 write_phy_reg(pi, 0x1d0, ci->PHY_BW3);
21316
21317 write_phy_reg(pi, 0x1d1, ci->PHY_BW4);
21318 write_phy_reg(pi, 0x1d2, ci->PHY_BW5);
21319 write_phy_reg(pi, 0x1d3, ci->PHY_BW6);
21320
21321 if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
21322 wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en, 0);
21323
21324 or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, 0x800);
21325 } else {
21326 wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en,
21327 NPHY_ClassifierCtrl_ofdm_en);
21328
21329 if (CHSPEC_IS2G(chanspec))
21330 and_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, ~0x840);
21331 }
21332
21333 if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF)
21334 wlc_phy_txpwr_fixpower_nphy(pi);
21335
21336 if (NREV_LT(pi->pubpi.phy_rev, 3))
21337 wlc_phy_adjust_lnagaintbl_nphy(pi);
21338
21339 wlc_phy_txlpfbw_nphy(pi);
21340
21341 if (NREV_GE(pi->pubpi.phy_rev, 3)
21342 && (pi->phy_spuravoid != SPURAVOID_DISABLE)) {
21343 u8 spuravoid = 0;
21344
21345 val = CHSPEC_CHANNEL(chanspec);
21346 if (!CHSPEC_IS40(pi->radio_chanspec)) {
21347 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21348 if ((val == 13) || (val == 14) || (val == 153))
21349 spuravoid = 1;
21350 } else if (((val >= 5) && (val <= 8)) || (val == 13)
21351 || (val == 14)) {
21352 spuravoid = 1;
21353 }
21354 } else if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21355 if (val == 54)
21356 spuravoid = 1;
21357 } else {
21358 if (pi->nphy_aband_spurwar_en &&
21359 ((val == 38) || (val == 102)
21360 || (val == 118)))
21361 spuravoid = 1;
21362 }
21363
21364 if (pi->phy_spuravoid == SPURAVOID_FORCEON)
21365 spuravoid = 1;
21366
21367 wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false);
21368 si_pmu_spuravoid(pi->sh->sih, spuravoid);
21369 wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true);
21370
21371 if ((pi->sh->chip == BCM43224_CHIP_ID) ||
21372 (pi->sh->chip == BCM43225_CHIP_ID)) {
21373
21374 if (spuravoid == 1) {
21375
21376 W_REG(&pi->regs->tsf_clk_frac_l,
21377 0x5341);
21378 W_REG(&pi->regs->tsf_clk_frac_h,
21379 0x8);
21380 } else {
21381
21382 W_REG(&pi->regs->tsf_clk_frac_l,
21383 0x8889);
21384 W_REG(&pi->regs->tsf_clk_frac_h,
21385 0x8);
21386 }
21387 }
21388
21389 wlapi_bmac_core_phypll_reset(pi->sh->physhim);
21390
21391 mod_phy_reg(pi, 0x01, (0x1 << 15),
21392 ((spuravoid > 0) ? (0x1 << 15) : 0));
21393
21394 wlc_phy_resetcca_nphy(pi);
21395
21396 pi->phy_isspuravoid = (spuravoid > 0);
21397 }
21398
21399 if (NREV_LT(pi->pubpi.phy_rev, 7))
21400 write_phy_reg(pi, 0x17e, 0x3830);
21401
21402 wlc_phy_spurwar_nphy(pi);
21403}
21404
21405void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, u16 chanspec)
21406{
21407 int freq;
21408 const struct chan_info_nphy_radio2057 *t0 = NULL;
21409 const struct chan_info_nphy_radio205x *t1 = NULL;
21410 const struct chan_info_nphy_radio2057_rev5 *t2 = NULL;
21411 const struct chan_info_nphy_2055 *t3 = NULL;
21412
21413 if (!wlc_phy_chan2freq_nphy
21414 (pi, CHSPEC_CHANNEL(chanspec), &freq, &t0, &t1, &t2, &t3))
21415 return;
21416
21417 wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec);
21418
21419 if (CHSPEC_BW(chanspec) != pi->bw)
21420 wlapi_bmac_bw_set(pi->sh->physhim, CHSPEC_BW(chanspec));
21421
21422 if (CHSPEC_IS40(chanspec)) {
21423 if (CHSPEC_SB_UPPER(chanspec)) {
21424 or_phy_reg(pi, 0xa0, BPHY_BAND_SEL_UP20);
21425 if (NREV_GE(pi->pubpi.phy_rev, 7))
21426 or_phy_reg(pi, 0x310, PRIM_SEL_UP20);
21427 } else {
21428 and_phy_reg(pi, 0xa0, ~BPHY_BAND_SEL_UP20);
21429 if (NREV_GE(pi->pubpi.phy_rev, 7))
21430 and_phy_reg(pi, 0x310,
21431 (~PRIM_SEL_UP20 & 0xffff));
21432 }
21433 }
21434
21435 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
21436 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21437
21438 if ((pi->pubpi.radiorev <= 4)
21439 || (pi->pubpi.radiorev == 6)) {
21440 mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE0,
21441 0x2,
21442 (CHSPEC_IS5G(chanspec) ? (1 << 1)
21443 : 0));
21444 mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE1,
21445 0x2,
21446 (CHSPEC_IS5G(chanspec) ? (1 << 1)
21447 : 0));
21448 }
21449
21450 wlc_phy_chanspec_radio2057_setup(pi, t0, t2);
21451 wlc_phy_chanspec_nphy_setup(pi, chanspec,
21452 (pi->pubpi.radiorev == 5) ?
21453 (const struct nphy_sfo_cfg *)&(t2->PHY_BW1a) :
21454 (const struct nphy_sfo_cfg *)&(t0->PHY_BW1a));
21455
21456 } else {
21457
21458 mod_radio_reg(pi,
21459 RADIO_2056_SYN_COM_CTRL | RADIO_2056_SYN,
21460 0x4,
21461 (CHSPEC_IS5G(chanspec) ? (0x1 << 2) : 0));
21462 wlc_phy_chanspec_radio2056_setup(pi, t1);
21463
21464 wlc_phy_chanspec_nphy_setup(pi, chanspec,
21465 (const struct nphy_sfo_cfg *) &(t1->PHY_BW1a));
21466 }
21467
21468 } else {
21469
21470 mod_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, 0x70,
21471 (CHSPEC_IS5G(chanspec) ? (0x02 << 4)
21472 : (0x05 << 4)));
21473
21474 wlc_phy_chanspec_radio2055_setup(pi, t3);
21475 wlc_phy_chanspec_nphy_setup(pi, chanspec,
21476 (const struct nphy_sfo_cfg *)
21477 &(t3->PHY_BW1a));
21478 }
21479
21480}
21481
21482void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init)
21483{
21484 struct brcms_phy *pi = (struct brcms_phy *) ppi;
21485 u16 mask = 0xfc00;
21486 u32 mc = 0;
21487
21488 if (NREV_GE(pi->pubpi.phy_rev, 7))
21489 return;
21490
21491 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
21492 u16 v0 = 0x211, v1 = 0x222, v2 = 0x144, v3 = 0x188;
21493
21494 if (lut_init == false)
21495 return;
21496
21497 if (pi->srom_fem2g.antswctrllut == 0) {
21498 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
21499 1, 0x02, 16, &v0);
21500 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
21501 1, 0x03, 16, &v1);
21502 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
21503 1, 0x08, 16, &v2);
21504 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
21505 1, 0x0C, 16, &v3);
21506 }
21507
21508 if (pi->srom_fem5g.antswctrllut == 0) {
21509 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
21510 1, 0x12, 16, &v0);
21511 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
21512 1, 0x13, 16, &v1);
21513 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
21514 1, 0x18, 16, &v2);
21515 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
21516 1, 0x1C, 16, &v3);
21517 }
21518 } else {
21519
21520 write_phy_reg(pi, 0xc8, 0x0);
21521 write_phy_reg(pi, 0xc9, 0x0);
21522
21523 ai_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY);
21524
21525 mc = R_REG(&pi->regs->maccontrol);
21526 mc &= ~MCTL_GPOUT_SEL_MASK;
21527 W_REG(&pi->regs->maccontrol, mc);
21528
21529 OR_REG(&pi->regs->psm_gpio_oe, mask);
21530
21531 AND_REG(&pi->regs->psm_gpio_out, ~mask);
21532
21533 if (lut_init) {
21534 write_phy_reg(pi, 0xf8, 0x02d8);
21535 write_phy_reg(pi, 0xf9, 0x0301);
21536 write_phy_reg(pi, 0xfa, 0x02d8);
21537 write_phy_reg(pi, 0xfb, 0x0301);
21538 }
21539 }
21540}
21541
21542u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val)
21543{
21544 u16 curr_ctl, new_ctl;
21545 bool suspended = false;
21546
21547 if (D11REV_IS(pi->sh->corerev, 16)) {
21548 suspended =
21549 (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) ?
21550 false : true;
21551 if (!suspended)
21552 wlapi_suspend_mac_and_wait(pi->sh->physhim);
21553 }
21554
21555 curr_ctl = read_phy_reg(pi, 0xb0) & (0x7 << 0);
21556
21557 new_ctl = (curr_ctl & (~mask)) | (val & mask);
21558
21559 mod_phy_reg(pi, 0xb0, (0x7 << 0), new_ctl);
21560
21561 if (D11REV_IS(pi->sh->corerev, 16) && !suspended)
21562 wlapi_enable_mac(pi->sh->physhim);
21563
21564 return new_ctl;
21565}
21566
21567void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd)
21568{
21569 u16 trigger_mask, status_mask;
21570 u16 orig_RfseqCoreActv;
21571
21572 switch (cmd) {
21573 case NPHY_RFSEQ_RX2TX:
21574 trigger_mask = NPHY_RfseqTrigger_rx2tx;
21575 status_mask = NPHY_RfseqStatus_rx2tx;
21576 break;
21577 case NPHY_RFSEQ_TX2RX:
21578 trigger_mask = NPHY_RfseqTrigger_tx2rx;
21579 status_mask = NPHY_RfseqStatus_tx2rx;
21580 break;
21581 case NPHY_RFSEQ_RESET2RX:
21582 trigger_mask = NPHY_RfseqTrigger_reset2rx;
21583 status_mask = NPHY_RfseqStatus_reset2rx;
21584 break;
21585 case NPHY_RFSEQ_UPDATEGAINH:
21586 trigger_mask = NPHY_RfseqTrigger_updategainh;
21587 status_mask = NPHY_RfseqStatus_updategainh;
21588 break;
21589 case NPHY_RFSEQ_UPDATEGAINL:
21590 trigger_mask = NPHY_RfseqTrigger_updategainl;
21591 status_mask = NPHY_RfseqStatus_updategainl;
21592 break;
21593 case NPHY_RFSEQ_UPDATEGAINU:
21594 trigger_mask = NPHY_RfseqTrigger_updategainu;
21595 status_mask = NPHY_RfseqStatus_updategainu;
21596 break;
21597 default:
21598 return;
21599 }
21600
21601 orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
21602 or_phy_reg(pi, 0xa1,
21603 (NPHY_RfseqMode_CoreActv_override |
21604 NPHY_RfseqMode_Trigger_override));
21605 or_phy_reg(pi, 0xa3, trigger_mask);
21606 SPINWAIT((read_phy_reg(pi, 0xa4) & status_mask), 200000);
21607 write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
21608 WARN(read_phy_reg(pi, 0xa4) & status_mask, "HW error in rf");
21609}
21610
21611static void
21612wlc_phy_rfctrl_override_1tomany_nphy(struct brcms_phy *pi, u16 cmd, u16 value,
21613 u8 core_mask, u8 off)
21614{
21615 u16 rfmxgain = 0, lpfgain = 0;
21616 u16 tgain = 0;
21617
21618 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21619
21620 switch (cmd) {
21621 case NPHY_REV7_RfctrlOverride_cmd_rxrf_pu:
21622 wlc_phy_rfctrl_override_nphy_rev7(
21623 pi, (0x1 << 5),
21624 value, core_mask, off,
21625 NPHY_REV7_RFCTRLOVERRIDE_ID1);
21626 wlc_phy_rfctrl_override_nphy_rev7(
21627 pi, (0x1 << 4), value,
21628 core_mask, off,
21629 NPHY_REV7_RFCTRLOVERRIDE_ID1);
21630 wlc_phy_rfctrl_override_nphy_rev7(
21631 pi, (0x1 << 3), value,
21632 core_mask, off,
21633 NPHY_REV7_RFCTRLOVERRIDE_ID1);
21634 break;
21635 case NPHY_REV7_RfctrlOverride_cmd_rx_pu:
21636 wlc_phy_rfctrl_override_nphy_rev7(
21637 pi, (0x1 << 2),
21638 value, core_mask, off,
21639 NPHY_REV7_RFCTRLOVERRIDE_ID1);
21640 wlc_phy_rfctrl_override_nphy_rev7(
21641 pi, (0x1 << 1), value,
21642 core_mask, off,
21643 NPHY_REV7_RFCTRLOVERRIDE_ID1);
21644 wlc_phy_rfctrl_override_nphy_rev7(
21645 pi, (0x1 << 0), value,
21646 core_mask, off,
21647 NPHY_REV7_RFCTRLOVERRIDE_ID1);
21648 wlc_phy_rfctrl_override_nphy_rev7(
21649 pi, (0x1 << 1), value,
21650 core_mask, off,
21651 NPHY_REV7_RFCTRLOVERRIDE_ID2);
21652 wlc_phy_rfctrl_override_nphy_rev7(
21653 pi, (0x1 << 11), 0,
21654 core_mask, off,
21655 NPHY_REV7_RFCTRLOVERRIDE_ID1);
21656 break;
21657 case NPHY_REV7_RfctrlOverride_cmd_tx_pu:
21658 wlc_phy_rfctrl_override_nphy_rev7(
21659 pi, (0x1 << 2),
21660 value, core_mask, off,
21661 NPHY_REV7_RFCTRLOVERRIDE_ID0);
21662 wlc_phy_rfctrl_override_nphy_rev7(
21663 pi, (0x1 << 1), value,
21664 core_mask, off,
21665 NPHY_REV7_RFCTRLOVERRIDE_ID1);
21666 wlc_phy_rfctrl_override_nphy_rev7(
21667 pi, (0x1 << 0), value,
21668 core_mask, off,
21669 NPHY_REV7_RFCTRLOVERRIDE_ID2);
21670 wlc_phy_rfctrl_override_nphy_rev7(
21671 pi, (0x1 << 2), value,
21672 core_mask, off,
21673 NPHY_REV7_RFCTRLOVERRIDE_ID2);
21674 wlc_phy_rfctrl_override_nphy_rev7(
21675 pi, (0x1 << 11), 1,
21676 core_mask, off,
21677 NPHY_REV7_RFCTRLOVERRIDE_ID1);
21678 break;
21679 case NPHY_REV7_RfctrlOverride_cmd_rxgain:
21680 rfmxgain = value & 0x000ff;
21681 lpfgain = value & 0x0ff00;
21682 lpfgain = lpfgain >> 8;
21683
21684 wlc_phy_rfctrl_override_nphy_rev7(
21685 pi, (0x1 << 11),
21686 rfmxgain, core_mask,
21687 off,
21688 NPHY_REV7_RFCTRLOVERRIDE_ID0);
21689 wlc_phy_rfctrl_override_nphy_rev7(
21690 pi, (0x3 << 13),
21691 lpfgain, core_mask,
21692 off,
21693 NPHY_REV7_RFCTRLOVERRIDE_ID0);
21694 break;
21695 case NPHY_REV7_RfctrlOverride_cmd_txgain:
21696 tgain = value & 0x7fff;
21697 lpfgain = value & 0x8000;
21698 lpfgain = lpfgain >> 14;
21699
21700 wlc_phy_rfctrl_override_nphy_rev7(
21701 pi, (0x1 << 12),
21702 tgain, core_mask, off,
21703 NPHY_REV7_RFCTRLOVERRIDE_ID0);
21704 wlc_phy_rfctrl_override_nphy_rev7(
21705 pi, (0x1 << 13),
21706 lpfgain, core_mask,
21707 off,
21708 NPHY_REV7_RFCTRLOVERRIDE_ID0);
21709 break;
21710 }
21711 }
21712}
21713
21714static void
21715wlc_phy_scale_offset_rssi_nphy(struct brcms_phy *pi, u16 scale, s8 offset,
21716 u8 coresel, u8 rail, u8 rssi_type)
21717{
21718 u16 valuetostuff;
21719
21720 offset = (offset > NPHY_RSSICAL_MAXREAD) ?
21721 NPHY_RSSICAL_MAXREAD : offset;
21722 offset = (offset < (-NPHY_RSSICAL_MAXREAD - 1)) ?
21723 -NPHY_RSSICAL_MAXREAD - 1 : offset;
21724
21725 valuetostuff = ((scale & 0x3f) << 8) | (offset & 0x3f);
21726
21727 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
21728 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21729 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB))
21730 write_phy_reg(pi, 0x1a6, valuetostuff);
21731
21732 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
21733 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21734 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB))
21735 write_phy_reg(pi, 0x1ac, valuetostuff);
21736
21737 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
21738 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21739 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB))
21740 write_phy_reg(pi, 0x1b2, valuetostuff);
21741
21742 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
21743 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21744 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB))
21745 write_phy_reg(pi, 0x1b8, valuetostuff);
21746
21747 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
21748 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21749 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1))
21750 write_phy_reg(pi, 0x1a4, valuetostuff);
21751
21752 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
21753 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21754 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1))
21755 write_phy_reg(pi, 0x1aa, valuetostuff);
21756
21757 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
21758 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21759 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1))
21760 write_phy_reg(pi, 0x1b0, valuetostuff);
21761
21762 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
21763 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21764 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1))
21765 write_phy_reg(pi, 0x1b6, valuetostuff);
21766
21767 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
21768 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21769 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2))
21770 write_phy_reg(pi, 0x1a5, valuetostuff);
21771 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
21772 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21773 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2))
21774 write_phy_reg(pi, 0x1ab, valuetostuff);
21775
21776 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
21777 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21778 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2))
21779 write_phy_reg(pi, 0x1b1, valuetostuff);
21780
21781 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
21782 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21783 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2))
21784 write_phy_reg(pi, 0x1b7, valuetostuff);
21785
21786 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
21787 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21788 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD))
21789 write_phy_reg(pi, 0x1a7, valuetostuff);
21790 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
21791 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21792 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD))
21793 write_phy_reg(pi, 0x1ad, valuetostuff);
21794 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
21795 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21796 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD))
21797 write_phy_reg(pi, 0x1b3, valuetostuff);
21798 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
21799 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21800 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD))
21801 write_phy_reg(pi, 0x1b9, valuetostuff);
21802
21803 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
21804 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21805 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ))
21806 write_phy_reg(pi, 0x1a8, valuetostuff);
21807
21808 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
21809 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21810 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ))
21811 write_phy_reg(pi, 0x1ae, valuetostuff);
21812
21813 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
21814 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21815 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ))
21816 write_phy_reg(pi, 0x1b4, valuetostuff);
21817
21818 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
21819 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21820 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ))
21821 write_phy_reg(pi, 0x1ba, valuetostuff);
21822
21823 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
21824 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21825 (rssi_type == NPHY_RSSI_SEL_TSSI_2G))
21826 write_phy_reg(pi, 0x1a9, valuetostuff);
21827 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
21828 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21829 (rssi_type == NPHY_RSSI_SEL_TSSI_2G))
21830 write_phy_reg(pi, 0x1b5, valuetostuff);
21831
21832 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
21833 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21834 (rssi_type == NPHY_RSSI_SEL_TSSI_5G))
21835 write_phy_reg(pi, 0x1af, valuetostuff);
21836
21837 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
21838 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
21839 (rssi_type == NPHY_RSSI_SEL_TSSI_5G))
21840 write_phy_reg(pi, 0x1bb, valuetostuff);
21841}
21842
21843static void brcms_phy_wr_tx_mux(struct brcms_phy *pi, u8 core)
21844{
21845 if (PHY_IPA(pi)) {
21846 if (NREV_GE(pi->pubpi.phy_rev, 7))
21847 write_radio_reg(pi,
21848 ((core == PHY_CORE_0) ?
21849 RADIO_2057_TX0_TX_SSI_MUX :
21850 RADIO_2057_TX1_TX_SSI_MUX),
21851 (CHSPEC_IS5G(pi->radio_chanspec) ?
21852 0xc : 0xe));
21853 else
21854 write_radio_reg(pi,
21855 RADIO_2056_TX_TX_SSI_MUX |
21856 ((core == PHY_CORE_0) ?
21857 RADIO_2056_TX0 : RADIO_2056_TX1),
21858 (CHSPEC_IS5G(pi->radio_chanspec) ?
21859 0xc : 0xe));
21860 } else {
21861 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21862 write_radio_reg(pi,
21863 ((core == PHY_CORE_0) ?
21864 RADIO_2057_TX0_TX_SSI_MUX :
21865 RADIO_2057_TX1_TX_SSI_MUX),
21866 0x11);
21867
21868 if (pi->pubpi.radioid == BCM2057_ID)
21869 write_radio_reg(pi,
21870 RADIO_2057_IQTEST_SEL_PU, 0x1);
21871
21872 } else {
21873 write_radio_reg(pi,
21874 RADIO_2056_TX_TX_SSI_MUX |
21875 ((core == PHY_CORE_0) ?
21876 RADIO_2056_TX0 : RADIO_2056_TX1),
21877 0x11);
21878 }
21879 }
21880}
21881
21882void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type)
21883{
21884 u16 mask, val;
21885 u16 afectrlovr_rssi_val, rfctrlcmd_rxen_val, rfctrlcmd_coresel_val,
21886 startseq;
21887 u16 rfctrlovr_rssi_val, rfctrlovr_rxen_val, rfctrlovr_coresel_val,
21888 rfctrlovr_trigger_val;
21889 u16 afectrlovr_rssi_mask, rfctrlcmd_mask, rfctrlovr_mask;
21890 u16 rfctrlcmd_val, rfctrlovr_val;
21891 u8 core;
21892
21893 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
21894 if (core_code == RADIO_MIMO_CORESEL_OFF) {
21895 mod_phy_reg(pi, 0x8f, (0x1 << 9), 0);
21896 mod_phy_reg(pi, 0xa5, (0x1 << 9), 0);
21897
21898 mod_phy_reg(pi, 0xa6, (0x3 << 8), 0);
21899 mod_phy_reg(pi, 0xa7, (0x3 << 8), 0);
21900
21901 mod_phy_reg(pi, 0xe5, (0x1 << 5), 0);
21902 mod_phy_reg(pi, 0xe6, (0x1 << 5), 0);
21903
21904 mask = (0x1 << 2) |
21905 (0x1 << 3) | (0x1 << 4) | (0x1 << 5);
21906 mod_phy_reg(pi, 0xf9, mask, 0);
21907 mod_phy_reg(pi, 0xfb, mask, 0);
21908
21909 } else {
21910 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
21911 if (core_code == RADIO_MIMO_CORESEL_CORE1
21912 && core == PHY_CORE_1)
21913 continue;
21914 else if (core_code == RADIO_MIMO_CORESEL_CORE2
21915 && core == PHY_CORE_0)
21916 continue;
21917
21918 mod_phy_reg(pi, (core == PHY_CORE_0) ?
21919 0x8f : 0xa5, (0x1 << 9), 1 << 9);
21920
21921 if (rssi_type == NPHY_RSSI_SEL_W1 ||
21922 rssi_type == NPHY_RSSI_SEL_W2 ||
21923 rssi_type == NPHY_RSSI_SEL_NB) {
21924 mod_phy_reg(pi,
21925 (core ==
21926 PHY_CORE_0) ? 0xa6 : 0xa7,
21927 (0x3 << 8), 0);
21928
21929 mask = (0x1 << 2) |
21930 (0x1 << 3) |
21931 (0x1 << 4) | (0x1 << 5);
21932 mod_phy_reg(pi,
21933 (core ==
21934 PHY_CORE_0) ? 0xf9 : 0xfb,
21935 mask, 0);
21936
21937 if (rssi_type == NPHY_RSSI_SEL_W1) {
21938 if (CHSPEC_IS5G(
21939 pi->radio_chanspec)) {
21940 mask = (0x1 << 2);
21941 val = 1 << 2;
21942 } else {
21943 mask = (0x1 << 3);
21944 val = 1 << 3;
21945 }
21946 } else if (rssi_type ==
21947 NPHY_RSSI_SEL_W2) {
21948 mask = (0x1 << 4);
21949 val = 1 << 4;
21950 } else {
21951 mask = (0x1 << 5);
21952 val = 1 << 5;
21953 }
21954 mod_phy_reg(pi,
21955 (core ==
21956 PHY_CORE_0) ? 0xf9 : 0xfb,
21957 mask, val);
21958
21959 mask = (0x1 << 5);
21960 val = 1 << 5;
21961 mod_phy_reg(pi, (core == PHY_CORE_0) ?
21962 0xe5 : 0xe6, mask, val);
21963 } else {
21964 if (rssi_type == NPHY_RSSI_SEL_TBD) {
21965 mask = (0x3 << 8);
21966 val = 1 << 8;
21967 mod_phy_reg(pi,
21968 (core ==
21969 PHY_CORE_0) ? 0xa6
21970 : 0xa7, mask, val);
21971 mask = (0x3 << 10);
21972 val = 1 << 10;
21973 mod_phy_reg(pi,
21974 (core ==
21975 PHY_CORE_0) ? 0xa6
21976 : 0xa7, mask, val);
21977 } else if (rssi_type ==
21978 NPHY_RSSI_SEL_IQ) {
21979 mask = (0x3 << 8);
21980 val = 2 << 8;
21981 mod_phy_reg(pi,
21982 (core ==
21983 PHY_CORE_0) ? 0xa6
21984 : 0xa7, mask, val);
21985 mask = (0x3 << 10);
21986 val = 2 << 10;
21987 mod_phy_reg(pi,
21988 (core ==
21989 PHY_CORE_0) ? 0xa6
21990 : 0xa7, mask, val);
21991 } else {
21992 mask = (0x3 << 8);
21993 val = 3 << 8;
21994 mod_phy_reg(pi,
21995 (core ==
21996 PHY_CORE_0) ? 0xa6
21997 : 0xa7, mask, val);
21998 mask = (0x3 << 10);
21999 val = 3 << 10;
22000 mod_phy_reg(pi,
22001 (core ==
22002 PHY_CORE_0) ? 0xa6
22003 : 0xa7, mask, val);
22004 brcms_phy_wr_tx_mux(pi, core);
22005 afectrlovr_rssi_val = 1 << 9;
22006 mod_phy_reg(pi,
22007 (core ==
22008 PHY_CORE_0) ? 0x8f
22009 : 0xa5, (0x1 << 9),
22010 afectrlovr_rssi_val);
22011 }
22012 }
22013 }
22014 }
22015 } else {
22016
22017 if ((rssi_type == NPHY_RSSI_SEL_W1) ||
22018 (rssi_type == NPHY_RSSI_SEL_W2) ||
22019 (rssi_type == NPHY_RSSI_SEL_NB))
22020 val = 0x0;
22021 else if (rssi_type == NPHY_RSSI_SEL_TBD)
22022 val = 0x1;
22023 else if (rssi_type == NPHY_RSSI_SEL_IQ)
22024 val = 0x2;
22025 else
22026 val = 0x3;
22027
22028 mask = ((0x3 << 12) | (0x3 << 14));
22029 val = (val << 12) | (val << 14);
22030 mod_phy_reg(pi, 0xa6, mask, val);
22031 mod_phy_reg(pi, 0xa7, mask, val);
22032
22033 if ((rssi_type == NPHY_RSSI_SEL_W1) ||
22034 (rssi_type == NPHY_RSSI_SEL_W2) ||
22035 (rssi_type == NPHY_RSSI_SEL_NB)) {
22036 if (rssi_type == NPHY_RSSI_SEL_W1)
22037 val = 0x1;
22038 if (rssi_type == NPHY_RSSI_SEL_W2)
22039 val = 0x2;
22040 if (rssi_type == NPHY_RSSI_SEL_NB)
22041 val = 0x3;
22042
22043 mask = (0x3 << 4);
22044 val = (val << 4);
22045 mod_phy_reg(pi, 0x7a, mask, val);
22046 mod_phy_reg(pi, 0x7d, mask, val);
22047 }
22048
22049 if (core_code == RADIO_MIMO_CORESEL_OFF) {
22050 afectrlovr_rssi_val = 0;
22051 rfctrlcmd_rxen_val = 0;
22052 rfctrlcmd_coresel_val = 0;
22053 rfctrlovr_rssi_val = 0;
22054 rfctrlovr_rxen_val = 0;
22055 rfctrlovr_coresel_val = 0;
22056 rfctrlovr_trigger_val = 0;
22057 startseq = 0;
22058 } else {
22059 afectrlovr_rssi_val = 1;
22060 rfctrlcmd_rxen_val = 1;
22061 rfctrlcmd_coresel_val = core_code;
22062 rfctrlovr_rssi_val = 1;
22063 rfctrlovr_rxen_val = 1;
22064 rfctrlovr_coresel_val = 1;
22065 rfctrlovr_trigger_val = 1;
22066 startseq = 1;
22067 }
22068
22069 afectrlovr_rssi_mask = ((0x1 << 12) | (0x1 << 13));
22070 afectrlovr_rssi_val = (afectrlovr_rssi_val <<
22071 12) | (afectrlovr_rssi_val << 13);
22072 mod_phy_reg(pi, 0xa5, afectrlovr_rssi_mask,
22073 afectrlovr_rssi_val);
22074
22075 if ((rssi_type == NPHY_RSSI_SEL_W1) ||
22076 (rssi_type == NPHY_RSSI_SEL_W2) ||
22077 (rssi_type == NPHY_RSSI_SEL_NB)) {
22078 rfctrlcmd_mask = ((0x1 << 8) | (0x7 << 3));
22079 rfctrlcmd_val = (rfctrlcmd_rxen_val << 8) |
22080 (rfctrlcmd_coresel_val << 3);
22081
22082 rfctrlovr_mask = ((0x1 << 5) |
22083 (0x1 << 12) |
22084 (0x1 << 1) | (0x1 << 0));
22085 rfctrlovr_val = (rfctrlovr_rssi_val <<
22086 5) |
22087 (rfctrlovr_rxen_val << 12) |
22088 (rfctrlovr_coresel_val << 1) |
22089 (rfctrlovr_trigger_val << 0);
22090
22091 mod_phy_reg(pi, 0x78, rfctrlcmd_mask, rfctrlcmd_val);
22092 mod_phy_reg(pi, 0xec, rfctrlovr_mask, rfctrlovr_val);
22093
22094 mod_phy_reg(pi, 0x78, (0x1 << 0), (startseq << 0));
22095 udelay(20);
22096
22097 mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
22098 }
22099 }
22100}
22101
22102int
22103wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type, s32 *rssi_buf,
22104 u8 nsamps)
22105{
22106 s16 rssi0, rssi1;
22107 u16 afectrlCore1_save = 0;
22108 u16 afectrlCore2_save = 0;
22109 u16 afectrlOverride1_save = 0;
22110 u16 afectrlOverride2_save = 0;
22111 u16 rfctrlOverrideAux0_save = 0;
22112 u16 rfctrlOverrideAux1_save = 0;
22113 u16 rfctrlMiscReg1_save = 0;
22114 u16 rfctrlMiscReg2_save = 0;
22115 u16 rfctrlcmd_save = 0;
22116 u16 rfctrloverride_save = 0;
22117 u16 rfctrlrssiothers1_save = 0;
22118 u16 rfctrlrssiothers2_save = 0;
22119 s8 tmp_buf[4];
22120 u8 ctr = 0, samp = 0;
22121 s32 rssi_out_val;
22122 u16 gpiosel_orig;
22123
22124 afectrlCore1_save = read_phy_reg(pi, 0xa6);
22125 afectrlCore2_save = read_phy_reg(pi, 0xa7);
22126 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
22127 rfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
22128 rfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
22129 afectrlOverride1_save = read_phy_reg(pi, 0x8f);
22130 afectrlOverride2_save = read_phy_reg(pi, 0xa5);
22131 rfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
22132 rfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
22133 } else {
22134 afectrlOverride1_save = read_phy_reg(pi, 0xa5);
22135 rfctrlcmd_save = read_phy_reg(pi, 0x78);
22136 rfctrloverride_save = read_phy_reg(pi, 0xec);
22137 rfctrlrssiothers1_save = read_phy_reg(pi, 0x7a);
22138 rfctrlrssiothers2_save = read_phy_reg(pi, 0x7d);
22139 }
22140
22141 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
22142
22143 gpiosel_orig = read_phy_reg(pi, 0xca);
22144 if (NREV_LT(pi->pubpi.phy_rev, 2))
22145 write_phy_reg(pi, 0xca, 5);
22146
22147 for (ctr = 0; ctr < 4; ctr++)
22148 rssi_buf[ctr] = 0;
22149
22150 for (samp = 0; samp < nsamps; samp++) {
22151 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
22152 rssi0 = read_phy_reg(pi, 0x1c9);
22153 rssi1 = read_phy_reg(pi, 0x1ca);
22154 } else {
22155 rssi0 = read_phy_reg(pi, 0x219);
22156 rssi1 = read_phy_reg(pi, 0x21a);
22157 }
22158
22159 ctr = 0;
22160 tmp_buf[ctr++] = ((s8) ((rssi0 & 0x3f) << 2)) >> 2;
22161 tmp_buf[ctr++] = ((s8) (((rssi0 >> 8) & 0x3f) << 2)) >> 2;
22162 tmp_buf[ctr++] = ((s8) ((rssi1 & 0x3f) << 2)) >> 2;
22163 tmp_buf[ctr++] = ((s8) (((rssi1 >> 8) & 0x3f) << 2)) >> 2;
22164
22165 for (ctr = 0; ctr < 4; ctr++)
22166 rssi_buf[ctr] += tmp_buf[ctr];
22167
22168 }
22169
22170 rssi_out_val = rssi_buf[3] & 0xff;
22171 rssi_out_val |= (rssi_buf[2] & 0xff) << 8;
22172 rssi_out_val |= (rssi_buf[1] & 0xff) << 16;
22173 rssi_out_val |= (rssi_buf[0] & 0xff) << 24;
22174
22175 if (NREV_LT(pi->pubpi.phy_rev, 2))
22176 write_phy_reg(pi, 0xca, gpiosel_orig);
22177
22178 write_phy_reg(pi, 0xa6, afectrlCore1_save);
22179 write_phy_reg(pi, 0xa7, afectrlCore2_save);
22180 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
22181 write_phy_reg(pi, 0xf9, rfctrlMiscReg1_save);
22182 write_phy_reg(pi, 0xfb, rfctrlMiscReg2_save);
22183 write_phy_reg(pi, 0x8f, afectrlOverride1_save);
22184 write_phy_reg(pi, 0xa5, afectrlOverride2_save);
22185 write_phy_reg(pi, 0xe5, rfctrlOverrideAux0_save);
22186 write_phy_reg(pi, 0xe6, rfctrlOverrideAux1_save);
22187 } else {
22188 write_phy_reg(pi, 0xa5, afectrlOverride1_save);
22189 write_phy_reg(pi, 0x78, rfctrlcmd_save);
22190 write_phy_reg(pi, 0xec, rfctrloverride_save);
22191 write_phy_reg(pi, 0x7a, rfctrlrssiothers1_save);
22192 write_phy_reg(pi, 0x7d, rfctrlrssiothers2_save);
22193 }
22194
22195 return rssi_out_val;
22196}
22197
22198s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi)
22199{
22200 u16 core1_txrf_iqcal1_save, core1_txrf_iqcal2_save;
22201 u16 core2_txrf_iqcal1_save, core2_txrf_iqcal2_save;
22202 u16 pwrdet_rxtx_core1_save;
22203 u16 pwrdet_rxtx_core2_save;
22204 u16 afectrlCore1_save;
22205 u16 afectrlCore2_save;
22206 u16 afectrlOverride_save;
22207 u16 afectrlOverride2_save;
22208 u16 pd_pll_ts_save;
22209 u16 gpioSel_save;
22210 s32 radio_temp[4];
22211 s32 radio_temp2[4];
22212 u16 syn_tempprocsense_save;
22213 s16 offset = 0;
22214
22215 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22216 u16 auxADC_Vmid, auxADC_Av, auxADC_Vmid_save, auxADC_Av_save;
22217 u16 auxADC_rssi_ctrlL_save, auxADC_rssi_ctrlH_save;
22218 u16 auxADC_rssi_ctrlL, auxADC_rssi_ctrlH;
22219 s32 auxADC_Vl;
22220 u16 RfctrlOverride5_save, RfctrlOverride6_save;
22221 u16 RfctrlMiscReg5_save, RfctrlMiscReg6_save;
22222 u16 RSSIMultCoef0QPowerDet_save;
22223 u16 tempsense_Rcal;
22224
22225 syn_tempprocsense_save =
22226 read_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG);
22227
22228 afectrlCore1_save = read_phy_reg(pi, 0xa6);
22229 afectrlCore2_save = read_phy_reg(pi, 0xa7);
22230 afectrlOverride_save = read_phy_reg(pi, 0x8f);
22231 afectrlOverride2_save = read_phy_reg(pi, 0xa5);
22232 RSSIMultCoef0QPowerDet_save = read_phy_reg(pi, 0x1ae);
22233 RfctrlOverride5_save = read_phy_reg(pi, 0x346);
22234 RfctrlOverride6_save = read_phy_reg(pi, 0x347);
22235 RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
22236 RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
22237
22238 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
22239 &auxADC_Vmid_save);
22240 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
22241 &auxADC_Av_save);
22242 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
22243 &auxADC_rssi_ctrlL_save);
22244 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
22245 &auxADC_rssi_ctrlH_save);
22246
22247 write_phy_reg(pi, 0x1ae, 0x0);
22248
22249 auxADC_rssi_ctrlL = 0x0;
22250 auxADC_rssi_ctrlH = 0x20;
22251 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
22252 &auxADC_rssi_ctrlL);
22253 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
22254 &auxADC_rssi_ctrlH);
22255
22256 tempsense_Rcal = syn_tempprocsense_save & 0x1c;
22257
22258 write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
22259 tempsense_Rcal | 0x01);
22260
22261 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
22262 1, 0, 0,
22263 NPHY_REV7_RFCTRLOVERRIDE_ID2);
22264 mod_phy_reg(pi, 0xa6, (0x1 << 7), 0);
22265 mod_phy_reg(pi, 0xa7, (0x1 << 7), 0);
22266 mod_phy_reg(pi, 0x8f, (0x1 << 7), (0x1 << 7));
22267 mod_phy_reg(pi, 0xa5, (0x1 << 7), (0x1 << 7));
22268
22269 mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
22270 mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
22271 mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
22272 mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
22273 udelay(5);
22274 mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
22275 mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
22276 mod_phy_reg(pi, 0xa6, (0x1 << 3), 0);
22277 mod_phy_reg(pi, 0xa7, (0x1 << 3), 0);
22278 mod_phy_reg(pi, 0x8f, (0x1 << 3), (0x1 << 3));
22279 mod_phy_reg(pi, 0xa5, (0x1 << 3), (0x1 << 3));
22280 mod_phy_reg(pi, 0xa6, (0x1 << 6), 0);
22281 mod_phy_reg(pi, 0xa7, (0x1 << 6), 0);
22282 mod_phy_reg(pi, 0x8f, (0x1 << 6), (0x1 << 6));
22283 mod_phy_reg(pi, 0xa5, (0x1 << 6), (0x1 << 6));
22284
22285 auxADC_Vmid = 0xA3;
22286 auxADC_Av = 0x0;
22287 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
22288 &auxADC_Vmid);
22289 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
22290 &auxADC_Av);
22291
22292 udelay(3);
22293
22294 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
22295 write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
22296 tempsense_Rcal | 0x03);
22297
22298 udelay(5);
22299 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
22300
22301 auxADC_Av = 0x7;
22302 if (radio_temp[1] + radio_temp2[1] < -30) {
22303 auxADC_Vmid = 0x45;
22304 auxADC_Vl = 263;
22305 } else if (radio_temp[1] + radio_temp2[1] < -9) {
22306 auxADC_Vmid = 0x200;
22307 auxADC_Vl = 467;
22308 } else if (radio_temp[1] + radio_temp2[1] < 11) {
22309 auxADC_Vmid = 0x266;
22310 auxADC_Vl = 634;
22311 } else {
22312 auxADC_Vmid = 0x2D5;
22313 auxADC_Vl = 816;
22314 }
22315
22316 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
22317 &auxADC_Vmid);
22318 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
22319 &auxADC_Av);
22320
22321 udelay(3);
22322
22323 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
22324 write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
22325 tempsense_Rcal | 0x01);
22326
22327 udelay(5);
22328 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
22329
22330 write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
22331 syn_tempprocsense_save);
22332
22333 write_phy_reg(pi, 0xa6, afectrlCore1_save);
22334 write_phy_reg(pi, 0xa7, afectrlCore2_save);
22335 write_phy_reg(pi, 0x8f, afectrlOverride_save);
22336 write_phy_reg(pi, 0xa5, afectrlOverride2_save);
22337 write_phy_reg(pi, 0x1ae, RSSIMultCoef0QPowerDet_save);
22338 write_phy_reg(pi, 0x346, RfctrlOverride5_save);
22339 write_phy_reg(pi, 0x347, RfctrlOverride6_save);
22340 write_phy_reg(pi, 0x344, RfctrlMiscReg5_save);
22341 write_phy_reg(pi, 0x345, RfctrlMiscReg5_save);
22342
22343 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
22344 &auxADC_Vmid_save);
22345 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
22346 &auxADC_Av_save);
22347 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
22348 &auxADC_rssi_ctrlL_save);
22349 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
22350 &auxADC_rssi_ctrlH_save);
22351
22352 radio_temp[0] = (179 * (radio_temp[1] + radio_temp2[1])
22353 + 82 * (auxADC_Vl) - 28861 +
22354 128) / 256;
22355
22356 offset = (s16) pi->phy_tempsense_offset;
22357
22358 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
22359 syn_tempprocsense_save =
22360 read_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE);
22361
22362 afectrlCore1_save = read_phy_reg(pi, 0xa6);
22363 afectrlCore2_save = read_phy_reg(pi, 0xa7);
22364 afectrlOverride_save = read_phy_reg(pi, 0x8f);
22365 afectrlOverride2_save = read_phy_reg(pi, 0xa5);
22366 gpioSel_save = read_phy_reg(pi, 0xca);
22367
22368 write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
22369
22370 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
22371 if (NREV_LT(pi->pubpi.phy_rev, 7))
22372 write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x05);
22373
22374 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
22375 if (NREV_GE(pi->pubpi.phy_rev, 7))
22376 write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x01);
22377 else
22378 write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
22379
22380 radio_temp[0] =
22381 (126 * (radio_temp[1] + radio_temp2[1]) + 3987) / 64;
22382
22383 write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE,
22384 syn_tempprocsense_save);
22385
22386 write_phy_reg(pi, 0xca, gpioSel_save);
22387 write_phy_reg(pi, 0xa6, afectrlCore1_save);
22388 write_phy_reg(pi, 0xa7, afectrlCore2_save);
22389 write_phy_reg(pi, 0x8f, afectrlOverride_save);
22390 write_phy_reg(pi, 0xa5, afectrlOverride2_save);
22391
22392 offset = (s16) pi->phy_tempsense_offset;
22393 } else {
22394
22395 pwrdet_rxtx_core1_save =
22396 read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
22397 pwrdet_rxtx_core2_save =
22398 read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
22399 core1_txrf_iqcal1_save =
22400 read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
22401 core1_txrf_iqcal2_save =
22402 read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
22403 core2_txrf_iqcal1_save =
22404 read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
22405 core2_txrf_iqcal2_save =
22406 read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
22407 pd_pll_ts_save = read_radio_reg(pi, RADIO_2055_PD_PLL_TS);
22408
22409 afectrlCore1_save = read_phy_reg(pi, 0xa6);
22410 afectrlCore2_save = read_phy_reg(pi, 0xa7);
22411 afectrlOverride_save = read_phy_reg(pi, 0xa5);
22412 gpioSel_save = read_phy_reg(pi, 0xca);
22413
22414 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x01);
22415 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x01);
22416 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x08);
22417 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x08);
22418 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
22419 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
22420 write_radio_reg(pi, RADIO_2055_PD_PLL_TS, 0x00);
22421
22422 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
22423 xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
22424
22425 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
22426 xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
22427
22428 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
22429 xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
22430
22431 radio_temp[0] = (radio_temp[0] + radio_temp2[0]);
22432 radio_temp[1] = (radio_temp[1] + radio_temp2[1]);
22433 radio_temp[2] = (radio_temp[2] + radio_temp2[2]);
22434 radio_temp[3] = (radio_temp[3] + radio_temp2[3]);
22435
22436 radio_temp[0] =
22437 (radio_temp[0] + radio_temp[1] + radio_temp[2] +
22438 radio_temp[3]);
22439
22440 radio_temp[0] =
22441 (radio_temp[0] +
22442 (8 * 32)) * (950 - 350) / 63 + (350 * 8);
22443
22444 radio_temp[0] = (radio_temp[0] - (8 * 420)) / 38;
22445
22446 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
22447 pwrdet_rxtx_core1_save);
22448 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
22449 pwrdet_rxtx_core2_save);
22450 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
22451 core1_txrf_iqcal1_save);
22452 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
22453 core2_txrf_iqcal1_save);
22454 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
22455 core1_txrf_iqcal2_save);
22456 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
22457 core2_txrf_iqcal2_save);
22458 write_radio_reg(pi, RADIO_2055_PD_PLL_TS, pd_pll_ts_save);
22459
22460 write_phy_reg(pi, 0xca, gpioSel_save);
22461 write_phy_reg(pi, 0xa6, afectrlCore1_save);
22462 write_phy_reg(pi, 0xa7, afectrlCore2_save);
22463 write_phy_reg(pi, 0xa5, afectrlOverride_save);
22464 }
22465
22466 return (s16) radio_temp[0] + offset;
22467}
22468
22469static void
22470wlc_phy_set_rssi_2055_vcm(struct brcms_phy *pi, u8 rssi_type, u8 *vcm_buf)
22471{
22472 u8 core;
22473
22474 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
22475 if (rssi_type == NPHY_RSSI_SEL_NB) {
22476 if (core == PHY_CORE_0) {
22477 mod_radio_reg(pi,
22478 RADIO_2055_CORE1_B0_NBRSSI_VCM,
22479 RADIO_2055_NBRSSI_VCM_I_MASK,
22480 vcm_buf[2 *
22481 core] <<
22482 RADIO_2055_NBRSSI_VCM_I_SHIFT);
22483 mod_radio_reg(pi,
22484 RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
22485 RADIO_2055_NBRSSI_VCM_Q_MASK,
22486 vcm_buf[2 * core +
22487 1] <<
22488 RADIO_2055_NBRSSI_VCM_Q_SHIFT);
22489 } else {
22490 mod_radio_reg(pi,
22491 RADIO_2055_CORE2_B0_NBRSSI_VCM,
22492 RADIO_2055_NBRSSI_VCM_I_MASK,
22493 vcm_buf[2 *
22494 core] <<
22495 RADIO_2055_NBRSSI_VCM_I_SHIFT);
22496 mod_radio_reg(pi,
22497 RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
22498 RADIO_2055_NBRSSI_VCM_Q_MASK,
22499 vcm_buf[2 * core +
22500 1] <<
22501 RADIO_2055_NBRSSI_VCM_Q_SHIFT);
22502 }
22503 } else {
22504 if (core == PHY_CORE_0)
22505 mod_radio_reg(pi,
22506 RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
22507 RADIO_2055_WBRSSI_VCM_IQ_MASK,
22508 vcm_buf[2 *
22509 core] <<
22510 RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
22511 else
22512 mod_radio_reg(pi,
22513 RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
22514 RADIO_2055_WBRSSI_VCM_IQ_MASK,
22515 vcm_buf[2 *
22516 core] <<
22517 RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
22518 }
22519 }
22520}
22521
22522static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi)
22523{
22524 u16 classif_state;
22525 u16 clip_state[2];
22526 u16 clip_off[] = { 0xffff, 0xffff };
22527 s32 target_code;
22528 u8 vcm, min_vcm;
22529 u8 vcm_final = 0;
22530 u8 result_idx;
22531 s32 poll_results[8][4] = {
22532 {0, 0, 0, 0},
22533 {0, 0, 0, 0},
22534 {0, 0, 0, 0},
22535 {0, 0, 0, 0},
22536 {0, 0, 0, 0},
22537 {0, 0, 0, 0},
22538 {0, 0, 0, 0},
22539 {0, 0, 0, 0}
22540 };
22541 s32 poll_result_core[4] = { 0, 0, 0, 0 };
22542 s32 min_d = NPHY_RSSICAL_MAXD, curr_d;
22543 s32 fine_digital_offset[4];
22544 s32 poll_results_min[4] = { 0, 0, 0, 0 };
22545 s32 min_poll;
22546 u8 vcm_level_max;
22547 u8 core;
22548 u8 wb_cnt;
22549 u8 rssi_type;
22550 u16 NPHY_Rfctrlintc1_save, NPHY_Rfctrlintc2_save;
22551 u16 NPHY_AfectrlOverride1_save, NPHY_AfectrlOverride2_save;
22552 u16 NPHY_AfectrlCore1_save, NPHY_AfectrlCore2_save;
22553 u16 NPHY_RfctrlOverride0_save, NPHY_RfctrlOverride1_save;
22554 u16 NPHY_RfctrlOverrideAux0_save, NPHY_RfctrlOverrideAux1_save;
22555 u16 NPHY_RfctrlCmd_save;
22556 u16 NPHY_RfctrlMiscReg1_save, NPHY_RfctrlMiscReg2_save;
22557 u16 NPHY_RfctrlRSSIOTHERS1_save, NPHY_RfctrlRSSIOTHERS2_save;
22558 u8 rxcore_state;
22559 u16 NPHY_REV7_RfctrlOverride3_save, NPHY_REV7_RfctrlOverride4_save;
22560 u16 NPHY_REV7_RfctrlOverride5_save, NPHY_REV7_RfctrlOverride6_save;
22561 u16 NPHY_REV7_RfctrlMiscReg3_save, NPHY_REV7_RfctrlMiscReg4_save;
22562 u16 NPHY_REV7_RfctrlMiscReg5_save, NPHY_REV7_RfctrlMiscReg6_save;
22563
22564 NPHY_REV7_RfctrlOverride3_save =
22565 NPHY_REV7_RfctrlOverride4_save =
22566 NPHY_REV7_RfctrlOverride5_save =
22567 NPHY_REV7_RfctrlOverride6_save =
22568 NPHY_REV7_RfctrlMiscReg3_save =
22569 NPHY_REV7_RfctrlMiscReg4_save =
22570 NPHY_REV7_RfctrlMiscReg5_save =
22571 NPHY_REV7_RfctrlMiscReg6_save = 0;
22572
22573 classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
22574 wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
22575 wlc_phy_clip_det_nphy(pi, 0, clip_state);
22576 wlc_phy_clip_det_nphy(pi, 1, clip_off);
22577
22578 NPHY_Rfctrlintc1_save = read_phy_reg(pi, 0x91);
22579 NPHY_Rfctrlintc2_save = read_phy_reg(pi, 0x92);
22580 NPHY_AfectrlOverride1_save = read_phy_reg(pi, 0x8f);
22581 NPHY_AfectrlOverride2_save = read_phy_reg(pi, 0xa5);
22582 NPHY_AfectrlCore1_save = read_phy_reg(pi, 0xa6);
22583 NPHY_AfectrlCore2_save = read_phy_reg(pi, 0xa7);
22584 NPHY_RfctrlOverride0_save = read_phy_reg(pi, 0xe7);
22585 NPHY_RfctrlOverride1_save = read_phy_reg(pi, 0xec);
22586 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22587 NPHY_REV7_RfctrlOverride3_save = read_phy_reg(pi, 0x342);
22588 NPHY_REV7_RfctrlOverride4_save = read_phy_reg(pi, 0x343);
22589 NPHY_REV7_RfctrlOverride5_save = read_phy_reg(pi, 0x346);
22590 NPHY_REV7_RfctrlOverride6_save = read_phy_reg(pi, 0x347);
22591 }
22592 NPHY_RfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
22593 NPHY_RfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
22594 NPHY_RfctrlCmd_save = read_phy_reg(pi, 0x78);
22595 NPHY_RfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
22596 NPHY_RfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
22597 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22598 NPHY_REV7_RfctrlMiscReg3_save = read_phy_reg(pi, 0x340);
22599 NPHY_REV7_RfctrlMiscReg4_save = read_phy_reg(pi, 0x341);
22600 NPHY_REV7_RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
22601 NPHY_REV7_RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
22602 }
22603 NPHY_RfctrlRSSIOTHERS1_save = read_phy_reg(pi, 0x7a);
22604 NPHY_RfctrlRSSIOTHERS2_save = read_phy_reg(pi, 0x7d);
22605
22606 wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_OFF, 0,
22607 RADIO_MIMO_CORESEL_ALLRXTX);
22608 wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_TRSW, 1,
22609 RADIO_MIMO_CORESEL_ALLRXTX);
22610
22611 if (NREV_GE(pi->pubpi.phy_rev, 7))
22612 wlc_phy_rfctrl_override_1tomany_nphy(
22613 pi,
22614 NPHY_REV7_RfctrlOverride_cmd_rxrf_pu,
22615 0, 0, 0);
22616 else
22617 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0, 0);
22618
22619 if (NREV_GE(pi->pubpi.phy_rev, 7))
22620 wlc_phy_rfctrl_override_1tomany_nphy(
22621 pi,
22622 NPHY_REV7_RfctrlOverride_cmd_rx_pu,
22623 1, 0, 0);
22624 else
22625 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0, 0);
22626
22627 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22628 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
22629 1, 0, 0,
22630 NPHY_REV7_RFCTRLOVERRIDE_ID0);
22631 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 6), 1, 0, 0,
22632 NPHY_REV7_RFCTRLOVERRIDE_ID0);
22633 } else {
22634 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 7), 1, 0, 0);
22635 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 6), 1, 0, 0);
22636 }
22637
22638 if (CHSPEC_IS5G(pi->radio_chanspec)) {
22639 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22640 wlc_phy_rfctrl_override_nphy_rev7(
22641 pi, (0x1 << 5),
22642 0, 0, 0,
22643 NPHY_REV7_RFCTRLOVERRIDE_ID0);
22644 wlc_phy_rfctrl_override_nphy_rev7(
22645 pi, (0x1 << 4), 1, 0,
22646 0,
22647 NPHY_REV7_RFCTRLOVERRIDE_ID0);
22648 } else {
22649 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 0, 0, 0);
22650 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 1, 0, 0);
22651 }
22652
22653 } else {
22654 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22655 wlc_phy_rfctrl_override_nphy_rev7(
22656 pi, (0x1 << 4),
22657 0, 0, 0,
22658 NPHY_REV7_RFCTRLOVERRIDE_ID0);
22659 wlc_phy_rfctrl_override_nphy_rev7(
22660 pi, (0x1 << 5), 1, 0,
22661 0,
22662 NPHY_REV7_RFCTRLOVERRIDE_ID0);
22663 } else {
22664 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 0, 0, 0);
22665 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 1, 0, 0);
22666 }
22667 }
22668
22669 rxcore_state = wlc_phy_rxcore_getstate_nphy(
22670 (struct brcms_phy_pub *) pi);
22671
22672 vcm_level_max = 8;
22673
22674 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
22675
22676 if ((rxcore_state & (1 << core)) == 0)
22677 continue;
22678
22679 wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
22680 core ==
22681 PHY_CORE_0 ?
22682 RADIO_MIMO_CORESEL_CORE1 :
22683 RADIO_MIMO_CORESEL_CORE2,
22684 NPHY_RAIL_I, NPHY_RSSI_SEL_NB);
22685 wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
22686 core ==
22687 PHY_CORE_0 ?
22688 RADIO_MIMO_CORESEL_CORE1 :
22689 RADIO_MIMO_CORESEL_CORE2,
22690 NPHY_RAIL_Q, NPHY_RSSI_SEL_NB);
22691
22692 for (vcm = 0; vcm < vcm_level_max; vcm++) {
22693 if (NREV_GE(pi->pubpi.phy_rev, 7))
22694 mod_radio_reg(pi, (core == PHY_CORE_0) ?
22695 RADIO_2057_NB_MASTER_CORE0 :
22696 RADIO_2057_NB_MASTER_CORE1,
22697 RADIO_2057_VCM_MASK, vcm);
22698 else
22699 mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
22700 ((core ==
22701 PHY_CORE_0) ? RADIO_2056_RX0 :
22702 RADIO_2056_RX1),
22703 RADIO_2056_VCM_MASK,
22704 vcm << RADIO_2056_RSSI_VCM_SHIFT);
22705
22706 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_NB,
22707 &poll_results[vcm][0],
22708 NPHY_RSSICAL_NPOLL);
22709 }
22710
22711 for (result_idx = 0; result_idx < 4; result_idx++) {
22712 if ((core == result_idx / 2) &&
22713 (result_idx % 2 == 0)) {
22714
22715 min_d = NPHY_RSSICAL_MAXD;
22716 min_vcm = 0;
22717 min_poll =
22718 NPHY_RSSICAL_MAXREAD *
22719 NPHY_RSSICAL_NPOLL + 1;
22720 for (vcm = 0; vcm < vcm_level_max; vcm++) {
22721 curr_d =
22722 poll_results[vcm][result_idx] *
22723 poll_results[vcm][result_idx] +
22724 poll_results[vcm][result_idx +
22725 1] *
22726 poll_results[vcm][result_idx +
22727 1];
22728 if (curr_d < min_d) {
22729 min_d = curr_d;
22730 min_vcm = vcm;
22731 }
22732 if (poll_results[vcm][result_idx] <
22733 min_poll)
22734 min_poll =
22735 poll_results[vcm]
22736 [result_idx];
22737 }
22738 vcm_final = min_vcm;
22739 poll_results_min[result_idx] = min_poll;
22740 }
22741 }
22742
22743 if (NREV_GE(pi->pubpi.phy_rev, 7))
22744 mod_radio_reg(pi, (core == PHY_CORE_0) ?
22745 RADIO_2057_NB_MASTER_CORE0 :
22746 RADIO_2057_NB_MASTER_CORE1,
22747 RADIO_2057_VCM_MASK, vcm_final);
22748 else
22749 mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
22750 ((core ==
22751 PHY_CORE_0) ? RADIO_2056_RX0 :
22752 RADIO_2056_RX1), RADIO_2056_VCM_MASK,
22753 vcm_final << RADIO_2056_RSSI_VCM_SHIFT);
22754
22755 for (result_idx = 0; result_idx < 4; result_idx++) {
22756 if (core == result_idx / 2) {
22757 fine_digital_offset[result_idx] =
22758 (NPHY_RSSICAL_NB_TARGET *
22759 NPHY_RSSICAL_NPOLL) -
22760 poll_results[vcm_final][result_idx];
22761 if (fine_digital_offset[result_idx] < 0) {
22762 fine_digital_offset[result_idx] =
22763 abs(fine_digital_offset
22764 [result_idx]);
22765 fine_digital_offset[result_idx] +=
22766 (NPHY_RSSICAL_NPOLL / 2);
22767 fine_digital_offset[result_idx] /=
22768 NPHY_RSSICAL_NPOLL;
22769 fine_digital_offset[result_idx] =
22770 -fine_digital_offset[
22771 result_idx];
22772 } else {
22773 fine_digital_offset[result_idx] +=
22774 (NPHY_RSSICAL_NPOLL / 2);
22775 fine_digital_offset[result_idx] /=
22776 NPHY_RSSICAL_NPOLL;
22777 }
22778
22779 if (poll_results_min[result_idx] ==
22780 NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL)
22781 fine_digital_offset[result_idx] =
22782 (NPHY_RSSICAL_NB_TARGET -
22783 NPHY_RSSICAL_MAXREAD - 1);
22784
22785 wlc_phy_scale_offset_rssi_nphy(
22786 pi, 0x0,
22787 (s8)
22788 fine_digital_offset
22789 [result_idx],
22790 (result_idx / 2 == 0) ?
22791 RADIO_MIMO_CORESEL_CORE1 :
22792 RADIO_MIMO_CORESEL_CORE2,
22793 (result_idx % 2 == 0) ?
22794 NPHY_RAIL_I : NPHY_RAIL_Q,
22795 NPHY_RSSI_SEL_NB);
22796 }
22797 }
22798
22799 }
22800
22801 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
22802
22803 if ((rxcore_state & (1 << core)) == 0)
22804 continue;
22805
22806 for (wb_cnt = 0; wb_cnt < 2; wb_cnt++) {
22807 if (wb_cnt == 0) {
22808 rssi_type = NPHY_RSSI_SEL_W1;
22809 target_code = NPHY_RSSICAL_W1_TARGET_REV3;
22810 } else {
22811 rssi_type = NPHY_RSSI_SEL_W2;
22812 target_code = NPHY_RSSICAL_W2_TARGET_REV3;
22813 }
22814
22815 wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
22816 core ==
22817 PHY_CORE_0 ?
22818 RADIO_MIMO_CORESEL_CORE1
22819 :
22820 RADIO_MIMO_CORESEL_CORE2,
22821 NPHY_RAIL_I, rssi_type);
22822 wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
22823 core ==
22824 PHY_CORE_0 ?
22825 RADIO_MIMO_CORESEL_CORE1
22826 :
22827 RADIO_MIMO_CORESEL_CORE2,
22828 NPHY_RAIL_Q, rssi_type);
22829
22830 wlc_phy_poll_rssi_nphy(pi, rssi_type, poll_result_core,
22831 NPHY_RSSICAL_NPOLL);
22832
22833 for (result_idx = 0; result_idx < 4; result_idx++) {
22834 if (core == result_idx / 2) {
22835 fine_digital_offset[result_idx] =
22836 (target_code *
22837 NPHY_RSSICAL_NPOLL) -
22838 poll_result_core[result_idx];
22839 if (fine_digital_offset[result_idx] <
22840 0) {
22841 fine_digital_offset[result_idx]
22842 = abs(
22843 fine_digital_offset
22844 [result_idx]);
22845 fine_digital_offset[result_idx]
22846 += (NPHY_RSSICAL_NPOLL
22847 / 2);
22848 fine_digital_offset[result_idx]
22849 /= NPHY_RSSICAL_NPOLL;
22850 fine_digital_offset[result_idx]
22851 = -fine_digital_offset
22852 [result_idx];
22853 } else {
22854 fine_digital_offset[result_idx]
22855 += (NPHY_RSSICAL_NPOLL
22856 / 2);
22857 fine_digital_offset[result_idx]
22858 /= NPHY_RSSICAL_NPOLL;
22859 }
22860
22861 wlc_phy_scale_offset_rssi_nphy(
22862 pi, 0x0,
22863 (s8)
22864 fine_digital_offset
22865 [core *
22866 2],
22867 (core == PHY_CORE_0) ?
22868 RADIO_MIMO_CORESEL_CORE1 :
22869 RADIO_MIMO_CORESEL_CORE2,
22870 (result_idx % 2 == 0) ?
22871 NPHY_RAIL_I :
22872 NPHY_RAIL_Q,
22873 rssi_type);
22874 }
22875 }
22876
22877 }
22878 }
22879
22880 write_phy_reg(pi, 0x91, NPHY_Rfctrlintc1_save);
22881 write_phy_reg(pi, 0x92, NPHY_Rfctrlintc2_save);
22882
22883 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
22884
22885 mod_phy_reg(pi, 0xe7, (0x1 << 0), 1 << 0);
22886 mod_phy_reg(pi, 0x78, (0x1 << 0), 1 << 0);
22887 mod_phy_reg(pi, 0xe7, (0x1 << 0), 0);
22888
22889 mod_phy_reg(pi, 0xec, (0x1 << 0), 1 << 0);
22890 mod_phy_reg(pi, 0x78, (0x1 << 1), 1 << 1);
22891 mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
22892
22893 write_phy_reg(pi, 0x8f, NPHY_AfectrlOverride1_save);
22894 write_phy_reg(pi, 0xa5, NPHY_AfectrlOverride2_save);
22895 write_phy_reg(pi, 0xa6, NPHY_AfectrlCore1_save);
22896 write_phy_reg(pi, 0xa7, NPHY_AfectrlCore2_save);
22897 write_phy_reg(pi, 0xe7, NPHY_RfctrlOverride0_save);
22898 write_phy_reg(pi, 0xec, NPHY_RfctrlOverride1_save);
22899 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22900 write_phy_reg(pi, 0x342, NPHY_REV7_RfctrlOverride3_save);
22901 write_phy_reg(pi, 0x343, NPHY_REV7_RfctrlOverride4_save);
22902 write_phy_reg(pi, 0x346, NPHY_REV7_RfctrlOverride5_save);
22903 write_phy_reg(pi, 0x347, NPHY_REV7_RfctrlOverride6_save);
22904 }
22905 write_phy_reg(pi, 0xe5, NPHY_RfctrlOverrideAux0_save);
22906 write_phy_reg(pi, 0xe6, NPHY_RfctrlOverrideAux1_save);
22907 write_phy_reg(pi, 0x78, NPHY_RfctrlCmd_save);
22908 write_phy_reg(pi, 0xf9, NPHY_RfctrlMiscReg1_save);
22909 write_phy_reg(pi, 0xfb, NPHY_RfctrlMiscReg2_save);
22910 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22911 write_phy_reg(pi, 0x340, NPHY_REV7_RfctrlMiscReg3_save);
22912 write_phy_reg(pi, 0x341, NPHY_REV7_RfctrlMiscReg4_save);
22913 write_phy_reg(pi, 0x344, NPHY_REV7_RfctrlMiscReg5_save);
22914 write_phy_reg(pi, 0x345, NPHY_REV7_RfctrlMiscReg6_save);
22915 }
22916 write_phy_reg(pi, 0x7a, NPHY_RfctrlRSSIOTHERS1_save);
22917 write_phy_reg(pi, 0x7d, NPHY_RfctrlRSSIOTHERS2_save);
22918
22919 if (CHSPEC_IS2G(pi->radio_chanspec)) {
22920 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22921 pi->rssical_cache.rssical_radio_regs_2G[0] =
22922 read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
22923 pi->rssical_cache.rssical_radio_regs_2G[1] =
22924 read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
22925 } else {
22926 pi->rssical_cache.rssical_radio_regs_2G[0] =
22927 read_radio_reg(pi,
22928 RADIO_2056_RX_RSSI_MISC |
22929 RADIO_2056_RX0);
22930 pi->rssical_cache.rssical_radio_regs_2G[1] =
22931 read_radio_reg(pi,
22932 RADIO_2056_RX_RSSI_MISC |
22933 RADIO_2056_RX1);
22934 }
22935
22936 pi->rssical_cache.rssical_phyregs_2G[0] =
22937 read_phy_reg(pi, 0x1a6);
22938 pi->rssical_cache.rssical_phyregs_2G[1] =
22939 read_phy_reg(pi, 0x1ac);
22940 pi->rssical_cache.rssical_phyregs_2G[2] =
22941 read_phy_reg(pi, 0x1b2);
22942 pi->rssical_cache.rssical_phyregs_2G[3] =
22943 read_phy_reg(pi, 0x1b8);
22944 pi->rssical_cache.rssical_phyregs_2G[4] =
22945 read_phy_reg(pi, 0x1a4);
22946 pi->rssical_cache.rssical_phyregs_2G[5] =
22947 read_phy_reg(pi, 0x1aa);
22948 pi->rssical_cache.rssical_phyregs_2G[6] =
22949 read_phy_reg(pi, 0x1b0);
22950 pi->rssical_cache.rssical_phyregs_2G[7] =
22951 read_phy_reg(pi, 0x1b6);
22952 pi->rssical_cache.rssical_phyregs_2G[8] =
22953 read_phy_reg(pi, 0x1a5);
22954 pi->rssical_cache.rssical_phyregs_2G[9] =
22955 read_phy_reg(pi, 0x1ab);
22956 pi->rssical_cache.rssical_phyregs_2G[10] =
22957 read_phy_reg(pi, 0x1b1);
22958 pi->rssical_cache.rssical_phyregs_2G[11] =
22959 read_phy_reg(pi, 0x1b7);
22960
22961 pi->nphy_rssical_chanspec_2G = pi->radio_chanspec;
22962 } else {
22963 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22964 pi->rssical_cache.rssical_radio_regs_5G[0] =
22965 read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
22966 pi->rssical_cache.rssical_radio_regs_5G[1] =
22967 read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
22968 } else {
22969 pi->rssical_cache.rssical_radio_regs_5G[0] =
22970 read_radio_reg(pi,
22971 RADIO_2056_RX_RSSI_MISC |
22972 RADIO_2056_RX0);
22973 pi->rssical_cache.rssical_radio_regs_5G[1] =
22974 read_radio_reg(pi,
22975 RADIO_2056_RX_RSSI_MISC |
22976 RADIO_2056_RX1);
22977 }
22978
22979 pi->rssical_cache.rssical_phyregs_5G[0] =
22980 read_phy_reg(pi, 0x1a6);
22981 pi->rssical_cache.rssical_phyregs_5G[1] =
22982 read_phy_reg(pi, 0x1ac);
22983 pi->rssical_cache.rssical_phyregs_5G[2] =
22984 read_phy_reg(pi, 0x1b2);
22985 pi->rssical_cache.rssical_phyregs_5G[3] =
22986 read_phy_reg(pi, 0x1b8);
22987 pi->rssical_cache.rssical_phyregs_5G[4] =
22988 read_phy_reg(pi, 0x1a4);
22989 pi->rssical_cache.rssical_phyregs_5G[5] =
22990 read_phy_reg(pi, 0x1aa);
22991 pi->rssical_cache.rssical_phyregs_5G[6] =
22992 read_phy_reg(pi, 0x1b0);
22993 pi->rssical_cache.rssical_phyregs_5G[7] =
22994 read_phy_reg(pi, 0x1b6);
22995 pi->rssical_cache.rssical_phyregs_5G[8] =
22996 read_phy_reg(pi, 0x1a5);
22997 pi->rssical_cache.rssical_phyregs_5G[9] =
22998 read_phy_reg(pi, 0x1ab);
22999 pi->rssical_cache.rssical_phyregs_5G[10] =
23000 read_phy_reg(pi, 0x1b1);
23001 pi->rssical_cache.rssical_phyregs_5G[11] =
23002 read_phy_reg(pi, 0x1b7);
23003
23004 pi->nphy_rssical_chanspec_5G = pi->radio_chanspec;
23005 }
23006
23007 wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
23008 wlc_phy_clip_det_nphy(pi, 1, clip_state);
23009}
23010
23011static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type)
23012{
23013 s32 target_code;
23014 u16 classif_state;
23015 u16 clip_state[2];
23016 u16 rssi_ctrl_state[2], pd_state[2];
23017 u16 rfctrlintc_state[2], rfpdcorerxtx_state[2];
23018 u16 rfctrlintc_override_val;
23019 u16 clip_off[] = { 0xffff, 0xffff };
23020 u16 rf_pd_val, pd_mask, rssi_ctrl_mask;
23021 u8 vcm, min_vcm, vcm_tmp[4];
23022 u8 vcm_final[4] = { 0, 0, 0, 0 };
23023 u8 result_idx, ctr;
23024 s32 poll_results[4][4] = {
23025 {0, 0, 0, 0},
23026 {0, 0, 0, 0},
23027 {0, 0, 0, 0},
23028 {0, 0, 0, 0}
23029 };
23030 s32 poll_miniq[4][2] = {
23031 {0, 0},
23032 {0, 0},
23033 {0, 0},
23034 {0, 0}
23035 };
23036 s32 min_d, curr_d;
23037 s32 fine_digital_offset[4];
23038 s32 poll_results_min[4] = { 0, 0, 0, 0 };
23039 s32 min_poll;
23040
23041 switch (rssi_type) {
23042 case NPHY_RSSI_SEL_NB:
23043 target_code = NPHY_RSSICAL_NB_TARGET;
23044 break;
23045 case NPHY_RSSI_SEL_W1:
23046 target_code = NPHY_RSSICAL_W1_TARGET;
23047 break;
23048 case NPHY_RSSI_SEL_W2:
23049 target_code = NPHY_RSSICAL_W2_TARGET;
23050 break;
23051 default:
23052 return;
23053 break;
23054 }
23055
23056 classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
23057 wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
23058 wlc_phy_clip_det_nphy(pi, 0, clip_state);
23059 wlc_phy_clip_det_nphy(pi, 1, clip_off);
23060
23061 rf_pd_val = (rssi_type == NPHY_RSSI_SEL_NB) ? 0x6 : 0x4;
23062 rfctrlintc_override_val =
23063 CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : 0x110;
23064
23065 rfctrlintc_state[0] = read_phy_reg(pi, 0x91);
23066 rfpdcorerxtx_state[0] = read_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX);
23067 write_phy_reg(pi, 0x91, rfctrlintc_override_val);
23068 write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rf_pd_val);
23069
23070 rfctrlintc_state[1] = read_phy_reg(pi, 0x92);
23071 rfpdcorerxtx_state[1] = read_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX);
23072 write_phy_reg(pi, 0x92, rfctrlintc_override_val);
23073 write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rf_pd_val);
23074
23075 pd_mask = RADIO_2055_NBRSSI_PD | RADIO_2055_WBRSSI_G1_PD |
23076 RADIO_2055_WBRSSI_G2_PD;
23077 pd_state[0] =
23078 read_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC) & pd_mask;
23079 pd_state[1] =
23080 read_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC) & pd_mask;
23081 mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, 0);
23082 mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, 0);
23083 rssi_ctrl_mask = RADIO_2055_NBRSSI_SEL | RADIO_2055_WBRSSI_G1_SEL |
23084 RADIO_2055_WBRSSI_G2_SEL;
23085 rssi_ctrl_state[0] =
23086 read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE1) & rssi_ctrl_mask;
23087 rssi_ctrl_state[1] =
23088 read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE2) & rssi_ctrl_mask;
23089 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
23090
23091 wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
23092 NPHY_RAIL_I, rssi_type);
23093 wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
23094 NPHY_RAIL_Q, rssi_type);
23095
23096 for (vcm = 0; vcm < 4; vcm++) {
23097
23098 vcm_tmp[0] = vcm_tmp[1] = vcm_tmp[2] = vcm_tmp[3] = vcm;
23099 if (rssi_type != NPHY_RSSI_SEL_W2)
23100 wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_tmp);
23101
23102 wlc_phy_poll_rssi_nphy(pi, rssi_type, &poll_results[vcm][0],
23103 NPHY_RSSICAL_NPOLL);
23104
23105 if ((rssi_type == NPHY_RSSI_SEL_W1)
23106 || (rssi_type == NPHY_RSSI_SEL_W2)) {
23107 for (ctr = 0; ctr < 2; ctr++)
23108 poll_miniq[vcm][ctr] =
23109 min(poll_results[vcm][ctr * 2 + 0],
23110 poll_results[vcm][ctr * 2 + 1]);
23111 }
23112 }
23113
23114 for (result_idx = 0; result_idx < 4; result_idx++) {
23115 min_d = NPHY_RSSICAL_MAXD;
23116 min_vcm = 0;
23117 min_poll = NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + 1;
23118 for (vcm = 0; vcm < 4; vcm++) {
23119 curr_d = abs(((rssi_type == NPHY_RSSI_SEL_NB) ?
23120 poll_results[vcm][result_idx] :
23121 poll_miniq[vcm][result_idx / 2]) -
23122 (target_code * NPHY_RSSICAL_NPOLL));
23123 if (curr_d < min_d) {
23124 min_d = curr_d;
23125 min_vcm = vcm;
23126 }
23127 if (poll_results[vcm][result_idx] < min_poll)
23128 min_poll = poll_results[vcm][result_idx];
23129 }
23130 vcm_final[result_idx] = min_vcm;
23131 poll_results_min[result_idx] = min_poll;
23132 }
23133
23134 if (rssi_type != NPHY_RSSI_SEL_W2)
23135 wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_final);
23136
23137 for (result_idx = 0; result_idx < 4; result_idx++) {
23138 fine_digital_offset[result_idx] =
23139 (target_code * NPHY_RSSICAL_NPOLL) -
23140 poll_results[vcm_final[result_idx]][result_idx];
23141 if (fine_digital_offset[result_idx] < 0) {
23142 fine_digital_offset[result_idx] =
23143 abs(fine_digital_offset[result_idx]);
23144 fine_digital_offset[result_idx] +=
23145 (NPHY_RSSICAL_NPOLL / 2);
23146 fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
23147 fine_digital_offset[result_idx] =
23148 -fine_digital_offset[result_idx];
23149 } else {
23150 fine_digital_offset[result_idx] +=
23151 (NPHY_RSSICAL_NPOLL / 2);
23152 fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
23153 }
23154
23155 if (poll_results_min[result_idx] ==
23156 NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL)
23157 fine_digital_offset[result_idx] =
23158 (target_code - NPHY_RSSICAL_MAXREAD - 1);
23159
23160 wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
23161 (s8)
23162 fine_digital_offset[result_idx],
23163 (result_idx / 2 ==
23164 0) ? RADIO_MIMO_CORESEL_CORE1 :
23165 RADIO_MIMO_CORESEL_CORE2,
23166 (result_idx % 2 ==
23167 0) ? NPHY_RAIL_I : NPHY_RAIL_Q,
23168 rssi_type);
23169 }
23170
23171 mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, pd_state[0]);
23172 mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, pd_state[1]);
23173 if (rssi_ctrl_state[0] == RADIO_2055_NBRSSI_SEL)
23174 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
23175 NPHY_RSSI_SEL_NB);
23176 else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL)
23177 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
23178 NPHY_RSSI_SEL_W1);
23179 else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G2_SEL)
23180 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
23181 NPHY_RSSI_SEL_W2);
23182 else
23183 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
23184 NPHY_RSSI_SEL_W2);
23185 if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL)
23186 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
23187 NPHY_RSSI_SEL_NB);
23188 else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL)
23189 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
23190 NPHY_RSSI_SEL_W1);
23191 else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G2_SEL)
23192 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
23193 NPHY_RSSI_SEL_W2);
23194 else
23195 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
23196 NPHY_RSSI_SEL_W2);
23197
23198 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type);
23199
23200 write_phy_reg(pi, 0x91, rfctrlintc_state[0]);
23201 write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rfpdcorerxtx_state[0]);
23202 write_phy_reg(pi, 0x92, rfctrlintc_state[1]);
23203 write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rfpdcorerxtx_state[1]);
23204
23205 wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
23206 wlc_phy_clip_det_nphy(pi, 1, clip_state);
23207
23208 wlc_phy_resetcca_nphy(pi);
23209}
23210
23211void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi)
23212{
23213 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
23214 wlc_phy_rssi_cal_nphy_rev3(pi);
23215 } else {
23216 wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_NB);
23217 wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W1);
23218 wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W2);
23219 }
23220}
23221
23222int
23223wlc_phy_rssi_compute_nphy(struct brcms_phy *pi, struct d11rxhdr *rxh)
23224{
23225 s16 rxpwr, rxpwr0, rxpwr1;
23226 s16 phyRx0_l, phyRx2_l;
23227
23228 rxpwr = 0;
23229 rxpwr0 = rxh->PhyRxStatus_1 & PRXS1_nphy_PWR0_MASK;
23230 rxpwr1 = (rxh->PhyRxStatus_1 & PRXS1_nphy_PWR1_MASK) >> 8;
23231
23232 if (rxpwr0 > 127)
23233 rxpwr0 -= 256;
23234 if (rxpwr1 > 127)
23235 rxpwr1 -= 256;
23236
23237 phyRx0_l = rxh->PhyRxStatus_0 & 0x00ff;
23238 phyRx2_l = rxh->PhyRxStatus_2 & 0x00ff;
23239 if (phyRx2_l > 127)
23240 phyRx2_l -= 256;
23241
23242 if (((rxpwr0 == 16) || (rxpwr0 == 32))) {
23243 rxpwr0 = rxpwr1;
23244 rxpwr1 = phyRx2_l;
23245 }
23246
23247 if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MAX)
23248 rxpwr = (rxpwr0 > rxpwr1) ? rxpwr0 : rxpwr1;
23249 else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MIN)
23250 rxpwr = (rxpwr0 < rxpwr1) ? rxpwr0 : rxpwr1;
23251 else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_AVG)
23252 rxpwr = (rxpwr0 + rxpwr1) >> 1;
23253
23254 return rxpwr;
23255}
23256
23257static void
23258wlc_phy_loadsampletable_nphy(struct brcms_phy *pi, struct cordic_iq *tone_buf,
23259 u16 num_samps)
23260{
23261 u16 t;
23262 u32 *data_buf = NULL;
23263
23264 data_buf = kmalloc(sizeof(u32) * num_samps, GFP_ATOMIC);
23265 if (data_buf == NULL)
23266 return;
23267
23268 if (pi->phyhang_avoid)
23269 wlc_phy_stay_in_carriersearch_nphy(pi, true);
23270
23271 for (t = 0; t < num_samps; t++)
23272 data_buf[t] = ((((unsigned int)tone_buf[t].i) & 0x3ff) << 10) |
23273 (((unsigned int)tone_buf[t].q) & 0x3ff);
23274 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SAMPLEPLAY, num_samps, 0, 32,
23275 data_buf);
23276
23277 kfree(data_buf);
23278
23279 if (pi->phyhang_avoid)
23280 wlc_phy_stay_in_carriersearch_nphy(pi, false);
23281}
23282
23283static u16
23284wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
23285 u8 dac_test_mode)
23286{
23287 u8 phy_bw, is_phybw40;
23288 u16 num_samps, t, spur;
23289 s32 theta = 0, rot = 0;
23290 u32 tbl_len;
23291 struct cordic_iq *tone_buf = NULL;
23292
23293 is_phybw40 = CHSPEC_IS40(pi->radio_chanspec);
23294 phy_bw = (is_phybw40 == 1) ? 40 : 20;
23295 tbl_len = (phy_bw << 3);
23296
23297 if (dac_test_mode == 1) {
23298 spur = read_phy_reg(pi, 0x01);
23299 spur = (spur >> 15) & 1;
23300 phy_bw = (spur == 1) ? 82 : 80;
23301 phy_bw = (is_phybw40 == 1) ? (phy_bw << 1) : phy_bw;
23302
23303 tbl_len = (phy_bw << 1);
23304 }
23305
23306 tone_buf = kmalloc(sizeof(struct cordic_iq) * tbl_len, GFP_ATOMIC);
23307 if (tone_buf == NULL)
23308 return 0;
23309
23310 num_samps = (u16) tbl_len;
23311 rot = ((f_kHz * 36) / phy_bw) / 100;
23312 theta = 0;
23313
23314 for (t = 0; t < num_samps; t++) {
23315
23316 tone_buf[t] = cordic_calc_iq(theta);
23317
23318 theta += rot;
23319
23320 tone_buf[t].q = (s32) FLOAT(tone_buf[t].q * max_val);
23321 tone_buf[t].i = (s32) FLOAT(tone_buf[t].i * max_val);
23322 }
23323
23324 wlc_phy_loadsampletable_nphy(pi, tone_buf, num_samps);
23325
23326 kfree(tone_buf);
23327
23328 return num_samps;
23329}
23330
23331static void
23332wlc_phy_runsamples_nphy(struct brcms_phy *pi, u16 num_samps, u16 loops,
23333 u16 wait, u8 iqmode, u8 dac_test_mode,
23334 bool modify_bbmult)
23335{
23336 u16 bb_mult;
23337 u8 phy_bw, sample_cmd;
23338 u16 orig_RfseqCoreActv;
23339 u16 lpf_bw_ctl_override3, lpf_bw_ctl_override4, lpf_bw_ctl_miscreg3,
23340 lpf_bw_ctl_miscreg4;
23341
23342 if (pi->phyhang_avoid)
23343 wlc_phy_stay_in_carriersearch_nphy(pi, true);
23344
23345 phy_bw = 20;
23346 if (CHSPEC_IS40(pi->radio_chanspec))
23347 phy_bw = 40;
23348
23349 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
23350
23351 lpf_bw_ctl_override3 = read_phy_reg(pi, 0x342) & (0x1 << 7);
23352 lpf_bw_ctl_override4 = read_phy_reg(pi, 0x343) & (0x1 << 7);
23353 if (lpf_bw_ctl_override3 | lpf_bw_ctl_override4) {
23354 lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
23355 (0x7 << 8);
23356 lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
23357 (0x7 << 8);
23358 } else {
23359 wlc_phy_rfctrl_override_nphy_rev7(
23360 pi,
23361 (0x1 << 7),
23362 wlc_phy_read_lpf_bw_ctl_nphy
23363 (pi,
23364 0), 0, 0,
23365 NPHY_REV7_RFCTRLOVERRIDE_ID1);
23366
23367 pi->nphy_sample_play_lpf_bw_ctl_ovr = true;
23368
23369 lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
23370 (0x7 << 8);
23371 lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
23372 (0x7 << 8);
23373 }
23374 }
23375
23376 if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) == 0) {
23377
23378 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
23379 &bb_mult);
23380 pi->nphy_bb_mult_save =
23381 BB_MULT_VALID_MASK | (bb_mult & BB_MULT_MASK);
23382 }
23383
23384 if (modify_bbmult) {
23385 bb_mult = (phy_bw == 20) ? 100 : 71;
23386 bb_mult = (bb_mult << 8) + bb_mult;
23387 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
23388 &bb_mult);
23389 }
23390
23391 if (pi->phyhang_avoid)
23392 wlc_phy_stay_in_carriersearch_nphy(pi, false);
23393
23394 write_phy_reg(pi, 0xc6, num_samps - 1);
23395
23396 if (loops != 0xffff)
23397 write_phy_reg(pi, 0xc4, loops - 1);
23398 else
23399 write_phy_reg(pi, 0xc4, loops);
23400
23401 write_phy_reg(pi, 0xc5, wait);
23402
23403 orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
23404 or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
23405 if (iqmode) {
23406
23407 and_phy_reg(pi, 0xc2, 0x7FFF);
23408
23409 or_phy_reg(pi, 0xc2, 0x8000);
23410 } else {
23411
23412 sample_cmd = (dac_test_mode == 1) ? 0x5 : 0x1;
23413 write_phy_reg(pi, 0xc3, sample_cmd);
23414 }
23415
23416 SPINWAIT(((read_phy_reg(pi, 0xa4) & 0x1) == 1), 1000);
23417
23418 write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
23419}
23420
23421int
23422wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
23423 u8 iqmode, u8 dac_test_mode, bool modify_bbmult)
23424{
23425 u16 num_samps;
23426 u16 loops = 0xffff;
23427 u16 wait = 0;
23428
23429 num_samps = wlc_phy_gen_load_samples_nphy(pi, f_kHz, max_val,
23430 dac_test_mode);
23431 if (num_samps == 0)
23432 return -EBADE;
23433
23434 wlc_phy_runsamples_nphy(pi, num_samps, loops, wait, iqmode,
23435 dac_test_mode, modify_bbmult);
23436
23437 return 0;
23438}
23439
23440void wlc_phy_stopplayback_nphy(struct brcms_phy *pi)
23441{
23442 u16 playback_status;
23443 u16 bb_mult;
23444
23445 if (pi->phyhang_avoid)
23446 wlc_phy_stay_in_carriersearch_nphy(pi, true);
23447
23448 playback_status = read_phy_reg(pi, 0xc7);
23449 if (playback_status & 0x1)
23450 or_phy_reg(pi, 0xc3, NPHY_sampleCmd_STOP);
23451 else if (playback_status & 0x2)
23452 and_phy_reg(pi, 0xc2,
23453 (u16) ~NPHY_iqloCalCmdGctl_IQLO_CAL_EN);
23454
23455 and_phy_reg(pi, 0xc3, (u16) ~(0x1 << 2));
23456
23457 if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) != 0) {
23458
23459 bb_mult = pi->nphy_bb_mult_save & BB_MULT_MASK;
23460 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
23461 &bb_mult);
23462
23463 pi->nphy_bb_mult_save = 0;
23464 }
23465
23466 if (NREV_IS(pi->pubpi.phy_rev, 7) || NREV_GE(pi->pubpi.phy_rev, 8)) {
23467 if (pi->nphy_sample_play_lpf_bw_ctl_ovr) {
23468 wlc_phy_rfctrl_override_nphy_rev7(
23469 pi,
23470 (0x1 << 7),
23471 0, 0, 1,
23472 NPHY_REV7_RFCTRLOVERRIDE_ID1);
23473 pi->nphy_sample_play_lpf_bw_ctl_ovr = false;
23474 }
23475 }
23476
23477 if (pi->phyhang_avoid)
23478 wlc_phy_stay_in_carriersearch_nphy(pi, false);
23479}
23480
23481static u32 *brcms_phy_get_tx_pwrctrl_tbl(struct brcms_phy *pi)
23482{
23483 u32 *tx_pwrctrl_tbl = NULL;
23484 uint phyrev = pi->pubpi.phy_rev;
23485
23486 if (PHY_IPA(pi)) {
23487 tx_pwrctrl_tbl =
23488 wlc_phy_get_ipa_gaintbl_nphy(pi);
23489 } else {
23490 if (CHSPEC_IS5G(pi->radio_chanspec)) {
23491 if (NREV_IS(phyrev, 3))
23492 tx_pwrctrl_tbl = nphy_tpc_5GHz_txgain_rev3;
23493 else if (NREV_IS(phyrev, 4))
23494 tx_pwrctrl_tbl =
23495 (pi->srom_fem5g.extpagain == 3) ?
23496 nphy_tpc_5GHz_txgain_HiPwrEPA :
23497 nphy_tpc_5GHz_txgain_rev4;
23498 else
23499 tx_pwrctrl_tbl = nphy_tpc_5GHz_txgain_rev5;
23500 } else {
23501 if (NREV_GE(phyrev, 7)) {
23502 if (pi->pubpi.radiorev == 3)
23503 tx_pwrctrl_tbl =
23504 nphy_tpc_txgain_epa_2057rev3;
23505 else if (pi->pubpi.radiorev == 5)
23506 tx_pwrctrl_tbl =
23507 nphy_tpc_txgain_epa_2057rev5;
23508 } else {
23509 if (NREV_GE(phyrev, 5) &&
23510 (pi->srom_fem2g.extpagain == 3))
23511 tx_pwrctrl_tbl =
23512 nphy_tpc_txgain_HiPwrEPA;
23513 else
23514 tx_pwrctrl_tbl =
23515 nphy_tpc_txgain_rev3;
23516 }
23517 }
23518 }
23519 return tx_pwrctrl_tbl;
23520}
23521
23522struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi)
23523{
23524 u16 base_idx[2], curr_gain[2];
23525 u8 core_no;
23526 struct nphy_txgains target_gain;
23527 u32 *tx_pwrctrl_tbl = NULL;
23528
23529 if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
23530 if (pi->phyhang_avoid)
23531 wlc_phy_stay_in_carriersearch_nphy(pi, true);
23532
23533 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
23534 curr_gain);
23535
23536 if (pi->phyhang_avoid)
23537 wlc_phy_stay_in_carriersearch_nphy(pi, false);
23538
23539 for (core_no = 0; core_no < 2; core_no++) {
23540 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
23541 target_gain.ipa[core_no] =
23542 curr_gain[core_no] & 0x0007;
23543 target_gain.pad[core_no] =
23544 ((curr_gain[core_no] & 0x00F8) >> 3);
23545 target_gain.pga[core_no] =
23546 ((curr_gain[core_no] & 0x0F00) >> 8);
23547 target_gain.txgm[core_no] =
23548 ((curr_gain[core_no] & 0x7000) >> 12);
23549 target_gain.txlpf[core_no] =
23550 ((curr_gain[core_no] & 0x8000) >> 15);
23551 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
23552 target_gain.ipa[core_no] =
23553 curr_gain[core_no] & 0x000F;
23554 target_gain.pad[core_no] =
23555 ((curr_gain[core_no] & 0x00F0) >> 4);
23556 target_gain.pga[core_no] =
23557 ((curr_gain[core_no] & 0x0F00) >> 8);
23558 target_gain.txgm[core_no] =
23559 ((curr_gain[core_no] & 0x7000) >> 12);
23560 } else {
23561 target_gain.ipa[core_no] =
23562 curr_gain[core_no] & 0x0003;
23563 target_gain.pad[core_no] =
23564 ((curr_gain[core_no] & 0x000C) >> 2);
23565 target_gain.pga[core_no] =
23566 ((curr_gain[core_no] & 0x0070) >> 4);
23567 target_gain.txgm[core_no] =
23568 ((curr_gain[core_no] & 0x0380) >> 7);
23569 }
23570 }
23571 } else {
23572 uint phyrev = pi->pubpi.phy_rev;
23573
23574 base_idx[0] = (read_phy_reg(pi, 0x1ed) >> 8) & 0x7f;
23575 base_idx[1] = (read_phy_reg(pi, 0x1ee) >> 8) & 0x7f;
23576 for (core_no = 0; core_no < 2; core_no++) {
23577 if (NREV_GE(phyrev, 3)) {
23578 tx_pwrctrl_tbl =
23579 brcms_phy_get_tx_pwrctrl_tbl(pi);
23580 if (NREV_GE(phyrev, 7)) {
23581 target_gain.ipa[core_no] =
23582 (tx_pwrctrl_tbl
23583 [base_idx[core_no]]
23584 >> 16) & 0x7;
23585 target_gain.pad[core_no] =
23586 (tx_pwrctrl_tbl
23587 [base_idx[core_no]]
23588 >> 19) & 0x1f;
23589 target_gain.pga[core_no] =
23590 (tx_pwrctrl_tbl
23591 [base_idx[core_no]]
23592 >> 24) & 0xf;
23593 target_gain.txgm[core_no] =
23594 (tx_pwrctrl_tbl
23595 [base_idx[core_no]]
23596 >> 28) & 0x7;
23597 target_gain.txlpf[core_no] =
23598 (tx_pwrctrl_tbl
23599 [base_idx[core_no]]
23600 >> 31) & 0x1;
23601 } else {
23602 target_gain.ipa[core_no] =
23603 (tx_pwrctrl_tbl
23604 [base_idx[core_no]]
23605 >> 16) & 0xf;
23606 target_gain.pad[core_no] =
23607 (tx_pwrctrl_tbl
23608 [base_idx[core_no]]
23609 >> 20) & 0xf;
23610 target_gain.pga[core_no] =
23611 (tx_pwrctrl_tbl
23612 [base_idx[core_no]]
23613 >> 24) & 0xf;
23614 target_gain.txgm[core_no] =
23615 (tx_pwrctrl_tbl
23616 [base_idx[core_no]]
23617 >> 28) & 0x7;
23618 }
23619 } else {
23620 target_gain.ipa[core_no] =
23621 (nphy_tpc_txgain[base_idx[core_no]] >>
23622 16) & 0x3;
23623 target_gain.pad[core_no] =
23624 (nphy_tpc_txgain[base_idx[core_no]] >>
23625 18) & 0x3;
23626 target_gain.pga[core_no] =
23627 (nphy_tpc_txgain[base_idx[core_no]] >>
23628 20) & 0x7;
23629 target_gain.txgm[core_no] =
23630 (nphy_tpc_txgain[base_idx[core_no]] >>
23631 23) & 0x7;
23632 }
23633 }
23634 }
23635
23636 return target_gain;
23637}
23638
23639static void
23640wlc_phy_iqcal_gainparams_nphy(struct brcms_phy *pi, u16 core_no,
23641 struct nphy_txgains target_gain,
23642 struct nphy_iqcal_params *params)
23643{
23644 u8 k;
23645 int idx;
23646 u16 gain_index;
23647 u8 band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
23648
23649 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
23650 if (NREV_GE(pi->pubpi.phy_rev, 7))
23651 params->txlpf = target_gain.txlpf[core_no];
23652
23653 params->txgm = target_gain.txgm[core_no];
23654 params->pga = target_gain.pga[core_no];
23655 params->pad = target_gain.pad[core_no];
23656 params->ipa = target_gain.ipa[core_no];
23657 if (NREV_GE(pi->pubpi.phy_rev, 7))
23658 params->cal_gain =
23659 ((params->txlpf << 15) | (params->txgm << 12) |
23660 (params->pga << 8) |
23661 (params->pad << 3) | (params->ipa));
23662 else
23663 params->cal_gain =
23664 ((params->txgm << 12) | (params->pga << 8) |
23665 (params->pad << 4) | (params->ipa));
23666
23667 params->ncorr[0] = 0x79;
23668 params->ncorr[1] = 0x79;
23669 params->ncorr[2] = 0x79;
23670 params->ncorr[3] = 0x79;
23671 params->ncorr[4] = 0x79;
23672 } else {
23673
23674 gain_index = ((target_gain.pad[core_no] << 0) |
23675 (target_gain.pga[core_no] << 4) |
23676 (target_gain.txgm[core_no] << 8));
23677
23678 idx = -1;
23679 for (k = 0; k < NPHY_IQCAL_NUMGAINS; k++) {
23680 if (tbl_iqcal_gainparams_nphy[band_idx][k][0] ==
23681 gain_index) {
23682 idx = k;
23683 break;
23684 }
23685 }
23686
23687 params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1];
23688 params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2];
23689 params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3];
23690 params->cal_gain = ((params->txgm << 7) | (params->pga << 4) |
23691 (params->pad << 2));
23692 params->ncorr[0] = tbl_iqcal_gainparams_nphy[band_idx][k][4];
23693 params->ncorr[1] = tbl_iqcal_gainparams_nphy[band_idx][k][5];
23694 params->ncorr[2] = tbl_iqcal_gainparams_nphy[band_idx][k][6];
23695 params->ncorr[3] = tbl_iqcal_gainparams_nphy[band_idx][k][7];
23696 }
23697}
23698
23699static void wlc_phy_txcal_radio_setup_nphy(struct brcms_phy *pi)
23700{
23701 u16 jtag_core, core;
23702
23703 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
23704
23705 for (core = 0; core <= 1; core++) {
23706
23707 pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
23708 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
23709 TX_SSI_MASTER);
23710
23711 pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
23712 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
23713 IQCAL_VCM_HG);
23714
23715 pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
23716 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
23717 IQCAL_IDAC);
23718
23719 pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
23720 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
23721 TSSI_VCM);
23722
23723 pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] = 0;
23724
23725 pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
23726 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
23727 TX_SSI_MUX);
23728
23729 if (pi->pubpi.radiorev != 5)
23730 pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
23731 READ_RADIO_REG3(pi, RADIO_2057, TX,
23732 core,
23733 TSSIA);
23734
23735 pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
23736 READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG);
23737
23738 pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
23739 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
23740 TSSI_MISC1);
23741
23742 if (CHSPEC_IS5G(pi->radio_chanspec)) {
23743 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
23744 TX_SSI_MASTER, 0x0a);
23745 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
23746 IQCAL_VCM_HG, 0x43);
23747 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
23748 IQCAL_IDAC, 0x55);
23749 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
23750 TSSI_VCM, 0x00);
23751 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
23752 TSSIG, 0x00);
23753 if (pi->use_int_tx_iqlo_cal_nphy) {
23754 WRITE_RADIO_REG3(pi, RADIO_2057, TX,
23755 core, TX_SSI_MUX, 0x4);
23756 if (!(pi->
23757 internal_tx_iqlo_cal_tapoff_intpa_nphy))
23758 WRITE_RADIO_REG3(pi, RADIO_2057,
23759 TX, core,
23760 TSSIA, 0x31);
23761 else
23762 WRITE_RADIO_REG3(pi, RADIO_2057,
23763 TX, core,
23764 TSSIA, 0x21);
23765 }
23766 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
23767 TSSI_MISC1, 0x00);
23768 } else {
23769 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
23770 TX_SSI_MASTER, 0x06);
23771 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
23772 IQCAL_VCM_HG, 0x43);
23773 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
23774 IQCAL_IDAC, 0x55);
23775 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
23776 TSSI_VCM, 0x00);
23777
23778 if (pi->pubpi.radiorev != 5)
23779 WRITE_RADIO_REG3(pi, RADIO_2057, TX,
23780 core, TSSIA, 0x00);
23781 if (pi->use_int_tx_iqlo_cal_nphy) {
23782 WRITE_RADIO_REG3(pi, RADIO_2057, TX,
23783 core, TX_SSI_MUX,
23784 0x06);
23785 if (!(pi->
23786 internal_tx_iqlo_cal_tapoff_intpa_nphy))
23787 WRITE_RADIO_REG3(pi, RADIO_2057,
23788 TX, core,
23789 TSSIG, 0x31);
23790 else
23791 WRITE_RADIO_REG3(pi, RADIO_2057,
23792 TX, core,
23793 TSSIG, 0x21);
23794 }
23795 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
23796 TSSI_MISC1, 0x00);
23797 }
23798 }
23799 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
23800
23801 for (core = 0; core <= 1; core++) {
23802 jtag_core =
23803 (core ==
23804 PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
23805
23806 pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
23807 read_radio_reg(pi,
23808 RADIO_2056_TX_TX_SSI_MASTER |
23809 jtag_core);
23810
23811 pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
23812 read_radio_reg(pi,
23813 RADIO_2056_TX_IQCAL_VCM_HG |
23814 jtag_core);
23815
23816 pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
23817 read_radio_reg(pi,
23818 RADIO_2056_TX_IQCAL_IDAC |
23819 jtag_core);
23820
23821 pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
23822 read_radio_reg(
23823 pi,
23824 RADIO_2056_TX_TSSI_VCM |
23825 jtag_core);
23826
23827 pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] =
23828 read_radio_reg(pi,
23829 RADIO_2056_TX_TX_AMP_DET |
23830 jtag_core);
23831
23832 pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
23833 read_radio_reg(pi,
23834 RADIO_2056_TX_TX_SSI_MUX |
23835 jtag_core);
23836
23837 pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
23838 read_radio_reg(pi,
23839 RADIO_2056_TX_TSSIA | jtag_core);
23840
23841 pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
23842 read_radio_reg(pi,
23843 RADIO_2056_TX_TSSIG | jtag_core);
23844
23845 pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
23846 read_radio_reg(pi,
23847 RADIO_2056_TX_TSSI_MISC1 |
23848 jtag_core);
23849
23850 pi->tx_rx_cal_radio_saveregs[(core * 11) + 9] =
23851 read_radio_reg(pi,
23852 RADIO_2056_TX_TSSI_MISC2 |
23853 jtag_core);
23854
23855 pi->tx_rx_cal_radio_saveregs[(core * 11) + 10] =
23856 read_radio_reg(pi,
23857 RADIO_2056_TX_TSSI_MISC3 |
23858 jtag_core);
23859
23860 if (CHSPEC_IS5G(pi->radio_chanspec)) {
23861 write_radio_reg(pi,
23862 RADIO_2056_TX_TX_SSI_MASTER |
23863 jtag_core, 0x0a);
23864 write_radio_reg(pi,
23865 RADIO_2056_TX_IQCAL_VCM_HG |
23866 jtag_core, 0x40);
23867 write_radio_reg(pi,
23868 RADIO_2056_TX_IQCAL_IDAC |
23869 jtag_core, 0x55);
23870 write_radio_reg(pi,
23871 RADIO_2056_TX_TSSI_VCM |
23872 jtag_core, 0x00);
23873 write_radio_reg(pi,
23874 RADIO_2056_TX_TX_AMP_DET |
23875 jtag_core, 0x00);
23876
23877 if (PHY_IPA(pi)) {
23878 write_radio_reg(
23879 pi,
23880 RADIO_2056_TX_TX_SSI_MUX
23881 | jtag_core, 0x4);
23882 write_radio_reg(pi,
23883 RADIO_2056_TX_TSSIA |
23884 jtag_core, 0x1);
23885 } else {
23886 write_radio_reg(
23887 pi,
23888 RADIO_2056_TX_TX_SSI_MUX
23889 | jtag_core, 0x00);
23890 write_radio_reg(pi,
23891 RADIO_2056_TX_TSSIA |
23892 jtag_core, 0x2f);
23893 }
23894 write_radio_reg(pi,
23895 RADIO_2056_TX_TSSIG | jtag_core,
23896 0x00);
23897 write_radio_reg(pi,
23898 RADIO_2056_TX_TSSI_MISC1 |
23899 jtag_core, 0x00);
23900
23901 write_radio_reg(pi,
23902 RADIO_2056_TX_TSSI_MISC2 |
23903 jtag_core, 0x00);
23904 write_radio_reg(pi,
23905 RADIO_2056_TX_TSSI_MISC3 |
23906 jtag_core, 0x00);
23907 } else {
23908 write_radio_reg(pi,
23909 RADIO_2056_TX_TX_SSI_MASTER |
23910 jtag_core, 0x06);
23911 write_radio_reg(pi,
23912 RADIO_2056_TX_IQCAL_VCM_HG |
23913 jtag_core, 0x40);
23914 write_radio_reg(pi,
23915 RADIO_2056_TX_IQCAL_IDAC |
23916 jtag_core, 0x55);
23917 write_radio_reg(pi,
23918 RADIO_2056_TX_TSSI_VCM |
23919 jtag_core, 0x00);
23920 write_radio_reg(pi,
23921 RADIO_2056_TX_TX_AMP_DET |
23922 jtag_core, 0x00);
23923 write_radio_reg(pi,
23924 RADIO_2056_TX_TSSIA | jtag_core,
23925 0x00);
23926
23927 if (PHY_IPA(pi)) {
23928
23929 write_radio_reg(
23930 pi,
23931 RADIO_2056_TX_TX_SSI_MUX
23932 | jtag_core, 0x06);
23933 if (NREV_LT(pi->pubpi.phy_rev, 5))
23934 write_radio_reg(
23935 pi,
23936 RADIO_2056_TX_TSSIG
23937 | jtag_core,
23938 0x11);
23939 else
23940 write_radio_reg(
23941 pi,
23942 RADIO_2056_TX_TSSIG
23943 | jtag_core,
23944 0x1);
23945 } else {
23946 write_radio_reg(
23947 pi,
23948 RADIO_2056_TX_TX_SSI_MUX
23949 | jtag_core, 0x00);
23950 write_radio_reg(pi,
23951 RADIO_2056_TX_TSSIG |
23952 jtag_core, 0x20);
23953 }
23954
23955 write_radio_reg(pi,
23956 RADIO_2056_TX_TSSI_MISC1 |
23957 jtag_core, 0x00);
23958 write_radio_reg(pi,
23959 RADIO_2056_TX_TSSI_MISC2 |
23960 jtag_core, 0x00);
23961 write_radio_reg(pi,
23962 RADIO_2056_TX_TSSI_MISC3 |
23963 jtag_core, 0x00);
23964 }
23965 }
23966 } else {
23967
23968 pi->tx_rx_cal_radio_saveregs[0] =
23969 read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
23970 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x29);
23971 pi->tx_rx_cal_radio_saveregs[1] =
23972 read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
23973 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x54);
23974
23975 pi->tx_rx_cal_radio_saveregs[2] =
23976 read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
23977 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x29);
23978 pi->tx_rx_cal_radio_saveregs[3] =
23979 read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
23980 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x54);
23981
23982 pi->tx_rx_cal_radio_saveregs[4] =
23983 read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
23984 pi->tx_rx_cal_radio_saveregs[5] =
23985 read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
23986
23987 if ((read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand) ==
23988 0) {
23989
23990 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
23991 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
23992 } else {
23993
23994 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x20);
23995 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x20);
23996 }
23997
23998 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
23999
24000 or_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0x20);
24001 or_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0x20);
24002 } else {
24003
24004 and_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0xdf);
24005 and_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0xdf);
24006 }
24007 }
24008}
24009
24010static void wlc_phy_txcal_radio_cleanup_nphy(struct brcms_phy *pi)
24011{
24012 u16 jtag_core, core;
24013
24014 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
24015 for (core = 0; core <= 1; core++) {
24016
24017 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
24018 TX_SSI_MASTER,
24019 pi->
24020 tx_rx_cal_radio_saveregs[(core * 11) +
24021 0]);
24022
24023 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
24024 pi->
24025 tx_rx_cal_radio_saveregs[(core * 11) +
24026 1]);
24027
24028 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
24029 pi->
24030 tx_rx_cal_radio_saveregs[(core * 11) +
24031 2]);
24032
24033 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
24034 pi->
24035 tx_rx_cal_radio_saveregs[(core * 11) +
24036 3]);
24037
24038 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TX_SSI_MUX,
24039 pi->
24040 tx_rx_cal_radio_saveregs[(core * 11) +
24041 5]);
24042
24043 if (pi->pubpi.radiorev != 5)
24044 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
24045 TSSIA,
24046 pi->tx_rx_cal_radio_saveregs
24047 [(core * 11) + 6]);
24048
24049 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG,
24050 pi->
24051 tx_rx_cal_radio_saveregs[(core * 11) +
24052 7]);
24053
24054 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
24055 pi->
24056 tx_rx_cal_radio_saveregs[(core * 11) +
24057 8]);
24058 }
24059 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
24060 for (core = 0; core <= 1; core++) {
24061 jtag_core = (core == PHY_CORE_0) ?
24062 RADIO_2056_TX0 : RADIO_2056_TX1;
24063
24064 write_radio_reg(pi,
24065 RADIO_2056_TX_TX_SSI_MASTER | jtag_core,
24066 pi->
24067 tx_rx_cal_radio_saveregs[(core * 11) +
24068 0]);
24069
24070 write_radio_reg(pi,
24071 RADIO_2056_TX_IQCAL_VCM_HG | jtag_core,
24072 pi->
24073 tx_rx_cal_radio_saveregs[(core * 11) +
24074 1]);
24075
24076 write_radio_reg(pi,
24077 RADIO_2056_TX_IQCAL_IDAC | jtag_core,
24078 pi->
24079 tx_rx_cal_radio_saveregs[(core * 11) +
24080 2]);
24081
24082 write_radio_reg(pi, RADIO_2056_TX_TSSI_VCM | jtag_core,
24083 pi->
24084 tx_rx_cal_radio_saveregs[(core * 11) +
24085 3]);
24086
24087 write_radio_reg(pi,
24088 RADIO_2056_TX_TX_AMP_DET | jtag_core,
24089 pi->
24090 tx_rx_cal_radio_saveregs[(core * 11) +
24091 4]);
24092
24093 write_radio_reg(pi,
24094 RADIO_2056_TX_TX_SSI_MUX | jtag_core,
24095 pi->
24096 tx_rx_cal_radio_saveregs[(core * 11) +
24097 5]);
24098
24099 write_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core,
24100 pi->
24101 tx_rx_cal_radio_saveregs[(core * 11) +
24102 6]);
24103
24104 write_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core,
24105 pi->
24106 tx_rx_cal_radio_saveregs[(core * 11) +
24107 7]);
24108
24109 write_radio_reg(pi,
24110 RADIO_2056_TX_TSSI_MISC1 | jtag_core,
24111 pi->
24112 tx_rx_cal_radio_saveregs[(core * 11) +
24113 8]);
24114
24115 write_radio_reg(pi,
24116 RADIO_2056_TX_TSSI_MISC2 | jtag_core,
24117 pi->
24118 tx_rx_cal_radio_saveregs[(core * 11) +
24119 9]);
24120
24121 write_radio_reg(pi,
24122 RADIO_2056_TX_TSSI_MISC3 | jtag_core,
24123 pi->
24124 tx_rx_cal_radio_saveregs[(core * 11) +
24125 10]);
24126 }
24127 } else {
24128
24129 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
24130 pi->tx_rx_cal_radio_saveregs[0]);
24131 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
24132 pi->tx_rx_cal_radio_saveregs[1]);
24133 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
24134 pi->tx_rx_cal_radio_saveregs[2]);
24135 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
24136 pi->tx_rx_cal_radio_saveregs[3]);
24137 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
24138 pi->tx_rx_cal_radio_saveregs[4]);
24139 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
24140 pi->tx_rx_cal_radio_saveregs[5]);
24141 }
24142}
24143
24144static void wlc_phy_txcal_physetup_nphy(struct brcms_phy *pi)
24145{
24146 u16 val, mask;
24147
24148 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
24149 pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
24150 pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
24151
24152 mask = ((0x3 << 8) | (0x3 << 10));
24153 val = (0x2 << 8);
24154 val |= (0x2 << 10);
24155 mod_phy_reg(pi, 0xa6, mask, val);
24156 mod_phy_reg(pi, 0xa7, mask, val);
24157
24158 val = read_phy_reg(pi, 0x8f);
24159 pi->tx_rx_cal_phy_saveregs[2] = val;
24160 val |= ((0x1 << 9) | (0x1 << 10));
24161 write_phy_reg(pi, 0x8f, val);
24162
24163 val = read_phy_reg(pi, 0xa5);
24164 pi->tx_rx_cal_phy_saveregs[3] = val;
24165 val |= ((0x1 << 9) | (0x1 << 10));
24166 write_phy_reg(pi, 0xa5, val);
24167
24168 pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x01);
24169 mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
24170
24171 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
24172 &val);
24173 pi->tx_rx_cal_phy_saveregs[5] = val;
24174 val = 0;
24175 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
24176 &val);
24177
24178 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
24179 &val);
24180 pi->tx_rx_cal_phy_saveregs[6] = val;
24181 val = 0;
24182 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
24183 &val);
24184
24185 pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0x91);
24186 pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0x92);
24187
24188 if (!(pi->use_int_tx_iqlo_cal_nphy))
24189 wlc_phy_rfctrlintc_override_nphy(
24190 pi,
24191 NPHY_RfctrlIntc_override_PA,
24192 1,
24193 RADIO_MIMO_CORESEL_CORE1
24194 |
24195 RADIO_MIMO_CORESEL_CORE2);
24196 else
24197 wlc_phy_rfctrlintc_override_nphy(
24198 pi,
24199 NPHY_RfctrlIntc_override_PA,
24200 0,
24201 RADIO_MIMO_CORESEL_CORE1
24202 |
24203 RADIO_MIMO_CORESEL_CORE2);
24204
24205 wlc_phy_rfctrlintc_override_nphy(pi,
24206 NPHY_RfctrlIntc_override_TRSW,
24207 0x2, RADIO_MIMO_CORESEL_CORE1);
24208 wlc_phy_rfctrlintc_override_nphy(pi,
24209 NPHY_RfctrlIntc_override_TRSW,
24210 0x8, RADIO_MIMO_CORESEL_CORE2);
24211
24212 pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
24213 pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
24214 mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
24215 0x29b, (0x1 << 0), (0) << 0);
24216
24217 mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
24218 0x29b, (0x1 << 0), (0) << 0);
24219
24220 if (NREV_IS(pi->pubpi.phy_rev, 7)
24221 || NREV_GE(pi->pubpi.phy_rev, 8))
24222 wlc_phy_rfctrl_override_nphy_rev7(
24223 pi, (0x1 << 7),
24224 wlc_phy_read_lpf_bw_ctl_nphy
24225 (pi,
24226 0), 0, 0,
24227 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24228
24229 if (pi->use_int_tx_iqlo_cal_nphy
24230 && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
24231
24232 if (NREV_IS(pi->pubpi.phy_rev, 7)) {
24233
24234 mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
24235 1 << 4);
24236
24237 if (CHSPEC_IS2G(pi->radio_chanspec)) {
24238 mod_radio_reg(
24239 pi,
24240 RADIO_2057_PAD2G_TUNE_PUS_CORE0,
24241 1, 0);
24242 mod_radio_reg(
24243 pi,
24244 RADIO_2057_PAD2G_TUNE_PUS_CORE1,
24245 1, 0);
24246 } else {
24247 mod_radio_reg(
24248 pi,
24249 RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
24250 1, 0);
24251 mod_radio_reg(
24252 pi,
24253 RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
24254 1, 0);
24255 }
24256 } else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
24257 wlc_phy_rfctrl_override_nphy_rev7(
24258 pi,
24259 (0x1 << 3), 0,
24260 0x3, 0,
24261 NPHY_REV7_RFCTRLOVERRIDE_ID0);
24262 }
24263 }
24264 } else {
24265 pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
24266 pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
24267
24268 mask = ((0x3 << 12) | (0x3 << 14));
24269 val = (0x2 << 12);
24270 val |= (0x2 << 14);
24271 mod_phy_reg(pi, 0xa6, mask, val);
24272 mod_phy_reg(pi, 0xa7, mask, val);
24273
24274 val = read_phy_reg(pi, 0xa5);
24275 pi->tx_rx_cal_phy_saveregs[2] = val;
24276 val |= ((0x1 << 12) | (0x1 << 13));
24277 write_phy_reg(pi, 0xa5, val);
24278
24279 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
24280 &val);
24281 pi->tx_rx_cal_phy_saveregs[3] = val;
24282 val |= 0x2000;
24283 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
24284 &val);
24285
24286 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
24287 &val);
24288 pi->tx_rx_cal_phy_saveregs[4] = val;
24289 val |= 0x2000;
24290 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
24291 &val);
24292
24293 pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x91);
24294 pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x92);
24295 val = CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
24296 write_phy_reg(pi, 0x91, val);
24297 write_phy_reg(pi, 0x92, val);
24298 }
24299}
24300
24301static void wlc_phy_txcal_phycleanup_nphy(struct brcms_phy *pi)
24302{
24303 u16 mask;
24304
24305 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
24306 write_phy_reg(pi, 0xa6, pi->tx_rx_cal_phy_saveregs[0]);
24307 write_phy_reg(pi, 0xa7, pi->tx_rx_cal_phy_saveregs[1]);
24308 write_phy_reg(pi, 0x8f, pi->tx_rx_cal_phy_saveregs[2]);
24309 write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[3]);
24310 write_phy_reg(pi, 0x01, pi->tx_rx_cal_phy_saveregs[4]);
24311
24312 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
24313 &pi->tx_rx_cal_phy_saveregs[5]);
24314 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
24315 &pi->tx_rx_cal_phy_saveregs[6]);
24316
24317 write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[7]);
24318 write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[8]);
24319
24320 write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
24321 write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
24322
24323 if (NREV_IS(pi->pubpi.phy_rev, 7)
24324 || NREV_GE(pi->pubpi.phy_rev, 8))
24325 wlc_phy_rfctrl_override_nphy_rev7(
24326 pi, (0x1 << 7), 0, 0,
24327 1,
24328 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24329
24330 wlc_phy_resetcca_nphy(pi);
24331
24332 if (pi->use_int_tx_iqlo_cal_nphy
24333 && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
24334
24335 if (NREV_IS(pi->pubpi.phy_rev, 7)) {
24336 if (CHSPEC_IS2G(pi->radio_chanspec)) {
24337 mod_radio_reg(
24338 pi,
24339 RADIO_2057_PAD2G_TUNE_PUS_CORE0,
24340 1, 1);
24341 mod_radio_reg(
24342 pi,
24343 RADIO_2057_PAD2G_TUNE_PUS_CORE1,
24344 1, 1);
24345 } else {
24346 mod_radio_reg(
24347 pi,
24348 RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
24349 1, 1);
24350 mod_radio_reg(
24351 pi,
24352 RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
24353 1, 1);
24354 }
24355
24356 mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
24357 0);
24358 } else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
24359 wlc_phy_rfctrl_override_nphy_rev7(
24360 pi,
24361 (0x1 << 3), 0,
24362 0x3, 1,
24363 NPHY_REV7_RFCTRLOVERRIDE_ID0);
24364 }
24365 }
24366 } else {
24367 mask = ((0x3 << 12) | (0x3 << 14));
24368 mod_phy_reg(pi, 0xa6, mask, pi->tx_rx_cal_phy_saveregs[0]);
24369 mod_phy_reg(pi, 0xa7, mask, pi->tx_rx_cal_phy_saveregs[1]);
24370 write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[2]);
24371
24372 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
24373 &pi->tx_rx_cal_phy_saveregs[3]);
24374
24375 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
24376 &pi->tx_rx_cal_phy_saveregs[4]);
24377
24378 write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[5]);
24379 write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[6]);
24380 }
24381}
24382
24383void
24384wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, u8 num_samps)
24385{
24386 u16 tssi_reg;
24387 s32 temp, pwrindex[2];
24388 s32 idle_tssi[2];
24389 s32 rssi_buf[4];
24390 s32 tssival[2];
24391 u8 tssi_type;
24392
24393 tssi_reg = read_phy_reg(pi, 0x1e9);
24394
24395 temp = (s32) (tssi_reg & 0x3f);
24396 idle_tssi[0] = (temp <= 31) ? temp : (temp - 64);
24397
24398 temp = (s32) ((tssi_reg >> 8) & 0x3f);
24399 idle_tssi[1] = (temp <= 31) ? temp : (temp - 64);
24400
24401 tssi_type =
24402 CHSPEC_IS5G(pi->radio_chanspec) ?
24403 (u8)NPHY_RSSI_SEL_TSSI_5G : (u8)NPHY_RSSI_SEL_TSSI_2G;
24404
24405 wlc_phy_poll_rssi_nphy(pi, tssi_type, rssi_buf, num_samps);
24406
24407 tssival[0] = rssi_buf[0] / ((s32) num_samps);
24408 tssival[1] = rssi_buf[2] / ((s32) num_samps);
24409
24410 pwrindex[0] = idle_tssi[0] - tssival[0] + 64;
24411 pwrindex[1] = idle_tssi[1] - tssival[1] + 64;
24412
24413 if (pwrindex[0] < 0)
24414 pwrindex[0] = 0;
24415 else if (pwrindex[0] > 63)
24416 pwrindex[0] = 63;
24417
24418 if (pwrindex[1] < 0)
24419 pwrindex[1] = 0;
24420 else if (pwrindex[1] > 63)
24421 pwrindex[1] = 63;
24422
24423 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 1,
24424 (u32) pwrindex[0], 32, &qdBm_pwrbuf[0]);
24425 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 1,
24426 (u32) pwrindex[1], 32, &qdBm_pwrbuf[1]);
24427}
24428
24429static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core)
24430{
24431 int index;
24432 u32 bbmult_scale;
24433 u16 bbmult;
24434 u16 tblentry;
24435
24436 struct nphy_txiqcal_ladder ladder_lo[] = {
24437 {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
24438 {25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5},
24439 {25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7}
24440 };
24441
24442 struct nphy_txiqcal_ladder ladder_iq[] = {
24443 {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
24444 {25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1},
24445 {100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7}
24446 };
24447
24448 bbmult = (core == PHY_CORE_0) ?
24449 ((pi->nphy_txcal_bbmult >> 8) & 0xff) :
24450 (pi->nphy_txcal_bbmult & 0xff);
24451
24452 for (index = 0; index < 18; index++) {
24453 bbmult_scale = ladder_lo[index].percent * bbmult;
24454 bbmult_scale /= 100;
24455
24456 tblentry =
24457 ((bbmult_scale & 0xff) << 8) | ladder_lo[index].g_env;
24458 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index, 16,
24459 &tblentry);
24460
24461 bbmult_scale = ladder_iq[index].percent * bbmult;
24462 bbmult_scale /= 100;
24463
24464 tblentry =
24465 ((bbmult_scale & 0xff) << 8) | ladder_iq[index].g_env;
24466 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index + 32,
24467 16, &tblentry);
24468 }
24469}
24470
24471static u8 wlc_phy_txpwr_idx_cur_get_nphy(struct brcms_phy *pi, u8 core)
24472{
24473 u16 tmp;
24474 tmp = read_phy_reg(pi, ((core == PHY_CORE_0) ? 0x1ed : 0x1ee));
24475
24476 tmp = (tmp & (0x7f << 8)) >> 8;
24477 return (u8) tmp;
24478}
24479
24480static void
24481wlc_phy_txpwr_idx_cur_set_nphy(struct brcms_phy *pi, u8 idx0, u8 idx1)
24482{
24483 mod_phy_reg(pi, 0x1e7, (0x7f << 0), idx0);
24484
24485 if (NREV_GT(pi->pubpi.phy_rev, 1))
24486 mod_phy_reg(pi, 0x222, (0xff << 0), idx1);
24487}
24488
24489static u16 wlc_phy_ipa_get_bbmult_nphy(struct brcms_phy *pi)
24490{
24491 u16 m0m1;
24492
24493 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
24494
24495 return m0m1;
24496}
24497
24498static void wlc_phy_ipa_set_bbmult_nphy(struct brcms_phy *pi, u8 m0, u8 m1)
24499{
24500 u16 m0m1 = (u16) ((m0 << 8) | m1);
24501
24502 wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m0m1);
24503 wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &m0m1);
24504}
24505
24506static void
24507wlc_phy_papd_cal_setup_nphy(struct brcms_phy *pi,
24508 struct nphy_papd_restore_state *state, u8 core)
24509{
24510 s32 tone_freq;
24511 u8 off_core;
24512 u16 mixgain = 0;
24513
24514 off_core = core ^ 0x1;
24515 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
24516
24517 if (NREV_IS(pi->pubpi.phy_rev, 7)
24518 || NREV_GE(pi->pubpi.phy_rev, 8))
24519 wlc_phy_rfctrl_override_nphy_rev7(
24520 pi, (0x1 << 7),
24521 wlc_phy_read_lpf_bw_ctl_nphy
24522 (pi,
24523 0), 0, 0,
24524 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24525
24526 if (CHSPEC_IS2G(pi->radio_chanspec)) {
24527 if (pi->pubpi.radiorev == 5)
24528 mixgain = (core == 0) ? 0x20 : 0x00;
24529 else if ((pi->pubpi.radiorev == 7)
24530 || (pi->pubpi.radiorev == 8))
24531 mixgain = 0x00;
24532 else if ((pi->pubpi.radiorev <= 4)
24533 || (pi->pubpi.radiorev == 6))
24534 mixgain = 0x00;
24535 } else {
24536 if ((pi->pubpi.radiorev == 4) ||
24537 (pi->pubpi.radiorev == 6))
24538 mixgain = 0x50;
24539 else if ((pi->pubpi.radiorev == 3)
24540 || (pi->pubpi.radiorev == 7)
24541 || (pi->pubpi.radiorev == 8))
24542 mixgain = 0x0;
24543 }
24544
24545 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11),
24546 mixgain, (1 << core), 0,
24547 NPHY_REV7_RFCTRLOVERRIDE_ID0);
24548
24549 wlc_phy_rfctrl_override_1tomany_nphy(
24550 pi,
24551 NPHY_REV7_RfctrlOverride_cmd_tx_pu,
24552 1, (1 << core), 0);
24553 wlc_phy_rfctrl_override_1tomany_nphy(
24554 pi,
24555 NPHY_REV7_RfctrlOverride_cmd_tx_pu,
24556 0, (1 << off_core), 0);
24557
24558 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
24559 0, 0x3, 0,
24560 NPHY_REV7_RFCTRLOVERRIDE_ID0);
24561 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1,
24562 (1 << core), 0,
24563 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24564 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0,
24565 (1 << core), 0,
24566 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24567 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1,
24568 (1 << core), 0,
24569 NPHY_REV7_RFCTRLOVERRIDE_ID2);
24570 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0,
24571 (1 << core), 0,
24572 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24573 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1,
24574 (1 << core), 0,
24575 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24576 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0,
24577 (1 << core), 0,
24578 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24579 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1,
24580 (1 << core), 0,
24581 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24582
24583 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
24584 0, (1 << core), 0,
24585 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24586 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0,
24587 (1 << core), 0,
24588 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24589
24590 state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
24591 0xa6 : 0xa7);
24592 state->afeoverride[core] =
24593 read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
24594 state->afectrl[off_core] =
24595 read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa7 : 0xa6);
24596 state->afeoverride[off_core] =
24597 read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa5 : 0x8f);
24598
24599 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
24600 (0x1 << 2), 0);
24601 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
24602 0xa5), (0x1 << 2), (0x1 << 2));
24603
24604 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa7 : 0xa6),
24605 (0x1 << 2), (0x1 << 2));
24606 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa5 :
24607 0x8f), (0x1 << 2), (0x1 << 2));
24608
24609 if (CHSPEC_IS2G(pi->radio_chanspec)) {
24610 state->pwrup[core] =
24611 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
24612 TXRXCOUPLE_2G_PWRUP);
24613 state->atten[core] =
24614 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
24615 TXRXCOUPLE_2G_ATTEN);
24616 state->pwrup[off_core] =
24617 READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
24618 TXRXCOUPLE_2G_PWRUP);
24619 state->atten[off_core] =
24620 READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
24621 TXRXCOUPLE_2G_ATTEN);
24622
24623 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
24624 TXRXCOUPLE_2G_PWRUP, 0xc);
24625
24626 if ((pi->pubpi.radiorev == 3) ||
24627 (pi->pubpi.radiorev == 4) ||
24628 (pi->pubpi.radiorev == 6))
24629 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
24630 TXRXCOUPLE_2G_ATTEN, 0xf0);
24631 else if (pi->pubpi.radiorev == 5)
24632 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
24633 TXRXCOUPLE_2G_ATTEN,
24634 (core == 0) ? 0xf7 : 0xf2);
24635 else if ((pi->pubpi.radiorev == 7)
24636 || (pi->pubpi.radiorev == 8))
24637 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
24638 TXRXCOUPLE_2G_ATTEN, 0xf0);
24639
24640 WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
24641 TXRXCOUPLE_2G_PWRUP, 0x0);
24642 WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
24643 TXRXCOUPLE_2G_ATTEN, 0xff);
24644 } else {
24645 state->pwrup[core] =
24646 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
24647 TXRXCOUPLE_5G_PWRUP);
24648 state->atten[core] =
24649 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
24650 TXRXCOUPLE_5G_ATTEN);
24651 state->pwrup[off_core] =
24652 READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
24653 TXRXCOUPLE_5G_PWRUP);
24654 state->atten[off_core] =
24655 READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
24656 TXRXCOUPLE_5G_ATTEN);
24657
24658 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
24659 TXRXCOUPLE_5G_PWRUP, 0xc);
24660
24661 if ((pi->pubpi.radiorev == 7)
24662 || (pi->pubpi.radiorev == 8))
24663 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
24664 TXRXCOUPLE_5G_ATTEN, 0xf4);
24665
24666 else
24667 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
24668 TXRXCOUPLE_5G_ATTEN, 0xf0);
24669
24670 WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
24671 TXRXCOUPLE_5G_PWRUP, 0x0);
24672 WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
24673 TXRXCOUPLE_5G_ATTEN, 0xff);
24674 }
24675
24676 tone_freq = 4000;
24677
24678 wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false);
24679
24680 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
24681 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
24682
24683 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
24684 0x2a4, (0x1 << 13), (1) << 13);
24685
24686 mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
24687 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_OFF) << 0);
24688
24689 mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x2a3 :
24690 0x2a4, (0x1 << 13), (0) << 13);
24691
24692 } else {
24693
24694 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 0);
24695
24696 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0, 0);
24697
24698 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 0);
24699
24700 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 1, 0x3, 0);
24701 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0x3, 0);
24702
24703 state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
24704 0xa6 : 0xa7);
24705 state->afeoverride[core] =
24706 read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
24707
24708 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
24709 (0x1 << 0) | (0x1 << 1) | (0x1 << 2), 0);
24710 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
24711 0xa5),
24712 (0x1 << 0) |
24713 (0x1 << 1) |
24714 (0x1 << 2), (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
24715
24716 state->vga_master[core] =
24717 READ_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER);
24718 WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, 0x2b);
24719 if (CHSPEC_IS2G(pi->radio_chanspec)) {
24720 state->fbmix[core] =
24721 READ_RADIO_REG2(pi, RADIO_2056, RX, core,
24722 TXFBMIX_G);
24723 state->intpa_master[core] =
24724 READ_RADIO_REG2(pi, RADIO_2056, TX, core,
24725 INTPAG_MASTER);
24726
24727 WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_G,
24728 0x03);
24729 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
24730 INTPAG_MASTER, 0x04);
24731 } else {
24732 state->fbmix[core] =
24733 READ_RADIO_REG2(pi, RADIO_2056, RX, core,
24734 TXFBMIX_A);
24735 state->intpa_master[core] =
24736 READ_RADIO_REG2(pi, RADIO_2056, TX, core,
24737 INTPAA_MASTER);
24738
24739 WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_A,
24740 0x03);
24741 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
24742 INTPAA_MASTER, 0x04);
24743
24744 }
24745
24746 tone_freq = 4000;
24747
24748 wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false);
24749
24750 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
24751 0x29b, (0x1 << 0), (1) << 0);
24752
24753 mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
24754 0x29b, (0x1 << 0), (0) << 0);
24755
24756 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
24757 }
24758}
24759
24760static void
24761wlc_phy_papd_cal_cleanup_nphy(struct brcms_phy *pi,
24762 struct nphy_papd_restore_state *state)
24763{
24764 u8 core;
24765
24766 wlc_phy_stopplayback_nphy(pi);
24767
24768 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
24769
24770 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
24771
24772 if (CHSPEC_IS2G(pi->radio_chanspec)) {
24773 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
24774 TXRXCOUPLE_2G_PWRUP, 0);
24775 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
24776 TXRXCOUPLE_2G_ATTEN,
24777 state->atten[core]);
24778 } else {
24779 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
24780 TXRXCOUPLE_5G_PWRUP, 0);
24781 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
24782 TXRXCOUPLE_5G_ATTEN,
24783 state->atten[core]);
24784 }
24785 }
24786
24787 if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6))
24788 wlc_phy_rfctrl_override_nphy_rev7(
24789 pi, (0x1 << 2),
24790 1, 0x3, 0,
24791 NPHY_REV7_RFCTRLOVERRIDE_ID0);
24792 else
24793 wlc_phy_rfctrl_override_nphy_rev7(
24794 pi, (0x1 << 2),
24795 0, 0x3, 1,
24796 NPHY_REV7_RFCTRLOVERRIDE_ID0);
24797
24798 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
24799 0, 0x3, 1,
24800 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24801 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
24802 NPHY_REV7_RFCTRLOVERRIDE_ID2);
24803 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 0, 0x3, 1,
24804 NPHY_REV7_RFCTRLOVERRIDE_ID2);
24805 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, 0x3, 1,
24806 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24807 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 0, 0x3, 1,
24808 NPHY_REV7_RFCTRLOVERRIDE_ID0);
24809 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0x3, 1,
24810 NPHY_REV7_RFCTRLOVERRIDE_ID0);
24811 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), 0, 0x3, 1,
24812 NPHY_REV7_RFCTRLOVERRIDE_ID0);
24813 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, 0x3, 1,
24814 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24815 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
24816 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24817 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0x3, 1,
24818 NPHY_REV7_RFCTRLOVERRIDE_ID2);
24819 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, 0x3, 1,
24820 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24821 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, 0x3, 1,
24822 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24823 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, 0x3, 1,
24824 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24825 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, 0x3, 1,
24826 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24827 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0x3, 1,
24828 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24829 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, 0x3, 1,
24830 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24831
24832 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
24833
24834 write_phy_reg(pi, (core == PHY_CORE_0) ?
24835 0xa6 : 0xa7, state->afectrl[core]);
24836 write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
24837 0xa5, state->afeoverride[core]);
24838 }
24839
24840 wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
24841 (state->mm & 0xff));
24842
24843 if (NREV_IS(pi->pubpi.phy_rev, 7)
24844 || NREV_GE(pi->pubpi.phy_rev, 8))
24845 wlc_phy_rfctrl_override_nphy_rev7(
24846 pi, (0x1 << 7), 0, 0,
24847 1,
24848 NPHY_REV7_RFCTRLOVERRIDE_ID1);
24849 } else {
24850 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
24851 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 0x3, 1);
24852 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 1);
24853
24854 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 0, 0x3, 1);
24855 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 0, 0x3, 1);
24856
24857 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
24858
24859 WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER,
24860 state->vga_master[core]);
24861 if (CHSPEC_IS2G(pi->radio_chanspec)) {
24862 WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
24863 TXFBMIX_G, state->fbmix[core]);
24864 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
24865 INTPAG_MASTER,
24866 state->intpa_master[core]);
24867 } else {
24868 WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
24869 TXFBMIX_A, state->fbmix[core]);
24870 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
24871 INTPAA_MASTER,
24872 state->intpa_master[core]);
24873 }
24874
24875 write_phy_reg(pi, (core == PHY_CORE_0) ?
24876 0xa6 : 0xa7, state->afectrl[core]);
24877 write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
24878 0xa5, state->afeoverride[core]);
24879 }
24880
24881 wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
24882 (state->mm & 0xff));
24883
24884 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 1);
24885 }
24886}
24887
24888static void
24889wlc_phy_a1_nphy(struct brcms_phy *pi, u8 core, u32 winsz, u32 start,
24890 u32 end)
24891{
24892 u32 *buf, *src, *dst, sz;
24893
24894 sz = end - start + 1;
24895
24896 buf = kmalloc(2 * sizeof(u32) * NPHY_PAPD_EPS_TBL_SIZE, GFP_ATOMIC);
24897 if (NULL == buf)
24898 return;
24899
24900 src = buf;
24901 dst = buf + NPHY_PAPD_EPS_TBL_SIZE;
24902
24903 wlc_phy_table_read_nphy(pi,
24904 (core ==
24905 PHY_CORE_0 ? NPHY_TBL_ID_EPSILONTBL0 :
24906 NPHY_TBL_ID_EPSILONTBL1),
24907 NPHY_PAPD_EPS_TBL_SIZE, 0, 32, src);
24908
24909 do {
24910 u32 phy_a1, phy_a2;
24911 s32 phy_a3, phy_a4, phy_a5, phy_a6, phy_a7;
24912
24913 phy_a1 = end - min(end, (winsz >> 1));
24914 phy_a2 = min_t(u32, NPHY_PAPD_EPS_TBL_SIZE - 1,
24915 end + (winsz >> 1));
24916 phy_a3 = phy_a2 - phy_a1 + 1;
24917 phy_a6 = 0;
24918 phy_a7 = 0;
24919
24920 do {
24921 wlc_phy_papd_decode_epsilon(src[phy_a2], &phy_a4,
24922 &phy_a5);
24923 phy_a6 += phy_a4;
24924 phy_a7 += phy_a5;
24925 } while (phy_a2-- != phy_a1);
24926
24927 phy_a6 /= phy_a3;
24928 phy_a7 /= phy_a3;
24929 dst[end] = ((u32) phy_a7 << 13) | ((u32) phy_a6 & 0x1fff);
24930 } while (end-- != start);
24931
24932 wlc_phy_table_write_nphy(pi,
24933 (core ==
24934 PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 :
24935 NPHY_TBL_ID_EPSILONTBL1, sz, start, 32, dst);
24936
24937 kfree(buf);
24938}
24939
24940static void
24941wlc_phy_a2_nphy(struct brcms_phy *pi, struct nphy_ipa_txcalgains *txgains,
24942 enum phy_cal_mode cal_mode, u8 core)
24943{
24944 u16 phy_a1, phy_a2, phy_a3;
24945 u16 phy_a4, phy_a5;
24946 bool phy_a6;
24947 u8 phy_a7, m[2];
24948 u32 phy_a8 = 0;
24949 struct nphy_txgains phy_a9;
24950
24951 if (NREV_LT(pi->pubpi.phy_rev, 3))
24952 return;
24953
24954 phy_a7 = (core == PHY_CORE_0) ? 1 : 0;
24955
24956 phy_a6 = ((cal_mode == CAL_GCTRL)
24957 || (cal_mode == CAL_SOFT)) ? true : false;
24958
24959 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
24960
24961 phy_a9 = wlc_phy_get_tx_gain_nphy(pi);
24962
24963 if (CHSPEC_IS2G(pi->radio_chanspec))
24964 phy_a5 = ((phy_a9.txlpf[core] << 15) |
24965 (phy_a9.txgm[core] << 12) |
24966 (phy_a9.pga[core] << 8) |
24967 (txgains->gains.pad[core] << 3) |
24968 (phy_a9.ipa[core]));
24969 else
24970 phy_a5 = ((phy_a9.txlpf[core] << 15) |
24971 (phy_a9.txgm[core] << 12) |
24972 (txgains->gains.pga[core] << 8) |
24973 (phy_a9.pad[core] << 3) | (phy_a9.ipa[core]));
24974
24975 wlc_phy_rfctrl_override_1tomany_nphy(
24976 pi,
24977 NPHY_REV7_RfctrlOverride_cmd_txgain,
24978 phy_a5, (1 << core), 0);
24979
24980 if (CHSPEC_IS2G(pi->radio_chanspec)) {
24981 if ((pi->pubpi.radiorev <= 4)
24982 || (pi->pubpi.radiorev == 6))
24983 m[core] = (pi->bw == WL_CHANSPEC_BW_40) ?
24984 60 : 79;
24985 else
24986 m[core] = (pi->bw == WL_CHANSPEC_BW_40) ?
24987 45 : 64;
24988 } else {
24989 m[core] = (pi->bw == WL_CHANSPEC_BW_40) ? 75 : 107;
24990 }
24991
24992 m[phy_a7] = 0;
24993 wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
24994
24995 phy_a2 = 63;
24996
24997 if (CHSPEC_IS2G(pi->radio_chanspec)) {
24998 if ((pi->pubpi.radiorev == 4)
24999 || (pi->pubpi.radiorev == 6)) {
25000 phy_a1 = 30;
25001 phy_a3 = 30;
25002 } else {
25003 phy_a1 = 25;
25004 phy_a3 = 25;
25005 }
25006 } else {
25007 if ((pi->pubpi.radiorev == 5)
25008 || (pi->pubpi.radiorev == 7)
25009 || (pi->pubpi.radiorev == 8)) {
25010 phy_a1 = 25;
25011 phy_a3 = 25;
25012 } else {
25013 phy_a1 = 35;
25014 phy_a3 = 35;
25015 }
25016 }
25017
25018 if (cal_mode == CAL_GCTRL) {
25019 if ((pi->pubpi.radiorev == 5)
25020 && (CHSPEC_IS2G(pi->radio_chanspec)))
25021 phy_a1 = 55;
25022 else if (((pi->pubpi.radiorev == 7) &&
25023 (CHSPEC_IS2G(pi->radio_chanspec))) ||
25024 ((pi->pubpi.radiorev == 8) &&
25025 (CHSPEC_IS2G(pi->radio_chanspec))))
25026 phy_a1 = 60;
25027 else
25028 phy_a1 = 63;
25029
25030 } else if ((cal_mode != CAL_FULL) && (cal_mode != CAL_SOFT)) {
25031
25032 phy_a1 = 35;
25033 phy_a3 = 35;
25034 }
25035
25036 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
25037 0x29b, (0x1 << 0), (1) << 0);
25038
25039 mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
25040 0x29b, (0x1 << 0), (0) << 0);
25041
25042 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
25043 0x2a4, (0x1 << 13), (1) << 13);
25044
25045 mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
25046 0x2a4, (0x1 << 13), (0) << 13);
25047
25048 write_phy_reg(pi, 0x2a1, 0x80);
25049 write_phy_reg(pi, 0x2a2, 0x100);
25050
25051 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
25052 0x2a4, (0x7 << 4), (11) << 4);
25053
25054 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
25055 0x2a4, (0x7 << 8), (11) << 8);
25056
25057 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
25058 0x2a4, (0x7 << 0), (0x3) << 0);
25059
25060 write_phy_reg(pi, 0x2e5, 0x20);
25061
25062 mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
25063
25064 mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
25065
25066 mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
25067
25068 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
25069 1, ((core == 0) ? 1 : 2), 0,
25070 NPHY_REV7_RFCTRLOVERRIDE_ID0);
25071 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
25072 0, ((core == 0) ? 2 : 1), 0,
25073 NPHY_REV7_RFCTRLOVERRIDE_ID0);
25074
25075 write_phy_reg(pi, 0x2be, 1);
25076 SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
25077
25078 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
25079 0, 0x3, 0,
25080 NPHY_REV7_RFCTRLOVERRIDE_ID0);
25081
25082 wlc_phy_table_write_nphy(pi,
25083 (core ==
25084 PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
25085 : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
25086 32, &phy_a8);
25087
25088 if (cal_mode != CAL_GCTRL) {
25089 if (CHSPEC_IS5G(pi->radio_chanspec))
25090 wlc_phy_a1_nphy(pi, core, 5, 0, 35);
25091 }
25092
25093 wlc_phy_rfctrl_override_1tomany_nphy(
25094 pi,
25095 NPHY_REV7_RfctrlOverride_cmd_txgain,
25096 phy_a5, (1 << core), 1);
25097
25098 } else {
25099
25100 if (txgains) {
25101 if (txgains->useindex) {
25102 phy_a4 = 15 - ((txgains->index) >> 3);
25103 if (CHSPEC_IS2G(pi->radio_chanspec)) {
25104 if (NREV_GE(pi->pubpi.phy_rev, 6))
25105 phy_a5 = 0x00f7 | (phy_a4 << 8);
25106
25107 else
25108 if (NREV_IS(pi->pubpi.phy_rev, 5))
25109 phy_a5 = 0x10f7 | (phy_a4 << 8);
25110 else
25111 phy_a5 = 0x50f7 | (phy_a4 << 8);
25112 } else {
25113 phy_a5 = 0x70f7 | (phy_a4 << 8);
25114 }
25115 wlc_phy_rfctrl_override_nphy(pi,
25116 (0x1 << 13),
25117 phy_a5,
25118 (1 << core), 0);
25119 } else {
25120 wlc_phy_rfctrl_override_nphy(pi,
25121 (0x1 << 13),
25122 0x5bf7,
25123 (1 << core), 0);
25124 }
25125 }
25126
25127 if (CHSPEC_IS2G(pi->radio_chanspec))
25128 m[core] = (pi->bw == WL_CHANSPEC_BW_40) ? 45 : 64;
25129 else
25130 m[core] = (pi->bw == WL_CHANSPEC_BW_40) ? 75 : 107;
25131
25132 m[phy_a7] = 0;
25133 wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
25134
25135 phy_a2 = 63;
25136
25137 if (cal_mode == CAL_FULL) {
25138 phy_a1 = 25;
25139 phy_a3 = 25;
25140 } else if (cal_mode == CAL_SOFT) {
25141 phy_a1 = 25;
25142 phy_a3 = 25;
25143 } else if (cal_mode == CAL_GCTRL) {
25144 phy_a1 = 63;
25145 phy_a3 = 25;
25146 } else {
25147
25148 phy_a1 = 25;
25149 phy_a3 = 25;
25150 }
25151
25152 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
25153 0x29b, (0x1 << 0), (1) << 0);
25154
25155 mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
25156 0x29b, (0x1 << 0), (0) << 0);
25157
25158 if (NREV_GE(pi->pubpi.phy_rev, 6)) {
25159 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
25160 0x2a4, (0x1 << 13), (1) << 13);
25161
25162 mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
25163 0x2a4, (0x1 << 13), (0) << 13);
25164
25165 write_phy_reg(pi, 0x2a1, 0x20);
25166 write_phy_reg(pi, 0x2a2, 0x60);
25167
25168 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
25169 0x2a4, (0xf << 4), (9) << 4);
25170
25171 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
25172 0x2a4, (0xf << 8), (9) << 8);
25173
25174 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
25175 0x2a4, (0xf << 0), (0x2) << 0);
25176
25177 write_phy_reg(pi, 0x2e5, 0x20);
25178 } else {
25179 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
25180 0x2a4, (0x1 << 11), (1) << 11);
25181
25182 mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
25183 0x2a4, (0x1 << 11), (0) << 11);
25184
25185 write_phy_reg(pi, 0x2a1, 0x80);
25186 write_phy_reg(pi, 0x2a2, 0x600);
25187
25188 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
25189 0x2a4, (0x7 << 4), (0) << 4);
25190
25191 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
25192 0x2a4, (0x7 << 8), (0) << 8);
25193
25194 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
25195 0x2a4, (0x7 << 0), (0x3) << 0);
25196
25197 mod_phy_reg(pi, 0x2a0, (0x3f << 8), (0x20) << 8);
25198
25199 }
25200
25201 mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
25202
25203 mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
25204
25205 mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
25206
25207 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0x3, 0);
25208
25209 write_phy_reg(pi, 0x2be, 1);
25210 SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
25211
25212 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
25213
25214 wlc_phy_table_write_nphy(pi,
25215 (core ==
25216 PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
25217 : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
25218 32, &phy_a8);
25219
25220 if (cal_mode != CAL_GCTRL)
25221 wlc_phy_a1_nphy(pi, core, 5, 0, 40);
25222 }
25223}
25224
25225static u8 wlc_phy_a3_nphy(struct brcms_phy *pi, u8 start_gain, u8 core)
25226{
25227 int phy_a1;
25228 int phy_a2;
25229 bool phy_a3;
25230 struct nphy_ipa_txcalgains phy_a4;
25231 bool phy_a5 = false;
25232 bool phy_a6 = true;
25233 s32 phy_a7, phy_a8;
25234 u32 phy_a9;
25235 int phy_a10;
25236 bool phy_a11 = false;
25237 int phy_a12;
25238 u8 phy_a13 = 0;
25239 u8 phy_a14;
25240 u8 *phy_a15 = NULL;
25241
25242 phy_a4.useindex = true;
25243 phy_a12 = start_gain;
25244
25245 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25246
25247 phy_a2 = 20;
25248 phy_a1 = 1;
25249
25250 if (CHSPEC_IS2G(pi->radio_chanspec)) {
25251 if (pi->pubpi.radiorev == 5) {
25252
25253 phy_a15 = pad_gain_codes_used_2057rev5;
25254 phy_a13 =
25255 sizeof(pad_gain_codes_used_2057rev5) /
25256 sizeof(pad_gain_codes_used_2057rev5
25257 [0]) - 1;
25258
25259 } else if ((pi->pubpi.radiorev == 7)
25260 || (pi->pubpi.radiorev == 8)) {
25261
25262 phy_a15 = pad_gain_codes_used_2057rev7;
25263 phy_a13 =
25264 sizeof(pad_gain_codes_used_2057rev7) /
25265 sizeof(pad_gain_codes_used_2057rev7
25266 [0]) - 1;
25267
25268 } else {
25269
25270 phy_a15 = pad_all_gain_codes_2057;
25271 phy_a13 = sizeof(pad_all_gain_codes_2057) /
25272 sizeof(pad_all_gain_codes_2057[0]) -
25273 1;
25274 }
25275
25276 } else {
25277
25278 phy_a15 = pga_all_gain_codes_2057;
25279 phy_a13 = sizeof(pga_all_gain_codes_2057) /
25280 sizeof(pga_all_gain_codes_2057[0]) - 1;
25281 }
25282
25283 phy_a14 = 0;
25284
25285 for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
25286 if (CHSPEC_IS2G(pi->radio_chanspec))
25287 phy_a4.gains.pad[core] =
25288 (u16) phy_a15[phy_a12];
25289 else
25290 phy_a4.gains.pga[core] =
25291 (u16) phy_a15[phy_a12];
25292
25293 wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
25294
25295 wlc_phy_table_read_nphy(pi,
25296 (core ==
25297 PHY_CORE_0 ?
25298 NPHY_TBL_ID_EPSILONTBL0 :
25299 NPHY_TBL_ID_EPSILONTBL1), 1,
25300 63, 32, &phy_a9);
25301
25302 wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
25303
25304 phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
25305 (phy_a8 == 4095) || (phy_a8 == -4096));
25306
25307 if (!phy_a6 && (phy_a3 != phy_a5)) {
25308 if (!phy_a3)
25309 phy_a12 -= (u8) phy_a1;
25310
25311 phy_a11 = true;
25312 break;
25313 }
25314
25315 if (phy_a3)
25316 phy_a12 += (u8) phy_a1;
25317 else
25318 phy_a12 -= (u8) phy_a1;
25319
25320 if ((phy_a12 < phy_a14) || (phy_a12 > phy_a13)) {
25321 if (phy_a12 < phy_a14)
25322 phy_a12 = phy_a14;
25323 else
25324 phy_a12 = phy_a13;
25325
25326 phy_a11 = true;
25327 break;
25328 }
25329
25330 phy_a6 = false;
25331 phy_a5 = phy_a3;
25332 }
25333
25334 } else {
25335 phy_a2 = 10;
25336 phy_a1 = 8;
25337 for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
25338 phy_a4.index = (u8) phy_a12;
25339 wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
25340
25341 wlc_phy_table_read_nphy(pi,
25342 (core ==
25343 PHY_CORE_0 ?
25344 NPHY_TBL_ID_EPSILONTBL0 :
25345 NPHY_TBL_ID_EPSILONTBL1), 1,
25346 63, 32, &phy_a9);
25347
25348 wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
25349
25350 phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
25351 (phy_a8 == 4095) || (phy_a8 == -4096));
25352
25353 if (!phy_a6 && (phy_a3 != phy_a5)) {
25354 if (!phy_a3)
25355 phy_a12 -= (u8) phy_a1;
25356
25357 phy_a11 = true;
25358 break;
25359 }
25360
25361 if (phy_a3)
25362 phy_a12 += (u8) phy_a1;
25363 else
25364 phy_a12 -= (u8) phy_a1;
25365
25366 if ((phy_a12 < 0) || (phy_a12 > 127)) {
25367 if (phy_a12 < 0)
25368 phy_a12 = 0;
25369 else
25370 phy_a12 = 127;
25371
25372 phy_a11 = true;
25373 break;
25374 }
25375
25376 phy_a6 = false;
25377 phy_a5 = phy_a3;
25378 }
25379
25380 }
25381
25382 if (NREV_GE(pi->pubpi.phy_rev, 7))
25383 return (u8) phy_a15[phy_a12];
25384 else
25385 return (u8) phy_a12;
25386
25387}
25388
25389static void wlc_phy_a4(struct brcms_phy *pi, bool full_cal)
25390{
25391 struct nphy_ipa_txcalgains phy_b1[2];
25392 struct nphy_papd_restore_state phy_b2;
25393 bool phy_b3;
25394 u8 phy_b4;
25395 u8 phy_b5;
25396 s16 phy_b6, phy_b7, phy_b8;
25397 u16 phy_b9;
25398 s16 phy_b10, phy_b11, phy_b12;
25399
25400 phy_b11 = 0;
25401 phy_b12 = 0;
25402 phy_b7 = 0;
25403 phy_b8 = 0;
25404 phy_b6 = 0;
25405
25406 if (pi->nphy_papd_skip == 1)
25407 return;
25408
25409 phy_b3 = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
25410 if (!phy_b3)
25411 wlapi_suspend_mac_and_wait(pi->sh->physhim);
25412
25413 wlc_phy_stay_in_carriersearch_nphy(pi, true);
25414
25415 pi->nphy_force_papd_cal = false;
25416
25417 for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++)
25418 pi->nphy_papd_tx_gain_at_last_cal[phy_b5] =
25419 wlc_phy_txpwr_idx_cur_get_nphy(pi, phy_b5);
25420
25421 pi->nphy_papd_last_cal = pi->sh->now;
25422 pi->nphy_papd_recal_counter++;
25423
25424 phy_b4 = pi->nphy_txpwrctrl;
25425 wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
25426
25427 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL0, 64, 0, 32,
25428 nphy_papd_scaltbl);
25429 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL1, 64, 0, 32,
25430 nphy_papd_scaltbl);
25431
25432 phy_b9 = read_phy_reg(pi, 0x01);
25433 mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
25434
25435 for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
25436 s32 i, val = 0;
25437 for (i = 0; i < 64; i++)
25438 wlc_phy_table_write_nphy(pi,
25439 ((phy_b5 ==
25440 PHY_CORE_0) ?
25441 NPHY_TBL_ID_EPSILONTBL0 :
25442 NPHY_TBL_ID_EPSILONTBL1), 1,
25443 i, 32, &val);
25444 }
25445
25446 wlc_phy_ipa_restore_tx_digi_filts_nphy(pi);
25447
25448 phy_b2.mm = wlc_phy_ipa_get_bbmult_nphy(pi);
25449 for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
25450 wlc_phy_papd_cal_setup_nphy(pi, &phy_b2, phy_b5);
25451
25452 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25453 if (CHSPEC_IS2G(pi->radio_chanspec)) {
25454 if ((pi->pubpi.radiorev == 3)
25455 || (pi->pubpi.radiorev == 4)
25456 || (pi->pubpi.radiorev == 6)) {
25457 pi->nphy_papd_cal_gain_index[phy_b5] =
25458 23;
25459 } else if (pi->pubpi.radiorev == 5) {
25460 pi->nphy_papd_cal_gain_index[phy_b5] =
25461 0;
25462 pi->nphy_papd_cal_gain_index[phy_b5] =
25463 wlc_phy_a3_nphy(
25464 pi,
25465 pi->
25466 nphy_papd_cal_gain_index
25467 [phy_b5],
25468 phy_b5);
25469
25470 } else if ((pi->pubpi.radiorev == 7)
25471 || (pi->pubpi.radiorev == 8)) {
25472
25473 pi->nphy_papd_cal_gain_index[phy_b5] =
25474 0;
25475 pi->nphy_papd_cal_gain_index[phy_b5] =
25476 wlc_phy_a3_nphy(
25477 pi,
25478 pi->
25479 nphy_papd_cal_gain_index
25480 [phy_b5],
25481 phy_b5);
25482
25483 }
25484
25485 phy_b1[phy_b5].gains.pad[phy_b5] =
25486 pi->nphy_papd_cal_gain_index[phy_b5];
25487
25488 } else {
25489 pi->nphy_papd_cal_gain_index[phy_b5] = 0;
25490 pi->nphy_papd_cal_gain_index[phy_b5] =
25491 wlc_phy_a3_nphy(
25492 pi,
25493 pi->
25494 nphy_papd_cal_gain_index
25495 [phy_b5], phy_b5);
25496 phy_b1[phy_b5].gains.pga[phy_b5] =
25497 pi->nphy_papd_cal_gain_index[phy_b5];
25498 }
25499 } else {
25500 phy_b1[phy_b5].useindex = true;
25501 phy_b1[phy_b5].index = 16;
25502 phy_b1[phy_b5].index =
25503 wlc_phy_a3_nphy(pi, phy_b1[phy_b5].index,
25504 phy_b5);
25505
25506 pi->nphy_papd_cal_gain_index[phy_b5] =
25507 15 - ((phy_b1[phy_b5].index) >> 3);
25508 }
25509
25510 switch (pi->nphy_papd_cal_type) {
25511 case 0:
25512 wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_FULL, phy_b5);
25513 break;
25514 case 1:
25515 wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_SOFT, phy_b5);
25516 break;
25517 }
25518
25519 if (NREV_GE(pi->pubpi.phy_rev, 7))
25520 wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
25521 }
25522
25523 if (NREV_LT(pi->pubpi.phy_rev, 7))
25524 wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
25525
25526 for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
25527 int eps_offset = 0;
25528
25529 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25530 if (CHSPEC_IS2G(pi->radio_chanspec)) {
25531 if (pi->pubpi.radiorev == 3)
25532 eps_offset = -2;
25533 else if (pi->pubpi.radiorev == 5)
25534 eps_offset = 3;
25535 else
25536 eps_offset = -1;
25537 } else {
25538 eps_offset = 2;
25539 }
25540
25541 if (CHSPEC_IS2G(pi->radio_chanspec)) {
25542 phy_b8 = phy_b1[phy_b5].gains.pad[phy_b5];
25543 phy_b10 = 0;
25544 if ((pi->pubpi.radiorev == 3) ||
25545 (pi->pubpi.radiorev == 4) ||
25546 (pi->pubpi.radiorev == 6)) {
25547 phy_b12 = -(
25548 nphy_papd_padgain_dlt_2g_2057rev3n4
25549 [phy_b8] + 1) / 2;
25550 phy_b10 = -1;
25551 } else if (pi->pubpi.radiorev == 5) {
25552 phy_b12 = -(
25553 nphy_papd_padgain_dlt_2g_2057rev5
25554 [phy_b8] + 1) / 2;
25555 } else if ((pi->pubpi.radiorev == 7) ||
25556 (pi->pubpi.radiorev == 8)) {
25557 phy_b12 = -(
25558 nphy_papd_padgain_dlt_2g_2057rev7
25559 [phy_b8] + 1) / 2;
25560 }
25561 } else {
25562 phy_b7 = phy_b1[phy_b5].gains.pga[phy_b5];
25563 if ((pi->pubpi.radiorev == 3) ||
25564 (pi->pubpi.radiorev == 4) ||
25565 (pi->pubpi.radiorev == 6))
25566 phy_b11 =
25567 -(nphy_papd_pgagain_dlt_5g_2057
25568 [phy_b7]
25569 + 1) / 2;
25570 else if ((pi->pubpi.radiorev == 7)
25571 || (pi->pubpi.radiorev == 8))
25572 phy_b11 = -(
25573 nphy_papd_pgagain_dlt_5g_2057rev7
25574 [phy_b7] + 1) / 2;
25575
25576 phy_b10 = -9;
25577 }
25578
25579 if (CHSPEC_IS2G(pi->radio_chanspec))
25580 phy_b6 =
25581 -60 + 27 + eps_offset + phy_b12 +
25582 phy_b10;
25583 else
25584 phy_b6 =
25585 -60 + 27 + eps_offset + phy_b11 +
25586 phy_b10;
25587
25588 mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
25589 0x29c, (0x1ff << 7), (phy_b6) << 7);
25590
25591 pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
25592 } else {
25593 if (NREV_LT(pi->pubpi.phy_rev, 5))
25594 eps_offset = 4;
25595 else
25596 eps_offset = 2;
25597
25598 phy_b7 = 15 - ((phy_b1[phy_b5].index) >> 3);
25599
25600 if (CHSPEC_IS2G(pi->radio_chanspec)) {
25601 phy_b11 =
25602 -(nphy_papd_pga_gain_delta_ipa_2g[
25603 phy_b7] +
25604 1) / 2;
25605 phy_b10 = 0;
25606 } else {
25607 phy_b11 =
25608 -(nphy_papd_pga_gain_delta_ipa_5g[
25609 phy_b7] +
25610 1) / 2;
25611 phy_b10 = -9;
25612 }
25613
25614 phy_b6 = -60 + 27 + eps_offset + phy_b11 + phy_b10;
25615
25616 mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
25617 0x29c, (0x1ff << 7), (phy_b6) << 7);
25618
25619 pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
25620 }
25621 }
25622
25623 mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
25624 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
25625
25626 mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
25627 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
25628
25629 if (NREV_GE(pi->pubpi.phy_rev, 6)) {
25630 mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
25631 0x2a4, (0x1 << 13), (0) << 13);
25632
25633 mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
25634 0x2a4, (0x1 << 13), (0) << 13);
25635
25636 } else {
25637 mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
25638 0x2a4, (0x1 << 11), (0) << 11);
25639
25640 mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
25641 0x2a4, (0x1 << 11), (0) << 11);
25642
25643 }
25644 pi->nphy_papdcomp = NPHY_PAPD_COMP_ON;
25645
25646 write_phy_reg(pi, 0x01, phy_b9);
25647
25648 wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
25649
25650 wlc_phy_txpwrctrl_enable_nphy(pi, phy_b4);
25651 if (phy_b4 == PHY_TPC_HW_OFF) {
25652 wlc_phy_txpwr_index_nphy(pi, (1 << 0),
25653 (s8) (pi->nphy_txpwrindex[0].
25654 index_internal), false);
25655 wlc_phy_txpwr_index_nphy(pi, (1 << 1),
25656 (s8) (pi->nphy_txpwrindex[1].
25657 index_internal), false);
25658 }
25659
25660 wlc_phy_stay_in_carriersearch_nphy(pi, false);
25661
25662 if (!phy_b3)
25663 wlapi_enable_mac(pi->sh->physhim);
25664}
25665
25666void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype)
25667{
25668 struct nphy_txgains target_gain;
25669 u8 tx_pwr_ctrl_state;
25670 bool fullcal = true;
25671 bool restore_tx_gain = false;
25672 bool mphase;
25673
25674 if (PHY_MUTED(pi))
25675 return;
25676
25677 if (caltype == PHY_PERICAL_AUTO)
25678 fullcal = (pi->radio_chanspec != pi->nphy_txiqlocal_chanspec);
25679 else if (caltype == PHY_PERICAL_PARTIAL)
25680 fullcal = false;
25681
25682 if (pi->cal_type_override != PHY_PERICAL_AUTO)
25683 fullcal =
25684 (pi->cal_type_override ==
25685 PHY_PERICAL_FULL) ? true : false;
25686
25687 if ((pi->mphase_cal_phase_id > MPHASE_CAL_STATE_INIT)) {
25688 if (pi->nphy_txiqlocal_chanspec != pi->radio_chanspec)
25689 wlc_phy_cal_perical_mphase_restart(pi);
25690 }
25691
25692 if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_RXCAL))
25693 wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
25694
25695 wlapi_suspend_mac_and_wait(pi->sh->physhim);
25696
25697 wlc_phyreg_enter((struct brcms_phy_pub *) pi);
25698
25699 if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_IDLE) ||
25700 (pi->mphase_cal_phase_id == MPHASE_CAL_STATE_INIT)) {
25701 pi->nphy_cal_orig_pwr_idx[0] =
25702 (u8) ((read_phy_reg(pi, 0x1ed) >> 8) & 0x7f);
25703 pi->nphy_cal_orig_pwr_idx[1] =
25704 (u8) ((read_phy_reg(pi, 0x1ee) >> 8) & 0x7f);
25705
25706 if (pi->nphy_txpwrctrl != PHY_TPC_HW_OFF) {
25707 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2,
25708 0x110, 16,
25709 pi->nphy_cal_orig_tx_gain);
25710 } else {
25711 pi->nphy_cal_orig_tx_gain[0] = 0;
25712 pi->nphy_cal_orig_tx_gain[1] = 0;
25713 }
25714 }
25715 target_gain = wlc_phy_get_tx_gain_nphy(pi);
25716 tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
25717 wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
25718
25719 if (pi->antsel_type == ANTSEL_2x3)
25720 wlc_phy_antsel_init((struct brcms_phy_pub *) pi, true);
25721
25722 mphase = (pi->mphase_cal_phase_id != MPHASE_CAL_STATE_IDLE);
25723 if (!mphase) {
25724
25725 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
25726 wlc_phy_precal_txgain_nphy(pi);
25727 pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
25728 restore_tx_gain = true;
25729
25730 target_gain = pi->nphy_cal_target_gain;
25731 }
25732 if (0 ==
25733 wlc_phy_cal_txiqlo_nphy(pi, target_gain, fullcal,
25734 mphase)) {
25735 if (PHY_IPA(pi))
25736 wlc_phy_a4(pi, true);
25737
25738 wlc_phyreg_exit((struct brcms_phy_pub *) pi);
25739 wlapi_enable_mac(pi->sh->physhim);
25740 wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION,
25741 10000);
25742 wlapi_suspend_mac_and_wait(pi->sh->physhim);
25743 wlc_phyreg_enter((struct brcms_phy_pub *) pi);
25744
25745 if (0 == wlc_phy_cal_rxiq_nphy(pi, target_gain,
25746 (pi->first_cal_after_assoc ||
25747 (pi->cal_type_override ==
25748 PHY_PERICAL_FULL)) ? 2 : 0, false)) {
25749 wlc_phy_savecal_nphy(pi);
25750
25751 wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
25752
25753 pi->nphy_perical_last = pi->sh->now;
25754 }
25755 }
25756 if (caltype != PHY_PERICAL_AUTO)
25757 wlc_phy_rssi_cal_nphy(pi);
25758
25759 if (pi->first_cal_after_assoc
25760 || (pi->cal_type_override == PHY_PERICAL_FULL)) {
25761 pi->first_cal_after_assoc = false;
25762 wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
25763 wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
25764 }
25765
25766 if (NREV_GE(pi->pubpi.phy_rev, 3))
25767 wlc_phy_radio205x_vcocal_nphy(pi);
25768 } else {
25769 switch (pi->mphase_cal_phase_id) {
25770 case MPHASE_CAL_STATE_INIT:
25771 pi->nphy_perical_last = pi->sh->now;
25772 pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
25773
25774 if (NREV_GE(pi->pubpi.phy_rev, 3))
25775 wlc_phy_precal_txgain_nphy(pi);
25776
25777 pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
25778 pi->mphase_cal_phase_id++;
25779 break;
25780
25781 case MPHASE_CAL_STATE_TXPHASE0:
25782 case MPHASE_CAL_STATE_TXPHASE1:
25783 case MPHASE_CAL_STATE_TXPHASE2:
25784 case MPHASE_CAL_STATE_TXPHASE3:
25785 case MPHASE_CAL_STATE_TXPHASE4:
25786 case MPHASE_CAL_STATE_TXPHASE5:
25787 if ((pi->radar_percal_mask & 0x10) != 0)
25788 pi->nphy_rxcal_active = true;
25789
25790 if (wlc_phy_cal_txiqlo_nphy
25791 (pi, pi->nphy_cal_target_gain, fullcal,
25792 true) != 0) {
25793
25794 wlc_phy_cal_perical_mphase_reset(pi);
25795 break;
25796 }
25797
25798 if (NREV_LE(pi->pubpi.phy_rev, 2) &&
25799 (pi->mphase_cal_phase_id ==
25800 MPHASE_CAL_STATE_TXPHASE4))
25801 pi->mphase_cal_phase_id += 2;
25802 else
25803 pi->mphase_cal_phase_id++;
25804 break;
25805
25806 case MPHASE_CAL_STATE_PAPDCAL:
25807 if ((pi->radar_percal_mask & 0x2) != 0)
25808 pi->nphy_rxcal_active = true;
25809
25810 if (PHY_IPA(pi))
25811 wlc_phy_a4(pi, true);
25812
25813 pi->mphase_cal_phase_id++;
25814 break;
25815
25816 case MPHASE_CAL_STATE_RXCAL:
25817 if ((pi->radar_percal_mask & 0x1) != 0)
25818 pi->nphy_rxcal_active = true;
25819 if (wlc_phy_cal_rxiq_nphy(pi, target_gain,
25820 (pi->first_cal_after_assoc ||
25821 (pi->cal_type_override ==
25822 PHY_PERICAL_FULL)) ? 2 : 0,
25823 false) == 0)
25824 wlc_phy_savecal_nphy(pi);
25825
25826 pi->mphase_cal_phase_id++;
25827 break;
25828
25829 case MPHASE_CAL_STATE_RSSICAL:
25830 if ((pi->radar_percal_mask & 0x4) != 0)
25831 pi->nphy_rxcal_active = true;
25832 wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
25833 wlc_phy_rssi_cal_nphy(pi);
25834
25835 if (NREV_GE(pi->pubpi.phy_rev, 3))
25836 wlc_phy_radio205x_vcocal_nphy(pi);
25837
25838 restore_tx_gain = true;
25839
25840 if (pi->first_cal_after_assoc)
25841 pi->mphase_cal_phase_id++;
25842 else
25843 wlc_phy_cal_perical_mphase_reset(pi);
25844
25845 break;
25846
25847 case MPHASE_CAL_STATE_IDLETSSI:
25848 if ((pi->radar_percal_mask & 0x8) != 0)
25849 pi->nphy_rxcal_active = true;
25850
25851 if (pi->first_cal_after_assoc) {
25852 pi->first_cal_after_assoc = false;
25853 wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
25854 wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
25855 }
25856
25857 wlc_phy_cal_perical_mphase_reset(pi);
25858 break;
25859
25860 default:
25861 wlc_phy_cal_perical_mphase_reset(pi);
25862 break;
25863 }
25864 }
25865
25866 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
25867 if (restore_tx_gain) {
25868 if (tx_pwr_ctrl_state != PHY_TPC_HW_OFF) {
25869
25870 wlc_phy_txpwr_index_nphy(pi, 1,
25871 pi->
25872 nphy_cal_orig_pwr_idx
25873 [0], false);
25874 wlc_phy_txpwr_index_nphy(pi, 2,
25875 pi->
25876 nphy_cal_orig_pwr_idx
25877 [1], false);
25878
25879 pi->nphy_txpwrindex[0].index = -1;
25880 pi->nphy_txpwrindex[1].index = -1;
25881 } else {
25882 wlc_phy_txpwr_index_nphy(pi, (1 << 0),
25883 (s8) (pi->
25884 nphy_txpwrindex
25885 [0].
25886 index_internal),
25887 false);
25888 wlc_phy_txpwr_index_nphy(pi, (1 << 1),
25889 (s8) (pi->
25890 nphy_txpwrindex
25891 [1].
25892 index_internal),
25893 false);
25894 }
25895 }
25896 }
25897
25898 wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
25899 wlc_phyreg_exit((struct brcms_phy_pub *) pi);
25900 wlapi_enable_mac(pi->sh->physhim);
25901}
25902
25903int
25904wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain,
25905 bool fullcal, bool mphase)
25906{
25907 u16 val;
25908 u16 tbl_buf[11];
25909 u8 cal_cnt;
25910 u16 cal_cmd;
25911 u8 num_cals, max_cal_cmds;
25912 u16 core_no, cal_type;
25913 u16 diq_start = 0;
25914 u8 phy_bw;
25915 u16 max_val;
25916 u16 tone_freq;
25917 u16 gain_save[2];
25918 u16 cal_gain[2];
25919 struct nphy_iqcal_params cal_params[2];
25920 u32 tbl_len;
25921 void *tbl_ptr;
25922 bool ladder_updated[2];
25923 u8 mphase_cal_lastphase = 0;
25924 int bcmerror = 0;
25925 bool phyhang_avoid_state = false;
25926
25927 u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
25928 0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901,
25929 0x1902,
25930 0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607,
25931 0x6407
25932 };
25933
25934 u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
25935 0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400,
25936 0x3200,
25937 0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406,
25938 0x6407
25939 };
25940
25941 u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
25942 0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201,
25943 0x1202,
25944 0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207,
25945 0x4707
25946 };
25947
25948 u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
25949 0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900,
25950 0x2300,
25951 0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706,
25952 0x4707
25953 };
25954
25955 u16 tbl_tx_iqlo_cal_startcoefs[] = {
25956 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
25957 0x0000
25958 };
25959
25960 u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
25961 0x8123, 0x8264, 0x8086, 0x8245, 0x8056,
25962 0x9123, 0x9264, 0x9086, 0x9245, 0x9056
25963 };
25964
25965 u16 tbl_tx_iqlo_cal_cmds_recal[] = {
25966 0x8101, 0x8253, 0x8053, 0x8234, 0x8034,
25967 0x9101, 0x9253, 0x9053, 0x9234, 0x9034
25968 };
25969
25970 u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
25971 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
25972 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
25973 0x0000
25974 };
25975
25976 u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
25977 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234,
25978 0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234
25979 };
25980
25981 u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
25982 0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223,
25983 0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223
25984 };
25985
25986 wlc_phy_stay_in_carriersearch_nphy(pi, true);
25987
25988 if (NREV_GE(pi->pubpi.phy_rev, 4)) {
25989 phyhang_avoid_state = pi->phyhang_avoid;
25990 pi->phyhang_avoid = false;
25991 }
25992
25993 if (CHSPEC_IS40(pi->radio_chanspec))
25994 phy_bw = 40;
25995 else
25996 phy_bw = 20;
25997
25998 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
25999
26000 for (core_no = 0; core_no <= 1; core_no++) {
26001 wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
26002 &cal_params[core_no]);
26003 cal_gain[core_no] = cal_params[core_no].cal_gain;
26004 }
26005
26006 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
26007
26008 wlc_phy_txcal_radio_setup_nphy(pi);
26009
26010 wlc_phy_txcal_physetup_nphy(pi);
26011
26012 ladder_updated[0] = ladder_updated[1] = false;
26013 if (!(NREV_GE(pi->pubpi.phy_rev, 6) ||
26014 (NREV_IS(pi->pubpi.phy_rev, 5) && PHY_IPA(pi)
26015 && (CHSPEC_IS2G(pi->radio_chanspec))))) {
26016
26017 if (phy_bw == 40) {
26018 tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_40;
26019 tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_40);
26020 } else {
26021 tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_20;
26022 tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_20);
26023 }
26024 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 0,
26025 16, tbl_ptr);
26026
26027 if (phy_bw == 40) {
26028 tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_40;
26029 tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_40);
26030 } else {
26031 tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_20;
26032 tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_20);
26033 }
26034 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 32,
26035 16, tbl_ptr);
26036 }
26037
26038 if (NREV_GE(pi->pubpi.phy_rev, 7))
26039 write_phy_reg(pi, 0xc2, 0x8ad9);
26040 else
26041 write_phy_reg(pi, 0xc2, 0x8aa9);
26042
26043 max_val = 250;
26044 tone_freq = (phy_bw == 20) ? 2500 : 5000;
26045
26046 if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
26047 wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, 0, 1, 0, false);
26048 bcmerror = 0;
26049 } else {
26050 bcmerror =
26051 wlc_phy_tx_tone_nphy(pi, tone_freq, max_val, 1, 0,
26052 false);
26053 }
26054
26055 if (bcmerror == 0) {
26056
26057 if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
26058 tbl_ptr = pi->mphase_txcal_bestcoeffs;
26059 tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs);
26060 if (NREV_LT(pi->pubpi.phy_rev, 3))
26061 tbl_len -= 2;
26062 } else {
26063 if ((!fullcal) && (pi->nphy_txiqlocal_coeffsvalid)) {
26064
26065 tbl_ptr = pi->nphy_txiqlocal_bestc;
26066 tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc);
26067 if (NREV_LT(pi->pubpi.phy_rev, 3))
26068 tbl_len -= 2;
26069 } else {
26070
26071 fullcal = true;
26072
26073 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
26074 tbl_ptr =
26075 tbl_tx_iqlo_cal_startcoefs_nphyrev3;
26076 tbl_len = ARRAY_SIZE(
26077 tbl_tx_iqlo_cal_startcoefs_nphyrev3);
26078 } else {
26079 tbl_ptr = tbl_tx_iqlo_cal_startcoefs;
26080 tbl_len = ARRAY_SIZE(
26081 tbl_tx_iqlo_cal_startcoefs);
26082 }
26083 }
26084 }
26085 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 64,
26086 16, tbl_ptr);
26087
26088 if (fullcal) {
26089 max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
26090 ARRAY_SIZE(
26091 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3) :
26092 ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal);
26093 } else {
26094 max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
26095 ARRAY_SIZE(
26096 tbl_tx_iqlo_cal_cmds_recal_nphyrev3) :
26097 ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal);
26098 }
26099
26100 if (mphase) {
26101 cal_cnt = pi->mphase_txcal_cmdidx;
26102 if ((cal_cnt + pi->mphase_txcal_numcmds) < max_cal_cmds)
26103 num_cals = cal_cnt + pi->mphase_txcal_numcmds;
26104 else
26105 num_cals = max_cal_cmds;
26106 } else {
26107 cal_cnt = 0;
26108 num_cals = max_cal_cmds;
26109 }
26110
26111 for (; cal_cnt < num_cals; cal_cnt++) {
26112
26113 if (fullcal) {
26114 cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
26115 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3
26116 [cal_cnt] :
26117 tbl_tx_iqlo_cal_cmds_fullcal[cal_cnt];
26118 } else {
26119 cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
26120 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[
26121 cal_cnt]
26122 : tbl_tx_iqlo_cal_cmds_recal[cal_cnt];
26123 }
26124
26125 core_no = ((cal_cmd & 0x3000) >> 12);
26126 cal_type = ((cal_cmd & 0x0F00) >> 8);
26127
26128 if (NREV_GE(pi->pubpi.phy_rev, 6) ||
26129 (NREV_IS(pi->pubpi.phy_rev, 5) &&
26130 PHY_IPA(pi)
26131 && (CHSPEC_IS2G(pi->radio_chanspec)))) {
26132 if (!ladder_updated[core_no]) {
26133 wlc_phy_update_txcal_ladder_nphy(
26134 pi,
26135 core_no);
26136 ladder_updated[core_no] = true;
26137 }
26138 }
26139
26140 val =
26141 (cal_params[core_no].
26142 ncorr[cal_type] << 8) | NPHY_N_GCTL;
26143 write_phy_reg(pi, 0xc1, val);
26144
26145 if ((cal_type == 1) || (cal_type == 3)
26146 || (cal_type == 4)) {
26147
26148 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
26149 1, 69 + core_no, 16,
26150 tbl_buf);
26151
26152 diq_start = tbl_buf[0];
26153
26154 tbl_buf[0] = 0;
26155 wlc_phy_table_write_nphy(pi,
26156 NPHY_TBL_ID_IQLOCAL, 1,
26157 69 + core_no, 16,
26158 tbl_buf);
26159 }
26160
26161 write_phy_reg(pi, 0xc0, cal_cmd);
26162
26163 SPINWAIT(((read_phy_reg(pi, 0xc0) & 0xc000) != 0),
26164 20000);
26165 if (WARN(read_phy_reg(pi, 0xc0) & 0xc000,
26166 "HW error: txiq calib"))
26167 return -EIO;
26168
26169 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
26170 tbl_len, 96, 16, tbl_buf);
26171 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL,
26172 tbl_len, 64, 16, tbl_buf);
26173
26174 if ((cal_type == 1) || (cal_type == 3)
26175 || (cal_type == 4)) {
26176
26177 tbl_buf[0] = diq_start;
26178
26179 }
26180
26181 }
26182
26183 if (mphase) {
26184 pi->mphase_txcal_cmdidx = num_cals;
26185 if (pi->mphase_txcal_cmdidx >= max_cal_cmds)
26186 pi->mphase_txcal_cmdidx = 0;
26187 }
26188
26189 mphase_cal_lastphase =
26190 (NREV_LE(pi->pubpi.phy_rev, 2)) ?
26191 MPHASE_CAL_STATE_TXPHASE4 : MPHASE_CAL_STATE_TXPHASE5;
26192
26193 if (!mphase
26194 || (pi->mphase_cal_phase_id == mphase_cal_lastphase)) {
26195
26196 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 96,
26197 16, tbl_buf);
26198 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
26199 16, tbl_buf);
26200
26201 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
26202
26203 tbl_buf[0] = 0;
26204 tbl_buf[1] = 0;
26205 tbl_buf[2] = 0;
26206 tbl_buf[3] = 0;
26207
26208 }
26209 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
26210 16, tbl_buf);
26211
26212 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 101,
26213 16, tbl_buf);
26214 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
26215 16, tbl_buf);
26216
26217 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
26218 16, tbl_buf);
26219
26220 tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc);
26221 if (NREV_LT(pi->pubpi.phy_rev, 3))
26222 tbl_len -= 2;
26223
26224 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
26225 tbl_len, 96, 16,
26226 pi->nphy_txiqlocal_bestc);
26227
26228 pi->nphy_txiqlocal_coeffsvalid = true;
26229 pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
26230 } else {
26231 tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs);
26232 if (NREV_LT(pi->pubpi.phy_rev, 3))
26233 tbl_len -= 2;
26234
26235 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
26236 tbl_len, 96, 16,
26237 pi->mphase_txcal_bestcoeffs);
26238 }
26239
26240 wlc_phy_stopplayback_nphy(pi);
26241
26242 write_phy_reg(pi, 0xc2, 0x0000);
26243
26244 }
26245
26246 wlc_phy_txcal_phycleanup_nphy(pi);
26247
26248 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
26249 gain_save);
26250
26251 wlc_phy_txcal_radio_cleanup_nphy(pi);
26252
26253 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
26254 if (!mphase
26255 || (pi->mphase_cal_phase_id == mphase_cal_lastphase))
26256 wlc_phy_tx_iq_war_nphy(pi);
26257 }
26258
26259 if (NREV_GE(pi->pubpi.phy_rev, 4))
26260 pi->phyhang_avoid = phyhang_avoid_state;
26261
26262 wlc_phy_stay_in_carriersearch_nphy(pi, false);
26263
26264 return bcmerror;
26265}
26266
26267static void wlc_phy_reapply_txcal_coeffs_nphy(struct brcms_phy *pi)
26268{
26269 u16 tbl_buf[7];
26270
26271 if ((pi->nphy_txiqlocal_chanspec == pi->radio_chanspec) &&
26272 (pi->nphy_txiqlocal_coeffsvalid)) {
26273 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
26274 ARRAY_SIZE(tbl_buf), 80, 16, tbl_buf);
26275
26276 if ((pi->nphy_txiqlocal_bestc[0] != tbl_buf[0]) ||
26277 (pi->nphy_txiqlocal_bestc[1] != tbl_buf[1]) ||
26278 (pi->nphy_txiqlocal_bestc[2] != tbl_buf[2]) ||
26279 (pi->nphy_txiqlocal_bestc[3] != tbl_buf[3])) {
26280
26281 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
26282 16, pi->nphy_txiqlocal_bestc);
26283
26284 tbl_buf[0] = 0;
26285 tbl_buf[1] = 0;
26286 tbl_buf[2] = 0;
26287 tbl_buf[3] = 0;
26288 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
26289 16, tbl_buf);
26290
26291 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
26292 16,
26293 &pi->nphy_txiqlocal_bestc[5]);
26294
26295 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
26296 16,
26297 &pi->nphy_txiqlocal_bestc[5]);
26298 }
26299 }
26300}
26301
26302void
26303wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write,
26304 struct nphy_iq_comp *pcomp)
26305{
26306 if (write) {
26307 write_phy_reg(pi, 0x9a, pcomp->a0);
26308 write_phy_reg(pi, 0x9b, pcomp->b0);
26309 write_phy_reg(pi, 0x9c, pcomp->a1);
26310 write_phy_reg(pi, 0x9d, pcomp->b1);
26311 } else {
26312 pcomp->a0 = read_phy_reg(pi, 0x9a);
26313 pcomp->b0 = read_phy_reg(pi, 0x9b);
26314 pcomp->a1 = read_phy_reg(pi, 0x9c);
26315 pcomp->b1 = read_phy_reg(pi, 0x9d);
26316 }
26317}
26318
26319void
26320wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est,
26321 u16 num_samps, u8 wait_time, u8 wait_for_crs)
26322{
26323 u8 core;
26324
26325 write_phy_reg(pi, 0x12b, num_samps);
26326 mod_phy_reg(pi, 0x12a, (0xff << 0), (wait_time << 0));
26327 mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqMode,
26328 (wait_for_crs) ? NPHY_IqestCmd_iqMode : 0);
26329
26330 mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqstart, NPHY_IqestCmd_iqstart);
26331
26332 SPINWAIT(((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) != 0),
26333 10000);
26334 if (WARN(read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart,
26335 "HW error: rxiq est"))
26336 return;
26337
26338 if ((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0) {
26339 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
26340 est[core].i_pwr =
26341 (read_phy_reg(pi,
26342 NPHY_IqestipwrAccHi(core)) << 16)
26343 | read_phy_reg(pi, NPHY_IqestipwrAccLo(core));
26344 est[core].q_pwr =
26345 (read_phy_reg(pi,
26346 NPHY_IqestqpwrAccHi(core)) << 16)
26347 | read_phy_reg(pi, NPHY_IqestqpwrAccLo(core));
26348 est[core].iq_prod =
26349 (read_phy_reg(pi,
26350 NPHY_IqestIqAccHi(core)) << 16) |
26351 read_phy_reg(pi, NPHY_IqestIqAccLo(core));
26352 }
26353 }
26354}
26355
26356#define CAL_RETRY_CNT 2
26357static void wlc_phy_calc_rx_iq_comp_nphy(struct brcms_phy *pi, u8 core_mask)
26358{
26359 u8 curr_core;
26360 struct phy_iq_est est[PHY_CORE_MAX];
26361 struct nphy_iq_comp old_comp, new_comp;
26362 s32 iq = 0;
26363 u32 ii = 0, qq = 0;
26364 s16 iq_nbits, qq_nbits, brsh, arsh;
26365 s32 a, b, temp;
26366 int bcmerror = 0;
26367 uint cal_retry = 0;
26368
26369 if (core_mask == 0x0)
26370 return;
26371
26372 wlc_phy_rx_iq_coeffs_nphy(pi, 0, &old_comp);
26373 new_comp.a0 = new_comp.b0 = new_comp.a1 = new_comp.b1 = 0x0;
26374 wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
26375
26376cal_try:
26377 wlc_phy_rx_iq_est_nphy(pi, est, 0x4000, 32, 0);
26378
26379 new_comp = old_comp;
26380
26381 for (curr_core = 0; curr_core < pi->pubpi.phy_corenum; curr_core++) {
26382
26383 if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
26384 iq = est[curr_core].iq_prod;
26385 ii = est[curr_core].i_pwr;
26386 qq = est[curr_core].q_pwr;
26387 } else if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
26388 iq = est[curr_core].iq_prod;
26389 ii = est[curr_core].i_pwr;
26390 qq = est[curr_core].q_pwr;
26391 } else {
26392 continue;
26393 }
26394
26395 if ((ii + qq) < NPHY_MIN_RXIQ_PWR) {
26396 bcmerror = -EBADE;
26397 break;
26398 }
26399
26400 iq_nbits = wlc_phy_nbits(iq);
26401 qq_nbits = wlc_phy_nbits(qq);
26402
26403 arsh = 10 - (30 - iq_nbits);
26404 if (arsh >= 0) {
26405 a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
26406 temp = (s32) (ii >> arsh);
26407 if (temp == 0) {
26408 bcmerror = -EBADE;
26409 break;
26410 }
26411 } else {
26412 a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
26413 temp = (s32) (ii << -arsh);
26414 if (temp == 0) {
26415 bcmerror = -EBADE;
26416 break;
26417 }
26418 }
26419
26420 a /= temp;
26421
26422 brsh = qq_nbits - 31 + 20;
26423 if (brsh >= 0) {
26424 b = (qq << (31 - qq_nbits));
26425 temp = (s32) (ii >> brsh);
26426 if (temp == 0) {
26427 bcmerror = -EBADE;
26428 break;
26429 }
26430 } else {
26431 b = (qq << (31 - qq_nbits));
26432 temp = (s32) (ii << -brsh);
26433 if (temp == 0) {
26434 bcmerror = -EBADE;
26435 break;
26436 }
26437 }
26438 b /= temp;
26439 b -= a * a;
26440 b = (s32) int_sqrt((unsigned long) b);
26441 b -= (1 << 10);
26442
26443 if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
26444 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
26445 new_comp.a0 = (s16) a & 0x3ff;
26446 new_comp.b0 = (s16) b & 0x3ff;
26447 } else {
26448
26449 new_comp.a0 = (s16) b & 0x3ff;
26450 new_comp.b0 = (s16) a & 0x3ff;
26451 }
26452 }
26453 if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
26454 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
26455 new_comp.a1 = (s16) a & 0x3ff;
26456 new_comp.b1 = (s16) b & 0x3ff;
26457 } else {
26458
26459 new_comp.a1 = (s16) b & 0x3ff;
26460 new_comp.b1 = (s16) a & 0x3ff;
26461 }
26462 }
26463 }
26464
26465 if (bcmerror != 0) {
26466 printk(KERN_DEBUG "%s: Failed, cnt = %d\n", __func__,
26467 cal_retry);
26468
26469 if (cal_retry < CAL_RETRY_CNT) {
26470 cal_retry++;
26471 goto cal_try;
26472 }
26473
26474 new_comp = old_comp;
26475 }
26476
26477 wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
26478}
26479
26480static void wlc_phy_rxcal_radio_setup_nphy(struct brcms_phy *pi, u8 rx_core)
26481{
26482 u16 offtune_val;
26483 u16 bias_g = 0;
26484 u16 bias_a = 0;
26485
26486 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
26487 if (rx_core == PHY_CORE_0) {
26488 if (CHSPEC_IS5G(pi->radio_chanspec)) {
26489 pi->tx_rx_cal_radio_saveregs[0] =
26490 read_radio_reg(pi,
26491 RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP);
26492 pi->tx_rx_cal_radio_saveregs[1] =
26493 read_radio_reg(pi,
26494 RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN);
26495
26496 write_radio_reg(pi,
26497 RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
26498 0x3);
26499 write_radio_reg(pi,
26500 RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
26501 0xaf);
26502
26503 } else {
26504 pi->tx_rx_cal_radio_saveregs[0] =
26505 read_radio_reg(pi,
26506 RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP);
26507 pi->tx_rx_cal_radio_saveregs[1] =
26508 read_radio_reg(pi,
26509 RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN);
26510
26511 write_radio_reg(
26512 pi,
26513 RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
26514 0x3);
26515 write_radio_reg(
26516 pi,
26517 RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
26518 0x7f);
26519 }
26520
26521 } else {
26522 if (CHSPEC_IS5G(pi->radio_chanspec)) {
26523 pi->tx_rx_cal_radio_saveregs[0] =
26524 read_radio_reg(pi,
26525 RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP);
26526 pi->tx_rx_cal_radio_saveregs[1] =
26527 read_radio_reg(pi,
26528 RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN);
26529
26530 write_radio_reg(
26531 pi,
26532 RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
26533 0x3);
26534 write_radio_reg(
26535 pi,
26536 RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
26537 0xaf);
26538
26539 } else {
26540 pi->tx_rx_cal_radio_saveregs[0] =
26541 read_radio_reg(pi,
26542 RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP);
26543 pi->tx_rx_cal_radio_saveregs[1] =
26544 read_radio_reg(pi,
26545 RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN);
26546
26547 write_radio_reg(pi,
26548 RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
26549 0x3);
26550 write_radio_reg(pi,
26551 RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
26552 0x7f);
26553 }
26554 }
26555
26556 } else {
26557 if (rx_core == PHY_CORE_0) {
26558 pi->tx_rx_cal_radio_saveregs[0] =
26559 read_radio_reg(pi,
26560 RADIO_2056_TX_RXIQCAL_TXMUX |
26561 RADIO_2056_TX1);
26562 pi->tx_rx_cal_radio_saveregs[1] =
26563 read_radio_reg(pi,
26564 RADIO_2056_RX_RXIQCAL_RXMUX |
26565 RADIO_2056_RX0);
26566
26567 if (pi->pubpi.radiorev >= 5) {
26568 pi->tx_rx_cal_radio_saveregs[2] =
26569 read_radio_reg(pi,
26570 RADIO_2056_RX_RXSPARE2 |
26571 RADIO_2056_RX0);
26572 pi->tx_rx_cal_radio_saveregs[3] =
26573 read_radio_reg(pi,
26574 RADIO_2056_TX_TXSPARE2 |
26575 RADIO_2056_TX1);
26576 }
26577
26578 if (CHSPEC_IS5G(pi->radio_chanspec)) {
26579
26580 if (pi->pubpi.radiorev >= 5) {
26581 pi->tx_rx_cal_radio_saveregs[4] =
26582 read_radio_reg(pi,
26583 RADIO_2056_RX_LNAA_MASTER
26584 | RADIO_2056_RX0);
26585
26586 write_radio_reg(
26587 pi,
26588 RADIO_2056_RX_LNAA_MASTER
26589 | RADIO_2056_RX0, 0x40);
26590
26591 write_radio_reg(pi,
26592 RADIO_2056_TX_TXSPARE2 |
26593 RADIO_2056_TX1, bias_a);
26594
26595 write_radio_reg(pi,
26596 RADIO_2056_RX_RXSPARE2 |
26597 RADIO_2056_RX0, bias_a);
26598 } else {
26599 pi->tx_rx_cal_radio_saveregs[4] =
26600 read_radio_reg(pi,
26601 RADIO_2056_RX_LNAA_TUNE
26602 | RADIO_2056_RX0);
26603
26604 offtune_val =
26605 (pi->tx_rx_cal_radio_saveregs
26606 [2] & 0xF0) >> 8;
26607 offtune_val =
26608 (offtune_val <= 0x7) ? 0xF : 0;
26609
26610 mod_radio_reg(pi,
26611 RADIO_2056_RX_LNAA_TUNE |
26612 RADIO_2056_RX0, 0xF0,
26613 (offtune_val << 8));
26614 }
26615
26616 write_radio_reg(pi,
26617 RADIO_2056_TX_RXIQCAL_TXMUX |
26618 RADIO_2056_TX1, 0x9);
26619 write_radio_reg(pi,
26620 RADIO_2056_RX_RXIQCAL_RXMUX |
26621 RADIO_2056_RX0, 0x9);
26622 } else {
26623 if (pi->pubpi.radiorev >= 5) {
26624 pi->tx_rx_cal_radio_saveregs[4] =
26625 read_radio_reg(
26626 pi,
26627 RADIO_2056_RX_LNAG_MASTER
26628 | RADIO_2056_RX0);
26629
26630 write_radio_reg(
26631 pi,
26632 RADIO_2056_RX_LNAG_MASTER
26633 | RADIO_2056_RX0, 0x40);
26634
26635 write_radio_reg(
26636 pi,
26637 RADIO_2056_TX_TXSPARE2
26638 |
26639 RADIO_2056_TX1, bias_g);
26640
26641 write_radio_reg(
26642 pi,
26643 RADIO_2056_RX_RXSPARE2
26644 |
26645 RADIO_2056_RX0, bias_g);
26646
26647 } else {
26648 pi->tx_rx_cal_radio_saveregs[4] =
26649 read_radio_reg(
26650 pi,
26651 RADIO_2056_RX_LNAG_TUNE
26652 | RADIO_2056_RX0);
26653
26654 offtune_val =
26655 (pi->
26656 tx_rx_cal_radio_saveregs[2] &
26657 0xF0) >> 8;
26658 offtune_val =
26659 (offtune_val <= 0x7) ? 0xF : 0;
26660
26661 mod_radio_reg(pi,
26662 RADIO_2056_RX_LNAG_TUNE |
26663 RADIO_2056_RX0, 0xF0,
26664 (offtune_val << 8));
26665 }
26666
26667 write_radio_reg(pi,
26668 RADIO_2056_TX_RXIQCAL_TXMUX |
26669 RADIO_2056_TX1, 0x6);
26670 write_radio_reg(pi,
26671 RADIO_2056_RX_RXIQCAL_RXMUX |
26672 RADIO_2056_RX0, 0x6);
26673 }
26674
26675 } else {
26676 pi->tx_rx_cal_radio_saveregs[0] =
26677 read_radio_reg(pi,
26678 RADIO_2056_TX_RXIQCAL_TXMUX |
26679 RADIO_2056_TX0);
26680 pi->tx_rx_cal_radio_saveregs[1] =
26681 read_radio_reg(pi,
26682 RADIO_2056_RX_RXIQCAL_RXMUX |
26683 RADIO_2056_RX1);
26684
26685 if (pi->pubpi.radiorev >= 5) {
26686 pi->tx_rx_cal_radio_saveregs[2] =
26687 read_radio_reg(pi,
26688 RADIO_2056_RX_RXSPARE2 |
26689 RADIO_2056_RX1);
26690 pi->tx_rx_cal_radio_saveregs[3] =
26691 read_radio_reg(pi,
26692 RADIO_2056_TX_TXSPARE2 |
26693 RADIO_2056_TX0);
26694 }
26695
26696 if (CHSPEC_IS5G(pi->radio_chanspec)) {
26697
26698 if (pi->pubpi.radiorev >= 5) {
26699 pi->tx_rx_cal_radio_saveregs[4] =
26700 read_radio_reg(
26701 pi,
26702 RADIO_2056_RX_LNAA_MASTER
26703 | RADIO_2056_RX1);
26704
26705 write_radio_reg(
26706 pi,
26707 RADIO_2056_RX_LNAA_MASTER |
26708 RADIO_2056_RX1, 0x40);
26709
26710 write_radio_reg(
26711 pi,
26712 RADIO_2056_TX_TXSPARE2
26713 |
26714 RADIO_2056_TX0, bias_a);
26715
26716 write_radio_reg(
26717 pi,
26718 RADIO_2056_RX_RXSPARE2
26719 |
26720 RADIO_2056_RX1, bias_a);
26721 } else {
26722 pi->tx_rx_cal_radio_saveregs[4] =
26723 read_radio_reg(
26724 pi,
26725 RADIO_2056_RX_LNAA_TUNE
26726 | RADIO_2056_RX1);
26727
26728 offtune_val =
26729 (pi->
26730 tx_rx_cal_radio_saveregs[2] &
26731 0xF0) >> 8;
26732 offtune_val =
26733 (offtune_val <= 0x7) ? 0xF : 0;
26734
26735 mod_radio_reg(pi,
26736 RADIO_2056_RX_LNAA_TUNE |
26737 RADIO_2056_RX1, 0xF0,
26738 (offtune_val << 8));
26739 }
26740
26741 write_radio_reg(pi,
26742 RADIO_2056_TX_RXIQCAL_TXMUX |
26743 RADIO_2056_TX0, 0x9);
26744 write_radio_reg(pi,
26745 RADIO_2056_RX_RXIQCAL_RXMUX |
26746 RADIO_2056_RX1, 0x9);
26747 } else {
26748 if (pi->pubpi.radiorev >= 5) {
26749 pi->tx_rx_cal_radio_saveregs[4] =
26750 read_radio_reg(
26751 pi,
26752 RADIO_2056_RX_LNAG_MASTER
26753 | RADIO_2056_RX1);
26754
26755 write_radio_reg(
26756 pi,
26757 RADIO_2056_RX_LNAG_MASTER
26758 | RADIO_2056_RX1, 0x40);
26759
26760 write_radio_reg(
26761 pi,
26762 RADIO_2056_TX_TXSPARE2
26763 |
26764 RADIO_2056_TX0, bias_g);
26765
26766 write_radio_reg(
26767 pi,
26768 RADIO_2056_RX_RXSPARE2
26769 |
26770 RADIO_2056_RX1, bias_g);
26771 } else {
26772 pi->tx_rx_cal_radio_saveregs[4] =
26773 read_radio_reg(
26774 pi,
26775 RADIO_2056_RX_LNAG_TUNE
26776 | RADIO_2056_RX1);
26777
26778 offtune_val =
26779 (pi->
26780 tx_rx_cal_radio_saveregs[2] &
26781 0xF0) >> 8;
26782 offtune_val =
26783 (offtune_val <= 0x7) ? 0xF : 0;
26784
26785 mod_radio_reg(pi,
26786 RADIO_2056_RX_LNAG_TUNE |
26787 RADIO_2056_RX1, 0xF0,
26788 (offtune_val << 8));
26789 }
26790
26791 write_radio_reg(pi,
26792 RADIO_2056_TX_RXIQCAL_TXMUX |
26793 RADIO_2056_TX0, 0x6);
26794 write_radio_reg(pi,
26795 RADIO_2056_RX_RXIQCAL_RXMUX |
26796 RADIO_2056_RX1, 0x6);
26797 }
26798 }
26799 }
26800}
26801
26802static void wlc_phy_rxcal_radio_cleanup_nphy(struct brcms_phy *pi, u8 rx_core)
26803{
26804 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
26805 if (rx_core == PHY_CORE_0) {
26806 if (CHSPEC_IS5G(pi->radio_chanspec)) {
26807 write_radio_reg(
26808 pi,
26809 RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
26810 pi->
26811 tx_rx_cal_radio_saveregs[0]);
26812 write_radio_reg(
26813 pi,
26814 RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
26815 pi->
26816 tx_rx_cal_radio_saveregs[1]);
26817
26818 } else {
26819 write_radio_reg(
26820 pi,
26821 RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
26822 pi->
26823 tx_rx_cal_radio_saveregs[0]);
26824 write_radio_reg(
26825 pi,
26826 RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
26827 pi->
26828 tx_rx_cal_radio_saveregs[1]);
26829 }
26830
26831 } else {
26832 if (CHSPEC_IS5G(pi->radio_chanspec)) {
26833 write_radio_reg(
26834 pi,
26835 RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
26836 pi->
26837 tx_rx_cal_radio_saveregs[0]);
26838 write_radio_reg(
26839 pi,
26840 RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
26841 pi->
26842 tx_rx_cal_radio_saveregs[1]);
26843
26844 } else {
26845 write_radio_reg(
26846 pi,
26847 RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
26848 pi->
26849 tx_rx_cal_radio_saveregs[0]);
26850 write_radio_reg(
26851 pi,
26852 RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
26853 pi->
26854 tx_rx_cal_radio_saveregs[1]);
26855 }
26856 }
26857
26858 } else {
26859 if (rx_core == PHY_CORE_0) {
26860 write_radio_reg(pi,
26861 RADIO_2056_TX_RXIQCAL_TXMUX |
26862 RADIO_2056_TX1,
26863 pi->tx_rx_cal_radio_saveregs[0]);
26864
26865 write_radio_reg(pi,
26866 RADIO_2056_RX_RXIQCAL_RXMUX |
26867 RADIO_2056_RX0,
26868 pi->tx_rx_cal_radio_saveregs[1]);
26869
26870 if (pi->pubpi.radiorev >= 5) {
26871 write_radio_reg(pi,
26872 RADIO_2056_RX_RXSPARE2 |
26873 RADIO_2056_RX0,
26874 pi->
26875 tx_rx_cal_radio_saveregs[2]);
26876
26877 write_radio_reg(pi,
26878 RADIO_2056_TX_TXSPARE2 |
26879 RADIO_2056_TX1,
26880 pi->
26881 tx_rx_cal_radio_saveregs[3]);
26882 }
26883
26884 if (CHSPEC_IS5G(pi->radio_chanspec)) {
26885 if (pi->pubpi.radiorev >= 5)
26886 write_radio_reg(
26887 pi,
26888 RADIO_2056_RX_LNAA_MASTER
26889 | RADIO_2056_RX0,
26890 pi->
26891 tx_rx_cal_radio_saveregs
26892 [4]);
26893 else
26894 write_radio_reg(
26895 pi,
26896 RADIO_2056_RX_LNAA_TUNE
26897 | RADIO_2056_RX0,
26898 pi->
26899 tx_rx_cal_radio_saveregs
26900 [4]);
26901 } else {
26902 if (pi->pubpi.radiorev >= 5)
26903 write_radio_reg(
26904 pi,
26905 RADIO_2056_RX_LNAG_MASTER
26906 | RADIO_2056_RX0,
26907 pi->
26908 tx_rx_cal_radio_saveregs
26909 [4]);
26910 else
26911 write_radio_reg(
26912 pi,
26913 RADIO_2056_RX_LNAG_TUNE
26914 | RADIO_2056_RX0,
26915 pi->
26916 tx_rx_cal_radio_saveregs
26917 [4]);
26918 }
26919
26920 } else {
26921 write_radio_reg(pi,
26922 RADIO_2056_TX_RXIQCAL_TXMUX |
26923 RADIO_2056_TX0,
26924 pi->tx_rx_cal_radio_saveregs[0]);
26925
26926 write_radio_reg(pi,
26927 RADIO_2056_RX_RXIQCAL_RXMUX |
26928 RADIO_2056_RX1,
26929 pi->tx_rx_cal_radio_saveregs[1]);
26930
26931 if (pi->pubpi.radiorev >= 5) {
26932 write_radio_reg(pi,
26933 RADIO_2056_RX_RXSPARE2 |
26934 RADIO_2056_RX1,
26935 pi->
26936 tx_rx_cal_radio_saveregs[2]);
26937
26938 write_radio_reg(pi,
26939 RADIO_2056_TX_TXSPARE2 |
26940 RADIO_2056_TX0,
26941 pi->
26942 tx_rx_cal_radio_saveregs[3]);
26943 }
26944
26945 if (CHSPEC_IS5G(pi->radio_chanspec)) {
26946 if (pi->pubpi.radiorev >= 5)
26947 write_radio_reg(
26948 pi,
26949 RADIO_2056_RX_LNAA_MASTER
26950 | RADIO_2056_RX1,
26951 pi->
26952 tx_rx_cal_radio_saveregs
26953 [4]);
26954 else
26955 write_radio_reg(
26956 pi,
26957 RADIO_2056_RX_LNAA_TUNE
26958 | RADIO_2056_RX1,
26959 pi->
26960 tx_rx_cal_radio_saveregs
26961 [4]);
26962 } else {
26963 if (pi->pubpi.radiorev >= 5)
26964 write_radio_reg(
26965 pi,
26966 RADIO_2056_RX_LNAG_MASTER
26967 | RADIO_2056_RX1,
26968 pi->
26969 tx_rx_cal_radio_saveregs
26970 [4]);
26971 else
26972 write_radio_reg(
26973 pi,
26974 RADIO_2056_RX_LNAG_TUNE
26975 | RADIO_2056_RX1,
26976 pi->
26977 tx_rx_cal_radio_saveregs
26978 [4]);
26979 }
26980 }
26981 }
26982}
26983
26984static void wlc_phy_rxcal_physetup_nphy(struct brcms_phy *pi, u8 rx_core)
26985{
26986 u8 tx_core;
26987 u16 rx_antval, tx_antval;
26988
26989 if (NREV_GE(pi->pubpi.phy_rev, 7))
26990 tx_core = rx_core;
26991 else
26992 tx_core = (rx_core == PHY_CORE_0) ? 1 : 0;
26993
26994 pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa2);
26995 pi->tx_rx_cal_phy_saveregs[1] =
26996 read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7);
26997 pi->tx_rx_cal_phy_saveregs[2] =
26998 read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5);
26999 pi->tx_rx_cal_phy_saveregs[3] = read_phy_reg(pi, 0x91);
27000 pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x92);
27001 pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x7a);
27002 pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x7d);
27003 pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0xe7);
27004 pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0xec);
27005 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
27006 pi->tx_rx_cal_phy_saveregs[11] = read_phy_reg(pi, 0x342);
27007 pi->tx_rx_cal_phy_saveregs[12] = read_phy_reg(pi, 0x343);
27008 pi->tx_rx_cal_phy_saveregs[13] = read_phy_reg(pi, 0x346);
27009 pi->tx_rx_cal_phy_saveregs[14] = read_phy_reg(pi, 0x347);
27010 }
27011
27012 pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
27013 pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
27014 mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
27015 0x29b, (0x1 << 0), (0) << 0);
27016
27017 mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
27018 0x29b, (0x1 << 0), (0) << 0);
27019
27020 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
27021
27022 mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
27023
27024 mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << (1 - rx_core)) << 12);
27025
27026 } else {
27027
27028 mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
27029 mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
27030 mod_phy_reg(pi, 0xa2, (0xf << 4), (1 << rx_core) << 4);
27031 mod_phy_reg(pi, 0xa2, (0xf << 8), (1 << rx_core) << 8);
27032 }
27033
27034 mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7), (0x1 << 2), 0);
27035 mod_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
27036 (0x1 << 2), (0x1 << 2));
27037 if (NREV_LT(pi->pubpi.phy_rev, 7)) {
27038 mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
27039 (0x1 << 0) | (0x1 << 1), 0);
27040 mod_phy_reg(pi, (rx_core == PHY_CORE_0) ?
27041 0x8f : 0xa5,
27042 (0x1 << 0) | (0x1 << 1), (0x1 << 0) | (0x1 << 1));
27043 }
27044
27045 wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 0,
27046 RADIO_MIMO_CORESEL_CORE1 |
27047 RADIO_MIMO_CORESEL_CORE2);
27048
27049 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
27050 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
27051 0, 0, 0,
27052 NPHY_REV7_RFCTRLOVERRIDE_ID0);
27053 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 0, 0, 0,
27054 NPHY_REV7_RFCTRLOVERRIDE_ID1);
27055 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 1, 0, 0,
27056 NPHY_REV7_RFCTRLOVERRIDE_ID1);
27057 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 1, 0, 0,
27058 NPHY_REV7_RFCTRLOVERRIDE_ID1);
27059 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0, 0,
27060 NPHY_REV7_RFCTRLOVERRIDE_ID2);
27061 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0, 0,
27062 NPHY_REV7_RFCTRLOVERRIDE_ID1);
27063 if (CHSPEC_IS40(pi->radio_chanspec))
27064 wlc_phy_rfctrl_override_nphy_rev7(
27065 pi,
27066 (0x1 << 7),
27067 2, 0, 0,
27068 NPHY_REV7_RFCTRLOVERRIDE_ID1);
27069 else
27070 wlc_phy_rfctrl_override_nphy_rev7(
27071 pi,
27072 (0x1 << 7),
27073 0, 0, 0,
27074 NPHY_REV7_RFCTRLOVERRIDE_ID1);
27075
27076 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
27077 0, 0, 0,
27078 NPHY_REV7_RFCTRLOVERRIDE_ID1);
27079 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0, 0,
27080 NPHY_REV7_RFCTRLOVERRIDE_ID1);
27081 } else {
27082 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 3, 0);
27083 }
27084
27085 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
27086
27087 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
27088
27089 wlc_phy_rfctrlintc_override_nphy(pi,
27090 NPHY_RfctrlIntc_override_TRSW,
27091 0x1, rx_core + 1);
27092 } else {
27093
27094 if (rx_core == PHY_CORE_0) {
27095 rx_antval = 0x1;
27096 tx_antval = 0x8;
27097 } else {
27098 rx_antval = 0x4;
27099 tx_antval = 0x2;
27100 }
27101
27102 wlc_phy_rfctrlintc_override_nphy(pi,
27103 NPHY_RfctrlIntc_override_TRSW,
27104 rx_antval, rx_core + 1);
27105 wlc_phy_rfctrlintc_override_nphy(pi,
27106 NPHY_RfctrlIntc_override_TRSW,
27107 tx_antval, tx_core + 1);
27108 }
27109}
27110
27111static void wlc_phy_rxcal_phycleanup_nphy(struct brcms_phy *pi, u8 rx_core)
27112{
27113
27114 write_phy_reg(pi, 0xa2, pi->tx_rx_cal_phy_saveregs[0]);
27115 write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7,
27116 pi->tx_rx_cal_phy_saveregs[1]);
27117 write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
27118 pi->tx_rx_cal_phy_saveregs[2]);
27119 write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[3]);
27120 write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[4]);
27121
27122 write_phy_reg(pi, 0x7a, pi->tx_rx_cal_phy_saveregs[5]);
27123 write_phy_reg(pi, 0x7d, pi->tx_rx_cal_phy_saveregs[6]);
27124 write_phy_reg(pi, 0xe7, pi->tx_rx_cal_phy_saveregs[7]);
27125 write_phy_reg(pi, 0xec, pi->tx_rx_cal_phy_saveregs[8]);
27126 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
27127 write_phy_reg(pi, 0x342, pi->tx_rx_cal_phy_saveregs[11]);
27128 write_phy_reg(pi, 0x343, pi->tx_rx_cal_phy_saveregs[12]);
27129 write_phy_reg(pi, 0x346, pi->tx_rx_cal_phy_saveregs[13]);
27130 write_phy_reg(pi, 0x347, pi->tx_rx_cal_phy_saveregs[14]);
27131 }
27132
27133 write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
27134 write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
27135}
27136
27137static void
27138wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rx_core,
27139 u16 *rxgain, u8 cal_type)
27140{
27141
27142 u16 num_samps;
27143 struct phy_iq_est est[PHY_CORE_MAX];
27144 u8 tx_core;
27145 struct nphy_iq_comp save_comp, zero_comp;
27146 u32 i_pwr, q_pwr, curr_pwr, optim_pwr = 0, prev_pwr = 0,
27147 thresh_pwr = 10000;
27148 s16 desired_log2_pwr, actual_log2_pwr, delta_pwr;
27149 bool gainctrl_done = false;
27150 u8 mix_tia_gain = 3;
27151 s8 optim_gaintbl_index = 0, prev_gaintbl_index = 0;
27152 s8 curr_gaintbl_index = 3;
27153 u8 gainctrl_dirn = NPHY_RXCAL_GAIN_INIT;
27154 const struct nphy_ipa_txrxgain *nphy_rxcal_gaintbl;
27155 u16 hpvga, lpf_biq1, lpf_biq0, lna2, lna1;
27156 int fine_gain_idx;
27157 s8 txpwrindex;
27158 u16 nphy_rxcal_txgain[2];
27159
27160 if (NREV_GE(pi->pubpi.phy_rev, 7))
27161 tx_core = rx_core;
27162 else
27163 tx_core = 1 - rx_core;
27164
27165 num_samps = 1024;
27166 desired_log2_pwr = (cal_type == 0) ? 13 : 13;
27167
27168 wlc_phy_rx_iq_coeffs_nphy(pi, 0, &save_comp);
27169 zero_comp.a0 = zero_comp.b0 = zero_comp.a1 = zero_comp.b1 = 0x0;
27170 wlc_phy_rx_iq_coeffs_nphy(pi, 1, &zero_comp);
27171
27172 if (CHSPEC_IS5G(pi->radio_chanspec)) {
27173 if (NREV_GE(pi->pubpi.phy_rev, 7))
27174 mix_tia_gain = 3;
27175 else if (NREV_GE(pi->pubpi.phy_rev, 4))
27176 mix_tia_gain = 4;
27177 else
27178 mix_tia_gain = 6;
27179 if (NREV_GE(pi->pubpi.phy_rev, 7))
27180 nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz_rev7;
27181 else
27182 nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz;
27183 } else {
27184 if (NREV_GE(pi->pubpi.phy_rev, 7))
27185 nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz_rev7;
27186 else
27187 nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz;
27188 }
27189
27190 do {
27191
27192 hpvga = (NREV_GE(pi->pubpi.phy_rev, 7)) ?
27193 0 : nphy_rxcal_gaintbl[curr_gaintbl_index].hpvga;
27194 lpf_biq1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq1;
27195 lpf_biq0 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq0;
27196 lna2 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna2;
27197 lna1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna1;
27198 txpwrindex = nphy_rxcal_gaintbl[curr_gaintbl_index].txpwrindex;
27199
27200 if (NREV_GE(pi->pubpi.phy_rev, 7))
27201 wlc_phy_rfctrl_override_1tomany_nphy(
27202 pi,
27203 NPHY_REV7_RfctrlOverride_cmd_rxgain,
27204 ((lpf_biq1 << 12) |
27205 (lpf_biq0 << 8) |
27206 (mix_tia_gain << 4) | (lna2 << 2)
27207 | lna1), 0x3, 0);
27208 else
27209 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
27210 ((hpvga << 12) |
27211 (lpf_biq1 << 10) |
27212 (lpf_biq0 << 8) |
27213 (mix_tia_gain << 4) |
27214 (lna2 << 2) | lna1), 0x3,
27215 0);
27216
27217 pi->nphy_rxcal_pwr_idx[tx_core] = txpwrindex;
27218
27219 if (txpwrindex == -1) {
27220 nphy_rxcal_txgain[0] = 0x8ff0 | pi->nphy_gmval;
27221 nphy_rxcal_txgain[1] = 0x8ff0 | pi->nphy_gmval;
27222 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
27223 2, 0x110, 16,
27224 nphy_rxcal_txgain);
27225 } else {
27226 wlc_phy_txpwr_index_nphy(pi, tx_core + 1, txpwrindex,
27227 false);
27228 }
27229
27230 wlc_phy_tx_tone_nphy(pi, (CHSPEC_IS40(pi->radio_chanspec)) ?
27231 NPHY_RXCAL_TONEFREQ_40MHz :
27232 NPHY_RXCAL_TONEFREQ_20MHz,
27233 NPHY_RXCAL_TONEAMP, 0, cal_type, false);
27234
27235 wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
27236 i_pwr = (est[rx_core].i_pwr + num_samps / 2) / num_samps;
27237 q_pwr = (est[rx_core].q_pwr + num_samps / 2) / num_samps;
27238 curr_pwr = i_pwr + q_pwr;
27239
27240 switch (gainctrl_dirn) {
27241 case NPHY_RXCAL_GAIN_INIT:
27242 if (curr_pwr > thresh_pwr) {
27243 gainctrl_dirn = NPHY_RXCAL_GAIN_DOWN;
27244 prev_gaintbl_index = curr_gaintbl_index;
27245 curr_gaintbl_index--;
27246 } else {
27247 gainctrl_dirn = NPHY_RXCAL_GAIN_UP;
27248 prev_gaintbl_index = curr_gaintbl_index;
27249 curr_gaintbl_index++;
27250 }
27251 break;
27252
27253 case NPHY_RXCAL_GAIN_UP:
27254 if (curr_pwr > thresh_pwr) {
27255 gainctrl_done = true;
27256 optim_pwr = prev_pwr;
27257 optim_gaintbl_index = prev_gaintbl_index;
27258 } else {
27259 prev_gaintbl_index = curr_gaintbl_index;
27260 curr_gaintbl_index++;
27261 }
27262 break;
27263
27264 case NPHY_RXCAL_GAIN_DOWN:
27265 if (curr_pwr > thresh_pwr) {
27266 prev_gaintbl_index = curr_gaintbl_index;
27267 curr_gaintbl_index--;
27268 } else {
27269 gainctrl_done = true;
27270 optim_pwr = curr_pwr;
27271 optim_gaintbl_index = curr_gaintbl_index;
27272 }
27273 break;
27274
27275 default:
27276 break;
27277 }
27278
27279 if ((curr_gaintbl_index < 0) ||
27280 (curr_gaintbl_index > NPHY_IPA_RXCAL_MAXGAININDEX)) {
27281 gainctrl_done = true;
27282 optim_pwr = curr_pwr;
27283 optim_gaintbl_index = prev_gaintbl_index;
27284 } else {
27285 prev_pwr = curr_pwr;
27286 }
27287
27288 wlc_phy_stopplayback_nphy(pi);
27289 } while (!gainctrl_done);
27290
27291 hpvga = nphy_rxcal_gaintbl[optim_gaintbl_index].hpvga;
27292 lpf_biq1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq1;
27293 lpf_biq0 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq0;
27294 lna2 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna2;
27295 lna1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna1;
27296 txpwrindex = nphy_rxcal_gaintbl[optim_gaintbl_index].txpwrindex;
27297
27298 actual_log2_pwr = wlc_phy_nbits(optim_pwr);
27299 delta_pwr = desired_log2_pwr - actual_log2_pwr;
27300
27301 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
27302 fine_gain_idx = (int)lpf_biq1 + delta_pwr;
27303
27304 if (fine_gain_idx + (int)lpf_biq0 > 10)
27305 lpf_biq1 = 10 - lpf_biq0;
27306 else
27307 lpf_biq1 = (u16) max(fine_gain_idx, 0);
27308
27309 wlc_phy_rfctrl_override_1tomany_nphy(
27310 pi,
27311 NPHY_REV7_RfctrlOverride_cmd_rxgain,
27312 ((lpf_biq1 << 12) |
27313 (lpf_biq0 << 8) |
27314 (mix_tia_gain << 4) |
27315 (lna2 << 2) | lna1), 0x3,
27316 0);
27317 } else {
27318 hpvga = (u16) max(min(((int)hpvga) + delta_pwr, 10), 0);
27319 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
27320 ((hpvga << 12) |
27321 (lpf_biq1 << 10) |
27322 (lpf_biq0 << 8) |
27323 (mix_tia_gain << 4) |
27324 (lna2 << 2) |
27325 lna1), 0x3, 0);
27326 }
27327
27328 if (rxgain != NULL) {
27329 *rxgain++ = lna1;
27330 *rxgain++ = lna2;
27331 *rxgain++ = mix_tia_gain;
27332 *rxgain++ = lpf_biq0;
27333 *rxgain++ = lpf_biq1;
27334 *rxgain = hpvga;
27335 }
27336
27337 wlc_phy_rx_iq_coeffs_nphy(pi, 1, &save_comp);
27338}
27339
27340static void
27341wlc_phy_rxcal_gainctrl_nphy(struct brcms_phy *pi, u8 rx_core, u16 *rxgain,
27342 u8 cal_type)
27343{
27344 wlc_phy_rxcal_gainctrl_nphy_rev5(pi, rx_core, rxgain, cal_type);
27345}
27346
27347static u8
27348wlc_phy_rc_sweep_nphy(struct brcms_phy *pi, u8 core_idx, u8 loopback_type)
27349{
27350 u32 target_bws[2] = { 9500, 21000 };
27351 u32 ref_tones[2] = { 3000, 6000 };
27352 u32 target_bw, ref_tone;
27353
27354 u32 target_pwr_ratios[2] = { 28606, 18468 };
27355 u32 target_pwr_ratio, pwr_ratio, last_pwr_ratio = 0;
27356
27357 u16 start_rccal_ovr_val = 128;
27358 u16 txlpf_rccal_lpc_ovr_val = 128;
27359 u16 rxlpf_rccal_hpc_ovr_val = 159;
27360
27361 u16 orig_txlpf_rccal_lpc_ovr_val;
27362 u16 orig_rxlpf_rccal_hpc_ovr_val;
27363 u16 radio_addr_offset_rx;
27364 u16 radio_addr_offset_tx;
27365 u16 orig_dcBypass;
27366 u16 orig_RxStrnFilt40Num[6];
27367 u16 orig_RxStrnFilt40Den[4];
27368 u16 orig_rfctrloverride[2];
27369 u16 orig_rfctrlauxreg[2];
27370 u16 orig_rfctrlrssiothers;
27371 u16 tx_lpf_bw = 4;
27372
27373 u16 rx_lpf_bw, rx_lpf_bws[2] = { 2, 4 };
27374 u16 lpf_hpc = 7, hpvga_hpc = 7;
27375
27376 s8 rccal_stepsize;
27377 u16 rccal_val, last_rccal_val = 0, best_rccal_val = 0;
27378 u32 ref_iq_vals = 0, target_iq_vals = 0;
27379 u16 num_samps, log_num_samps = 10;
27380 struct phy_iq_est est[PHY_CORE_MAX];
27381
27382 if (NREV_GE(pi->pubpi.phy_rev, 7))
27383 return 0;
27384
27385 num_samps = (1 << log_num_samps);
27386
27387 if (CHSPEC_IS40(pi->radio_chanspec)) {
27388 target_bw = target_bws[1];
27389 target_pwr_ratio = target_pwr_ratios[1];
27390 ref_tone = ref_tones[1];
27391 rx_lpf_bw = rx_lpf_bws[1];
27392 } else {
27393 target_bw = target_bws[0];
27394 target_pwr_ratio = target_pwr_ratios[0];
27395 ref_tone = ref_tones[0];
27396 rx_lpf_bw = rx_lpf_bws[0];
27397 }
27398
27399 if (core_idx == 0) {
27400 radio_addr_offset_rx = RADIO_2056_RX0;
27401 radio_addr_offset_tx =
27402 (loopback_type == 0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
27403 } else {
27404 radio_addr_offset_rx = RADIO_2056_RX1;
27405 radio_addr_offset_tx =
27406 (loopback_type == 0) ? RADIO_2056_TX1 : RADIO_2056_TX0;
27407 }
27408
27409 orig_txlpf_rccal_lpc_ovr_val =
27410 read_radio_reg(pi,
27411 (RADIO_2056_TX_TXLPF_RCCAL |
27412 radio_addr_offset_tx));
27413 orig_rxlpf_rccal_hpc_ovr_val =
27414 read_radio_reg(pi,
27415 (RADIO_2056_RX_RXLPF_RCCAL_HPC |
27416 radio_addr_offset_rx));
27417
27418 orig_dcBypass = ((read_phy_reg(pi, 0x48) >> 8) & 1);
27419
27420 orig_RxStrnFilt40Num[0] = read_phy_reg(pi, 0x267);
27421 orig_RxStrnFilt40Num[1] = read_phy_reg(pi, 0x268);
27422 orig_RxStrnFilt40Num[2] = read_phy_reg(pi, 0x269);
27423 orig_RxStrnFilt40Den[0] = read_phy_reg(pi, 0x26a);
27424 orig_RxStrnFilt40Den[1] = read_phy_reg(pi, 0x26b);
27425 orig_RxStrnFilt40Num[3] = read_phy_reg(pi, 0x26c);
27426 orig_RxStrnFilt40Num[4] = read_phy_reg(pi, 0x26d);
27427 orig_RxStrnFilt40Num[5] = read_phy_reg(pi, 0x26e);
27428 orig_RxStrnFilt40Den[2] = read_phy_reg(pi, 0x26f);
27429 orig_RxStrnFilt40Den[3] = read_phy_reg(pi, 0x270);
27430
27431 orig_rfctrloverride[0] = read_phy_reg(pi, 0xe7);
27432 orig_rfctrloverride[1] = read_phy_reg(pi, 0xec);
27433 orig_rfctrlauxreg[0] = read_phy_reg(pi, 0xf8);
27434 orig_rfctrlauxreg[1] = read_phy_reg(pi, 0xfa);
27435 orig_rfctrlrssiothers = read_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d);
27436
27437 write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
27438 txlpf_rccal_lpc_ovr_val);
27439
27440 write_radio_reg(pi,
27441 (RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
27442 rxlpf_rccal_hpc_ovr_val);
27443
27444 mod_phy_reg(pi, 0x48, (0x1 << 8), (0x1 << 8));
27445
27446 write_phy_reg(pi, 0x267, 0x02d4);
27447 write_phy_reg(pi, 0x268, 0x0000);
27448 write_phy_reg(pi, 0x269, 0x0000);
27449 write_phy_reg(pi, 0x26a, 0x0000);
27450 write_phy_reg(pi, 0x26b, 0x0000);
27451 write_phy_reg(pi, 0x26c, 0x02d4);
27452 write_phy_reg(pi, 0x26d, 0x0000);
27453 write_phy_reg(pi, 0x26e, 0x0000);
27454 write_phy_reg(pi, 0x26f, 0x0000);
27455 write_phy_reg(pi, 0x270, 0x0000);
27456
27457 or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 8));
27458 or_phy_reg(pi, (core_idx == 0) ? 0xec : 0xe7, (0x1 << 15));
27459 or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 9));
27460 or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 10));
27461
27462 mod_phy_reg(pi, (core_idx == 0) ? 0xfa : 0xf8,
27463 (0x7 << 10), (tx_lpf_bw << 10));
27464 mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
27465 (0x7 << 0), (hpvga_hpc << 0));
27466 mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
27467 (0x7 << 4), (lpf_hpc << 4));
27468 mod_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d,
27469 (0x7 << 8), (rx_lpf_bw << 8));
27470
27471 rccal_stepsize = 16;
27472 rccal_val = start_rccal_ovr_val + rccal_stepsize;
27473
27474 while (rccal_stepsize >= 0) {
27475 write_radio_reg(pi,
27476 (RADIO_2056_RX_RXLPF_RCCAL_LPC |
27477 radio_addr_offset_rx), rccal_val);
27478
27479 if (rccal_stepsize == 16) {
27480
27481 wlc_phy_tx_tone_nphy(pi, ref_tone, NPHY_RXCAL_TONEAMP,
27482 0, 1, false);
27483 udelay(2);
27484
27485 wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
27486
27487 if (core_idx == 0)
27488 ref_iq_vals =
27489 max_t(u32, (est[0].i_pwr +
27490 est[0].q_pwr) >>
27491 (log_num_samps + 1),
27492 1);
27493 else
27494 ref_iq_vals =
27495 max_t(u32, (est[1].i_pwr +
27496 est[1].q_pwr) >>
27497 (log_num_samps + 1),
27498 1);
27499
27500 wlc_phy_tx_tone_nphy(pi, target_bw, NPHY_RXCAL_TONEAMP,
27501 0, 1, false);
27502 udelay(2);
27503 }
27504
27505 wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
27506
27507 if (core_idx == 0)
27508 target_iq_vals = (est[0].i_pwr + est[0].q_pwr) >>
27509 (log_num_samps + 1);
27510 else
27511 target_iq_vals =
27512 (est[1].i_pwr +
27513 est[1].q_pwr) >> (log_num_samps + 1);
27514
27515 pwr_ratio = (uint) ((target_iq_vals << 16) / ref_iq_vals);
27516
27517 if (rccal_stepsize == 0)
27518 rccal_stepsize--;
27519 else if (rccal_stepsize == 1) {
27520 last_rccal_val = rccal_val;
27521 rccal_val += (pwr_ratio > target_pwr_ratio) ? 1 : -1;
27522 last_pwr_ratio = pwr_ratio;
27523 rccal_stepsize--;
27524 } else {
27525 rccal_stepsize = (rccal_stepsize >> 1);
27526 rccal_val += ((pwr_ratio > target_pwr_ratio) ?
27527 rccal_stepsize : (-rccal_stepsize));
27528 }
27529
27530 if (rccal_stepsize == -1) {
27531 best_rccal_val =
27532 (abs((int)last_pwr_ratio -
27533 (int)target_pwr_ratio) <
27534 abs((int)pwr_ratio -
27535 (int)target_pwr_ratio)) ? last_rccal_val :
27536 rccal_val;
27537
27538 if (CHSPEC_IS40(pi->radio_chanspec)) {
27539 if ((best_rccal_val > 140)
27540 || (best_rccal_val < 135))
27541 best_rccal_val = 138;
27542 } else {
27543 if ((best_rccal_val > 142)
27544 || (best_rccal_val < 137))
27545 best_rccal_val = 140;
27546 }
27547
27548 write_radio_reg(pi,
27549 (RADIO_2056_RX_RXLPF_RCCAL_LPC |
27550 radio_addr_offset_rx), best_rccal_val);
27551 }
27552 }
27553
27554 wlc_phy_stopplayback_nphy(pi);
27555
27556 write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
27557 orig_txlpf_rccal_lpc_ovr_val);
27558 write_radio_reg(pi,
27559 (RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
27560 orig_rxlpf_rccal_hpc_ovr_val);
27561
27562 mod_phy_reg(pi, 0x48, (0x1 << 8), (orig_dcBypass << 8));
27563
27564 write_phy_reg(pi, 0x267, orig_RxStrnFilt40Num[0]);
27565 write_phy_reg(pi, 0x268, orig_RxStrnFilt40Num[1]);
27566 write_phy_reg(pi, 0x269, orig_RxStrnFilt40Num[2]);
27567 write_phy_reg(pi, 0x26a, orig_RxStrnFilt40Den[0]);
27568 write_phy_reg(pi, 0x26b, orig_RxStrnFilt40Den[1]);
27569 write_phy_reg(pi, 0x26c, orig_RxStrnFilt40Num[3]);
27570 write_phy_reg(pi, 0x26d, orig_RxStrnFilt40Num[4]);
27571 write_phy_reg(pi, 0x26e, orig_RxStrnFilt40Num[5]);
27572 write_phy_reg(pi, 0x26f, orig_RxStrnFilt40Den[2]);
27573 write_phy_reg(pi, 0x270, orig_RxStrnFilt40Den[3]);
27574
27575 write_phy_reg(pi, 0xe7, orig_rfctrloverride[0]);
27576 write_phy_reg(pi, 0xec, orig_rfctrloverride[1]);
27577 write_phy_reg(pi, 0xf8, orig_rfctrlauxreg[0]);
27578 write_phy_reg(pi, 0xfa, orig_rfctrlauxreg[1]);
27579 write_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d, orig_rfctrlrssiothers);
27580
27581 pi->nphy_anarxlpf_adjusted = false;
27582
27583 return best_rccal_val - 0x80;
27584}
27585
27586#define WAIT_FOR_SCOPE 4000
27587static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi,
27588 struct nphy_txgains target_gain,
27589 u8 cal_type, bool debug)
27590{
27591 u16 orig_BBConfig;
27592 u8 core_no, rx_core;
27593 u8 best_rccal[2];
27594 u16 gain_save[2];
27595 u16 cal_gain[2];
27596 struct nphy_iqcal_params cal_params[2];
27597 u8 rxcore_state;
27598 s8 rxlpf_rccal_hpc, txlpf_rccal_lpc;
27599 s8 txlpf_idac;
27600 bool phyhang_avoid_state = false;
27601 bool skip_rxiqcal = false;
27602
27603 orig_BBConfig = read_phy_reg(pi, 0x01);
27604 mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
27605
27606 wlc_phy_stay_in_carriersearch_nphy(pi, true);
27607
27608 if (NREV_GE(pi->pubpi.phy_rev, 4)) {
27609 phyhang_avoid_state = pi->phyhang_avoid;
27610 pi->phyhang_avoid = false;
27611 }
27612
27613 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
27614
27615 for (core_no = 0; core_no <= 1; core_no++) {
27616 wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
27617 &cal_params[core_no]);
27618 cal_gain[core_no] = cal_params[core_no].cal_gain;
27619 }
27620
27621 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
27622
27623 rxcore_state = wlc_phy_rxcore_getstate_nphy(
27624 (struct brcms_phy_pub *) pi);
27625
27626 for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
27627
27628 skip_rxiqcal =
27629 ((rxcore_state & (1 << rx_core)) == 0) ? true : false;
27630
27631 wlc_phy_rxcal_physetup_nphy(pi, rx_core);
27632
27633 wlc_phy_rxcal_radio_setup_nphy(pi, rx_core);
27634
27635 if ((!skip_rxiqcal) && ((cal_type == 0) || (cal_type == 2))) {
27636
27637 wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, 0);
27638
27639 wlc_phy_tx_tone_nphy(pi,
27640 (CHSPEC_IS40(
27641 pi->radio_chanspec)) ?
27642 NPHY_RXCAL_TONEFREQ_40MHz :
27643 NPHY_RXCAL_TONEFREQ_20MHz,
27644 NPHY_RXCAL_TONEAMP, 0, cal_type,
27645 false);
27646
27647 if (debug)
27648 mdelay(WAIT_FOR_SCOPE);
27649
27650 wlc_phy_calc_rx_iq_comp_nphy(pi, rx_core + 1);
27651 wlc_phy_stopplayback_nphy(pi);
27652 }
27653
27654 if (((cal_type == 1) || (cal_type == 2))
27655 && NREV_LT(pi->pubpi.phy_rev, 7)) {
27656
27657 if (rx_core == PHY_CORE_1) {
27658
27659 if (rxcore_state == 1)
27660 wlc_phy_rxcore_setstate_nphy(
27661 (struct brcms_phy_pub *) pi, 3);
27662
27663 wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL,
27664 1);
27665
27666 best_rccal[rx_core] =
27667 wlc_phy_rc_sweep_nphy(pi, rx_core, 1);
27668 pi->nphy_rccal_value = best_rccal[rx_core];
27669
27670 if (rxcore_state == 1)
27671 wlc_phy_rxcore_setstate_nphy(
27672 (struct brcms_phy_pub *) pi,
27673 rxcore_state);
27674 }
27675 }
27676
27677 wlc_phy_rxcal_radio_cleanup_nphy(pi, rx_core);
27678
27679 wlc_phy_rxcal_phycleanup_nphy(pi, rx_core);
27680 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
27681 }
27682
27683 if ((cal_type == 1) || (cal_type == 2)) {
27684
27685 best_rccal[0] = best_rccal[1];
27686 write_radio_reg(pi,
27687 (RADIO_2056_RX_RXLPF_RCCAL_LPC |
27688 RADIO_2056_RX0), (best_rccal[0] | 0x80));
27689
27690 for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
27691 rxlpf_rccal_hpc =
27692 (((int)best_rccal[rx_core] - 12) >> 1) + 10;
27693 txlpf_rccal_lpc = ((int)best_rccal[rx_core] - 12) + 10;
27694
27695 if (PHY_IPA(pi)) {
27696 txlpf_rccal_lpc +=
27697 (pi->bw == WL_CHANSPEC_BW_40) ? 24 : 12;
27698 txlpf_idac = (pi->bw == WL_CHANSPEC_BW_40) ?
27699 0x0e : 0x13;
27700 WRITE_RADIO_REG2(pi, RADIO_2056, TX, rx_core,
27701 TXLPF_IDAC_4, txlpf_idac);
27702 }
27703
27704 rxlpf_rccal_hpc = max(min_t(u8, rxlpf_rccal_hpc, 31),
27705 0);
27706 txlpf_rccal_lpc = max(min_t(u8, txlpf_rccal_lpc, 31),
27707 0);
27708
27709 write_radio_reg(pi, (RADIO_2056_RX_RXLPF_RCCAL_HPC |
27710 ((rx_core ==
27711 PHY_CORE_0) ? RADIO_2056_RX0 :
27712 RADIO_2056_RX1)),
27713 (rxlpf_rccal_hpc | 0x80));
27714
27715 write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL |
27716 ((rx_core ==
27717 PHY_CORE_0) ? RADIO_2056_TX0 :
27718 RADIO_2056_TX1)),
27719 (txlpf_rccal_lpc | 0x80));
27720 }
27721 }
27722
27723 write_phy_reg(pi, 0x01, orig_BBConfig);
27724
27725 wlc_phy_resetcca_nphy(pi);
27726
27727 if (NREV_GE(pi->pubpi.phy_rev, 7))
27728 wlc_phy_rfctrl_override_1tomany_nphy(
27729 pi,
27730 NPHY_REV7_RfctrlOverride_cmd_rxgain,
27731 0, 0x3, 1);
27732 else
27733 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
27734
27735 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
27736
27737 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
27738 gain_save);
27739
27740 if (NREV_GE(pi->pubpi.phy_rev, 4))
27741 pi->phyhang_avoid = phyhang_avoid_state;
27742
27743 wlc_phy_stay_in_carriersearch_nphy(pi, false);
27744
27745 return 0;
27746}
27747
27748static int
27749wlc_phy_cal_rxiq_nphy_rev2(struct brcms_phy *pi,
27750 struct nphy_txgains target_gain, bool debug)
27751{
27752 struct phy_iq_est est[PHY_CORE_MAX];
27753 u8 core_num, rx_core, tx_core;
27754 u16 lna_vals[] = { 0x3, 0x3, 0x1 };
27755 u16 hpf1_vals[] = { 0x7, 0x2, 0x0 };
27756 u16 hpf2_vals[] = { 0x2, 0x0, 0x0 };
27757 s16 curr_hpf1, curr_hpf2, curr_hpf, curr_lna;
27758 s16 desired_log2_pwr, actual_log2_pwr, hpf_change;
27759 u16 orig_RfseqCoreActv, orig_AfectrlCore, orig_AfectrlOverride;
27760 u16 orig_RfctrlIntcRx, orig_RfctrlIntcTx;
27761 u16 num_samps;
27762 u32 i_pwr, q_pwr, tot_pwr[3];
27763 u8 gain_pass, use_hpf_num;
27764 u16 mask, val1, val2;
27765 u16 core_no;
27766 u16 gain_save[2];
27767 u16 cal_gain[2];
27768 struct nphy_iqcal_params cal_params[2];
27769 u8 phy_bw;
27770 int bcmerror = 0;
27771 bool first_playtone = true;
27772
27773 wlc_phy_stay_in_carriersearch_nphy(pi, true);
27774
27775 if (NREV_LT(pi->pubpi.phy_rev, 2))
27776 wlc_phy_reapply_txcal_coeffs_nphy(pi);
27777
27778 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
27779
27780 for (core_no = 0; core_no <= 1; core_no++) {
27781 wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
27782 &cal_params[core_no]);
27783 cal_gain[core_no] = cal_params[core_no].cal_gain;
27784 }
27785
27786 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
27787
27788 num_samps = 1024;
27789 desired_log2_pwr = 13;
27790
27791 for (core_num = 0; core_num < 2; core_num++) {
27792
27793 rx_core = core_num;
27794 tx_core = 1 - core_num;
27795
27796 orig_RfseqCoreActv = read_phy_reg(pi, 0xa2);
27797 orig_AfectrlCore = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
27798 0xa6 : 0xa7);
27799 orig_AfectrlOverride = read_phy_reg(pi, 0xa5);
27800 orig_RfctrlIntcRx = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
27801 0x91 : 0x92);
27802 orig_RfctrlIntcTx = read_phy_reg(pi, (tx_core == PHY_CORE_0) ?
27803 0x91 : 0x92);
27804
27805 mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
27806 mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
27807
27808 or_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
27809 ((0x1 << 1) | (0x1 << 2)));
27810 or_phy_reg(pi, 0xa5, ((0x1 << 1) | (0x1 << 2)));
27811
27812 if (((pi->nphy_rxcalparams) & 0xff000000))
27813 write_phy_reg(pi,
27814 (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
27815 (CHSPEC_IS5G(pi->radio_chanspec) ?
27816 0x140 : 0x110));
27817 else
27818 write_phy_reg(pi,
27819 (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
27820 (CHSPEC_IS5G(pi->radio_chanspec) ?
27821 0x180 : 0x120));
27822
27823 write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 : 0x92,
27824 (CHSPEC_IS5G(pi->radio_chanspec) ? 0x148 :
27825 0x114));
27826
27827 mask = RADIO_2055_COUPLE_RX_MASK | RADIO_2055_COUPLE_TX_MASK;
27828 if (rx_core == PHY_CORE_0) {
27829 val1 = RADIO_2055_COUPLE_RX_MASK;
27830 val2 = RADIO_2055_COUPLE_TX_MASK;
27831 } else {
27832 val1 = RADIO_2055_COUPLE_TX_MASK;
27833 val2 = RADIO_2055_COUPLE_RX_MASK;
27834 }
27835
27836 if ((pi->nphy_rxcalparams & 0x10000)) {
27837 mod_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, mask,
27838 val1);
27839 mod_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, mask,
27840 val2);
27841 }
27842
27843 for (gain_pass = 0; gain_pass < 4; gain_pass++) {
27844
27845 if (debug)
27846 mdelay(WAIT_FOR_SCOPE);
27847
27848 if (gain_pass < 3) {
27849 curr_lna = lna_vals[gain_pass];
27850 curr_hpf1 = hpf1_vals[gain_pass];
27851 curr_hpf2 = hpf2_vals[gain_pass];
27852 } else {
27853
27854 if (tot_pwr[1] > 10000) {
27855 curr_lna = lna_vals[2];
27856 curr_hpf1 = hpf1_vals[2];
27857 curr_hpf2 = hpf2_vals[2];
27858 use_hpf_num = 1;
27859 curr_hpf = curr_hpf1;
27860 actual_log2_pwr =
27861 wlc_phy_nbits(tot_pwr[2]);
27862 } else {
27863 if (tot_pwr[0] > 10000) {
27864 curr_lna = lna_vals[1];
27865 curr_hpf1 = hpf1_vals[1];
27866 curr_hpf2 = hpf2_vals[1];
27867 use_hpf_num = 1;
27868 curr_hpf = curr_hpf1;
27869 actual_log2_pwr =
27870 wlc_phy_nbits(
27871 tot_pwr[1]);
27872 } else {
27873 curr_lna = lna_vals[0];
27874 curr_hpf1 = hpf1_vals[0];
27875 curr_hpf2 = hpf2_vals[0];
27876 use_hpf_num = 2;
27877 curr_hpf = curr_hpf2;
27878 actual_log2_pwr =
27879 wlc_phy_nbits(
27880 tot_pwr[0]);
27881 }
27882 }
27883
27884 hpf_change = desired_log2_pwr - actual_log2_pwr;
27885 curr_hpf += hpf_change;
27886 curr_hpf = max(min_t(u16, curr_hpf, 10), 0);
27887 if (use_hpf_num == 1)
27888 curr_hpf1 = curr_hpf;
27889 else
27890 curr_hpf2 = curr_hpf;
27891 }
27892
27893 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10),
27894 ((curr_hpf2 << 8) |
27895 (curr_hpf1 << 4) |
27896 (curr_lna << 2)), 0x3, 0);
27897 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
27898
27899 wlc_phy_stopplayback_nphy(pi);
27900
27901 if (first_playtone) {
27902 bcmerror = wlc_phy_tx_tone_nphy(pi, 4000,
27903 (u16) (pi->nphy_rxcalparams &
27904 0xffff), 0, 0, true);
27905 first_playtone = false;
27906 } else {
27907 phy_bw = (CHSPEC_IS40(pi->radio_chanspec)) ?
27908 40 : 20;
27909 wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff,
27910 0, 0, 0, true);
27911 }
27912
27913 if (bcmerror == 0) {
27914 if (gain_pass < 3) {
27915
27916 wlc_phy_rx_iq_est_nphy(pi, est,
27917 num_samps, 32,
27918 0);
27919 i_pwr = (est[rx_core].i_pwr +
27920 num_samps / 2) / num_samps;
27921 q_pwr = (est[rx_core].q_pwr +
27922 num_samps / 2) / num_samps;
27923 tot_pwr[gain_pass] = i_pwr + q_pwr;
27924 } else {
27925
27926 wlc_phy_calc_rx_iq_comp_nphy(pi,
27927 (1 <<
27928 rx_core));
27929 }
27930
27931 wlc_phy_stopplayback_nphy(pi);
27932 }
27933
27934 if (bcmerror != 0)
27935 break;
27936 }
27937
27938 and_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, ~mask);
27939 and_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, ~mask);
27940
27941 write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 :
27942 0x92, orig_RfctrlIntcTx);
27943 write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x91 :
27944 0x92, orig_RfctrlIntcRx);
27945 write_phy_reg(pi, 0xa5, orig_AfectrlOverride);
27946 write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 :
27947 0xa7, orig_AfectrlCore);
27948 write_phy_reg(pi, 0xa2, orig_RfseqCoreActv);
27949
27950 if (bcmerror != 0)
27951 break;
27952 }
27953
27954 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10), 0, 0x3, 1);
27955 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
27956
27957 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
27958 gain_save);
27959
27960 wlc_phy_stay_in_carriersearch_nphy(pi, false);
27961
27962 return bcmerror;
27963}
27964
27965int
27966wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain,
27967 u8 cal_type, bool debug)
27968{
27969 if (NREV_GE(pi->pubpi.phy_rev, 7))
27970 cal_type = 0;
27971
27972 if (NREV_GE(pi->pubpi.phy_rev, 3))
27973 return wlc_phy_cal_rxiq_nphy_rev3(pi, target_gain, cal_type,
27974 debug);
27975 else
27976 return wlc_phy_cal_rxiq_nphy_rev2(pi, target_gain, debug);
27977}
27978
27979void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi)
27980{
27981 uint core;
27982 u32 txgain;
27983 u16 rad_gain, dac_gain, bbmult, m1m2;
27984 u8 txpi[2], chan_freq_range;
27985 s32 rfpwr_offset;
27986
27987 if (pi->phyhang_avoid)
27988 wlc_phy_stay_in_carriersearch_nphy(pi, true);
27989
27990 if (pi->sh->sromrev < 4) {
27991 txpi[0] = txpi[1] = 72;
27992 } else {
27993
27994 chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
27995 switch (chan_freq_range) {
27996 case WL_CHAN_FREQ_RANGE_2G:
27997 txpi[0] = pi->nphy_txpid2g[0];
27998 txpi[1] = pi->nphy_txpid2g[1];
27999 break;
28000 case WL_CHAN_FREQ_RANGE_5GL:
28001 txpi[0] = pi->nphy_txpid5gl[0];
28002 txpi[1] = pi->nphy_txpid5gl[1];
28003 break;
28004 case WL_CHAN_FREQ_RANGE_5GM:
28005 txpi[0] = pi->nphy_txpid5g[0];
28006 txpi[1] = pi->nphy_txpid5g[1];
28007 break;
28008 case WL_CHAN_FREQ_RANGE_5GH:
28009 txpi[0] = pi->nphy_txpid5gh[0];
28010 txpi[1] = pi->nphy_txpid5gh[1];
28011 break;
28012 default:
28013 txpi[0] = txpi[1] = 91;
28014 break;
28015 }
28016 }
28017
28018 if (NREV_GE(pi->pubpi.phy_rev, 7))
28019 txpi[0] = txpi[1] = 30;
28020 else if (NREV_GE(pi->pubpi.phy_rev, 3))
28021 txpi[0] = txpi[1] = 40;
28022
28023 if (NREV_LT(pi->pubpi.phy_rev, 7)) {
28024
28025 if ((txpi[0] < 40) || (txpi[0] > 100) ||
28026 (txpi[1] < 40) || (txpi[1] > 100))
28027 txpi[0] = txpi[1] = 91;
28028 }
28029
28030 pi->nphy_txpwrindex[PHY_CORE_0].index_internal = txpi[0];
28031 pi->nphy_txpwrindex[PHY_CORE_1].index_internal = txpi[1];
28032 pi->nphy_txpwrindex[PHY_CORE_0].index_internal_save = txpi[0];
28033 pi->nphy_txpwrindex[PHY_CORE_1].index_internal_save = txpi[1];
28034
28035 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
28036 uint phyrev = pi->pubpi.phy_rev;
28037
28038 if (NREV_GE(phyrev, 3)) {
28039 if (PHY_IPA(pi)) {
28040 u32 *tx_gaintbl =
28041 wlc_phy_get_ipa_gaintbl_nphy(pi);
28042 txgain = tx_gaintbl[txpi[core]];
28043 } else {
28044 if (CHSPEC_IS5G(pi->radio_chanspec)) {
28045 if (NREV_IS(phyrev, 3)) {
28046 txgain =
28047 nphy_tpc_5GHz_txgain_rev3
28048 [txpi[core]];
28049 } else if (NREV_IS(phyrev, 4)) {
28050 txgain = (
28051 pi->srom_fem5g.extpagain ==
28052 3) ?
28053 nphy_tpc_5GHz_txgain_HiPwrEPA
28054 [txpi[core]] :
28055 nphy_tpc_5GHz_txgain_rev4
28056 [txpi[core]];
28057 } else {
28058 txgain =
28059 nphy_tpc_5GHz_txgain_rev5
28060 [txpi[core]];
28061 }
28062 } else {
28063 if (NREV_GE(phyrev, 5) &&
28064 (pi->srom_fem2g.extpagain == 3)) {
28065 txgain =
28066 nphy_tpc_txgain_HiPwrEPA
28067 [txpi[core]];
28068 } else {
28069 txgain = nphy_tpc_txgain_rev3
28070 [txpi[core]];
28071 }
28072 }
28073 }
28074 } else {
28075 txgain = nphy_tpc_txgain[txpi[core]];
28076 }
28077
28078 if (NREV_GE(phyrev, 3))
28079 rad_gain = (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1);
28080 else
28081 rad_gain = (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1);
28082
28083 if (NREV_GE(phyrev, 7))
28084 dac_gain = (txgain >> 8) & ((1 << (10 - 8 + 1)) - 1);
28085 else
28086 dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
28087
28088 bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
28089
28090 if (NREV_GE(phyrev, 3))
28091 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
28092 0xa5), (0x1 << 8), (0x1 << 8));
28093 else
28094 mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
28095
28096 write_phy_reg(pi, (core == PHY_CORE_0) ? 0xaa : 0xab, dac_gain);
28097
28098 wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
28099 &rad_gain);
28100
28101 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
28102 m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
28103 m1m2 |= ((core == PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0));
28104 wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
28105
28106 if (PHY_IPA(pi)) {
28107 wlc_phy_table_read_nphy(pi,
28108 (core ==
28109 PHY_CORE_0 ?
28110 NPHY_TBL_ID_CORE1TXPWRCTL :
28111 NPHY_TBL_ID_CORE2TXPWRCTL), 1,
28112 576 + txpi[core], 32,
28113 &rfpwr_offset);
28114
28115 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
28116 0x29b, (0x1ff << 4),
28117 ((s16) rfpwr_offset) << 4);
28118
28119 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
28120 0x29b, (0x1 << 2), (1) << 2);
28121
28122 }
28123 }
28124
28125 and_phy_reg(pi, 0xbf, (u16) (~(0x1f << 0)));
28126
28127 if (pi->phyhang_avoid)
28128 wlc_phy_stay_in_carriersearch_nphy(pi, false);
28129}
28130
28131static void
28132wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max, u16 *pwr_offset,
28133 u8 tmp_max_pwr, u8 rate_start,
28134 u8 rate_end)
28135{
28136 u8 rate;
28137 u8 word_num, nibble_num;
28138 u8 tmp_nibble;
28139
28140 for (rate = rate_start; rate <= rate_end; rate++) {
28141 word_num = (rate - rate_start) >> 2;
28142 nibble_num = (rate - rate_start) & 0x3;
28143 tmp_nibble = (pwr_offset[word_num] >> 4 * nibble_num) & 0xf;
28144
28145 srom_max[rate] = tmp_max_pwr - 2 * tmp_nibble;
28146 }
28147}
28148
28149static void
28150wlc_phy_txpwr_nphy_po_apply(u8 *srom_max, u8 pwr_offset,
28151 u8 rate_start, u8 rate_end)
28152{
28153 u8 rate;
28154
28155 for (rate = rate_start; rate <= rate_end; rate++)
28156 srom_max[rate] -= 2 * pwr_offset;
28157}
28158
28159void
28160wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
28161 u8 rate_mcs_end, u8 rate_ofdm_start)
28162{
28163 u8 rate1, rate2;
28164
28165 rate2 = rate_ofdm_start;
28166 for (rate1 = rate_mcs_start; rate1 <= rate_mcs_end - 1; rate1++) {
28167 power[rate1] = power[rate2];
28168 rate2 += (rate1 == rate_mcs_start) ? 2 : 1;
28169 }
28170 power[rate_mcs_end] = power[rate_mcs_end - 1];
28171}
28172
28173void
28174wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, u8 rate_ofdm_start,
28175 u8 rate_ofdm_end, u8 rate_mcs_start)
28176{
28177 u8 rate1, rate2;
28178
28179 for (rate1 = rate_ofdm_start, rate2 = rate_mcs_start;
28180 rate1 <= rate_ofdm_end; rate1++, rate2++) {
28181 power[rate1] = power[rate2];
28182 if (rate1 == rate_ofdm_start)
28183 power[++rate1] = power[rate2];
28184 }
28185}
28186
28187void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi)
28188{
28189 uint rate1, rate2, band_num;
28190 u8 tmp_bw40po = 0, tmp_cddpo = 0, tmp_stbcpo = 0;
28191 u8 tmp_max_pwr = 0;
28192 u16 pwr_offsets1[2], *pwr_offsets2 = NULL;
28193 u8 *tx_srom_max_rate = NULL;
28194
28195 for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP);
28196 band_num++) {
28197 switch (band_num) {
28198 case 0:
28199
28200 tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_2g,
28201 pi->nphy_pwrctrl_info[1].max_pwr_2g);
28202
28203 pwr_offsets1[0] = pi->cck2gpo;
28204 wlc_phy_txpwr_nphy_srom_convert(pi->tx_srom_max_rate_2g,
28205 pwr_offsets1,
28206 tmp_max_pwr,
28207 TXP_FIRST_CCK,
28208 TXP_LAST_CCK);
28209
28210 pwr_offsets1[0] = (u16) (pi->ofdm2gpo & 0xffff);
28211 pwr_offsets1[1] =
28212 (u16) (pi->ofdm2gpo >> 16) & 0xffff;
28213
28214 pwr_offsets2 = pi->mcs2gpo;
28215
28216 tmp_cddpo = pi->cdd2gpo;
28217 tmp_stbcpo = pi->stbc2gpo;
28218 tmp_bw40po = pi->bw402gpo;
28219
28220 tx_srom_max_rate = pi->tx_srom_max_rate_2g;
28221 break;
28222 case 1:
28223
28224 tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gm,
28225 pi->nphy_pwrctrl_info[1].max_pwr_5gm);
28226
28227 pwr_offsets1[0] = (u16) (pi->ofdm5gpo & 0xffff);
28228 pwr_offsets1[1] =
28229 (u16) (pi->ofdm5gpo >> 16) & 0xffff;
28230
28231 pwr_offsets2 = pi->mcs5gpo;
28232
28233 tmp_cddpo = pi->cdd5gpo;
28234 tmp_stbcpo = pi->stbc5gpo;
28235 tmp_bw40po = pi->bw405gpo;
28236
28237 tx_srom_max_rate = pi->tx_srom_max_rate_5g_mid;
28238 break;
28239 case 2:
28240
28241 tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gl,
28242 pi->nphy_pwrctrl_info[1].max_pwr_5gl);
28243
28244 pwr_offsets1[0] = (u16) (pi->ofdm5glpo & 0xffff);
28245 pwr_offsets1[1] =
28246 (u16) (pi->ofdm5glpo >> 16) & 0xffff;
28247
28248 pwr_offsets2 = pi->mcs5glpo;
28249
28250 tmp_cddpo = pi->cdd5glpo;
28251 tmp_stbcpo = pi->stbc5glpo;
28252 tmp_bw40po = pi->bw405glpo;
28253
28254 tx_srom_max_rate = pi->tx_srom_max_rate_5g_low;
28255 break;
28256 case 3:
28257
28258 tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gh,
28259 pi->nphy_pwrctrl_info[1].max_pwr_5gh);
28260
28261 pwr_offsets1[0] = (u16) (pi->ofdm5ghpo & 0xffff);
28262 pwr_offsets1[1] =
28263 (u16) (pi->ofdm5ghpo >> 16) & 0xffff;
28264
28265 pwr_offsets2 = pi->mcs5ghpo;
28266
28267 tmp_cddpo = pi->cdd5ghpo;
28268 tmp_stbcpo = pi->stbc5ghpo;
28269 tmp_bw40po = pi->bw405ghpo;
28270
28271 tx_srom_max_rate = pi->tx_srom_max_rate_5g_hi;
28272 break;
28273 }
28274
28275 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets1,
28276 tmp_max_pwr, TXP_FIRST_OFDM,
28277 TXP_LAST_OFDM);
28278
28279 wlc_phy_ofdm_to_mcs_powers_nphy(tx_srom_max_rate,
28280 TXP_FIRST_MCS_20_SISO,
28281 TXP_LAST_MCS_20_SISO,
28282 TXP_FIRST_OFDM);
28283
28284 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
28285 tmp_max_pwr,
28286 TXP_FIRST_MCS_20_CDD,
28287 TXP_LAST_MCS_20_CDD);
28288
28289 if (NREV_GE(pi->pubpi.phy_rev, 3))
28290 wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
28291 TXP_FIRST_MCS_20_CDD,
28292 TXP_LAST_MCS_20_CDD);
28293
28294 wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
28295 TXP_FIRST_OFDM_20_CDD,
28296 TXP_LAST_OFDM_20_CDD,
28297 TXP_FIRST_MCS_20_CDD);
28298
28299 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
28300 tmp_max_pwr,
28301 TXP_FIRST_MCS_20_STBC,
28302 TXP_LAST_MCS_20_STBC);
28303
28304 if (NREV_GE(pi->pubpi.phy_rev, 3))
28305 wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
28306 tmp_stbcpo,
28307 TXP_FIRST_MCS_20_STBC,
28308 TXP_LAST_MCS_20_STBC);
28309
28310 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
28311 &pwr_offsets2[2], tmp_max_pwr,
28312 TXP_FIRST_MCS_20_SDM,
28313 TXP_LAST_MCS_20_SDM);
28314
28315 if (NPHY_IS_SROM_REINTERPRET) {
28316
28317 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
28318 &pwr_offsets2[4],
28319 tmp_max_pwr,
28320 TXP_FIRST_MCS_40_SISO,
28321 TXP_LAST_MCS_40_SISO);
28322
28323 wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
28324 TXP_FIRST_OFDM_40_SISO,
28325 TXP_LAST_OFDM_40_SISO,
28326 TXP_FIRST_MCS_40_SISO);
28327
28328 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
28329 &pwr_offsets2[4],
28330 tmp_max_pwr,
28331 TXP_FIRST_MCS_40_CDD,
28332 TXP_LAST_MCS_40_CDD);
28333
28334 wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
28335 TXP_FIRST_MCS_40_CDD,
28336 TXP_LAST_MCS_40_CDD);
28337
28338 wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
28339 TXP_FIRST_OFDM_40_CDD,
28340 TXP_LAST_OFDM_40_CDD,
28341 TXP_FIRST_MCS_40_CDD);
28342
28343 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
28344 &pwr_offsets2[4],
28345 tmp_max_pwr,
28346 TXP_FIRST_MCS_40_STBC,
28347 TXP_LAST_MCS_40_STBC);
28348
28349 wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
28350 tmp_stbcpo,
28351 TXP_FIRST_MCS_40_STBC,
28352 TXP_LAST_MCS_40_STBC);
28353
28354 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
28355 &pwr_offsets2[6],
28356 tmp_max_pwr,
28357 TXP_FIRST_MCS_40_SDM,
28358 TXP_LAST_MCS_40_SDM);
28359 } else {
28360
28361 for (rate1 = TXP_FIRST_OFDM_40_SISO, rate2 =
28362 TXP_FIRST_OFDM;
28363 rate1 <= TXP_LAST_MCS_40_SDM;
28364 rate1++, rate2++)
28365 tx_srom_max_rate[rate1] =
28366 tx_srom_max_rate[rate2];
28367 }
28368
28369 if (NREV_GE(pi->pubpi.phy_rev, 3))
28370 wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
28371 tmp_bw40po,
28372 TXP_FIRST_OFDM_40_SISO,
28373 TXP_LAST_MCS_40_SDM);
28374
28375 tx_srom_max_rate[TXP_MCS_32] =
28376 tx_srom_max_rate[TXP_FIRST_MCS_40_CDD];
28377 }
28378
28379 return;
28380}
28381
28382void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi)
28383{
28384 u8 tx_pwr_ctrl_state;
28385 wlc_phy_txpwr_limit_to_tbl_nphy(pi);
28386 wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
28387
28388 tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
28389
28390 if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
28391 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
28392 (void)R_REG(&pi->regs->maccontrol);
28393 udelay(1);
28394 }
28395
28396 wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
28397
28398 if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
28399 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
28400}
28401
28402static bool wlc_phy_txpwr_ison_nphy(struct brcms_phy *pi)
28403{
28404 return read_phy_reg((pi), 0x1e7) & ((0x1 << 15) |
28405 (0x1 << 14) | (0x1 << 13));
28406}
28407
28408u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi)
28409{
28410 u16 tmp;
28411 u16 pwr_idx[2];
28412
28413 if (wlc_phy_txpwr_ison_nphy(pi)) {
28414 pwr_idx[0] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_0);
28415 pwr_idx[1] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_1);
28416
28417 tmp = (pwr_idx[0] << 8) | pwr_idx[1];
28418 } else {
28419 tmp = ((pi->nphy_txpwrindex[PHY_CORE_0].index_internal & 0xff)
28420 << 8) |
28421 (pi->nphy_txpwrindex[PHY_CORE_1].index_internal & 0xff);
28422 }
28423
28424 return tmp;
28425}
28426
28427void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi)
28428{
28429 if (PHY_IPA(pi)
28430 && (pi->nphy_force_papd_cal
28431 || (wlc_phy_txpwr_ison_nphy(pi)
28432 &&
28433 (((u32)
28434 abs(wlc_phy_txpwr_idx_cur_get_nphy(pi, 0) -
28435 pi->nphy_papd_tx_gain_at_last_cal[0]) >= 4)
28436 || ((u32)
28437 abs(wlc_phy_txpwr_idx_cur_get_nphy(pi, 1) -
28438 pi->nphy_papd_tx_gain_at_last_cal[1]) >= 4)))))
28439 wlc_phy_a4(pi, true);
28440}
28441
28442void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type)
28443{
28444 u16 mask = 0, val = 0, ishw = 0;
28445 u8 ctr;
28446 uint core;
28447 u32 tbl_offset;
28448 u32 tbl_len;
28449 u16 regval[84];
28450
28451 if (pi->phyhang_avoid)
28452 wlc_phy_stay_in_carriersearch_nphy(pi, true);
28453
28454 switch (ctrl_type) {
28455 case PHY_TPC_HW_OFF:
28456 case PHY_TPC_HW_ON:
28457 pi->nphy_txpwrctrl = ctrl_type;
28458 break;
28459 default:
28460 break;
28461 }
28462
28463 if (ctrl_type == PHY_TPC_HW_OFF) {
28464 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28465
28466 if (wlc_phy_txpwr_ison_nphy(pi)) {
28467 for (core = 0; core < pi->pubpi.phy_corenum;
28468 core++)
28469 pi->nphy_txpwr_idx[core] =
28470 wlc_phy_txpwr_idx_cur_get_nphy(
28471 pi,
28472 (u8) core);
28473 }
28474
28475 }
28476
28477 tbl_len = 84;
28478 tbl_offset = 64;
28479 for (ctr = 0; ctr < tbl_len; ctr++)
28480 regval[ctr] = 0;
28481 wlc_phy_table_write_nphy(pi, 26, tbl_len, tbl_offset, 16,
28482 regval);
28483 wlc_phy_table_write_nphy(pi, 27, tbl_len, tbl_offset, 16,
28484 regval);
28485
28486 if (NREV_GE(pi->pubpi.phy_rev, 3))
28487 and_phy_reg(pi, 0x1e7,
28488 (u16) (~((0x1 << 15) |
28489 (0x1 << 14) | (0x1 << 13))));
28490 else
28491 and_phy_reg(pi, 0x1e7,
28492 (u16) (~((0x1 << 14) | (0x1 << 13))));
28493
28494 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28495 or_phy_reg(pi, 0x8f, (0x1 << 8));
28496 or_phy_reg(pi, 0xa5, (0x1 << 8));
28497 } else {
28498 or_phy_reg(pi, 0xa5, (0x1 << 14));
28499 }
28500
28501 if (NREV_IS(pi->pubpi.phy_rev, 2))
28502 mod_phy_reg(pi, 0xdc, 0x00ff, 0x53);
28503 else if (NREV_LT(pi->pubpi.phy_rev, 2))
28504 mod_phy_reg(pi, 0xdc, 0x00ff, 0x5a);
28505
28506 if (NREV_LT(pi->pubpi.phy_rev, 2) &&
28507 pi->bw == WL_CHANSPEC_BW_40)
28508 wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
28509 MHF1_IQSWAP_WAR, BRCM_BAND_ALL);
28510
28511 } else {
28512
28513 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64,
28514 8, pi->adj_pwr_tbl_nphy);
28515 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64,
28516 8, pi->adj_pwr_tbl_nphy);
28517
28518 ishw = (ctrl_type == PHY_TPC_HW_ON) ? 0x1 : 0x0;
28519 mask = (0x1 << 14) | (0x1 << 13);
28520 val = (ishw << 14) | (ishw << 13);
28521
28522 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28523 mask |= (0x1 << 15);
28524 val |= (ishw << 15);
28525 }
28526
28527 mod_phy_reg(pi, 0x1e7, mask, val);
28528
28529 if (CHSPEC_IS5G(pi->radio_chanspec)) {
28530 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
28531 mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x32);
28532 mod_phy_reg(pi, 0x222, (0xff << 0), 0x32);
28533 } else {
28534 mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x64);
28535 if (NREV_GT(pi->pubpi.phy_rev, 1))
28536 mod_phy_reg(pi, 0x222,
28537 (0xff << 0), 0x64);
28538 }
28539 }
28540
28541 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28542 if ((pi->nphy_txpwr_idx[0] != 128)
28543 && (pi->nphy_txpwr_idx[1] != 128))
28544 wlc_phy_txpwr_idx_cur_set_nphy(pi,
28545 pi->
28546 nphy_txpwr_idx
28547 [0],
28548 pi->
28549 nphy_txpwr_idx
28550 [1]);
28551 }
28552
28553 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28554 and_phy_reg(pi, 0x8f, ~(0x1 << 8));
28555 and_phy_reg(pi, 0xa5, ~(0x1 << 8));
28556 } else {
28557 and_phy_reg(pi, 0xa5, ~(0x1 << 14));
28558 }
28559
28560 if (NREV_IS(pi->pubpi.phy_rev, 2))
28561 mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
28562 else if (NREV_LT(pi->pubpi.phy_rev, 2))
28563 mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
28564
28565 if (NREV_LT(pi->pubpi.phy_rev, 2) &&
28566 pi->bw == WL_CHANSPEC_BW_40)
28567 wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
28568 0x0, BRCM_BAND_ALL);
28569
28570 if (PHY_IPA(pi)) {
28571 mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
28572 0x29b, (0x1 << 2), (0) << 2);
28573
28574 mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
28575 0x29b, (0x1 << 2), (0) << 2);
28576
28577 }
28578
28579 }
28580
28581 if (pi->phyhang_avoid)
28582 wlc_phy_stay_in_carriersearch_nphy(pi, false);
28583}
28584
28585void
28586wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, s8 txpwrindex,
28587 bool restore_cals)
28588{
28589 u8 core, txpwrctl_tbl;
28590 u16 tx_ind0, iq_ind0, lo_ind0;
28591 u16 m1m2;
28592 u32 txgain;
28593 u16 rad_gain, dac_gain;
28594 u8 bbmult;
28595 u32 iqcomp;
28596 u16 iqcomp_a, iqcomp_b;
28597 u32 locomp;
28598 u16 tmpval;
28599 u8 tx_pwr_ctrl_state;
28600 s32 rfpwr_offset;
28601 u16 regval[2];
28602
28603 if (pi->phyhang_avoid)
28604 wlc_phy_stay_in_carriersearch_nphy(pi, true);
28605
28606 tx_ind0 = 192;
28607 iq_ind0 = 320;
28608 lo_ind0 = 448;
28609
28610 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
28611
28612 if ((core_mask & (1 << core)) == 0)
28613 continue;
28614
28615 txpwrctl_tbl = (core == PHY_CORE_0) ? 26 : 27;
28616
28617 if (txpwrindex < 0) {
28618 if (pi->nphy_txpwrindex[core].index < 0)
28619 continue;
28620
28621 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28622 mod_phy_reg(pi, 0x8f,
28623 (0x1 << 8),
28624 pi->nphy_txpwrindex[core].
28625 AfectrlOverride);
28626 mod_phy_reg(pi, 0xa5, (0x1 << 8),
28627 pi->nphy_txpwrindex[core].
28628 AfectrlOverride);
28629 } else {
28630 mod_phy_reg(pi, 0xa5,
28631 (0x1 << 14),
28632 pi->nphy_txpwrindex[core].
28633 AfectrlOverride);
28634 }
28635
28636 write_phy_reg(pi, (core == PHY_CORE_0) ?
28637 0xaa : 0xab,
28638 pi->nphy_txpwrindex[core].AfeCtrlDacGain);
28639
28640 wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
28641 &pi->nphy_txpwrindex[core].
28642 rad_gain);
28643
28644 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
28645 m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
28646 m1m2 |= ((core == PHY_CORE_0) ?
28647 (pi->nphy_txpwrindex[core].bbmult << 8) :
28648 (pi->nphy_txpwrindex[core].bbmult << 0));
28649 wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
28650
28651 if (restore_cals) {
28652 wlc_phy_table_write_nphy(
28653 pi, 15, 2, (80 + 2 * core), 16,
28654 &pi->nphy_txpwrindex[core].iqcomp_a);
28655 wlc_phy_table_write_nphy(
28656 pi, 15, 1, (85 + core), 16,
28657 &pi->nphy_txpwrindex[core].locomp);
28658 wlc_phy_table_write_nphy(
28659 pi, 15, 1, (93 + core), 16,
28660 &pi->nphy_txpwrindex[core].locomp);
28661 }
28662
28663 wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
28664
28665 pi->nphy_txpwrindex[core].index_internal =
28666 pi->nphy_txpwrindex[core].index_internal_save;
28667 } else {
28668
28669 if (pi->nphy_txpwrindex[core].index < 0) {
28670
28671 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28672 mod_phy_reg(pi, 0x8f,
28673 (0x1 << 8),
28674 pi->nphy_txpwrindex[core].
28675 AfectrlOverride);
28676 mod_phy_reg(pi, 0xa5, (0x1 << 8),
28677 pi->nphy_txpwrindex[core].
28678 AfectrlOverride);
28679 } else {
28680 pi->nphy_txpwrindex[core].
28681 AfectrlOverride =
28682 read_phy_reg(pi, 0xa5);
28683 }
28684
28685 pi->nphy_txpwrindex[core].AfeCtrlDacGain =
28686 read_phy_reg(pi, (core == PHY_CORE_0) ?
28687 0xaa : 0xab);
28688
28689 wlc_phy_table_read_nphy(pi, 7, 1,
28690 (0x110 + core), 16,
28691 &pi->
28692 nphy_txpwrindex[core].
28693 rad_gain);
28694
28695 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
28696 &tmpval);
28697 tmpval >>= ((core == PHY_CORE_0) ? 8 : 0);
28698 tmpval &= 0xff;
28699 pi->nphy_txpwrindex[core].bbmult = (u8) tmpval;
28700
28701 wlc_phy_table_read_nphy(pi, 15, 2,
28702 (80 + 2 * core), 16,
28703 &pi->
28704 nphy_txpwrindex[core].
28705 iqcomp_a);
28706
28707 wlc_phy_table_read_nphy(pi, 15, 1, (85 + core),
28708 16,
28709 &pi->
28710 nphy_txpwrindex[core].
28711 locomp);
28712
28713 pi->nphy_txpwrindex[core].index_internal_save =
28714 pi->nphy_txpwrindex[core].
28715 index_internal;
28716 }
28717
28718 tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
28719 wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
28720
28721 if (NREV_IS(pi->pubpi.phy_rev, 1))
28722 wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
28723
28724 wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
28725 (tx_ind0 + txpwrindex), 32,
28726 &txgain);
28727
28728 if (NREV_GE(pi->pubpi.phy_rev, 3))
28729 rad_gain = (txgain >> 16) &
28730 ((1 << (32 - 16 + 1)) - 1);
28731 else
28732 rad_gain = (txgain >> 16) &
28733 ((1 << (28 - 16 + 1)) - 1);
28734
28735 dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
28736 bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
28737
28738 if (NREV_GE(pi->pubpi.phy_rev, 3))
28739 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
28740 0xa5), (0x1 << 8), (0x1 << 8));
28741 else
28742 mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
28743
28744 write_phy_reg(pi, (core == PHY_CORE_0) ?
28745 0xaa : 0xab, dac_gain);
28746
28747 wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
28748 &rad_gain);
28749
28750 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
28751 m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
28752 m1m2 |= ((core == PHY_CORE_0) ?
28753 (bbmult << 8) : (bbmult << 0));
28754
28755 wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
28756
28757 wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
28758 (iq_ind0 + txpwrindex), 32,
28759 &iqcomp);
28760 iqcomp_a = (iqcomp >> 10) & ((1 << (19 - 10 + 1)) - 1);
28761 iqcomp_b = (iqcomp >> 0) & ((1 << (9 - 0 + 1)) - 1);
28762
28763 if (restore_cals) {
28764 regval[0] = (u16) iqcomp_a;
28765 regval[1] = (u16) iqcomp_b;
28766 wlc_phy_table_write_nphy(pi, 15, 2,
28767 (80 + 2 * core), 16,
28768 regval);
28769 }
28770
28771 wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
28772 (lo_ind0 + txpwrindex), 32,
28773 &locomp);
28774 if (restore_cals)
28775 wlc_phy_table_write_nphy(pi, 15, 1, (85 + core),
28776 16, &locomp);
28777
28778 if (NREV_IS(pi->pubpi.phy_rev, 1))
28779 wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
28780
28781 if (PHY_IPA(pi)) {
28782 wlc_phy_table_read_nphy(pi,
28783 (core == PHY_CORE_0 ?
28784 NPHY_TBL_ID_CORE1TXPWRCTL :
28785 NPHY_TBL_ID_CORE2TXPWRCTL),
28786 1, 576 + txpwrindex, 32,
28787 &rfpwr_offset);
28788
28789 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
28790 0x29b, (0x1ff << 4),
28791 ((s16) rfpwr_offset) << 4);
28792
28793 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
28794 0x29b, (0x1 << 2), (1) << 2);
28795
28796 }
28797
28798 wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
28799 }
28800
28801 pi->nphy_txpwrindex[core].index = txpwrindex;
28802 }
28803
28804 if (pi->phyhang_avoid)
28805 wlc_phy_stay_in_carriersearch_nphy(pi, false);
28806}
28807
28808void
28809wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan, u8 *max_pwr,
28810 u8 txp_rate_idx)
28811{
28812 u8 chan_freq_range;
28813
28814 chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, chan);
28815 switch (chan_freq_range) {
28816 case WL_CHAN_FREQ_RANGE_2G:
28817 *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
28818 break;
28819 case WL_CHAN_FREQ_RANGE_5GM:
28820 *max_pwr = pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
28821 break;
28822 case WL_CHAN_FREQ_RANGE_5GL:
28823 *max_pwr = pi->tx_srom_max_rate_5g_low[txp_rate_idx];
28824 break;
28825 case WL_CHAN_FREQ_RANGE_5GH:
28826 *max_pwr = pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
28827 break;
28828 default:
28829 *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
28830 break;
28831 }
28832
28833 return;
28834}
28835
28836void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi, bool enable)
28837{
28838 u16 clip_off[] = { 0xffff, 0xffff };
28839
28840 if (enable) {
28841 if (pi->nphy_deaf_count == 0) {
28842 pi->classifier_state =
28843 wlc_phy_classifier_nphy(pi, 0, 0);
28844 wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
28845 wlc_phy_clip_det_nphy(pi, 0, pi->clip_state);
28846 wlc_phy_clip_det_nphy(pi, 1, clip_off);
28847 }
28848
28849 pi->nphy_deaf_count++;
28850
28851 wlc_phy_resetcca_nphy(pi);
28852
28853 } else {
28854 pi->nphy_deaf_count--;
28855
28856 if (pi->nphy_deaf_count == 0) {
28857 wlc_phy_classifier_nphy(pi, (0x7 << 0),
28858 pi->classifier_state);
28859 wlc_phy_clip_det_nphy(pi, 1, pi->clip_state);
28860 }
28861 }
28862}
28863
28864void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode)
28865{
28866 wlapi_suspend_mac_and_wait(pi->sh->physhim);
28867
28868 if (mode) {
28869 if (pi->nphy_deaf_count == 0)
28870 wlc_phy_stay_in_carriersearch_nphy(pi, true);
28871 } else if (pi->nphy_deaf_count > 0) {
28872 wlc_phy_stay_in_carriersearch_nphy(pi, false);
28873 }
28874
28875 wlapi_enable_mac(pi->sh->physhim);
28876}
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 000000000000..faf1ebe76068
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
@@ -0,0 +1,308 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "phy_qmath.h"
18
19/*
20 * Description: This function make 16 bit unsigned multiplication.
21 * To fit the output into 16 bits the 32 bit multiplication result is right
22 * shifted by 16 bits.
23 */
24u16 qm_mulu16(u16 op1, u16 op2)
25{
26 return (u16) (((u32) op1 * (u32) op2) >> 16);
27}
28
29/*
30 * Description: This function make 16 bit multiplication and return the result
31 * in 16 bits. To fit the multiplication result into 16 bits the multiplication
32 * result is right shifted by 15 bits. Right shifting 15 bits instead of 16 bits
33 * is done to remove the extra sign bit formed due to the multiplication.
34 * When both the 16bit inputs are 0x8000 then the output is saturated to
35 * 0x7fffffff.
36 */
37s16 qm_muls16(s16 op1, s16 op2)
38{
39 s32 result;
40 if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000)
41 result = 0x7fffffff;
42 else
43 result = ((s32) (op1) * (s32) (op2));
44
45 return (s16) (result >> 15);
46}
47
48/*
49 * Description: This function add two 32 bit numbers and return the 32bit
50 * result. If the result overflow 32 bits, the output will be saturated to
51 * 32bits.
52 */
53s32 qm_add32(s32 op1, s32 op2)
54{
55 s32 result;
56 result = op1 + op2;
57 if (op1 < 0 && op2 < 0 && result > 0)
58 result = 0x80000000;
59 else if (op1 > 0 && op2 > 0 && result < 0)
60 result = 0x7fffffff;
61
62 return result;
63}
64
65/*
66 * Description: This function add two 16 bit numbers and return the 16bit
67 * result. If the result overflow 16 bits, the output will be saturated to
68 * 16bits.
69 */
70s16 qm_add16(s16 op1, s16 op2)
71{
72 s16 result;
73 s32 temp = (s32) op1 + (s32) op2;
74 if (temp > (s32) 0x7fff)
75 result = (s16) 0x7fff;
76 else if (temp < (s32) 0xffff8000)
77 result = (s16) 0xffff8000;
78 else
79 result = (s16) temp;
80
81 return result;
82}
83
84/*
85 * Description: This function make 16 bit subtraction and return the 16bit
86 * result. If the result overflow 16 bits, the output will be saturated to
87 * 16bits.
88 */
89s16 qm_sub16(s16 op1, s16 op2)
90{
91 s16 result;
92 s32 temp = (s32) op1 - (s32) op2;
93 if (temp > (s32) 0x7fff)
94 result = (s16) 0x7fff;
95 else if (temp < (s32) 0xffff8000)
96 result = (s16) 0xffff8000;
97 else
98 result = (s16) temp;
99
100 return result;
101}
102
103/*
104 * Description: This function make a 32 bit saturated left shift when the
105 * specified shift is +ve. This function will make a 32 bit right shift when
106 * the specified shift is -ve. This function return the result after shifting
107 * operation.
108 */
109s32 qm_shl32(s32 op, int shift)
110{
111 int i;
112 s32 result;
113 result = op;
114 if (shift > 31)
115 shift = 31;
116 else if (shift < -31)
117 shift = -31;
118 if (shift >= 0) {
119 for (i = 0; i < shift; i++)
120 result = qm_add32(result, result);
121 } else {
122 result = result >> (-shift);
123 }
124
125 return result;
126}
127
128/*
129 * Description: This function make a 16 bit saturated left shift when the
130 * specified shift is +ve. This function will make a 16 bit right shift when
131 * the specified shift is -ve. This function return the result after shifting
132 * operation.
133 */
134s16 qm_shl16(s16 op, int shift)
135{
136 int i;
137 s16 result;
138 result = op;
139 if (shift > 15)
140 shift = 15;
141 else if (shift < -15)
142 shift = -15;
143 if (shift > 0) {
144 for (i = 0; i < shift; i++)
145 result = qm_add16(result, result);
146 } else {
147 result = result >> (-shift);
148 }
149
150 return result;
151}
152
153/*
154 * Description: This function make a 16 bit right shift when shift is +ve.
155 * This function make a 16 bit saturated left shift when shift is -ve. This
156 * function return the result of the shift operation.
157 */
158s16 qm_shr16(s16 op, int shift)
159{
160 return qm_shl16(op, -shift);
161}
162
163/*
164 * Description: This function return the number of redundant sign bits in a
165 * 32 bit number. Example: qm_norm32(0x00000080) = 23
166 */
167s16 qm_norm32(s32 op)
168{
169 u16 u16extraSignBits;
170 if (op == 0) {
171 return 31;
172 } else {
173 u16extraSignBits = 0;
174 while ((op >> 31) == (op >> 30)) {
175 u16extraSignBits++;
176 op = op << 1;
177 }
178 }
179 return u16extraSignBits;
180}
181
182/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
183static const s16 log_table[] = {
184 0,
185 1455,
186 2866,
187 4236,
188 5568,
189 6863,
190 8124,
191 9352,
192 10549,
193 11716,
194 12855,
195 13968,
196 15055,
197 16117,
198 17156,
199 18173,
200 19168,
201 20143,
202 21098,
203 22034,
204 22952,
205 23852,
206 24736,
207 25604,
208 26455,
209 27292,
210 28114,
211 28922,
212 29717,
213 30498,
214 31267,
215 32024
216};
217
218#define LOG_TABLE_SIZE 32 /* log_table size */
219#define LOG2_LOG_TABLE_SIZE 5 /* log2(log_table size) */
220#define Q_LOG_TABLE 15 /* qformat of log_table */
221#define LOG10_2 19728 /* log10(2) in q.16 */
222
223/*
224 * Description:
225 * This routine takes the input number N and its q format qN and compute
226 * the log10(N). This routine first normalizes the input no N. Then N is in
227 * mag*(2^x) format. mag is any number in the range 2^30-(2^31 - 1).
228 * Then log2(mag * 2^x) = log2(mag) + x is computed. From that
229 * log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
230 * This routine looks the log2 value in the table considering
231 * LOG2_LOG_TABLE_SIZE+1 MSBs. As the MSB is always 1, only next
232 * LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup. Next 16 MSBs are used
233 * for interpolation.
234 * Inputs:
235 * N - number to which log10 has to be found.
236 * qN - q format of N
237 * log10N - address where log10(N) will be written.
238 * qLog10N - address where log10N qformat will be written.
239 * Note/Problem:
240 * For accurate results input should be in normalized or near normalized form.
241 */
242void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N)
243{
244 s16 s16norm, s16tableIndex, s16errorApproximation;
245 u16 u16offset;
246 s32 s32log;
247
248 /* normalize the N. */
249 s16norm = qm_norm32(N);
250 N = N << s16norm;
251
252 /* The qformat of N after normalization.
253 * -30 is added to treat the no as between 1.0 to 2.0
254 * i.e. after adding the -30 to the qformat the decimal point will be
255 * just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
256 * at the right side of 30th bit.
257 */
258 qN = qN + s16norm - 30;
259
260 /* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the
261 * MSB */
262 s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
263
264 /* remove the MSB. the MSB is always 1 after normalization. */
265 s16tableIndex =
266 s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
267
268 /* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
269 N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
270
271 /* take the offset as the 16 MSBS after table index.
272 */
273 u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
274
275 /* look the log value in the table. */
276 s32log = log_table[s16tableIndex]; /* q.15 format */
277
278 /* interpolate using the offset. q.15 format. */
279 s16errorApproximation = (s16) qm_mulu16(u16offset,
280 (u16) (log_table[s16tableIndex + 1] -
281 log_table[s16tableIndex]));
282
283 /* q.15 format */
284 s32log = qm_add16((s16) s32log, s16errorApproximation);
285
286 /* adjust for the qformat of the N as
287 * log2(mag * 2^x) = log2(mag) + x
288 */
289 s32log = qm_add32(s32log, ((s32) -qN) << 15); /* q.15 format */
290
291 /* normalize the result. */
292 s16norm = qm_norm32(s32log);
293
294 /* bring all the important bits into lower 16 bits */
295 /* q.15+s16norm-16 format */
296 s32log = qm_shl32(s32log, s16norm - 16);
297
298 /* compute the log10(N) by multiplying log2(N) with log10(2).
299 * as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
300 * log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
301 */
302 *log10N = qm_muls16((s16) s32log, (s16) LOG10_2);
303
304 /* write the q format of the result. */
305 *qLog10N = 15 + s16norm - 16 + 1;
306
307 return;
308}
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 000000000000..20e3783f921b
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_QMATH_H_
18#define _BRCM_QMATH_H_
19
20#include <types.h>
21
22u16 qm_mulu16(u16 op1, u16 op2);
23
24s16 qm_muls16(s16 op1, s16 op2);
25
26s32 qm_add32(s32 op1, s32 op2);
27
28s16 qm_add16(s16 op1, s16 op2);
29
30s16 qm_sub16(s16 op1, s16 op2);
31
32s32 qm_shl32(s32 op, int shift);
33
34s16 qm_shl16(s16 op, int shift);
35
36s16 qm_shr16(s16 op, int shift);
37
38s16 qm_norm32(s32 op);
39
40void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N);
41
42#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 000000000000..c3a675455ff5
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
@@ -0,0 +1,1533 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_PHY_RADIO_H_
18#define _BRCM_PHY_RADIO_H_
19
20#define RADIO_IDCODE 0x01
21
22#define RADIO_DEFAULT_CORE 0
23
24#define RXC0_RSSI_RST 0x80
25#define RXC0_MODE_RSSI 0x40
26#define RXC0_MODE_OFF 0x20
27#define RXC0_MODE_CM 0x10
28#define RXC0_LAN_LOAD 0x08
29#define RXC0_OFF_ADJ_MASK 0x07
30
31#define TXC0_MODE_TXLPF 0x04
32#define TXC0_PA_TSSI_EN 0x02
33#define TXC0_TSSI_EN 0x01
34
35#define TXC1_PA_GAIN_MASK 0x60
36#define TXC1_PA_GAIN_3DB 0x40
37#define TXC1_PA_GAIN_2DB 0x20
38#define TXC1_TX_MIX_GAIN 0x10
39#define TXC1_OFF_I_MASK 0x0c
40#define TXC1_OFF_Q_MASK 0x03
41
42#define RADIO_2055_READ_OFF 0x100
43#define RADIO_2057_READ_OFF 0x200
44
45#define RADIO_2055_GEN_SPARE 0x00
46#define RADIO_2055_SP_PIN_PD 0x02
47#define RADIO_2055_SP_RSSI_CORE1 0x03
48#define RADIO_2055_SP_PD_MISC_CORE1 0x04
49#define RADIO_2055_SP_RSSI_CORE2 0x05
50#define RADIO_2055_SP_PD_MISC_CORE2 0x06
51#define RADIO_2055_SP_RX_GC1_CORE1 0x07
52#define RADIO_2055_SP_RX_GC2_CORE1 0x08
53#define RADIO_2055_SP_RX_GC1_CORE2 0x09
54#define RADIO_2055_SP_RX_GC2_CORE2 0x0a
55#define RADIO_2055_SP_LPF_BW_SELECT_CORE1 0x0b
56#define RADIO_2055_SP_LPF_BW_SELECT_CORE2 0x0c
57#define RADIO_2055_SP_TX_GC1_CORE1 0x0d
58#define RADIO_2055_SP_TX_GC2_CORE1 0x0e
59#define RADIO_2055_SP_TX_GC1_CORE2 0x0f
60#define RADIO_2055_SP_TX_GC2_CORE2 0x10
61#define RADIO_2055_MASTER_CNTRL1 0x11
62#define RADIO_2055_MASTER_CNTRL2 0x12
63#define RADIO_2055_PD_LGEN 0x13
64#define RADIO_2055_PD_PLL_TS 0x14
65#define RADIO_2055_PD_CORE1_LGBUF 0x15
66#define RADIO_2055_PD_CORE1_TX 0x16
67#define RADIO_2055_PD_CORE1_RXTX 0x17
68#define RADIO_2055_PD_CORE1_RSSI_MISC 0x18
69#define RADIO_2055_PD_CORE2_LGBUF 0x19
70#define RADIO_2055_PD_CORE2_TX 0x1a
71#define RADIO_2055_PD_CORE2_RXTX 0x1b
72#define RADIO_2055_PD_CORE2_RSSI_MISC 0x1c
73#define RADIO_2055_PWRDET_LGEN 0x1d
74#define RADIO_2055_PWRDET_LGBUF_CORE1 0x1e
75#define RADIO_2055_PWRDET_RXTX_CORE1 0x1f
76#define RADIO_2055_PWRDET_LGBUF_CORE2 0x20
77#define RADIO_2055_PWRDET_RXTX_CORE2 0x21
78#define RADIO_2055_RRCCAL_CNTRL_SPARE 0x22
79#define RADIO_2055_RRCCAL_N_OPT_SEL 0x23
80#define RADIO_2055_CAL_MISC 0x24
81#define RADIO_2055_CAL_COUNTER_OUT 0x25
82#define RADIO_2055_CAL_COUNTER_OUT2 0x26
83#define RADIO_2055_CAL_CVAR_CNTRL 0x27
84#define RADIO_2055_CAL_RVAR_CNTRL 0x28
85#define RADIO_2055_CAL_LPO_CNTRL 0x29
86#define RADIO_2055_CAL_TS 0x2a
87#define RADIO_2055_CAL_RCCAL_READ_TS 0x2b
88#define RADIO_2055_CAL_RCAL_READ_TS 0x2c
89#define RADIO_2055_PAD_DRIVER 0x2d
90#define RADIO_2055_XO_CNTRL1 0x2e
91#define RADIO_2055_XO_CNTRL2 0x2f
92#define RADIO_2055_XO_REGULATOR 0x30
93#define RADIO_2055_XO_MISC 0x31
94#define RADIO_2055_PLL_LF_C1 0x32
95#define RADIO_2055_PLL_CAL_VTH 0x33
96#define RADIO_2055_PLL_LF_C2 0x34
97#define RADIO_2055_PLL_REF 0x35
98#define RADIO_2055_PLL_LF_R1 0x36
99#define RADIO_2055_PLL_PFD_CP 0x37
100#define RADIO_2055_PLL_IDAC_CPOPAMP 0x38
101#define RADIO_2055_PLL_CP_REGULATOR 0x39
102#define RADIO_2055_PLL_RCAL 0x3a
103#define RADIO_2055_RF_PLL_MOD0 0x3b
104#define RADIO_2055_RF_PLL_MOD1 0x3c
105#define RADIO_2055_RF_MMD_IDAC1 0x3d
106#define RADIO_2055_RF_MMD_IDAC0 0x3e
107#define RADIO_2055_RF_MMD_SPARE 0x3f
108#define RADIO_2055_VCO_CAL1 0x40
109#define RADIO_2055_VCO_CAL2 0x41
110#define RADIO_2055_VCO_CAL3 0x42
111#define RADIO_2055_VCO_CAL4 0x43
112#define RADIO_2055_VCO_CAL5 0x44
113#define RADIO_2055_VCO_CAL6 0x45
114#define RADIO_2055_VCO_CAL7 0x46
115#define RADIO_2055_VCO_CAL8 0x47
116#define RADIO_2055_VCO_CAL9 0x48
117#define RADIO_2055_VCO_CAL10 0x49
118#define RADIO_2055_VCO_CAL11 0x4a
119#define RADIO_2055_VCO_CAL12 0x4b
120#define RADIO_2055_VCO_CAL13 0x4c
121#define RADIO_2055_VCO_CAL14 0x4d
122#define RADIO_2055_VCO_CAL15 0x4e
123#define RADIO_2055_VCO_CAL16 0x4f
124#define RADIO_2055_VCO_KVCO 0x50
125#define RADIO_2055_VCO_CAP_TAIL 0x51
126#define RADIO_2055_VCO_IDAC_VCO 0x52
127#define RADIO_2055_VCO_REGULATOR 0x53
128#define RADIO_2055_PLL_RF_VTH 0x54
129#define RADIO_2055_LGBUF_CEN_BUF 0x55
130#define RADIO_2055_LGEN_TUNE1 0x56
131#define RADIO_2055_LGEN_TUNE2 0x57
132#define RADIO_2055_LGEN_IDAC1 0x58
133#define RADIO_2055_LGEN_IDAC2 0x59
134#define RADIO_2055_LGEN_BIAS_CNT 0x5a
135#define RADIO_2055_LGEN_BIAS_IDAC 0x5b
136#define RADIO_2055_LGEN_RCAL 0x5c
137#define RADIO_2055_LGEN_DIV 0x5d
138#define RADIO_2055_LGEN_SPARE2 0x5e
139#define RADIO_2055_CORE1_LGBUF_A_TUNE 0x5f
140#define RADIO_2055_CORE1_LGBUF_G_TUNE 0x60
141#define RADIO_2055_CORE1_LGBUF_DIV 0x61
142#define RADIO_2055_CORE1_LGBUF_A_IDAC 0x62
143#define RADIO_2055_CORE1_LGBUF_G_IDAC 0x63
144#define RADIO_2055_CORE1_LGBUF_IDACFIL_OVR 0x64
145#define RADIO_2055_CORE1_LGBUF_SPARE 0x65
146#define RADIO_2055_CORE1_RXRF_SPC1 0x66
147#define RADIO_2055_CORE1_RXRF_REG1 0x67
148#define RADIO_2055_CORE1_RXRF_REG2 0x68
149#define RADIO_2055_CORE1_RXRF_RCAL 0x69
150#define RADIO_2055_CORE1_RXBB_BUFI_LPFCMP 0x6a
151#define RADIO_2055_CORE1_RXBB_LPF 0x6b
152#define RADIO_2055_CORE1_RXBB_MIDAC_HIPAS 0x6c
153#define RADIO_2055_CORE1_RXBB_VGA1_IDAC 0x6d
154#define RADIO_2055_CORE1_RXBB_VGA2_IDAC 0x6e
155#define RADIO_2055_CORE1_RXBB_VGA3_IDAC 0x6f
156#define RADIO_2055_CORE1_RXBB_BUFO_CTRL 0x70
157#define RADIO_2055_CORE1_RXBB_RCCAL_CTRL 0x71
158#define RADIO_2055_CORE1_RXBB_RSSI_CTRL1 0x72
159#define RADIO_2055_CORE1_RXBB_RSSI_CTRL2 0x73
160#define RADIO_2055_CORE1_RXBB_RSSI_CTRL3 0x74
161#define RADIO_2055_CORE1_RXBB_RSSI_CTRL4 0x75
162#define RADIO_2055_CORE1_RXBB_RSSI_CTRL5 0x76
163#define RADIO_2055_CORE1_RXBB_REGULATOR 0x77
164#define RADIO_2055_CORE1_RXBB_SPARE1 0x78
165#define RADIO_2055_CORE1_RXTXBB_RCAL 0x79
166#define RADIO_2055_CORE1_TXRF_SGM_PGA 0x7a
167#define RADIO_2055_CORE1_TXRF_SGM_PAD 0x7b
168#define RADIO_2055_CORE1_TXRF_CNTR_PGA1 0x7c
169#define RADIO_2055_CORE1_TXRF_CNTR_PAD1 0x7d
170#define RADIO_2055_CORE1_TX_RFPGA_IDAC 0x7e
171#define RADIO_2055_CORE1_TX_PGA_PAD_TN 0x7f
172#define RADIO_2055_CORE1_TX_PAD_IDAC1 0x80
173#define RADIO_2055_CORE1_TX_PAD_IDAC2 0x81
174#define RADIO_2055_CORE1_TX_MX_BGTRIM 0x82
175#define RADIO_2055_CORE1_TXRF_RCAL 0x83
176#define RADIO_2055_CORE1_TXRF_PAD_TSSI1 0x84
177#define RADIO_2055_CORE1_TXRF_PAD_TSSI2 0x85
178#define RADIO_2055_CORE1_TX_RF_SPARE 0x86
179#define RADIO_2055_CORE1_TXRF_IQCAL1 0x87
180#define RADIO_2055_CORE1_TXRF_IQCAL2 0x88
181#define RADIO_2055_CORE1_TXBB_RCCAL_CTRL 0x89
182#define RADIO_2055_CORE1_TXBB_LPF1 0x8a
183#define RADIO_2055_CORE1_TX_VOS_CNCL 0x8b
184#define RADIO_2055_CORE1_TX_LPF_MXGM_IDAC 0x8c
185#define RADIO_2055_CORE1_TX_BB_MXGM 0x8d
186#define RADIO_2055_CORE2_LGBUF_A_TUNE 0x8e
187#define RADIO_2055_CORE2_LGBUF_G_TUNE 0x8f
188#define RADIO_2055_CORE2_LGBUF_DIV 0x90
189#define RADIO_2055_CORE2_LGBUF_A_IDAC 0x91
190#define RADIO_2055_CORE2_LGBUF_G_IDAC 0x92
191#define RADIO_2055_CORE2_LGBUF_IDACFIL_OVR 0x93
192#define RADIO_2055_CORE2_LGBUF_SPARE 0x94
193#define RADIO_2055_CORE2_RXRF_SPC1 0x95
194#define RADIO_2055_CORE2_RXRF_REG1 0x96
195#define RADIO_2055_CORE2_RXRF_REG2 0x97
196#define RADIO_2055_CORE2_RXRF_RCAL 0x98
197#define RADIO_2055_CORE2_RXBB_BUFI_LPFCMP 0x99
198#define RADIO_2055_CORE2_RXBB_LPF 0x9a
199#define RADIO_2055_CORE2_RXBB_MIDAC_HIPAS 0x9b
200#define RADIO_2055_CORE2_RXBB_VGA1_IDAC 0x9c
201#define RADIO_2055_CORE2_RXBB_VGA2_IDAC 0x9d
202#define RADIO_2055_CORE2_RXBB_VGA3_IDAC 0x9e
203#define RADIO_2055_CORE2_RXBB_BUFO_CTRL 0x9f
204#define RADIO_2055_CORE2_RXBB_RCCAL_CTRL 0xa0
205#define RADIO_2055_CORE2_RXBB_RSSI_CTRL1 0xa1
206#define RADIO_2055_CORE2_RXBB_RSSI_CTRL2 0xa2
207#define RADIO_2055_CORE2_RXBB_RSSI_CTRL3 0xa3
208#define RADIO_2055_CORE2_RXBB_RSSI_CTRL4 0xa4
209#define RADIO_2055_CORE2_RXBB_RSSI_CTRL5 0xa5
210#define RADIO_2055_CORE2_RXBB_REGULATOR 0xa6
211#define RADIO_2055_CORE2_RXBB_SPARE1 0xa7
212#define RADIO_2055_CORE2_RXTXBB_RCAL 0xa8
213#define RADIO_2055_CORE2_TXRF_SGM_PGA 0xa9
214#define RADIO_2055_CORE2_TXRF_SGM_PAD 0xaa
215#define RADIO_2055_CORE2_TXRF_CNTR_PGA1 0xab
216#define RADIO_2055_CORE2_TXRF_CNTR_PAD1 0xac
217#define RADIO_2055_CORE2_TX_RFPGA_IDAC 0xad
218#define RADIO_2055_CORE2_TX_PGA_PAD_TN 0xae
219#define RADIO_2055_CORE2_TX_PAD_IDAC1 0xaf
220#define RADIO_2055_CORE2_TX_PAD_IDAC2 0xb0
221#define RADIO_2055_CORE2_TX_MX_BGTRIM 0xb1
222#define RADIO_2055_CORE2_TXRF_RCAL 0xb2
223#define RADIO_2055_CORE2_TXRF_PAD_TSSI1 0xb3
224#define RADIO_2055_CORE2_TXRF_PAD_TSSI2 0xb4
225#define RADIO_2055_CORE2_TX_RF_SPARE 0xb5
226#define RADIO_2055_CORE2_TXRF_IQCAL1 0xb6
227#define RADIO_2055_CORE2_TXRF_IQCAL2 0xb7
228#define RADIO_2055_CORE2_TXBB_RCCAL_CTRL 0xb8
229#define RADIO_2055_CORE2_TXBB_LPF1 0xb9
230#define RADIO_2055_CORE2_TX_VOS_CNCL 0xba
231#define RADIO_2055_CORE2_TX_LPF_MXGM_IDAC 0xbb
232#define RADIO_2055_CORE2_TX_BB_MXGM 0xbc
233#define RADIO_2055_PRG_GC_HPVGA23_21 0xbd
234#define RADIO_2055_PRG_GC_HPVGA23_22 0xbe
235#define RADIO_2055_PRG_GC_HPVGA23_23 0xbf
236#define RADIO_2055_PRG_GC_HPVGA23_24 0xc0
237#define RADIO_2055_PRG_GC_HPVGA23_25 0xc1
238#define RADIO_2055_PRG_GC_HPVGA23_26 0xc2
239#define RADIO_2055_PRG_GC_HPVGA23_27 0xc3
240#define RADIO_2055_PRG_GC_HPVGA23_28 0xc4
241#define RADIO_2055_PRG_GC_HPVGA23_29 0xc5
242#define RADIO_2055_PRG_GC_HPVGA23_30 0xc6
243#define RADIO_2055_CORE1_LNA_GAINBST 0xcd
244#define RADIO_2055_CORE1_B0_NBRSSI_VCM 0xd2
245#define RADIO_2055_CORE1_GEN_SPARE2 0xd6
246#define RADIO_2055_CORE2_LNA_GAINBST 0xd9
247#define RADIO_2055_CORE2_B0_NBRSSI_VCM 0xde
248#define RADIO_2055_CORE2_GEN_SPARE2 0xe2
249
250#define RADIO_2055_GAINBST_GAIN_DB 6
251#define RADIO_2055_GAINBST_CODE 0x6
252
253#define RADIO_2055_JTAGCTRL_MASK 0x04
254#define RADIO_2055_JTAGSYNC_MASK 0x08
255#define RADIO_2055_RRCAL_START 0x40
256#define RADIO_2055_RRCAL_RST_N 0x01
257#define RADIO_2055_CAL_LPO_ENABLE 0x80
258#define RADIO_2055_RCAL_DONE 0x80
259#define RADIO_2055_NBRSSI_VCM_I_MASK 0x03
260#define RADIO_2055_NBRSSI_VCM_I_SHIFT 0x00
261#define RADIO_2055_NBRSSI_VCM_Q_MASK 0x03
262#define RADIO_2055_NBRSSI_VCM_Q_SHIFT 0x00
263#define RADIO_2055_WBRSSI_VCM_IQ_MASK 0x0c
264#define RADIO_2055_WBRSSI_VCM_IQ_SHIFT 0x02
265#define RADIO_2055_NBRSSI_PD 0x01
266#define RADIO_2055_WBRSSI_G1_PD 0x04
267#define RADIO_2055_WBRSSI_G2_PD 0x02
268#define RADIO_2055_NBRSSI_SEL 0x01
269#define RADIO_2055_WBRSSI_G1_SEL 0x04
270#define RADIO_2055_WBRSSI_G2_SEL 0x02
271#define RADIO_2055_COUPLE_RX_MASK 0x01
272#define RADIO_2055_COUPLE_TX_MASK 0x02
273#define RADIO_2055_GAINBST_DISABLE 0x02
274#define RADIO_2055_GAINBST_VAL_MASK 0x07
275#define RADIO_2055_RXMX_GC_MASK 0x0c
276
277#define RADIO_MIMO_CORESEL_OFF 0x0
278#define RADIO_MIMO_CORESEL_CORE1 0x1
279#define RADIO_MIMO_CORESEL_CORE2 0x2
280#define RADIO_MIMO_CORESEL_CORE3 0x3
281#define RADIO_MIMO_CORESEL_CORE4 0x4
282#define RADIO_MIMO_CORESEL_ALLRX 0x5
283#define RADIO_MIMO_CORESEL_ALLTX 0x6
284#define RADIO_MIMO_CORESEL_ALLRXTX 0x7
285
286#define RADIO_2064_READ_OFF 0x200
287
288#define RADIO_2064_REG000 0x0
289#define RADIO_2064_REG001 0x1
290#define RADIO_2064_REG002 0x2
291#define RADIO_2064_REG003 0x3
292#define RADIO_2064_REG004 0x4
293#define RADIO_2064_REG005 0x5
294#define RADIO_2064_REG006 0x6
295#define RADIO_2064_REG007 0x7
296#define RADIO_2064_REG008 0x8
297#define RADIO_2064_REG009 0x9
298#define RADIO_2064_REG00A 0xa
299#define RADIO_2064_REG00B 0xb
300#define RADIO_2064_REG00C 0xc
301#define RADIO_2064_REG00D 0xd
302#define RADIO_2064_REG00E 0xe
303#define RADIO_2064_REG00F 0xf
304#define RADIO_2064_REG010 0x10
305#define RADIO_2064_REG011 0x11
306#define RADIO_2064_REG012 0x12
307#define RADIO_2064_REG013 0x13
308#define RADIO_2064_REG014 0x14
309#define RADIO_2064_REG015 0x15
310#define RADIO_2064_REG016 0x16
311#define RADIO_2064_REG017 0x17
312#define RADIO_2064_REG018 0x18
313#define RADIO_2064_REG019 0x19
314#define RADIO_2064_REG01A 0x1a
315#define RADIO_2064_REG01B 0x1b
316#define RADIO_2064_REG01C 0x1c
317#define RADIO_2064_REG01D 0x1d
318#define RADIO_2064_REG01E 0x1e
319#define RADIO_2064_REG01F 0x1f
320#define RADIO_2064_REG020 0x20
321#define RADIO_2064_REG021 0x21
322#define RADIO_2064_REG022 0x22
323#define RADIO_2064_REG023 0x23
324#define RADIO_2064_REG024 0x24
325#define RADIO_2064_REG025 0x25
326#define RADIO_2064_REG026 0x26
327#define RADIO_2064_REG027 0x27
328#define RADIO_2064_REG028 0x28
329#define RADIO_2064_REG029 0x29
330#define RADIO_2064_REG02A 0x2a
331#define RADIO_2064_REG02B 0x2b
332#define RADIO_2064_REG02C 0x2c
333#define RADIO_2064_REG02D 0x2d
334#define RADIO_2064_REG02E 0x2e
335#define RADIO_2064_REG02F 0x2f
336#define RADIO_2064_REG030 0x30
337#define RADIO_2064_REG031 0x31
338#define RADIO_2064_REG032 0x32
339#define RADIO_2064_REG033 0x33
340#define RADIO_2064_REG034 0x34
341#define RADIO_2064_REG035 0x35
342#define RADIO_2064_REG036 0x36
343#define RADIO_2064_REG037 0x37
344#define RADIO_2064_REG038 0x38
345#define RADIO_2064_REG039 0x39
346#define RADIO_2064_REG03A 0x3a
347#define RADIO_2064_REG03B 0x3b
348#define RADIO_2064_REG03C 0x3c
349#define RADIO_2064_REG03D 0x3d
350#define RADIO_2064_REG03E 0x3e
351#define RADIO_2064_REG03F 0x3f
352#define RADIO_2064_REG040 0x40
353#define RADIO_2064_REG041 0x41
354#define RADIO_2064_REG042 0x42
355#define RADIO_2064_REG043 0x43
356#define RADIO_2064_REG044 0x44
357#define RADIO_2064_REG045 0x45
358#define RADIO_2064_REG046 0x46
359#define RADIO_2064_REG047 0x47
360#define RADIO_2064_REG048 0x48
361#define RADIO_2064_REG049 0x49
362#define RADIO_2064_REG04A 0x4a
363#define RADIO_2064_REG04B 0x4b
364#define RADIO_2064_REG04C 0x4c
365#define RADIO_2064_REG04D 0x4d
366#define RADIO_2064_REG04E 0x4e
367#define RADIO_2064_REG04F 0x4f
368#define RADIO_2064_REG050 0x50
369#define RADIO_2064_REG051 0x51
370#define RADIO_2064_REG052 0x52
371#define RADIO_2064_REG053 0x53
372#define RADIO_2064_REG054 0x54
373#define RADIO_2064_REG055 0x55
374#define RADIO_2064_REG056 0x56
375#define RADIO_2064_REG057 0x57
376#define RADIO_2064_REG058 0x58
377#define RADIO_2064_REG059 0x59
378#define RADIO_2064_REG05A 0x5a
379#define RADIO_2064_REG05B 0x5b
380#define RADIO_2064_REG05C 0x5c
381#define RADIO_2064_REG05D 0x5d
382#define RADIO_2064_REG05E 0x5e
383#define RADIO_2064_REG05F 0x5f
384#define RADIO_2064_REG060 0x60
385#define RADIO_2064_REG061 0x61
386#define RADIO_2064_REG062 0x62
387#define RADIO_2064_REG063 0x63
388#define RADIO_2064_REG064 0x64
389#define RADIO_2064_REG065 0x65
390#define RADIO_2064_REG066 0x66
391#define RADIO_2064_REG067 0x67
392#define RADIO_2064_REG068 0x68
393#define RADIO_2064_REG069 0x69
394#define RADIO_2064_REG06A 0x6a
395#define RADIO_2064_REG06B 0x6b
396#define RADIO_2064_REG06C 0x6c
397#define RADIO_2064_REG06D 0x6d
398#define RADIO_2064_REG06E 0x6e
399#define RADIO_2064_REG06F 0x6f
400#define RADIO_2064_REG070 0x70
401#define RADIO_2064_REG071 0x71
402#define RADIO_2064_REG072 0x72
403#define RADIO_2064_REG073 0x73
404#define RADIO_2064_REG074 0x74
405#define RADIO_2064_REG075 0x75
406#define RADIO_2064_REG076 0x76
407#define RADIO_2064_REG077 0x77
408#define RADIO_2064_REG078 0x78
409#define RADIO_2064_REG079 0x79
410#define RADIO_2064_REG07A 0x7a
411#define RADIO_2064_REG07B 0x7b
412#define RADIO_2064_REG07C 0x7c
413#define RADIO_2064_REG07D 0x7d
414#define RADIO_2064_REG07E 0x7e
415#define RADIO_2064_REG07F 0x7f
416#define RADIO_2064_REG080 0x80
417#define RADIO_2064_REG081 0x81
418#define RADIO_2064_REG082 0x82
419#define RADIO_2064_REG083 0x83
420#define RADIO_2064_REG084 0x84
421#define RADIO_2064_REG085 0x85
422#define RADIO_2064_REG086 0x86
423#define RADIO_2064_REG087 0x87
424#define RADIO_2064_REG088 0x88
425#define RADIO_2064_REG089 0x89
426#define RADIO_2064_REG08A 0x8a
427#define RADIO_2064_REG08B 0x8b
428#define RADIO_2064_REG08C 0x8c
429#define RADIO_2064_REG08D 0x8d
430#define RADIO_2064_REG08E 0x8e
431#define RADIO_2064_REG08F 0x8f
432#define RADIO_2064_REG090 0x90
433#define RADIO_2064_REG091 0x91
434#define RADIO_2064_REG092 0x92
435#define RADIO_2064_REG093 0x93
436#define RADIO_2064_REG094 0x94
437#define RADIO_2064_REG095 0x95
438#define RADIO_2064_REG096 0x96
439#define RADIO_2064_REG097 0x97
440#define RADIO_2064_REG098 0x98
441#define RADIO_2064_REG099 0x99
442#define RADIO_2064_REG09A 0x9a
443#define RADIO_2064_REG09B 0x9b
444#define RADIO_2064_REG09C 0x9c
445#define RADIO_2064_REG09D 0x9d
446#define RADIO_2064_REG09E 0x9e
447#define RADIO_2064_REG09F 0x9f
448#define RADIO_2064_REG0A0 0xa0
449#define RADIO_2064_REG0A1 0xa1
450#define RADIO_2064_REG0A2 0xa2
451#define RADIO_2064_REG0A3 0xa3
452#define RADIO_2064_REG0A4 0xa4
453#define RADIO_2064_REG0A5 0xa5
454#define RADIO_2064_REG0A6 0xa6
455#define RADIO_2064_REG0A7 0xa7
456#define RADIO_2064_REG0A8 0xa8
457#define RADIO_2064_REG0A9 0xa9
458#define RADIO_2064_REG0AA 0xaa
459#define RADIO_2064_REG0AB 0xab
460#define RADIO_2064_REG0AC 0xac
461#define RADIO_2064_REG0AD 0xad
462#define RADIO_2064_REG0AE 0xae
463#define RADIO_2064_REG0AF 0xaf
464#define RADIO_2064_REG0B0 0xb0
465#define RADIO_2064_REG0B1 0xb1
466#define RADIO_2064_REG0B2 0xb2
467#define RADIO_2064_REG0B3 0xb3
468#define RADIO_2064_REG0B4 0xb4
469#define RADIO_2064_REG0B5 0xb5
470#define RADIO_2064_REG0B6 0xb6
471#define RADIO_2064_REG0B7 0xb7
472#define RADIO_2064_REG0B8 0xb8
473#define RADIO_2064_REG0B9 0xb9
474#define RADIO_2064_REG0BA 0xba
475#define RADIO_2064_REG0BB 0xbb
476#define RADIO_2064_REG0BC 0xbc
477#define RADIO_2064_REG0BD 0xbd
478#define RADIO_2064_REG0BE 0xbe
479#define RADIO_2064_REG0BF 0xbf
480#define RADIO_2064_REG0C0 0xc0
481#define RADIO_2064_REG0C1 0xc1
482#define RADIO_2064_REG0C2 0xc2
483#define RADIO_2064_REG0C3 0xc3
484#define RADIO_2064_REG0C4 0xc4
485#define RADIO_2064_REG0C5 0xc5
486#define RADIO_2064_REG0C6 0xc6
487#define RADIO_2064_REG0C7 0xc7
488#define RADIO_2064_REG0C8 0xc8
489#define RADIO_2064_REG0C9 0xc9
490#define RADIO_2064_REG0CA 0xca
491#define RADIO_2064_REG0CB 0xcb
492#define RADIO_2064_REG0CC 0xcc
493#define RADIO_2064_REG0CD 0xcd
494#define RADIO_2064_REG0CE 0xce
495#define RADIO_2064_REG0CF 0xcf
496#define RADIO_2064_REG0D0 0xd0
497#define RADIO_2064_REG0D1 0xd1
498#define RADIO_2064_REG0D2 0xd2
499#define RADIO_2064_REG0D3 0xd3
500#define RADIO_2064_REG0D4 0xd4
501#define RADIO_2064_REG0D5 0xd5
502#define RADIO_2064_REG0D6 0xd6
503#define RADIO_2064_REG0D7 0xd7
504#define RADIO_2064_REG0D8 0xd8
505#define RADIO_2064_REG0D9 0xd9
506#define RADIO_2064_REG0DA 0xda
507#define RADIO_2064_REG0DB 0xdb
508#define RADIO_2064_REG0DC 0xdc
509#define RADIO_2064_REG0DD 0xdd
510#define RADIO_2064_REG0DE 0xde
511#define RADIO_2064_REG0DF 0xdf
512#define RADIO_2064_REG0E0 0xe0
513#define RADIO_2064_REG0E1 0xe1
514#define RADIO_2064_REG0E2 0xe2
515#define RADIO_2064_REG0E3 0xe3
516#define RADIO_2064_REG0E4 0xe4
517#define RADIO_2064_REG0E5 0xe5
518#define RADIO_2064_REG0E6 0xe6
519#define RADIO_2064_REG0E7 0xe7
520#define RADIO_2064_REG0E8 0xe8
521#define RADIO_2064_REG0E9 0xe9
522#define RADIO_2064_REG0EA 0xea
523#define RADIO_2064_REG0EB 0xeb
524#define RADIO_2064_REG0EC 0xec
525#define RADIO_2064_REG0ED 0xed
526#define RADIO_2064_REG0EE 0xee
527#define RADIO_2064_REG0EF 0xef
528#define RADIO_2064_REG0F0 0xf0
529#define RADIO_2064_REG0F1 0xf1
530#define RADIO_2064_REG0F2 0xf2
531#define RADIO_2064_REG0F3 0xf3
532#define RADIO_2064_REG0F4 0xf4
533#define RADIO_2064_REG0F5 0xf5
534#define RADIO_2064_REG0F6 0xf6
535#define RADIO_2064_REG0F7 0xf7
536#define RADIO_2064_REG0F8 0xf8
537#define RADIO_2064_REG0F9 0xf9
538#define RADIO_2064_REG0FA 0xfa
539#define RADIO_2064_REG0FB 0xfb
540#define RADIO_2064_REG0FC 0xfc
541#define RADIO_2064_REG0FD 0xfd
542#define RADIO_2064_REG0FE 0xfe
543#define RADIO_2064_REG0FF 0xff
544#define RADIO_2064_REG100 0x100
545#define RADIO_2064_REG101 0x101
546#define RADIO_2064_REG102 0x102
547#define RADIO_2064_REG103 0x103
548#define RADIO_2064_REG104 0x104
549#define RADIO_2064_REG105 0x105
550#define RADIO_2064_REG106 0x106
551#define RADIO_2064_REG107 0x107
552#define RADIO_2064_REG108 0x108
553#define RADIO_2064_REG109 0x109
554#define RADIO_2064_REG10A 0x10a
555#define RADIO_2064_REG10B 0x10b
556#define RADIO_2064_REG10C 0x10c
557#define RADIO_2064_REG10D 0x10d
558#define RADIO_2064_REG10E 0x10e
559#define RADIO_2064_REG10F 0x10f
560#define RADIO_2064_REG110 0x110
561#define RADIO_2064_REG111 0x111
562#define RADIO_2064_REG112 0x112
563#define RADIO_2064_REG113 0x113
564#define RADIO_2064_REG114 0x114
565#define RADIO_2064_REG115 0x115
566#define RADIO_2064_REG116 0x116
567#define RADIO_2064_REG117 0x117
568#define RADIO_2064_REG118 0x118
569#define RADIO_2064_REG119 0x119
570#define RADIO_2064_REG11A 0x11a
571#define RADIO_2064_REG11B 0x11b
572#define RADIO_2064_REG11C 0x11c
573#define RADIO_2064_REG11D 0x11d
574#define RADIO_2064_REG11E 0x11e
575#define RADIO_2064_REG11F 0x11f
576#define RADIO_2064_REG120 0x120
577#define RADIO_2064_REG121 0x121
578#define RADIO_2064_REG122 0x122
579#define RADIO_2064_REG123 0x123
580#define RADIO_2064_REG124 0x124
581#define RADIO_2064_REG125 0x125
582#define RADIO_2064_REG126 0x126
583#define RADIO_2064_REG127 0x127
584#define RADIO_2064_REG128 0x128
585#define RADIO_2064_REG129 0x129
586#define RADIO_2064_REG12A 0x12a
587#define RADIO_2064_REG12B 0x12b
588#define RADIO_2064_REG12C 0x12c
589#define RADIO_2064_REG12D 0x12d
590#define RADIO_2064_REG12E 0x12e
591#define RADIO_2064_REG12F 0x12f
592#define RADIO_2064_REG130 0x130
593
594#define RADIO_2056_SYN (0x0 << 12)
595#define RADIO_2056_TX0 (0x2 << 12)
596#define RADIO_2056_TX1 (0x3 << 12)
597#define RADIO_2056_RX0 (0x6 << 12)
598#define RADIO_2056_RX1 (0x7 << 12)
599#define RADIO_2056_ALLTX (0xe << 12)
600#define RADIO_2056_ALLRX (0xf << 12)
601
602#define RADIO_2056_SYN_RESERVED_ADDR0 0x0
603#define RADIO_2056_SYN_IDCODE 0x1
604#define RADIO_2056_SYN_RESERVED_ADDR2 0x2
605#define RADIO_2056_SYN_RESERVED_ADDR3 0x3
606#define RADIO_2056_SYN_RESERVED_ADDR4 0x4
607#define RADIO_2056_SYN_RESERVED_ADDR5 0x5
608#define RADIO_2056_SYN_RESERVED_ADDR6 0x6
609#define RADIO_2056_SYN_RESERVED_ADDR7 0x7
610#define RADIO_2056_SYN_COM_CTRL 0x8
611#define RADIO_2056_SYN_COM_PU 0x9
612#define RADIO_2056_SYN_COM_OVR 0xa
613#define RADIO_2056_SYN_COM_RESET 0xb
614#define RADIO_2056_SYN_COM_RCAL 0xc
615#define RADIO_2056_SYN_COM_RC_RXLPF 0xd
616#define RADIO_2056_SYN_COM_RC_TXLPF 0xe
617#define RADIO_2056_SYN_COM_RC_RXHPF 0xf
618#define RADIO_2056_SYN_RESERVED_ADDR16 0x10
619#define RADIO_2056_SYN_RESERVED_ADDR17 0x11
620#define RADIO_2056_SYN_RESERVED_ADDR18 0x12
621#define RADIO_2056_SYN_RESERVED_ADDR19 0x13
622#define RADIO_2056_SYN_RESERVED_ADDR20 0x14
623#define RADIO_2056_SYN_RESERVED_ADDR21 0x15
624#define RADIO_2056_SYN_RESERVED_ADDR22 0x16
625#define RADIO_2056_SYN_RESERVED_ADDR23 0x17
626#define RADIO_2056_SYN_RESERVED_ADDR24 0x18
627#define RADIO_2056_SYN_RESERVED_ADDR25 0x19
628#define RADIO_2056_SYN_RESERVED_ADDR26 0x1a
629#define RADIO_2056_SYN_RESERVED_ADDR27 0x1b
630#define RADIO_2056_SYN_RESERVED_ADDR28 0x1c
631#define RADIO_2056_SYN_RESERVED_ADDR29 0x1d
632#define RADIO_2056_SYN_RESERVED_ADDR30 0x1e
633#define RADIO_2056_SYN_RESERVED_ADDR31 0x1f
634#define RADIO_2056_SYN_GPIO_MASTER1 0x20
635#define RADIO_2056_SYN_GPIO_MASTER2 0x21
636#define RADIO_2056_SYN_TOPBIAS_MASTER 0x22
637#define RADIO_2056_SYN_TOPBIAS_RCAL 0x23
638#define RADIO_2056_SYN_AFEREG 0x24
639#define RADIO_2056_SYN_TEMPPROCSENSE 0x25
640#define RADIO_2056_SYN_TEMPPROCSENSEIDAC 0x26
641#define RADIO_2056_SYN_TEMPPROCSENSERCAL 0x27
642#define RADIO_2056_SYN_LPO 0x28
643#define RADIO_2056_SYN_VDDCAL_MASTER 0x29
644#define RADIO_2056_SYN_VDDCAL_IDAC 0x2a
645#define RADIO_2056_SYN_VDDCAL_STATUS 0x2b
646#define RADIO_2056_SYN_RCAL_MASTER 0x2c
647#define RADIO_2056_SYN_RCAL_CODE_OUT 0x2d
648#define RADIO_2056_SYN_RCCAL_CTRL0 0x2e
649#define RADIO_2056_SYN_RCCAL_CTRL1 0x2f
650#define RADIO_2056_SYN_RCCAL_CTRL2 0x30
651#define RADIO_2056_SYN_RCCAL_CTRL3 0x31
652#define RADIO_2056_SYN_RCCAL_CTRL4 0x32
653#define RADIO_2056_SYN_RCCAL_CTRL5 0x33
654#define RADIO_2056_SYN_RCCAL_CTRL6 0x34
655#define RADIO_2056_SYN_RCCAL_CTRL7 0x35
656#define RADIO_2056_SYN_RCCAL_CTRL8 0x36
657#define RADIO_2056_SYN_RCCAL_CTRL9 0x37
658#define RADIO_2056_SYN_RCCAL_CTRL10 0x38
659#define RADIO_2056_SYN_RCCAL_CTRL11 0x39
660#define RADIO_2056_SYN_ZCAL_SPARE1 0x3a
661#define RADIO_2056_SYN_ZCAL_SPARE2 0x3b
662#define RADIO_2056_SYN_PLL_MAST1 0x3c
663#define RADIO_2056_SYN_PLL_MAST2 0x3d
664#define RADIO_2056_SYN_PLL_MAST3 0x3e
665#define RADIO_2056_SYN_PLL_BIAS_RESET 0x3f
666#define RADIO_2056_SYN_PLL_XTAL0 0x40
667#define RADIO_2056_SYN_PLL_XTAL1 0x41
668#define RADIO_2056_SYN_PLL_XTAL3 0x42
669#define RADIO_2056_SYN_PLL_XTAL4 0x43
670#define RADIO_2056_SYN_PLL_XTAL5 0x44
671#define RADIO_2056_SYN_PLL_XTAL6 0x45
672#define RADIO_2056_SYN_PLL_REFDIV 0x46
673#define RADIO_2056_SYN_PLL_PFD 0x47
674#define RADIO_2056_SYN_PLL_CP1 0x48
675#define RADIO_2056_SYN_PLL_CP2 0x49
676#define RADIO_2056_SYN_PLL_CP3 0x4a
677#define RADIO_2056_SYN_PLL_LOOPFILTER1 0x4b
678#define RADIO_2056_SYN_PLL_LOOPFILTER2 0x4c
679#define RADIO_2056_SYN_PLL_LOOPFILTER3 0x4d
680#define RADIO_2056_SYN_PLL_LOOPFILTER4 0x4e
681#define RADIO_2056_SYN_PLL_LOOPFILTER5 0x4f
682#define RADIO_2056_SYN_PLL_MMD1 0x50
683#define RADIO_2056_SYN_PLL_MMD2 0x51
684#define RADIO_2056_SYN_PLL_VCO1 0x52
685#define RADIO_2056_SYN_PLL_VCO2 0x53
686#define RADIO_2056_SYN_PLL_MONITOR1 0x54
687#define RADIO_2056_SYN_PLL_MONITOR2 0x55
688#define RADIO_2056_SYN_PLL_VCOCAL1 0x56
689#define RADIO_2056_SYN_PLL_VCOCAL2 0x57
690#define RADIO_2056_SYN_PLL_VCOCAL4 0x58
691#define RADIO_2056_SYN_PLL_VCOCAL5 0x59
692#define RADIO_2056_SYN_PLL_VCOCAL6 0x5a
693#define RADIO_2056_SYN_PLL_VCOCAL7 0x5b
694#define RADIO_2056_SYN_PLL_VCOCAL8 0x5c
695#define RADIO_2056_SYN_PLL_VCOCAL9 0x5d
696#define RADIO_2056_SYN_PLL_VCOCAL10 0x5e
697#define RADIO_2056_SYN_PLL_VCOCAL11 0x5f
698#define RADIO_2056_SYN_PLL_VCOCAL12 0x60
699#define RADIO_2056_SYN_PLL_VCOCAL13 0x61
700#define RADIO_2056_SYN_PLL_VREG 0x62
701#define RADIO_2056_SYN_PLL_STATUS1 0x63
702#define RADIO_2056_SYN_PLL_STATUS2 0x64
703#define RADIO_2056_SYN_PLL_STATUS3 0x65
704#define RADIO_2056_SYN_LOGEN_PU0 0x66
705#define RADIO_2056_SYN_LOGEN_PU1 0x67
706#define RADIO_2056_SYN_LOGEN_PU2 0x68
707#define RADIO_2056_SYN_LOGEN_PU3 0x69
708#define RADIO_2056_SYN_LOGEN_PU5 0x6a
709#define RADIO_2056_SYN_LOGEN_PU6 0x6b
710#define RADIO_2056_SYN_LOGEN_PU7 0x6c
711#define RADIO_2056_SYN_LOGEN_PU8 0x6d
712#define RADIO_2056_SYN_LOGEN_BIAS_RESET 0x6e
713#define RADIO_2056_SYN_LOGEN_RCCR1 0x6f
714#define RADIO_2056_SYN_LOGEN_VCOBUF1 0x70
715#define RADIO_2056_SYN_LOGEN_MIXER1 0x71
716#define RADIO_2056_SYN_LOGEN_MIXER2 0x72
717#define RADIO_2056_SYN_LOGEN_BUF1 0x73
718#define RADIO_2056_SYN_LOGENBUF2 0x74
719#define RADIO_2056_SYN_LOGEN_BUF3 0x75
720#define RADIO_2056_SYN_LOGEN_BUF4 0x76
721#define RADIO_2056_SYN_LOGEN_DIV1 0x77
722#define RADIO_2056_SYN_LOGEN_DIV2 0x78
723#define RADIO_2056_SYN_LOGEN_DIV3 0x79
724#define RADIO_2056_SYN_LOGEN_ACL1 0x7a
725#define RADIO_2056_SYN_LOGEN_ACL2 0x7b
726#define RADIO_2056_SYN_LOGEN_ACL3 0x7c
727#define RADIO_2056_SYN_LOGEN_ACL4 0x7d
728#define RADIO_2056_SYN_LOGEN_ACL5 0x7e
729#define RADIO_2056_SYN_LOGEN_ACL6 0x7f
730#define RADIO_2056_SYN_LOGEN_ACLOUT 0x80
731#define RADIO_2056_SYN_LOGEN_ACLCAL1 0x81
732#define RADIO_2056_SYN_LOGEN_ACLCAL2 0x82
733#define RADIO_2056_SYN_LOGEN_ACLCAL3 0x83
734#define RADIO_2056_SYN_CALEN 0x84
735#define RADIO_2056_SYN_LOGEN_PEAKDET1 0x85
736#define RADIO_2056_SYN_LOGEN_CORE_ACL_OVR 0x86
737#define RADIO_2056_SYN_LOGEN_RX_DIFF_ACL_OVR 0x87
738#define RADIO_2056_SYN_LOGEN_TX_DIFF_ACL_OVR 0x88
739#define RADIO_2056_SYN_LOGEN_RX_CMOS_ACL_OVR 0x89
740#define RADIO_2056_SYN_LOGEN_TX_CMOS_ACL_OVR 0x8a
741#define RADIO_2056_SYN_LOGEN_VCOBUF2 0x8b
742#define RADIO_2056_SYN_LOGEN_MIXER3 0x8c
743#define RADIO_2056_SYN_LOGEN_BUF5 0x8d
744#define RADIO_2056_SYN_LOGEN_BUF6 0x8e
745#define RADIO_2056_SYN_LOGEN_CBUFRX1 0x8f
746#define RADIO_2056_SYN_LOGEN_CBUFRX2 0x90
747#define RADIO_2056_SYN_LOGEN_CBUFRX3 0x91
748#define RADIO_2056_SYN_LOGEN_CBUFRX4 0x92
749#define RADIO_2056_SYN_LOGEN_CBUFTX1 0x93
750#define RADIO_2056_SYN_LOGEN_CBUFTX2 0x94
751#define RADIO_2056_SYN_LOGEN_CBUFTX3 0x95
752#define RADIO_2056_SYN_LOGEN_CBUFTX4 0x96
753#define RADIO_2056_SYN_LOGEN_CMOSRX1 0x97
754#define RADIO_2056_SYN_LOGEN_CMOSRX2 0x98
755#define RADIO_2056_SYN_LOGEN_CMOSRX3 0x99
756#define RADIO_2056_SYN_LOGEN_CMOSRX4 0x9a
757#define RADIO_2056_SYN_LOGEN_CMOSTX1 0x9b
758#define RADIO_2056_SYN_LOGEN_CMOSTX2 0x9c
759#define RADIO_2056_SYN_LOGEN_CMOSTX3 0x9d
760#define RADIO_2056_SYN_LOGEN_CMOSTX4 0x9e
761#define RADIO_2056_SYN_LOGEN_VCOBUF2_OVRVAL 0x9f
762#define RADIO_2056_SYN_LOGEN_MIXER3_OVRVAL 0xa0
763#define RADIO_2056_SYN_LOGEN_BUF5_OVRVAL 0xa1
764#define RADIO_2056_SYN_LOGEN_BUF6_OVRVAL 0xa2
765#define RADIO_2056_SYN_LOGEN_CBUFRX1_OVRVAL 0xa3
766#define RADIO_2056_SYN_LOGEN_CBUFRX2_OVRVAL 0xa4
767#define RADIO_2056_SYN_LOGEN_CBUFRX3_OVRVAL 0xa5
768#define RADIO_2056_SYN_LOGEN_CBUFRX4_OVRVAL 0xa6
769#define RADIO_2056_SYN_LOGEN_CBUFTX1_OVRVAL 0xa7
770#define RADIO_2056_SYN_LOGEN_CBUFTX2_OVRVAL 0xa8
771#define RADIO_2056_SYN_LOGEN_CBUFTX3_OVRVAL 0xa9
772#define RADIO_2056_SYN_LOGEN_CBUFTX4_OVRVAL 0xaa
773#define RADIO_2056_SYN_LOGEN_CMOSRX1_OVRVAL 0xab
774#define RADIO_2056_SYN_LOGEN_CMOSRX2_OVRVAL 0xac
775#define RADIO_2056_SYN_LOGEN_CMOSRX3_OVRVAL 0xad
776#define RADIO_2056_SYN_LOGEN_CMOSRX4_OVRVAL 0xae
777#define RADIO_2056_SYN_LOGEN_CMOSTX1_OVRVAL 0xaf
778#define RADIO_2056_SYN_LOGEN_CMOSTX2_OVRVAL 0xb0
779#define RADIO_2056_SYN_LOGEN_CMOSTX3_OVRVAL 0xb1
780#define RADIO_2056_SYN_LOGEN_CMOSTX4_OVRVAL 0xb2
781#define RADIO_2056_SYN_LOGEN_ACL_WAITCNT 0xb3
782#define RADIO_2056_SYN_LOGEN_CORE_CALVALID 0xb4
783#define RADIO_2056_SYN_LOGEN_RX_CMOS_CALVALID 0xb5
784#define RADIO_2056_SYN_LOGEN_TX_CMOS_VALID 0xb6
785
786#define RADIO_2056_TX_RESERVED_ADDR0 0x0
787#define RADIO_2056_TX_IDCODE 0x1
788#define RADIO_2056_TX_RESERVED_ADDR2 0x2
789#define RADIO_2056_TX_RESERVED_ADDR3 0x3
790#define RADIO_2056_TX_RESERVED_ADDR4 0x4
791#define RADIO_2056_TX_RESERVED_ADDR5 0x5
792#define RADIO_2056_TX_RESERVED_ADDR6 0x6
793#define RADIO_2056_TX_RESERVED_ADDR7 0x7
794#define RADIO_2056_TX_COM_CTRL 0x8
795#define RADIO_2056_TX_COM_PU 0x9
796#define RADIO_2056_TX_COM_OVR 0xa
797#define RADIO_2056_TX_COM_RESET 0xb
798#define RADIO_2056_TX_COM_RCAL 0xc
799#define RADIO_2056_TX_COM_RC_RXLPF 0xd
800#define RADIO_2056_TX_COM_RC_TXLPF 0xe
801#define RADIO_2056_TX_COM_RC_RXHPF 0xf
802#define RADIO_2056_TX_RESERVED_ADDR16 0x10
803#define RADIO_2056_TX_RESERVED_ADDR17 0x11
804#define RADIO_2056_TX_RESERVED_ADDR18 0x12
805#define RADIO_2056_TX_RESERVED_ADDR19 0x13
806#define RADIO_2056_TX_RESERVED_ADDR20 0x14
807#define RADIO_2056_TX_RESERVED_ADDR21 0x15
808#define RADIO_2056_TX_RESERVED_ADDR22 0x16
809#define RADIO_2056_TX_RESERVED_ADDR23 0x17
810#define RADIO_2056_TX_RESERVED_ADDR24 0x18
811#define RADIO_2056_TX_RESERVED_ADDR25 0x19
812#define RADIO_2056_TX_RESERVED_ADDR26 0x1a
813#define RADIO_2056_TX_RESERVED_ADDR27 0x1b
814#define RADIO_2056_TX_RESERVED_ADDR28 0x1c
815#define RADIO_2056_TX_RESERVED_ADDR29 0x1d
816#define RADIO_2056_TX_RESERVED_ADDR30 0x1e
817#define RADIO_2056_TX_RESERVED_ADDR31 0x1f
818#define RADIO_2056_TX_IQCAL_GAIN_BW 0x20
819#define RADIO_2056_TX_LOFT_FINE_I 0x21
820#define RADIO_2056_TX_LOFT_FINE_Q 0x22
821#define RADIO_2056_TX_LOFT_COARSE_I 0x23
822#define RADIO_2056_TX_LOFT_COARSE_Q 0x24
823#define RADIO_2056_TX_TX_COM_MASTER1 0x25
824#define RADIO_2056_TX_TX_COM_MASTER2 0x26
825#define RADIO_2056_TX_RXIQCAL_TXMUX 0x27
826#define RADIO_2056_TX_TX_SSI_MASTER 0x28
827#define RADIO_2056_TX_IQCAL_VCM_HG 0x29
828#define RADIO_2056_TX_IQCAL_IDAC 0x2a
829#define RADIO_2056_TX_TSSI_VCM 0x2b
830#define RADIO_2056_TX_TX_AMP_DET 0x2c
831#define RADIO_2056_TX_TX_SSI_MUX 0x2d
832#define RADIO_2056_TX_TSSIA 0x2e
833#define RADIO_2056_TX_TSSIG 0x2f
834#define RADIO_2056_TX_TSSI_MISC1 0x30
835#define RADIO_2056_TX_TSSI_MISC2 0x31
836#define RADIO_2056_TX_TSSI_MISC3 0x32
837#define RADIO_2056_TX_PA_SPARE1 0x33
838#define RADIO_2056_TX_PA_SPARE2 0x34
839#define RADIO_2056_TX_INTPAA_MASTER 0x35
840#define RADIO_2056_TX_INTPAA_GAIN 0x36
841#define RADIO_2056_TX_INTPAA_BOOST_TUNE 0x37
842#define RADIO_2056_TX_INTPAA_IAUX_STAT 0x38
843#define RADIO_2056_TX_INTPAA_IAUX_DYN 0x39
844#define RADIO_2056_TX_INTPAA_IMAIN_STAT 0x3a
845#define RADIO_2056_TX_INTPAA_IMAIN_DYN 0x3b
846#define RADIO_2056_TX_INTPAA_CASCBIAS 0x3c
847#define RADIO_2056_TX_INTPAA_PASLOPE 0x3d
848#define RADIO_2056_TX_INTPAA_PA_MISC 0x3e
849#define RADIO_2056_TX_INTPAG_MASTER 0x3f
850#define RADIO_2056_TX_INTPAG_GAIN 0x40
851#define RADIO_2056_TX_INTPAG_BOOST_TUNE 0x41
852#define RADIO_2056_TX_INTPAG_IAUX_STAT 0x42
853#define RADIO_2056_TX_INTPAG_IAUX_DYN 0x43
854#define RADIO_2056_TX_INTPAG_IMAIN_STAT 0x44
855#define RADIO_2056_TX_INTPAG_IMAIN_DYN 0x45
856#define RADIO_2056_TX_INTPAG_CASCBIAS 0x46
857#define RADIO_2056_TX_INTPAG_PASLOPE 0x47
858#define RADIO_2056_TX_INTPAG_PA_MISC 0x48
859#define RADIO_2056_TX_PADA_MASTER 0x49
860#define RADIO_2056_TX_PADA_IDAC 0x4a
861#define RADIO_2056_TX_PADA_CASCBIAS 0x4b
862#define RADIO_2056_TX_PADA_GAIN 0x4c
863#define RADIO_2056_TX_PADA_BOOST_TUNE 0x4d
864#define RADIO_2056_TX_PADA_SLOPE 0x4e
865#define RADIO_2056_TX_PADG_MASTER 0x4f
866#define RADIO_2056_TX_PADG_IDAC 0x50
867#define RADIO_2056_TX_PADG_CASCBIAS 0x51
868#define RADIO_2056_TX_PADG_GAIN 0x52
869#define RADIO_2056_TX_PADG_BOOST_TUNE 0x53
870#define RADIO_2056_TX_PADG_SLOPE 0x54
871#define RADIO_2056_TX_PGAA_MASTER 0x55
872#define RADIO_2056_TX_PGAA_IDAC 0x56
873#define RADIO_2056_TX_PGAA_GAIN 0x57
874#define RADIO_2056_TX_PGAA_BOOST_TUNE 0x58
875#define RADIO_2056_TX_PGAA_SLOPE 0x59
876#define RADIO_2056_TX_PGAA_MISC 0x5a
877#define RADIO_2056_TX_PGAG_MASTER 0x5b
878#define RADIO_2056_TX_PGAG_IDAC 0x5c
879#define RADIO_2056_TX_PGAG_GAIN 0x5d
880#define RADIO_2056_TX_PGAG_BOOST_TUNE 0x5e
881#define RADIO_2056_TX_PGAG_SLOPE 0x5f
882#define RADIO_2056_TX_PGAG_MISC 0x60
883#define RADIO_2056_TX_MIXA_MASTER 0x61
884#define RADIO_2056_TX_MIXA_BOOST_TUNE 0x62
885#define RADIO_2056_TX_MIXG 0x63
886#define RADIO_2056_TX_MIXG_BOOST_TUNE 0x64
887#define RADIO_2056_TX_BB_GM_MASTER 0x65
888#define RADIO_2056_TX_GMBB_GM 0x66
889#define RADIO_2056_TX_GMBB_IDAC 0x67
890#define RADIO_2056_TX_TXLPF_MASTER 0x68
891#define RADIO_2056_TX_TXLPF_RCCAL 0x69
892#define RADIO_2056_TX_TXLPF_RCCAL_OFF0 0x6a
893#define RADIO_2056_TX_TXLPF_RCCAL_OFF1 0x6b
894#define RADIO_2056_TX_TXLPF_RCCAL_OFF2 0x6c
895#define RADIO_2056_TX_TXLPF_RCCAL_OFF3 0x6d
896#define RADIO_2056_TX_TXLPF_RCCAL_OFF4 0x6e
897#define RADIO_2056_TX_TXLPF_RCCAL_OFF5 0x6f
898#define RADIO_2056_TX_TXLPF_RCCAL_OFF6 0x70
899#define RADIO_2056_TX_TXLPF_BW 0x71
900#define RADIO_2056_TX_TXLPF_GAIN 0x72
901#define RADIO_2056_TX_TXLPF_IDAC 0x73
902#define RADIO_2056_TX_TXLPF_IDAC_0 0x74
903#define RADIO_2056_TX_TXLPF_IDAC_1 0x75
904#define RADIO_2056_TX_TXLPF_IDAC_2 0x76
905#define RADIO_2056_TX_TXLPF_IDAC_3 0x77
906#define RADIO_2056_TX_TXLPF_IDAC_4 0x78
907#define RADIO_2056_TX_TXLPF_IDAC_5 0x79
908#define RADIO_2056_TX_TXLPF_IDAC_6 0x7a
909#define RADIO_2056_TX_TXLPF_OPAMP_IDAC 0x7b
910#define RADIO_2056_TX_TXLPF_MISC 0x7c
911#define RADIO_2056_TX_TXSPARE1 0x7d
912#define RADIO_2056_TX_TXSPARE2 0x7e
913#define RADIO_2056_TX_TXSPARE3 0x7f
914#define RADIO_2056_TX_TXSPARE4 0x80
915#define RADIO_2056_TX_TXSPARE5 0x81
916#define RADIO_2056_TX_TXSPARE6 0x82
917#define RADIO_2056_TX_TXSPARE7 0x83
918#define RADIO_2056_TX_TXSPARE8 0x84
919#define RADIO_2056_TX_TXSPARE9 0x85
920#define RADIO_2056_TX_TXSPARE10 0x86
921#define RADIO_2056_TX_TXSPARE11 0x87
922#define RADIO_2056_TX_TXSPARE12 0x88
923#define RADIO_2056_TX_TXSPARE13 0x89
924#define RADIO_2056_TX_TXSPARE14 0x8a
925#define RADIO_2056_TX_TXSPARE15 0x8b
926#define RADIO_2056_TX_TXSPARE16 0x8c
927#define RADIO_2056_TX_STATUS_INTPA_GAIN 0x8d
928#define RADIO_2056_TX_STATUS_PAD_GAIN 0x8e
929#define RADIO_2056_TX_STATUS_PGA_GAIN 0x8f
930#define RADIO_2056_TX_STATUS_GM_TXLPF_GAIN 0x90
931#define RADIO_2056_TX_STATUS_TXLPF_BW 0x91
932#define RADIO_2056_TX_STATUS_TXLPF_RC 0x92
933#define RADIO_2056_TX_GMBB_IDAC0 0x93
934#define RADIO_2056_TX_GMBB_IDAC1 0x94
935#define RADIO_2056_TX_GMBB_IDAC2 0x95
936#define RADIO_2056_TX_GMBB_IDAC3 0x96
937#define RADIO_2056_TX_GMBB_IDAC4 0x97
938#define RADIO_2056_TX_GMBB_IDAC5 0x98
939#define RADIO_2056_TX_GMBB_IDAC6 0x99
940#define RADIO_2056_TX_GMBB_IDAC7 0x9a
941
942#define RADIO_2056_RX_RESERVED_ADDR0 0x0
943#define RADIO_2056_RX_IDCODE 0x1
944#define RADIO_2056_RX_RESERVED_ADDR2 0x2
945#define RADIO_2056_RX_RESERVED_ADDR3 0x3
946#define RADIO_2056_RX_RESERVED_ADDR4 0x4
947#define RADIO_2056_RX_RESERVED_ADDR5 0x5
948#define RADIO_2056_RX_RESERVED_ADDR6 0x6
949#define RADIO_2056_RX_RESERVED_ADDR7 0x7
950#define RADIO_2056_RX_COM_CTRL 0x8
951#define RADIO_2056_RX_COM_PU 0x9
952#define RADIO_2056_RX_COM_OVR 0xa
953#define RADIO_2056_RX_COM_RESET 0xb
954#define RADIO_2056_RX_COM_RCAL 0xc
955#define RADIO_2056_RX_COM_RC_RXLPF 0xd
956#define RADIO_2056_RX_COM_RC_TXLPF 0xe
957#define RADIO_2056_RX_COM_RC_RXHPF 0xf
958#define RADIO_2056_RX_RESERVED_ADDR16 0x10
959#define RADIO_2056_RX_RESERVED_ADDR17 0x11
960#define RADIO_2056_RX_RESERVED_ADDR18 0x12
961#define RADIO_2056_RX_RESERVED_ADDR19 0x13
962#define RADIO_2056_RX_RESERVED_ADDR20 0x14
963#define RADIO_2056_RX_RESERVED_ADDR21 0x15
964#define RADIO_2056_RX_RESERVED_ADDR22 0x16
965#define RADIO_2056_RX_RESERVED_ADDR23 0x17
966#define RADIO_2056_RX_RESERVED_ADDR24 0x18
967#define RADIO_2056_RX_RESERVED_ADDR25 0x19
968#define RADIO_2056_RX_RESERVED_ADDR26 0x1a
969#define RADIO_2056_RX_RESERVED_ADDR27 0x1b
970#define RADIO_2056_RX_RESERVED_ADDR28 0x1c
971#define RADIO_2056_RX_RESERVED_ADDR29 0x1d
972#define RADIO_2056_RX_RESERVED_ADDR30 0x1e
973#define RADIO_2056_RX_RESERVED_ADDR31 0x1f
974#define RADIO_2056_RX_RXIQCAL_RXMUX 0x20
975#define RADIO_2056_RX_RSSI_PU 0x21
976#define RADIO_2056_RX_RSSI_SEL 0x22
977#define RADIO_2056_RX_RSSI_GAIN 0x23
978#define RADIO_2056_RX_RSSI_NB_IDAC 0x24
979#define RADIO_2056_RX_RSSI_WB2I_IDAC_1 0x25
980#define RADIO_2056_RX_RSSI_WB2I_IDAC_2 0x26
981#define RADIO_2056_RX_RSSI_WB2Q_IDAC_1 0x27
982#define RADIO_2056_RX_RSSI_WB2Q_IDAC_2 0x28
983#define RADIO_2056_RX_RSSI_POLE 0x29
984#define RADIO_2056_RX_RSSI_WB1_IDAC 0x2a
985#define RADIO_2056_RX_RSSI_MISC 0x2b
986#define RADIO_2056_RX_LNAA_MASTER 0x2c
987#define RADIO_2056_RX_LNAA_TUNE 0x2d
988#define RADIO_2056_RX_LNAA_GAIN 0x2e
989#define RADIO_2056_RX_LNA_A_SLOPE 0x2f
990#define RADIO_2056_RX_BIASPOLE_LNAA1_IDAC 0x30
991#define RADIO_2056_RX_LNAA2_IDAC 0x31
992#define RADIO_2056_RX_LNA1A_MISC 0x32
993#define RADIO_2056_RX_LNAG_MASTER 0x33
994#define RADIO_2056_RX_LNAG_TUNE 0x34
995#define RADIO_2056_RX_LNAG_GAIN 0x35
996#define RADIO_2056_RX_LNA_G_SLOPE 0x36
997#define RADIO_2056_RX_BIASPOLE_LNAG1_IDAC 0x37
998#define RADIO_2056_RX_LNAG2_IDAC 0x38
999#define RADIO_2056_RX_LNA1G_MISC 0x39
1000#define RADIO_2056_RX_MIXA_MASTER 0x3a
1001#define RADIO_2056_RX_MIXA_VCM 0x3b
1002#define RADIO_2056_RX_MIXA_CTRLPTAT 0x3c
1003#define RADIO_2056_RX_MIXA_LOB_BIAS 0x3d
1004#define RADIO_2056_RX_MIXA_CORE_IDAC 0x3e
1005#define RADIO_2056_RX_MIXA_CMFB_IDAC 0x3f
1006#define RADIO_2056_RX_MIXA_BIAS_AUX 0x40
1007#define RADIO_2056_RX_MIXA_BIAS_MAIN 0x41
1008#define RADIO_2056_RX_MIXA_BIAS_MISC 0x42
1009#define RADIO_2056_RX_MIXA_MAST_BIAS 0x43
1010#define RADIO_2056_RX_MIXG_MASTER 0x44
1011#define RADIO_2056_RX_MIXG_VCM 0x45
1012#define RADIO_2056_RX_MIXG_CTRLPTAT 0x46
1013#define RADIO_2056_RX_MIXG_LOB_BIAS 0x47
1014#define RADIO_2056_RX_MIXG_CORE_IDAC 0x48
1015#define RADIO_2056_RX_MIXG_CMFB_IDAC 0x49
1016#define RADIO_2056_RX_MIXG_BIAS_AUX 0x4a
1017#define RADIO_2056_RX_MIXG_BIAS_MAIN 0x4b
1018#define RADIO_2056_RX_MIXG_BIAS_MISC 0x4c
1019#define RADIO_2056_RX_MIXG_MAST_BIAS 0x4d
1020#define RADIO_2056_RX_TIA_MASTER 0x4e
1021#define RADIO_2056_RX_TIA_IOPAMP 0x4f
1022#define RADIO_2056_RX_TIA_QOPAMP 0x50
1023#define RADIO_2056_RX_TIA_IMISC 0x51
1024#define RADIO_2056_RX_TIA_QMISC 0x52
1025#define RADIO_2056_RX_TIA_GAIN 0x53
1026#define RADIO_2056_RX_TIA_SPARE1 0x54
1027#define RADIO_2056_RX_TIA_SPARE2 0x55
1028#define RADIO_2056_RX_BB_LPF_MASTER 0x56
1029#define RADIO_2056_RX_AACI_MASTER 0x57
1030#define RADIO_2056_RX_RXLPF_IDAC 0x58
1031#define RADIO_2056_RX_RXLPF_OPAMPBIAS_LOWQ 0x59
1032#define RADIO_2056_RX_RXLPF_OPAMPBIAS_HIGHQ 0x5a
1033#define RADIO_2056_RX_RXLPF_BIAS_DCCANCEL 0x5b
1034#define RADIO_2056_RX_RXLPF_OUTVCM 0x5c
1035#define RADIO_2056_RX_RXLPF_INVCM_BODY 0x5d
1036#define RADIO_2056_RX_RXLPF_CC_OP 0x5e
1037#define RADIO_2056_RX_RXLPF_GAIN 0x5f
1038#define RADIO_2056_RX_RXLPF_Q_BW 0x60
1039#define RADIO_2056_RX_RXLPF_HP_CORNER_BW 0x61
1040#define RADIO_2056_RX_RXLPF_RCCAL_HPC 0x62
1041#define RADIO_2056_RX_RXHPF_OFF0 0x63
1042#define RADIO_2056_RX_RXHPF_OFF1 0x64
1043#define RADIO_2056_RX_RXHPF_OFF2 0x65
1044#define RADIO_2056_RX_RXHPF_OFF3 0x66
1045#define RADIO_2056_RX_RXHPF_OFF4 0x67
1046#define RADIO_2056_RX_RXHPF_OFF5 0x68
1047#define RADIO_2056_RX_RXHPF_OFF6 0x69
1048#define RADIO_2056_RX_RXHPF_OFF7 0x6a
1049#define RADIO_2056_RX_RXLPF_RCCAL_LPC 0x6b
1050#define RADIO_2056_RX_RXLPF_OFF_0 0x6c
1051#define RADIO_2056_RX_RXLPF_OFF_1 0x6d
1052#define RADIO_2056_RX_RXLPF_OFF_2 0x6e
1053#define RADIO_2056_RX_RXLPF_OFF_3 0x6f
1054#define RADIO_2056_RX_RXLPF_OFF_4 0x70
1055#define RADIO_2056_RX_UNUSED 0x71
1056#define RADIO_2056_RX_VGA_MASTER 0x72
1057#define RADIO_2056_RX_VGA_BIAS 0x73
1058#define RADIO_2056_RX_VGA_BIAS_DCCANCEL 0x74
1059#define RADIO_2056_RX_VGA_GAIN 0x75
1060#define RADIO_2056_RX_VGA_HP_CORNER_BW 0x76
1061#define RADIO_2056_RX_VGABUF_BIAS 0x77
1062#define RADIO_2056_RX_VGABUF_GAIN_BW 0x78
1063#define RADIO_2056_RX_TXFBMIX_A 0x79
1064#define RADIO_2056_RX_TXFBMIX_G 0x7a
1065#define RADIO_2056_RX_RXSPARE1 0x7b
1066#define RADIO_2056_RX_RXSPARE2 0x7c
1067#define RADIO_2056_RX_RXSPARE3 0x7d
1068#define RADIO_2056_RX_RXSPARE4 0x7e
1069#define RADIO_2056_RX_RXSPARE5 0x7f
1070#define RADIO_2056_RX_RXSPARE6 0x80
1071#define RADIO_2056_RX_RXSPARE7 0x81
1072#define RADIO_2056_RX_RXSPARE8 0x82
1073#define RADIO_2056_RX_RXSPARE9 0x83
1074#define RADIO_2056_RX_RXSPARE10 0x84
1075#define RADIO_2056_RX_RXSPARE11 0x85
1076#define RADIO_2056_RX_RXSPARE12 0x86
1077#define RADIO_2056_RX_RXSPARE13 0x87
1078#define RADIO_2056_RX_RXSPARE14 0x88
1079#define RADIO_2056_RX_RXSPARE15 0x89
1080#define RADIO_2056_RX_RXSPARE16 0x8a
1081#define RADIO_2056_RX_STATUS_LNAA_GAIN 0x8b
1082#define RADIO_2056_RX_STATUS_LNAG_GAIN 0x8c
1083#define RADIO_2056_RX_STATUS_MIXTIA_GAIN 0x8d
1084#define RADIO_2056_RX_STATUS_RXLPF_GAIN 0x8e
1085#define RADIO_2056_RX_STATUS_VGA_BUF_GAIN 0x8f
1086#define RADIO_2056_RX_STATUS_RXLPF_Q 0x90
1087#define RADIO_2056_RX_STATUS_RXLPF_BUF_BW 0x91
1088#define RADIO_2056_RX_STATUS_RXLPF_VGA_HPC 0x92
1089#define RADIO_2056_RX_STATUS_RXLPF_RC 0x93
1090#define RADIO_2056_RX_STATUS_HPC_RC 0x94
1091
1092#define RADIO_2056_LNA1_A_PU 0x01
1093#define RADIO_2056_LNA2_A_PU 0x02
1094#define RADIO_2056_LNA1_G_PU 0x01
1095#define RADIO_2056_LNA2_G_PU 0x02
1096#define RADIO_2056_MIXA_PU_I 0x01
1097#define RADIO_2056_MIXA_PU_Q 0x02
1098#define RADIO_2056_MIXA_PU_GM 0x10
1099#define RADIO_2056_MIXG_PU_I 0x01
1100#define RADIO_2056_MIXG_PU_Q 0x02
1101#define RADIO_2056_MIXG_PU_GM 0x10
1102#define RADIO_2056_TIA_PU 0x01
1103#define RADIO_2056_BB_LPF_PU 0x20
1104#define RADIO_2056_W1_PU 0x02
1105#define RADIO_2056_W2_PU 0x04
1106#define RADIO_2056_NB_PU 0x08
1107#define RADIO_2056_RSSI_W1_SEL 0x02
1108#define RADIO_2056_RSSI_W2_SEL 0x04
1109#define RADIO_2056_RSSI_NB_SEL 0x08
1110#define RADIO_2056_VCM_MASK 0x1c
1111#define RADIO_2056_RSSI_VCM_SHIFT 0x02
1112
1113#define RADIO_2057_DACBUF_VINCM_CORE0 0x0
1114#define RADIO_2057_IDCODE 0x1
1115#define RADIO_2057_RCCAL_MASTER 0x2
1116#define RADIO_2057_RCCAL_CAP_SIZE 0x3
1117#define RADIO_2057_RCAL_CONFIG 0x4
1118#define RADIO_2057_GPAIO_CONFIG 0x5
1119#define RADIO_2057_GPAIO_SEL1 0x6
1120#define RADIO_2057_GPAIO_SEL0 0x7
1121#define RADIO_2057_CLPO_CONFIG 0x8
1122#define RADIO_2057_BANDGAP_CONFIG 0x9
1123#define RADIO_2057_BANDGAP_RCAL_TRIM 0xa
1124#define RADIO_2057_AFEREG_CONFIG 0xb
1125#define RADIO_2057_TEMPSENSE_CONFIG 0xc
1126#define RADIO_2057_XTAL_CONFIG1 0xd
1127#define RADIO_2057_XTAL_ICORE_SIZE 0xe
1128#define RADIO_2057_XTAL_BUF_SIZE 0xf
1129#define RADIO_2057_XTAL_PULLCAP_SIZE 0x10
1130#define RADIO_2057_RFPLL_MASTER 0x11
1131#define RADIO_2057_VCOMONITOR_VTH_L 0x12
1132#define RADIO_2057_VCOMONITOR_VTH_H 0x13
1133#define RADIO_2057_VCOCAL_BIASRESET_RFPLLREG_VOUT 0x14
1134#define RADIO_2057_VCO_VARCSIZE_IDAC 0x15
1135#define RADIO_2057_VCOCAL_COUNTVAL0 0x16
1136#define RADIO_2057_VCOCAL_COUNTVAL1 0x17
1137#define RADIO_2057_VCOCAL_INTCLK_COUNT 0x18
1138#define RADIO_2057_VCOCAL_MASTER 0x19
1139#define RADIO_2057_VCOCAL_NUMCAPCHANGE 0x1a
1140#define RADIO_2057_VCOCAL_WINSIZE 0x1b
1141#define RADIO_2057_VCOCAL_DELAY_AFTER_REFRESH 0x1c
1142#define RADIO_2057_VCOCAL_DELAY_AFTER_CLOSELOOP 0x1d
1143#define RADIO_2057_VCOCAL_DELAY_AFTER_OPENLOOP 0x1e
1144#define RADIO_2057_VCOCAL_DELAY_BEFORE_OPENLOOP 0x1f
1145#define RADIO_2057_VCO_FORCECAPEN_FORCECAP1 0x20
1146#define RADIO_2057_VCO_FORCECAP0 0x21
1147#define RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE 0x22
1148#define RADIO_2057_RFPLL_PFD_RESET_PW 0x23
1149#define RADIO_2057_RFPLL_LOOPFILTER_R2 0x24
1150#define RADIO_2057_RFPLL_LOOPFILTER_R1 0x25
1151#define RADIO_2057_RFPLL_LOOPFILTER_C3 0x26
1152#define RADIO_2057_RFPLL_LOOPFILTER_C2 0x27
1153#define RADIO_2057_RFPLL_LOOPFILTER_C1 0x28
1154#define RADIO_2057_CP_KPD_IDAC 0x29
1155#define RADIO_2057_RFPLL_IDACS 0x2a
1156#define RADIO_2057_RFPLL_MISC_EN 0x2b
1157#define RADIO_2057_RFPLL_MMD0 0x2c
1158#define RADIO_2057_RFPLL_MMD1 0x2d
1159#define RADIO_2057_RFPLL_MISC_CAL_RESETN 0x2e
1160#define RADIO_2057_JTAGXTAL_SIZE_CPBIAS_FILTRES 0x2f
1161#define RADIO_2057_VCO_ALCREF_BBPLLXTAL_SIZE 0x30
1162#define RADIO_2057_VCOCAL_READCAP0 0x31
1163#define RADIO_2057_VCOCAL_READCAP1 0x32
1164#define RADIO_2057_VCOCAL_STATUS 0x33
1165#define RADIO_2057_LOGEN_PUS 0x34
1166#define RADIO_2057_LOGEN_PTAT_RESETS 0x35
1167#define RADIO_2057_VCOBUF_IDACS 0x36
1168#define RADIO_2057_VCOBUF_TUNE 0x37
1169#define RADIO_2057_CMOSBUF_TX2GQ_IDACS 0x38
1170#define RADIO_2057_CMOSBUF_TX2GI_IDACS 0x39
1171#define RADIO_2057_CMOSBUF_TX5GQ_IDACS 0x3a
1172#define RADIO_2057_CMOSBUF_TX5GI_IDACS 0x3b
1173#define RADIO_2057_CMOSBUF_RX2GQ_IDACS 0x3c
1174#define RADIO_2057_CMOSBUF_RX2GI_IDACS 0x3d
1175#define RADIO_2057_CMOSBUF_RX5GQ_IDACS 0x3e
1176#define RADIO_2057_CMOSBUF_RX5GI_IDACS 0x3f
1177#define RADIO_2057_LOGEN_MX2G_IDACS 0x40
1178#define RADIO_2057_LOGEN_MX2G_TUNE 0x41
1179#define RADIO_2057_LOGEN_MX5G_IDACS 0x42
1180#define RADIO_2057_LOGEN_MX5G_TUNE 0x43
1181#define RADIO_2057_LOGEN_MX5G_RCCR 0x44
1182#define RADIO_2057_LOGEN_INDBUF2G_IDAC 0x45
1183#define RADIO_2057_LOGEN_INDBUF2G_IBOOST 0x46
1184#define RADIO_2057_LOGEN_INDBUF2G_TUNE 0x47
1185#define RADIO_2057_LOGEN_INDBUF5G_IDAC 0x48
1186#define RADIO_2057_LOGEN_INDBUF5G_IBOOST 0x49
1187#define RADIO_2057_LOGEN_INDBUF5G_TUNE 0x4a
1188#define RADIO_2057_CMOSBUF_TX_RCCR 0x4b
1189#define RADIO_2057_CMOSBUF_RX_RCCR 0x4c
1190#define RADIO_2057_LOGEN_SEL_PKDET 0x4d
1191#define RADIO_2057_CMOSBUF_SHAREIQ_PTAT 0x4e
1192#define RADIO_2057_RXTXBIAS_CONFIG_CORE0 0x4f
1193#define RADIO_2057_TXGM_TXRF_PUS_CORE0 0x50
1194#define RADIO_2057_TXGM_IDAC_BLEED_CORE0 0x51
1195#define RADIO_2057_TXGM_GAIN_CORE0 0x56
1196#define RADIO_2057_TXGM2G_PKDET_PUS_CORE0 0x57
1197#define RADIO_2057_PAD2G_PTATS_CORE0 0x58
1198#define RADIO_2057_PAD2G_IDACS_CORE0 0x59
1199#define RADIO_2057_PAD2G_BOOST_PU_CORE0 0x5a
1200#define RADIO_2057_PAD2G_CASCV_GAIN_CORE0 0x5b
1201#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0 0x5c
1202#define RADIO_2057_TXMIX2G_LODC_CORE0 0x5d
1203#define RADIO_2057_PAD2G_TUNE_PUS_CORE0 0x5e
1204#define RADIO_2057_IPA2G_GAIN_CORE0 0x5f
1205#define RADIO_2057_TSSI2G_SPARE1_CORE0 0x60
1206#define RADIO_2057_TSSI2G_SPARE2_CORE0 0x61
1207#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE0 0x62
1208#define RADIO_2057_IPA2G_IMAIN_CORE0 0x63
1209#define RADIO_2057_IPA2G_CASCONV_CORE0 0x64
1210#define RADIO_2057_IPA2G_CASCOFFV_CORE0 0x65
1211#define RADIO_2057_IPA2G_BIAS_FILTER_CORE0 0x66
1212#define RADIO_2057_TX5G_PKDET_CORE0 0x69
1213#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE0 0x6a
1214#define RADIO_2057_PAD5G_PTATS1_CORE0 0x6b
1215#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE0 0x6c
1216#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE0 0x6d
1217#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE0 0x6e
1218#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE0 0x6f
1219#define RADIO_2057_PGA_BOOST_TUNE_CORE0 0x70
1220#define RADIO_2057_PGA_GAIN_CORE0 0x71
1221#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE0 0x72
1222#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0 0x73
1223#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0 0x74
1224#define RADIO_2057_IPA5G_IAUX_CORE0 0x75
1225#define RADIO_2057_IPA5G_GAIN_CORE0 0x76
1226#define RADIO_2057_TSSI5G_SPARE1_CORE0 0x77
1227#define RADIO_2057_TSSI5G_SPARE2_CORE0 0x78
1228#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE0 0x79
1229#define RADIO_2057_IPA5G_PTAT_CORE0 0x7a
1230#define RADIO_2057_IPA5G_IMAIN_CORE0 0x7b
1231#define RADIO_2057_IPA5G_CASCONV_CORE0 0x7c
1232#define RADIO_2057_IPA5G_BIAS_FILTER_CORE0 0x7d
1233#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE0 0x80
1234#define RADIO_2057_TR2G_CONFIG1_CORE0_NU 0x81
1235#define RADIO_2057_TR2G_CONFIG2_CORE0_NU 0x82
1236#define RADIO_2057_LNA5G_RFEN_CORE0 0x83
1237#define RADIO_2057_TR5G_CONFIG2_CORE0_NU 0x84
1238#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE0 0x85
1239#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE0 0x86
1240#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE0 0x87
1241#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE0 0x88
1242#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE0 0x89
1243#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE0 0x8a
1244#define RADIO_2057_LNA2_IAUX_PTAT_CORE0 0x8b
1245#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE0 0x8c
1246#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE0 0x8d
1247#define RADIO_2057_RXRFBIAS_BANDSEL_CORE0 0x8e
1248#define RADIO_2057_TIA_CONFIG_CORE0 0x8f
1249#define RADIO_2057_TIA_IQGAIN_CORE0 0x90
1250#define RADIO_2057_TIA_IBIAS2_CORE0 0x91
1251#define RADIO_2057_TIA_IBIAS1_CORE0 0x92
1252#define RADIO_2057_TIA_SPARE_Q_CORE0 0x93
1253#define RADIO_2057_TIA_SPARE_I_CORE0 0x94
1254#define RADIO_2057_RXMIX2G_PUS_CORE0 0x95
1255#define RADIO_2057_RXMIX2G_VCMREFS_CORE0 0x96
1256#define RADIO_2057_RXMIX2G_LODC_QI_CORE0 0x97
1257#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE0 0x98
1258#define RADIO_2057_LNA2G_GAIN_CORE0 0x99
1259#define RADIO_2057_LNA2G_TUNE_CORE0 0x9a
1260#define RADIO_2057_RXMIX5G_PUS_CORE0 0x9b
1261#define RADIO_2057_RXMIX5G_VCMREFS_CORE0 0x9c
1262#define RADIO_2057_RXMIX5G_LODC_QI_CORE0 0x9d
1263#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE0 0x9e
1264#define RADIO_2057_LNA5G_GAIN_CORE0 0x9f
1265#define RADIO_2057_LNA5G_TUNE_CORE0 0xa0
1266#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE0 0xa1
1267#define RADIO_2057_RXBB_BIAS_MASTER_CORE0 0xa2
1268#define RADIO_2057_RXBB_VGABUF_IDACS_CORE0 0xa3
1269#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE0 0xa4
1270#define RADIO_2057_TXBUF_VINCM_CORE0 0xa5
1271#define RADIO_2057_TXBUF_IDACS_CORE0 0xa6
1272#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE0 0xa7
1273#define RADIO_2057_RXBB_CC_CORE0 0xa8
1274#define RADIO_2057_RXBB_SPARE3_CORE0 0xa9
1275#define RADIO_2057_RXBB_RCCAL_HPC_CORE0 0xaa
1276#define RADIO_2057_LPF_IDACS_CORE0 0xab
1277#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE0 0xac
1278#define RADIO_2057_TXBUF_GAIN_CORE0 0xad
1279#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE0 0xae
1280#define RADIO_2057_RXBUF_DEGEN_CORE0 0xaf
1281#define RADIO_2057_RXBB_SPARE2_CORE0 0xb0
1282#define RADIO_2057_RXBB_SPARE1_CORE0 0xb1
1283#define RADIO_2057_RSSI_MASTER_CORE0 0xb2
1284#define RADIO_2057_W2_MASTER_CORE0 0xb3
1285#define RADIO_2057_NB_MASTER_CORE0 0xb4
1286#define RADIO_2057_W2_IDACS0_Q_CORE0 0xb5
1287#define RADIO_2057_W2_IDACS1_Q_CORE0 0xb6
1288#define RADIO_2057_W2_IDACS0_I_CORE0 0xb7
1289#define RADIO_2057_W2_IDACS1_I_CORE0 0xb8
1290#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE0 0xb9
1291#define RADIO_2057_NB_IDACS_Q_CORE0 0xba
1292#define RADIO_2057_NB_IDACS_I_CORE0 0xbb
1293#define RADIO_2057_BACKUP4_CORE0 0xc1
1294#define RADIO_2057_BACKUP3_CORE0 0xc2
1295#define RADIO_2057_BACKUP2_CORE0 0xc3
1296#define RADIO_2057_BACKUP1_CORE0 0xc4
1297#define RADIO_2057_SPARE16_CORE0 0xc5
1298#define RADIO_2057_SPARE15_CORE0 0xc6
1299#define RADIO_2057_SPARE14_CORE0 0xc7
1300#define RADIO_2057_SPARE13_CORE0 0xc8
1301#define RADIO_2057_SPARE12_CORE0 0xc9
1302#define RADIO_2057_SPARE11_CORE0 0xca
1303#define RADIO_2057_TX2G_BIAS_RESETS_CORE0 0xcb
1304#define RADIO_2057_TX5G_BIAS_RESETS_CORE0 0xcc
1305#define RADIO_2057_IQTEST_SEL_PU 0xcd
1306#define RADIO_2057_XTAL_CONFIG2 0xce
1307#define RADIO_2057_BUFS_MISC_LPFBW_CORE0 0xcf
1308#define RADIO_2057_TXLPF_RCCAL_CORE0 0xd0
1309#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0 0xd1
1310#define RADIO_2057_LPF_GAIN_CORE0 0xd2
1311#define RADIO_2057_DACBUF_IDACS_BW_CORE0 0xd3
1312#define RADIO_2057_RXTXBIAS_CONFIG_CORE1 0xd4
1313#define RADIO_2057_TXGM_TXRF_PUS_CORE1 0xd5
1314#define RADIO_2057_TXGM_IDAC_BLEED_CORE1 0xd6
1315#define RADIO_2057_TXGM_GAIN_CORE1 0xdb
1316#define RADIO_2057_TXGM2G_PKDET_PUS_CORE1 0xdc
1317#define RADIO_2057_PAD2G_PTATS_CORE1 0xdd
1318#define RADIO_2057_PAD2G_IDACS_CORE1 0xde
1319#define RADIO_2057_PAD2G_BOOST_PU_CORE1 0xdf
1320#define RADIO_2057_PAD2G_CASCV_GAIN_CORE1 0xe0
1321#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1 0xe1
1322#define RADIO_2057_TXMIX2G_LODC_CORE1 0xe2
1323#define RADIO_2057_PAD2G_TUNE_PUS_CORE1 0xe3
1324#define RADIO_2057_IPA2G_GAIN_CORE1 0xe4
1325#define RADIO_2057_TSSI2G_SPARE1_CORE1 0xe5
1326#define RADIO_2057_TSSI2G_SPARE2_CORE1 0xe6
1327#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE1 0xe7
1328#define RADIO_2057_IPA2G_IMAIN_CORE1 0xe8
1329#define RADIO_2057_IPA2G_CASCONV_CORE1 0xe9
1330#define RADIO_2057_IPA2G_CASCOFFV_CORE1 0xea
1331#define RADIO_2057_IPA2G_BIAS_FILTER_CORE1 0xeb
1332#define RADIO_2057_TX5G_PKDET_CORE1 0xee
1333#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE1 0xef
1334#define RADIO_2057_PAD5G_PTATS1_CORE1 0xf0
1335#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE1 0xf1
1336#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE1 0xf2
1337#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE1 0xf3
1338#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE1 0xf4
1339#define RADIO_2057_PGA_BOOST_TUNE_CORE1 0xf5
1340#define RADIO_2057_PGA_GAIN_CORE1 0xf6
1341#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE1 0xf7
1342#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1 0xf8
1343#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1 0xf9
1344#define RADIO_2057_IPA5G_IAUX_CORE1 0xfa
1345#define RADIO_2057_IPA5G_GAIN_CORE1 0xfb
1346#define RADIO_2057_TSSI5G_SPARE1_CORE1 0xfc
1347#define RADIO_2057_TSSI5G_SPARE2_CORE1 0xfd
1348#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE1 0xfe
1349#define RADIO_2057_IPA5G_PTAT_CORE1 0xff
1350#define RADIO_2057_IPA5G_IMAIN_CORE1 0x100
1351#define RADIO_2057_IPA5G_CASCONV_CORE1 0x101
1352#define RADIO_2057_IPA5G_BIAS_FILTER_CORE1 0x102
1353#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE1 0x105
1354#define RADIO_2057_TR2G_CONFIG1_CORE1_NU 0x106
1355#define RADIO_2057_TR2G_CONFIG2_CORE1_NU 0x107
1356#define RADIO_2057_LNA5G_RFEN_CORE1 0x108
1357#define RADIO_2057_TR5G_CONFIG2_CORE1_NU 0x109
1358#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE1 0x10a
1359#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE1 0x10b
1360#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE1 0x10c
1361#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE1 0x10d
1362#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE1 0x10e
1363#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE1 0x10f
1364#define RADIO_2057_LNA2_IAUX_PTAT_CORE1 0x110
1365#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE1 0x111
1366#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE1 0x112
1367#define RADIO_2057_RXRFBIAS_BANDSEL_CORE1 0x113
1368#define RADIO_2057_TIA_CONFIG_CORE1 0x114
1369#define RADIO_2057_TIA_IQGAIN_CORE1 0x115
1370#define RADIO_2057_TIA_IBIAS2_CORE1 0x116
1371#define RADIO_2057_TIA_IBIAS1_CORE1 0x117
1372#define RADIO_2057_TIA_SPARE_Q_CORE1 0x118
1373#define RADIO_2057_TIA_SPARE_I_CORE1 0x119
1374#define RADIO_2057_RXMIX2G_PUS_CORE1 0x11a
1375#define RADIO_2057_RXMIX2G_VCMREFS_CORE1 0x11b
1376#define RADIO_2057_RXMIX2G_LODC_QI_CORE1 0x11c
1377#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE1 0x11d
1378#define RADIO_2057_LNA2G_GAIN_CORE1 0x11e
1379#define RADIO_2057_LNA2G_TUNE_CORE1 0x11f
1380#define RADIO_2057_RXMIX5G_PUS_CORE1 0x120
1381#define RADIO_2057_RXMIX5G_VCMREFS_CORE1 0x121
1382#define RADIO_2057_RXMIX5G_LODC_QI_CORE1 0x122
1383#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE1 0x123
1384#define RADIO_2057_LNA5G_GAIN_CORE1 0x124
1385#define RADIO_2057_LNA5G_TUNE_CORE1 0x125
1386#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE1 0x126
1387#define RADIO_2057_RXBB_BIAS_MASTER_CORE1 0x127
1388#define RADIO_2057_RXBB_VGABUF_IDACS_CORE1 0x128
1389#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE1 0x129
1390#define RADIO_2057_TXBUF_VINCM_CORE1 0x12a
1391#define RADIO_2057_TXBUF_IDACS_CORE1 0x12b
1392#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE1 0x12c
1393#define RADIO_2057_RXBB_CC_CORE1 0x12d
1394#define RADIO_2057_RXBB_SPARE3_CORE1 0x12e
1395#define RADIO_2057_RXBB_RCCAL_HPC_CORE1 0x12f
1396#define RADIO_2057_LPF_IDACS_CORE1 0x130
1397#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE1 0x131
1398#define RADIO_2057_TXBUF_GAIN_CORE1 0x132
1399#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE1 0x133
1400#define RADIO_2057_RXBUF_DEGEN_CORE1 0x134
1401#define RADIO_2057_RXBB_SPARE2_CORE1 0x135
1402#define RADIO_2057_RXBB_SPARE1_CORE1 0x136
1403#define RADIO_2057_RSSI_MASTER_CORE1 0x137
1404#define RADIO_2057_W2_MASTER_CORE1 0x138
1405#define RADIO_2057_NB_MASTER_CORE1 0x139
1406#define RADIO_2057_W2_IDACS0_Q_CORE1 0x13a
1407#define RADIO_2057_W2_IDACS1_Q_CORE1 0x13b
1408#define RADIO_2057_W2_IDACS0_I_CORE1 0x13c
1409#define RADIO_2057_W2_IDACS1_I_CORE1 0x13d
1410#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE1 0x13e
1411#define RADIO_2057_NB_IDACS_Q_CORE1 0x13f
1412#define RADIO_2057_NB_IDACS_I_CORE1 0x140
1413#define RADIO_2057_BACKUP4_CORE1 0x146
1414#define RADIO_2057_BACKUP3_CORE1 0x147
1415#define RADIO_2057_BACKUP2_CORE1 0x148
1416#define RADIO_2057_BACKUP1_CORE1 0x149
1417#define RADIO_2057_SPARE16_CORE1 0x14a
1418#define RADIO_2057_SPARE15_CORE1 0x14b
1419#define RADIO_2057_SPARE14_CORE1 0x14c
1420#define RADIO_2057_SPARE13_CORE1 0x14d
1421#define RADIO_2057_SPARE12_CORE1 0x14e
1422#define RADIO_2057_SPARE11_CORE1 0x14f
1423#define RADIO_2057_TX2G_BIAS_RESETS_CORE1 0x150
1424#define RADIO_2057_TX5G_BIAS_RESETS_CORE1 0x151
1425#define RADIO_2057_SPARE8_CORE1 0x152
1426#define RADIO_2057_SPARE7_CORE1 0x153
1427#define RADIO_2057_BUFS_MISC_LPFBW_CORE1 0x154
1428#define RADIO_2057_TXLPF_RCCAL_CORE1 0x155
1429#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1 0x156
1430#define RADIO_2057_LPF_GAIN_CORE1 0x157
1431#define RADIO_2057_DACBUF_IDACS_BW_CORE1 0x158
1432#define RADIO_2057_DACBUF_VINCM_CORE1 0x159
1433#define RADIO_2057_RCCAL_START_R1_Q1_P1 0x15a
1434#define RADIO_2057_RCCAL_X1 0x15b
1435#define RADIO_2057_RCCAL_TRC0 0x15c
1436#define RADIO_2057_RCCAL_TRC1 0x15d
1437#define RADIO_2057_RCCAL_DONE_OSCCAP 0x15e
1438#define RADIO_2057_RCCAL_N0_0 0x15f
1439#define RADIO_2057_RCCAL_N0_1 0x160
1440#define RADIO_2057_RCCAL_N1_0 0x161
1441#define RADIO_2057_RCCAL_N1_1 0x162
1442#define RADIO_2057_RCAL_STATUS 0x163
1443#define RADIO_2057_XTALPUOVR_PINCTRL 0x164
1444#define RADIO_2057_OVR_REG0 0x165
1445#define RADIO_2057_OVR_REG1 0x166
1446#define RADIO_2057_OVR_REG2 0x167
1447#define RADIO_2057_OVR_REG3 0x168
1448#define RADIO_2057_OVR_REG4 0x169
1449#define RADIO_2057_RCCAL_SCAP_VAL 0x16a
1450#define RADIO_2057_RCCAL_BCAP_VAL 0x16b
1451#define RADIO_2057_RCCAL_HPC_VAL 0x16c
1452#define RADIO_2057_RCCAL_OVERRIDES 0x16d
1453#define RADIO_2057_TX0_IQCAL_GAIN_BW 0x170
1454#define RADIO_2057_TX0_LOFT_FINE_I 0x171
1455#define RADIO_2057_TX0_LOFT_FINE_Q 0x172
1456#define RADIO_2057_TX0_LOFT_COARSE_I 0x173
1457#define RADIO_2057_TX0_LOFT_COARSE_Q 0x174
1458#define RADIO_2057_TX0_TX_SSI_MASTER 0x175
1459#define RADIO_2057_TX0_IQCAL_VCM_HG 0x176
1460#define RADIO_2057_TX0_IQCAL_IDAC 0x177
1461#define RADIO_2057_TX0_TSSI_VCM 0x178
1462#define RADIO_2057_TX0_TX_SSI_MUX 0x179
1463#define RADIO_2057_TX0_TSSIA 0x17a
1464#define RADIO_2057_TX0_TSSIG 0x17b
1465#define RADIO_2057_TX0_TSSI_MISC1 0x17c
1466#define RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN 0x17d
1467#define RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP 0x17e
1468#define RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN 0x17f
1469#define RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP 0x180
1470#define RADIO_2057_TX1_IQCAL_GAIN_BW 0x190
1471#define RADIO_2057_TX1_LOFT_FINE_I 0x191
1472#define RADIO_2057_TX1_LOFT_FINE_Q 0x192
1473#define RADIO_2057_TX1_LOFT_COARSE_I 0x193
1474#define RADIO_2057_TX1_LOFT_COARSE_Q 0x194
1475#define RADIO_2057_TX1_TX_SSI_MASTER 0x195
1476#define RADIO_2057_TX1_IQCAL_VCM_HG 0x196
1477#define RADIO_2057_TX1_IQCAL_IDAC 0x197
1478#define RADIO_2057_TX1_TSSI_VCM 0x198
1479#define RADIO_2057_TX1_TX_SSI_MUX 0x199
1480#define RADIO_2057_TX1_TSSIA 0x19a
1481#define RADIO_2057_TX1_TSSIG 0x19b
1482#define RADIO_2057_TX1_TSSI_MISC1 0x19c
1483#define RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN 0x19d
1484#define RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP 0x19e
1485#define RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN 0x19f
1486#define RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP 0x1a0
1487#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE0 0x1a1
1488#define RADIO_2057_AFE_SET_VCM_I_CORE0 0x1a2
1489#define RADIO_2057_AFE_SET_VCM_Q_CORE0 0x1a3
1490#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE0 0x1a4
1491#define RADIO_2057_AFE_STATUS_VCM_I_CORE0 0x1a5
1492#define RADIO_2057_AFE_STATUS_VCM_Q_CORE0 0x1a6
1493#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE1 0x1a7
1494#define RADIO_2057_AFE_SET_VCM_I_CORE1 0x1a8
1495#define RADIO_2057_AFE_SET_VCM_Q_CORE1 0x1a9
1496#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE1 0x1aa
1497#define RADIO_2057_AFE_STATUS_VCM_I_CORE1 0x1ab
1498#define RADIO_2057_AFE_STATUS_VCM_Q_CORE1 0x1ac
1499
1500#define RADIO_2057v7_DACBUF_VINCM_CORE0 0x1ad
1501#define RADIO_2057v7_RCCAL_MASTER 0x1ae
1502#define RADIO_2057v7_TR2G_CONFIG3_CORE0_NU 0x1af
1503#define RADIO_2057v7_TR2G_CONFIG3_CORE1_NU 0x1b0
1504#define RADIO_2057v7_LOGEN_PUS1 0x1b1
1505#define RADIO_2057v7_OVR_REG5 0x1b2
1506#define RADIO_2057v7_OVR_REG6 0x1b3
1507#define RADIO_2057v7_OVR_REG7 0x1b4
1508#define RADIO_2057v7_OVR_REG8 0x1b5
1509#define RADIO_2057v7_OVR_REG9 0x1b6
1510#define RADIO_2057v7_OVR_REG10 0x1b7
1511#define RADIO_2057v7_OVR_REG11 0x1b8
1512#define RADIO_2057v7_OVR_REG12 0x1b9
1513#define RADIO_2057v7_OVR_REG13 0x1ba
1514#define RADIO_2057v7_OVR_REG14 0x1bb
1515#define RADIO_2057v7_OVR_REG15 0x1bc
1516#define RADIO_2057v7_OVR_REG16 0x1bd
1517#define RADIO_2057v7_OVR_REG1 0x1be
1518#define RADIO_2057v7_OVR_REG18 0x1bf
1519#define RADIO_2057v7_OVR_REG19 0x1c0
1520#define RADIO_2057v7_OVR_REG20 0x1c1
1521#define RADIO_2057v7_OVR_REG21 0x1c2
1522#define RADIO_2057v7_OVR_REG2 0x1c3
1523#define RADIO_2057v7_OVR_REG23 0x1c4
1524#define RADIO_2057v7_OVR_REG24 0x1c5
1525#define RADIO_2057v7_OVR_REG25 0x1c6
1526#define RADIO_2057v7_OVR_REG26 0x1c7
1527#define RADIO_2057v7_OVR_REG27 0x1c8
1528#define RADIO_2057v7_OVR_REG28 0x1c9
1529#define RADIO_2057v7_IQTEST_SEL_PU2 0x1ca
1530
1531#define RADIO_2057_VCM_MASK 0x7
1532
1533#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 000000000000..a97c3a799479
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
@@ -0,0 +1,167 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#define NPHY_TBL_ID_GAIN1 0
18#define NPHY_TBL_ID_GAIN2 1
19#define NPHY_TBL_ID_GAINBITS1 2
20#define NPHY_TBL_ID_GAINBITS2 3
21#define NPHY_TBL_ID_GAINLIMIT 4
22#define NPHY_TBL_ID_WRSSIGainLimit 5
23#define NPHY_TBL_ID_RFSEQ 7
24#define NPHY_TBL_ID_AFECTRL 8
25#define NPHY_TBL_ID_ANTSWCTRLLUT 9
26#define NPHY_TBL_ID_IQLOCAL 15
27#define NPHY_TBL_ID_NOISEVAR 16
28#define NPHY_TBL_ID_SAMPLEPLAY 17
29#define NPHY_TBL_ID_CORE1TXPWRCTL 26
30#define NPHY_TBL_ID_CORE2TXPWRCTL 27
31#define NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL 30
32
33#define NPHY_TBL_ID_EPSILONTBL0 31
34#define NPHY_TBL_ID_SCALARTBL0 32
35#define NPHY_TBL_ID_EPSILONTBL1 33
36#define NPHY_TBL_ID_SCALARTBL1 34
37
38#define NPHY_TO_BPHY_OFF 0xc00
39
40#define NPHY_BandControl_currentBand 0x0001
41#define RFCC_CHIP0_PU 0x0400
42#define RFCC_POR_FORCE 0x0040
43#define RFCC_OE_POR_FORCE 0x0080
44#define NPHY_RfctrlIntc_override_OFF 0
45#define NPHY_RfctrlIntc_override_TRSW 1
46#define NPHY_RfctrlIntc_override_PA 2
47#define NPHY_RfctrlIntc_override_EXT_LNA_PU 3
48#define NPHY_RfctrlIntc_override_EXT_LNA_GAIN 4
49#define RIFS_ENABLE 0x80
50#define BPHY_BAND_SEL_UP20 0x10
51#define NPHY_MLenable 0x02
52
53#define NPHY_RfseqMode_CoreActv_override 0x0001
54#define NPHY_RfseqMode_Trigger_override 0x0002
55#define NPHY_RfseqCoreActv_TxRxChain0 (0x11)
56#define NPHY_RfseqCoreActv_TxRxChain1 (0x22)
57
58#define NPHY_RfseqTrigger_rx2tx 0x0001
59#define NPHY_RfseqTrigger_tx2rx 0x0002
60#define NPHY_RfseqTrigger_updategainh 0x0004
61#define NPHY_RfseqTrigger_updategainl 0x0008
62#define NPHY_RfseqTrigger_updategainu 0x0010
63#define NPHY_RfseqTrigger_reset2rx 0x0020
64#define NPHY_RfseqStatus_rx2tx 0x0001
65#define NPHY_RfseqStatus_tx2rx 0x0002
66#define NPHY_RfseqStatus_updategainh 0x0004
67#define NPHY_RfseqStatus_updategainl 0x0008
68#define NPHY_RfseqStatus_updategainu 0x0010
69#define NPHY_RfseqStatus_reset2rx 0x0020
70#define NPHY_ClassifierCtrl_cck_en 0x1
71#define NPHY_ClassifierCtrl_ofdm_en 0x2
72#define NPHY_ClassifierCtrl_waited_en 0x4
73#define NPHY_IQFlip_ADC1 0x0001
74#define NPHY_IQFlip_ADC2 0x0010
75#define NPHY_sampleCmd_STOP 0x0002
76
77#define RX_GF_OR_MM 0x0004
78#define RX_GF_MM_AUTO 0x0100
79
80#define NPHY_iqloCalCmdGctl_IQLO_CAL_EN 0x8000
81
82#define NPHY_IqestCmd_iqstart 0x1
83#define NPHY_IqestCmd_iqMode 0x2
84
85#define NPHY_TxPwrCtrlCmd_pwrIndex_init 0x40
86#define NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 0x19
87
88#define PRIM_SEL_UP20 0x8000
89
90#define NPHY_RFSEQ_RX2TX 0x0
91#define NPHY_RFSEQ_TX2RX 0x1
92#define NPHY_RFSEQ_RESET2RX 0x2
93#define NPHY_RFSEQ_UPDATEGAINH 0x3
94#define NPHY_RFSEQ_UPDATEGAINL 0x4
95#define NPHY_RFSEQ_UPDATEGAINU 0x5
96
97#define NPHY_RFSEQ_CMD_NOP 0x0
98#define NPHY_RFSEQ_CMD_RXG_FBW 0x1
99#define NPHY_RFSEQ_CMD_TR_SWITCH 0x2
100#define NPHY_RFSEQ_CMD_EXT_PA 0x3
101#define NPHY_RFSEQ_CMD_RXPD_TXPD 0x4
102#define NPHY_RFSEQ_CMD_TX_GAIN 0x5
103#define NPHY_RFSEQ_CMD_RX_GAIN 0x6
104#define NPHY_RFSEQ_CMD_SET_HPF_BW 0x7
105#define NPHY_RFSEQ_CMD_CLR_HIQ_DIS 0x8
106#define NPHY_RFSEQ_CMD_END 0xf
107
108#define NPHY_REV3_RFSEQ_CMD_NOP 0x0
109#define NPHY_REV3_RFSEQ_CMD_RXG_FBW 0x1
110#define NPHY_REV3_RFSEQ_CMD_TR_SWITCH 0x2
111#define NPHY_REV3_RFSEQ_CMD_INT_PA_PU 0x3
112#define NPHY_REV3_RFSEQ_CMD_EXT_PA 0x4
113#define NPHY_REV3_RFSEQ_CMD_RXPD_TXPD 0x5
114#define NPHY_REV3_RFSEQ_CMD_TX_GAIN 0x6
115#define NPHY_REV3_RFSEQ_CMD_RX_GAIN 0x7
116#define NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS 0x8
117#define NPHY_REV3_RFSEQ_CMD_SET_HPF_H_HPC 0x9
118#define NPHY_REV3_RFSEQ_CMD_SET_LPF_H_HPC 0xa
119#define NPHY_REV3_RFSEQ_CMD_SET_HPF_M_HPC 0xb
120#define NPHY_REV3_RFSEQ_CMD_SET_LPF_M_HPC 0xc
121#define NPHY_REV3_RFSEQ_CMD_SET_HPF_L_HPC 0xd
122#define NPHY_REV3_RFSEQ_CMD_SET_LPF_L_HPC 0xe
123#define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS 0xf
124#define NPHY_REV3_RFSEQ_CMD_END 0x1f
125
126#define NPHY_RSSI_SEL_W1 0x0
127#define NPHY_RSSI_SEL_W2 0x1
128#define NPHY_RSSI_SEL_NB 0x2
129#define NPHY_RSSI_SEL_IQ 0x3
130#define NPHY_RSSI_SEL_TSSI_2G 0x4
131#define NPHY_RSSI_SEL_TSSI_5G 0x5
132#define NPHY_RSSI_SEL_TBD 0x6
133
134#define NPHY_RAIL_I 0x0
135#define NPHY_RAIL_Q 0x1
136
137#define NPHY_FORCESIG_DECODEGATEDCLKS 0x8
138
139#define NPHY_REV7_RfctrlOverride_cmd_rxrf_pu 0x0
140#define NPHY_REV7_RfctrlOverride_cmd_rx_pu 0x1
141#define NPHY_REV7_RfctrlOverride_cmd_tx_pu 0x2
142#define NPHY_REV7_RfctrlOverride_cmd_rxgain 0x3
143#define NPHY_REV7_RfctrlOverride_cmd_txgain 0x4
144
145#define NPHY_REV7_RXGAINCODE_RFMXGAIN_MASK 0x000ff
146#define NPHY_REV7_RXGAINCODE_LPFGAIN_MASK 0x0ff00
147#define NPHY_REV7_RXGAINCODE_DVGAGAIN_MASK 0xf0000
148
149#define NPHY_REV7_TXGAINCODE_TGAIN_MASK 0x7fff
150#define NPHY_REV7_TXGAINCODE_LPFGAIN_MASK 0x8000
151#define NPHY_REV7_TXGAINCODE_BIQ0GAIN_SHIFT 14
152
153#define NPHY_REV7_RFCTRLOVERRIDE_ID0 0x0
154#define NPHY_REV7_RFCTRLOVERRIDE_ID1 0x1
155#define NPHY_REV7_RFCTRLOVERRIDE_ID2 0x2
156
157#define NPHY_IqestIqAccLo(core) ((core == 0) ? 0x12c : 0x134)
158
159#define NPHY_IqestIqAccHi(core) ((core == 0) ? 0x12d : 0x135)
160
161#define NPHY_IqestipwrAccLo(core) ((core == 0) ? 0x12e : 0x136)
162
163#define NPHY_IqestipwrAccHi(core) ((core == 0) ? 0x12f : 0x137)
164
165#define NPHY_IqestqpwrAccLo(core) ((core == 0) ? 0x130 : 0x138)
166
167#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 000000000000..622c01ca72c5
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
@@ -0,0 +1,3250 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <types.h>
18#include "phytbl_lcn.h"
19
20static const u32 dot11lcn_gain_tbl_rev0[] = {
21 0x00000000,
22 0x00000000,
23 0x00000000,
24 0x00000000,
25 0x00000000,
26 0x00000000,
27 0x00000000,
28 0x00000000,
29 0x00000004,
30 0x00000000,
31 0x00000004,
32 0x00000008,
33 0x00000001,
34 0x00000005,
35 0x00000009,
36 0x0000000d,
37 0x0000004d,
38 0x0000008d,
39 0x0000000d,
40 0x0000004d,
41 0x0000008d,
42 0x000000cd,
43 0x0000004f,
44 0x0000008f,
45 0x000000cf,
46 0x000000d3,
47 0x00000113,
48 0x00000513,
49 0x00000913,
50 0x00000953,
51 0x00000d53,
52 0x00001153,
53 0x00001193,
54 0x00005193,
55 0x00009193,
56 0x0000d193,
57 0x00011193,
58 0x00000000,
59 0x00000000,
60 0x00000000,
61 0x00000000,
62 0x00000000,
63 0x00000000,
64 0x00000004,
65 0x00000000,
66 0x00000004,
67 0x00000008,
68 0x00000001,
69 0x00000005,
70 0x00000009,
71 0x0000000d,
72 0x0000004d,
73 0x0000008d,
74 0x0000000d,
75 0x0000004d,
76 0x0000008d,
77 0x000000cd,
78 0x0000004f,
79 0x0000008f,
80 0x000000cf,
81 0x000000d3,
82 0x00000113,
83 0x00000513,
84 0x00000913,
85 0x00000953,
86 0x00000d53,
87 0x00001153,
88 0x00005153,
89 0x00009153,
90 0x0000d153,
91 0x00011153,
92 0x00015153,
93 0x00019153,
94 0x0001d153,
95 0x00000000,
96 0x00000000,
97 0x00000000,
98 0x00000000,
99 0x00000000,
100 0x00000000,
101 0x00000000,
102 0x00000000,
103 0x00000000,
104 0x00000000,
105 0x00000000,
106 0x00000000,
107 0x00000000,
108 0x00000000,
109 0x00000000,
110 0x00000000,
111 0x00000000,
112 0x00000000,
113 0x00000000,
114 0x00000000,
115 0x00000000,
116 0x00000000,
117};
118
119static const u32 dot11lcn_gain_tbl_rev1[] = {
120 0x00000000,
121 0x00000000,
122 0x00000000,
123 0x00000000,
124 0x00000000,
125 0x00000000,
126 0x00000000,
127 0x00000000,
128 0x00000008,
129 0x00000004,
130 0x00000008,
131 0x00000001,
132 0x00000005,
133 0x00000009,
134 0x0000000D,
135 0x00000011,
136 0x00000051,
137 0x00000091,
138 0x00000011,
139 0x00000051,
140 0x00000091,
141 0x000000d1,
142 0x00000053,
143 0x00000093,
144 0x000000d3,
145 0x000000d7,
146 0x00000117,
147 0x00000517,
148 0x00000917,
149 0x00000957,
150 0x00000d57,
151 0x00001157,
152 0x00001197,
153 0x00005197,
154 0x00009197,
155 0x0000d197,
156 0x00011197,
157 0x00000000,
158 0x00000000,
159 0x00000000,
160 0x00000000,
161 0x00000000,
162 0x00000000,
163 0x00000008,
164 0x00000004,
165 0x00000008,
166 0x00000001,
167 0x00000005,
168 0x00000009,
169 0x0000000D,
170 0x00000011,
171 0x00000051,
172 0x00000091,
173 0x00000011,
174 0x00000051,
175 0x00000091,
176 0x000000d1,
177 0x00000053,
178 0x00000093,
179 0x000000d3,
180 0x000000d7,
181 0x00000117,
182 0x00000517,
183 0x00000917,
184 0x00000957,
185 0x00000d57,
186 0x00001157,
187 0x00005157,
188 0x00009157,
189 0x0000d157,
190 0x00011157,
191 0x00015157,
192 0x00019157,
193 0x0001d157,
194 0x00000000,
195 0x00000000,
196 0x00000000,
197 0x00000000,
198 0x00000000,
199 0x00000000,
200 0x00000000,
201 0x00000000,
202 0x00000000,
203 0x00000000,
204 0x00000000,
205 0x00000000,
206 0x00000000,
207 0x00000000,
208 0x00000000,
209 0x00000000,
210 0x00000000,
211 0x00000000,
212 0x00000000,
213 0x00000000,
214 0x00000000,
215 0x00000000,
216};
217
218static const u16 dot11lcn_aux_gain_idx_tbl_rev0[] = {
219 0x0401,
220 0x0402,
221 0x0403,
222 0x0404,
223 0x0405,
224 0x0406,
225 0x0407,
226 0x0408,
227 0x0409,
228 0x040a,
229 0x058b,
230 0x058c,
231 0x058d,
232 0x058e,
233 0x058f,
234 0x0090,
235 0x0091,
236 0x0092,
237 0x0193,
238 0x0194,
239 0x0195,
240 0x0196,
241 0x0197,
242 0x0198,
243 0x0199,
244 0x019a,
245 0x019b,
246 0x019c,
247 0x019d,
248 0x019e,
249 0x019f,
250 0x01a0,
251 0x01a1,
252 0x01a2,
253 0x01a3,
254 0x01a4,
255 0x01a5,
256 0x0000,
257};
258
259static const u32 dot11lcn_gain_idx_tbl_rev0[] = {
260 0x00000000,
261 0x00000000,
262 0x10000000,
263 0x00000000,
264 0x20000000,
265 0x00000000,
266 0x30000000,
267 0x00000000,
268 0x40000000,
269 0x00000000,
270 0x50000000,
271 0x00000000,
272 0x60000000,
273 0x00000000,
274 0x70000000,
275 0x00000000,
276 0x80000000,
277 0x00000000,
278 0x90000000,
279 0x00000008,
280 0xa0000000,
281 0x00000008,
282 0xb0000000,
283 0x00000008,
284 0xc0000000,
285 0x00000008,
286 0xd0000000,
287 0x00000008,
288 0xe0000000,
289 0x00000008,
290 0xf0000000,
291 0x00000008,
292 0x00000000,
293 0x00000009,
294 0x10000000,
295 0x00000009,
296 0x20000000,
297 0x00000019,
298 0x30000000,
299 0x00000019,
300 0x40000000,
301 0x00000019,
302 0x50000000,
303 0x00000019,
304 0x60000000,
305 0x00000019,
306 0x70000000,
307 0x00000019,
308 0x80000000,
309 0x00000019,
310 0x90000000,
311 0x00000019,
312 0xa0000000,
313 0x00000019,
314 0xb0000000,
315 0x00000019,
316 0xc0000000,
317 0x00000019,
318 0xd0000000,
319 0x00000019,
320 0xe0000000,
321 0x00000019,
322 0xf0000000,
323 0x00000019,
324 0x00000000,
325 0x0000001a,
326 0x10000000,
327 0x0000001a,
328 0x20000000,
329 0x0000001a,
330 0x30000000,
331 0x0000001a,
332 0x40000000,
333 0x0000001a,
334 0x50000000,
335 0x00000002,
336 0x60000000,
337 0x00000002,
338 0x70000000,
339 0x00000002,
340 0x80000000,
341 0x00000002,
342 0x90000000,
343 0x00000002,
344 0xa0000000,
345 0x00000002,
346 0xb0000000,
347 0x00000002,
348 0xc0000000,
349 0x0000000a,
350 0xd0000000,
351 0x0000000a,
352 0xe0000000,
353 0x0000000a,
354 0xf0000000,
355 0x0000000a,
356 0x00000000,
357 0x0000000b,
358 0x10000000,
359 0x0000000b,
360 0x20000000,
361 0x0000000b,
362 0x30000000,
363 0x0000000b,
364 0x40000000,
365 0x0000000b,
366 0x50000000,
367 0x0000001b,
368 0x60000000,
369 0x0000001b,
370 0x70000000,
371 0x0000001b,
372 0x80000000,
373 0x0000001b,
374 0x90000000,
375 0x0000001b,
376 0xa0000000,
377 0x0000001b,
378 0xb0000000,
379 0x0000001b,
380 0xc0000000,
381 0x0000001b,
382 0xd0000000,
383 0x0000001b,
384 0xe0000000,
385 0x0000001b,
386 0xf0000000,
387 0x0000001b,
388 0x00000000,
389 0x0000001c,
390 0x10000000,
391 0x0000001c,
392 0x20000000,
393 0x0000001c,
394 0x30000000,
395 0x0000001c,
396 0x40000000,
397 0x0000001c,
398 0x50000000,
399 0x0000001c,
400 0x60000000,
401 0x0000001c,
402 0x70000000,
403 0x0000001c,
404 0x80000000,
405 0x0000001c,
406 0x90000000,
407 0x0000001c,
408};
409
410static const u16 dot11lcn_aux_gain_idx_tbl_2G[] = {
411 0x0000,
412 0x0000,
413 0x0000,
414 0x0000,
415 0x0001,
416 0x0080,
417 0x0081,
418 0x0100,
419 0x0101,
420 0x0180,
421 0x0181,
422 0x0182,
423 0x0183,
424 0x0184,
425 0x0185,
426 0x0186,
427 0x0187,
428 0x0188,
429 0x0285,
430 0x0289,
431 0x028a,
432 0x028b,
433 0x028c,
434 0x028d,
435 0x028e,
436 0x028f,
437 0x0290,
438 0x0291,
439 0x0292,
440 0x0293,
441 0x0294,
442 0x0295,
443 0x0296,
444 0x0297,
445 0x0298,
446 0x0299,
447 0x029a,
448 0x0000
449};
450
451static const u8 dot11lcn_gain_val_tbl_2G[] = {
452 0xfc,
453 0x02,
454 0x08,
455 0x0e,
456 0x13,
457 0x1b,
458 0xfc,
459 0x02,
460 0x08,
461 0x0e,
462 0x13,
463 0x1b,
464 0xfc,
465 0x00,
466 0x0c,
467 0x03,
468 0xeb,
469 0xfe,
470 0x07,
471 0x0b,
472 0x0f,
473 0xfb,
474 0xfe,
475 0x01,
476 0x05,
477 0x08,
478 0x0b,
479 0x0e,
480 0x11,
481 0x14,
482 0x17,
483 0x00,
484 0x00,
485 0x00,
486 0x00,
487 0x00,
488 0x00,
489 0x00,
490 0x03,
491 0x06,
492 0x09,
493 0x0c,
494 0x0f,
495 0x12,
496 0x00,
497 0x00,
498 0x00,
499 0x00,
500 0x00,
501 0x00,
502 0x00,
503 0x00,
504 0x00,
505 0x00,
506 0x03,
507 0x06,
508 0x09,
509 0x0c,
510 0x0f,
511 0x12,
512 0x15,
513 0x18,
514 0x1b,
515 0x00,
516 0x00,
517 0x00,
518 0x00,
519 0x00
520};
521
522static const u32 dot11lcn_gain_idx_tbl_2G[] = {
523 0x00000000,
524 0x00000000,
525 0x00000000,
526 0x00000000,
527 0x00000000,
528 0x00000000,
529 0x00000000,
530 0x00000000,
531 0x10000000,
532 0x00000000,
533 0x00000000,
534 0x00000008,
535 0x10000000,
536 0x00000008,
537 0x00000000,
538 0x00000010,
539 0x10000000,
540 0x00000010,
541 0x00000000,
542 0x00000018,
543 0x10000000,
544 0x00000018,
545 0x20000000,
546 0x00000018,
547 0x30000000,
548 0x00000018,
549 0x40000000,
550 0x00000018,
551 0x50000000,
552 0x00000018,
553 0x60000000,
554 0x00000018,
555 0x70000000,
556 0x00000018,
557 0x80000000,
558 0x00000018,
559 0x50000000,
560 0x00000028,
561 0x90000000,
562 0x00000028,
563 0xa0000000,
564 0x00000028,
565 0xb0000000,
566 0x00000028,
567 0xc0000000,
568 0x00000028,
569 0xd0000000,
570 0x00000028,
571 0xe0000000,
572 0x00000028,
573 0xf0000000,
574 0x00000028,
575 0x00000000,
576 0x00000029,
577 0x10000000,
578 0x00000029,
579 0x20000000,
580 0x00000029,
581 0x30000000,
582 0x00000029,
583 0x40000000,
584 0x00000029,
585 0x50000000,
586 0x00000029,
587 0x60000000,
588 0x00000029,
589 0x70000000,
590 0x00000029,
591 0x80000000,
592 0x00000029,
593 0x90000000,
594 0x00000029,
595 0xa0000000,
596 0x00000029,
597 0x00000000,
598 0x00000000,
599 0x00000000,
600 0x00000000,
601 0x10000000,
602 0x00000000,
603 0x00000000,
604 0x00000008,
605 0x10000000,
606 0x00000008,
607 0x00000000,
608 0x00000010,
609 0x10000000,
610 0x00000010,
611 0x00000000,
612 0x00000018,
613 0x10000000,
614 0x00000018,
615 0x20000000,
616 0x00000018,
617 0x30000000,
618 0x00000018,
619 0x40000000,
620 0x00000018,
621 0x50000000,
622 0x00000018,
623 0x60000000,
624 0x00000018,
625 0x70000000,
626 0x00000018,
627 0x80000000,
628 0x00000018,
629 0x50000000,
630 0x00000028,
631 0x90000000,
632 0x00000028,
633 0xa0000000,
634 0x00000028,
635 0xb0000000,
636 0x00000028,
637 0xc0000000,
638 0x00000028,
639 0xd0000000,
640 0x00000028,
641 0xe0000000,
642 0x00000028,
643 0xf0000000,
644 0x00000028,
645 0x00000000,
646 0x00000029,
647 0x10000000,
648 0x00000029,
649 0x20000000,
650 0x00000029,
651 0x30000000,
652 0x00000029,
653 0x40000000,
654 0x00000029,
655 0x50000000,
656 0x00000029,
657 0x60000000,
658 0x00000029,
659 0x70000000,
660 0x00000029,
661 0x80000000,
662 0x00000029,
663 0x90000000,
664 0x00000029,
665 0xa0000000,
666 0x00000029,
667 0xb0000000,
668 0x00000029,
669 0xc0000000,
670 0x00000029,
671 0x00000000,
672 0x00000000,
673 0x00000000,
674 0x00000000
675};
676
677static const u32 dot11lcn_gain_tbl_2G[] = {
678 0x00000000,
679 0x00000004,
680 0x00000008,
681 0x00000001,
682 0x00000005,
683 0x00000009,
684 0x0000000d,
685 0x0000004d,
686 0x0000008d,
687 0x00000049,
688 0x00000089,
689 0x000000c9,
690 0x0000004b,
691 0x0000008b,
692 0x000000cb,
693 0x000000cf,
694 0x0000010f,
695 0x0000050f,
696 0x0000090f,
697 0x0000094f,
698 0x00000d4f,
699 0x0000114f,
700 0x0000118f,
701 0x0000518f,
702 0x0000918f,
703 0x0000d18f,
704 0x0001118f,
705 0x0001518f,
706 0x0001918f,
707 0x00000000,
708 0x00000000,
709 0x00000000,
710 0x00000000,
711 0x00000000,
712 0x00000000,
713 0x00000000,
714 0x00000000,
715 0x00000000,
716 0x00000000,
717 0x00000000,
718 0x00000000,
719 0x00000000,
720 0x00000000,
721 0x00000000,
722 0x00000000,
723 0x00000000,
724 0x00000000,
725 0x00000000,
726 0x00000000,
727 0x00000000,
728 0x00000000,
729 0x00000000,
730 0x00000000,
731 0x00000000,
732 0x00000000,
733 0x00000000,
734 0x00000000,
735 0x00000000,
736 0x00000000,
737 0x00000000,
738 0x00000000,
739 0x00000000,
740 0x00000000,
741 0x00000000,
742 0x00000000,
743 0x00000000,
744 0x00000000,
745 0x00000000,
746 0x00000000,
747 0x00000000,
748 0x00000000,
749 0x00000000,
750 0x00000000,
751 0x00000000,
752 0x00000000,
753 0x00000000,
754 0x00000000,
755 0x00000000,
756 0x00000000,
757 0x00000000,
758 0x00000000,
759 0x00000000,
760 0x00000000,
761 0x00000000,
762 0x00000000,
763 0x00000000,
764 0x00000000,
765 0x00000000,
766 0x00000000,
767 0x00000000,
768 0x00000000,
769 0x00000000,
770 0x00000000,
771 0x00000000,
772 0x00000000,
773 0x00000000
774};
775
776static const u32 dot11lcn_gain_tbl_extlna_2G[] = {
777 0x00000000,
778 0x00000004,
779 0x00000008,
780 0x00000001,
781 0x00000005,
782 0x00000009,
783 0x0000000d,
784 0x00000003,
785 0x00000007,
786 0x0000000b,
787 0x0000000f,
788 0x0000004f,
789 0x0000008f,
790 0x000000cf,
791 0x0000010f,
792 0x0000014f,
793 0x0000018f,
794 0x0000058f,
795 0x0000098f,
796 0x00000d8f,
797 0x00008000,
798 0x00008004,
799 0x00008008,
800 0x00008001,
801 0x00008005,
802 0x00008009,
803 0x0000800d,
804 0x00008003,
805 0x00008007,
806 0x0000800b,
807 0x0000800f,
808 0x0000804f,
809 0x0000808f,
810 0x000080cf,
811 0x0000810f,
812 0x0000814f,
813 0x0000818f,
814 0x0000858f,
815 0x0000898f,
816 0x00008d8f,
817 0x00000000,
818 0x00000000,
819 0x00000000,
820 0x00000000,
821 0x00000000,
822 0x00000000,
823 0x00000000,
824 0x00000000,
825 0x00000000,
826 0x00000000,
827 0x00000000,
828 0x00000000,
829 0x00000000,
830 0x00000000,
831 0x00000000,
832 0x00000000,
833 0x00000000,
834 0x00000000,
835 0x00000000,
836 0x00000000,
837 0x00000000,
838 0x00000000,
839 0x00000000,
840 0x00000000,
841 0x00000000,
842 0x00000000,
843 0x00000000,
844 0x00000000,
845 0x00000000,
846 0x00000000,
847 0x00000000,
848 0x00000000,
849 0x00000000,
850 0x00000000,
851 0x00000000,
852 0x00000000,
853 0x00000000,
854 0x00000000,
855 0x00000000,
856 0x00000000,
857 0x00000000,
858 0x00000000,
859 0x00000000,
860 0x00000000,
861 0x00000000,
862 0x00000000,
863 0x00000000,
864 0x00000000,
865 0x00000000,
866 0x00000000,
867 0x00000000,
868 0x00000000,
869 0x00000000,
870 0x00000000,
871 0x00000000,
872 0x00000000
873};
874
875static const u16 dot11lcn_aux_gain_idx_tbl_extlna_2G[] = {
876 0x0400,
877 0x0400,
878 0x0400,
879 0x0400,
880 0x0400,
881 0x0400,
882 0x0400,
883 0x0400,
884 0x0400,
885 0x0401,
886 0x0402,
887 0x0403,
888 0x0404,
889 0x0483,
890 0x0484,
891 0x0485,
892 0x0486,
893 0x0583,
894 0x0584,
895 0x0585,
896 0x0587,
897 0x0588,
898 0x0589,
899 0x058a,
900 0x0687,
901 0x0688,
902 0x0689,
903 0x068a,
904 0x068b,
905 0x068c,
906 0x068d,
907 0x068e,
908 0x068f,
909 0x0690,
910 0x0691,
911 0x0692,
912 0x0693,
913 0x0000
914};
915
916static const u8 dot11lcn_gain_val_tbl_extlna_2G[] = {
917 0xfc,
918 0x02,
919 0x08,
920 0x0e,
921 0x13,
922 0x1b,
923 0xfc,
924 0x02,
925 0x08,
926 0x0e,
927 0x13,
928 0x1b,
929 0xfc,
930 0x00,
931 0x0f,
932 0x03,
933 0xeb,
934 0xfe,
935 0x07,
936 0x0b,
937 0x0f,
938 0xfb,
939 0xfe,
940 0x01,
941 0x05,
942 0x08,
943 0x0b,
944 0x0e,
945 0x11,
946 0x14,
947 0x17,
948 0x00,
949 0x00,
950 0x00,
951 0x00,
952 0x00,
953 0x00,
954 0x00,
955 0x03,
956 0x06,
957 0x09,
958 0x0c,
959 0x0f,
960 0x12,
961 0x00,
962 0x00,
963 0x00,
964 0x00,
965 0x00,
966 0x00,
967 0x00,
968 0x00,
969 0x00,
970 0x00,
971 0x03,
972 0x06,
973 0x09,
974 0x0c,
975 0x0f,
976 0x12,
977 0x15,
978 0x18,
979 0x1b,
980 0x00,
981 0x00,
982 0x00,
983 0x00,
984 0x00
985};
986
987static const u32 dot11lcn_gain_idx_tbl_extlna_2G[] = {
988 0x00000000,
989 0x00000040,
990 0x00000000,
991 0x00000040,
992 0x00000000,
993 0x00000040,
994 0x00000000,
995 0x00000040,
996 0x00000000,
997 0x00000040,
998 0x00000000,
999 0x00000040,
1000 0x00000000,
1001 0x00000040,
1002 0x00000000,
1003 0x00000040,
1004 0x00000000,
1005 0x00000040,
1006 0x10000000,
1007 0x00000040,
1008 0x20000000,
1009 0x00000040,
1010 0x30000000,
1011 0x00000040,
1012 0x40000000,
1013 0x00000040,
1014 0x30000000,
1015 0x00000048,
1016 0x40000000,
1017 0x00000048,
1018 0x50000000,
1019 0x00000048,
1020 0x60000000,
1021 0x00000048,
1022 0x30000000,
1023 0x00000058,
1024 0x40000000,
1025 0x00000058,
1026 0x50000000,
1027 0x00000058,
1028 0x70000000,
1029 0x00000058,
1030 0x80000000,
1031 0x00000058,
1032 0x90000000,
1033 0x00000058,
1034 0xa0000000,
1035 0x00000058,
1036 0x70000000,
1037 0x00000068,
1038 0x80000000,
1039 0x00000068,
1040 0x90000000,
1041 0x00000068,
1042 0xa0000000,
1043 0x00000068,
1044 0xb0000000,
1045 0x00000068,
1046 0xc0000000,
1047 0x00000068,
1048 0xd0000000,
1049 0x00000068,
1050 0xe0000000,
1051 0x00000068,
1052 0xf0000000,
1053 0x00000068,
1054 0x00000000,
1055 0x00000069,
1056 0x10000000,
1057 0x00000069,
1058 0x20000000,
1059 0x00000069,
1060 0x30000000,
1061 0x00000069,
1062 0x40000000,
1063 0x00000041,
1064 0x40000000,
1065 0x00000041,
1066 0x40000000,
1067 0x00000041,
1068 0x40000000,
1069 0x00000041,
1070 0x40000000,
1071 0x00000041,
1072 0x40000000,
1073 0x00000041,
1074 0x40000000,
1075 0x00000041,
1076 0x40000000,
1077 0x00000041,
1078 0x40000000,
1079 0x00000041,
1080 0x50000000,
1081 0x00000041,
1082 0x60000000,
1083 0x00000041,
1084 0x70000000,
1085 0x00000041,
1086 0x80000000,
1087 0x00000041,
1088 0x70000000,
1089 0x00000049,
1090 0x80000000,
1091 0x00000049,
1092 0x90000000,
1093 0x00000049,
1094 0xa0000000,
1095 0x00000049,
1096 0x70000000,
1097 0x00000059,
1098 0x80000000,
1099 0x00000059,
1100 0x90000000,
1101 0x00000059,
1102 0xb0000000,
1103 0x00000059,
1104 0xc0000000,
1105 0x00000059,
1106 0xd0000000,
1107 0x00000059,
1108 0xe0000000,
1109 0x00000059,
1110 0xb0000000,
1111 0x00000069,
1112 0xc0000000,
1113 0x00000069,
1114 0xd0000000,
1115 0x00000069,
1116 0xe0000000,
1117 0x00000069,
1118 0xf0000000,
1119 0x00000069,
1120 0x00000000,
1121 0x0000006a,
1122 0x10000000,
1123 0x0000006a,
1124 0x20000000,
1125 0x0000006a,
1126 0x30000000,
1127 0x0000006a,
1128 0x40000000,
1129 0x0000006a,
1130 0x50000000,
1131 0x0000006a,
1132 0x60000000,
1133 0x0000006a,
1134 0x70000000,
1135 0x0000006a,
1136 0x00000000,
1137 0x00000000,
1138 0x00000000,
1139 0x00000000
1140};
1141
1142static const u32 dot11lcn_aux_gain_idx_tbl_5G[] = {
1143 0x0000,
1144 0x0000,
1145 0x0000,
1146 0x0000,
1147 0x0001,
1148 0x0002,
1149 0x0003,
1150 0x0004,
1151 0x0083,
1152 0x0084,
1153 0x0085,
1154 0x0086,
1155 0x0087,
1156 0x0186,
1157 0x0187,
1158 0x0188,
1159 0x0189,
1160 0x018a,
1161 0x018b,
1162 0x018c,
1163 0x018d,
1164 0x018e,
1165 0x018f,
1166 0x0190,
1167 0x0191,
1168 0x0192,
1169 0x0193,
1170 0x0194,
1171 0x0195,
1172 0x0196,
1173 0x0197,
1174 0x0198,
1175 0x0199,
1176 0x019a,
1177 0x019b,
1178 0x019c,
1179 0x019d,
1180 0x0000
1181};
1182
1183static const u32 dot11lcn_gain_val_tbl_5G[] = {
1184 0xf7,
1185 0xfd,
1186 0x00,
1187 0x04,
1188 0x04,
1189 0x04,
1190 0xf7,
1191 0xfd,
1192 0x00,
1193 0x04,
1194 0x04,
1195 0x04,
1196 0xf6,
1197 0x00,
1198 0x0c,
1199 0x03,
1200 0xeb,
1201 0xfe,
1202 0x06,
1203 0x0a,
1204 0x10,
1205 0x00,
1206 0x03,
1207 0x06,
1208 0x09,
1209 0x0c,
1210 0x0f,
1211 0x12,
1212 0x15,
1213 0x18,
1214 0x1b,
1215 0x00,
1216 0x00,
1217 0x00,
1218 0x00,
1219 0x00,
1220 0x00,
1221 0x00,
1222 0x03,
1223 0x06,
1224 0x09,
1225 0x0c,
1226 0x0f,
1227 0x12,
1228 0x00,
1229 0x00,
1230 0x00,
1231 0x00,
1232 0x00,
1233 0x00,
1234 0x00,
1235 0x00,
1236 0x00,
1237 0x00,
1238 0x03,
1239 0x06,
1240 0x09,
1241 0x0c,
1242 0x0f,
1243 0x12,
1244 0x15,
1245 0x18,
1246 0x1b,
1247 0x00,
1248 0x00,
1249 0x00,
1250 0x00,
1251 0x00
1252};
1253
1254static const u32 dot11lcn_gain_idx_tbl_5G[] = {
1255 0x00000000,
1256 0x00000000,
1257 0x00000000,
1258 0x00000000,
1259 0x00000000,
1260 0x00000000,
1261 0x00000000,
1262 0x00000000,
1263 0x10000000,
1264 0x00000000,
1265 0x20000000,
1266 0x00000000,
1267 0x30000000,
1268 0x00000000,
1269 0x40000000,
1270 0x00000000,
1271 0x30000000,
1272 0x00000008,
1273 0x40000000,
1274 0x00000008,
1275 0x50000000,
1276 0x00000008,
1277 0x60000000,
1278 0x00000008,
1279 0x70000000,
1280 0x00000008,
1281 0x60000000,
1282 0x00000018,
1283 0x70000000,
1284 0x00000018,
1285 0x80000000,
1286 0x00000018,
1287 0x90000000,
1288 0x00000018,
1289 0xa0000000,
1290 0x00000018,
1291 0xb0000000,
1292 0x00000018,
1293 0xc0000000,
1294 0x00000018,
1295 0xd0000000,
1296 0x00000018,
1297 0xe0000000,
1298 0x00000018,
1299 0xf0000000,
1300 0x00000018,
1301 0x00000000,
1302 0x00000019,
1303 0x10000000,
1304 0x00000019,
1305 0x20000000,
1306 0x00000019,
1307 0x30000000,
1308 0x00000019,
1309 0x40000000,
1310 0x00000019,
1311 0x50000000,
1312 0x00000019,
1313 0x60000000,
1314 0x00000019,
1315 0x70000000,
1316 0x00000019,
1317 0x80000000,
1318 0x00000019,
1319 0x90000000,
1320 0x00000019,
1321 0xa0000000,
1322 0x00000019,
1323 0xb0000000,
1324 0x00000019,
1325 0xc0000000,
1326 0x00000019,
1327 0xd0000000,
1328 0x00000019,
1329 0x00000000,
1330 0x00000000,
1331 0x00000000,
1332 0x00000000,
1333 0x00000000,
1334 0x00000000,
1335 0x00000000,
1336 0x00000000,
1337 0x00000000,
1338 0x00000000,
1339 0x00000000,
1340 0x00000000,
1341 0x00000000,
1342 0x00000000,
1343 0x00000000,
1344 0x00000000,
1345 0x00000000,
1346 0x00000000,
1347 0x00000000,
1348 0x00000000,
1349 0x00000000,
1350 0x00000000,
1351 0x00000000,
1352 0x00000000,
1353 0x00000000,
1354 0x00000000,
1355 0x00000000,
1356 0x00000000,
1357 0x00000000,
1358 0x00000000,
1359 0x00000000,
1360 0x00000000,
1361 0x00000000,
1362 0x00000000,
1363 0x00000000,
1364 0x00000000,
1365 0x00000000,
1366 0x00000000,
1367 0x00000000,
1368 0x00000000,
1369 0x00000000,
1370 0x00000000,
1371 0x00000000,
1372 0x00000000,
1373 0x00000000,
1374 0x00000000,
1375 0x00000000,
1376 0x00000000,
1377 0x00000000,
1378 0x00000000,
1379 0x00000000,
1380 0x00000000,
1381 0x00000000,
1382 0x00000000,
1383 0x00000000,
1384 0x00000000,
1385 0x00000000,
1386 0x00000000,
1387 0x00000000,
1388 0x00000000,
1389 0x00000000,
1390 0x00000000,
1391 0x00000000,
1392 0x00000000,
1393 0x00000000,
1394 0x00000000,
1395 0x00000000,
1396 0x00000000,
1397 0x00000000,
1398 0x00000000,
1399 0x00000000,
1400 0x00000000,
1401 0x00000000,
1402 0x00000000,
1403 0x00000000,
1404 0x00000000,
1405 0x00000000,
1406 0x00000000
1407};
1408
1409static const u32 dot11lcn_gain_tbl_5G[] = {
1410 0x00000000,
1411 0x00000040,
1412 0x00000080,
1413 0x00000001,
1414 0x00000005,
1415 0x00000009,
1416 0x0000000d,
1417 0x00000011,
1418 0x00000015,
1419 0x00000055,
1420 0x00000095,
1421 0x00000017,
1422 0x0000001b,
1423 0x0000005b,
1424 0x0000009b,
1425 0x000000db,
1426 0x0000011b,
1427 0x0000015b,
1428 0x0000019b,
1429 0x0000059b,
1430 0x0000099b,
1431 0x00000d9b,
1432 0x0000119b,
1433 0x0000519b,
1434 0x0000919b,
1435 0x0000d19b,
1436 0x0001119b,
1437 0x0001519b,
1438 0x0001919b,
1439 0x0001d19b,
1440 0x00000000,
1441 0x00000000,
1442 0x00000000,
1443 0x00000000,
1444 0x00000000,
1445 0x00000000,
1446 0x00000000,
1447 0x00000000,
1448 0x00000000,
1449 0x00000000,
1450 0x00000000,
1451 0x00000000,
1452 0x00000000,
1453 0x00000000,
1454 0x00000000,
1455 0x00000000,
1456 0x00000000,
1457 0x00000000,
1458 0x00000000,
1459 0x00000000,
1460 0x00000000,
1461 0x00000000,
1462 0x00000000,
1463 0x00000000,
1464 0x00000000,
1465 0x00000000,
1466 0x00000000,
1467 0x00000000,
1468 0x00000000,
1469 0x00000000,
1470 0x00000000,
1471 0x00000000,
1472 0x00000000,
1473 0x00000000,
1474 0x00000000,
1475 0x00000000,
1476 0x00000000,
1477 0x00000000,
1478 0x00000000,
1479 0x00000000,
1480 0x00000000,
1481 0x00000000,
1482 0x00000000,
1483 0x00000000,
1484 0x00000000,
1485 0x00000000,
1486 0x00000000,
1487 0x00000000,
1488 0x00000000,
1489 0x00000000,
1490 0x00000000,
1491 0x00000000,
1492 0x00000000,
1493 0x00000000,
1494 0x00000000,
1495 0x00000000,
1496 0x00000000,
1497 0x00000000,
1498 0x00000000,
1499 0x00000000,
1500 0x00000000,
1501 0x00000000,
1502 0x00000000,
1503 0x00000000,
1504 0x00000000,
1505 0x00000000
1506};
1507
1508const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[] = {
1509 {&dot11lcn_gain_tbl_rev0,
1510 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
1511 0, 32}
1512 ,
1513 {&dot11lcn_aux_gain_idx_tbl_rev0,
1514 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
1515 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
1516 ,
1517 {&dot11lcn_gain_idx_tbl_rev0,
1518 sizeof(dot11lcn_gain_idx_tbl_rev0) /
1519 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
1520 ,
1521};
1522
1523static const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev1[] = {
1524 {&dot11lcn_gain_tbl_rev1,
1525 sizeof(dot11lcn_gain_tbl_rev1) / sizeof(dot11lcn_gain_tbl_rev1[0]), 18,
1526 0, 32}
1527 ,
1528 {&dot11lcn_aux_gain_idx_tbl_rev0,
1529 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
1530 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
1531 ,
1532 {&dot11lcn_gain_idx_tbl_rev0,
1533 sizeof(dot11lcn_gain_idx_tbl_rev0) /
1534 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
1535 ,
1536};
1537
1538const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[] = {
1539 {&dot11lcn_gain_tbl_2G,
1540 sizeof(dot11lcn_gain_tbl_2G) / sizeof(dot11lcn_gain_tbl_2G[0]), 18, 0,
1541 32}
1542 ,
1543 {&dot11lcn_aux_gain_idx_tbl_2G,
1544 sizeof(dot11lcn_aux_gain_idx_tbl_2G) /
1545 sizeof(dot11lcn_aux_gain_idx_tbl_2G[0]), 14, 0, 16}
1546 ,
1547 {&dot11lcn_gain_idx_tbl_2G,
1548 sizeof(dot11lcn_gain_idx_tbl_2G) / sizeof(dot11lcn_gain_idx_tbl_2G[0]),
1549 13, 0, 32}
1550 ,
1551 {&dot11lcn_gain_val_tbl_2G,
1552 sizeof(dot11lcn_gain_val_tbl_2G) / sizeof(dot11lcn_gain_val_tbl_2G[0]),
1553 17, 0, 8}
1554};
1555
1556const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[] = {
1557 {&dot11lcn_gain_tbl_5G,
1558 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
1559 32}
1560 ,
1561 {&dot11lcn_aux_gain_idx_tbl_5G,
1562 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
1563 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
1564 ,
1565 {&dot11lcn_gain_idx_tbl_5G,
1566 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
1567 13, 0, 32}
1568 ,
1569 {&dot11lcn_gain_val_tbl_5G,
1570 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
1571 17, 0, 8}
1572};
1573
1574const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = {
1575 {&dot11lcn_gain_tbl_extlna_2G,
1576 sizeof(dot11lcn_gain_tbl_extlna_2G) /
1577 sizeof(dot11lcn_gain_tbl_extlna_2G[0]), 18, 0, 32}
1578 ,
1579 {&dot11lcn_aux_gain_idx_tbl_extlna_2G,
1580 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G) /
1581 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G[0]), 14, 0, 16}
1582 ,
1583 {&dot11lcn_gain_idx_tbl_extlna_2G,
1584 sizeof(dot11lcn_gain_idx_tbl_extlna_2G) /
1585 sizeof(dot11lcn_gain_idx_tbl_extlna_2G[0]), 13, 0, 32}
1586 ,
1587 {&dot11lcn_gain_val_tbl_extlna_2G,
1588 sizeof(dot11lcn_gain_val_tbl_extlna_2G) /
1589 sizeof(dot11lcn_gain_val_tbl_extlna_2G[0]), 17, 0, 8}
1590};
1591
1592const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = {
1593 {&dot11lcn_gain_tbl_5G,
1594 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
1595 32}
1596 ,
1597 {&dot11lcn_aux_gain_idx_tbl_5G,
1598 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
1599 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
1600 ,
1601 {&dot11lcn_gain_idx_tbl_5G,
1602 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
1603 13, 0, 32}
1604 ,
1605 {&dot11lcn_gain_val_tbl_5G,
1606 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
1607 17, 0, 8}
1608};
1609
1610const u32 dot11lcnphytbl_rx_gain_info_sz_rev0 =
1611 sizeof(dot11lcnphytbl_rx_gain_info_rev0) /
1612 sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]);
1613
1614const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz =
1615 sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) /
1616 sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]);
1617
1618const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz =
1619 sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) /
1620 sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]);
1621
1622static const u16 dot11lcn_min_sig_sq_tbl_rev0[] = {
1623 0x014d,
1624 0x014d,
1625 0x014d,
1626 0x014d,
1627 0x014d,
1628 0x014d,
1629 0x014d,
1630 0x014d,
1631 0x014d,
1632 0x014d,
1633 0x014d,
1634 0x014d,
1635 0x014d,
1636 0x014d,
1637 0x014d,
1638 0x014d,
1639 0x014d,
1640 0x014d,
1641 0x014d,
1642 0x014d,
1643 0x014d,
1644 0x014d,
1645 0x014d,
1646 0x014d,
1647 0x014d,
1648 0x014d,
1649 0x014d,
1650 0x014d,
1651 0x014d,
1652 0x014d,
1653 0x014d,
1654 0x014d,
1655 0x014d,
1656 0x014d,
1657 0x014d,
1658 0x014d,
1659 0x014d,
1660 0x014d,
1661 0x014d,
1662 0x014d,
1663 0x014d,
1664 0x014d,
1665 0x014d,
1666 0x014d,
1667 0x014d,
1668 0x014d,
1669 0x014d,
1670 0x014d,
1671 0x014d,
1672 0x014d,
1673 0x014d,
1674 0x014d,
1675 0x014d,
1676 0x014d,
1677 0x014d,
1678 0x014d,
1679 0x014d,
1680 0x014d,
1681 0x014d,
1682 0x014d,
1683 0x014d,
1684 0x014d,
1685 0x014d,
1686 0x014d,
1687};
1688
1689static const u16 dot11lcn_noise_scale_tbl_rev0[] = {
1690 0x0000,
1691 0x0000,
1692 0x0000,
1693 0x0000,
1694 0x0000,
1695 0x0000,
1696 0x0000,
1697 0x0000,
1698 0x0000,
1699 0x0000,
1700 0x0000,
1701 0x0000,
1702 0x0000,
1703 0x0000,
1704 0x0000,
1705 0x0000,
1706 0x0000,
1707 0x0000,
1708 0x0000,
1709 0x0000,
1710 0x0000,
1711 0x0000,
1712 0x0000,
1713 0x0000,
1714 0x0000,
1715 0x0000,
1716 0x0000,
1717 0x0000,
1718 0x0000,
1719 0x0000,
1720 0x0000,
1721 0x0000,
1722 0x0000,
1723 0x0000,
1724 0x0000,
1725 0x0000,
1726 0x0000,
1727 0x0000,
1728 0x0000,
1729 0x0000,
1730 0x0000,
1731 0x0000,
1732 0x0000,
1733 0x0000,
1734 0x0000,
1735 0x0000,
1736 0x0000,
1737 0x0000,
1738 0x0000,
1739 0x0000,
1740 0x0000,
1741 0x0000,
1742 0x0000,
1743 0x0000,
1744 0x0000,
1745 0x0000,
1746 0x0000,
1747 0x0000,
1748 0x0000,
1749 0x0000,
1750 0x0000,
1751 0x0000,
1752 0x0000,
1753 0x0000,
1754};
1755
1756static const u32 dot11lcn_fltr_ctrl_tbl_rev0[] = {
1757 0x000141f8,
1758 0x000021f8,
1759 0x000021fb,
1760 0x000041fb,
1761 0x0001fe4b,
1762 0x0000217b,
1763 0x00002133,
1764 0x000040eb,
1765 0x0001fea3,
1766 0x0000024b,
1767};
1768
1769static const u32 dot11lcn_ps_ctrl_tbl_rev0[] = {
1770 0x00100001,
1771 0x00200010,
1772 0x00300001,
1773 0x00400010,
1774 0x00500022,
1775 0x00600122,
1776 0x00700222,
1777 0x00800322,
1778 0x00900422,
1779 0x00a00522,
1780 0x00b00622,
1781 0x00c00722,
1782 0x00d00822,
1783 0x00f00922,
1784 0x00100a22,
1785 0x00200b22,
1786 0x00300c22,
1787 0x00400d22,
1788 0x00500e22,
1789 0x00600f22,
1790};
1791
1792static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[] = {
1793 0x0007,
1794 0x0005,
1795 0x0006,
1796 0x0004,
1797 0x0007,
1798 0x0005,
1799 0x0006,
1800 0x0004,
1801 0x0007,
1802 0x0005,
1803 0x0006,
1804 0x0004,
1805 0x0007,
1806 0x0005,
1807 0x0006,
1808 0x0004,
1809 0x000b,
1810 0x000b,
1811 0x000a,
1812 0x000a,
1813 0x000b,
1814 0x000b,
1815 0x000a,
1816 0x000a,
1817 0x000b,
1818 0x000b,
1819 0x000a,
1820 0x000a,
1821 0x000b,
1822 0x000b,
1823 0x000a,
1824 0x000a,
1825 0x0007,
1826 0x0005,
1827 0x0006,
1828 0x0004,
1829 0x0007,
1830 0x0005,
1831 0x0006,
1832 0x0004,
1833 0x0007,
1834 0x0005,
1835 0x0006,
1836 0x0004,
1837 0x0007,
1838 0x0005,
1839 0x0006,
1840 0x0004,
1841 0x000b,
1842 0x000b,
1843 0x000a,
1844 0x000a,
1845 0x000b,
1846 0x000b,
1847 0x000a,
1848 0x000a,
1849 0x000b,
1850 0x000b,
1851 0x000a,
1852 0x000a,
1853 0x000b,
1854 0x000b,
1855 0x000a,
1856 0x000a,
1857
1858};
1859
1860static const u16 dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[] = {
1861 0x0007,
1862 0x0005,
1863 0x0002,
1864 0x0000,
1865 0x0007,
1866 0x0005,
1867 0x0002,
1868 0x0000,
1869 0x0007,
1870 0x0005,
1871 0x0002,
1872 0x0000,
1873 0x0007,
1874 0x0005,
1875 0x0002,
1876 0x0000,
1877 0x0007,
1878 0x0007,
1879 0x0002,
1880 0x0002,
1881 0x0007,
1882 0x0007,
1883 0x0002,
1884 0x0002,
1885 0x0007,
1886 0x0007,
1887 0x0002,
1888 0x0002,
1889 0x0007,
1890 0x0007,
1891 0x0002,
1892 0x0002,
1893 0x0007,
1894 0x0005,
1895 0x0002,
1896 0x0000,
1897 0x0007,
1898 0x0005,
1899 0x0002,
1900 0x0000,
1901 0x0007,
1902 0x0005,
1903 0x0002,
1904 0x0000,
1905 0x0007,
1906 0x0005,
1907 0x0002,
1908 0x0000,
1909 0x0007,
1910 0x0007,
1911 0x0002,
1912 0x0002,
1913 0x0007,
1914 0x0007,
1915 0x0002,
1916 0x0002,
1917 0x0007,
1918 0x0007,
1919 0x0002,
1920 0x0002,
1921 0x0007,
1922 0x0007,
1923 0x0002,
1924 0x0002,
1925};
1926
1927static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
1928 0x0002,
1929 0x0008,
1930 0x0004,
1931 0x0001,
1932 0x0002,
1933 0x0008,
1934 0x0004,
1935 0x0001,
1936 0x0002,
1937 0x0008,
1938 0x0004,
1939 0x0001,
1940 0x0002,
1941 0x0008,
1942 0x0004,
1943 0x0001,
1944 0x0002,
1945 0x0008,
1946 0x0004,
1947 0x0001,
1948 0x0002,
1949 0x0008,
1950 0x0004,
1951 0x0001,
1952 0x0002,
1953 0x0008,
1954 0x0004,
1955 0x0001,
1956 0x0002,
1957 0x0008,
1958 0x0004,
1959 0x0001,
1960 0x0002,
1961 0x0008,
1962 0x0004,
1963 0x0001,
1964 0x0002,
1965 0x0008,
1966 0x0004,
1967 0x0001,
1968 0x0002,
1969 0x0008,
1970 0x0004,
1971 0x0001,
1972 0x0002,
1973 0x0008,
1974 0x0004,
1975 0x0001,
1976 0x0002,
1977 0x0008,
1978 0x0004,
1979 0x0001,
1980 0x0002,
1981 0x0008,
1982 0x0004,
1983 0x0001,
1984 0x0002,
1985 0x0008,
1986 0x0004,
1987 0x0001,
1988 0x0002,
1989 0x0008,
1990 0x0004,
1991 0x0001,
1992};
1993
1994static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
1995 0x000a,
1996 0x0009,
1997 0x0006,
1998 0x0005,
1999 0x000a,
2000 0x0009,
2001 0x0006,
2002 0x0005,
2003 0x000a,
2004 0x0009,
2005 0x0006,
2006 0x0005,
2007 0x000a,
2008 0x0009,
2009 0x0006,
2010 0x0005,
2011 0x000a,
2012 0x0009,
2013 0x0006,
2014 0x0005,
2015 0x000a,
2016 0x0009,
2017 0x0006,
2018 0x0005,
2019 0x000a,
2020 0x0009,
2021 0x0006,
2022 0x0005,
2023 0x000a,
2024 0x0009,
2025 0x0006,
2026 0x0005,
2027 0x000a,
2028 0x0009,
2029 0x0006,
2030 0x0005,
2031 0x000a,
2032 0x0009,
2033 0x0006,
2034 0x0005,
2035 0x000a,
2036 0x0009,
2037 0x0006,
2038 0x0005,
2039 0x000a,
2040 0x0009,
2041 0x0006,
2042 0x0005,
2043 0x000a,
2044 0x0009,
2045 0x0006,
2046 0x0005,
2047 0x000a,
2048 0x0009,
2049 0x0006,
2050 0x0005,
2051 0x000a,
2052 0x0009,
2053 0x0006,
2054 0x0005,
2055 0x000a,
2056 0x0009,
2057 0x0006,
2058 0x0005,
2059};
2060
2061static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {
2062 0x0004,
2063 0x0004,
2064 0x0002,
2065 0x0002,
2066 0x0004,
2067 0x0004,
2068 0x0002,
2069 0x0002,
2070 0x0004,
2071 0x0004,
2072 0x0002,
2073 0x0002,
2074 0x0004,
2075 0x0004,
2076 0x0002,
2077 0x0002,
2078 0x0004,
2079 0x0004,
2080 0x0002,
2081 0x0002,
2082 0x0004,
2083 0x0004,
2084 0x0002,
2085 0x0002,
2086 0x0004,
2087 0x0004,
2088 0x0002,
2089 0x0002,
2090 0x0004,
2091 0x0004,
2092 0x0002,
2093 0x0002,
2094 0x0004,
2095 0x0004,
2096 0x0002,
2097 0x0002,
2098 0x0004,
2099 0x0004,
2100 0x0002,
2101 0x0002,
2102 0x0004,
2103 0x0004,
2104 0x0002,
2105 0x0002,
2106 0x0004,
2107 0x0004,
2108 0x0002,
2109 0x0002,
2110 0x0004,
2111 0x0004,
2112 0x0002,
2113 0x0002,
2114 0x0004,
2115 0x0004,
2116 0x0002,
2117 0x0002,
2118 0x0004,
2119 0x0004,
2120 0x0002,
2121 0x0002,
2122 0x0004,
2123 0x0004,
2124 0x0002,
2125 0x0002,
2126};
2127
2128static const u8 dot11lcn_nf_table_rev0[] = {
2129 0x5f,
2130 0x36,
2131 0x29,
2132 0x1f,
2133 0x5f,
2134 0x36,
2135 0x29,
2136 0x1f,
2137 0x5f,
2138 0x36,
2139 0x29,
2140 0x1f,
2141 0x5f,
2142 0x36,
2143 0x29,
2144 0x1f,
2145};
2146
2147static const u8 dot11lcn_gain_val_tbl_rev0[] = {
2148 0x09,
2149 0x0f,
2150 0x14,
2151 0x18,
2152 0xfe,
2153 0x07,
2154 0x0b,
2155 0x0f,
2156 0xfb,
2157 0xfe,
2158 0x01,
2159 0x05,
2160 0x08,
2161 0x0b,
2162 0x0e,
2163 0x11,
2164 0x14,
2165 0x17,
2166 0x00,
2167 0x00,
2168 0x00,
2169 0x00,
2170 0x00,
2171 0x00,
2172 0x00,
2173 0x03,
2174 0x06,
2175 0x09,
2176 0x0c,
2177 0x0f,
2178 0x12,
2179 0x00,
2180 0x00,
2181 0x00,
2182 0x00,
2183 0x00,
2184 0x00,
2185 0x00,
2186 0x00,
2187 0x00,
2188 0x00,
2189 0x03,
2190 0x06,
2191 0x09,
2192 0x0c,
2193 0x0f,
2194 0x12,
2195 0x15,
2196 0x18,
2197 0x1b,
2198 0x00,
2199 0x00,
2200 0x00,
2201 0x00,
2202 0x00,
2203 0x00,
2204 0x03,
2205 0xeb,
2206 0x00,
2207 0x00,
2208};
2209
2210static const u8 dot11lcn_spur_tbl_rev0[] = {
2211 0x01,
2212 0x01,
2213 0x01,
2214 0x01,
2215 0x01,
2216 0x01,
2217 0x01,
2218 0x01,
2219 0x01,
2220 0x01,
2221 0x01,
2222 0x01,
2223 0x01,
2224 0x01,
2225 0x01,
2226 0x01,
2227 0x01,
2228 0x01,
2229 0x01,
2230 0x01,
2231 0x01,
2232 0x01,
2233 0x01,
2234 0x01,
2235 0x01,
2236 0x01,
2237 0x01,
2238 0x01,
2239 0x01,
2240 0x01,
2241 0x02,
2242 0x03,
2243 0x01,
2244 0x03,
2245 0x02,
2246 0x01,
2247 0x01,
2248 0x01,
2249 0x01,
2250 0x01,
2251 0x01,
2252 0x01,
2253 0x01,
2254 0x01,
2255 0x01,
2256 0x01,
2257 0x01,
2258 0x01,
2259 0x01,
2260 0x01,
2261 0x01,
2262 0x01,
2263 0x01,
2264 0x01,
2265 0x01,
2266 0x01,
2267 0x01,
2268 0x01,
2269 0x01,
2270 0x01,
2271 0x01,
2272 0x01,
2273 0x01,
2274 0x01,
2275 0x01,
2276 0x01,
2277 0x01,
2278 0x01,
2279 0x01,
2280 0x01,
2281 0x01,
2282 0x01,
2283 0x01,
2284 0x01,
2285 0x01,
2286 0x01,
2287 0x01,
2288 0x01,
2289 0x01,
2290 0x01,
2291 0x01,
2292 0x01,
2293 0x01,
2294 0x01,
2295 0x01,
2296 0x01,
2297 0x01,
2298 0x01,
2299 0x01,
2300 0x01,
2301 0x01,
2302 0x01,
2303 0x01,
2304 0x01,
2305 0x02,
2306 0x03,
2307 0x01,
2308 0x03,
2309 0x02,
2310 0x01,
2311 0x01,
2312 0x01,
2313 0x01,
2314 0x01,
2315 0x01,
2316 0x01,
2317 0x01,
2318 0x01,
2319 0x01,
2320 0x01,
2321 0x01,
2322 0x01,
2323 0x01,
2324 0x01,
2325 0x01,
2326 0x01,
2327 0x01,
2328 0x01,
2329 0x01,
2330 0x01,
2331 0x01,
2332 0x01,
2333 0x01,
2334 0x01,
2335 0x01,
2336 0x01,
2337 0x01,
2338 0x01,
2339};
2340
2341static const u16 dot11lcn_unsup_mcs_tbl_rev0[] = {
2342 0x001a,
2343 0x0034,
2344 0x004e,
2345 0x0068,
2346 0x009c,
2347 0x00d0,
2348 0x00ea,
2349 0x0104,
2350 0x0034,
2351 0x0068,
2352 0x009c,
2353 0x00d0,
2354 0x0138,
2355 0x01a0,
2356 0x01d4,
2357 0x0208,
2358 0x004e,
2359 0x009c,
2360 0x00ea,
2361 0x0138,
2362 0x01d4,
2363 0x0270,
2364 0x02be,
2365 0x030c,
2366 0x0068,
2367 0x00d0,
2368 0x0138,
2369 0x01a0,
2370 0x0270,
2371 0x0340,
2372 0x03a8,
2373 0x0410,
2374 0x0018,
2375 0x009c,
2376 0x00d0,
2377 0x0104,
2378 0x00ea,
2379 0x0138,
2380 0x0186,
2381 0x00d0,
2382 0x0104,
2383 0x0104,
2384 0x0138,
2385 0x016c,
2386 0x016c,
2387 0x01a0,
2388 0x0138,
2389 0x0186,
2390 0x0186,
2391 0x01d4,
2392 0x0222,
2393 0x0222,
2394 0x0270,
2395 0x0104,
2396 0x0138,
2397 0x016c,
2398 0x0138,
2399 0x016c,
2400 0x01a0,
2401 0x01d4,
2402 0x01a0,
2403 0x01d4,
2404 0x0208,
2405 0x0208,
2406 0x023c,
2407 0x0186,
2408 0x01d4,
2409 0x0222,
2410 0x01d4,
2411 0x0222,
2412 0x0270,
2413 0x02be,
2414 0x0270,
2415 0x02be,
2416 0x030c,
2417 0x030c,
2418 0x035a,
2419 0x0036,
2420 0x006c,
2421 0x00a2,
2422 0x00d8,
2423 0x0144,
2424 0x01b0,
2425 0x01e6,
2426 0x021c,
2427 0x006c,
2428 0x00d8,
2429 0x0144,
2430 0x01b0,
2431 0x0288,
2432 0x0360,
2433 0x03cc,
2434 0x0438,
2435 0x00a2,
2436 0x0144,
2437 0x01e6,
2438 0x0288,
2439 0x03cc,
2440 0x0510,
2441 0x05b2,
2442 0x0654,
2443 0x00d8,
2444 0x01b0,
2445 0x0288,
2446 0x0360,
2447 0x0510,
2448 0x06c0,
2449 0x0798,
2450 0x0870,
2451 0x0018,
2452 0x0144,
2453 0x01b0,
2454 0x021c,
2455 0x01e6,
2456 0x0288,
2457 0x032a,
2458 0x01b0,
2459 0x021c,
2460 0x021c,
2461 0x0288,
2462 0x02f4,
2463 0x02f4,
2464 0x0360,
2465 0x0288,
2466 0x032a,
2467 0x032a,
2468 0x03cc,
2469 0x046e,
2470 0x046e,
2471 0x0510,
2472 0x021c,
2473 0x0288,
2474 0x02f4,
2475 0x0288,
2476 0x02f4,
2477 0x0360,
2478 0x03cc,
2479 0x0360,
2480 0x03cc,
2481 0x0438,
2482 0x0438,
2483 0x04a4,
2484 0x032a,
2485 0x03cc,
2486 0x046e,
2487 0x03cc,
2488 0x046e,
2489 0x0510,
2490 0x05b2,
2491 0x0510,
2492 0x05b2,
2493 0x0654,
2494 0x0654,
2495 0x06f6,
2496};
2497
2498static const u16 dot11lcn_iq_local_tbl_rev0[] = {
2499 0x0200,
2500 0x0300,
2501 0x0400,
2502 0x0600,
2503 0x0800,
2504 0x0b00,
2505 0x1000,
2506 0x1001,
2507 0x1002,
2508 0x1003,
2509 0x1004,
2510 0x1005,
2511 0x1006,
2512 0x1007,
2513 0x1707,
2514 0x2007,
2515 0x2d07,
2516 0x4007,
2517 0x0000,
2518 0x0000,
2519 0x0000,
2520 0x0000,
2521 0x0000,
2522 0x0000,
2523 0x0000,
2524 0x0000,
2525 0x0000,
2526 0x0000,
2527 0x0000,
2528 0x0000,
2529 0x0000,
2530 0x0000,
2531 0x0200,
2532 0x0300,
2533 0x0400,
2534 0x0600,
2535 0x0800,
2536 0x0b00,
2537 0x1000,
2538 0x1001,
2539 0x1002,
2540 0x1003,
2541 0x1004,
2542 0x1005,
2543 0x1006,
2544 0x1007,
2545 0x1707,
2546 0x2007,
2547 0x2d07,
2548 0x4007,
2549 0x0000,
2550 0x0000,
2551 0x0000,
2552 0x0000,
2553 0x0000,
2554 0x0000,
2555 0x0000,
2556 0x0000,
2557 0x0000,
2558 0x0000,
2559 0x0000,
2560 0x0000,
2561 0x0000,
2562 0x0000,
2563 0x0000,
2564 0x0000,
2565 0x0000,
2566 0x0000,
2567 0x0000,
2568 0x0000,
2569 0x0000,
2570 0x0000,
2571 0x0000,
2572 0x0000,
2573 0x0000,
2574 0x0000,
2575 0x0000,
2576 0x0000,
2577 0x0000,
2578 0x0000,
2579 0x0000,
2580 0x0000,
2581 0x0000,
2582 0x0000,
2583 0x0000,
2584 0x0000,
2585 0x0000,
2586 0x4000,
2587 0x0000,
2588 0x0000,
2589 0x0000,
2590 0x0000,
2591 0x0000,
2592 0x0000,
2593 0x0000,
2594 0x0000,
2595 0x0000,
2596 0x0000,
2597 0x0000,
2598 0x0000,
2599 0x0000,
2600 0x0000,
2601 0x0000,
2602 0x0000,
2603 0x0000,
2604 0x0000,
2605 0x0000,
2606 0x0000,
2607};
2608
2609static const u32 dot11lcn_papd_compdelta_tbl_rev0[] = {
2610 0x00080000,
2611 0x00080000,
2612 0x00080000,
2613 0x00080000,
2614 0x00080000,
2615 0x00080000,
2616 0x00080000,
2617 0x00080000,
2618 0x00080000,
2619 0x00080000,
2620 0x00080000,
2621 0x00080000,
2622 0x00080000,
2623 0x00080000,
2624 0x00080000,
2625 0x00080000,
2626 0x00080000,
2627 0x00080000,
2628 0x00080000,
2629 0x00080000,
2630 0x00080000,
2631 0x00080000,
2632 0x00080000,
2633 0x00080000,
2634 0x00080000,
2635 0x00080000,
2636 0x00080000,
2637 0x00080000,
2638 0x00080000,
2639 0x00080000,
2640 0x00080000,
2641 0x00080000,
2642 0x00080000,
2643 0x00080000,
2644 0x00080000,
2645 0x00080000,
2646 0x00080000,
2647 0x00080000,
2648 0x00080000,
2649 0x00080000,
2650 0x00080000,
2651 0x00080000,
2652 0x00080000,
2653 0x00080000,
2654 0x00080000,
2655 0x00080000,
2656 0x00080000,
2657 0x00080000,
2658 0x00080000,
2659 0x00080000,
2660 0x00080000,
2661 0x00080000,
2662 0x00080000,
2663 0x00080000,
2664 0x00080000,
2665 0x00080000,
2666 0x00080000,
2667 0x00080000,
2668 0x00080000,
2669 0x00080000,
2670 0x00080000,
2671 0x00080000,
2672 0x00080000,
2673 0x00080000,
2674 0x00080000,
2675 0x00080000,
2676 0x00080000,
2677 0x00080000,
2678 0x00080000,
2679 0x00080000,
2680 0x00080000,
2681 0x00080000,
2682 0x00080000,
2683 0x00080000,
2684 0x00080000,
2685 0x00080000,
2686 0x00080000,
2687 0x00080000,
2688 0x00080000,
2689 0x00080000,
2690 0x00080000,
2691 0x00080000,
2692 0x00080000,
2693 0x00080000,
2694 0x00080000,
2695 0x00080000,
2696 0x00080000,
2697 0x00080000,
2698 0x00080000,
2699 0x00080000,
2700 0x00080000,
2701 0x00080000,
2702 0x00080000,
2703 0x00080000,
2704 0x00080000,
2705 0x00080000,
2706 0x00080000,
2707 0x00080000,
2708 0x00080000,
2709 0x00080000,
2710 0x00080000,
2711 0x00080000,
2712 0x00080000,
2713 0x00080000,
2714 0x00080000,
2715 0x00080000,
2716 0x00080000,
2717 0x00080000,
2718 0x00080000,
2719 0x00080000,
2720 0x00080000,
2721 0x00080000,
2722 0x00080000,
2723 0x00080000,
2724 0x00080000,
2725 0x00080000,
2726 0x00080000,
2727 0x00080000,
2728 0x00080000,
2729 0x00080000,
2730 0x00080000,
2731 0x00080000,
2732 0x00080000,
2733 0x00080000,
2734 0x00080000,
2735 0x00080000,
2736 0x00080000,
2737 0x00080000,
2738 0x00080000,
2739 0x00080000,
2740 0x00080000,
2741 0x00080000,
2742 0x00080000,
2743 0x00080000,
2744 0x00080000,
2745 0x00080000,
2746 0x00080000,
2747 0x00080000,
2748 0x00080000,
2749 0x00080000,
2750 0x00080000,
2751 0x00080000,
2752 0x00080000,
2753 0x00080000,
2754 0x00080000,
2755 0x00080000,
2756 0x00080000,
2757 0x00080000,
2758 0x00080000,
2759 0x00080000,
2760 0x00080000,
2761 0x00080000,
2762 0x00080000,
2763 0x00080000,
2764 0x00080000,
2765 0x00080000,
2766 0x00080000,
2767 0x00080000,
2768 0x00080000,
2769 0x00080000,
2770};
2771
2772const struct phytbl_info dot11lcnphytbl_info_rev0[] = {
2773 {&dot11lcn_min_sig_sq_tbl_rev0,
2774 sizeof(dot11lcn_min_sig_sq_tbl_rev0) /
2775 sizeof(dot11lcn_min_sig_sq_tbl_rev0[0]), 2, 0, 16}
2776 ,
2777 {&dot11lcn_noise_scale_tbl_rev0,
2778 sizeof(dot11lcn_noise_scale_tbl_rev0) /
2779 sizeof(dot11lcn_noise_scale_tbl_rev0[0]), 1, 0, 16}
2780 ,
2781 {&dot11lcn_fltr_ctrl_tbl_rev0,
2782 sizeof(dot11lcn_fltr_ctrl_tbl_rev0) /
2783 sizeof(dot11lcn_fltr_ctrl_tbl_rev0[0]), 11, 0, 32}
2784 ,
2785 {&dot11lcn_ps_ctrl_tbl_rev0,
2786 sizeof(dot11lcn_ps_ctrl_tbl_rev0) /
2787 sizeof(dot11lcn_ps_ctrl_tbl_rev0[0]), 12, 0, 32}
2788 ,
2789 {&dot11lcn_gain_idx_tbl_rev0,
2790 sizeof(dot11lcn_gain_idx_tbl_rev0) /
2791 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
2792 ,
2793 {&dot11lcn_aux_gain_idx_tbl_rev0,
2794 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
2795 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
2796 ,
2797 {&dot11lcn_sw_ctrl_tbl_rev0,
2798 sizeof(dot11lcn_sw_ctrl_tbl_rev0) /
2799 sizeof(dot11lcn_sw_ctrl_tbl_rev0[0]), 15, 0, 16}
2800 ,
2801 {&dot11lcn_nf_table_rev0,
2802 sizeof(dot11lcn_nf_table_rev0) / sizeof(dot11lcn_nf_table_rev0[0]), 16,
2803 0, 8}
2804 ,
2805 {&dot11lcn_gain_val_tbl_rev0,
2806 sizeof(dot11lcn_gain_val_tbl_rev0) /
2807 sizeof(dot11lcn_gain_val_tbl_rev0[0]), 17, 0, 8}
2808 ,
2809 {&dot11lcn_gain_tbl_rev0,
2810 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
2811 0, 32}
2812 ,
2813 {&dot11lcn_spur_tbl_rev0,
2814 sizeof(dot11lcn_spur_tbl_rev0) / sizeof(dot11lcn_spur_tbl_rev0[0]), 20,
2815 0, 8}
2816 ,
2817 {&dot11lcn_unsup_mcs_tbl_rev0,
2818 sizeof(dot11lcn_unsup_mcs_tbl_rev0) /
2819 sizeof(dot11lcn_unsup_mcs_tbl_rev0[0]), 23, 0, 16}
2820 ,
2821 {&dot11lcn_iq_local_tbl_rev0,
2822 sizeof(dot11lcn_iq_local_tbl_rev0) /
2823 sizeof(dot11lcn_iq_local_tbl_rev0[0]), 0, 0, 16}
2824 ,
2825 {&dot11lcn_papd_compdelta_tbl_rev0,
2826 sizeof(dot11lcn_papd_compdelta_tbl_rev0) /
2827 sizeof(dot11lcn_papd_compdelta_tbl_rev0[0]), 24, 0, 32}
2828 ,
2829};
2830
2831const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313 = {
2832 &dot11lcn_sw_ctrl_tbl_4313_rev0,
2833 sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0) /
2834 sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0[0]), 15, 0, 16
2835};
2836
2837const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa = {
2838 &dot11lcn_sw_ctrl_tbl_4313_epa_rev0,
2839 sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0) /
2840 sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0[0]), 15, 0, 16
2841};
2842
2843const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = {
2844 &dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo,
2845 sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo) /
2846 sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[0]), 15, 0, 16
2847};
2848
2849const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = {
2850 &dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0,
2851 sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0) /
2852 sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[0]), 15, 0, 16
2853};
2854
2855const u32 dot11lcnphytbl_info_sz_rev0 =
2856 sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]);
2857
2858const struct lcnphy_tx_gain_tbl_entry
2859dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = {
2860 {3, 0, 31, 0, 72},
2861 {3, 0, 31, 0, 70},
2862 {3, 0, 31, 0, 68},
2863 {3, 0, 30, 0, 67},
2864 {3, 0, 29, 0, 68},
2865 {3, 0, 28, 0, 68},
2866 {3, 0, 27, 0, 69},
2867 {3, 0, 26, 0, 70},
2868 {3, 0, 25, 0, 70},
2869 {3, 0, 24, 0, 71},
2870 {3, 0, 23, 0, 72},
2871 {3, 0, 23, 0, 70},
2872 {3, 0, 22, 0, 71},
2873 {3, 0, 21, 0, 72},
2874 {3, 0, 21, 0, 70},
2875 {3, 0, 21, 0, 68},
2876 {3, 0, 21, 0, 66},
2877 {3, 0, 21, 0, 64},
2878 {3, 0, 21, 0, 63},
2879 {3, 0, 20, 0, 64},
2880 {3, 0, 19, 0, 65},
2881 {3, 0, 19, 0, 64},
2882 {3, 0, 18, 0, 65},
2883 {3, 0, 18, 0, 64},
2884 {3, 0, 17, 0, 65},
2885 {3, 0, 17, 0, 64},
2886 {3, 0, 16, 0, 65},
2887 {3, 0, 16, 0, 64},
2888 {3, 0, 16, 0, 62},
2889 {3, 0, 16, 0, 60},
2890 {3, 0, 16, 0, 58},
2891 {3, 0, 15, 0, 61},
2892 {3, 0, 15, 0, 59},
2893 {3, 0, 14, 0, 61},
2894 {3, 0, 14, 0, 60},
2895 {3, 0, 14, 0, 58},
2896 {3, 0, 13, 0, 60},
2897 {3, 0, 13, 0, 59},
2898 {3, 0, 12, 0, 62},
2899 {3, 0, 12, 0, 60},
2900 {3, 0, 12, 0, 58},
2901 {3, 0, 11, 0, 62},
2902 {3, 0, 11, 0, 60},
2903 {3, 0, 11, 0, 59},
2904 {3, 0, 11, 0, 57},
2905 {3, 0, 10, 0, 61},
2906 {3, 0, 10, 0, 59},
2907 {3, 0, 10, 0, 57},
2908 {3, 0, 9, 0, 62},
2909 {3, 0, 9, 0, 60},
2910 {3, 0, 9, 0, 58},
2911 {3, 0, 9, 0, 57},
2912 {3, 0, 8, 0, 62},
2913 {3, 0, 8, 0, 60},
2914 {3, 0, 8, 0, 58},
2915 {3, 0, 8, 0, 57},
2916 {3, 0, 8, 0, 55},
2917 {3, 0, 7, 0, 61},
2918 {3, 0, 7, 0, 60},
2919 {3, 0, 7, 0, 58},
2920 {3, 0, 7, 0, 56},
2921 {3, 0, 7, 0, 55},
2922 {3, 0, 6, 0, 62},
2923 {3, 0, 6, 0, 60},
2924 {3, 0, 6, 0, 58},
2925 {3, 0, 6, 0, 57},
2926 {3, 0, 6, 0, 55},
2927 {3, 0, 6, 0, 54},
2928 {3, 0, 6, 0, 52},
2929 {3, 0, 5, 0, 61},
2930 {3, 0, 5, 0, 59},
2931 {3, 0, 5, 0, 57},
2932 {3, 0, 5, 0, 56},
2933 {3, 0, 5, 0, 54},
2934 {3, 0, 5, 0, 53},
2935 {3, 0, 5, 0, 51},
2936 {3, 0, 4, 0, 62},
2937 {3, 0, 4, 0, 60},
2938 {3, 0, 4, 0, 58},
2939 {3, 0, 4, 0, 57},
2940 {3, 0, 4, 0, 55},
2941 {3, 0, 4, 0, 54},
2942 {3, 0, 4, 0, 52},
2943 {3, 0, 4, 0, 51},
2944 {3, 0, 4, 0, 49},
2945 {3, 0, 4, 0, 48},
2946 {3, 0, 4, 0, 46},
2947 {3, 0, 3, 0, 60},
2948 {3, 0, 3, 0, 58},
2949 {3, 0, 3, 0, 57},
2950 {3, 0, 3, 0, 55},
2951 {3, 0, 3, 0, 54},
2952 {3, 0, 3, 0, 52},
2953 {3, 0, 3, 0, 51},
2954 {3, 0, 3, 0, 49},
2955 {3, 0, 3, 0, 48},
2956 {3, 0, 3, 0, 46},
2957 {3, 0, 3, 0, 45},
2958 {3, 0, 3, 0, 44},
2959 {3, 0, 3, 0, 43},
2960 {3, 0, 3, 0, 41},
2961 {3, 0, 2, 0, 61},
2962 {3, 0, 2, 0, 59},
2963 {3, 0, 2, 0, 57},
2964 {3, 0, 2, 0, 56},
2965 {3, 0, 2, 0, 54},
2966 {3, 0, 2, 0, 53},
2967 {3, 0, 2, 0, 51},
2968 {3, 0, 2, 0, 50},
2969 {3, 0, 2, 0, 48},
2970 {3, 0, 2, 0, 47},
2971 {3, 0, 2, 0, 46},
2972 {3, 0, 2, 0, 44},
2973 {3, 0, 2, 0, 43},
2974 {3, 0, 2, 0, 42},
2975 {3, 0, 2, 0, 41},
2976 {3, 0, 2, 0, 39},
2977 {3, 0, 2, 0, 38},
2978 {3, 0, 2, 0, 37},
2979 {3, 0, 2, 0, 36},
2980 {3, 0, 2, 0, 35},
2981 {3, 0, 2, 0, 34},
2982 {3, 0, 2, 0, 33},
2983 {3, 0, 2, 0, 32},
2984 {3, 0, 1, 0, 63},
2985 {3, 0, 1, 0, 61},
2986 {3, 0, 1, 0, 59},
2987 {3, 0, 1, 0, 57},
2988};
2989
2990const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = {
2991 {7, 0, 31, 0, 72},
2992 {7, 0, 31, 0, 70},
2993 {7, 0, 31, 0, 68},
2994 {7, 0, 30, 0, 67},
2995 {7, 0, 29, 0, 68},
2996 {7, 0, 28, 0, 68},
2997 {7, 0, 27, 0, 69},
2998 {7, 0, 26, 0, 70},
2999 {7, 0, 25, 0, 70},
3000 {7, 0, 24, 0, 71},
3001 {7, 0, 23, 0, 72},
3002 {7, 0, 23, 0, 70},
3003 {7, 0, 22, 0, 71},
3004 {7, 0, 21, 0, 72},
3005 {7, 0, 21, 0, 70},
3006 {7, 0, 21, 0, 68},
3007 {7, 0, 21, 0, 66},
3008 {7, 0, 21, 0, 64},
3009 {7, 0, 21, 0, 63},
3010 {7, 0, 20, 0, 64},
3011 {7, 0, 19, 0, 65},
3012 {7, 0, 19, 0, 64},
3013 {7, 0, 18, 0, 65},
3014 {7, 0, 18, 0, 64},
3015 {7, 0, 17, 0, 65},
3016 {7, 0, 17, 0, 64},
3017 {7, 0, 16, 0, 65},
3018 {7, 0, 16, 0, 64},
3019 {7, 0, 16, 0, 62},
3020 {7, 0, 16, 0, 60},
3021 {7, 0, 16, 0, 58},
3022 {7, 0, 15, 0, 61},
3023 {7, 0, 15, 0, 59},
3024 {7, 0, 14, 0, 61},
3025 {7, 0, 14, 0, 60},
3026 {7, 0, 14, 0, 58},
3027 {7, 0, 13, 0, 60},
3028 {7, 0, 13, 0, 59},
3029 {7, 0, 12, 0, 62},
3030 {7, 0, 12, 0, 60},
3031 {7, 0, 12, 0, 58},
3032 {7, 0, 11, 0, 62},
3033 {7, 0, 11, 0, 60},
3034 {7, 0, 11, 0, 59},
3035 {7, 0, 11, 0, 57},
3036 {7, 0, 10, 0, 61},
3037 {7, 0, 10, 0, 59},
3038 {7, 0, 10, 0, 57},
3039 {7, 0, 9, 0, 62},
3040 {7, 0, 9, 0, 60},
3041 {7, 0, 9, 0, 58},
3042 {7, 0, 9, 0, 57},
3043 {7, 0, 8, 0, 62},
3044 {7, 0, 8, 0, 60},
3045 {7, 0, 8, 0, 58},
3046 {7, 0, 8, 0, 57},
3047 {7, 0, 8, 0, 55},
3048 {7, 0, 7, 0, 61},
3049 {7, 0, 7, 0, 60},
3050 {7, 0, 7, 0, 58},
3051 {7, 0, 7, 0, 56},
3052 {7, 0, 7, 0, 55},
3053 {7, 0, 6, 0, 62},
3054 {7, 0, 6, 0, 60},
3055 {7, 0, 6, 0, 58},
3056 {7, 0, 6, 0, 57},
3057 {7, 0, 6, 0, 55},
3058 {7, 0, 6, 0, 54},
3059 {7, 0, 6, 0, 52},
3060 {7, 0, 5, 0, 61},
3061 {7, 0, 5, 0, 59},
3062 {7, 0, 5, 0, 57},
3063 {7, 0, 5, 0, 56},
3064 {7, 0, 5, 0, 54},
3065 {7, 0, 5, 0, 53},
3066 {7, 0, 5, 0, 51},
3067 {7, 0, 4, 0, 62},
3068 {7, 0, 4, 0, 60},
3069 {7, 0, 4, 0, 58},
3070 {7, 0, 4, 0, 57},
3071 {7, 0, 4, 0, 55},
3072 {7, 0, 4, 0, 54},
3073 {7, 0, 4, 0, 52},
3074 {7, 0, 4, 0, 51},
3075 {7, 0, 4, 0, 49},
3076 {7, 0, 4, 0, 48},
3077 {7, 0, 4, 0, 46},
3078 {7, 0, 3, 0, 60},
3079 {7, 0, 3, 0, 58},
3080 {7, 0, 3, 0, 57},
3081 {7, 0, 3, 0, 55},
3082 {7, 0, 3, 0, 54},
3083 {7, 0, 3, 0, 52},
3084 {7, 0, 3, 0, 51},
3085 {7, 0, 3, 0, 49},
3086 {7, 0, 3, 0, 48},
3087 {7, 0, 3, 0, 46},
3088 {7, 0, 3, 0, 45},
3089 {7, 0, 3, 0, 44},
3090 {7, 0, 3, 0, 43},
3091 {7, 0, 3, 0, 41},
3092 {7, 0, 2, 0, 61},
3093 {7, 0, 2, 0, 59},
3094 {7, 0, 2, 0, 57},
3095 {7, 0, 2, 0, 56},
3096 {7, 0, 2, 0, 54},
3097 {7, 0, 2, 0, 53},
3098 {7, 0, 2, 0, 51},
3099 {7, 0, 2, 0, 50},
3100 {7, 0, 2, 0, 48},
3101 {7, 0, 2, 0, 47},
3102 {7, 0, 2, 0, 46},
3103 {7, 0, 2, 0, 44},
3104 {7, 0, 2, 0, 43},
3105 {7, 0, 2, 0, 42},
3106 {7, 0, 2, 0, 41},
3107 {7, 0, 2, 0, 39},
3108 {7, 0, 2, 0, 38},
3109 {7, 0, 2, 0, 37},
3110 {7, 0, 2, 0, 36},
3111 {7, 0, 2, 0, 35},
3112 {7, 0, 2, 0, 34},
3113 {7, 0, 2, 0, 33},
3114 {7, 0, 2, 0, 32},
3115 {7, 0, 1, 0, 63},
3116 {7, 0, 1, 0, 61},
3117 {7, 0, 1, 0, 59},
3118 {7, 0, 1, 0, 57},
3119};
3120
3121const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = {
3122 {255, 255, 0xf0, 0, 152},
3123 {255, 255, 0xf0, 0, 147},
3124 {255, 255, 0xf0, 0, 143},
3125 {255, 255, 0xf0, 0, 139},
3126 {255, 255, 0xf0, 0, 135},
3127 {255, 255, 0xf0, 0, 131},
3128 {255, 255, 0xf0, 0, 128},
3129 {255, 255, 0xf0, 0, 124},
3130 {255, 255, 0xf0, 0, 121},
3131 {255, 255, 0xf0, 0, 117},
3132 {255, 255, 0xf0, 0, 114},
3133 {255, 255, 0xf0, 0, 111},
3134 {255, 255, 0xf0, 0, 107},
3135 {255, 255, 0xf0, 0, 104},
3136 {255, 255, 0xf0, 0, 101},
3137 {255, 255, 0xf0, 0, 99},
3138 {255, 255, 0xf0, 0, 96},
3139 {255, 255, 0xf0, 0, 93},
3140 {255, 255, 0xf0, 0, 90},
3141 {255, 255, 0xf0, 0, 88},
3142 {255, 255, 0xf0, 0, 85},
3143 {255, 255, 0xf0, 0, 83},
3144 {255, 255, 0xf0, 0, 81},
3145 {255, 255, 0xf0, 0, 78},
3146 {255, 255, 0xf0, 0, 76},
3147 {255, 255, 0xf0, 0, 74},
3148 {255, 255, 0xf0, 0, 72},
3149 {255, 255, 0xf0, 0, 70},
3150 {255, 255, 0xf0, 0, 68},
3151 {255, 255, 0xf0, 0, 66},
3152 {255, 255, 0xf0, 0, 64},
3153 {255, 248, 0xf0, 0, 64},
3154 {255, 241, 0xf0, 0, 64},
3155 {255, 251, 0xe0, 0, 64},
3156 {255, 244, 0xe0, 0, 64},
3157 {255, 254, 0xd0, 0, 64},
3158 {255, 246, 0xd0, 0, 64},
3159 {255, 239, 0xd0, 0, 64},
3160 {255, 249, 0xc0, 0, 64},
3161 {255, 242, 0xc0, 0, 64},
3162 {255, 255, 0xb0, 0, 64},
3163 {255, 248, 0xb0, 0, 64},
3164 {255, 241, 0xb0, 0, 64},
3165 {255, 254, 0xa0, 0, 64},
3166 {255, 246, 0xa0, 0, 64},
3167 {255, 239, 0xa0, 0, 64},
3168 {255, 255, 0x90, 0, 64},
3169 {255, 248, 0x90, 0, 64},
3170 {255, 241, 0x90, 0, 64},
3171 {255, 234, 0x90, 0, 64},
3172 {255, 255, 0x80, 0, 64},
3173 {255, 248, 0x80, 0, 64},
3174 {255, 241, 0x80, 0, 64},
3175 {255, 234, 0x80, 0, 64},
3176 {255, 255, 0x70, 0, 64},
3177 {255, 248, 0x70, 0, 64},
3178 {255, 241, 0x70, 0, 64},
3179 {255, 234, 0x70, 0, 64},
3180 {255, 227, 0x70, 0, 64},
3181 {255, 221, 0x70, 0, 64},
3182 {255, 215, 0x70, 0, 64},
3183 {255, 208, 0x70, 0, 64},
3184 {255, 203, 0x70, 0, 64},
3185 {255, 197, 0x70, 0, 64},
3186 {255, 255, 0x60, 0, 64},
3187 {255, 248, 0x60, 0, 64},
3188 {255, 241, 0x60, 0, 64},
3189 {255, 234, 0x60, 0, 64},
3190 {255, 227, 0x60, 0, 64},
3191 {255, 221, 0x60, 0, 64},
3192 {255, 255, 0x50, 0, 64},
3193 {255, 248, 0x50, 0, 64},
3194 {255, 241, 0x50, 0, 64},
3195 {255, 234, 0x50, 0, 64},
3196 {255, 227, 0x50, 0, 64},
3197 {255, 221, 0x50, 0, 64},
3198 {255, 215, 0x50, 0, 64},
3199 {255, 208, 0x50, 0, 64},
3200 {255, 255, 0x40, 0, 64},
3201 {255, 248, 0x40, 0, 64},
3202 {255, 241, 0x40, 0, 64},
3203 {255, 234, 0x40, 0, 64},
3204 {255, 227, 0x40, 0, 64},
3205 {255, 221, 0x40, 0, 64},
3206 {255, 215, 0x40, 0, 64},
3207 {255, 208, 0x40, 0, 64},
3208 {255, 203, 0x40, 0, 64},
3209 {255, 197, 0x40, 0, 64},
3210 {255, 255, 0x30, 0, 64},
3211 {255, 248, 0x30, 0, 64},
3212 {255, 241, 0x30, 0, 64},
3213 {255, 234, 0x30, 0, 64},
3214 {255, 227, 0x30, 0, 64},
3215 {255, 221, 0x30, 0, 64},
3216 {255, 215, 0x30, 0, 64},
3217 {255, 208, 0x30, 0, 64},
3218 {255, 203, 0x30, 0, 64},
3219 {255, 197, 0x30, 0, 64},
3220 {255, 191, 0x30, 0, 64},
3221 {255, 186, 0x30, 0, 64},
3222 {255, 181, 0x30, 0, 64},
3223 {255, 175, 0x30, 0, 64},
3224 {255, 255, 0x20, 0, 64},
3225 {255, 248, 0x20, 0, 64},
3226 {255, 241, 0x20, 0, 64},
3227 {255, 234, 0x20, 0, 64},
3228 {255, 227, 0x20, 0, 64},
3229 {255, 221, 0x20, 0, 64},
3230 {255, 215, 0x20, 0, 64},
3231 {255, 208, 0x20, 0, 64},
3232 {255, 203, 0x20, 0, 64},
3233 {255, 197, 0x20, 0, 64},
3234 {255, 191, 0x20, 0, 64},
3235 {255, 186, 0x20, 0, 64},
3236 {255, 181, 0x20, 0, 64},
3237 {255, 175, 0x20, 0, 64},
3238 {255, 170, 0x20, 0, 64},
3239 {255, 166, 0x20, 0, 64},
3240 {255, 161, 0x20, 0, 64},
3241 {255, 156, 0x20, 0, 64},
3242 {255, 152, 0x20, 0, 64},
3243 {255, 148, 0x20, 0, 64},
3244 {255, 143, 0x20, 0, 64},
3245 {255, 139, 0x20, 0, 64},
3246 {255, 135, 0x20, 0, 64},
3247 {255, 132, 0x20, 0, 64},
3248 {255, 255, 0x10, 0, 64},
3249 {255, 248, 0x10, 0, 64},
3250};
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 000000000000..5f75e16bf5a7
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
@@ -0,0 +1,54 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <types.h>
18#include "phy_int.h"
19
20extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[];
21extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0;
22extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313;
23extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa;
24extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa_combo;
25extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa;
26extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250;
27
28extern const struct phytbl_info dot11lcnphytbl_info_rev0[];
29extern const u32 dot11lcnphytbl_info_sz_rev0;
30
31extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[];
32extern const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
33
34extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[];
35extern const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
36
37extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[];
38
39extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[];
40
41struct lcnphy_tx_gain_tbl_entry {
42 unsigned char gm;
43 unsigned char pga;
44 unsigned char pad;
45 unsigned char dac;
46 unsigned char bb_mult;
47};
48
49extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[];
50
51extern const struct
52lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[];
53
54extern 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 000000000000..dbf50ef6cd75
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
@@ -0,0 +1,10630 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <types.h>
18#include "phytbl_n.h"
19
20static const u32 frame_struct_rev0[] = {
21 0x08004a04,
22 0x00100000,
23 0x01000a05,
24 0x00100020,
25 0x09804506,
26 0x00100030,
27 0x09804507,
28 0x00100030,
29 0x00000000,
30 0x00000000,
31 0x00000000,
32 0x00000000,
33 0x00000000,
34 0x00000000,
35 0x00000000,
36 0x00000000,
37 0x08004a0c,
38 0x00100004,
39 0x01000a0d,
40 0x00100024,
41 0x0980450e,
42 0x00100034,
43 0x0980450f,
44 0x00100034,
45 0x00000000,
46 0x00000000,
47 0x00000000,
48 0x00000000,
49 0x00000000,
50 0x00000000,
51 0x00000000,
52 0x00000000,
53 0x00000a04,
54 0x00100000,
55 0x11008a05,
56 0x00100020,
57 0x1980c506,
58 0x00100030,
59 0x21810506,
60 0x00100030,
61 0x21810506,
62 0x00100030,
63 0x01800504,
64 0x00100030,
65 0x11808505,
66 0x00100030,
67 0x29814507,
68 0x01100030,
69 0x00000a04,
70 0x00100000,
71 0x11008a05,
72 0x00100020,
73 0x21810506,
74 0x00100030,
75 0x21810506,
76 0x00100030,
77 0x29814507,
78 0x01100030,
79 0x00000000,
80 0x00000000,
81 0x00000000,
82 0x00000000,
83 0x00000000,
84 0x00000000,
85 0x00000a0c,
86 0x00100008,
87 0x11008a0d,
88 0x00100028,
89 0x1980c50e,
90 0x00100038,
91 0x2181050e,
92 0x00100038,
93 0x2181050e,
94 0x00100038,
95 0x0180050c,
96 0x00100038,
97 0x1180850d,
98 0x00100038,
99 0x2981450f,
100 0x01100038,
101 0x00000a0c,
102 0x00100008,
103 0x11008a0d,
104 0x00100028,
105 0x2181050e,
106 0x00100038,
107 0x2181050e,
108 0x00100038,
109 0x2981450f,
110 0x01100038,
111 0x00000000,
112 0x00000000,
113 0x00000000,
114 0x00000000,
115 0x00000000,
116 0x00000000,
117 0x08004a04,
118 0x00100000,
119 0x01000a05,
120 0x00100020,
121 0x1980c506,
122 0x00100030,
123 0x1980c506,
124 0x00100030,
125 0x11808504,
126 0x00100030,
127 0x3981ca05,
128 0x00100030,
129 0x29814507,
130 0x01100030,
131 0x00000000,
132 0x00000000,
133 0x10008a04,
134 0x00100000,
135 0x3981ca05,
136 0x00100030,
137 0x1980c506,
138 0x00100030,
139 0x29814507,
140 0x01100030,
141 0x00000000,
142 0x00000000,
143 0x00000000,
144 0x00000000,
145 0x00000000,
146 0x00000000,
147 0x00000000,
148 0x00000000,
149 0x08004a0c,
150 0x00100008,
151 0x01000a0d,
152 0x00100028,
153 0x1980c50e,
154 0x00100038,
155 0x1980c50e,
156 0x00100038,
157 0x1180850c,
158 0x00100038,
159 0x3981ca0d,
160 0x00100038,
161 0x2981450f,
162 0x01100038,
163 0x00000000,
164 0x00000000,
165 0x10008a0c,
166 0x00100008,
167 0x3981ca0d,
168 0x00100038,
169 0x1980c50e,
170 0x00100038,
171 0x2981450f,
172 0x01100038,
173 0x00000000,
174 0x00000000,
175 0x00000000,
176 0x00000000,
177 0x00000000,
178 0x00000000,
179 0x00000000,
180 0x00000000,
181 0x40021404,
182 0x00100000,
183 0x02001405,
184 0x00100040,
185 0x0b004a06,
186 0x01900060,
187 0x13008a06,
188 0x01900060,
189 0x13008a06,
190 0x01900060,
191 0x43020a04,
192 0x00100060,
193 0x1b00ca05,
194 0x00100060,
195 0x23010a07,
196 0x01500060,
197 0x40021404,
198 0x00100000,
199 0x1a00d405,
200 0x00100040,
201 0x13008a06,
202 0x01900060,
203 0x13008a06,
204 0x01900060,
205 0x23010a07,
206 0x01500060,
207 0x00000000,
208 0x00000000,
209 0x00000000,
210 0x00000000,
211 0x00000000,
212 0x00000000,
213 0x4002140c,
214 0x00100010,
215 0x0200140d,
216 0x00100050,
217 0x0b004a0e,
218 0x01900070,
219 0x13008a0e,
220 0x01900070,
221 0x13008a0e,
222 0x01900070,
223 0x43020a0c,
224 0x00100070,
225 0x1b00ca0d,
226 0x00100070,
227 0x23010a0f,
228 0x01500070,
229 0x4002140c,
230 0x00100010,
231 0x1a00d40d,
232 0x00100050,
233 0x13008a0e,
234 0x01900070,
235 0x13008a0e,
236 0x01900070,
237 0x23010a0f,
238 0x01500070,
239 0x00000000,
240 0x00000000,
241 0x00000000,
242 0x00000000,
243 0x00000000,
244 0x00000000,
245 0x50029404,
246 0x00100000,
247 0x32019405,
248 0x00100040,
249 0x0b004a06,
250 0x01900060,
251 0x0b004a06,
252 0x01900060,
253 0x5b02ca04,
254 0x00100060,
255 0x3b01d405,
256 0x00100060,
257 0x23010a07,
258 0x01500060,
259 0x00000000,
260 0x00000000,
261 0x5802d404,
262 0x00100000,
263 0x3b01d405,
264 0x00100060,
265 0x0b004a06,
266 0x01900060,
267 0x23010a07,
268 0x01500060,
269 0x00000000,
270 0x00000000,
271 0x00000000,
272 0x00000000,
273 0x00000000,
274 0x00000000,
275 0x00000000,
276 0x00000000,
277 0x5002940c,
278 0x00100010,
279 0x3201940d,
280 0x00100050,
281 0x0b004a0e,
282 0x01900070,
283 0x0b004a0e,
284 0x01900070,
285 0x5b02ca0c,
286 0x00100070,
287 0x3b01d40d,
288 0x00100070,
289 0x23010a0f,
290 0x01500070,
291 0x00000000,
292 0x00000000,
293 0x5802d40c,
294 0x00100010,
295 0x3b01d40d,
296 0x00100070,
297 0x0b004a0e,
298 0x01900070,
299 0x23010a0f,
300 0x01500070,
301 0x00000000,
302 0x00000000,
303 0x00000000,
304 0x00000000,
305 0x00000000,
306 0x00000000,
307 0x00000000,
308 0x00000000,
309 0x40021404,
310 0x000f4800,
311 0x62031405,
312 0x00100040,
313 0x53028a06,
314 0x01900060,
315 0x53028a07,
316 0x01900060,
317 0x00000000,
318 0x00000000,
319 0x00000000,
320 0x00000000,
321 0x00000000,
322 0x00000000,
323 0x00000000,
324 0x00000000,
325 0x4002140c,
326 0x000f4808,
327 0x6203140d,
328 0x00100048,
329 0x53028a0e,
330 0x01900068,
331 0x53028a0f,
332 0x01900068,
333 0x00000000,
334 0x00000000,
335 0x00000000,
336 0x00000000,
337 0x00000000,
338 0x00000000,
339 0x00000000,
340 0x00000000,
341 0x00000a0c,
342 0x00100004,
343 0x11008a0d,
344 0x00100024,
345 0x1980c50e,
346 0x00100034,
347 0x2181050e,
348 0x00100034,
349 0x2181050e,
350 0x00100034,
351 0x0180050c,
352 0x00100038,
353 0x1180850d,
354 0x00100038,
355 0x1181850d,
356 0x00100038,
357 0x2981450f,
358 0x01100038,
359 0x00000000,
360 0x00000000,
361 0x00000000,
362 0x00000000,
363 0x00000000,
364 0x00000000,
365 0x00000000,
366 0x00000000,
367 0x00000000,
368 0x00000000,
369 0x00000000,
370 0x00000000,
371 0x00000000,
372 0x00000000,
373 0x00000a0c,
374 0x00100008,
375 0x11008a0d,
376 0x00100028,
377 0x2181050e,
378 0x00100038,
379 0x2181050e,
380 0x00100038,
381 0x1181850d,
382 0x00100038,
383 0x2981450f,
384 0x01100038,
385 0x00000000,
386 0x00000000,
387 0x00000000,
388 0x00000000,
389 0x00000000,
390 0x00000000,
391 0x00000000,
392 0x00000000,
393 0x00000000,
394 0x00000000,
395 0x00000000,
396 0x00000000,
397 0x00000000,
398 0x00000000,
399 0x00000000,
400 0x00000000,
401 0x00000000,
402 0x00000000,
403 0x00000000,
404 0x00000000,
405 0x08004a04,
406 0x00100000,
407 0x01000a05,
408 0x00100020,
409 0x0180c506,
410 0x00100030,
411 0x0180c506,
412 0x00100030,
413 0x2180c50c,
414 0x00100030,
415 0x49820a0d,
416 0x0016a130,
417 0x41824a0d,
418 0x0016a130,
419 0x2981450f,
420 0x01100030,
421 0x00000000,
422 0x00000000,
423 0x00000000,
424 0x00000000,
425 0x00000000,
426 0x00000000,
427 0x00000000,
428 0x00000000,
429 0x00000000,
430 0x00000000,
431 0x00000000,
432 0x00000000,
433 0x00000000,
434 0x00000000,
435 0x00000000,
436 0x00000000,
437 0x2000ca0c,
438 0x00100000,
439 0x49820a0d,
440 0x0016a130,
441 0x1980c50e,
442 0x00100030,
443 0x41824a0d,
444 0x0016a130,
445 0x2981450f,
446 0x01100030,
447 0x00000000,
448 0x00000000,
449 0x00000000,
450 0x00000000,
451 0x00000000,
452 0x00000000,
453 0x00000000,
454 0x00000000,
455 0x00000000,
456 0x00000000,
457 0x00000000,
458 0x00000000,
459 0x00000000,
460 0x00000000,
461 0x00000000,
462 0x00000000,
463 0x00000000,
464 0x00000000,
465 0x00000000,
466 0x00000000,
467 0x00000000,
468 0x00000000,
469 0x4002140c,
470 0x00100008,
471 0x0200140d,
472 0x00100048,
473 0x0b004a0e,
474 0x01900068,
475 0x13008a0e,
476 0x01900068,
477 0x13008a0e,
478 0x01900068,
479 0x43020a0c,
480 0x00100070,
481 0x1b00ca0d,
482 0x00100070,
483 0x1b014a0d,
484 0x00100070,
485 0x23010a0f,
486 0x01500070,
487 0x00000000,
488 0x00000000,
489 0x00000000,
490 0x00000000,
491 0x00000000,
492 0x00000000,
493 0x00000000,
494 0x00000000,
495 0x00000000,
496 0x00000000,
497 0x00000000,
498 0x00000000,
499 0x00000000,
500 0x00000000,
501 0x4002140c,
502 0x00100010,
503 0x1a00d40d,
504 0x00100050,
505 0x13008a0e,
506 0x01900070,
507 0x13008a0e,
508 0x01900070,
509 0x1b014a0d,
510 0x00100070,
511 0x23010a0f,
512 0x01500070,
513 0x00000000,
514 0x00000000,
515 0x00000000,
516 0x00000000,
517 0x00000000,
518 0x00000000,
519 0x00000000,
520 0x00000000,
521 0x00000000,
522 0x00000000,
523 0x00000000,
524 0x00000000,
525 0x00000000,
526 0x00000000,
527 0x00000000,
528 0x00000000,
529 0x00000000,
530 0x00000000,
531 0x00000000,
532 0x00000000,
533 0x50029404,
534 0x00100000,
535 0x32019405,
536 0x00100040,
537 0x03004a06,
538 0x01900060,
539 0x03004a06,
540 0x01900060,
541 0x6b030a0c,
542 0x00100060,
543 0x4b02140d,
544 0x0016a160,
545 0x4302540d,
546 0x0016a160,
547 0x23010a0f,
548 0x01500060,
549 0x00000000,
550 0x00000000,
551 0x00000000,
552 0x00000000,
553 0x00000000,
554 0x00000000,
555 0x00000000,
556 0x00000000,
557 0x00000000,
558 0x00000000,
559 0x00000000,
560 0x00000000,
561 0x00000000,
562 0x00000000,
563 0x00000000,
564 0x00000000,
565 0x6b03140c,
566 0x00100060,
567 0x4b02140d,
568 0x0016a160,
569 0x0b004a0e,
570 0x01900060,
571 0x4302540d,
572 0x0016a160,
573 0x23010a0f,
574 0x01500060,
575 0x00000000,
576 0x00000000,
577 0x00000000,
578 0x00000000,
579 0x00000000,
580 0x00000000,
581 0x00000000,
582 0x00000000,
583 0x00000000,
584 0x00000000,
585 0x00000000,
586 0x00000000,
587 0x00000000,
588 0x00000000,
589 0x00000000,
590 0x00000000,
591 0x00000000,
592 0x00000000,
593 0x00000000,
594 0x00000000,
595 0x00000000,
596 0x00000000,
597 0x40021404,
598 0x00100000,
599 0x1a00d405,
600 0x00100040,
601 0x53028a06,
602 0x01900060,
603 0x5b02ca06,
604 0x01900060,
605 0x5b02ca06,
606 0x01900060,
607 0x43020a04,
608 0x00100060,
609 0x1b00ca05,
610 0x00100060,
611 0x53028a07,
612 0x0190c060,
613 0x00000000,
614 0x00000000,
615 0x00000000,
616 0x00000000,
617 0x00000000,
618 0x00000000,
619 0x00000000,
620 0x00000000,
621 0x00000000,
622 0x00000000,
623 0x00000000,
624 0x00000000,
625 0x00000000,
626 0x00000000,
627 0x00000000,
628 0x00000000,
629 0x4002140c,
630 0x00100010,
631 0x1a00d40d,
632 0x00100050,
633 0x53028a0e,
634 0x01900070,
635 0x5b02ca0e,
636 0x01900070,
637 0x5b02ca0e,
638 0x01900070,
639 0x43020a0c,
640 0x00100070,
641 0x1b00ca0d,
642 0x00100070,
643 0x53028a0f,
644 0x0190c070,
645 0x00000000,
646 0x00000000,
647 0x00000000,
648 0x00000000,
649 0x00000000,
650 0x00000000,
651 0x00000000,
652 0x00000000,
653 0x00000000,
654 0x00000000,
655 0x00000000,
656 0x00000000,
657 0x00000000,
658 0x00000000,
659 0x00000000,
660 0x00000000,
661 0x40021404,
662 0x00100000,
663 0x1a00d405,
664 0x00100040,
665 0x5b02ca06,
666 0x01900060,
667 0x5b02ca06,
668 0x01900060,
669 0x53028a07,
670 0x0190c060,
671 0x00000000,
672 0x00000000,
673 0x00000000,
674 0x00000000,
675 0x00000000,
676 0x00000000,
677 0x00000000,
678 0x00000000,
679 0x00000000,
680 0x00000000,
681 0x00000000,
682 0x00000000,
683 0x00000000,
684 0x00000000,
685 0x00000000,
686 0x00000000,
687 0x00000000,
688 0x00000000,
689 0x00000000,
690 0x00000000,
691 0x00000000,
692 0x00000000,
693 0x4002140c,
694 0x00100010,
695 0x1a00d40d,
696 0x00100050,
697 0x5b02ca0e,
698 0x01900070,
699 0x5b02ca0e,
700 0x01900070,
701 0x53028a0f,
702 0x0190c070,
703 0x00000000,
704 0x00000000,
705 0x00000000,
706 0x00000000,
707 0x00000000,
708 0x00000000,
709 0x00000000,
710 0x00000000,
711 0x00000000,
712 0x00000000,
713 0x00000000,
714 0x00000000,
715 0x00000000,
716 0x00000000,
717 0x00000000,
718 0x00000000,
719 0x00000000,
720 0x00000000,
721 0x00000000,
722 0x00000000,
723 0x00000000,
724 0x00000000,
725 0x00000000,
726 0x00000000,
727 0x00000000,
728 0x00000000,
729 0x00000000,
730 0x00000000,
731 0x00000000,
732 0x00000000,
733 0x00000000,
734 0x00000000,
735 0x00000000,
736 0x00000000,
737 0x00000000,
738 0x00000000,
739 0x00000000,
740 0x00000000,
741 0x00000000,
742 0x00000000,
743 0x00000000,
744 0x00000000,
745 0x00000000,
746 0x00000000,
747 0x00000000,
748 0x00000000,
749 0x00000000,
750 0x00000000,
751 0x00000000,
752 0x00000000,
753 0x00000000,
754 0x00000000,
755 0x00000000,
756 0x00000000,
757 0x00000000,
758 0x00000000,
759 0x00000000,
760 0x00000000,
761 0x00000000,
762 0x00000000,
763 0x00000000,
764 0x00000000,
765 0x00000000,
766 0x00000000,
767 0x00000000,
768 0x00000000,
769 0x00000000,
770 0x00000000,
771 0x00000000,
772 0x00000000,
773 0x00000000,
774 0x00000000,
775 0x00000000,
776 0x00000000,
777 0x00000000,
778 0x00000000,
779 0x00000000,
780 0x00000000,
781 0x00000000,
782 0x00000000,
783 0x00000000,
784 0x00000000,
785 0x00000000,
786 0x00000000,
787 0x00000000,
788 0x00000000,
789 0x00000000,
790 0x00000000,
791 0x00000000,
792 0x00000000,
793 0x00000000,
794 0x00000000,
795 0x00000000,
796 0x00000000,
797 0x00000000,
798 0x00000000,
799 0x00000000,
800 0x00000000,
801 0x00000000,
802 0x00000000,
803 0x00000000,
804 0x00000000,
805 0x00000000,
806 0x00000000,
807 0x00000000,
808 0x00000000,
809 0x00000000,
810 0x00000000,
811 0x00000000,
812 0x00000000,
813 0x00000000,
814 0x00000000,
815 0x00000000,
816 0x00000000,
817 0x00000000,
818 0x00000000,
819 0x00000000,
820 0x00000000,
821 0x00000000,
822 0x00000000,
823 0x00000000,
824 0x00000000,
825 0x00000000,
826 0x00000000,
827 0x00000000,
828 0x00000000,
829 0x00000000,
830 0x00000000,
831 0x00000000,
832 0x00000000,
833 0x00000000,
834 0x00000000,
835 0x00000000,
836 0x00000000,
837 0x00000000,
838 0x00000000,
839 0x00000000,
840 0x00000000,
841 0x00000000,
842 0x00000000,
843 0x00000000,
844 0x00000000,
845 0x00000000,
846 0x00000000,
847 0x00000000,
848 0x00000000,
849 0x00000000,
850 0x00000000,
851 0x00000000,
852 0x00000000,
853};
854
855static const u8 frame_lut_rev0[] = {
856 0x02,
857 0x04,
858 0x14,
859 0x14,
860 0x03,
861 0x05,
862 0x16,
863 0x16,
864 0x0a,
865 0x0c,
866 0x1c,
867 0x1c,
868 0x0b,
869 0x0d,
870 0x1e,
871 0x1e,
872 0x06,
873 0x08,
874 0x18,
875 0x18,
876 0x07,
877 0x09,
878 0x1a,
879 0x1a,
880 0x0e,
881 0x10,
882 0x20,
883 0x28,
884 0x0f,
885 0x11,
886 0x22,
887 0x2a,
888};
889
890static const u32 tmap_tbl_rev0[] = {
891 0x8a88aa80,
892 0x8aaaaa8a,
893 0x8a8a8aa8,
894 0x00000888,
895 0x88000000,
896 0x8a8a88aa,
897 0x8aa88888,
898 0x8888a8a8,
899 0xf1111110,
900 0x11111111,
901 0x11f11111,
902 0x00000111,
903 0x11000000,
904 0x1111f111,
905 0x11111111,
906 0x111111f1,
907 0x8a88aa80,
908 0x8aaaaa8a,
909 0x8a8a8aa8,
910 0x000aa888,
911 0x88880000,
912 0x8a8a88aa,
913 0x8aa88888,
914 0x8888a8a8,
915 0xa1111110,
916 0x11111111,
917 0x11c11111,
918 0x00000111,
919 0x11000000,
920 0x1111a111,
921 0x11111111,
922 0x111111a1,
923 0xa2222220,
924 0x22222222,
925 0x22c22222,
926 0x00000222,
927 0x22000000,
928 0x2222a222,
929 0x22222222,
930 0x222222a2,
931 0xf1111110,
932 0x11111111,
933 0x11f11111,
934 0x00011111,
935 0x11110000,
936 0x1111f111,
937 0x11111111,
938 0x111111f1,
939 0xa8aa88a0,
940 0xa88888a8,
941 0xa8a8a88a,
942 0x00088aaa,
943 0xaaaa0000,
944 0xa8a8aa88,
945 0xa88aaaaa,
946 0xaaaa8a8a,
947 0xaaa8aaa0,
948 0x8aaa8aaa,
949 0xaa8a8a8a,
950 0x000aaa88,
951 0x8aaa0000,
952 0xaaa8a888,
953 0x8aa88a8a,
954 0x8a88a888,
955 0x08080a00,
956 0x0a08080a,
957 0x080a0a08,
958 0x00080808,
959 0x080a0000,
960 0x080a0808,
961 0x080a0808,
962 0x0a0a0a08,
963 0xa0a0a0a0,
964 0x80a0a080,
965 0x8080a0a0,
966 0x00008080,
967 0x80a00000,
968 0x80a080a0,
969 0xa080a0a0,
970 0x8080a0a0,
971 0x00000000,
972 0x00000000,
973 0x00000000,
974 0x00000000,
975 0x00000000,
976 0x00000000,
977 0x00000000,
978 0x00000000,
979 0x00000000,
980 0x00000000,
981 0x00000000,
982 0x00000000,
983 0x00000000,
984 0x00000000,
985 0x00000000,
986 0x00000000,
987 0x00000000,
988 0x00000000,
989 0x00000000,
990 0x00000000,
991 0x00000000,
992 0x00000000,
993 0x00000000,
994 0x00000000,
995 0x00000000,
996 0x00000000,
997 0x00000000,
998 0x00000000,
999 0x00000000,
1000 0x00000000,
1001 0x00000000,
1002 0x00000000,
1003 0x00000000,
1004 0x00000000,
1005 0x00000000,
1006 0x00000000,
1007 0x00000000,
1008 0x00000000,
1009 0x00000000,
1010 0x00000000,
1011 0x00000000,
1012 0x00000000,
1013 0x00000000,
1014 0x00000000,
1015 0x00000000,
1016 0x00000000,
1017 0x00000000,
1018 0x00000000,
1019 0x99999000,
1020 0x9b9b99bb,
1021 0x9bb99999,
1022 0x9999b9b9,
1023 0x9b99bb90,
1024 0x9bbbbb9b,
1025 0x9b9b9bb9,
1026 0x00000999,
1027 0x88000000,
1028 0x8a8a88aa,
1029 0x8aa88888,
1030 0x8888a8a8,
1031 0x8a88aa80,
1032 0x8aaaaa8a,
1033 0x8a8a8aa8,
1034 0x00aaa888,
1035 0x22000000,
1036 0x2222b222,
1037 0x22222222,
1038 0x222222b2,
1039 0xb2222220,
1040 0x22222222,
1041 0x22d22222,
1042 0x00000222,
1043 0x11000000,
1044 0x1111a111,
1045 0x11111111,
1046 0x111111a1,
1047 0xa1111110,
1048 0x11111111,
1049 0x11c11111,
1050 0x00000111,
1051 0x33000000,
1052 0x3333b333,
1053 0x33333333,
1054 0x333333b3,
1055 0xb3333330,
1056 0x33333333,
1057 0x33d33333,
1058 0x00000333,
1059 0x22000000,
1060 0x2222a222,
1061 0x22222222,
1062 0x222222a2,
1063 0xa2222220,
1064 0x22222222,
1065 0x22c22222,
1066 0x00000222,
1067 0x99b99b00,
1068 0x9b9b99bb,
1069 0x9bb99999,
1070 0x9999b9b9,
1071 0x9b99bb99,
1072 0x9bbbbb9b,
1073 0x9b9b9bb9,
1074 0x00000999,
1075 0x88000000,
1076 0x8a8a88aa,
1077 0x8aa88888,
1078 0x8888a8a8,
1079 0x8a88aa88,
1080 0x8aaaaa8a,
1081 0x8a8a8aa8,
1082 0x08aaa888,
1083 0x22222200,
1084 0x2222f222,
1085 0x22222222,
1086 0x222222f2,
1087 0x22222222,
1088 0x22222222,
1089 0x22f22222,
1090 0x00000222,
1091 0x11000000,
1092 0x1111f111,
1093 0x11111111,
1094 0x11111111,
1095 0xf1111111,
1096 0x11111111,
1097 0x11f11111,
1098 0x01111111,
1099 0xbb9bb900,
1100 0xb9b9bb99,
1101 0xb99bbbbb,
1102 0xbbbb9b9b,
1103 0xb9bb99bb,
1104 0xb99999b9,
1105 0xb9b9b99b,
1106 0x00000bbb,
1107 0xaa000000,
1108 0xa8a8aa88,
1109 0xa88aaaaa,
1110 0xaaaa8a8a,
1111 0xa8aa88aa,
1112 0xa88888a8,
1113 0xa8a8a88a,
1114 0x0a888aaa,
1115 0xaa000000,
1116 0xa8a8aa88,
1117 0xa88aaaaa,
1118 0xaaaa8a8a,
1119 0xa8aa88a0,
1120 0xa88888a8,
1121 0xa8a8a88a,
1122 0x00000aaa,
1123 0x88000000,
1124 0x8a8a88aa,
1125 0x8aa88888,
1126 0x8888a8a8,
1127 0x8a88aa80,
1128 0x8aaaaa8a,
1129 0x8a8a8aa8,
1130 0x00000888,
1131 0xbbbbbb00,
1132 0x999bbbbb,
1133 0x9bb99b9b,
1134 0xb9b9b9bb,
1135 0xb9b99bbb,
1136 0xb9b9b9bb,
1137 0xb9bb9b99,
1138 0x00000999,
1139 0x8a000000,
1140 0xaa88a888,
1141 0xa88888aa,
1142 0xa88a8a88,
1143 0xa88aa88a,
1144 0x88a8aaaa,
1145 0xa8aa8aaa,
1146 0x0888a88a,
1147 0x0b0b0b00,
1148 0x090b0b0b,
1149 0x0b090b0b,
1150 0x0909090b,
1151 0x09090b0b,
1152 0x09090b0b,
1153 0x09090b09,
1154 0x00000909,
1155 0x0a000000,
1156 0x0a080808,
1157 0x080a080a,
1158 0x080a0a08,
1159 0x080a080a,
1160 0x0808080a,
1161 0x0a0a0a08,
1162 0x0808080a,
1163 0xb0b0b000,
1164 0x9090b0b0,
1165 0x90b09090,
1166 0xb0b0b090,
1167 0xb0b090b0,
1168 0x90b0b0b0,
1169 0xb0b09090,
1170 0x00000090,
1171 0x80000000,
1172 0xa080a080,
1173 0xa08080a0,
1174 0xa0808080,
1175 0xa080a080,
1176 0x80a0a0a0,
1177 0xa0a080a0,
1178 0x00a0a0a0,
1179 0x22000000,
1180 0x2222f222,
1181 0x22222222,
1182 0x222222f2,
1183 0xf2222220,
1184 0x22222222,
1185 0x22f22222,
1186 0x00000222,
1187 0x11000000,
1188 0x1111f111,
1189 0x11111111,
1190 0x111111f1,
1191 0xf1111110,
1192 0x11111111,
1193 0x11f11111,
1194 0x00000111,
1195 0x33000000,
1196 0x3333f333,
1197 0x33333333,
1198 0x333333f3,
1199 0xf3333330,
1200 0x33333333,
1201 0x33f33333,
1202 0x00000333,
1203 0x22000000,
1204 0x2222f222,
1205 0x22222222,
1206 0x222222f2,
1207 0xf2222220,
1208 0x22222222,
1209 0x22f22222,
1210 0x00000222,
1211 0x99000000,
1212 0x9b9b99bb,
1213 0x9bb99999,
1214 0x9999b9b9,
1215 0x9b99bb90,
1216 0x9bbbbb9b,
1217 0x9b9b9bb9,
1218 0x00000999,
1219 0x88000000,
1220 0x8a8a88aa,
1221 0x8aa88888,
1222 0x8888a8a8,
1223 0x8a88aa80,
1224 0x8aaaaa8a,
1225 0x8a8a8aa8,
1226 0x00000888,
1227 0x88888000,
1228 0x8a8a88aa,
1229 0x8aa88888,
1230 0x8888a8a8,
1231 0x8a88aa80,
1232 0x8aaaaa8a,
1233 0x8a8a8aa8,
1234 0x00000888,
1235 0x88000000,
1236 0x8a8a88aa,
1237 0x8aa88888,
1238 0x8888a8a8,
1239 0x8a88aa80,
1240 0x8aaaaa8a,
1241 0x8a8a8aa8,
1242 0x00aaa888,
1243 0x88a88a00,
1244 0x8a8a88aa,
1245 0x8aa88888,
1246 0x8888a8a8,
1247 0x8a88aa88,
1248 0x8aaaaa8a,
1249 0x8a8a8aa8,
1250 0x00000888,
1251 0x88000000,
1252 0x8a8a88aa,
1253 0x8aa88888,
1254 0x8888a8a8,
1255 0x8a88aa88,
1256 0x8aaaaa8a,
1257 0x8a8a8aa8,
1258 0x08aaa888,
1259 0x11000000,
1260 0x1111a111,
1261 0x11111111,
1262 0x111111a1,
1263 0xa1111110,
1264 0x11111111,
1265 0x11c11111,
1266 0x00000111,
1267 0x11000000,
1268 0x1111a111,
1269 0x11111111,
1270 0x111111a1,
1271 0xa1111110,
1272 0x11111111,
1273 0x11c11111,
1274 0x00000111,
1275 0x88000000,
1276 0x8a8a88aa,
1277 0x8aa88888,
1278 0x8888a8a8,
1279 0x8a88aa80,
1280 0x8aaaaa8a,
1281 0x8a8a8aa8,
1282 0x00000888,
1283 0x88000000,
1284 0x8a8a88aa,
1285 0x8aa88888,
1286 0x8888a8a8,
1287 0x8a88aa80,
1288 0x8aaaaa8a,
1289 0x8a8a8aa8,
1290 0x00000888,
1291 0x00000000,
1292 0x00000000,
1293 0x00000000,
1294 0x00000000,
1295 0x00000000,
1296 0x00000000,
1297 0x00000000,
1298 0x00000000,
1299 0x00000000,
1300 0x00000000,
1301 0x00000000,
1302 0x00000000,
1303 0x00000000,
1304 0x00000000,
1305 0x00000000,
1306 0x00000000,
1307 0x00000000,
1308 0x00000000,
1309 0x00000000,
1310 0x00000000,
1311 0x00000000,
1312 0x00000000,
1313 0x00000000,
1314 0x00000000,
1315 0x00000000,
1316 0x00000000,
1317 0x00000000,
1318 0x00000000,
1319 0x00000000,
1320 0x00000000,
1321 0x00000000,
1322 0x00000000,
1323 0x00000000,
1324 0x00000000,
1325 0x00000000,
1326 0x00000000,
1327 0x00000000,
1328 0x00000000,
1329 0x00000000,
1330 0x00000000,
1331 0x00000000,
1332 0x00000000,
1333 0x00000000,
1334 0x00000000,
1335 0x00000000,
1336 0x00000000,
1337 0x00000000,
1338 0x00000000,
1339};
1340
1341static const u32 tdtrn_tbl_rev0[] = {
1342 0x061c061c,
1343 0x0050ee68,
1344 0xf592fe36,
1345 0xfe5212f6,
1346 0x00000c38,
1347 0xfe5212f6,
1348 0xf592fe36,
1349 0x0050ee68,
1350 0x061c061c,
1351 0xee680050,
1352 0xfe36f592,
1353 0x12f6fe52,
1354 0x0c380000,
1355 0x12f6fe52,
1356 0xfe36f592,
1357 0xee680050,
1358 0x061c061c,
1359 0x0050ee68,
1360 0xf592fe36,
1361 0xfe5212f6,
1362 0x00000c38,
1363 0xfe5212f6,
1364 0xf592fe36,
1365 0x0050ee68,
1366 0x061c061c,
1367 0xee680050,
1368 0xfe36f592,
1369 0x12f6fe52,
1370 0x0c380000,
1371 0x12f6fe52,
1372 0xfe36f592,
1373 0xee680050,
1374 0x05e305e3,
1375 0x004def0c,
1376 0xf5f3fe47,
1377 0xfe611246,
1378 0x00000bc7,
1379 0xfe611246,
1380 0xf5f3fe47,
1381 0x004def0c,
1382 0x05e305e3,
1383 0xef0c004d,
1384 0xfe47f5f3,
1385 0x1246fe61,
1386 0x0bc70000,
1387 0x1246fe61,
1388 0xfe47f5f3,
1389 0xef0c004d,
1390 0x05e305e3,
1391 0x004def0c,
1392 0xf5f3fe47,
1393 0xfe611246,
1394 0x00000bc7,
1395 0xfe611246,
1396 0xf5f3fe47,
1397 0x004def0c,
1398 0x05e305e3,
1399 0xef0c004d,
1400 0xfe47f5f3,
1401 0x1246fe61,
1402 0x0bc70000,
1403 0x1246fe61,
1404 0xfe47f5f3,
1405 0xef0c004d,
1406 0xfa58fa58,
1407 0xf895043b,
1408 0xff4c09c0,
1409 0xfbc6ffa8,
1410 0xfb84f384,
1411 0x0798f6f9,
1412 0x05760122,
1413 0x058409f6,
1414 0x0b500000,
1415 0x05b7f542,
1416 0x08860432,
1417 0x06ddfee7,
1418 0xfb84f384,
1419 0xf9d90664,
1420 0xf7e8025c,
1421 0x00fff7bd,
1422 0x05a805a8,
1423 0xf7bd00ff,
1424 0x025cf7e8,
1425 0x0664f9d9,
1426 0xf384fb84,
1427 0xfee706dd,
1428 0x04320886,
1429 0xf54205b7,
1430 0x00000b50,
1431 0x09f60584,
1432 0x01220576,
1433 0xf6f90798,
1434 0xf384fb84,
1435 0xffa8fbc6,
1436 0x09c0ff4c,
1437 0x043bf895,
1438 0x02d402d4,
1439 0x07de0270,
1440 0xfc96079c,
1441 0xf90afe94,
1442 0xfe00ff2c,
1443 0x02d4065d,
1444 0x092a0096,
1445 0x0014fbb8,
1446 0xfd2cfd2c,
1447 0x076afb3c,
1448 0x0096f752,
1449 0xf991fd87,
1450 0xfb2c0200,
1451 0xfeb8f960,
1452 0x08e0fc96,
1453 0x049802a8,
1454 0xfd2cfd2c,
1455 0x02a80498,
1456 0xfc9608e0,
1457 0xf960feb8,
1458 0x0200fb2c,
1459 0xfd87f991,
1460 0xf7520096,
1461 0xfb3c076a,
1462 0xfd2cfd2c,
1463 0xfbb80014,
1464 0x0096092a,
1465 0x065d02d4,
1466 0xff2cfe00,
1467 0xfe94f90a,
1468 0x079cfc96,
1469 0x027007de,
1470 0x02d402d4,
1471 0x027007de,
1472 0x079cfc96,
1473 0xfe94f90a,
1474 0xff2cfe00,
1475 0x065d02d4,
1476 0x0096092a,
1477 0xfbb80014,
1478 0xfd2cfd2c,
1479 0xfb3c076a,
1480 0xf7520096,
1481 0xfd87f991,
1482 0x0200fb2c,
1483 0xf960feb8,
1484 0xfc9608e0,
1485 0x02a80498,
1486 0xfd2cfd2c,
1487 0x049802a8,
1488 0x08e0fc96,
1489 0xfeb8f960,
1490 0xfb2c0200,
1491 0xf991fd87,
1492 0x0096f752,
1493 0x076afb3c,
1494 0xfd2cfd2c,
1495 0x0014fbb8,
1496 0x092a0096,
1497 0x02d4065d,
1498 0xfe00ff2c,
1499 0xf90afe94,
1500 0xfc96079c,
1501 0x07de0270,
1502 0x00000000,
1503 0x00000000,
1504 0x00000000,
1505 0x00000000,
1506 0x00000000,
1507 0x00000000,
1508 0x00000000,
1509 0x00000000,
1510 0x00000000,
1511 0x00000000,
1512 0x00000000,
1513 0x00000000,
1514 0x00000000,
1515 0x00000000,
1516 0x00000000,
1517 0x00000000,
1518 0x00000000,
1519 0x00000000,
1520 0x00000000,
1521 0x00000000,
1522 0x00000000,
1523 0x00000000,
1524 0x00000000,
1525 0x00000000,
1526 0x00000000,
1527 0x00000000,
1528 0x00000000,
1529 0x00000000,
1530 0x00000000,
1531 0x00000000,
1532 0x00000000,
1533 0x00000000,
1534 0x00000000,
1535 0x00000000,
1536 0x00000000,
1537 0x00000000,
1538 0x00000000,
1539 0x00000000,
1540 0x00000000,
1541 0x00000000,
1542 0x00000000,
1543 0x00000000,
1544 0x00000000,
1545 0x00000000,
1546 0x00000000,
1547 0x00000000,
1548 0x00000000,
1549 0x00000000,
1550 0x00000000,
1551 0x00000000,
1552 0x00000000,
1553 0x00000000,
1554 0x00000000,
1555 0x00000000,
1556 0x00000000,
1557 0x00000000,
1558 0x00000000,
1559 0x00000000,
1560 0x00000000,
1561 0x00000000,
1562 0x00000000,
1563 0x00000000,
1564 0x00000000,
1565 0x00000000,
1566 0x00000000,
1567 0x00000000,
1568 0x00000000,
1569 0x00000000,
1570 0x00000000,
1571 0x00000000,
1572 0x00000000,
1573 0x00000000,
1574 0x00000000,
1575 0x00000000,
1576 0x00000000,
1577 0x00000000,
1578 0x00000000,
1579 0x00000000,
1580 0x00000000,
1581 0x00000000,
1582 0x00000000,
1583 0x00000000,
1584 0x00000000,
1585 0x00000000,
1586 0x00000000,
1587 0x00000000,
1588 0x00000000,
1589 0x00000000,
1590 0x00000000,
1591 0x00000000,
1592 0x00000000,
1593 0x00000000,
1594 0x00000000,
1595 0x00000000,
1596 0x00000000,
1597 0x00000000,
1598 0x062a0000,
1599 0xfefa0759,
1600 0x08b80908,
1601 0xf396fc2d,
1602 0xf9d6045c,
1603 0xfc4ef608,
1604 0xf748f596,
1605 0x07b207bf,
1606 0x062a062a,
1607 0xf84ef841,
1608 0xf748f596,
1609 0x03b209f8,
1610 0xf9d6045c,
1611 0x0c6a03d3,
1612 0x08b80908,
1613 0x0106f8a7,
1614 0x062a0000,
1615 0xfefaf8a7,
1616 0x08b8f6f8,
1617 0xf39603d3,
1618 0xf9d6fba4,
1619 0xfc4e09f8,
1620 0xf7480a6a,
1621 0x07b2f841,
1622 0x062af9d6,
1623 0xf84e07bf,
1624 0xf7480a6a,
1625 0x03b2f608,
1626 0xf9d6fba4,
1627 0x0c6afc2d,
1628 0x08b8f6f8,
1629 0x01060759,
1630 0x062a0000,
1631 0xfefa0759,
1632 0x08b80908,
1633 0xf396fc2d,
1634 0xf9d6045c,
1635 0xfc4ef608,
1636 0xf748f596,
1637 0x07b207bf,
1638 0x062a062a,
1639 0xf84ef841,
1640 0xf748f596,
1641 0x03b209f8,
1642 0xf9d6045c,
1643 0x0c6a03d3,
1644 0x08b80908,
1645 0x0106f8a7,
1646 0x062a0000,
1647 0xfefaf8a7,
1648 0x08b8f6f8,
1649 0xf39603d3,
1650 0xf9d6fba4,
1651 0xfc4e09f8,
1652 0xf7480a6a,
1653 0x07b2f841,
1654 0x062af9d6,
1655 0xf84e07bf,
1656 0xf7480a6a,
1657 0x03b2f608,
1658 0xf9d6fba4,
1659 0x0c6afc2d,
1660 0x08b8f6f8,
1661 0x01060759,
1662 0x061c061c,
1663 0xff30009d,
1664 0xffb21141,
1665 0xfd87fb54,
1666 0xf65dfe59,
1667 0x02eef99e,
1668 0x0166f03c,
1669 0xfff809b6,
1670 0x000008a4,
1671 0x000af42b,
1672 0x00eff577,
1673 0xfa840bf2,
1674 0xfc02ff51,
1675 0x08260f67,
1676 0xfff0036f,
1677 0x0842f9c3,
1678 0x00000000,
1679 0x063df7be,
1680 0xfc910010,
1681 0xf099f7da,
1682 0x00af03fe,
1683 0xf40e057c,
1684 0x0a89ff11,
1685 0x0bd5fff6,
1686 0xf75c0000,
1687 0xf64a0008,
1688 0x0fc4fe9a,
1689 0x0662fd12,
1690 0x01a709a3,
1691 0x04ac0279,
1692 0xeebf004e,
1693 0xff6300d0,
1694 0xf9e4f9e4,
1695 0x00d0ff63,
1696 0x004eeebf,
1697 0x027904ac,
1698 0x09a301a7,
1699 0xfd120662,
1700 0xfe9a0fc4,
1701 0x0008f64a,
1702 0x0000f75c,
1703 0xfff60bd5,
1704 0xff110a89,
1705 0x057cf40e,
1706 0x03fe00af,
1707 0xf7daf099,
1708 0x0010fc91,
1709 0xf7be063d,
1710 0x00000000,
1711 0xf9c30842,
1712 0x036ffff0,
1713 0x0f670826,
1714 0xff51fc02,
1715 0x0bf2fa84,
1716 0xf57700ef,
1717 0xf42b000a,
1718 0x08a40000,
1719 0x09b6fff8,
1720 0xf03c0166,
1721 0xf99e02ee,
1722 0xfe59f65d,
1723 0xfb54fd87,
1724 0x1141ffb2,
1725 0x009dff30,
1726 0x05e30000,
1727 0xff060705,
1728 0x085408a0,
1729 0xf425fc59,
1730 0xfa1d042a,
1731 0xfc78f67a,
1732 0xf7acf60e,
1733 0x075a0766,
1734 0x05e305e3,
1735 0xf8a6f89a,
1736 0xf7acf60e,
1737 0x03880986,
1738 0xfa1d042a,
1739 0x0bdb03a7,
1740 0x085408a0,
1741 0x00faf8fb,
1742 0x05e30000,
1743 0xff06f8fb,
1744 0x0854f760,
1745 0xf42503a7,
1746 0xfa1dfbd6,
1747 0xfc780986,
1748 0xf7ac09f2,
1749 0x075af89a,
1750 0x05e3fa1d,
1751 0xf8a60766,
1752 0xf7ac09f2,
1753 0x0388f67a,
1754 0xfa1dfbd6,
1755 0x0bdbfc59,
1756 0x0854f760,
1757 0x00fa0705,
1758 0x05e30000,
1759 0xff060705,
1760 0x085408a0,
1761 0xf425fc59,
1762 0xfa1d042a,
1763 0xfc78f67a,
1764 0xf7acf60e,
1765 0x075a0766,
1766 0x05e305e3,
1767 0xf8a6f89a,
1768 0xf7acf60e,
1769 0x03880986,
1770 0xfa1d042a,
1771 0x0bdb03a7,
1772 0x085408a0,
1773 0x00faf8fb,
1774 0x05e30000,
1775 0xff06f8fb,
1776 0x0854f760,
1777 0xf42503a7,
1778 0xfa1dfbd6,
1779 0xfc780986,
1780 0xf7ac09f2,
1781 0x075af89a,
1782 0x05e3fa1d,
1783 0xf8a60766,
1784 0xf7ac09f2,
1785 0x0388f67a,
1786 0xfa1dfbd6,
1787 0x0bdbfc59,
1788 0x0854f760,
1789 0x00fa0705,
1790 0xfa58fa58,
1791 0xf8f0fe00,
1792 0x0448073d,
1793 0xfdc9fe46,
1794 0xf9910258,
1795 0x089d0407,
1796 0xfd5cf71a,
1797 0x02affde0,
1798 0x083e0496,
1799 0xff5a0740,
1800 0xff7afd97,
1801 0x00fe01f1,
1802 0x0009082e,
1803 0xfa94ff75,
1804 0xfecdf8ea,
1805 0xffb0f693,
1806 0xfd2cfa58,
1807 0x0433ff16,
1808 0xfba405dd,
1809 0xfa610341,
1810 0x06a606cb,
1811 0x0039fd2d,
1812 0x0677fa97,
1813 0x01fa05e0,
1814 0xf896003e,
1815 0x075a068b,
1816 0x012cfc3e,
1817 0xfa23f98d,
1818 0xfc7cfd43,
1819 0xff90fc0d,
1820 0x01c10982,
1821 0x00c601d6,
1822 0xfd2cfd2c,
1823 0x01d600c6,
1824 0x098201c1,
1825 0xfc0dff90,
1826 0xfd43fc7c,
1827 0xf98dfa23,
1828 0xfc3e012c,
1829 0x068b075a,
1830 0x003ef896,
1831 0x05e001fa,
1832 0xfa970677,
1833 0xfd2d0039,
1834 0x06cb06a6,
1835 0x0341fa61,
1836 0x05ddfba4,
1837 0xff160433,
1838 0xfa58fd2c,
1839 0xf693ffb0,
1840 0xf8eafecd,
1841 0xff75fa94,
1842 0x082e0009,
1843 0x01f100fe,
1844 0xfd97ff7a,
1845 0x0740ff5a,
1846 0x0496083e,
1847 0xfde002af,
1848 0xf71afd5c,
1849 0x0407089d,
1850 0x0258f991,
1851 0xfe46fdc9,
1852 0x073d0448,
1853 0xfe00f8f0,
1854 0xfd2cfd2c,
1855 0xfce00500,
1856 0xfc09fddc,
1857 0xfe680157,
1858 0x04c70571,
1859 0xfc3aff21,
1860 0xfcd70228,
1861 0x056d0277,
1862 0x0200fe00,
1863 0x0022f927,
1864 0xfe3c032b,
1865 0xfc44ff3c,
1866 0x03e9fbdb,
1867 0x04570313,
1868 0x04c9ff5c,
1869 0x000d03b8,
1870 0xfa580000,
1871 0xfbe900d2,
1872 0xf9d0fe0b,
1873 0x0125fdf9,
1874 0x042501bf,
1875 0x0328fa2b,
1876 0xffa902f0,
1877 0xfa250157,
1878 0x0200fe00,
1879 0x03740438,
1880 0xff0405fd,
1881 0x030cfe52,
1882 0x0037fb39,
1883 0xff6904c5,
1884 0x04f8fd23,
1885 0xfd31fc1b,
1886 0xfd2cfd2c,
1887 0xfc1bfd31,
1888 0xfd2304f8,
1889 0x04c5ff69,
1890 0xfb390037,
1891 0xfe52030c,
1892 0x05fdff04,
1893 0x04380374,
1894 0xfe000200,
1895 0x0157fa25,
1896 0x02f0ffa9,
1897 0xfa2b0328,
1898 0x01bf0425,
1899 0xfdf90125,
1900 0xfe0bf9d0,
1901 0x00d2fbe9,
1902 0x0000fa58,
1903 0x03b8000d,
1904 0xff5c04c9,
1905 0x03130457,
1906 0xfbdb03e9,
1907 0xff3cfc44,
1908 0x032bfe3c,
1909 0xf9270022,
1910 0xfe000200,
1911 0x0277056d,
1912 0x0228fcd7,
1913 0xff21fc3a,
1914 0x057104c7,
1915 0x0157fe68,
1916 0xfddcfc09,
1917 0x0500fce0,
1918 0xfd2cfd2c,
1919 0x0500fce0,
1920 0xfddcfc09,
1921 0x0157fe68,
1922 0x057104c7,
1923 0xff21fc3a,
1924 0x0228fcd7,
1925 0x0277056d,
1926 0xfe000200,
1927 0xf9270022,
1928 0x032bfe3c,
1929 0xff3cfc44,
1930 0xfbdb03e9,
1931 0x03130457,
1932 0xff5c04c9,
1933 0x03b8000d,
1934 0x0000fa58,
1935 0x00d2fbe9,
1936 0xfe0bf9d0,
1937 0xfdf90125,
1938 0x01bf0425,
1939 0xfa2b0328,
1940 0x02f0ffa9,
1941 0x0157fa25,
1942 0xfe000200,
1943 0x04380374,
1944 0x05fdff04,
1945 0xfe52030c,
1946 0xfb390037,
1947 0x04c5ff69,
1948 0xfd2304f8,
1949 0xfc1bfd31,
1950 0xfd2cfd2c,
1951 0xfd31fc1b,
1952 0x04f8fd23,
1953 0xff6904c5,
1954 0x0037fb39,
1955 0x030cfe52,
1956 0xff0405fd,
1957 0x03740438,
1958 0x0200fe00,
1959 0xfa250157,
1960 0xffa902f0,
1961 0x0328fa2b,
1962 0x042501bf,
1963 0x0125fdf9,
1964 0xf9d0fe0b,
1965 0xfbe900d2,
1966 0xfa580000,
1967 0x000d03b8,
1968 0x04c9ff5c,
1969 0x04570313,
1970 0x03e9fbdb,
1971 0xfc44ff3c,
1972 0xfe3c032b,
1973 0x0022f927,
1974 0x0200fe00,
1975 0x056d0277,
1976 0xfcd70228,
1977 0xfc3aff21,
1978 0x04c70571,
1979 0xfe680157,
1980 0xfc09fddc,
1981 0xfce00500,
1982 0x05a80000,
1983 0xff1006be,
1984 0x0800084a,
1985 0xf49cfc7e,
1986 0xfa580400,
1987 0xfc9cf6da,
1988 0xf800f672,
1989 0x0710071c,
1990 0x05a805a8,
1991 0xf8f0f8e4,
1992 0xf800f672,
1993 0x03640926,
1994 0xfa580400,
1995 0x0b640382,
1996 0x0800084a,
1997 0x00f0f942,
1998 0x05a80000,
1999 0xff10f942,
2000 0x0800f7b6,
2001 0xf49c0382,
2002 0xfa58fc00,
2003 0xfc9c0926,
2004 0xf800098e,
2005 0x0710f8e4,
2006 0x05a8fa58,
2007 0xf8f0071c,
2008 0xf800098e,
2009 0x0364f6da,
2010 0xfa58fc00,
2011 0x0b64fc7e,
2012 0x0800f7b6,
2013 0x00f006be,
2014 0x05a80000,
2015 0xff1006be,
2016 0x0800084a,
2017 0xf49cfc7e,
2018 0xfa580400,
2019 0xfc9cf6da,
2020 0xf800f672,
2021 0x0710071c,
2022 0x05a805a8,
2023 0xf8f0f8e4,
2024 0xf800f672,
2025 0x03640926,
2026 0xfa580400,
2027 0x0b640382,
2028 0x0800084a,
2029 0x00f0f942,
2030 0x05a80000,
2031 0xff10f942,
2032 0x0800f7b6,
2033 0xf49c0382,
2034 0xfa58fc00,
2035 0xfc9c0926,
2036 0xf800098e,
2037 0x0710f8e4,
2038 0x05a8fa58,
2039 0xf8f0071c,
2040 0xf800098e,
2041 0x0364f6da,
2042 0xfa58fc00,
2043 0x0b64fc7e,
2044 0x0800f7b6,
2045 0x00f006be,
2046};
2047
2048static const u32 intlv_tbl_rev0[] = {
2049 0x00802070,
2050 0x0671188d,
2051 0x0a60192c,
2052 0x0a300e46,
2053 0x00c1188d,
2054 0x080024d2,
2055 0x00000070,
2056};
2057
2058static const u16 pilot_tbl_rev0[] = {
2059 0xff08,
2060 0xff08,
2061 0xff08,
2062 0xff08,
2063 0xff08,
2064 0xff08,
2065 0xff08,
2066 0xff08,
2067 0x80d5,
2068 0x80d5,
2069 0x80d5,
2070 0x80d5,
2071 0x80d5,
2072 0x80d5,
2073 0x80d5,
2074 0x80d5,
2075 0xff0a,
2076 0xff82,
2077 0xffa0,
2078 0xff28,
2079 0xffff,
2080 0xffff,
2081 0xffff,
2082 0xffff,
2083 0xff82,
2084 0xffa0,
2085 0xff28,
2086 0xff0a,
2087 0xffff,
2088 0xffff,
2089 0xffff,
2090 0xffff,
2091 0xf83f,
2092 0xfa1f,
2093 0xfa97,
2094 0xfab5,
2095 0xf2bd,
2096 0xf0bf,
2097 0xffff,
2098 0xffff,
2099 0xf017,
2100 0xf815,
2101 0xf215,
2102 0xf095,
2103 0xf035,
2104 0xf01d,
2105 0xffff,
2106 0xffff,
2107 0xff08,
2108 0xff02,
2109 0xff80,
2110 0xff20,
2111 0xff08,
2112 0xff02,
2113 0xff80,
2114 0xff20,
2115 0xf01f,
2116 0xf817,
2117 0xfa15,
2118 0xf295,
2119 0xf0b5,
2120 0xf03d,
2121 0xffff,
2122 0xffff,
2123 0xf82a,
2124 0xfa0a,
2125 0xfa82,
2126 0xfaa0,
2127 0xf2a8,
2128 0xf0aa,
2129 0xffff,
2130 0xffff,
2131 0xf002,
2132 0xf800,
2133 0xf200,
2134 0xf080,
2135 0xf020,
2136 0xf008,
2137 0xffff,
2138 0xffff,
2139 0xf00a,
2140 0xf802,
2141 0xfa00,
2142 0xf280,
2143 0xf0a0,
2144 0xf028,
2145 0xffff,
2146 0xffff,
2147};
2148
2149static const u32 pltlut_tbl_rev0[] = {
2150 0x76540123,
2151 0x62407351,
2152 0x76543201,
2153 0x76540213,
2154 0x76540123,
2155 0x76430521,
2156};
2157
2158static const u32 tdi_tbl20_ant0_rev0[] = {
2159 0x00091226,
2160 0x000a1429,
2161 0x000b56ad,
2162 0x000c58b0,
2163 0x000d5ab3,
2164 0x000e9cb6,
2165 0x000f9eba,
2166 0x0000c13d,
2167 0x00020301,
2168 0x00030504,
2169 0x00040708,
2170 0x0005090b,
2171 0x00064b8e,
2172 0x00095291,
2173 0x000a5494,
2174 0x000b9718,
2175 0x000c9927,
2176 0x000d9b2a,
2177 0x000edd2e,
2178 0x000fdf31,
2179 0x000101b4,
2180 0x000243b7,
2181 0x000345bb,
2182 0x000447be,
2183 0x00058982,
2184 0x00068c05,
2185 0x00099309,
2186 0x000a950c,
2187 0x000bd78f,
2188 0x000cd992,
2189 0x000ddb96,
2190 0x000f1d99,
2191 0x00005fa8,
2192 0x0001422c,
2193 0x0002842f,
2194 0x00038632,
2195 0x00048835,
2196 0x0005ca38,
2197 0x0006ccbc,
2198 0x0009d3bf,
2199 0x000b1603,
2200 0x000c1806,
2201 0x000d1a0a,
2202 0x000e1c0d,
2203 0x000f5e10,
2204 0x00008093,
2205 0x00018297,
2206 0x0002c49a,
2207 0x0003c680,
2208 0x0004c880,
2209 0x00060b00,
2210 0x00070d00,
2211 0x00000000,
2212 0x00000000,
2213 0x00000000,
2214};
2215
2216static const u32 tdi_tbl20_ant1_rev0[] = {
2217 0x00014b26,
2218 0x00028d29,
2219 0x000393ad,
2220 0x00049630,
2221 0x0005d833,
2222 0x0006da36,
2223 0x00099c3a,
2224 0x000a9e3d,
2225 0x000bc081,
2226 0x000cc284,
2227 0x000dc488,
2228 0x000f068b,
2229 0x0000488e,
2230 0x00018b91,
2231 0x0002d214,
2232 0x0003d418,
2233 0x0004d6a7,
2234 0x000618aa,
2235 0x00071aae,
2236 0x0009dcb1,
2237 0x000b1eb4,
2238 0x000c0137,
2239 0x000d033b,
2240 0x000e053e,
2241 0x000f4702,
2242 0x00008905,
2243 0x00020c09,
2244 0x0003128c,
2245 0x0004148f,
2246 0x00051712,
2247 0x00065916,
2248 0x00091b19,
2249 0x000a1d28,
2250 0x000b5f2c,
2251 0x000c41af,
2252 0x000d43b2,
2253 0x000e85b5,
2254 0x000f87b8,
2255 0x0000c9bc,
2256 0x00024cbf,
2257 0x00035303,
2258 0x00045506,
2259 0x0005978a,
2260 0x0006998d,
2261 0x00095b90,
2262 0x000a5d93,
2263 0x000b9f97,
2264 0x000c821a,
2265 0x000d8400,
2266 0x000ec600,
2267 0x000fc800,
2268 0x00010a00,
2269 0x00000000,
2270 0x00000000,
2271 0x00000000,
2272};
2273
2274static const u32 tdi_tbl40_ant0_rev0[] = {
2275 0x0011a346,
2276 0x00136ccf,
2277 0x0014f5d9,
2278 0x001641e2,
2279 0x0017cb6b,
2280 0x00195475,
2281 0x001b2383,
2282 0x001cad0c,
2283 0x001e7616,
2284 0x0000821f,
2285 0x00020ba8,
2286 0x0003d4b2,
2287 0x00056447,
2288 0x00072dd0,
2289 0x0008b6da,
2290 0x000a02e3,
2291 0x000b8c6c,
2292 0x000d15f6,
2293 0x0011e484,
2294 0x0013ae0d,
2295 0x00153717,
2296 0x00168320,
2297 0x00180ca9,
2298 0x00199633,
2299 0x001b6548,
2300 0x001ceed1,
2301 0x001eb7db,
2302 0x0000c3e4,
2303 0x00024d6d,
2304 0x000416f7,
2305 0x0005a585,
2306 0x00076f0f,
2307 0x0008f818,
2308 0x000a4421,
2309 0x000bcdab,
2310 0x000d9734,
2311 0x00122649,
2312 0x0013efd2,
2313 0x001578dc,
2314 0x0016c4e5,
2315 0x00184e6e,
2316 0x001a17f8,
2317 0x001ba686,
2318 0x001d3010,
2319 0x001ef999,
2320 0x00010522,
2321 0x00028eac,
2322 0x00045835,
2323 0x0005e74a,
2324 0x0007b0d3,
2325 0x00093a5d,
2326 0x000a85e6,
2327 0x000c0f6f,
2328 0x000dd8f9,
2329 0x00126787,
2330 0x00143111,
2331 0x0015ba9a,
2332 0x00170623,
2333 0x00188fad,
2334 0x001a5936,
2335 0x001be84b,
2336 0x001db1d4,
2337 0x001f3b5e,
2338 0x000146e7,
2339 0x00031070,
2340 0x000499fa,
2341 0x00062888,
2342 0x0007f212,
2343 0x00097b9b,
2344 0x000ac7a4,
2345 0x000c50ae,
2346 0x000e1a37,
2347 0x0012a94c,
2348 0x001472d5,
2349 0x0015fc5f,
2350 0x00174868,
2351 0x0018d171,
2352 0x001a9afb,
2353 0x001c2989,
2354 0x001df313,
2355 0x001f7c9c,
2356 0x000188a5,
2357 0x000351af,
2358 0x0004db38,
2359 0x0006aa4d,
2360 0x000833d7,
2361 0x0009bd60,
2362 0x000b0969,
2363 0x000c9273,
2364 0x000e5bfc,
2365 0x00132a8a,
2366 0x0014b414,
2367 0x00163d9d,
2368 0x001789a6,
2369 0x001912b0,
2370 0x001adc39,
2371 0x001c6bce,
2372 0x001e34d8,
2373 0x001fbe61,
2374 0x0001ca6a,
2375 0x00039374,
2376 0x00051cfd,
2377 0x0006ec0b,
2378 0x00087515,
2379 0x0009fe9e,
2380 0x000b4aa7,
2381 0x000cd3b1,
2382 0x000e9d3a,
2383 0x00000000,
2384 0x00000000,
2385};
2386
2387static const u32 tdi_tbl40_ant1_rev0[] = {
2388 0x001edb36,
2389 0x000129ca,
2390 0x0002b353,
2391 0x00047cdd,
2392 0x0005c8e6,
2393 0x000791ef,
2394 0x00091bf9,
2395 0x000aaa07,
2396 0x000c3391,
2397 0x000dfd1a,
2398 0x00120923,
2399 0x0013d22d,
2400 0x00155c37,
2401 0x0016eacb,
2402 0x00187454,
2403 0x001a3dde,
2404 0x001b89e7,
2405 0x001d12f0,
2406 0x001f1cfa,
2407 0x00016b88,
2408 0x00033492,
2409 0x0004be1b,
2410 0x00060a24,
2411 0x0007d32e,
2412 0x00095d38,
2413 0x000aec4c,
2414 0x000c7555,
2415 0x000e3edf,
2416 0x00124ae8,
2417 0x001413f1,
2418 0x0015a37b,
2419 0x00172c89,
2420 0x0018b593,
2421 0x001a419c,
2422 0x001bcb25,
2423 0x001d942f,
2424 0x001f63b9,
2425 0x0001ad4d,
2426 0x00037657,
2427 0x0004c260,
2428 0x00068be9,
2429 0x000814f3,
2430 0x0009a47c,
2431 0x000b2d8a,
2432 0x000cb694,
2433 0x000e429d,
2434 0x00128c26,
2435 0x001455b0,
2436 0x0015e4ba,
2437 0x00176e4e,
2438 0x0018f758,
2439 0x001a8361,
2440 0x001c0cea,
2441 0x001dd674,
2442 0x001fa57d,
2443 0x0001ee8b,
2444 0x0003b795,
2445 0x0005039e,
2446 0x0006cd27,
2447 0x000856b1,
2448 0x0009e5c6,
2449 0x000b6f4f,
2450 0x000cf859,
2451 0x000e8462,
2452 0x00130deb,
2453 0x00149775,
2454 0x00162603,
2455 0x0017af8c,
2456 0x00193896,
2457 0x001ac49f,
2458 0x001c4e28,
2459 0x001e17b2,
2460 0x0000a6c7,
2461 0x00023050,
2462 0x0003f9da,
2463 0x00054563,
2464 0x00070eec,
2465 0x00089876,
2466 0x000a2704,
2467 0x000bb08d,
2468 0x000d3a17,
2469 0x001185a0,
2470 0x00134f29,
2471 0x0014d8b3,
2472 0x001667c8,
2473 0x0017f151,
2474 0x00197adb,
2475 0x001b0664,
2476 0x001c8fed,
2477 0x001e5977,
2478 0x0000e805,
2479 0x0002718f,
2480 0x00043b18,
2481 0x000586a1,
2482 0x0007502b,
2483 0x0008d9b4,
2484 0x000a68c9,
2485 0x000bf252,
2486 0x000dbbdc,
2487 0x0011c7e5,
2488 0x001390ee,
2489 0x00151a78,
2490 0x0016a906,
2491 0x00183290,
2492 0x0019bc19,
2493 0x001b4822,
2494 0x001cd12c,
2495 0x001e9ab5,
2496 0x00000000,
2497 0x00000000,
2498};
2499
2500static const u16 bdi_tbl_rev0[] = {
2501 0x0070,
2502 0x0126,
2503 0x012c,
2504 0x0246,
2505 0x048d,
2506 0x04d2,
2507};
2508
2509static const u32 chanest_tbl_rev0[] = {
2510 0x44444444,
2511 0x44444444,
2512 0x44444444,
2513 0x44444444,
2514 0x44444444,
2515 0x44444444,
2516 0x44444444,
2517 0x44444444,
2518 0x10101010,
2519 0x10101010,
2520 0x10101010,
2521 0x10101010,
2522 0x10101010,
2523 0x10101010,
2524 0x10101010,
2525 0x10101010,
2526 0x44444444,
2527 0x44444444,
2528 0x44444444,
2529 0x44444444,
2530 0x44444444,
2531 0x44444444,
2532 0x44444444,
2533 0x44444444,
2534 0x10101010,
2535 0x10101010,
2536 0x10101010,
2537 0x10101010,
2538 0x10101010,
2539 0x10101010,
2540 0x10101010,
2541 0x10101010,
2542 0x44444444,
2543 0x44444444,
2544 0x44444444,
2545 0x44444444,
2546 0x44444444,
2547 0x44444444,
2548 0x44444444,
2549 0x44444444,
2550 0x44444444,
2551 0x44444444,
2552 0x44444444,
2553 0x44444444,
2554 0x44444444,
2555 0x44444444,
2556 0x44444444,
2557 0x44444444,
2558 0x10101010,
2559 0x10101010,
2560 0x10101010,
2561 0x10101010,
2562 0x10101010,
2563 0x10101010,
2564 0x10101010,
2565 0x10101010,
2566 0x10101010,
2567 0x10101010,
2568 0x10101010,
2569 0x10101010,
2570 0x10101010,
2571 0x10101010,
2572 0x10101010,
2573 0x10101010,
2574 0x44444444,
2575 0x44444444,
2576 0x44444444,
2577 0x44444444,
2578 0x44444444,
2579 0x44444444,
2580 0x44444444,
2581 0x44444444,
2582 0x44444444,
2583 0x44444444,
2584 0x44444444,
2585 0x44444444,
2586 0x44444444,
2587 0x44444444,
2588 0x44444444,
2589 0x44444444,
2590 0x10101010,
2591 0x10101010,
2592 0x10101010,
2593 0x10101010,
2594 0x10101010,
2595 0x10101010,
2596 0x10101010,
2597 0x10101010,
2598 0x10101010,
2599 0x10101010,
2600 0x10101010,
2601 0x10101010,
2602 0x10101010,
2603 0x10101010,
2604 0x10101010,
2605 0x10101010,
2606};
2607
2608static const u8 mcs_tbl_rev0[] = {
2609 0x00,
2610 0x08,
2611 0x0a,
2612 0x10,
2613 0x12,
2614 0x19,
2615 0x1a,
2616 0x1c,
2617 0x40,
2618 0x48,
2619 0x4a,
2620 0x50,
2621 0x52,
2622 0x59,
2623 0x5a,
2624 0x5c,
2625 0x80,
2626 0x88,
2627 0x8a,
2628 0x90,
2629 0x92,
2630 0x99,
2631 0x9a,
2632 0x9c,
2633 0xc0,
2634 0xc8,
2635 0xca,
2636 0xd0,
2637 0xd2,
2638 0xd9,
2639 0xda,
2640 0xdc,
2641 0x00,
2642 0x00,
2643 0x00,
2644 0x00,
2645 0x00,
2646 0x00,
2647 0x00,
2648 0x00,
2649 0x00,
2650 0x00,
2651 0x00,
2652 0x00,
2653 0x00,
2654 0x00,
2655 0x00,
2656 0x00,
2657 0x00,
2658 0x00,
2659 0x00,
2660 0x00,
2661 0x00,
2662 0x00,
2663 0x00,
2664 0x00,
2665 0x00,
2666 0x00,
2667 0x00,
2668 0x00,
2669 0x00,
2670 0x00,
2671 0x00,
2672 0x00,
2673 0x00,
2674 0x01,
2675 0x02,
2676 0x04,
2677 0x08,
2678 0x09,
2679 0x0a,
2680 0x0c,
2681 0x10,
2682 0x11,
2683 0x12,
2684 0x14,
2685 0x18,
2686 0x19,
2687 0x1a,
2688 0x1c,
2689 0x20,
2690 0x21,
2691 0x22,
2692 0x24,
2693 0x40,
2694 0x41,
2695 0x42,
2696 0x44,
2697 0x48,
2698 0x49,
2699 0x4a,
2700 0x4c,
2701 0x50,
2702 0x51,
2703 0x52,
2704 0x54,
2705 0x58,
2706 0x59,
2707 0x5a,
2708 0x5c,
2709 0x60,
2710 0x61,
2711 0x62,
2712 0x64,
2713 0x00,
2714 0x00,
2715 0x00,
2716 0x00,
2717 0x00,
2718 0x00,
2719 0x00,
2720 0x00,
2721 0x00,
2722 0x00,
2723 0x00,
2724 0x00,
2725 0x00,
2726 0x00,
2727 0x00,
2728 0x00,
2729 0x00,
2730 0x00,
2731 0x00,
2732 0x00,
2733 0x00,
2734 0x00,
2735 0x00,
2736 0x00,
2737};
2738
2739static const u32 noise_var_tbl0_rev0[] = {
2740 0x020c020c,
2741 0x0000014d,
2742 0x020c020c,
2743 0x0000014d,
2744 0x020c020c,
2745 0x0000014d,
2746 0x020c020c,
2747 0x0000014d,
2748 0x020c020c,
2749 0x0000014d,
2750 0x020c020c,
2751 0x0000014d,
2752 0x020c020c,
2753 0x0000014d,
2754 0x020c020c,
2755 0x0000014d,
2756 0x020c020c,
2757 0x0000014d,
2758 0x020c020c,
2759 0x0000014d,
2760 0x020c020c,
2761 0x0000014d,
2762 0x020c020c,
2763 0x0000014d,
2764 0x020c020c,
2765 0x0000014d,
2766 0x020c020c,
2767 0x0000014d,
2768 0x020c020c,
2769 0x0000014d,
2770 0x020c020c,
2771 0x0000014d,
2772 0x020c020c,
2773 0x0000014d,
2774 0x020c020c,
2775 0x0000014d,
2776 0x020c020c,
2777 0x0000014d,
2778 0x020c020c,
2779 0x0000014d,
2780 0x020c020c,
2781 0x0000014d,
2782 0x020c020c,
2783 0x0000014d,
2784 0x020c020c,
2785 0x0000014d,
2786 0x020c020c,
2787 0x0000014d,
2788 0x020c020c,
2789 0x0000014d,
2790 0x020c020c,
2791 0x0000014d,
2792 0x020c020c,
2793 0x0000014d,
2794 0x020c020c,
2795 0x0000014d,
2796 0x020c020c,
2797 0x0000014d,
2798 0x020c020c,
2799 0x0000014d,
2800 0x020c020c,
2801 0x0000014d,
2802 0x020c020c,
2803 0x0000014d,
2804 0x020c020c,
2805 0x0000014d,
2806 0x020c020c,
2807 0x0000014d,
2808 0x020c020c,
2809 0x0000014d,
2810 0x020c020c,
2811 0x0000014d,
2812 0x020c020c,
2813 0x0000014d,
2814 0x020c020c,
2815 0x0000014d,
2816 0x020c020c,
2817 0x0000014d,
2818 0x020c020c,
2819 0x0000014d,
2820 0x020c020c,
2821 0x0000014d,
2822 0x020c020c,
2823 0x0000014d,
2824 0x020c020c,
2825 0x0000014d,
2826 0x020c020c,
2827 0x0000014d,
2828 0x020c020c,
2829 0x0000014d,
2830 0x020c020c,
2831 0x0000014d,
2832 0x020c020c,
2833 0x0000014d,
2834 0x020c020c,
2835 0x0000014d,
2836 0x020c020c,
2837 0x0000014d,
2838 0x020c020c,
2839 0x0000014d,
2840 0x020c020c,
2841 0x0000014d,
2842 0x020c020c,
2843 0x0000014d,
2844 0x020c020c,
2845 0x0000014d,
2846 0x020c020c,
2847 0x0000014d,
2848 0x020c020c,
2849 0x0000014d,
2850 0x020c020c,
2851 0x0000014d,
2852 0x020c020c,
2853 0x0000014d,
2854 0x020c020c,
2855 0x0000014d,
2856 0x020c020c,
2857 0x0000014d,
2858 0x020c020c,
2859 0x0000014d,
2860 0x020c020c,
2861 0x0000014d,
2862 0x020c020c,
2863 0x0000014d,
2864 0x020c020c,
2865 0x0000014d,
2866 0x020c020c,
2867 0x0000014d,
2868 0x020c020c,
2869 0x0000014d,
2870 0x020c020c,
2871 0x0000014d,
2872 0x020c020c,
2873 0x0000014d,
2874 0x020c020c,
2875 0x0000014d,
2876 0x020c020c,
2877 0x0000014d,
2878 0x020c020c,
2879 0x0000014d,
2880 0x020c020c,
2881 0x0000014d,
2882 0x020c020c,
2883 0x0000014d,
2884 0x020c020c,
2885 0x0000014d,
2886 0x020c020c,
2887 0x0000014d,
2888 0x020c020c,
2889 0x0000014d,
2890 0x020c020c,
2891 0x0000014d,
2892 0x020c020c,
2893 0x0000014d,
2894 0x020c020c,
2895 0x0000014d,
2896 0x020c020c,
2897 0x0000014d,
2898 0x020c020c,
2899 0x0000014d,
2900 0x020c020c,
2901 0x0000014d,
2902 0x020c020c,
2903 0x0000014d,
2904 0x020c020c,
2905 0x0000014d,
2906 0x020c020c,
2907 0x0000014d,
2908 0x020c020c,
2909 0x0000014d,
2910 0x020c020c,
2911 0x0000014d,
2912 0x020c020c,
2913 0x0000014d,
2914 0x020c020c,
2915 0x0000014d,
2916 0x020c020c,
2917 0x0000014d,
2918 0x020c020c,
2919 0x0000014d,
2920 0x020c020c,
2921 0x0000014d,
2922 0x020c020c,
2923 0x0000014d,
2924 0x020c020c,
2925 0x0000014d,
2926 0x020c020c,
2927 0x0000014d,
2928 0x020c020c,
2929 0x0000014d,
2930 0x020c020c,
2931 0x0000014d,
2932 0x020c020c,
2933 0x0000014d,
2934 0x020c020c,
2935 0x0000014d,
2936 0x020c020c,
2937 0x0000014d,
2938 0x020c020c,
2939 0x0000014d,
2940 0x020c020c,
2941 0x0000014d,
2942 0x020c020c,
2943 0x0000014d,
2944 0x020c020c,
2945 0x0000014d,
2946 0x020c020c,
2947 0x0000014d,
2948 0x020c020c,
2949 0x0000014d,
2950 0x020c020c,
2951 0x0000014d,
2952 0x020c020c,
2953 0x0000014d,
2954 0x020c020c,
2955 0x0000014d,
2956 0x020c020c,
2957 0x0000014d,
2958 0x020c020c,
2959 0x0000014d,
2960 0x020c020c,
2961 0x0000014d,
2962 0x020c020c,
2963 0x0000014d,
2964 0x020c020c,
2965 0x0000014d,
2966 0x020c020c,
2967 0x0000014d,
2968 0x020c020c,
2969 0x0000014d,
2970 0x020c020c,
2971 0x0000014d,
2972 0x020c020c,
2973 0x0000014d,
2974 0x020c020c,
2975 0x0000014d,
2976 0x020c020c,
2977 0x0000014d,
2978 0x020c020c,
2979 0x0000014d,
2980 0x020c020c,
2981 0x0000014d,
2982 0x020c020c,
2983 0x0000014d,
2984 0x020c020c,
2985 0x0000014d,
2986 0x020c020c,
2987 0x0000014d,
2988 0x020c020c,
2989 0x0000014d,
2990 0x020c020c,
2991 0x0000014d,
2992 0x020c020c,
2993 0x0000014d,
2994 0x020c020c,
2995 0x0000014d,
2996};
2997
2998static const u32 noise_var_tbl1_rev0[] = {
2999 0x020c020c,
3000 0x0000014d,
3001 0x020c020c,
3002 0x0000014d,
3003 0x020c020c,
3004 0x0000014d,
3005 0x020c020c,
3006 0x0000014d,
3007 0x020c020c,
3008 0x0000014d,
3009 0x020c020c,
3010 0x0000014d,
3011 0x020c020c,
3012 0x0000014d,
3013 0x020c020c,
3014 0x0000014d,
3015 0x020c020c,
3016 0x0000014d,
3017 0x020c020c,
3018 0x0000014d,
3019 0x020c020c,
3020 0x0000014d,
3021 0x020c020c,
3022 0x0000014d,
3023 0x020c020c,
3024 0x0000014d,
3025 0x020c020c,
3026 0x0000014d,
3027 0x020c020c,
3028 0x0000014d,
3029 0x020c020c,
3030 0x0000014d,
3031 0x020c020c,
3032 0x0000014d,
3033 0x020c020c,
3034 0x0000014d,
3035 0x020c020c,
3036 0x0000014d,
3037 0x020c020c,
3038 0x0000014d,
3039 0x020c020c,
3040 0x0000014d,
3041 0x020c020c,
3042 0x0000014d,
3043 0x020c020c,
3044 0x0000014d,
3045 0x020c020c,
3046 0x0000014d,
3047 0x020c020c,
3048 0x0000014d,
3049 0x020c020c,
3050 0x0000014d,
3051 0x020c020c,
3052 0x0000014d,
3053 0x020c020c,
3054 0x0000014d,
3055 0x020c020c,
3056 0x0000014d,
3057 0x020c020c,
3058 0x0000014d,
3059 0x020c020c,
3060 0x0000014d,
3061 0x020c020c,
3062 0x0000014d,
3063 0x020c020c,
3064 0x0000014d,
3065 0x020c020c,
3066 0x0000014d,
3067 0x020c020c,
3068 0x0000014d,
3069 0x020c020c,
3070 0x0000014d,
3071 0x020c020c,
3072 0x0000014d,
3073 0x020c020c,
3074 0x0000014d,
3075 0x020c020c,
3076 0x0000014d,
3077 0x020c020c,
3078 0x0000014d,
3079 0x020c020c,
3080 0x0000014d,
3081 0x020c020c,
3082 0x0000014d,
3083 0x020c020c,
3084 0x0000014d,
3085 0x020c020c,
3086 0x0000014d,
3087 0x020c020c,
3088 0x0000014d,
3089 0x020c020c,
3090 0x0000014d,
3091 0x020c020c,
3092 0x0000014d,
3093 0x020c020c,
3094 0x0000014d,
3095 0x020c020c,
3096 0x0000014d,
3097 0x020c020c,
3098 0x0000014d,
3099 0x020c020c,
3100 0x0000014d,
3101 0x020c020c,
3102 0x0000014d,
3103 0x020c020c,
3104 0x0000014d,
3105 0x020c020c,
3106 0x0000014d,
3107 0x020c020c,
3108 0x0000014d,
3109 0x020c020c,
3110 0x0000014d,
3111 0x020c020c,
3112 0x0000014d,
3113 0x020c020c,
3114 0x0000014d,
3115 0x020c020c,
3116 0x0000014d,
3117 0x020c020c,
3118 0x0000014d,
3119 0x020c020c,
3120 0x0000014d,
3121 0x020c020c,
3122 0x0000014d,
3123 0x020c020c,
3124 0x0000014d,
3125 0x020c020c,
3126 0x0000014d,
3127 0x020c020c,
3128 0x0000014d,
3129 0x020c020c,
3130 0x0000014d,
3131 0x020c020c,
3132 0x0000014d,
3133 0x020c020c,
3134 0x0000014d,
3135 0x020c020c,
3136 0x0000014d,
3137 0x020c020c,
3138 0x0000014d,
3139 0x020c020c,
3140 0x0000014d,
3141 0x020c020c,
3142 0x0000014d,
3143 0x020c020c,
3144 0x0000014d,
3145 0x020c020c,
3146 0x0000014d,
3147 0x020c020c,
3148 0x0000014d,
3149 0x020c020c,
3150 0x0000014d,
3151 0x020c020c,
3152 0x0000014d,
3153 0x020c020c,
3154 0x0000014d,
3155 0x020c020c,
3156 0x0000014d,
3157 0x020c020c,
3158 0x0000014d,
3159 0x020c020c,
3160 0x0000014d,
3161 0x020c020c,
3162 0x0000014d,
3163 0x020c020c,
3164 0x0000014d,
3165 0x020c020c,
3166 0x0000014d,
3167 0x020c020c,
3168 0x0000014d,
3169 0x020c020c,
3170 0x0000014d,
3171 0x020c020c,
3172 0x0000014d,
3173 0x020c020c,
3174 0x0000014d,
3175 0x020c020c,
3176 0x0000014d,
3177 0x020c020c,
3178 0x0000014d,
3179 0x020c020c,
3180 0x0000014d,
3181 0x020c020c,
3182 0x0000014d,
3183 0x020c020c,
3184 0x0000014d,
3185 0x020c020c,
3186 0x0000014d,
3187 0x020c020c,
3188 0x0000014d,
3189 0x020c020c,
3190 0x0000014d,
3191 0x020c020c,
3192 0x0000014d,
3193 0x020c020c,
3194 0x0000014d,
3195 0x020c020c,
3196 0x0000014d,
3197 0x020c020c,
3198 0x0000014d,
3199 0x020c020c,
3200 0x0000014d,
3201 0x020c020c,
3202 0x0000014d,
3203 0x020c020c,
3204 0x0000014d,
3205 0x020c020c,
3206 0x0000014d,
3207 0x020c020c,
3208 0x0000014d,
3209 0x020c020c,
3210 0x0000014d,
3211 0x020c020c,
3212 0x0000014d,
3213 0x020c020c,
3214 0x0000014d,
3215 0x020c020c,
3216 0x0000014d,
3217 0x020c020c,
3218 0x0000014d,
3219 0x020c020c,
3220 0x0000014d,
3221 0x020c020c,
3222 0x0000014d,
3223 0x020c020c,
3224 0x0000014d,
3225 0x020c020c,
3226 0x0000014d,
3227 0x020c020c,
3228 0x0000014d,
3229 0x020c020c,
3230 0x0000014d,
3231 0x020c020c,
3232 0x0000014d,
3233 0x020c020c,
3234 0x0000014d,
3235 0x020c020c,
3236 0x0000014d,
3237 0x020c020c,
3238 0x0000014d,
3239 0x020c020c,
3240 0x0000014d,
3241 0x020c020c,
3242 0x0000014d,
3243 0x020c020c,
3244 0x0000014d,
3245 0x020c020c,
3246 0x0000014d,
3247 0x020c020c,
3248 0x0000014d,
3249 0x020c020c,
3250 0x0000014d,
3251 0x020c020c,
3252 0x0000014d,
3253 0x020c020c,
3254 0x0000014d,
3255};
3256
3257static const u8 est_pwr_lut_core0_rev0[] = {
3258 0x50,
3259 0x4f,
3260 0x4e,
3261 0x4d,
3262 0x4c,
3263 0x4b,
3264 0x4a,
3265 0x49,
3266 0x48,
3267 0x47,
3268 0x46,
3269 0x45,
3270 0x44,
3271 0x43,
3272 0x42,
3273 0x41,
3274 0x40,
3275 0x3f,
3276 0x3e,
3277 0x3d,
3278 0x3c,
3279 0x3b,
3280 0x3a,
3281 0x39,
3282 0x38,
3283 0x37,
3284 0x36,
3285 0x35,
3286 0x34,
3287 0x33,
3288 0x32,
3289 0x31,
3290 0x30,
3291 0x2f,
3292 0x2e,
3293 0x2d,
3294 0x2c,
3295 0x2b,
3296 0x2a,
3297 0x29,
3298 0x28,
3299 0x27,
3300 0x26,
3301 0x25,
3302 0x24,
3303 0x23,
3304 0x22,
3305 0x21,
3306 0x20,
3307 0x1f,
3308 0x1e,
3309 0x1d,
3310 0x1c,
3311 0x1b,
3312 0x1a,
3313 0x19,
3314 0x18,
3315 0x17,
3316 0x16,
3317 0x15,
3318 0x14,
3319 0x13,
3320 0x12,
3321 0x11,
3322};
3323
3324static const u8 est_pwr_lut_core1_rev0[] = {
3325 0x50,
3326 0x4f,
3327 0x4e,
3328 0x4d,
3329 0x4c,
3330 0x4b,
3331 0x4a,
3332 0x49,
3333 0x48,
3334 0x47,
3335 0x46,
3336 0x45,
3337 0x44,
3338 0x43,
3339 0x42,
3340 0x41,
3341 0x40,
3342 0x3f,
3343 0x3e,
3344 0x3d,
3345 0x3c,
3346 0x3b,
3347 0x3a,
3348 0x39,
3349 0x38,
3350 0x37,
3351 0x36,
3352 0x35,
3353 0x34,
3354 0x33,
3355 0x32,
3356 0x31,
3357 0x30,
3358 0x2f,
3359 0x2e,
3360 0x2d,
3361 0x2c,
3362 0x2b,
3363 0x2a,
3364 0x29,
3365 0x28,
3366 0x27,
3367 0x26,
3368 0x25,
3369 0x24,
3370 0x23,
3371 0x22,
3372 0x21,
3373 0x20,
3374 0x1f,
3375 0x1e,
3376 0x1d,
3377 0x1c,
3378 0x1b,
3379 0x1a,
3380 0x19,
3381 0x18,
3382 0x17,
3383 0x16,
3384 0x15,
3385 0x14,
3386 0x13,
3387 0x12,
3388 0x11,
3389};
3390
3391static const u8 adj_pwr_lut_core0_rev0[] = {
3392 0x00,
3393 0x00,
3394 0x00,
3395 0x00,
3396 0x00,
3397 0x00,
3398 0x00,
3399 0x00,
3400 0x00,
3401 0x00,
3402 0x00,
3403 0x00,
3404 0x00,
3405 0x00,
3406 0x00,
3407 0x00,
3408 0x00,
3409 0x00,
3410 0x00,
3411 0x00,
3412 0x00,
3413 0x00,
3414 0x00,
3415 0x00,
3416 0x00,
3417 0x00,
3418 0x00,
3419 0x00,
3420 0x00,
3421 0x00,
3422 0x00,
3423 0x00,
3424 0x00,
3425 0x00,
3426 0x00,
3427 0x00,
3428 0x00,
3429 0x00,
3430 0x00,
3431 0x00,
3432 0x00,
3433 0x00,
3434 0x00,
3435 0x00,
3436 0x00,
3437 0x00,
3438 0x00,
3439 0x00,
3440 0x00,
3441 0x00,
3442 0x00,
3443 0x00,
3444 0x00,
3445 0x00,
3446 0x00,
3447 0x00,
3448 0x00,
3449 0x00,
3450 0x00,
3451 0x00,
3452 0x00,
3453 0x00,
3454 0x00,
3455 0x00,
3456 0x00,
3457 0x00,
3458 0x00,
3459 0x00,
3460 0x00,
3461 0x00,
3462 0x00,
3463 0x00,
3464 0x00,
3465 0x00,
3466 0x00,
3467 0x00,
3468 0x00,
3469 0x00,
3470 0x00,
3471 0x00,
3472 0x00,
3473 0x00,
3474 0x00,
3475 0x00,
3476 0x00,
3477 0x00,
3478 0x00,
3479 0x00,
3480 0x00,
3481 0x00,
3482 0x00,
3483 0x00,
3484 0x00,
3485 0x00,
3486 0x00,
3487 0x00,
3488 0x00,
3489 0x00,
3490 0x00,
3491 0x00,
3492 0x00,
3493 0x00,
3494 0x00,
3495 0x00,
3496 0x00,
3497 0x00,
3498 0x00,
3499 0x00,
3500 0x00,
3501 0x00,
3502 0x00,
3503 0x00,
3504 0x00,
3505 0x00,
3506 0x00,
3507 0x00,
3508 0x00,
3509 0x00,
3510 0x00,
3511 0x00,
3512 0x00,
3513 0x00,
3514 0x00,
3515 0x00,
3516 0x00,
3517 0x00,
3518 0x00,
3519 0x00,
3520};
3521
3522static const u8 adj_pwr_lut_core1_rev0[] = {
3523 0x00,
3524 0x00,
3525 0x00,
3526 0x00,
3527 0x00,
3528 0x00,
3529 0x00,
3530 0x00,
3531 0x00,
3532 0x00,
3533 0x00,
3534 0x00,
3535 0x00,
3536 0x00,
3537 0x00,
3538 0x00,
3539 0x00,
3540 0x00,
3541 0x00,
3542 0x00,
3543 0x00,
3544 0x00,
3545 0x00,
3546 0x00,
3547 0x00,
3548 0x00,
3549 0x00,
3550 0x00,
3551 0x00,
3552 0x00,
3553 0x00,
3554 0x00,
3555 0x00,
3556 0x00,
3557 0x00,
3558 0x00,
3559 0x00,
3560 0x00,
3561 0x00,
3562 0x00,
3563 0x00,
3564 0x00,
3565 0x00,
3566 0x00,
3567 0x00,
3568 0x00,
3569 0x00,
3570 0x00,
3571 0x00,
3572 0x00,
3573 0x00,
3574 0x00,
3575 0x00,
3576 0x00,
3577 0x00,
3578 0x00,
3579 0x00,
3580 0x00,
3581 0x00,
3582 0x00,
3583 0x00,
3584 0x00,
3585 0x00,
3586 0x00,
3587 0x00,
3588 0x00,
3589 0x00,
3590 0x00,
3591 0x00,
3592 0x00,
3593 0x00,
3594 0x00,
3595 0x00,
3596 0x00,
3597 0x00,
3598 0x00,
3599 0x00,
3600 0x00,
3601 0x00,
3602 0x00,
3603 0x00,
3604 0x00,
3605 0x00,
3606 0x00,
3607 0x00,
3608 0x00,
3609 0x00,
3610 0x00,
3611 0x00,
3612 0x00,
3613 0x00,
3614 0x00,
3615 0x00,
3616 0x00,
3617 0x00,
3618 0x00,
3619 0x00,
3620 0x00,
3621 0x00,
3622 0x00,
3623 0x00,
3624 0x00,
3625 0x00,
3626 0x00,
3627 0x00,
3628 0x00,
3629 0x00,
3630 0x00,
3631 0x00,
3632 0x00,
3633 0x00,
3634 0x00,
3635 0x00,
3636 0x00,
3637 0x00,
3638 0x00,
3639 0x00,
3640 0x00,
3641 0x00,
3642 0x00,
3643 0x00,
3644 0x00,
3645 0x00,
3646 0x00,
3647 0x00,
3648 0x00,
3649 0x00,
3650 0x00,
3651};
3652
3653static const u32 gainctrl_lut_core0_rev0[] = {
3654 0x03cc2b44,
3655 0x03cc2b42,
3656 0x03cc2b40,
3657 0x03cc2b3e,
3658 0x03cc2b3d,
3659 0x03cc2b3b,
3660 0x03c82b44,
3661 0x03c82b42,
3662 0x03c82b40,
3663 0x03c82b3e,
3664 0x03c82b3d,
3665 0x03c82b3b,
3666 0x03c82b39,
3667 0x03c82b38,
3668 0x03c82b36,
3669 0x03c82b34,
3670 0x03c42b44,
3671 0x03c42b42,
3672 0x03c42b40,
3673 0x03c42b3e,
3674 0x03c42b3d,
3675 0x03c42b3b,
3676 0x03c42b39,
3677 0x03c42b38,
3678 0x03c42b36,
3679 0x03c42b34,
3680 0x03c42b33,
3681 0x03c42b32,
3682 0x03c42b30,
3683 0x03c42b2f,
3684 0x03c42b2d,
3685 0x03c02b44,
3686 0x03c02b42,
3687 0x03c02b40,
3688 0x03c02b3e,
3689 0x03c02b3d,
3690 0x03c02b3b,
3691 0x03c02b39,
3692 0x03c02b38,
3693 0x03c02b36,
3694 0x03c02b34,
3695 0x03b02b44,
3696 0x03b02b42,
3697 0x03b02b40,
3698 0x03b02b3e,
3699 0x03b02b3d,
3700 0x03b02b3b,
3701 0x03b02b39,
3702 0x03b02b38,
3703 0x03b02b36,
3704 0x03b02b34,
3705 0x03b02b33,
3706 0x03b02b32,
3707 0x03b02b30,
3708 0x03b02b2f,
3709 0x03b02b2d,
3710 0x03a02b44,
3711 0x03a02b42,
3712 0x03a02b40,
3713 0x03a02b3e,
3714 0x03a02b3d,
3715 0x03a02b3b,
3716 0x03a02b39,
3717 0x03a02b38,
3718 0x03a02b36,
3719 0x03a02b34,
3720 0x03902b44,
3721 0x03902b42,
3722 0x03902b40,
3723 0x03902b3e,
3724 0x03902b3d,
3725 0x03902b3b,
3726 0x03902b39,
3727 0x03902b38,
3728 0x03902b36,
3729 0x03902b34,
3730 0x03902b33,
3731 0x03902b32,
3732 0x03902b30,
3733 0x03802b44,
3734 0x03802b42,
3735 0x03802b40,
3736 0x03802b3e,
3737 0x03802b3d,
3738 0x03802b3b,
3739 0x03802b39,
3740 0x03802b38,
3741 0x03802b36,
3742 0x03802b34,
3743 0x03802b33,
3744 0x03802b32,
3745 0x03802b30,
3746 0x03802b2f,
3747 0x03802b2d,
3748 0x03802b2c,
3749 0x03802b2b,
3750 0x03802b2a,
3751 0x03802b29,
3752 0x03802b27,
3753 0x03802b26,
3754 0x03802b25,
3755 0x03802b24,
3756 0x03802b23,
3757 0x03802b22,
3758 0x03802b21,
3759 0x03802b20,
3760 0x03802b1f,
3761 0x03802b1e,
3762 0x03802b1e,
3763 0x03802b1d,
3764 0x03802b1c,
3765 0x03802b1b,
3766 0x03802b1a,
3767 0x03802b1a,
3768 0x03802b19,
3769 0x03802b18,
3770 0x03802b18,
3771 0x03802b18,
3772 0x03802b18,
3773 0x03802b18,
3774 0x03802b18,
3775 0x03802b18,
3776 0x03802b18,
3777 0x03802b18,
3778 0x03802b18,
3779 0x03802b18,
3780 0x03802b18,
3781 0x00002b00,
3782};
3783
3784static const u32 gainctrl_lut_core1_rev0[] = {
3785 0x03cc2b44,
3786 0x03cc2b42,
3787 0x03cc2b40,
3788 0x03cc2b3e,
3789 0x03cc2b3d,
3790 0x03cc2b3b,
3791 0x03c82b44,
3792 0x03c82b42,
3793 0x03c82b40,
3794 0x03c82b3e,
3795 0x03c82b3d,
3796 0x03c82b3b,
3797 0x03c82b39,
3798 0x03c82b38,
3799 0x03c82b36,
3800 0x03c82b34,
3801 0x03c42b44,
3802 0x03c42b42,
3803 0x03c42b40,
3804 0x03c42b3e,
3805 0x03c42b3d,
3806 0x03c42b3b,
3807 0x03c42b39,
3808 0x03c42b38,
3809 0x03c42b36,
3810 0x03c42b34,
3811 0x03c42b33,
3812 0x03c42b32,
3813 0x03c42b30,
3814 0x03c42b2f,
3815 0x03c42b2d,
3816 0x03c02b44,
3817 0x03c02b42,
3818 0x03c02b40,
3819 0x03c02b3e,
3820 0x03c02b3d,
3821 0x03c02b3b,
3822 0x03c02b39,
3823 0x03c02b38,
3824 0x03c02b36,
3825 0x03c02b34,
3826 0x03b02b44,
3827 0x03b02b42,
3828 0x03b02b40,
3829 0x03b02b3e,
3830 0x03b02b3d,
3831 0x03b02b3b,
3832 0x03b02b39,
3833 0x03b02b38,
3834 0x03b02b36,
3835 0x03b02b34,
3836 0x03b02b33,
3837 0x03b02b32,
3838 0x03b02b30,
3839 0x03b02b2f,
3840 0x03b02b2d,
3841 0x03a02b44,
3842 0x03a02b42,
3843 0x03a02b40,
3844 0x03a02b3e,
3845 0x03a02b3d,
3846 0x03a02b3b,
3847 0x03a02b39,
3848 0x03a02b38,
3849 0x03a02b36,
3850 0x03a02b34,
3851 0x03902b44,
3852 0x03902b42,
3853 0x03902b40,
3854 0x03902b3e,
3855 0x03902b3d,
3856 0x03902b3b,
3857 0x03902b39,
3858 0x03902b38,
3859 0x03902b36,
3860 0x03902b34,
3861 0x03902b33,
3862 0x03902b32,
3863 0x03902b30,
3864 0x03802b44,
3865 0x03802b42,
3866 0x03802b40,
3867 0x03802b3e,
3868 0x03802b3d,
3869 0x03802b3b,
3870 0x03802b39,
3871 0x03802b38,
3872 0x03802b36,
3873 0x03802b34,
3874 0x03802b33,
3875 0x03802b32,
3876 0x03802b30,
3877 0x03802b2f,
3878 0x03802b2d,
3879 0x03802b2c,
3880 0x03802b2b,
3881 0x03802b2a,
3882 0x03802b29,
3883 0x03802b27,
3884 0x03802b26,
3885 0x03802b25,
3886 0x03802b24,
3887 0x03802b23,
3888 0x03802b22,
3889 0x03802b21,
3890 0x03802b20,
3891 0x03802b1f,
3892 0x03802b1e,
3893 0x03802b1e,
3894 0x03802b1d,
3895 0x03802b1c,
3896 0x03802b1b,
3897 0x03802b1a,
3898 0x03802b1a,
3899 0x03802b19,
3900 0x03802b18,
3901 0x03802b18,
3902 0x03802b18,
3903 0x03802b18,
3904 0x03802b18,
3905 0x03802b18,
3906 0x03802b18,
3907 0x03802b18,
3908 0x03802b18,
3909 0x03802b18,
3910 0x03802b18,
3911 0x03802b18,
3912 0x00002b00,
3913};
3914
3915static const u32 iq_lut_core0_rev0[] = {
3916 0x0000007f,
3917 0x0000007f,
3918 0x0000007f,
3919 0x0000007f,
3920 0x0000007f,
3921 0x0000007f,
3922 0x0000007f,
3923 0x0000007f,
3924 0x0000007f,
3925 0x0000007f,
3926 0x0000007f,
3927 0x0000007f,
3928 0x0000007f,
3929 0x0000007f,
3930 0x0000007f,
3931 0x0000007f,
3932 0x0000007f,
3933 0x0000007f,
3934 0x0000007f,
3935 0x0000007f,
3936 0x0000007f,
3937 0x0000007f,
3938 0x0000007f,
3939 0x0000007f,
3940 0x0000007f,
3941 0x0000007f,
3942 0x0000007f,
3943 0x0000007f,
3944 0x0000007f,
3945 0x0000007f,
3946 0x0000007f,
3947 0x0000007f,
3948 0x0000007f,
3949 0x0000007f,
3950 0x0000007f,
3951 0x0000007f,
3952 0x0000007f,
3953 0x0000007f,
3954 0x0000007f,
3955 0x0000007f,
3956 0x0000007f,
3957 0x0000007f,
3958 0x0000007f,
3959 0x0000007f,
3960 0x0000007f,
3961 0x0000007f,
3962 0x0000007f,
3963 0x0000007f,
3964 0x0000007f,
3965 0x0000007f,
3966 0x0000007f,
3967 0x0000007f,
3968 0x0000007f,
3969 0x0000007f,
3970 0x0000007f,
3971 0x0000007f,
3972 0x0000007f,
3973 0x0000007f,
3974 0x0000007f,
3975 0x0000007f,
3976 0x0000007f,
3977 0x0000007f,
3978 0x0000007f,
3979 0x0000007f,
3980 0x0000007f,
3981 0x0000007f,
3982 0x0000007f,
3983 0x0000007f,
3984 0x0000007f,
3985 0x0000007f,
3986 0x0000007f,
3987 0x0000007f,
3988 0x0000007f,
3989 0x0000007f,
3990 0x0000007f,
3991 0x0000007f,
3992 0x0000007f,
3993 0x0000007f,
3994 0x0000007f,
3995 0x0000007f,
3996 0x0000007f,
3997 0x0000007f,
3998 0x0000007f,
3999 0x0000007f,
4000 0x0000007f,
4001 0x0000007f,
4002 0x0000007f,
4003 0x0000007f,
4004 0x0000007f,
4005 0x0000007f,
4006 0x0000007f,
4007 0x0000007f,
4008 0x0000007f,
4009 0x0000007f,
4010 0x0000007f,
4011 0x0000007f,
4012 0x0000007f,
4013 0x0000007f,
4014 0x0000007f,
4015 0x0000007f,
4016 0x0000007f,
4017 0x0000007f,
4018 0x0000007f,
4019 0x0000007f,
4020 0x0000007f,
4021 0x0000007f,
4022 0x0000007f,
4023 0x0000007f,
4024 0x0000007f,
4025 0x0000007f,
4026 0x0000007f,
4027 0x0000007f,
4028 0x0000007f,
4029 0x0000007f,
4030 0x0000007f,
4031 0x0000007f,
4032 0x0000007f,
4033 0x0000007f,
4034 0x0000007f,
4035 0x0000007f,
4036 0x0000007f,
4037 0x0000007f,
4038 0x0000007f,
4039 0x0000007f,
4040 0x0000007f,
4041 0x0000007f,
4042 0x0000007f,
4043 0x0000007f,
4044};
4045
4046static const u32 iq_lut_core1_rev0[] = {
4047 0x0000007f,
4048 0x0000007f,
4049 0x0000007f,
4050 0x0000007f,
4051 0x0000007f,
4052 0x0000007f,
4053 0x0000007f,
4054 0x0000007f,
4055 0x0000007f,
4056 0x0000007f,
4057 0x0000007f,
4058 0x0000007f,
4059 0x0000007f,
4060 0x0000007f,
4061 0x0000007f,
4062 0x0000007f,
4063 0x0000007f,
4064 0x0000007f,
4065 0x0000007f,
4066 0x0000007f,
4067 0x0000007f,
4068 0x0000007f,
4069 0x0000007f,
4070 0x0000007f,
4071 0x0000007f,
4072 0x0000007f,
4073 0x0000007f,
4074 0x0000007f,
4075 0x0000007f,
4076 0x0000007f,
4077 0x0000007f,
4078 0x0000007f,
4079 0x0000007f,
4080 0x0000007f,
4081 0x0000007f,
4082 0x0000007f,
4083 0x0000007f,
4084 0x0000007f,
4085 0x0000007f,
4086 0x0000007f,
4087 0x0000007f,
4088 0x0000007f,
4089 0x0000007f,
4090 0x0000007f,
4091 0x0000007f,
4092 0x0000007f,
4093 0x0000007f,
4094 0x0000007f,
4095 0x0000007f,
4096 0x0000007f,
4097 0x0000007f,
4098 0x0000007f,
4099 0x0000007f,
4100 0x0000007f,
4101 0x0000007f,
4102 0x0000007f,
4103 0x0000007f,
4104 0x0000007f,
4105 0x0000007f,
4106 0x0000007f,
4107 0x0000007f,
4108 0x0000007f,
4109 0x0000007f,
4110 0x0000007f,
4111 0x0000007f,
4112 0x0000007f,
4113 0x0000007f,
4114 0x0000007f,
4115 0x0000007f,
4116 0x0000007f,
4117 0x0000007f,
4118 0x0000007f,
4119 0x0000007f,
4120 0x0000007f,
4121 0x0000007f,
4122 0x0000007f,
4123 0x0000007f,
4124 0x0000007f,
4125 0x0000007f,
4126 0x0000007f,
4127 0x0000007f,
4128 0x0000007f,
4129 0x0000007f,
4130 0x0000007f,
4131 0x0000007f,
4132 0x0000007f,
4133 0x0000007f,
4134 0x0000007f,
4135 0x0000007f,
4136 0x0000007f,
4137 0x0000007f,
4138 0x0000007f,
4139 0x0000007f,
4140 0x0000007f,
4141 0x0000007f,
4142 0x0000007f,
4143 0x0000007f,
4144 0x0000007f,
4145 0x0000007f,
4146 0x0000007f,
4147 0x0000007f,
4148 0x0000007f,
4149 0x0000007f,
4150 0x0000007f,
4151 0x0000007f,
4152 0x0000007f,
4153 0x0000007f,
4154 0x0000007f,
4155 0x0000007f,
4156 0x0000007f,
4157 0x0000007f,
4158 0x0000007f,
4159 0x0000007f,
4160 0x0000007f,
4161 0x0000007f,
4162 0x0000007f,
4163 0x0000007f,
4164 0x0000007f,
4165 0x0000007f,
4166 0x0000007f,
4167 0x0000007f,
4168 0x0000007f,
4169 0x0000007f,
4170 0x0000007f,
4171 0x0000007f,
4172 0x0000007f,
4173 0x0000007f,
4174 0x0000007f,
4175};
4176
4177static const u16 loft_lut_core0_rev0[] = {
4178 0x0000,
4179 0x0101,
4180 0x0002,
4181 0x0103,
4182 0x0000,
4183 0x0101,
4184 0x0002,
4185 0x0103,
4186 0x0000,
4187 0x0101,
4188 0x0002,
4189 0x0103,
4190 0x0000,
4191 0x0101,
4192 0x0002,
4193 0x0103,
4194 0x0000,
4195 0x0101,
4196 0x0002,
4197 0x0103,
4198 0x0000,
4199 0x0101,
4200 0x0002,
4201 0x0103,
4202 0x0000,
4203 0x0101,
4204 0x0002,
4205 0x0103,
4206 0x0000,
4207 0x0101,
4208 0x0002,
4209 0x0103,
4210 0x0000,
4211 0x0101,
4212 0x0002,
4213 0x0103,
4214 0x0000,
4215 0x0101,
4216 0x0002,
4217 0x0103,
4218 0x0000,
4219 0x0101,
4220 0x0002,
4221 0x0103,
4222 0x0000,
4223 0x0101,
4224 0x0002,
4225 0x0103,
4226 0x0000,
4227 0x0101,
4228 0x0002,
4229 0x0103,
4230 0x0000,
4231 0x0101,
4232 0x0002,
4233 0x0103,
4234 0x0000,
4235 0x0101,
4236 0x0002,
4237 0x0103,
4238 0x0000,
4239 0x0101,
4240 0x0002,
4241 0x0103,
4242 0x0000,
4243 0x0101,
4244 0x0002,
4245 0x0103,
4246 0x0000,
4247 0x0101,
4248 0x0002,
4249 0x0103,
4250 0x0000,
4251 0x0101,
4252 0x0002,
4253 0x0103,
4254 0x0000,
4255 0x0101,
4256 0x0002,
4257 0x0103,
4258 0x0000,
4259 0x0101,
4260 0x0002,
4261 0x0103,
4262 0x0000,
4263 0x0101,
4264 0x0002,
4265 0x0103,
4266 0x0000,
4267 0x0101,
4268 0x0002,
4269 0x0103,
4270 0x0000,
4271 0x0101,
4272 0x0002,
4273 0x0103,
4274 0x0000,
4275 0x0101,
4276 0x0002,
4277 0x0103,
4278 0x0000,
4279 0x0101,
4280 0x0002,
4281 0x0103,
4282 0x0000,
4283 0x0101,
4284 0x0002,
4285 0x0103,
4286 0x0000,
4287 0x0101,
4288 0x0002,
4289 0x0103,
4290 0x0000,
4291 0x0101,
4292 0x0002,
4293 0x0103,
4294 0x0000,
4295 0x0101,
4296 0x0002,
4297 0x0103,
4298 0x0000,
4299 0x0101,
4300 0x0002,
4301 0x0103,
4302 0x0000,
4303 0x0101,
4304 0x0002,
4305 0x0103,
4306};
4307
4308static const u16 loft_lut_core1_rev0[] = {
4309 0x0000,
4310 0x0101,
4311 0x0002,
4312 0x0103,
4313 0x0000,
4314 0x0101,
4315 0x0002,
4316 0x0103,
4317 0x0000,
4318 0x0101,
4319 0x0002,
4320 0x0103,
4321 0x0000,
4322 0x0101,
4323 0x0002,
4324 0x0103,
4325 0x0000,
4326 0x0101,
4327 0x0002,
4328 0x0103,
4329 0x0000,
4330 0x0101,
4331 0x0002,
4332 0x0103,
4333 0x0000,
4334 0x0101,
4335 0x0002,
4336 0x0103,
4337 0x0000,
4338 0x0101,
4339 0x0002,
4340 0x0103,
4341 0x0000,
4342 0x0101,
4343 0x0002,
4344 0x0103,
4345 0x0000,
4346 0x0101,
4347 0x0002,
4348 0x0103,
4349 0x0000,
4350 0x0101,
4351 0x0002,
4352 0x0103,
4353 0x0000,
4354 0x0101,
4355 0x0002,
4356 0x0103,
4357 0x0000,
4358 0x0101,
4359 0x0002,
4360 0x0103,
4361 0x0000,
4362 0x0101,
4363 0x0002,
4364 0x0103,
4365 0x0000,
4366 0x0101,
4367 0x0002,
4368 0x0103,
4369 0x0000,
4370 0x0101,
4371 0x0002,
4372 0x0103,
4373 0x0000,
4374 0x0101,
4375 0x0002,
4376 0x0103,
4377 0x0000,
4378 0x0101,
4379 0x0002,
4380 0x0103,
4381 0x0000,
4382 0x0101,
4383 0x0002,
4384 0x0103,
4385 0x0000,
4386 0x0101,
4387 0x0002,
4388 0x0103,
4389 0x0000,
4390 0x0101,
4391 0x0002,
4392 0x0103,
4393 0x0000,
4394 0x0101,
4395 0x0002,
4396 0x0103,
4397 0x0000,
4398 0x0101,
4399 0x0002,
4400 0x0103,
4401 0x0000,
4402 0x0101,
4403 0x0002,
4404 0x0103,
4405 0x0000,
4406 0x0101,
4407 0x0002,
4408 0x0103,
4409 0x0000,
4410 0x0101,
4411 0x0002,
4412 0x0103,
4413 0x0000,
4414 0x0101,
4415 0x0002,
4416 0x0103,
4417 0x0000,
4418 0x0101,
4419 0x0002,
4420 0x0103,
4421 0x0000,
4422 0x0101,
4423 0x0002,
4424 0x0103,
4425 0x0000,
4426 0x0101,
4427 0x0002,
4428 0x0103,
4429 0x0000,
4430 0x0101,
4431 0x0002,
4432 0x0103,
4433 0x0000,
4434 0x0101,
4435 0x0002,
4436 0x0103,
4437};
4438
4439const struct phytbl_info mimophytbl_info_rev0_volatile[] = {
4440 {&bdi_tbl_rev0, sizeof(bdi_tbl_rev0) / sizeof(bdi_tbl_rev0[0]), 21, 0,
4441 16}
4442 ,
4443 {&pltlut_tbl_rev0, sizeof(pltlut_tbl_rev0) / sizeof(pltlut_tbl_rev0[0]),
4444 20, 0, 32}
4445 ,
4446 {&gainctrl_lut_core0_rev0,
4447 sizeof(gainctrl_lut_core0_rev0) / sizeof(gainctrl_lut_core0_rev0[0]),
4448 26, 192, 32}
4449 ,
4450 {&gainctrl_lut_core1_rev0,
4451 sizeof(gainctrl_lut_core1_rev0) / sizeof(gainctrl_lut_core1_rev0[0]),
4452 27, 192, 32}
4453 ,
4454
4455 {&est_pwr_lut_core0_rev0,
4456 sizeof(est_pwr_lut_core0_rev0) / sizeof(est_pwr_lut_core0_rev0[0]), 26,
4457 0, 8}
4458 ,
4459 {&est_pwr_lut_core1_rev0,
4460 sizeof(est_pwr_lut_core1_rev0) / sizeof(est_pwr_lut_core1_rev0[0]), 27,
4461 0, 8}
4462 ,
4463 {&adj_pwr_lut_core0_rev0,
4464 sizeof(adj_pwr_lut_core0_rev0) / sizeof(adj_pwr_lut_core0_rev0[0]), 26,
4465 64, 8}
4466 ,
4467 {&adj_pwr_lut_core1_rev0,
4468 sizeof(adj_pwr_lut_core1_rev0) / sizeof(adj_pwr_lut_core1_rev0[0]), 27,
4469 64, 8}
4470 ,
4471 {&iq_lut_core0_rev0,
4472 sizeof(iq_lut_core0_rev0) / sizeof(iq_lut_core0_rev0[0]), 26, 320, 32}
4473 ,
4474 {&iq_lut_core1_rev0,
4475 sizeof(iq_lut_core1_rev0) / sizeof(iq_lut_core1_rev0[0]), 27, 320, 32}
4476 ,
4477 {&loft_lut_core0_rev0,
4478 sizeof(loft_lut_core0_rev0) / sizeof(loft_lut_core0_rev0[0]), 26, 448,
4479 16}
4480 ,
4481 {&loft_lut_core1_rev0,
4482 sizeof(loft_lut_core1_rev0) / sizeof(loft_lut_core1_rev0[0]), 27, 448,
4483 16}
4484 ,
4485};
4486
4487const struct phytbl_info mimophytbl_info_rev0[] = {
4488 {&frame_struct_rev0,
4489 sizeof(frame_struct_rev0) / sizeof(frame_struct_rev0[0]), 10, 0, 32}
4490 ,
4491 {&frame_lut_rev0, sizeof(frame_lut_rev0) / sizeof(frame_lut_rev0[0]),
4492 24, 0, 8}
4493 ,
4494 {&tmap_tbl_rev0, sizeof(tmap_tbl_rev0) / sizeof(tmap_tbl_rev0[0]), 12,
4495 0, 32}
4496 ,
4497 {&tdtrn_tbl_rev0, sizeof(tdtrn_tbl_rev0) / sizeof(tdtrn_tbl_rev0[0]),
4498 14, 0, 32}
4499 ,
4500 {&intlv_tbl_rev0, sizeof(intlv_tbl_rev0) / sizeof(intlv_tbl_rev0[0]),
4501 13, 0, 32}
4502 ,
4503 {&pilot_tbl_rev0, sizeof(pilot_tbl_rev0) / sizeof(pilot_tbl_rev0[0]),
4504 11, 0, 16}
4505 ,
4506 {&tdi_tbl20_ant0_rev0,
4507 sizeof(tdi_tbl20_ant0_rev0) / sizeof(tdi_tbl20_ant0_rev0[0]), 19, 128,
4508 32}
4509 ,
4510 {&tdi_tbl20_ant1_rev0,
4511 sizeof(tdi_tbl20_ant1_rev0) / sizeof(tdi_tbl20_ant1_rev0[0]), 19, 256,
4512 32}
4513 ,
4514 {&tdi_tbl40_ant0_rev0,
4515 sizeof(tdi_tbl40_ant0_rev0) / sizeof(tdi_tbl40_ant0_rev0[0]), 19, 640,
4516 32}
4517 ,
4518 {&tdi_tbl40_ant1_rev0,
4519 sizeof(tdi_tbl40_ant1_rev0) / sizeof(tdi_tbl40_ant1_rev0[0]), 19, 768,
4520 32}
4521 ,
4522 {&chanest_tbl_rev0,
4523 sizeof(chanest_tbl_rev0) / sizeof(chanest_tbl_rev0[0]), 22, 0, 32}
4524 ,
4525 {&mcs_tbl_rev0, sizeof(mcs_tbl_rev0) / sizeof(mcs_tbl_rev0[0]), 18, 0,
4526 8}
4527 ,
4528 {&noise_var_tbl0_rev0,
4529 sizeof(noise_var_tbl0_rev0) / sizeof(noise_var_tbl0_rev0[0]), 16, 0,
4530 32}
4531 ,
4532 {&noise_var_tbl1_rev0,
4533 sizeof(noise_var_tbl1_rev0) / sizeof(noise_var_tbl1_rev0[0]), 16, 128,
4534 32}
4535 ,
4536};
4537
4538const u32 mimophytbl_info_sz_rev0 =
4539 sizeof(mimophytbl_info_rev0) / sizeof(mimophytbl_info_rev0[0]);
4540const u32 mimophytbl_info_sz_rev0_volatile =
4541 sizeof(mimophytbl_info_rev0_volatile) /
4542 sizeof(mimophytbl_info_rev0_volatile[0]);
4543
4544static const u16 ant_swctrl_tbl_rev3[] = {
4545 0x0082,
4546 0x0082,
4547 0x0211,
4548 0x0222,
4549 0x0328,
4550 0x0000,
4551 0x0000,
4552 0x0000,
4553 0x0144,
4554 0x0000,
4555 0x0000,
4556 0x0000,
4557 0x0188,
4558 0x0000,
4559 0x0000,
4560 0x0000,
4561 0x0082,
4562 0x0082,
4563 0x0211,
4564 0x0222,
4565 0x0328,
4566 0x0000,
4567 0x0000,
4568 0x0000,
4569 0x0144,
4570 0x0000,
4571 0x0000,
4572 0x0000,
4573 0x0188,
4574 0x0000,
4575 0x0000,
4576 0x0000,
4577};
4578
4579static const u16 ant_swctrl_tbl_rev3_1[] = {
4580 0x0022,
4581 0x0022,
4582 0x0011,
4583 0x0022,
4584 0x0022,
4585 0x0000,
4586 0x0000,
4587 0x0000,
4588 0x0011,
4589 0x0000,
4590 0x0000,
4591 0x0000,
4592 0x0022,
4593 0x0000,
4594 0x0000,
4595 0x0000,
4596 0x0022,
4597 0x0022,
4598 0x0011,
4599 0x0022,
4600 0x0022,
4601 0x0000,
4602 0x0000,
4603 0x0000,
4604 0x0011,
4605 0x0000,
4606 0x0000,
4607 0x0000,
4608 0x0022,
4609 0x0000,
4610 0x0000,
4611 0x0000,
4612};
4613
4614static const u16 ant_swctrl_tbl_rev3_2[] = {
4615 0x0088,
4616 0x0088,
4617 0x0044,
4618 0x0088,
4619 0x0088,
4620 0x0000,
4621 0x0000,
4622 0x0000,
4623 0x0044,
4624 0x0000,
4625 0x0000,
4626 0x0000,
4627 0x0088,
4628 0x0000,
4629 0x0000,
4630 0x0000,
4631 0x0088,
4632 0x0088,
4633 0x0044,
4634 0x0088,
4635 0x0088,
4636 0x0000,
4637 0x0000,
4638 0x0000,
4639 0x0044,
4640 0x0000,
4641 0x0000,
4642 0x0000,
4643 0x0088,
4644 0x0000,
4645 0x0000,
4646 0x0000,
4647};
4648
4649static const u16 ant_swctrl_tbl_rev3_3[] = {
4650 0x022,
4651 0x022,
4652 0x011,
4653 0x022,
4654 0x000,
4655 0x000,
4656 0x000,
4657 0x000,
4658 0x011,
4659 0x000,
4660 0x000,
4661 0x000,
4662 0x022,
4663 0x000,
4664 0x000,
4665 0x3cc,
4666 0x022,
4667 0x022,
4668 0x011,
4669 0x022,
4670 0x000,
4671 0x000,
4672 0x000,
4673 0x000,
4674 0x011,
4675 0x000,
4676 0x000,
4677 0x000,
4678 0x022,
4679 0x000,
4680 0x000,
4681 0x3cc
4682};
4683
4684static const u32 frame_struct_rev3[] = {
4685 0x08004a04,
4686 0x00100000,
4687 0x01000a05,
4688 0x00100020,
4689 0x09804506,
4690 0x00100030,
4691 0x09804507,
4692 0x00100030,
4693 0x00000000,
4694 0x00000000,
4695 0x00000000,
4696 0x00000000,
4697 0x00000000,
4698 0x00000000,
4699 0x00000000,
4700 0x00000000,
4701 0x08004a0c,
4702 0x00100004,
4703 0x01000a0d,
4704 0x00100024,
4705 0x0980450e,
4706 0x00100034,
4707 0x0980450f,
4708 0x00100034,
4709 0x00000000,
4710 0x00000000,
4711 0x00000000,
4712 0x00000000,
4713 0x00000000,
4714 0x00000000,
4715 0x00000000,
4716 0x00000000,
4717 0x00000a04,
4718 0x00100000,
4719 0x11008a05,
4720 0x00100020,
4721 0x1980c506,
4722 0x00100030,
4723 0x21810506,
4724 0x00100030,
4725 0x21810506,
4726 0x00100030,
4727 0x01800504,
4728 0x00100030,
4729 0x11808505,
4730 0x00100030,
4731 0x29814507,
4732 0x01100030,
4733 0x00000a04,
4734 0x00100000,
4735 0x11008a05,
4736 0x00100020,
4737 0x21810506,
4738 0x00100030,
4739 0x21810506,
4740 0x00100030,
4741 0x29814507,
4742 0x01100030,
4743 0x00000000,
4744 0x00000000,
4745 0x00000000,
4746 0x00000000,
4747 0x00000000,
4748 0x00000000,
4749 0x00000a0c,
4750 0x00100008,
4751 0x11008a0d,
4752 0x00100028,
4753 0x1980c50e,
4754 0x00100038,
4755 0x2181050e,
4756 0x00100038,
4757 0x2181050e,
4758 0x00100038,
4759 0x0180050c,
4760 0x00100038,
4761 0x1180850d,
4762 0x00100038,
4763 0x2981450f,
4764 0x01100038,
4765 0x00000a0c,
4766 0x00100008,
4767 0x11008a0d,
4768 0x00100028,
4769 0x2181050e,
4770 0x00100038,
4771 0x2181050e,
4772 0x00100038,
4773 0x2981450f,
4774 0x01100038,
4775 0x00000000,
4776 0x00000000,
4777 0x00000000,
4778 0x00000000,
4779 0x00000000,
4780 0x00000000,
4781 0x08004a04,
4782 0x00100000,
4783 0x01000a05,
4784 0x00100020,
4785 0x1980c506,
4786 0x00100030,
4787 0x1980c506,
4788 0x00100030,
4789 0x11808504,
4790 0x00100030,
4791 0x3981ca05,
4792 0x00100030,
4793 0x29814507,
4794 0x01100030,
4795 0x00000000,
4796 0x00000000,
4797 0x10008a04,
4798 0x00100000,
4799 0x3981ca05,
4800 0x00100030,
4801 0x1980c506,
4802 0x00100030,
4803 0x29814507,
4804 0x01100030,
4805 0x00000000,
4806 0x00000000,
4807 0x00000000,
4808 0x00000000,
4809 0x00000000,
4810 0x00000000,
4811 0x00000000,
4812 0x00000000,
4813 0x08004a0c,
4814 0x00100008,
4815 0x01000a0d,
4816 0x00100028,
4817 0x1980c50e,
4818 0x00100038,
4819 0x1980c50e,
4820 0x00100038,
4821 0x1180850c,
4822 0x00100038,
4823 0x3981ca0d,
4824 0x00100038,
4825 0x2981450f,
4826 0x01100038,
4827 0x00000000,
4828 0x00000000,
4829 0x10008a0c,
4830 0x00100008,
4831 0x3981ca0d,
4832 0x00100038,
4833 0x1980c50e,
4834 0x00100038,
4835 0x2981450f,
4836 0x01100038,
4837 0x00000000,
4838 0x00000000,
4839 0x00000000,
4840 0x00000000,
4841 0x00000000,
4842 0x00000000,
4843 0x00000000,
4844 0x00000000,
4845 0x40021404,
4846 0x00100000,
4847 0x02001405,
4848 0x00100040,
4849 0x0b004a06,
4850 0x01900060,
4851 0x13008a06,
4852 0x01900060,
4853 0x13008a06,
4854 0x01900060,
4855 0x43020a04,
4856 0x00100060,
4857 0x1b00ca05,
4858 0x00100060,
4859 0x23010a07,
4860 0x01500060,
4861 0x40021404,
4862 0x00100000,
4863 0x1a00d405,
4864 0x00100040,
4865 0x13008a06,
4866 0x01900060,
4867 0x13008a06,
4868 0x01900060,
4869 0x23010a07,
4870 0x01500060,
4871 0x00000000,
4872 0x00000000,
4873 0x00000000,
4874 0x00000000,
4875 0x00000000,
4876 0x00000000,
4877 0x4002140c,
4878 0x00100010,
4879 0x0200140d,
4880 0x00100050,
4881 0x0b004a0e,
4882 0x01900070,
4883 0x13008a0e,
4884 0x01900070,
4885 0x13008a0e,
4886 0x01900070,
4887 0x43020a0c,
4888 0x00100070,
4889 0x1b00ca0d,
4890 0x00100070,
4891 0x23010a0f,
4892 0x01500070,
4893 0x4002140c,
4894 0x00100010,
4895 0x1a00d40d,
4896 0x00100050,
4897 0x13008a0e,
4898 0x01900070,
4899 0x13008a0e,
4900 0x01900070,
4901 0x23010a0f,
4902 0x01500070,
4903 0x00000000,
4904 0x00000000,
4905 0x00000000,
4906 0x00000000,
4907 0x00000000,
4908 0x00000000,
4909 0x50029404,
4910 0x00100000,
4911 0x32019405,
4912 0x00100040,
4913 0x0b004a06,
4914 0x01900060,
4915 0x0b004a06,
4916 0x01900060,
4917 0x5b02ca04,
4918 0x00100060,
4919 0x3b01d405,
4920 0x00100060,
4921 0x23010a07,
4922 0x01500060,
4923 0x00000000,
4924 0x00000000,
4925 0x5802d404,
4926 0x00100000,
4927 0x3b01d405,
4928 0x00100060,
4929 0x0b004a06,
4930 0x01900060,
4931 0x23010a07,
4932 0x01500060,
4933 0x00000000,
4934 0x00000000,
4935 0x00000000,
4936 0x00000000,
4937 0x00000000,
4938 0x00000000,
4939 0x00000000,
4940 0x00000000,
4941 0x5002940c,
4942 0x00100010,
4943 0x3201940d,
4944 0x00100050,
4945 0x0b004a0e,
4946 0x01900070,
4947 0x0b004a0e,
4948 0x01900070,
4949 0x5b02ca0c,
4950 0x00100070,
4951 0x3b01d40d,
4952 0x00100070,
4953 0x23010a0f,
4954 0x01500070,
4955 0x00000000,
4956 0x00000000,
4957 0x5802d40c,
4958 0x00100010,
4959 0x3b01d40d,
4960 0x00100070,
4961 0x0b004a0e,
4962 0x01900070,
4963 0x23010a0f,
4964 0x01500070,
4965 0x00000000,
4966 0x00000000,
4967 0x00000000,
4968 0x00000000,
4969 0x00000000,
4970 0x00000000,
4971 0x00000000,
4972 0x00000000,
4973 0x40021404,
4974 0x000f4800,
4975 0x62031405,
4976 0x00100040,
4977 0x53028a06,
4978 0x01900060,
4979 0x53028a07,
4980 0x01900060,
4981 0x00000000,
4982 0x00000000,
4983 0x00000000,
4984 0x00000000,
4985 0x00000000,
4986 0x00000000,
4987 0x00000000,
4988 0x00000000,
4989 0x4002140c,
4990 0x000f4808,
4991 0x6203140d,
4992 0x00100048,
4993 0x53028a0e,
4994 0x01900068,
4995 0x53028a0f,
4996 0x01900068,
4997 0x00000000,
4998 0x00000000,
4999 0x00000000,
5000 0x00000000,
5001 0x00000000,
5002 0x00000000,
5003 0x00000000,
5004 0x00000000,
5005 0x00000a0c,
5006 0x00100004,
5007 0x11008a0d,
5008 0x00100024,
5009 0x1980c50e,
5010 0x00100034,
5011 0x2181050e,
5012 0x00100034,
5013 0x2181050e,
5014 0x00100034,
5015 0x0180050c,
5016 0x00100038,
5017 0x1180850d,
5018 0x00100038,
5019 0x1181850d,
5020 0x00100038,
5021 0x2981450f,
5022 0x01100038,
5023 0x00000000,
5024 0x00000000,
5025 0x00000000,
5026 0x00000000,
5027 0x00000000,
5028 0x00000000,
5029 0x00000000,
5030 0x00000000,
5031 0x00000000,
5032 0x00000000,
5033 0x00000000,
5034 0x00000000,
5035 0x00000000,
5036 0x00000000,
5037 0x00000a0c,
5038 0x00100008,
5039 0x11008a0d,
5040 0x00100028,
5041 0x2181050e,
5042 0x00100038,
5043 0x2181050e,
5044 0x00100038,
5045 0x1181850d,
5046 0x00100038,
5047 0x2981450f,
5048 0x01100038,
5049 0x00000000,
5050 0x00000000,
5051 0x00000000,
5052 0x00000000,
5053 0x00000000,
5054 0x00000000,
5055 0x00000000,
5056 0x00000000,
5057 0x00000000,
5058 0x00000000,
5059 0x00000000,
5060 0x00000000,
5061 0x00000000,
5062 0x00000000,
5063 0x00000000,
5064 0x00000000,
5065 0x00000000,
5066 0x00000000,
5067 0x00000000,
5068 0x00000000,
5069 0x08004a04,
5070 0x00100000,
5071 0x01000a05,
5072 0x00100020,
5073 0x0180c506,
5074 0x00100030,
5075 0x0180c506,
5076 0x00100030,
5077 0x2180c50c,
5078 0x00100030,
5079 0x49820a0d,
5080 0x0016a130,
5081 0x41824a0d,
5082 0x0016a130,
5083 0x2981450f,
5084 0x01100030,
5085 0x00000000,
5086 0x00000000,
5087 0x00000000,
5088 0x00000000,
5089 0x00000000,
5090 0x00000000,
5091 0x00000000,
5092 0x00000000,
5093 0x00000000,
5094 0x00000000,
5095 0x00000000,
5096 0x00000000,
5097 0x00000000,
5098 0x00000000,
5099 0x00000000,
5100 0x00000000,
5101 0x2000ca0c,
5102 0x00100000,
5103 0x49820a0d,
5104 0x0016a130,
5105 0x1980c50e,
5106 0x00100030,
5107 0x41824a0d,
5108 0x0016a130,
5109 0x2981450f,
5110 0x01100030,
5111 0x00000000,
5112 0x00000000,
5113 0x00000000,
5114 0x00000000,
5115 0x00000000,
5116 0x00000000,
5117 0x00000000,
5118 0x00000000,
5119 0x00000000,
5120 0x00000000,
5121 0x00000000,
5122 0x00000000,
5123 0x00000000,
5124 0x00000000,
5125 0x00000000,
5126 0x00000000,
5127 0x00000000,
5128 0x00000000,
5129 0x00000000,
5130 0x00000000,
5131 0x00000000,
5132 0x00000000,
5133 0x4002140c,
5134 0x00100008,
5135 0x0200140d,
5136 0x00100048,
5137 0x0b004a0e,
5138 0x01900068,
5139 0x13008a0e,
5140 0x01900068,
5141 0x13008a0e,
5142 0x01900068,
5143 0x43020a0c,
5144 0x00100070,
5145 0x1b00ca0d,
5146 0x00100070,
5147 0x1b014a0d,
5148 0x00100070,
5149 0x23010a0f,
5150 0x01500070,
5151 0x00000000,
5152 0x00000000,
5153 0x00000000,
5154 0x00000000,
5155 0x00000000,
5156 0x00000000,
5157 0x00000000,
5158 0x00000000,
5159 0x00000000,
5160 0x00000000,
5161 0x00000000,
5162 0x00000000,
5163 0x00000000,
5164 0x00000000,
5165 0x4002140c,
5166 0x00100010,
5167 0x1a00d40d,
5168 0x00100050,
5169 0x13008a0e,
5170 0x01900070,
5171 0x13008a0e,
5172 0x01900070,
5173 0x1b014a0d,
5174 0x00100070,
5175 0x23010a0f,
5176 0x01500070,
5177 0x00000000,
5178 0x00000000,
5179 0x00000000,
5180 0x00000000,
5181 0x00000000,
5182 0x00000000,
5183 0x00000000,
5184 0x00000000,
5185 0x00000000,
5186 0x00000000,
5187 0x00000000,
5188 0x00000000,
5189 0x00000000,
5190 0x00000000,
5191 0x00000000,
5192 0x00000000,
5193 0x00000000,
5194 0x00000000,
5195 0x00000000,
5196 0x00000000,
5197 0x50029404,
5198 0x00100000,
5199 0x32019405,
5200 0x00100040,
5201 0x03004a06,
5202 0x01900060,
5203 0x03004a06,
5204 0x01900060,
5205 0x6b030a0c,
5206 0x00100060,
5207 0x4b02140d,
5208 0x0016a160,
5209 0x4302540d,
5210 0x0016a160,
5211 0x23010a0f,
5212 0x01500060,
5213 0x00000000,
5214 0x00000000,
5215 0x00000000,
5216 0x00000000,
5217 0x00000000,
5218 0x00000000,
5219 0x00000000,
5220 0x00000000,
5221 0x00000000,
5222 0x00000000,
5223 0x00000000,
5224 0x00000000,
5225 0x00000000,
5226 0x00000000,
5227 0x00000000,
5228 0x00000000,
5229 0x6b03140c,
5230 0x00100060,
5231 0x4b02140d,
5232 0x0016a160,
5233 0x0b004a0e,
5234 0x01900060,
5235 0x4302540d,
5236 0x0016a160,
5237 0x23010a0f,
5238 0x01500060,
5239 0x00000000,
5240 0x00000000,
5241 0x00000000,
5242 0x00000000,
5243 0x00000000,
5244 0x00000000,
5245 0x00000000,
5246 0x00000000,
5247 0x00000000,
5248 0x00000000,
5249 0x00000000,
5250 0x00000000,
5251 0x00000000,
5252 0x00000000,
5253 0x00000000,
5254 0x00000000,
5255 0x00000000,
5256 0x00000000,
5257 0x00000000,
5258 0x00000000,
5259 0x00000000,
5260 0x00000000,
5261 0x40021404,
5262 0x00100000,
5263 0x1a00d405,
5264 0x00100040,
5265 0x53028a06,
5266 0x01900060,
5267 0x5b02ca06,
5268 0x01900060,
5269 0x5b02ca06,
5270 0x01900060,
5271 0x43020a04,
5272 0x00100060,
5273 0x1b00ca05,
5274 0x00100060,
5275 0x53028a07,
5276 0x0190c060,
5277 0x00000000,
5278 0x00000000,
5279 0x00000000,
5280 0x00000000,
5281 0x00000000,
5282 0x00000000,
5283 0x00000000,
5284 0x00000000,
5285 0x00000000,
5286 0x00000000,
5287 0x00000000,
5288 0x00000000,
5289 0x00000000,
5290 0x00000000,
5291 0x00000000,
5292 0x00000000,
5293 0x4002140c,
5294 0x00100010,
5295 0x1a00d40d,
5296 0x00100050,
5297 0x53028a0e,
5298 0x01900070,
5299 0x5b02ca0e,
5300 0x01900070,
5301 0x5b02ca0e,
5302 0x01900070,
5303 0x43020a0c,
5304 0x00100070,
5305 0x1b00ca0d,
5306 0x00100070,
5307 0x53028a0f,
5308 0x0190c070,
5309 0x00000000,
5310 0x00000000,
5311 0x00000000,
5312 0x00000000,
5313 0x00000000,
5314 0x00000000,
5315 0x00000000,
5316 0x00000000,
5317 0x00000000,
5318 0x00000000,
5319 0x00000000,
5320 0x00000000,
5321 0x00000000,
5322 0x00000000,
5323 0x00000000,
5324 0x00000000,
5325 0x40021404,
5326 0x00100000,
5327 0x1a00d405,
5328 0x00100040,
5329 0x5b02ca06,
5330 0x01900060,
5331 0x5b02ca06,
5332 0x01900060,
5333 0x53028a07,
5334 0x0190c060,
5335 0x00000000,
5336 0x00000000,
5337 0x00000000,
5338 0x00000000,
5339 0x00000000,
5340 0x00000000,
5341 0x00000000,
5342 0x00000000,
5343 0x00000000,
5344 0x00000000,
5345 0x00000000,
5346 0x00000000,
5347 0x00000000,
5348 0x00000000,
5349 0x00000000,
5350 0x00000000,
5351 0x00000000,
5352 0x00000000,
5353 0x00000000,
5354 0x00000000,
5355 0x00000000,
5356 0x00000000,
5357 0x4002140c,
5358 0x00100010,
5359 0x1a00d40d,
5360 0x00100050,
5361 0x5b02ca0e,
5362 0x01900070,
5363 0x5b02ca0e,
5364 0x01900070,
5365 0x53028a0f,
5366 0x0190c070,
5367 0x00000000,
5368 0x00000000,
5369 0x00000000,
5370 0x00000000,
5371 0x00000000,
5372 0x00000000,
5373 0x00000000,
5374 0x00000000,
5375 0x00000000,
5376 0x00000000,
5377 0x00000000,
5378 0x00000000,
5379 0x00000000,
5380 0x00000000,
5381 0x00000000,
5382 0x00000000,
5383 0x00000000,
5384 0x00000000,
5385 0x00000000,
5386 0x00000000,
5387 0x00000000,
5388 0x00000000,
5389 0x00000000,
5390 0x00000000,
5391 0x00000000,
5392 0x00000000,
5393 0x00000000,
5394 0x00000000,
5395 0x00000000,
5396 0x00000000,
5397 0x00000000,
5398 0x00000000,
5399 0x00000000,
5400 0x00000000,
5401 0x00000000,
5402 0x00000000,
5403 0x00000000,
5404 0x00000000,
5405 0x00000000,
5406 0x00000000,
5407 0x00000000,
5408 0x00000000,
5409 0x00000000,
5410 0x00000000,
5411 0x00000000,
5412 0x00000000,
5413 0x00000000,
5414 0x00000000,
5415 0x00000000,
5416 0x00000000,
5417 0x00000000,
5418 0x00000000,
5419 0x00000000,
5420 0x00000000,
5421 0x00000000,
5422 0x00000000,
5423 0x00000000,
5424 0x00000000,
5425 0x00000000,
5426 0x00000000,
5427 0x00000000,
5428 0x00000000,
5429 0x00000000,
5430 0x00000000,
5431 0x00000000,
5432 0x00000000,
5433 0x00000000,
5434 0x00000000,
5435 0x00000000,
5436 0x00000000,
5437 0x00000000,
5438 0x00000000,
5439 0x00000000,
5440 0x00000000,
5441 0x00000000,
5442 0x00000000,
5443 0x00000000,
5444 0x00000000,
5445 0x00000000,
5446 0x00000000,
5447 0x00000000,
5448 0x00000000,
5449 0x00000000,
5450 0x00000000,
5451 0x00000000,
5452 0x00000000,
5453 0x00000000,
5454 0x00000000,
5455 0x00000000,
5456 0x00000000,
5457 0x00000000,
5458 0x00000000,
5459 0x00000000,
5460 0x00000000,
5461 0x00000000,
5462 0x00000000,
5463 0x00000000,
5464 0x00000000,
5465 0x00000000,
5466 0x00000000,
5467 0x00000000,
5468 0x00000000,
5469 0x00000000,
5470 0x00000000,
5471 0x00000000,
5472 0x00000000,
5473 0x00000000,
5474 0x00000000,
5475 0x00000000,
5476 0x00000000,
5477 0x00000000,
5478 0x00000000,
5479 0x00000000,
5480 0x00000000,
5481 0x00000000,
5482 0x00000000,
5483 0x00000000,
5484 0x00000000,
5485 0x00000000,
5486 0x00000000,
5487 0x00000000,
5488 0x00000000,
5489 0x00000000,
5490 0x00000000,
5491 0x00000000,
5492 0x00000000,
5493 0x00000000,
5494 0x00000000,
5495 0x00000000,
5496 0x00000000,
5497 0x00000000,
5498 0x00000000,
5499 0x00000000,
5500 0x00000000,
5501 0x00000000,
5502 0x00000000,
5503 0x00000000,
5504 0x00000000,
5505 0x00000000,
5506 0x00000000,
5507 0x00000000,
5508 0x00000000,
5509 0x00000000,
5510 0x00000000,
5511 0x00000000,
5512 0x00000000,
5513 0x00000000,
5514 0x00000000,
5515 0x00000000,
5516 0x00000000,
5517};
5518
5519static const u16 pilot_tbl_rev3[] = {
5520 0xff08,
5521 0xff08,
5522 0xff08,
5523 0xff08,
5524 0xff08,
5525 0xff08,
5526 0xff08,
5527 0xff08,
5528 0x80d5,
5529 0x80d5,
5530 0x80d5,
5531 0x80d5,
5532 0x80d5,
5533 0x80d5,
5534 0x80d5,
5535 0x80d5,
5536 0xff0a,
5537 0xff82,
5538 0xffa0,
5539 0xff28,
5540 0xffff,
5541 0xffff,
5542 0xffff,
5543 0xffff,
5544 0xff82,
5545 0xffa0,
5546 0xff28,
5547 0xff0a,
5548 0xffff,
5549 0xffff,
5550 0xffff,
5551 0xffff,
5552 0xf83f,
5553 0xfa1f,
5554 0xfa97,
5555 0xfab5,
5556 0xf2bd,
5557 0xf0bf,
5558 0xffff,
5559 0xffff,
5560 0xf017,
5561 0xf815,
5562 0xf215,
5563 0xf095,
5564 0xf035,
5565 0xf01d,
5566 0xffff,
5567 0xffff,
5568 0xff08,
5569 0xff02,
5570 0xff80,
5571 0xff20,
5572 0xff08,
5573 0xff02,
5574 0xff80,
5575 0xff20,
5576 0xf01f,
5577 0xf817,
5578 0xfa15,
5579 0xf295,
5580 0xf0b5,
5581 0xf03d,
5582 0xffff,
5583 0xffff,
5584 0xf82a,
5585 0xfa0a,
5586 0xfa82,
5587 0xfaa0,
5588 0xf2a8,
5589 0xf0aa,
5590 0xffff,
5591 0xffff,
5592 0xf002,
5593 0xf800,
5594 0xf200,
5595 0xf080,
5596 0xf020,
5597 0xf008,
5598 0xffff,
5599 0xffff,
5600 0xf00a,
5601 0xf802,
5602 0xfa00,
5603 0xf280,
5604 0xf0a0,
5605 0xf028,
5606 0xffff,
5607 0xffff,
5608};
5609
5610static const u32 tmap_tbl_rev3[] = {
5611 0x8a88aa80,
5612 0x8aaaaa8a,
5613 0x8a8a8aa8,
5614 0x00000888,
5615 0x88000000,
5616 0x8a8a88aa,
5617 0x8aa88888,
5618 0x8888a8a8,
5619 0xf1111110,
5620 0x11111111,
5621 0x11f11111,
5622 0x00000111,
5623 0x11000000,
5624 0x1111f111,
5625 0x11111111,
5626 0x111111f1,
5627 0x8a88aa80,
5628 0x8aaaaa8a,
5629 0x8a8a8aa8,
5630 0x000aa888,
5631 0x88880000,
5632 0x8a8a88aa,
5633 0x8aa88888,
5634 0x8888a8a8,
5635 0xa1111110,
5636 0x11111111,
5637 0x11c11111,
5638 0x00000111,
5639 0x11000000,
5640 0x1111a111,
5641 0x11111111,
5642 0x111111a1,
5643 0xa2222220,
5644 0x22222222,
5645 0x22c22222,
5646 0x00000222,
5647 0x22000000,
5648 0x2222a222,
5649 0x22222222,
5650 0x222222a2,
5651 0xf1111110,
5652 0x11111111,
5653 0x11f11111,
5654 0x00011111,
5655 0x11110000,
5656 0x1111f111,
5657 0x11111111,
5658 0x111111f1,
5659 0xa8aa88a0,
5660 0xa88888a8,
5661 0xa8a8a88a,
5662 0x00088aaa,
5663 0xaaaa0000,
5664 0xa8a8aa88,
5665 0xa88aaaaa,
5666 0xaaaa8a8a,
5667 0xaaa8aaa0,
5668 0x8aaa8aaa,
5669 0xaa8a8a8a,
5670 0x000aaa88,
5671 0x8aaa0000,
5672 0xaaa8a888,
5673 0x8aa88a8a,
5674 0x8a88a888,
5675 0x08080a00,
5676 0x0a08080a,
5677 0x080a0a08,
5678 0x00080808,
5679 0x080a0000,
5680 0x080a0808,
5681 0x080a0808,
5682 0x0a0a0a08,
5683 0xa0a0a0a0,
5684 0x80a0a080,
5685 0x8080a0a0,
5686 0x00008080,
5687 0x80a00000,
5688 0x80a080a0,
5689 0xa080a0a0,
5690 0x8080a0a0,
5691 0x00000000,
5692 0x00000000,
5693 0x00000000,
5694 0x00000000,
5695 0x00000000,
5696 0x00000000,
5697 0x00000000,
5698 0x00000000,
5699 0x00000000,
5700 0x00000000,
5701 0x00000000,
5702 0x00000000,
5703 0x00000000,
5704 0x00000000,
5705 0x00000000,
5706 0x00000000,
5707 0x00000000,
5708 0x00000000,
5709 0x00000000,
5710 0x00000000,
5711 0x00000000,
5712 0x00000000,
5713 0x00000000,
5714 0x00000000,
5715 0x00000000,
5716 0x00000000,
5717 0x00000000,
5718 0x00000000,
5719 0x00000000,
5720 0x00000000,
5721 0x00000000,
5722 0x00000000,
5723 0x00000000,
5724 0x00000000,
5725 0x00000000,
5726 0x00000000,
5727 0x00000000,
5728 0x00000000,
5729 0x00000000,
5730 0x00000000,
5731 0x00000000,
5732 0x00000000,
5733 0x00000000,
5734 0x00000000,
5735 0x00000000,
5736 0x00000000,
5737 0x00000000,
5738 0x00000000,
5739 0x99999000,
5740 0x9b9b99bb,
5741 0x9bb99999,
5742 0x9999b9b9,
5743 0x9b99bb90,
5744 0x9bbbbb9b,
5745 0x9b9b9bb9,
5746 0x00000999,
5747 0x88000000,
5748 0x8a8a88aa,
5749 0x8aa88888,
5750 0x8888a8a8,
5751 0x8a88aa80,
5752 0x8aaaaa8a,
5753 0x8a8a8aa8,
5754 0x00aaa888,
5755 0x22000000,
5756 0x2222b222,
5757 0x22222222,
5758 0x222222b2,
5759 0xb2222220,
5760 0x22222222,
5761 0x22d22222,
5762 0x00000222,
5763 0x11000000,
5764 0x1111a111,
5765 0x11111111,
5766 0x111111a1,
5767 0xa1111110,
5768 0x11111111,
5769 0x11c11111,
5770 0x00000111,
5771 0x33000000,
5772 0x3333b333,
5773 0x33333333,
5774 0x333333b3,
5775 0xb3333330,
5776 0x33333333,
5777 0x33d33333,
5778 0x00000333,
5779 0x22000000,
5780 0x2222a222,
5781 0x22222222,
5782 0x222222a2,
5783 0xa2222220,
5784 0x22222222,
5785 0x22c22222,
5786 0x00000222,
5787 0x99b99b00,
5788 0x9b9b99bb,
5789 0x9bb99999,
5790 0x9999b9b9,
5791 0x9b99bb99,
5792 0x9bbbbb9b,
5793 0x9b9b9bb9,
5794 0x00000999,
5795 0x88000000,
5796 0x8a8a88aa,
5797 0x8aa88888,
5798 0x8888a8a8,
5799 0x8a88aa88,
5800 0x8aaaaa8a,
5801 0x8a8a8aa8,
5802 0x08aaa888,
5803 0x22222200,
5804 0x2222f222,
5805 0x22222222,
5806 0x222222f2,
5807 0x22222222,
5808 0x22222222,
5809 0x22f22222,
5810 0x00000222,
5811 0x11000000,
5812 0x1111f111,
5813 0x11111111,
5814 0x11111111,
5815 0xf1111111,
5816 0x11111111,
5817 0x11f11111,
5818 0x01111111,
5819 0xbb9bb900,
5820 0xb9b9bb99,
5821 0xb99bbbbb,
5822 0xbbbb9b9b,
5823 0xb9bb99bb,
5824 0xb99999b9,
5825 0xb9b9b99b,
5826 0x00000bbb,
5827 0xaa000000,
5828 0xa8a8aa88,
5829 0xa88aaaaa,
5830 0xaaaa8a8a,
5831 0xa8aa88aa,
5832 0xa88888a8,
5833 0xa8a8a88a,
5834 0x0a888aaa,
5835 0xaa000000,
5836 0xa8a8aa88,
5837 0xa88aaaaa,
5838 0xaaaa8a8a,
5839 0xa8aa88a0,
5840 0xa88888a8,
5841 0xa8a8a88a,
5842 0x00000aaa,
5843 0x88000000,
5844 0x8a8a88aa,
5845 0x8aa88888,
5846 0x8888a8a8,
5847 0x8a88aa80,
5848 0x8aaaaa8a,
5849 0x8a8a8aa8,
5850 0x00000888,
5851 0xbbbbbb00,
5852 0x999bbbbb,
5853 0x9bb99b9b,
5854 0xb9b9b9bb,
5855 0xb9b99bbb,
5856 0xb9b9b9bb,
5857 0xb9bb9b99,
5858 0x00000999,
5859 0x8a000000,
5860 0xaa88a888,
5861 0xa88888aa,
5862 0xa88a8a88,
5863 0xa88aa88a,
5864 0x88a8aaaa,
5865 0xa8aa8aaa,
5866 0x0888a88a,
5867 0x0b0b0b00,
5868 0x090b0b0b,
5869 0x0b090b0b,
5870 0x0909090b,
5871 0x09090b0b,
5872 0x09090b0b,
5873 0x09090b09,
5874 0x00000909,
5875 0x0a000000,
5876 0x0a080808,
5877 0x080a080a,
5878 0x080a0a08,
5879 0x080a080a,
5880 0x0808080a,
5881 0x0a0a0a08,
5882 0x0808080a,
5883 0xb0b0b000,
5884 0x9090b0b0,
5885 0x90b09090,
5886 0xb0b0b090,
5887 0xb0b090b0,
5888 0x90b0b0b0,
5889 0xb0b09090,
5890 0x00000090,
5891 0x80000000,
5892 0xa080a080,
5893 0xa08080a0,
5894 0xa0808080,
5895 0xa080a080,
5896 0x80a0a0a0,
5897 0xa0a080a0,
5898 0x00a0a0a0,
5899 0x22000000,
5900 0x2222f222,
5901 0x22222222,
5902 0x222222f2,
5903 0xf2222220,
5904 0x22222222,
5905 0x22f22222,
5906 0x00000222,
5907 0x11000000,
5908 0x1111f111,
5909 0x11111111,
5910 0x111111f1,
5911 0xf1111110,
5912 0x11111111,
5913 0x11f11111,
5914 0x00000111,
5915 0x33000000,
5916 0x3333f333,
5917 0x33333333,
5918 0x333333f3,
5919 0xf3333330,
5920 0x33333333,
5921 0x33f33333,
5922 0x00000333,
5923 0x22000000,
5924 0x2222f222,
5925 0x22222222,
5926 0x222222f2,
5927 0xf2222220,
5928 0x22222222,
5929 0x22f22222,
5930 0x00000222,
5931 0x99000000,
5932 0x9b9b99bb,
5933 0x9bb99999,
5934 0x9999b9b9,
5935 0x9b99bb90,
5936 0x9bbbbb9b,
5937 0x9b9b9bb9,
5938 0x00000999,
5939 0x88000000,
5940 0x8a8a88aa,
5941 0x8aa88888,
5942 0x8888a8a8,
5943 0x8a88aa80,
5944 0x8aaaaa8a,
5945 0x8a8a8aa8,
5946 0x00000888,
5947 0x88888000,
5948 0x8a8a88aa,
5949 0x8aa88888,
5950 0x8888a8a8,
5951 0x8a88aa80,
5952 0x8aaaaa8a,
5953 0x8a8a8aa8,
5954 0x00000888,
5955 0x88000000,
5956 0x8a8a88aa,
5957 0x8aa88888,
5958 0x8888a8a8,
5959 0x8a88aa80,
5960 0x8aaaaa8a,
5961 0x8a8a8aa8,
5962 0x00aaa888,
5963 0x88a88a00,
5964 0x8a8a88aa,
5965 0x8aa88888,
5966 0x8888a8a8,
5967 0x8a88aa88,
5968 0x8aaaaa8a,
5969 0x8a8a8aa8,
5970 0x00000888,
5971 0x88000000,
5972 0x8a8a88aa,
5973 0x8aa88888,
5974 0x8888a8a8,
5975 0x8a88aa88,
5976 0x8aaaaa8a,
5977 0x8a8a8aa8,
5978 0x08aaa888,
5979 0x11000000,
5980 0x1111a111,
5981 0x11111111,
5982 0x111111a1,
5983 0xa1111110,
5984 0x11111111,
5985 0x11c11111,
5986 0x00000111,
5987 0x11000000,
5988 0x1111a111,
5989 0x11111111,
5990 0x111111a1,
5991 0xa1111110,
5992 0x11111111,
5993 0x11c11111,
5994 0x00000111,
5995 0x88000000,
5996 0x8a8a88aa,
5997 0x8aa88888,
5998 0x8888a8a8,
5999 0x8a88aa80,
6000 0x8aaaaa8a,
6001 0x8a8a8aa8,
6002 0x00000888,
6003 0x88000000,
6004 0x8a8a88aa,
6005 0x8aa88888,
6006 0x8888a8a8,
6007 0x8a88aa80,
6008 0x8aaaaa8a,
6009 0x8a8a8aa8,
6010 0x00000888,
6011 0x00000000,
6012 0x00000000,
6013 0x00000000,
6014 0x00000000,
6015 0x00000000,
6016 0x00000000,
6017 0x00000000,
6018 0x00000000,
6019 0x00000000,
6020 0x00000000,
6021 0x00000000,
6022 0x00000000,
6023 0x00000000,
6024 0x00000000,
6025 0x00000000,
6026 0x00000000,
6027 0x00000000,
6028 0x00000000,
6029 0x00000000,
6030 0x00000000,
6031 0x00000000,
6032 0x00000000,
6033 0x00000000,
6034 0x00000000,
6035 0x00000000,
6036 0x00000000,
6037 0x00000000,
6038 0x00000000,
6039 0x00000000,
6040 0x00000000,
6041 0x00000000,
6042 0x00000000,
6043 0x00000000,
6044 0x00000000,
6045 0x00000000,
6046 0x00000000,
6047 0x00000000,
6048 0x00000000,
6049 0x00000000,
6050 0x00000000,
6051 0x00000000,
6052 0x00000000,
6053 0x00000000,
6054 0x00000000,
6055 0x00000000,
6056 0x00000000,
6057 0x00000000,
6058 0x00000000,
6059};
6060
6061static const u32 intlv_tbl_rev3[] = {
6062 0x00802070,
6063 0x0671188d,
6064 0x0a60192c,
6065 0x0a300e46,
6066 0x00c1188d,
6067 0x080024d2,
6068 0x00000070,
6069};
6070
6071static const u32 tdtrn_tbl_rev3[] = {
6072 0x061c061c,
6073 0x0050ee68,
6074 0xf592fe36,
6075 0xfe5212f6,
6076 0x00000c38,
6077 0xfe5212f6,
6078 0xf592fe36,
6079 0x0050ee68,
6080 0x061c061c,
6081 0xee680050,
6082 0xfe36f592,
6083 0x12f6fe52,
6084 0x0c380000,
6085 0x12f6fe52,
6086 0xfe36f592,
6087 0xee680050,
6088 0x061c061c,
6089 0x0050ee68,
6090 0xf592fe36,
6091 0xfe5212f6,
6092 0x00000c38,
6093 0xfe5212f6,
6094 0xf592fe36,
6095 0x0050ee68,
6096 0x061c061c,
6097 0xee680050,
6098 0xfe36f592,
6099 0x12f6fe52,
6100 0x0c380000,
6101 0x12f6fe52,
6102 0xfe36f592,
6103 0xee680050,
6104 0x05e305e3,
6105 0x004def0c,
6106 0xf5f3fe47,
6107 0xfe611246,
6108 0x00000bc7,
6109 0xfe611246,
6110 0xf5f3fe47,
6111 0x004def0c,
6112 0x05e305e3,
6113 0xef0c004d,
6114 0xfe47f5f3,
6115 0x1246fe61,
6116 0x0bc70000,
6117 0x1246fe61,
6118 0xfe47f5f3,
6119 0xef0c004d,
6120 0x05e305e3,
6121 0x004def0c,
6122 0xf5f3fe47,
6123 0xfe611246,
6124 0x00000bc7,
6125 0xfe611246,
6126 0xf5f3fe47,
6127 0x004def0c,
6128 0x05e305e3,
6129 0xef0c004d,
6130 0xfe47f5f3,
6131 0x1246fe61,
6132 0x0bc70000,
6133 0x1246fe61,
6134 0xfe47f5f3,
6135 0xef0c004d,
6136 0xfa58fa58,
6137 0xf895043b,
6138 0xff4c09c0,
6139 0xfbc6ffa8,
6140 0xfb84f384,
6141 0x0798f6f9,
6142 0x05760122,
6143 0x058409f6,
6144 0x0b500000,
6145 0x05b7f542,
6146 0x08860432,
6147 0x06ddfee7,
6148 0xfb84f384,
6149 0xf9d90664,
6150 0xf7e8025c,
6151 0x00fff7bd,
6152 0x05a805a8,
6153 0xf7bd00ff,
6154 0x025cf7e8,
6155 0x0664f9d9,
6156 0xf384fb84,
6157 0xfee706dd,
6158 0x04320886,
6159 0xf54205b7,
6160 0x00000b50,
6161 0x09f60584,
6162 0x01220576,
6163 0xf6f90798,
6164 0xf384fb84,
6165 0xffa8fbc6,
6166 0x09c0ff4c,
6167 0x043bf895,
6168 0x02d402d4,
6169 0x07de0270,
6170 0xfc96079c,
6171 0xf90afe94,
6172 0xfe00ff2c,
6173 0x02d4065d,
6174 0x092a0096,
6175 0x0014fbb8,
6176 0xfd2cfd2c,
6177 0x076afb3c,
6178 0x0096f752,
6179 0xf991fd87,
6180 0xfb2c0200,
6181 0xfeb8f960,
6182 0x08e0fc96,
6183 0x049802a8,
6184 0xfd2cfd2c,
6185 0x02a80498,
6186 0xfc9608e0,
6187 0xf960feb8,
6188 0x0200fb2c,
6189 0xfd87f991,
6190 0xf7520096,
6191 0xfb3c076a,
6192 0xfd2cfd2c,
6193 0xfbb80014,
6194 0x0096092a,
6195 0x065d02d4,
6196 0xff2cfe00,
6197 0xfe94f90a,
6198 0x079cfc96,
6199 0x027007de,
6200 0x02d402d4,
6201 0x027007de,
6202 0x079cfc96,
6203 0xfe94f90a,
6204 0xff2cfe00,
6205 0x065d02d4,
6206 0x0096092a,
6207 0xfbb80014,
6208 0xfd2cfd2c,
6209 0xfb3c076a,
6210 0xf7520096,
6211 0xfd87f991,
6212 0x0200fb2c,
6213 0xf960feb8,
6214 0xfc9608e0,
6215 0x02a80498,
6216 0xfd2cfd2c,
6217 0x049802a8,
6218 0x08e0fc96,
6219 0xfeb8f960,
6220 0xfb2c0200,
6221 0xf991fd87,
6222 0x0096f752,
6223 0x076afb3c,
6224 0xfd2cfd2c,
6225 0x0014fbb8,
6226 0x092a0096,
6227 0x02d4065d,
6228 0xfe00ff2c,
6229 0xf90afe94,
6230 0xfc96079c,
6231 0x07de0270,
6232 0x00000000,
6233 0x00000000,
6234 0x00000000,
6235 0x00000000,
6236 0x00000000,
6237 0x00000000,
6238 0x00000000,
6239 0x00000000,
6240 0x00000000,
6241 0x00000000,
6242 0x00000000,
6243 0x00000000,
6244 0x00000000,
6245 0x00000000,
6246 0x00000000,
6247 0x00000000,
6248 0x00000000,
6249 0x00000000,
6250 0x00000000,
6251 0x00000000,
6252 0x00000000,
6253 0x00000000,
6254 0x00000000,
6255 0x00000000,
6256 0x00000000,
6257 0x00000000,
6258 0x00000000,
6259 0x00000000,
6260 0x00000000,
6261 0x00000000,
6262 0x00000000,
6263 0x00000000,
6264 0x00000000,
6265 0x00000000,
6266 0x00000000,
6267 0x00000000,
6268 0x00000000,
6269 0x00000000,
6270 0x00000000,
6271 0x00000000,
6272 0x00000000,
6273 0x00000000,
6274 0x00000000,
6275 0x00000000,
6276 0x00000000,
6277 0x00000000,
6278 0x00000000,
6279 0x00000000,
6280 0x00000000,
6281 0x00000000,
6282 0x00000000,
6283 0x00000000,
6284 0x00000000,
6285 0x00000000,
6286 0x00000000,
6287 0x00000000,
6288 0x00000000,
6289 0x00000000,
6290 0x00000000,
6291 0x00000000,
6292 0x00000000,
6293 0x00000000,
6294 0x00000000,
6295 0x00000000,
6296 0x00000000,
6297 0x00000000,
6298 0x00000000,
6299 0x00000000,
6300 0x00000000,
6301 0x00000000,
6302 0x00000000,
6303 0x00000000,
6304 0x00000000,
6305 0x00000000,
6306 0x00000000,
6307 0x00000000,
6308 0x00000000,
6309 0x00000000,
6310 0x00000000,
6311 0x00000000,
6312 0x00000000,
6313 0x00000000,
6314 0x00000000,
6315 0x00000000,
6316 0x00000000,
6317 0x00000000,
6318 0x00000000,
6319 0x00000000,
6320 0x00000000,
6321 0x00000000,
6322 0x00000000,
6323 0x00000000,
6324 0x00000000,
6325 0x00000000,
6326 0x00000000,
6327 0x00000000,
6328 0x062a0000,
6329 0xfefa0759,
6330 0x08b80908,
6331 0xf396fc2d,
6332 0xf9d6045c,
6333 0xfc4ef608,
6334 0xf748f596,
6335 0x07b207bf,
6336 0x062a062a,
6337 0xf84ef841,
6338 0xf748f596,
6339 0x03b209f8,
6340 0xf9d6045c,
6341 0x0c6a03d3,
6342 0x08b80908,
6343 0x0106f8a7,
6344 0x062a0000,
6345 0xfefaf8a7,
6346 0x08b8f6f8,
6347 0xf39603d3,
6348 0xf9d6fba4,
6349 0xfc4e09f8,
6350 0xf7480a6a,
6351 0x07b2f841,
6352 0x062af9d6,
6353 0xf84e07bf,
6354 0xf7480a6a,
6355 0x03b2f608,
6356 0xf9d6fba4,
6357 0x0c6afc2d,
6358 0x08b8f6f8,
6359 0x01060759,
6360 0x062a0000,
6361 0xfefa0759,
6362 0x08b80908,
6363 0xf396fc2d,
6364 0xf9d6045c,
6365 0xfc4ef608,
6366 0xf748f596,
6367 0x07b207bf,
6368 0x062a062a,
6369 0xf84ef841,
6370 0xf748f596,
6371 0x03b209f8,
6372 0xf9d6045c,
6373 0x0c6a03d3,
6374 0x08b80908,
6375 0x0106f8a7,
6376 0x062a0000,
6377 0xfefaf8a7,
6378 0x08b8f6f8,
6379 0xf39603d3,
6380 0xf9d6fba4,
6381 0xfc4e09f8,
6382 0xf7480a6a,
6383 0x07b2f841,
6384 0x062af9d6,
6385 0xf84e07bf,
6386 0xf7480a6a,
6387 0x03b2f608,
6388 0xf9d6fba4,
6389 0x0c6afc2d,
6390 0x08b8f6f8,
6391 0x01060759,
6392 0x061c061c,
6393 0xff30009d,
6394 0xffb21141,
6395 0xfd87fb54,
6396 0xf65dfe59,
6397 0x02eef99e,
6398 0x0166f03c,
6399 0xfff809b6,
6400 0x000008a4,
6401 0x000af42b,
6402 0x00eff577,
6403 0xfa840bf2,
6404 0xfc02ff51,
6405 0x08260f67,
6406 0xfff0036f,
6407 0x0842f9c3,
6408 0x00000000,
6409 0x063df7be,
6410 0xfc910010,
6411 0xf099f7da,
6412 0x00af03fe,
6413 0xf40e057c,
6414 0x0a89ff11,
6415 0x0bd5fff6,
6416 0xf75c0000,
6417 0xf64a0008,
6418 0x0fc4fe9a,
6419 0x0662fd12,
6420 0x01a709a3,
6421 0x04ac0279,
6422 0xeebf004e,
6423 0xff6300d0,
6424 0xf9e4f9e4,
6425 0x00d0ff63,
6426 0x004eeebf,
6427 0x027904ac,
6428 0x09a301a7,
6429 0xfd120662,
6430 0xfe9a0fc4,
6431 0x0008f64a,
6432 0x0000f75c,
6433 0xfff60bd5,
6434 0xff110a89,
6435 0x057cf40e,
6436 0x03fe00af,
6437 0xf7daf099,
6438 0x0010fc91,
6439 0xf7be063d,
6440 0x00000000,
6441 0xf9c30842,
6442 0x036ffff0,
6443 0x0f670826,
6444 0xff51fc02,
6445 0x0bf2fa84,
6446 0xf57700ef,
6447 0xf42b000a,
6448 0x08a40000,
6449 0x09b6fff8,
6450 0xf03c0166,
6451 0xf99e02ee,
6452 0xfe59f65d,
6453 0xfb54fd87,
6454 0x1141ffb2,
6455 0x009dff30,
6456 0x05e30000,
6457 0xff060705,
6458 0x085408a0,
6459 0xf425fc59,
6460 0xfa1d042a,
6461 0xfc78f67a,
6462 0xf7acf60e,
6463 0x075a0766,
6464 0x05e305e3,
6465 0xf8a6f89a,
6466 0xf7acf60e,
6467 0x03880986,
6468 0xfa1d042a,
6469 0x0bdb03a7,
6470 0x085408a0,
6471 0x00faf8fb,
6472 0x05e30000,
6473 0xff06f8fb,
6474 0x0854f760,
6475 0xf42503a7,
6476 0xfa1dfbd6,
6477 0xfc780986,
6478 0xf7ac09f2,
6479 0x075af89a,
6480 0x05e3fa1d,
6481 0xf8a60766,
6482 0xf7ac09f2,
6483 0x0388f67a,
6484 0xfa1dfbd6,
6485 0x0bdbfc59,
6486 0x0854f760,
6487 0x00fa0705,
6488 0x05e30000,
6489 0xff060705,
6490 0x085408a0,
6491 0xf425fc59,
6492 0xfa1d042a,
6493 0xfc78f67a,
6494 0xf7acf60e,
6495 0x075a0766,
6496 0x05e305e3,
6497 0xf8a6f89a,
6498 0xf7acf60e,
6499 0x03880986,
6500 0xfa1d042a,
6501 0x0bdb03a7,
6502 0x085408a0,
6503 0x00faf8fb,
6504 0x05e30000,
6505 0xff06f8fb,
6506 0x0854f760,
6507 0xf42503a7,
6508 0xfa1dfbd6,
6509 0xfc780986,
6510 0xf7ac09f2,
6511 0x075af89a,
6512 0x05e3fa1d,
6513 0xf8a60766,
6514 0xf7ac09f2,
6515 0x0388f67a,
6516 0xfa1dfbd6,
6517 0x0bdbfc59,
6518 0x0854f760,
6519 0x00fa0705,
6520 0xfa58fa58,
6521 0xf8f0fe00,
6522 0x0448073d,
6523 0xfdc9fe46,
6524 0xf9910258,
6525 0x089d0407,
6526 0xfd5cf71a,
6527 0x02affde0,
6528 0x083e0496,
6529 0xff5a0740,
6530 0xff7afd97,
6531 0x00fe01f1,
6532 0x0009082e,
6533 0xfa94ff75,
6534 0xfecdf8ea,
6535 0xffb0f693,
6536 0xfd2cfa58,
6537 0x0433ff16,
6538 0xfba405dd,
6539 0xfa610341,
6540 0x06a606cb,
6541 0x0039fd2d,
6542 0x0677fa97,
6543 0x01fa05e0,
6544 0xf896003e,
6545 0x075a068b,
6546 0x012cfc3e,
6547 0xfa23f98d,
6548 0xfc7cfd43,
6549 0xff90fc0d,
6550 0x01c10982,
6551 0x00c601d6,
6552 0xfd2cfd2c,
6553 0x01d600c6,
6554 0x098201c1,
6555 0xfc0dff90,
6556 0xfd43fc7c,
6557 0xf98dfa23,
6558 0xfc3e012c,
6559 0x068b075a,
6560 0x003ef896,
6561 0x05e001fa,
6562 0xfa970677,
6563 0xfd2d0039,
6564 0x06cb06a6,
6565 0x0341fa61,
6566 0x05ddfba4,
6567 0xff160433,
6568 0xfa58fd2c,
6569 0xf693ffb0,
6570 0xf8eafecd,
6571 0xff75fa94,
6572 0x082e0009,
6573 0x01f100fe,
6574 0xfd97ff7a,
6575 0x0740ff5a,
6576 0x0496083e,
6577 0xfde002af,
6578 0xf71afd5c,
6579 0x0407089d,
6580 0x0258f991,
6581 0xfe46fdc9,
6582 0x073d0448,
6583 0xfe00f8f0,
6584 0xfd2cfd2c,
6585 0xfce00500,
6586 0xfc09fddc,
6587 0xfe680157,
6588 0x04c70571,
6589 0xfc3aff21,
6590 0xfcd70228,
6591 0x056d0277,
6592 0x0200fe00,
6593 0x0022f927,
6594 0xfe3c032b,
6595 0xfc44ff3c,
6596 0x03e9fbdb,
6597 0x04570313,
6598 0x04c9ff5c,
6599 0x000d03b8,
6600 0xfa580000,
6601 0xfbe900d2,
6602 0xf9d0fe0b,
6603 0x0125fdf9,
6604 0x042501bf,
6605 0x0328fa2b,
6606 0xffa902f0,
6607 0xfa250157,
6608 0x0200fe00,
6609 0x03740438,
6610 0xff0405fd,
6611 0x030cfe52,
6612 0x0037fb39,
6613 0xff6904c5,
6614 0x04f8fd23,
6615 0xfd31fc1b,
6616 0xfd2cfd2c,
6617 0xfc1bfd31,
6618 0xfd2304f8,
6619 0x04c5ff69,
6620 0xfb390037,
6621 0xfe52030c,
6622 0x05fdff04,
6623 0x04380374,
6624 0xfe000200,
6625 0x0157fa25,
6626 0x02f0ffa9,
6627 0xfa2b0328,
6628 0x01bf0425,
6629 0xfdf90125,
6630 0xfe0bf9d0,
6631 0x00d2fbe9,
6632 0x0000fa58,
6633 0x03b8000d,
6634 0xff5c04c9,
6635 0x03130457,
6636 0xfbdb03e9,
6637 0xff3cfc44,
6638 0x032bfe3c,
6639 0xf9270022,
6640 0xfe000200,
6641 0x0277056d,
6642 0x0228fcd7,
6643 0xff21fc3a,
6644 0x057104c7,
6645 0x0157fe68,
6646 0xfddcfc09,
6647 0x0500fce0,
6648 0xfd2cfd2c,
6649 0x0500fce0,
6650 0xfddcfc09,
6651 0x0157fe68,
6652 0x057104c7,
6653 0xff21fc3a,
6654 0x0228fcd7,
6655 0x0277056d,
6656 0xfe000200,
6657 0xf9270022,
6658 0x032bfe3c,
6659 0xff3cfc44,
6660 0xfbdb03e9,
6661 0x03130457,
6662 0xff5c04c9,
6663 0x03b8000d,
6664 0x0000fa58,
6665 0x00d2fbe9,
6666 0xfe0bf9d0,
6667 0xfdf90125,
6668 0x01bf0425,
6669 0xfa2b0328,
6670 0x02f0ffa9,
6671 0x0157fa25,
6672 0xfe000200,
6673 0x04380374,
6674 0x05fdff04,
6675 0xfe52030c,
6676 0xfb390037,
6677 0x04c5ff69,
6678 0xfd2304f8,
6679 0xfc1bfd31,
6680 0xfd2cfd2c,
6681 0xfd31fc1b,
6682 0x04f8fd23,
6683 0xff6904c5,
6684 0x0037fb39,
6685 0x030cfe52,
6686 0xff0405fd,
6687 0x03740438,
6688 0x0200fe00,
6689 0xfa250157,
6690 0xffa902f0,
6691 0x0328fa2b,
6692 0x042501bf,
6693 0x0125fdf9,
6694 0xf9d0fe0b,
6695 0xfbe900d2,
6696 0xfa580000,
6697 0x000d03b8,
6698 0x04c9ff5c,
6699 0x04570313,
6700 0x03e9fbdb,
6701 0xfc44ff3c,
6702 0xfe3c032b,
6703 0x0022f927,
6704 0x0200fe00,
6705 0x056d0277,
6706 0xfcd70228,
6707 0xfc3aff21,
6708 0x04c70571,
6709 0xfe680157,
6710 0xfc09fddc,
6711 0xfce00500,
6712 0x05a80000,
6713 0xff1006be,
6714 0x0800084a,
6715 0xf49cfc7e,
6716 0xfa580400,
6717 0xfc9cf6da,
6718 0xf800f672,
6719 0x0710071c,
6720 0x05a805a8,
6721 0xf8f0f8e4,
6722 0xf800f672,
6723 0x03640926,
6724 0xfa580400,
6725 0x0b640382,
6726 0x0800084a,
6727 0x00f0f942,
6728 0x05a80000,
6729 0xff10f942,
6730 0x0800f7b6,
6731 0xf49c0382,
6732 0xfa58fc00,
6733 0xfc9c0926,
6734 0xf800098e,
6735 0x0710f8e4,
6736 0x05a8fa58,
6737 0xf8f0071c,
6738 0xf800098e,
6739 0x0364f6da,
6740 0xfa58fc00,
6741 0x0b64fc7e,
6742 0x0800f7b6,
6743 0x00f006be,
6744 0x05a80000,
6745 0xff1006be,
6746 0x0800084a,
6747 0xf49cfc7e,
6748 0xfa580400,
6749 0xfc9cf6da,
6750 0xf800f672,
6751 0x0710071c,
6752 0x05a805a8,
6753 0xf8f0f8e4,
6754 0xf800f672,
6755 0x03640926,
6756 0xfa580400,
6757 0x0b640382,
6758 0x0800084a,
6759 0x00f0f942,
6760 0x05a80000,
6761 0xff10f942,
6762 0x0800f7b6,
6763 0xf49c0382,
6764 0xfa58fc00,
6765 0xfc9c0926,
6766 0xf800098e,
6767 0x0710f8e4,
6768 0x05a8fa58,
6769 0xf8f0071c,
6770 0xf800098e,
6771 0x0364f6da,
6772 0xfa58fc00,
6773 0x0b64fc7e,
6774 0x0800f7b6,
6775 0x00f006be,
6776};
6777
6778const u32 noise_var_tbl_rev3[] = {
6779 0x02110211,
6780 0x0000014d,
6781 0x02110211,
6782 0x0000014d,
6783 0x02110211,
6784 0x0000014d,
6785 0x02110211,
6786 0x0000014d,
6787 0x02110211,
6788 0x0000014d,
6789 0x02110211,
6790 0x0000014d,
6791 0x02110211,
6792 0x0000014d,
6793 0x02110211,
6794 0x0000014d,
6795 0x02110211,
6796 0x0000014d,
6797 0x02110211,
6798 0x0000014d,
6799 0x02110211,
6800 0x0000014d,
6801 0x02110211,
6802 0x0000014d,
6803 0x02110211,
6804 0x0000014d,
6805 0x02110211,
6806 0x0000014d,
6807 0x02110211,
6808 0x0000014d,
6809 0x02110211,
6810 0x0000014d,
6811 0x02110211,
6812 0x0000014d,
6813 0x02110211,
6814 0x0000014d,
6815 0x02110211,
6816 0x0000014d,
6817 0x02110211,
6818 0x0000014d,
6819 0x02110211,
6820 0x0000014d,
6821 0x02110211,
6822 0x0000014d,
6823 0x02110211,
6824 0x0000014d,
6825 0x02110211,
6826 0x0000014d,
6827 0x02110211,
6828 0x0000014d,
6829 0x02110211,
6830 0x0000014d,
6831 0x02110211,
6832 0x0000014d,
6833 0x02110211,
6834 0x0000014d,
6835 0x02110211,
6836 0x0000014d,
6837 0x02110211,
6838 0x0000014d,
6839 0x02110211,
6840 0x0000014d,
6841 0x02110211,
6842 0x0000014d,
6843 0x02110211,
6844 0x0000014d,
6845 0x02110211,
6846 0x0000014d,
6847 0x02110211,
6848 0x0000014d,
6849 0x02110211,
6850 0x0000014d,
6851 0x02110211,
6852 0x0000014d,
6853 0x02110211,
6854 0x0000014d,
6855 0x02110211,
6856 0x0000014d,
6857 0x02110211,
6858 0x0000014d,
6859 0x02110211,
6860 0x0000014d,
6861 0x02110211,
6862 0x0000014d,
6863 0x02110211,
6864 0x0000014d,
6865 0x02110211,
6866 0x0000014d,
6867 0x02110211,
6868 0x0000014d,
6869 0x02110211,
6870 0x0000014d,
6871 0x02110211,
6872 0x0000014d,
6873 0x02110211,
6874 0x0000014d,
6875 0x02110211,
6876 0x0000014d,
6877 0x02110211,
6878 0x0000014d,
6879 0x02110211,
6880 0x0000014d,
6881 0x02110211,
6882 0x0000014d,
6883 0x02110211,
6884 0x0000014d,
6885 0x02110211,
6886 0x0000014d,
6887 0x02110211,
6888 0x0000014d,
6889 0x02110211,
6890 0x0000014d,
6891 0x02110211,
6892 0x0000014d,
6893 0x02110211,
6894 0x0000014d,
6895 0x02110211,
6896 0x0000014d,
6897 0x02110211,
6898 0x0000014d,
6899 0x02110211,
6900 0x0000014d,
6901 0x02110211,
6902 0x0000014d,
6903 0x02110211,
6904 0x0000014d,
6905 0x02110211,
6906 0x0000014d,
6907 0x02110211,
6908 0x0000014d,
6909 0x02110211,
6910 0x0000014d,
6911 0x02110211,
6912 0x0000014d,
6913 0x02110211,
6914 0x0000014d,
6915 0x02110211,
6916 0x0000014d,
6917 0x02110211,
6918 0x0000014d,
6919 0x02110211,
6920 0x0000014d,
6921 0x02110211,
6922 0x0000014d,
6923 0x02110211,
6924 0x0000014d,
6925 0x02110211,
6926 0x0000014d,
6927 0x02110211,
6928 0x0000014d,
6929 0x02110211,
6930 0x0000014d,
6931 0x02110211,
6932 0x0000014d,
6933 0x02110211,
6934 0x0000014d,
6935 0x02110211,
6936 0x0000014d,
6937 0x02110211,
6938 0x0000014d,
6939 0x02110211,
6940 0x0000014d,
6941 0x02110211,
6942 0x0000014d,
6943 0x02110211,
6944 0x0000014d,
6945 0x02110211,
6946 0x0000014d,
6947 0x02110211,
6948 0x0000014d,
6949 0x02110211,
6950 0x0000014d,
6951 0x02110211,
6952 0x0000014d,
6953 0x02110211,
6954 0x0000014d,
6955 0x02110211,
6956 0x0000014d,
6957 0x02110211,
6958 0x0000014d,
6959 0x02110211,
6960 0x0000014d,
6961 0x02110211,
6962 0x0000014d,
6963 0x02110211,
6964 0x0000014d,
6965 0x02110211,
6966 0x0000014d,
6967 0x02110211,
6968 0x0000014d,
6969 0x02110211,
6970 0x0000014d,
6971 0x02110211,
6972 0x0000014d,
6973 0x02110211,
6974 0x0000014d,
6975 0x02110211,
6976 0x0000014d,
6977 0x02110211,
6978 0x0000014d,
6979 0x02110211,
6980 0x0000014d,
6981 0x02110211,
6982 0x0000014d,
6983 0x02110211,
6984 0x0000014d,
6985 0x02110211,
6986 0x0000014d,
6987 0x02110211,
6988 0x0000014d,
6989 0x02110211,
6990 0x0000014d,
6991 0x02110211,
6992 0x0000014d,
6993 0x02110211,
6994 0x0000014d,
6995 0x02110211,
6996 0x0000014d,
6997 0x02110211,
6998 0x0000014d,
6999 0x02110211,
7000 0x0000014d,
7001 0x02110211,
7002 0x0000014d,
7003 0x02110211,
7004 0x0000014d,
7005 0x02110211,
7006 0x0000014d,
7007 0x02110211,
7008 0x0000014d,
7009 0x02110211,
7010 0x0000014d,
7011 0x02110211,
7012 0x0000014d,
7013 0x02110211,
7014 0x0000014d,
7015 0x02110211,
7016 0x0000014d,
7017 0x02110211,
7018 0x0000014d,
7019 0x02110211,
7020 0x0000014d,
7021 0x02110211,
7022 0x0000014d,
7023 0x02110211,
7024 0x0000014d,
7025 0x02110211,
7026 0x0000014d,
7027 0x02110211,
7028 0x0000014d,
7029 0x02110211,
7030 0x0000014d,
7031 0x02110211,
7032 0x0000014d,
7033 0x02110211,
7034 0x0000014d,
7035};
7036
7037static const u16 mcs_tbl_rev3[] = {
7038 0x0000,
7039 0x0008,
7040 0x000a,
7041 0x0010,
7042 0x0012,
7043 0x0019,
7044 0x001a,
7045 0x001c,
7046 0x0080,
7047 0x0088,
7048 0x008a,
7049 0x0090,
7050 0x0092,
7051 0x0099,
7052 0x009a,
7053 0x009c,
7054 0x0100,
7055 0x0108,
7056 0x010a,
7057 0x0110,
7058 0x0112,
7059 0x0119,
7060 0x011a,
7061 0x011c,
7062 0x0180,
7063 0x0188,
7064 0x018a,
7065 0x0190,
7066 0x0192,
7067 0x0199,
7068 0x019a,
7069 0x019c,
7070 0x0000,
7071 0x0098,
7072 0x00a0,
7073 0x00a8,
7074 0x009a,
7075 0x00a2,
7076 0x00aa,
7077 0x0120,
7078 0x0128,
7079 0x0128,
7080 0x0130,
7081 0x0138,
7082 0x0138,
7083 0x0140,
7084 0x0122,
7085 0x012a,
7086 0x012a,
7087 0x0132,
7088 0x013a,
7089 0x013a,
7090 0x0142,
7091 0x01a8,
7092 0x01b0,
7093 0x01b8,
7094 0x01b0,
7095 0x01b8,
7096 0x01c0,
7097 0x01c8,
7098 0x01c0,
7099 0x01c8,
7100 0x01d0,
7101 0x01d0,
7102 0x01d8,
7103 0x01aa,
7104 0x01b2,
7105 0x01ba,
7106 0x01b2,
7107 0x01ba,
7108 0x01c2,
7109 0x01ca,
7110 0x01c2,
7111 0x01ca,
7112 0x01d2,
7113 0x01d2,
7114 0x01da,
7115 0x0001,
7116 0x0002,
7117 0x0004,
7118 0x0009,
7119 0x000c,
7120 0x0011,
7121 0x0014,
7122 0x0018,
7123 0x0020,
7124 0x0021,
7125 0x0022,
7126 0x0024,
7127 0x0081,
7128 0x0082,
7129 0x0084,
7130 0x0089,
7131 0x008c,
7132 0x0091,
7133 0x0094,
7134 0x0098,
7135 0x00a0,
7136 0x00a1,
7137 0x00a2,
7138 0x00a4,
7139 0x0007,
7140 0x0007,
7141 0x0007,
7142 0x0007,
7143 0x0007,
7144 0x0007,
7145 0x0007,
7146 0x0007,
7147 0x0007,
7148 0x0007,
7149 0x0007,
7150 0x0007,
7151 0x0007,
7152 0x0007,
7153 0x0007,
7154 0x0007,
7155 0x0007,
7156 0x0007,
7157 0x0007,
7158 0x0007,
7159 0x0007,
7160 0x0007,
7161 0x0007,
7162 0x0007,
7163 0x0007,
7164 0x0007,
7165 0x0007,
7166};
7167
7168static const u32 tdi_tbl20_ant0_rev3[] = {
7169 0x00091226,
7170 0x000a1429,
7171 0x000b56ad,
7172 0x000c58b0,
7173 0x000d5ab3,
7174 0x000e9cb6,
7175 0x000f9eba,
7176 0x0000c13d,
7177 0x00020301,
7178 0x00030504,
7179 0x00040708,
7180 0x0005090b,
7181 0x00064b8e,
7182 0x00095291,
7183 0x000a5494,
7184 0x000b9718,
7185 0x000c9927,
7186 0x000d9b2a,
7187 0x000edd2e,
7188 0x000fdf31,
7189 0x000101b4,
7190 0x000243b7,
7191 0x000345bb,
7192 0x000447be,
7193 0x00058982,
7194 0x00068c05,
7195 0x00099309,
7196 0x000a950c,
7197 0x000bd78f,
7198 0x000cd992,
7199 0x000ddb96,
7200 0x000f1d99,
7201 0x00005fa8,
7202 0x0001422c,
7203 0x0002842f,
7204 0x00038632,
7205 0x00048835,
7206 0x0005ca38,
7207 0x0006ccbc,
7208 0x0009d3bf,
7209 0x000b1603,
7210 0x000c1806,
7211 0x000d1a0a,
7212 0x000e1c0d,
7213 0x000f5e10,
7214 0x00008093,
7215 0x00018297,
7216 0x0002c49a,
7217 0x0003c680,
7218 0x0004c880,
7219 0x00060b00,
7220 0x00070d00,
7221 0x00000000,
7222 0x00000000,
7223 0x00000000,
7224};
7225
7226static const u32 tdi_tbl20_ant1_rev3[] = {
7227 0x00014b26,
7228 0x00028d29,
7229 0x000393ad,
7230 0x00049630,
7231 0x0005d833,
7232 0x0006da36,
7233 0x00099c3a,
7234 0x000a9e3d,
7235 0x000bc081,
7236 0x000cc284,
7237 0x000dc488,
7238 0x000f068b,
7239 0x0000488e,
7240 0x00018b91,
7241 0x0002d214,
7242 0x0003d418,
7243 0x0004d6a7,
7244 0x000618aa,
7245 0x00071aae,
7246 0x0009dcb1,
7247 0x000b1eb4,
7248 0x000c0137,
7249 0x000d033b,
7250 0x000e053e,
7251 0x000f4702,
7252 0x00008905,
7253 0x00020c09,
7254 0x0003128c,
7255 0x0004148f,
7256 0x00051712,
7257 0x00065916,
7258 0x00091b19,
7259 0x000a1d28,
7260 0x000b5f2c,
7261 0x000c41af,
7262 0x000d43b2,
7263 0x000e85b5,
7264 0x000f87b8,
7265 0x0000c9bc,
7266 0x00024cbf,
7267 0x00035303,
7268 0x00045506,
7269 0x0005978a,
7270 0x0006998d,
7271 0x00095b90,
7272 0x000a5d93,
7273 0x000b9f97,
7274 0x000c821a,
7275 0x000d8400,
7276 0x000ec600,
7277 0x000fc800,
7278 0x00010a00,
7279 0x00000000,
7280 0x00000000,
7281 0x00000000,
7282};
7283
7284static const u32 tdi_tbl40_ant0_rev3[] = {
7285 0x0011a346,
7286 0x00136ccf,
7287 0x0014f5d9,
7288 0x001641e2,
7289 0x0017cb6b,
7290 0x00195475,
7291 0x001b2383,
7292 0x001cad0c,
7293 0x001e7616,
7294 0x0000821f,
7295 0x00020ba8,
7296 0x0003d4b2,
7297 0x00056447,
7298 0x00072dd0,
7299 0x0008b6da,
7300 0x000a02e3,
7301 0x000b8c6c,
7302 0x000d15f6,
7303 0x0011e484,
7304 0x0013ae0d,
7305 0x00153717,
7306 0x00168320,
7307 0x00180ca9,
7308 0x00199633,
7309 0x001b6548,
7310 0x001ceed1,
7311 0x001eb7db,
7312 0x0000c3e4,
7313 0x00024d6d,
7314 0x000416f7,
7315 0x0005a585,
7316 0x00076f0f,
7317 0x0008f818,
7318 0x000a4421,
7319 0x000bcdab,
7320 0x000d9734,
7321 0x00122649,
7322 0x0013efd2,
7323 0x001578dc,
7324 0x0016c4e5,
7325 0x00184e6e,
7326 0x001a17f8,
7327 0x001ba686,
7328 0x001d3010,
7329 0x001ef999,
7330 0x00010522,
7331 0x00028eac,
7332 0x00045835,
7333 0x0005e74a,
7334 0x0007b0d3,
7335 0x00093a5d,
7336 0x000a85e6,
7337 0x000c0f6f,
7338 0x000dd8f9,
7339 0x00126787,
7340 0x00143111,
7341 0x0015ba9a,
7342 0x00170623,
7343 0x00188fad,
7344 0x001a5936,
7345 0x001be84b,
7346 0x001db1d4,
7347 0x001f3b5e,
7348 0x000146e7,
7349 0x00031070,
7350 0x000499fa,
7351 0x00062888,
7352 0x0007f212,
7353 0x00097b9b,
7354 0x000ac7a4,
7355 0x000c50ae,
7356 0x000e1a37,
7357 0x0012a94c,
7358 0x001472d5,
7359 0x0015fc5f,
7360 0x00174868,
7361 0x0018d171,
7362 0x001a9afb,
7363 0x001c2989,
7364 0x001df313,
7365 0x001f7c9c,
7366 0x000188a5,
7367 0x000351af,
7368 0x0004db38,
7369 0x0006aa4d,
7370 0x000833d7,
7371 0x0009bd60,
7372 0x000b0969,
7373 0x000c9273,
7374 0x000e5bfc,
7375 0x00132a8a,
7376 0x0014b414,
7377 0x00163d9d,
7378 0x001789a6,
7379 0x001912b0,
7380 0x001adc39,
7381 0x001c6bce,
7382 0x001e34d8,
7383 0x001fbe61,
7384 0x0001ca6a,
7385 0x00039374,
7386 0x00051cfd,
7387 0x0006ec0b,
7388 0x00087515,
7389 0x0009fe9e,
7390 0x000b4aa7,
7391 0x000cd3b1,
7392 0x000e9d3a,
7393 0x00000000,
7394 0x00000000,
7395};
7396
7397static const u32 tdi_tbl40_ant1_rev3[] = {
7398 0x001edb36,
7399 0x000129ca,
7400 0x0002b353,
7401 0x00047cdd,
7402 0x0005c8e6,
7403 0x000791ef,
7404 0x00091bf9,
7405 0x000aaa07,
7406 0x000c3391,
7407 0x000dfd1a,
7408 0x00120923,
7409 0x0013d22d,
7410 0x00155c37,
7411 0x0016eacb,
7412 0x00187454,
7413 0x001a3dde,
7414 0x001b89e7,
7415 0x001d12f0,
7416 0x001f1cfa,
7417 0x00016b88,
7418 0x00033492,
7419 0x0004be1b,
7420 0x00060a24,
7421 0x0007d32e,
7422 0x00095d38,
7423 0x000aec4c,
7424 0x000c7555,
7425 0x000e3edf,
7426 0x00124ae8,
7427 0x001413f1,
7428 0x0015a37b,
7429 0x00172c89,
7430 0x0018b593,
7431 0x001a419c,
7432 0x001bcb25,
7433 0x001d942f,
7434 0x001f63b9,
7435 0x0001ad4d,
7436 0x00037657,
7437 0x0004c260,
7438 0x00068be9,
7439 0x000814f3,
7440 0x0009a47c,
7441 0x000b2d8a,
7442 0x000cb694,
7443 0x000e429d,
7444 0x00128c26,
7445 0x001455b0,
7446 0x0015e4ba,
7447 0x00176e4e,
7448 0x0018f758,
7449 0x001a8361,
7450 0x001c0cea,
7451 0x001dd674,
7452 0x001fa57d,
7453 0x0001ee8b,
7454 0x0003b795,
7455 0x0005039e,
7456 0x0006cd27,
7457 0x000856b1,
7458 0x0009e5c6,
7459 0x000b6f4f,
7460 0x000cf859,
7461 0x000e8462,
7462 0x00130deb,
7463 0x00149775,
7464 0x00162603,
7465 0x0017af8c,
7466 0x00193896,
7467 0x001ac49f,
7468 0x001c4e28,
7469 0x001e17b2,
7470 0x0000a6c7,
7471 0x00023050,
7472 0x0003f9da,
7473 0x00054563,
7474 0x00070eec,
7475 0x00089876,
7476 0x000a2704,
7477 0x000bb08d,
7478 0x000d3a17,
7479 0x001185a0,
7480 0x00134f29,
7481 0x0014d8b3,
7482 0x001667c8,
7483 0x0017f151,
7484 0x00197adb,
7485 0x001b0664,
7486 0x001c8fed,
7487 0x001e5977,
7488 0x0000e805,
7489 0x0002718f,
7490 0x00043b18,
7491 0x000586a1,
7492 0x0007502b,
7493 0x0008d9b4,
7494 0x000a68c9,
7495 0x000bf252,
7496 0x000dbbdc,
7497 0x0011c7e5,
7498 0x001390ee,
7499 0x00151a78,
7500 0x0016a906,
7501 0x00183290,
7502 0x0019bc19,
7503 0x001b4822,
7504 0x001cd12c,
7505 0x001e9ab5,
7506 0x00000000,
7507 0x00000000,
7508};
7509
7510static const u32 pltlut_tbl_rev3[] = {
7511 0x76540213,
7512 0x62407351,
7513 0x76543210,
7514 0x76540213,
7515 0x76540213,
7516 0x76430521,
7517};
7518
7519static const u32 chanest_tbl_rev3[] = {
7520 0x44444444,
7521 0x44444444,
7522 0x44444444,
7523 0x44444444,
7524 0x44444444,
7525 0x44444444,
7526 0x44444444,
7527 0x44444444,
7528 0x10101010,
7529 0x10101010,
7530 0x10101010,
7531 0x10101010,
7532 0x10101010,
7533 0x10101010,
7534 0x10101010,
7535 0x10101010,
7536 0x44444444,
7537 0x44444444,
7538 0x44444444,
7539 0x44444444,
7540 0x44444444,
7541 0x44444444,
7542 0x44444444,
7543 0x44444444,
7544 0x10101010,
7545 0x10101010,
7546 0x10101010,
7547 0x10101010,
7548 0x10101010,
7549 0x10101010,
7550 0x10101010,
7551 0x10101010,
7552 0x44444444,
7553 0x44444444,
7554 0x44444444,
7555 0x44444444,
7556 0x44444444,
7557 0x44444444,
7558 0x44444444,
7559 0x44444444,
7560 0x44444444,
7561 0x44444444,
7562 0x44444444,
7563 0x44444444,
7564 0x44444444,
7565 0x44444444,
7566 0x44444444,
7567 0x44444444,
7568 0x10101010,
7569 0x10101010,
7570 0x10101010,
7571 0x10101010,
7572 0x10101010,
7573 0x10101010,
7574 0x10101010,
7575 0x10101010,
7576 0x10101010,
7577 0x10101010,
7578 0x10101010,
7579 0x10101010,
7580 0x10101010,
7581 0x10101010,
7582 0x10101010,
7583 0x10101010,
7584 0x44444444,
7585 0x44444444,
7586 0x44444444,
7587 0x44444444,
7588 0x44444444,
7589 0x44444444,
7590 0x44444444,
7591 0x44444444,
7592 0x44444444,
7593 0x44444444,
7594 0x44444444,
7595 0x44444444,
7596 0x44444444,
7597 0x44444444,
7598 0x44444444,
7599 0x44444444,
7600 0x10101010,
7601 0x10101010,
7602 0x10101010,
7603 0x10101010,
7604 0x10101010,
7605 0x10101010,
7606 0x10101010,
7607 0x10101010,
7608 0x10101010,
7609 0x10101010,
7610 0x10101010,
7611 0x10101010,
7612 0x10101010,
7613 0x10101010,
7614 0x10101010,
7615 0x10101010,
7616};
7617
7618static const u8 frame_lut_rev3[] = {
7619 0x02,
7620 0x04,
7621 0x14,
7622 0x14,
7623 0x03,
7624 0x05,
7625 0x16,
7626 0x16,
7627 0x0a,
7628 0x0c,
7629 0x1c,
7630 0x1c,
7631 0x0b,
7632 0x0d,
7633 0x1e,
7634 0x1e,
7635 0x06,
7636 0x08,
7637 0x18,
7638 0x18,
7639 0x07,
7640 0x09,
7641 0x1a,
7642 0x1a,
7643 0x0e,
7644 0x10,
7645 0x20,
7646 0x28,
7647 0x0f,
7648 0x11,
7649 0x22,
7650 0x2a,
7651};
7652
7653static const u8 est_pwr_lut_core0_rev3[] = {
7654 0x55,
7655 0x54,
7656 0x54,
7657 0x53,
7658 0x52,
7659 0x52,
7660 0x51,
7661 0x51,
7662 0x50,
7663 0x4f,
7664 0x4f,
7665 0x4e,
7666 0x4e,
7667 0x4d,
7668 0x4c,
7669 0x4c,
7670 0x4b,
7671 0x4a,
7672 0x49,
7673 0x49,
7674 0x48,
7675 0x47,
7676 0x46,
7677 0x46,
7678 0x45,
7679 0x44,
7680 0x43,
7681 0x42,
7682 0x41,
7683 0x40,
7684 0x40,
7685 0x3f,
7686 0x3e,
7687 0x3d,
7688 0x3c,
7689 0x3a,
7690 0x39,
7691 0x38,
7692 0x37,
7693 0x36,
7694 0x35,
7695 0x33,
7696 0x32,
7697 0x31,
7698 0x2f,
7699 0x2e,
7700 0x2c,
7701 0x2b,
7702 0x29,
7703 0x27,
7704 0x25,
7705 0x23,
7706 0x21,
7707 0x1f,
7708 0x1d,
7709 0x1a,
7710 0x18,
7711 0x15,
7712 0x12,
7713 0x0e,
7714 0x0b,
7715 0x07,
7716 0x02,
7717 0xfd,
7718};
7719
7720static const u8 est_pwr_lut_core1_rev3[] = {
7721 0x55,
7722 0x54,
7723 0x54,
7724 0x53,
7725 0x52,
7726 0x52,
7727 0x51,
7728 0x51,
7729 0x50,
7730 0x4f,
7731 0x4f,
7732 0x4e,
7733 0x4e,
7734 0x4d,
7735 0x4c,
7736 0x4c,
7737 0x4b,
7738 0x4a,
7739 0x49,
7740 0x49,
7741 0x48,
7742 0x47,
7743 0x46,
7744 0x46,
7745 0x45,
7746 0x44,
7747 0x43,
7748 0x42,
7749 0x41,
7750 0x40,
7751 0x40,
7752 0x3f,
7753 0x3e,
7754 0x3d,
7755 0x3c,
7756 0x3a,
7757 0x39,
7758 0x38,
7759 0x37,
7760 0x36,
7761 0x35,
7762 0x33,
7763 0x32,
7764 0x31,
7765 0x2f,
7766 0x2e,
7767 0x2c,
7768 0x2b,
7769 0x29,
7770 0x27,
7771 0x25,
7772 0x23,
7773 0x21,
7774 0x1f,
7775 0x1d,
7776 0x1a,
7777 0x18,
7778 0x15,
7779 0x12,
7780 0x0e,
7781 0x0b,
7782 0x07,
7783 0x02,
7784 0xfd,
7785};
7786
7787static const u8 adj_pwr_lut_core0_rev3[] = {
7788 0x00,
7789 0x00,
7790 0x00,
7791 0x00,
7792 0x00,
7793 0x00,
7794 0x00,
7795 0x00,
7796 0x00,
7797 0x00,
7798 0x00,
7799 0x00,
7800 0x00,
7801 0x00,
7802 0x00,
7803 0x00,
7804 0x00,
7805 0x00,
7806 0x00,
7807 0x00,
7808 0x00,
7809 0x00,
7810 0x00,
7811 0x00,
7812 0x00,
7813 0x00,
7814 0x00,
7815 0x00,
7816 0x00,
7817 0x00,
7818 0x00,
7819 0x00,
7820 0x00,
7821 0x00,
7822 0x00,
7823 0x00,
7824 0x00,
7825 0x00,
7826 0x00,
7827 0x00,
7828 0x00,
7829 0x00,
7830 0x00,
7831 0x00,
7832 0x00,
7833 0x00,
7834 0x00,
7835 0x00,
7836 0x00,
7837 0x00,
7838 0x00,
7839 0x00,
7840 0x00,
7841 0x00,
7842 0x00,
7843 0x00,
7844 0x00,
7845 0x00,
7846 0x00,
7847 0x00,
7848 0x00,
7849 0x00,
7850 0x00,
7851 0x00,
7852 0x00,
7853 0x00,
7854 0x00,
7855 0x00,
7856 0x00,
7857 0x00,
7858 0x00,
7859 0x00,
7860 0x00,
7861 0x00,
7862 0x00,
7863 0x00,
7864 0x00,
7865 0x00,
7866 0x00,
7867 0x00,
7868 0x00,
7869 0x00,
7870 0x00,
7871 0x00,
7872 0x00,
7873 0x00,
7874 0x00,
7875 0x00,
7876 0x00,
7877 0x00,
7878 0x00,
7879 0x00,
7880 0x00,
7881 0x00,
7882 0x00,
7883 0x00,
7884 0x00,
7885 0x00,
7886 0x00,
7887 0x00,
7888 0x00,
7889 0x00,
7890 0x00,
7891 0x00,
7892 0x00,
7893 0x00,
7894 0x00,
7895 0x00,
7896 0x00,
7897 0x00,
7898 0x00,
7899 0x00,
7900 0x00,
7901 0x00,
7902 0x00,
7903 0x00,
7904 0x00,
7905 0x00,
7906 0x00,
7907 0x00,
7908 0x00,
7909 0x00,
7910 0x00,
7911 0x00,
7912 0x00,
7913 0x00,
7914 0x00,
7915 0x00,
7916};
7917
7918static const u8 adj_pwr_lut_core1_rev3[] = {
7919 0x00,
7920 0x00,
7921 0x00,
7922 0x00,
7923 0x00,
7924 0x00,
7925 0x00,
7926 0x00,
7927 0x00,
7928 0x00,
7929 0x00,
7930 0x00,
7931 0x00,
7932 0x00,
7933 0x00,
7934 0x00,
7935 0x00,
7936 0x00,
7937 0x00,
7938 0x00,
7939 0x00,
7940 0x00,
7941 0x00,
7942 0x00,
7943 0x00,
7944 0x00,
7945 0x00,
7946 0x00,
7947 0x00,
7948 0x00,
7949 0x00,
7950 0x00,
7951 0x00,
7952 0x00,
7953 0x00,
7954 0x00,
7955 0x00,
7956 0x00,
7957 0x00,
7958 0x00,
7959 0x00,
7960 0x00,
7961 0x00,
7962 0x00,
7963 0x00,
7964 0x00,
7965 0x00,
7966 0x00,
7967 0x00,
7968 0x00,
7969 0x00,
7970 0x00,
7971 0x00,
7972 0x00,
7973 0x00,
7974 0x00,
7975 0x00,
7976 0x00,
7977 0x00,
7978 0x00,
7979 0x00,
7980 0x00,
7981 0x00,
7982 0x00,
7983 0x00,
7984 0x00,
7985 0x00,
7986 0x00,
7987 0x00,
7988 0x00,
7989 0x00,
7990 0x00,
7991 0x00,
7992 0x00,
7993 0x00,
7994 0x00,
7995 0x00,
7996 0x00,
7997 0x00,
7998 0x00,
7999 0x00,
8000 0x00,
8001 0x00,
8002 0x00,
8003 0x00,
8004 0x00,
8005 0x00,
8006 0x00,
8007 0x00,
8008 0x00,
8009 0x00,
8010 0x00,
8011 0x00,
8012 0x00,
8013 0x00,
8014 0x00,
8015 0x00,
8016 0x00,
8017 0x00,
8018 0x00,
8019 0x00,
8020 0x00,
8021 0x00,
8022 0x00,
8023 0x00,
8024 0x00,
8025 0x00,
8026 0x00,
8027 0x00,
8028 0x00,
8029 0x00,
8030 0x00,
8031 0x00,
8032 0x00,
8033 0x00,
8034 0x00,
8035 0x00,
8036 0x00,
8037 0x00,
8038 0x00,
8039 0x00,
8040 0x00,
8041 0x00,
8042 0x00,
8043 0x00,
8044 0x00,
8045 0x00,
8046 0x00,
8047};
8048
8049static const u32 gainctrl_lut_core0_rev3[] = {
8050 0x5bf70044,
8051 0x5bf70042,
8052 0x5bf70040,
8053 0x5bf7003e,
8054 0x5bf7003c,
8055 0x5bf7003b,
8056 0x5bf70039,
8057 0x5bf70037,
8058 0x5bf70036,
8059 0x5bf70034,
8060 0x5bf70033,
8061 0x5bf70031,
8062 0x5bf70030,
8063 0x5ba70044,
8064 0x5ba70042,
8065 0x5ba70040,
8066 0x5ba7003e,
8067 0x5ba7003c,
8068 0x5ba7003b,
8069 0x5ba70039,
8070 0x5ba70037,
8071 0x5ba70036,
8072 0x5ba70034,
8073 0x5ba70033,
8074 0x5b770044,
8075 0x5b770042,
8076 0x5b770040,
8077 0x5b77003e,
8078 0x5b77003c,
8079 0x5b77003b,
8080 0x5b770039,
8081 0x5b770037,
8082 0x5b770036,
8083 0x5b770034,
8084 0x5b770033,
8085 0x5b770031,
8086 0x5b770030,
8087 0x5b77002f,
8088 0x5b77002d,
8089 0x5b77002c,
8090 0x5b470044,
8091 0x5b470042,
8092 0x5b470040,
8093 0x5b47003e,
8094 0x5b47003c,
8095 0x5b47003b,
8096 0x5b470039,
8097 0x5b470037,
8098 0x5b470036,
8099 0x5b470034,
8100 0x5b470033,
8101 0x5b470031,
8102 0x5b470030,
8103 0x5b47002f,
8104 0x5b47002d,
8105 0x5b47002c,
8106 0x5b47002b,
8107 0x5b47002a,
8108 0x5b270044,
8109 0x5b270042,
8110 0x5b270040,
8111 0x5b27003e,
8112 0x5b27003c,
8113 0x5b27003b,
8114 0x5b270039,
8115 0x5b270037,
8116 0x5b270036,
8117 0x5b270034,
8118 0x5b270033,
8119 0x5b270031,
8120 0x5b270030,
8121 0x5b27002f,
8122 0x5b170044,
8123 0x5b170042,
8124 0x5b170040,
8125 0x5b17003e,
8126 0x5b17003c,
8127 0x5b17003b,
8128 0x5b170039,
8129 0x5b170037,
8130 0x5b170036,
8131 0x5b170034,
8132 0x5b170033,
8133 0x5b170031,
8134 0x5b170030,
8135 0x5b17002f,
8136 0x5b17002d,
8137 0x5b17002c,
8138 0x5b17002b,
8139 0x5b17002a,
8140 0x5b170028,
8141 0x5b170027,
8142 0x5b170026,
8143 0x5b170025,
8144 0x5b170024,
8145 0x5b170023,
8146 0x5b070044,
8147 0x5b070042,
8148 0x5b070040,
8149 0x5b07003e,
8150 0x5b07003c,
8151 0x5b07003b,
8152 0x5b070039,
8153 0x5b070037,
8154 0x5b070036,
8155 0x5b070034,
8156 0x5b070033,
8157 0x5b070031,
8158 0x5b070030,
8159 0x5b07002f,
8160 0x5b07002d,
8161 0x5b07002c,
8162 0x5b07002b,
8163 0x5b07002a,
8164 0x5b070028,
8165 0x5b070027,
8166 0x5b070026,
8167 0x5b070025,
8168 0x5b070024,
8169 0x5b070023,
8170 0x5b070022,
8171 0x5b070021,
8172 0x5b070020,
8173 0x5b07001f,
8174 0x5b07001e,
8175 0x5b07001d,
8176 0x5b07001d,
8177 0x5b07001c,
8178};
8179
8180static const u32 gainctrl_lut_core1_rev3[] = {
8181 0x5bf70044,
8182 0x5bf70042,
8183 0x5bf70040,
8184 0x5bf7003e,
8185 0x5bf7003c,
8186 0x5bf7003b,
8187 0x5bf70039,
8188 0x5bf70037,
8189 0x5bf70036,
8190 0x5bf70034,
8191 0x5bf70033,
8192 0x5bf70031,
8193 0x5bf70030,
8194 0x5ba70044,
8195 0x5ba70042,
8196 0x5ba70040,
8197 0x5ba7003e,
8198 0x5ba7003c,
8199 0x5ba7003b,
8200 0x5ba70039,
8201 0x5ba70037,
8202 0x5ba70036,
8203 0x5ba70034,
8204 0x5ba70033,
8205 0x5b770044,
8206 0x5b770042,
8207 0x5b770040,
8208 0x5b77003e,
8209 0x5b77003c,
8210 0x5b77003b,
8211 0x5b770039,
8212 0x5b770037,
8213 0x5b770036,
8214 0x5b770034,
8215 0x5b770033,
8216 0x5b770031,
8217 0x5b770030,
8218 0x5b77002f,
8219 0x5b77002d,
8220 0x5b77002c,
8221 0x5b470044,
8222 0x5b470042,
8223 0x5b470040,
8224 0x5b47003e,
8225 0x5b47003c,
8226 0x5b47003b,
8227 0x5b470039,
8228 0x5b470037,
8229 0x5b470036,
8230 0x5b470034,
8231 0x5b470033,
8232 0x5b470031,
8233 0x5b470030,
8234 0x5b47002f,
8235 0x5b47002d,
8236 0x5b47002c,
8237 0x5b47002b,
8238 0x5b47002a,
8239 0x5b270044,
8240 0x5b270042,
8241 0x5b270040,
8242 0x5b27003e,
8243 0x5b27003c,
8244 0x5b27003b,
8245 0x5b270039,
8246 0x5b270037,
8247 0x5b270036,
8248 0x5b270034,
8249 0x5b270033,
8250 0x5b270031,
8251 0x5b270030,
8252 0x5b27002f,
8253 0x5b170044,
8254 0x5b170042,
8255 0x5b170040,
8256 0x5b17003e,
8257 0x5b17003c,
8258 0x5b17003b,
8259 0x5b170039,
8260 0x5b170037,
8261 0x5b170036,
8262 0x5b170034,
8263 0x5b170033,
8264 0x5b170031,
8265 0x5b170030,
8266 0x5b17002f,
8267 0x5b17002d,
8268 0x5b17002c,
8269 0x5b17002b,
8270 0x5b17002a,
8271 0x5b170028,
8272 0x5b170027,
8273 0x5b170026,
8274 0x5b170025,
8275 0x5b170024,
8276 0x5b170023,
8277 0x5b070044,
8278 0x5b070042,
8279 0x5b070040,
8280 0x5b07003e,
8281 0x5b07003c,
8282 0x5b07003b,
8283 0x5b070039,
8284 0x5b070037,
8285 0x5b070036,
8286 0x5b070034,
8287 0x5b070033,
8288 0x5b070031,
8289 0x5b070030,
8290 0x5b07002f,
8291 0x5b07002d,
8292 0x5b07002c,
8293 0x5b07002b,
8294 0x5b07002a,
8295 0x5b070028,
8296 0x5b070027,
8297 0x5b070026,
8298 0x5b070025,
8299 0x5b070024,
8300 0x5b070023,
8301 0x5b070022,
8302 0x5b070021,
8303 0x5b070020,
8304 0x5b07001f,
8305 0x5b07001e,
8306 0x5b07001d,
8307 0x5b07001d,
8308 0x5b07001c,
8309};
8310
8311static const u32 iq_lut_core0_rev3[] = {
8312 0x00000000,
8313 0x00000000,
8314 0x00000000,
8315 0x00000000,
8316 0x00000000,
8317 0x00000000,
8318 0x00000000,
8319 0x00000000,
8320 0x00000000,
8321 0x00000000,
8322 0x00000000,
8323 0x00000000,
8324 0x00000000,
8325 0x00000000,
8326 0x00000000,
8327 0x00000000,
8328 0x00000000,
8329 0x00000000,
8330 0x00000000,
8331 0x00000000,
8332 0x00000000,
8333 0x00000000,
8334 0x00000000,
8335 0x00000000,
8336 0x00000000,
8337 0x00000000,
8338 0x00000000,
8339 0x00000000,
8340 0x00000000,
8341 0x00000000,
8342 0x00000000,
8343 0x00000000,
8344 0x00000000,
8345 0x00000000,
8346 0x00000000,
8347 0x00000000,
8348 0x00000000,
8349 0x00000000,
8350 0x00000000,
8351 0x00000000,
8352 0x00000000,
8353 0x00000000,
8354 0x00000000,
8355 0x00000000,
8356 0x00000000,
8357 0x00000000,
8358 0x00000000,
8359 0x00000000,
8360 0x00000000,
8361 0x00000000,
8362 0x00000000,
8363 0x00000000,
8364 0x00000000,
8365 0x00000000,
8366 0x00000000,
8367 0x00000000,
8368 0x00000000,
8369 0x00000000,
8370 0x00000000,
8371 0x00000000,
8372 0x00000000,
8373 0x00000000,
8374 0x00000000,
8375 0x00000000,
8376 0x00000000,
8377 0x00000000,
8378 0x00000000,
8379 0x00000000,
8380 0x00000000,
8381 0x00000000,
8382 0x00000000,
8383 0x00000000,
8384 0x00000000,
8385 0x00000000,
8386 0x00000000,
8387 0x00000000,
8388 0x00000000,
8389 0x00000000,
8390 0x00000000,
8391 0x00000000,
8392 0x00000000,
8393 0x00000000,
8394 0x00000000,
8395 0x00000000,
8396 0x00000000,
8397 0x00000000,
8398 0x00000000,
8399 0x00000000,
8400 0x00000000,
8401 0x00000000,
8402 0x00000000,
8403 0x00000000,
8404 0x00000000,
8405 0x00000000,
8406 0x00000000,
8407 0x00000000,
8408 0x00000000,
8409 0x00000000,
8410 0x00000000,
8411 0x00000000,
8412 0x00000000,
8413 0x00000000,
8414 0x00000000,
8415 0x00000000,
8416 0x00000000,
8417 0x00000000,
8418 0x00000000,
8419 0x00000000,
8420 0x00000000,
8421 0x00000000,
8422 0x00000000,
8423 0x00000000,
8424 0x00000000,
8425 0x00000000,
8426 0x00000000,
8427 0x00000000,
8428 0x00000000,
8429 0x00000000,
8430 0x00000000,
8431 0x00000000,
8432 0x00000000,
8433 0x00000000,
8434 0x00000000,
8435 0x00000000,
8436 0x00000000,
8437 0x00000000,
8438 0x00000000,
8439 0x00000000,
8440};
8441
8442static const u32 iq_lut_core1_rev3[] = {
8443 0x00000000,
8444 0x00000000,
8445 0x00000000,
8446 0x00000000,
8447 0x00000000,
8448 0x00000000,
8449 0x00000000,
8450 0x00000000,
8451 0x00000000,
8452 0x00000000,
8453 0x00000000,
8454 0x00000000,
8455 0x00000000,
8456 0x00000000,
8457 0x00000000,
8458 0x00000000,
8459 0x00000000,
8460 0x00000000,
8461 0x00000000,
8462 0x00000000,
8463 0x00000000,
8464 0x00000000,
8465 0x00000000,
8466 0x00000000,
8467 0x00000000,
8468 0x00000000,
8469 0x00000000,
8470 0x00000000,
8471 0x00000000,
8472 0x00000000,
8473 0x00000000,
8474 0x00000000,
8475 0x00000000,
8476 0x00000000,
8477 0x00000000,
8478 0x00000000,
8479 0x00000000,
8480 0x00000000,
8481 0x00000000,
8482 0x00000000,
8483 0x00000000,
8484 0x00000000,
8485 0x00000000,
8486 0x00000000,
8487 0x00000000,
8488 0x00000000,
8489 0x00000000,
8490 0x00000000,
8491 0x00000000,
8492 0x00000000,
8493 0x00000000,
8494 0x00000000,
8495 0x00000000,
8496 0x00000000,
8497 0x00000000,
8498 0x00000000,
8499 0x00000000,
8500 0x00000000,
8501 0x00000000,
8502 0x00000000,
8503 0x00000000,
8504 0x00000000,
8505 0x00000000,
8506 0x00000000,
8507 0x00000000,
8508 0x00000000,
8509 0x00000000,
8510 0x00000000,
8511 0x00000000,
8512 0x00000000,
8513 0x00000000,
8514 0x00000000,
8515 0x00000000,
8516 0x00000000,
8517 0x00000000,
8518 0x00000000,
8519 0x00000000,
8520 0x00000000,
8521 0x00000000,
8522 0x00000000,
8523 0x00000000,
8524 0x00000000,
8525 0x00000000,
8526 0x00000000,
8527 0x00000000,
8528 0x00000000,
8529 0x00000000,
8530 0x00000000,
8531 0x00000000,
8532 0x00000000,
8533 0x00000000,
8534 0x00000000,
8535 0x00000000,
8536 0x00000000,
8537 0x00000000,
8538 0x00000000,
8539 0x00000000,
8540 0x00000000,
8541 0x00000000,
8542 0x00000000,
8543 0x00000000,
8544 0x00000000,
8545 0x00000000,
8546 0x00000000,
8547 0x00000000,
8548 0x00000000,
8549 0x00000000,
8550 0x00000000,
8551 0x00000000,
8552 0x00000000,
8553 0x00000000,
8554 0x00000000,
8555 0x00000000,
8556 0x00000000,
8557 0x00000000,
8558 0x00000000,
8559 0x00000000,
8560 0x00000000,
8561 0x00000000,
8562 0x00000000,
8563 0x00000000,
8564 0x00000000,
8565 0x00000000,
8566 0x00000000,
8567 0x00000000,
8568 0x00000000,
8569 0x00000000,
8570 0x00000000,
8571};
8572
8573static const u16 loft_lut_core0_rev3[] = {
8574 0x0000,
8575 0x0000,
8576 0x0000,
8577 0x0000,
8578 0x0000,
8579 0x0000,
8580 0x0000,
8581 0x0000,
8582 0x0000,
8583 0x0000,
8584 0x0000,
8585 0x0000,
8586 0x0000,
8587 0x0000,
8588 0x0000,
8589 0x0000,
8590 0x0000,
8591 0x0000,
8592 0x0000,
8593 0x0000,
8594 0x0000,
8595 0x0000,
8596 0x0000,
8597 0x0000,
8598 0x0000,
8599 0x0000,
8600 0x0000,
8601 0x0000,
8602 0x0000,
8603 0x0000,
8604 0x0000,
8605 0x0000,
8606 0x0000,
8607 0x0000,
8608 0x0000,
8609 0x0000,
8610 0x0000,
8611 0x0000,
8612 0x0000,
8613 0x0000,
8614 0x0000,
8615 0x0000,
8616 0x0000,
8617 0x0000,
8618 0x0000,
8619 0x0000,
8620 0x0000,
8621 0x0000,
8622 0x0000,
8623 0x0000,
8624 0x0000,
8625 0x0000,
8626 0x0000,
8627 0x0000,
8628 0x0000,
8629 0x0000,
8630 0x0000,
8631 0x0000,
8632 0x0000,
8633 0x0000,
8634 0x0000,
8635 0x0000,
8636 0x0000,
8637 0x0000,
8638 0x0000,
8639 0x0000,
8640 0x0000,
8641 0x0000,
8642 0x0000,
8643 0x0000,
8644 0x0000,
8645 0x0000,
8646 0x0000,
8647 0x0000,
8648 0x0000,
8649 0x0000,
8650 0x0000,
8651 0x0000,
8652 0x0000,
8653 0x0000,
8654 0x0000,
8655 0x0000,
8656 0x0000,
8657 0x0000,
8658 0x0000,
8659 0x0000,
8660 0x0000,
8661 0x0000,
8662 0x0000,
8663 0x0000,
8664 0x0000,
8665 0x0000,
8666 0x0000,
8667 0x0000,
8668 0x0000,
8669 0x0000,
8670 0x0000,
8671 0x0000,
8672 0x0000,
8673 0x0000,
8674 0x0000,
8675 0x0000,
8676 0x0000,
8677 0x0000,
8678 0x0000,
8679 0x0000,
8680 0x0000,
8681 0x0000,
8682 0x0000,
8683 0x0000,
8684 0x0000,
8685 0x0000,
8686 0x0000,
8687 0x0000,
8688 0x0000,
8689 0x0000,
8690 0x0000,
8691 0x0000,
8692 0x0000,
8693 0x0000,
8694 0x0000,
8695 0x0000,
8696 0x0000,
8697 0x0000,
8698 0x0000,
8699 0x0000,
8700 0x0000,
8701 0x0000,
8702};
8703
8704static const u16 loft_lut_core1_rev3[] = {
8705 0x0000,
8706 0x0000,
8707 0x0000,
8708 0x0000,
8709 0x0000,
8710 0x0000,
8711 0x0000,
8712 0x0000,
8713 0x0000,
8714 0x0000,
8715 0x0000,
8716 0x0000,
8717 0x0000,
8718 0x0000,
8719 0x0000,
8720 0x0000,
8721 0x0000,
8722 0x0000,
8723 0x0000,
8724 0x0000,
8725 0x0000,
8726 0x0000,
8727 0x0000,
8728 0x0000,
8729 0x0000,
8730 0x0000,
8731 0x0000,
8732 0x0000,
8733 0x0000,
8734 0x0000,
8735 0x0000,
8736 0x0000,
8737 0x0000,
8738 0x0000,
8739 0x0000,
8740 0x0000,
8741 0x0000,
8742 0x0000,
8743 0x0000,
8744 0x0000,
8745 0x0000,
8746 0x0000,
8747 0x0000,
8748 0x0000,
8749 0x0000,
8750 0x0000,
8751 0x0000,
8752 0x0000,
8753 0x0000,
8754 0x0000,
8755 0x0000,
8756 0x0000,
8757 0x0000,
8758 0x0000,
8759 0x0000,
8760 0x0000,
8761 0x0000,
8762 0x0000,
8763 0x0000,
8764 0x0000,
8765 0x0000,
8766 0x0000,
8767 0x0000,
8768 0x0000,
8769 0x0000,
8770 0x0000,
8771 0x0000,
8772 0x0000,
8773 0x0000,
8774 0x0000,
8775 0x0000,
8776 0x0000,
8777 0x0000,
8778 0x0000,
8779 0x0000,
8780 0x0000,
8781 0x0000,
8782 0x0000,
8783 0x0000,
8784 0x0000,
8785 0x0000,
8786 0x0000,
8787 0x0000,
8788 0x0000,
8789 0x0000,
8790 0x0000,
8791 0x0000,
8792 0x0000,
8793 0x0000,
8794 0x0000,
8795 0x0000,
8796 0x0000,
8797 0x0000,
8798 0x0000,
8799 0x0000,
8800 0x0000,
8801 0x0000,
8802 0x0000,
8803 0x0000,
8804 0x0000,
8805 0x0000,
8806 0x0000,
8807 0x0000,
8808 0x0000,
8809 0x0000,
8810 0x0000,
8811 0x0000,
8812 0x0000,
8813 0x0000,
8814 0x0000,
8815 0x0000,
8816 0x0000,
8817 0x0000,
8818 0x0000,
8819 0x0000,
8820 0x0000,
8821 0x0000,
8822 0x0000,
8823 0x0000,
8824 0x0000,
8825 0x0000,
8826 0x0000,
8827 0x0000,
8828 0x0000,
8829 0x0000,
8830 0x0000,
8831 0x0000,
8832 0x0000,
8833};
8834
8835static const u16 papd_comp_rfpwr_tbl_core0_rev3[] = {
8836 0x0036,
8837 0x0036,
8838 0x0036,
8839 0x0036,
8840 0x0036,
8841 0x0036,
8842 0x0036,
8843 0x0036,
8844 0x0036,
8845 0x0036,
8846 0x0036,
8847 0x0036,
8848 0x0036,
8849 0x002a,
8850 0x002a,
8851 0x002a,
8852 0x002a,
8853 0x002a,
8854 0x002a,
8855 0x002a,
8856 0x002a,
8857 0x002a,
8858 0x002a,
8859 0x002a,
8860 0x001e,
8861 0x001e,
8862 0x001e,
8863 0x001e,
8864 0x001e,
8865 0x001e,
8866 0x001e,
8867 0x001e,
8868 0x001e,
8869 0x001e,
8870 0x001e,
8871 0x001e,
8872 0x001e,
8873 0x001e,
8874 0x001e,
8875 0x001e,
8876 0x000e,
8877 0x000e,
8878 0x000e,
8879 0x000e,
8880 0x000e,
8881 0x000e,
8882 0x000e,
8883 0x000e,
8884 0x000e,
8885 0x000e,
8886 0x000e,
8887 0x000e,
8888 0x000e,
8889 0x000e,
8890 0x000e,
8891 0x000e,
8892 0x000e,
8893 0x000e,
8894 0x01fc,
8895 0x01fc,
8896 0x01fc,
8897 0x01fc,
8898 0x01fc,
8899 0x01fc,
8900 0x01fc,
8901 0x01fc,
8902 0x01fc,
8903 0x01fc,
8904 0x01fc,
8905 0x01fc,
8906 0x01fc,
8907 0x01fc,
8908 0x01ee,
8909 0x01ee,
8910 0x01ee,
8911 0x01ee,
8912 0x01ee,
8913 0x01ee,
8914 0x01ee,
8915 0x01ee,
8916 0x01ee,
8917 0x01ee,
8918 0x01ee,
8919 0x01ee,
8920 0x01ee,
8921 0x01ee,
8922 0x01ee,
8923 0x01ee,
8924 0x01ee,
8925 0x01ee,
8926 0x01ee,
8927 0x01ee,
8928 0x01ee,
8929 0x01ee,
8930 0x01ee,
8931 0x01ee,
8932 0x01d6,
8933 0x01d6,
8934 0x01d6,
8935 0x01d6,
8936 0x01d6,
8937 0x01d6,
8938 0x01d6,
8939 0x01d6,
8940 0x01d6,
8941 0x01d6,
8942 0x01d6,
8943 0x01d6,
8944 0x01d6,
8945 0x01d6,
8946 0x01d6,
8947 0x01d6,
8948 0x01d6,
8949 0x01d6,
8950 0x01d6,
8951 0x01d6,
8952 0x01d6,
8953 0x01d6,
8954 0x01d6,
8955 0x01d6,
8956 0x01d6,
8957 0x01d6,
8958 0x01d6,
8959 0x01d6,
8960 0x01d6,
8961 0x01d6,
8962 0x01d6,
8963 0x01d6,
8964};
8965
8966static const u16 papd_comp_rfpwr_tbl_core1_rev3[] = {
8967 0x0036,
8968 0x0036,
8969 0x0036,
8970 0x0036,
8971 0x0036,
8972 0x0036,
8973 0x0036,
8974 0x0036,
8975 0x0036,
8976 0x0036,
8977 0x0036,
8978 0x0036,
8979 0x0036,
8980 0x002a,
8981 0x002a,
8982 0x002a,
8983 0x002a,
8984 0x002a,
8985 0x002a,
8986 0x002a,
8987 0x002a,
8988 0x002a,
8989 0x002a,
8990 0x002a,
8991 0x001e,
8992 0x001e,
8993 0x001e,
8994 0x001e,
8995 0x001e,
8996 0x001e,
8997 0x001e,
8998 0x001e,
8999 0x001e,
9000 0x001e,
9001 0x001e,
9002 0x001e,
9003 0x001e,
9004 0x001e,
9005 0x001e,
9006 0x001e,
9007 0x000e,
9008 0x000e,
9009 0x000e,
9010 0x000e,
9011 0x000e,
9012 0x000e,
9013 0x000e,
9014 0x000e,
9015 0x000e,
9016 0x000e,
9017 0x000e,
9018 0x000e,
9019 0x000e,
9020 0x000e,
9021 0x000e,
9022 0x000e,
9023 0x000e,
9024 0x000e,
9025 0x01fc,
9026 0x01fc,
9027 0x01fc,
9028 0x01fc,
9029 0x01fc,
9030 0x01fc,
9031 0x01fc,
9032 0x01fc,
9033 0x01fc,
9034 0x01fc,
9035 0x01fc,
9036 0x01fc,
9037 0x01fc,
9038 0x01fc,
9039 0x01ee,
9040 0x01ee,
9041 0x01ee,
9042 0x01ee,
9043 0x01ee,
9044 0x01ee,
9045 0x01ee,
9046 0x01ee,
9047 0x01ee,
9048 0x01ee,
9049 0x01ee,
9050 0x01ee,
9051 0x01ee,
9052 0x01ee,
9053 0x01ee,
9054 0x01ee,
9055 0x01ee,
9056 0x01ee,
9057 0x01ee,
9058 0x01ee,
9059 0x01ee,
9060 0x01ee,
9061 0x01ee,
9062 0x01ee,
9063 0x01d6,
9064 0x01d6,
9065 0x01d6,
9066 0x01d6,
9067 0x01d6,
9068 0x01d6,
9069 0x01d6,
9070 0x01d6,
9071 0x01d6,
9072 0x01d6,
9073 0x01d6,
9074 0x01d6,
9075 0x01d6,
9076 0x01d6,
9077 0x01d6,
9078 0x01d6,
9079 0x01d6,
9080 0x01d6,
9081 0x01d6,
9082 0x01d6,
9083 0x01d6,
9084 0x01d6,
9085 0x01d6,
9086 0x01d6,
9087 0x01d6,
9088 0x01d6,
9089 0x01d6,
9090 0x01d6,
9091 0x01d6,
9092 0x01d6,
9093 0x01d6,
9094 0x01d6,
9095};
9096
9097static const u32 papd_comp_epsilon_tbl_core0_rev3[] = {
9098 0x00000000,
9099 0x00001fa0,
9100 0x00019f78,
9101 0x0001df7e,
9102 0x03fa9f86,
9103 0x03fd1f90,
9104 0x03fe5f8a,
9105 0x03fb1f94,
9106 0x03fd9fa0,
9107 0x00009f98,
9108 0x03fd1fac,
9109 0x03ff9fa2,
9110 0x03fe9fae,
9111 0x00001fae,
9112 0x03fddfb4,
9113 0x03ff1fb8,
9114 0x03ff9fbc,
9115 0x03ffdfbe,
9116 0x03fe9fc2,
9117 0x03fedfc6,
9118 0x03fedfc6,
9119 0x03ff9fc8,
9120 0x03ff5fc6,
9121 0x03fedfc2,
9122 0x03ff9fc0,
9123 0x03ff5fac,
9124 0x03ff5fac,
9125 0x03ff9fa2,
9126 0x03ff9fa6,
9127 0x03ff9faa,
9128 0x03ff5fb0,
9129 0x03ff5fb4,
9130 0x03ff1fca,
9131 0x03ff5fce,
9132 0x03fcdfdc,
9133 0x03fb4006,
9134 0x00000030,
9135 0x03ff808a,
9136 0x03ff80da,
9137 0x0000016c,
9138 0x03ff8318,
9139 0x03ff063a,
9140 0x03fd8bd6,
9141 0x00014ffe,
9142 0x00034ffe,
9143 0x00034ffe,
9144 0x0003cffe,
9145 0x00040ffe,
9146 0x00040ffe,
9147 0x0003cffe,
9148 0x0003cffe,
9149 0x00020ffe,
9150 0x03fe0ffe,
9151 0x03fdcffe,
9152 0x03f94ffe,
9153 0x03f54ffe,
9154 0x03f44ffe,
9155 0x03ef8ffe,
9156 0x03ee0ffe,
9157 0x03ebcffe,
9158 0x03e8cffe,
9159 0x03e74ffe,
9160 0x03e4cffe,
9161 0x03e38ffe,
9162};
9163
9164static const u32 papd_cal_scalars_tbl_core0_rev3[] = {
9165 0x05af005a,
9166 0x0571005e,
9167 0x05040066,
9168 0x04bd006c,
9169 0x047d0072,
9170 0x04430078,
9171 0x03f70081,
9172 0x03cb0087,
9173 0x03870091,
9174 0x035e0098,
9175 0x032e00a1,
9176 0x030300aa,
9177 0x02d800b4,
9178 0x02ae00bf,
9179 0x028900ca,
9180 0x026400d6,
9181 0x024100e3,
9182 0x022200f0,
9183 0x020200ff,
9184 0x01e5010e,
9185 0x01ca011e,
9186 0x01b0012f,
9187 0x01990140,
9188 0x01830153,
9189 0x016c0168,
9190 0x0158017d,
9191 0x01450193,
9192 0x013301ab,
9193 0x012101c5,
9194 0x011101e0,
9195 0x010201fc,
9196 0x00f4021a,
9197 0x00e6011d,
9198 0x00d9012e,
9199 0x00cd0140,
9200 0x00c20153,
9201 0x00b70167,
9202 0x00ac017c,
9203 0x00a30193,
9204 0x009a01ab,
9205 0x009101c4,
9206 0x008901df,
9207 0x008101fb,
9208 0x007a0219,
9209 0x00730239,
9210 0x006d025b,
9211 0x0067027e,
9212 0x006102a4,
9213 0x005c02cc,
9214 0x005602f6,
9215 0x00520323,
9216 0x004d0353,
9217 0x00490385,
9218 0x004503bb,
9219 0x004103f3,
9220 0x003d042f,
9221 0x003a046f,
9222 0x003704b2,
9223 0x003404f9,
9224 0x00310545,
9225 0x002e0596,
9226 0x002b05f5,
9227 0x00290640,
9228 0x002606a4,
9229};
9230
9231static const u32 papd_comp_epsilon_tbl_core1_rev3[] = {
9232 0x00000000,
9233 0x00001fa0,
9234 0x00019f78,
9235 0x0001df7e,
9236 0x03fa9f86,
9237 0x03fd1f90,
9238 0x03fe5f8a,
9239 0x03fb1f94,
9240 0x03fd9fa0,
9241 0x00009f98,
9242 0x03fd1fac,
9243 0x03ff9fa2,
9244 0x03fe9fae,
9245 0x00001fae,
9246 0x03fddfb4,
9247 0x03ff1fb8,
9248 0x03ff9fbc,
9249 0x03ffdfbe,
9250 0x03fe9fc2,
9251 0x03fedfc6,
9252 0x03fedfc6,
9253 0x03ff9fc8,
9254 0x03ff5fc6,
9255 0x03fedfc2,
9256 0x03ff9fc0,
9257 0x03ff5fac,
9258 0x03ff5fac,
9259 0x03ff9fa2,
9260 0x03ff9fa6,
9261 0x03ff9faa,
9262 0x03ff5fb0,
9263 0x03ff5fb4,
9264 0x03ff1fca,
9265 0x03ff5fce,
9266 0x03fcdfdc,
9267 0x03fb4006,
9268 0x00000030,
9269 0x03ff808a,
9270 0x03ff80da,
9271 0x0000016c,
9272 0x03ff8318,
9273 0x03ff063a,
9274 0x03fd8bd6,
9275 0x00014ffe,
9276 0x00034ffe,
9277 0x00034ffe,
9278 0x0003cffe,
9279 0x00040ffe,
9280 0x00040ffe,
9281 0x0003cffe,
9282 0x0003cffe,
9283 0x00020ffe,
9284 0x03fe0ffe,
9285 0x03fdcffe,
9286 0x03f94ffe,
9287 0x03f54ffe,
9288 0x03f44ffe,
9289 0x03ef8ffe,
9290 0x03ee0ffe,
9291 0x03ebcffe,
9292 0x03e8cffe,
9293 0x03e74ffe,
9294 0x03e4cffe,
9295 0x03e38ffe,
9296};
9297
9298static const u32 papd_cal_scalars_tbl_core1_rev3[] = {
9299 0x05af005a,
9300 0x0571005e,
9301 0x05040066,
9302 0x04bd006c,
9303 0x047d0072,
9304 0x04430078,
9305 0x03f70081,
9306 0x03cb0087,
9307 0x03870091,
9308 0x035e0098,
9309 0x032e00a1,
9310 0x030300aa,
9311 0x02d800b4,
9312 0x02ae00bf,
9313 0x028900ca,
9314 0x026400d6,
9315 0x024100e3,
9316 0x022200f0,
9317 0x020200ff,
9318 0x01e5010e,
9319 0x01ca011e,
9320 0x01b0012f,
9321 0x01990140,
9322 0x01830153,
9323 0x016c0168,
9324 0x0158017d,
9325 0x01450193,
9326 0x013301ab,
9327 0x012101c5,
9328 0x011101e0,
9329 0x010201fc,
9330 0x00f4021a,
9331 0x00e6011d,
9332 0x00d9012e,
9333 0x00cd0140,
9334 0x00c20153,
9335 0x00b70167,
9336 0x00ac017c,
9337 0x00a30193,
9338 0x009a01ab,
9339 0x009101c4,
9340 0x008901df,
9341 0x008101fb,
9342 0x007a0219,
9343 0x00730239,
9344 0x006d025b,
9345 0x0067027e,
9346 0x006102a4,
9347 0x005c02cc,
9348 0x005602f6,
9349 0x00520323,
9350 0x004d0353,
9351 0x00490385,
9352 0x004503bb,
9353 0x004103f3,
9354 0x003d042f,
9355 0x003a046f,
9356 0x003704b2,
9357 0x003404f9,
9358 0x00310545,
9359 0x002e0596,
9360 0x002b05f5,
9361 0x00290640,
9362 0x002606a4,
9363};
9364
9365const struct phytbl_info mimophytbl_info_rev3_volatile[] = {
9366 {&ant_swctrl_tbl_rev3,
9367 sizeof(ant_swctrl_tbl_rev3) / sizeof(ant_swctrl_tbl_rev3[0]), 9, 0, 16}
9368 ,
9369};
9370
9371const struct phytbl_info mimophytbl_info_rev3_volatile1[] = {
9372 {&ant_swctrl_tbl_rev3_1,
9373 sizeof(ant_swctrl_tbl_rev3_1) / sizeof(ant_swctrl_tbl_rev3_1[0]), 9, 0,
9374 16}
9375 ,
9376};
9377
9378const struct phytbl_info mimophytbl_info_rev3_volatile2[] = {
9379 {&ant_swctrl_tbl_rev3_2,
9380 sizeof(ant_swctrl_tbl_rev3_2) / sizeof(ant_swctrl_tbl_rev3_2[0]), 9, 0,
9381 16}
9382 ,
9383};
9384
9385const struct phytbl_info mimophytbl_info_rev3_volatile3[] = {
9386 {&ant_swctrl_tbl_rev3_3,
9387 sizeof(ant_swctrl_tbl_rev3_3) / sizeof(ant_swctrl_tbl_rev3_3[0]), 9, 0,
9388 16}
9389 ,
9390};
9391
9392const struct phytbl_info mimophytbl_info_rev3[] = {
9393 {&frame_struct_rev3,
9394 sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
9395 ,
9396 {&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
9397 11, 0, 16}
9398 ,
9399 {&tmap_tbl_rev3, sizeof(tmap_tbl_rev3) / sizeof(tmap_tbl_rev3[0]), 12,
9400 0, 32}
9401 ,
9402 {&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
9403 13, 0, 32}
9404 ,
9405 {&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
9406 14, 0, 32}
9407 ,
9408 {&noise_var_tbl_rev3,
9409 sizeof(noise_var_tbl_rev3) / sizeof(noise_var_tbl_rev3[0]), 16, 0, 32}
9410 ,
9411 {&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
9412 16}
9413 ,
9414 {&tdi_tbl20_ant0_rev3,
9415 sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
9416 32}
9417 ,
9418 {&tdi_tbl20_ant1_rev3,
9419 sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
9420 32}
9421 ,
9422 {&tdi_tbl40_ant0_rev3,
9423 sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
9424 32}
9425 ,
9426 {&tdi_tbl40_ant1_rev3,
9427 sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
9428 32}
9429 ,
9430 {&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
9431 20, 0, 32}
9432 ,
9433 {&chanest_tbl_rev3,
9434 sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
9435 ,
9436 {&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
9437 24, 0, 8}
9438 ,
9439 {&est_pwr_lut_core0_rev3,
9440 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
9441 0, 8}
9442 ,
9443 {&est_pwr_lut_core1_rev3,
9444 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
9445 0, 8}
9446 ,
9447 {&adj_pwr_lut_core0_rev3,
9448 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
9449 64, 8}
9450 ,
9451 {&adj_pwr_lut_core1_rev3,
9452 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
9453 64, 8}
9454 ,
9455 {&gainctrl_lut_core0_rev3,
9456 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
9457 26, 192, 32}
9458 ,
9459 {&gainctrl_lut_core1_rev3,
9460 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
9461 27, 192, 32}
9462 ,
9463 {&iq_lut_core0_rev3,
9464 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
9465 ,
9466 {&iq_lut_core1_rev3,
9467 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
9468 ,
9469 {&loft_lut_core0_rev3,
9470 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
9471 16}
9472 ,
9473 {&loft_lut_core1_rev3,
9474 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
9475 16}
9476};
9477
9478const u32 mimophytbl_info_sz_rev3 =
9479 sizeof(mimophytbl_info_rev3) / sizeof(mimophytbl_info_rev3[0]);
9480const u32 mimophytbl_info_sz_rev3_volatile =
9481 sizeof(mimophytbl_info_rev3_volatile) /
9482 sizeof(mimophytbl_info_rev3_volatile[0]);
9483const u32 mimophytbl_info_sz_rev3_volatile1 =
9484 sizeof(mimophytbl_info_rev3_volatile1) /
9485 sizeof(mimophytbl_info_rev3_volatile1[0]);
9486const u32 mimophytbl_info_sz_rev3_volatile2 =
9487 sizeof(mimophytbl_info_rev3_volatile2) /
9488 sizeof(mimophytbl_info_rev3_volatile2[0]);
9489const u32 mimophytbl_info_sz_rev3_volatile3 =
9490 sizeof(mimophytbl_info_rev3_volatile3) /
9491 sizeof(mimophytbl_info_rev3_volatile3[0]);
9492
9493static const u32 tmap_tbl_rev7[] = {
9494 0x8a88aa80,
9495 0x8aaaaa8a,
9496 0x8a8a8aa8,
9497 0x00000888,
9498 0x88000000,
9499 0x8a8a88aa,
9500 0x8aa88888,
9501 0x8888a8a8,
9502 0xf1111110,
9503 0x11111111,
9504 0x11f11111,
9505 0x00000111,
9506 0x11000000,
9507 0x1111f111,
9508 0x11111111,
9509 0x111111f1,
9510 0x8a88aa80,
9511 0x8aaaaa8a,
9512 0x8a8a8aa8,
9513 0x000aa888,
9514 0x88880000,
9515 0x8a8a88aa,
9516 0x8aa88888,
9517 0x8888a8a8,
9518 0xa1111110,
9519 0x11111111,
9520 0x11c11111,
9521 0x00000111,
9522 0x11000000,
9523 0x1111a111,
9524 0x11111111,
9525 0x111111a1,
9526 0xa2222220,
9527 0x22222222,
9528 0x22c22222,
9529 0x00000222,
9530 0x22000000,
9531 0x2222a222,
9532 0x22222222,
9533 0x222222a2,
9534 0xf1111110,
9535 0x11111111,
9536 0x11f11111,
9537 0x00011111,
9538 0x11110000,
9539 0x1111f111,
9540 0x11111111,
9541 0x111111f1,
9542 0xa8aa88a0,
9543 0xa88888a8,
9544 0xa8a8a88a,
9545 0x00088aaa,
9546 0xaaaa0000,
9547 0xa8a8aa88,
9548 0xa88aaaaa,
9549 0xaaaa8a8a,
9550 0xaaa8aaa0,
9551 0x8aaa8aaa,
9552 0xaa8a8a8a,
9553 0x000aaa88,
9554 0x8aaa0000,
9555 0xaaa8a888,
9556 0x8aa88a8a,
9557 0x8a88a888,
9558 0x08080a00,
9559 0x0a08080a,
9560 0x080a0a08,
9561 0x00080808,
9562 0x080a0000,
9563 0x080a0808,
9564 0x080a0808,
9565 0x0a0a0a08,
9566 0xa0a0a0a0,
9567 0x80a0a080,
9568 0x8080a0a0,
9569 0x00008080,
9570 0x80a00000,
9571 0x80a080a0,
9572 0xa080a0a0,
9573 0x8080a0a0,
9574 0x00000000,
9575 0x00000000,
9576 0x00000000,
9577 0x00000000,
9578 0x00000000,
9579 0x00000000,
9580 0x00000000,
9581 0x00000000,
9582 0x00000000,
9583 0x00000000,
9584 0x00000000,
9585 0x00000000,
9586 0x00000000,
9587 0x00000000,
9588 0x00000000,
9589 0x00000000,
9590 0x00000000,
9591 0x00000000,
9592 0x00000000,
9593 0x00000000,
9594 0x00000000,
9595 0x00000000,
9596 0x00000000,
9597 0x00000000,
9598 0x00000000,
9599 0x00000000,
9600 0x00000000,
9601 0x00000000,
9602 0x00000000,
9603 0x00000000,
9604 0x00000000,
9605 0x00000000,
9606 0x00000000,
9607 0x00000000,
9608 0x00000000,
9609 0x00000000,
9610 0x00000000,
9611 0x00000000,
9612 0x00000000,
9613 0x00000000,
9614 0x00000000,
9615 0x00000000,
9616 0x00000000,
9617 0x00000000,
9618 0x00000000,
9619 0x00000000,
9620 0x00000000,
9621 0x00000000,
9622 0x99999000,
9623 0x9b9b99bb,
9624 0x9bb99999,
9625 0x9999b9b9,
9626 0x9b99bb90,
9627 0x9bbbbb9b,
9628 0x9b9b9bb9,
9629 0x00000999,
9630 0x88000000,
9631 0x8a8a88aa,
9632 0x8aa88888,
9633 0x8888a8a8,
9634 0x8a88aa80,
9635 0x8aaaaa8a,
9636 0x8a8a8aa8,
9637 0x00aaa888,
9638 0x22000000,
9639 0x2222b222,
9640 0x22222222,
9641 0x222222b2,
9642 0xb2222220,
9643 0x22222222,
9644 0x22d22222,
9645 0x00000222,
9646 0x11000000,
9647 0x1111a111,
9648 0x11111111,
9649 0x111111a1,
9650 0xa1111110,
9651 0x11111111,
9652 0x11c11111,
9653 0x00000111,
9654 0x33000000,
9655 0x3333b333,
9656 0x33333333,
9657 0x333333b3,
9658 0xb3333330,
9659 0x33333333,
9660 0x33d33333,
9661 0x00000333,
9662 0x22000000,
9663 0x2222a222,
9664 0x22222222,
9665 0x222222a2,
9666 0xa2222220,
9667 0x22222222,
9668 0x22c22222,
9669 0x00000222,
9670 0x99b99b00,
9671 0x9b9b99bb,
9672 0x9bb99999,
9673 0x9999b9b9,
9674 0x9b99bb99,
9675 0x9bbbbb9b,
9676 0x9b9b9bb9,
9677 0x00000999,
9678 0x88000000,
9679 0x8a8a88aa,
9680 0x8aa88888,
9681 0x8888a8a8,
9682 0x8a88aa88,
9683 0x8aaaaa8a,
9684 0x8a8a8aa8,
9685 0x08aaa888,
9686 0x22222200,
9687 0x2222f222,
9688 0x22222222,
9689 0x222222f2,
9690 0x22222222,
9691 0x22222222,
9692 0x22f22222,
9693 0x00000222,
9694 0x11000000,
9695 0x1111f111,
9696 0x11111111,
9697 0x11111111,
9698 0xf1111111,
9699 0x11111111,
9700 0x11f11111,
9701 0x01111111,
9702 0xbb9bb900,
9703 0xb9b9bb99,
9704 0xb99bbbbb,
9705 0xbbbb9b9b,
9706 0xb9bb99bb,
9707 0xb99999b9,
9708 0xb9b9b99b,
9709 0x00000bbb,
9710 0xaa000000,
9711 0xa8a8aa88,
9712 0xa88aaaaa,
9713 0xaaaa8a8a,
9714 0xa8aa88aa,
9715 0xa88888a8,
9716 0xa8a8a88a,
9717 0x0a888aaa,
9718 0xaa000000,
9719 0xa8a8aa88,
9720 0xa88aaaaa,
9721 0xaaaa8a8a,
9722 0xa8aa88a0,
9723 0xa88888a8,
9724 0xa8a8a88a,
9725 0x00000aaa,
9726 0x88000000,
9727 0x8a8a88aa,
9728 0x8aa88888,
9729 0x8888a8a8,
9730 0x8a88aa80,
9731 0x8aaaaa8a,
9732 0x8a8a8aa8,
9733 0x00000888,
9734 0xbbbbbb00,
9735 0x999bbbbb,
9736 0x9bb99b9b,
9737 0xb9b9b9bb,
9738 0xb9b99bbb,
9739 0xb9b9b9bb,
9740 0xb9bb9b99,
9741 0x00000999,
9742 0x8a000000,
9743 0xaa88a888,
9744 0xa88888aa,
9745 0xa88a8a88,
9746 0xa88aa88a,
9747 0x88a8aaaa,
9748 0xa8aa8aaa,
9749 0x0888a88a,
9750 0x0b0b0b00,
9751 0x090b0b0b,
9752 0x0b090b0b,
9753 0x0909090b,
9754 0x09090b0b,
9755 0x09090b0b,
9756 0x09090b09,
9757 0x00000909,
9758 0x0a000000,
9759 0x0a080808,
9760 0x080a080a,
9761 0x080a0a08,
9762 0x080a080a,
9763 0x0808080a,
9764 0x0a0a0a08,
9765 0x0808080a,
9766 0xb0b0b000,
9767 0x9090b0b0,
9768 0x90b09090,
9769 0xb0b0b090,
9770 0xb0b090b0,
9771 0x90b0b0b0,
9772 0xb0b09090,
9773 0x00000090,
9774 0x80000000,
9775 0xa080a080,
9776 0xa08080a0,
9777 0xa0808080,
9778 0xa080a080,
9779 0x80a0a0a0,
9780 0xa0a080a0,
9781 0x00a0a0a0,
9782 0x22000000,
9783 0x2222f222,
9784 0x22222222,
9785 0x222222f2,
9786 0xf2222220,
9787 0x22222222,
9788 0x22f22222,
9789 0x00000222,
9790 0x11000000,
9791 0x1111f111,
9792 0x11111111,
9793 0x111111f1,
9794 0xf1111110,
9795 0x11111111,
9796 0x11f11111,
9797 0x00000111,
9798 0x33000000,
9799 0x3333f333,
9800 0x33333333,
9801 0x333333f3,
9802 0xf3333330,
9803 0x33333333,
9804 0x33f33333,
9805 0x00000333,
9806 0x22000000,
9807 0x2222f222,
9808 0x22222222,
9809 0x222222f2,
9810 0xf2222220,
9811 0x22222222,
9812 0x22f22222,
9813 0x00000222,
9814 0x99000000,
9815 0x9b9b99bb,
9816 0x9bb99999,
9817 0x9999b9b9,
9818 0x9b99bb90,
9819 0x9bbbbb9b,
9820 0x9b9b9bb9,
9821 0x00000999,
9822 0x88000000,
9823 0x8a8a88aa,
9824 0x8aa88888,
9825 0x8888a8a8,
9826 0x8a88aa80,
9827 0x8aaaaa8a,
9828 0x8a8a8aa8,
9829 0x00000888,
9830 0x88888000,
9831 0x8a8a88aa,
9832 0x8aa88888,
9833 0x8888a8a8,
9834 0x8a88aa80,
9835 0x8aaaaa8a,
9836 0x8a8a8aa8,
9837 0x00000888,
9838 0x88000000,
9839 0x8a8a88aa,
9840 0x8aa88888,
9841 0x8888a8a8,
9842 0x8a88aa80,
9843 0x8aaaaa8a,
9844 0x8a8a8aa8,
9845 0x00aaa888,
9846 0x88a88a00,
9847 0x8a8a88aa,
9848 0x8aa88888,
9849 0x8888a8a8,
9850 0x8a88aa88,
9851 0x8aaaaa8a,
9852 0x8a8a8aa8,
9853 0x000aa888,
9854 0x88880000,
9855 0x8a8a88aa,
9856 0x8aa88888,
9857 0x8888a8a8,
9858 0x8a88aa88,
9859 0x8aaaaa8a,
9860 0x8a8a8aa8,
9861 0x08aaa888,
9862 0x11000000,
9863 0x1111a111,
9864 0x11111111,
9865 0x111111a1,
9866 0xa1111110,
9867 0x11111111,
9868 0x11c11111,
9869 0x00000111,
9870 0x11000000,
9871 0x1111a111,
9872 0x11111111,
9873 0x111111a1,
9874 0xa1111110,
9875 0x11111111,
9876 0x11c11111,
9877 0x00000111,
9878 0x88000000,
9879 0x8a8a88aa,
9880 0x8aa88888,
9881 0x8888a8a8,
9882 0x8a88aa80,
9883 0x8aaaaa8a,
9884 0x8a8a8aa8,
9885 0x00000888,
9886 0x88000000,
9887 0x8a8a88aa,
9888 0x8aa88888,
9889 0x8888a8a8,
9890 0x8a88aa80,
9891 0x8aaaaa8a,
9892 0x8a8a8aa8,
9893 0x00000888,
9894 0x00000000,
9895 0x00000000,
9896 0x00000000,
9897 0x00000000,
9898 0x00000000,
9899 0x00000000,
9900 0x00000000,
9901 0x00000000,
9902 0x00000000,
9903 0x00000000,
9904 0x00000000,
9905 0x00000000,
9906 0x00000000,
9907 0x00000000,
9908 0x00000000,
9909 0x00000000,
9910 0x00000000,
9911 0x00000000,
9912 0x00000000,
9913 0x00000000,
9914 0x00000000,
9915 0x00000000,
9916 0x00000000,
9917 0x00000000,
9918 0x00000000,
9919 0x00000000,
9920 0x00000000,
9921 0x00000000,
9922 0x00000000,
9923 0x00000000,
9924 0x00000000,
9925 0x00000000,
9926 0x00000000,
9927 0x00000000,
9928 0x00000000,
9929 0x00000000,
9930 0x00000000,
9931 0x00000000,
9932 0x00000000,
9933 0x00000000,
9934 0x00000000,
9935 0x00000000,
9936 0x00000000,
9937 0x00000000,
9938 0x00000000,
9939 0x00000000,
9940 0x00000000,
9941 0x00000000,
9942};
9943
9944const u32 noise_var_tbl_rev7[] = {
9945 0x020c020c,
9946 0x0000014d,
9947 0x020c020c,
9948 0x0000014d,
9949 0x020c020c,
9950 0x0000014d,
9951 0x020c020c,
9952 0x0000014d,
9953 0x020c020c,
9954 0x0000014d,
9955 0x020c020c,
9956 0x0000014d,
9957 0x020c020c,
9958 0x0000014d,
9959 0x020c020c,
9960 0x0000014d,
9961 0x020c020c,
9962 0x0000014d,
9963 0x020c020c,
9964 0x0000014d,
9965 0x020c020c,
9966 0x0000014d,
9967 0x020c020c,
9968 0x0000014d,
9969 0x020c020c,
9970 0x0000014d,
9971 0x020c020c,
9972 0x0000014d,
9973 0x020c020c,
9974 0x0000014d,
9975 0x020c020c,
9976 0x0000014d,
9977 0x020c020c,
9978 0x0000014d,
9979 0x020c020c,
9980 0x0000014d,
9981 0x020c020c,
9982 0x0000014d,
9983 0x020c020c,
9984 0x0000014d,
9985 0x020c020c,
9986 0x0000014d,
9987 0x020c020c,
9988 0x0000014d,
9989 0x020c020c,
9990 0x0000014d,
9991 0x020c020c,
9992 0x0000014d,
9993 0x020c020c,
9994 0x0000014d,
9995 0x020c020c,
9996 0x0000014d,
9997 0x020c020c,
9998 0x0000014d,
9999 0x020c020c,
10000 0x0000014d,
10001 0x020c020c,
10002 0x0000014d,
10003 0x020c020c,
10004 0x0000014d,
10005 0x020c020c,
10006 0x0000014d,
10007 0x020c020c,
10008 0x0000014d,
10009 0x020c020c,
10010 0x0000014d,
10011 0x020c020c,
10012 0x0000014d,
10013 0x020c020c,
10014 0x0000014d,
10015 0x020c020c,
10016 0x0000014d,
10017 0x020c020c,
10018 0x0000014d,
10019 0x020c020c,
10020 0x0000014d,
10021 0x020c020c,
10022 0x0000014d,
10023 0x020c020c,
10024 0x0000014d,
10025 0x020c020c,
10026 0x0000014d,
10027 0x020c020c,
10028 0x0000014d,
10029 0x020c020c,
10030 0x0000014d,
10031 0x020c020c,
10032 0x0000014d,
10033 0x020c020c,
10034 0x0000014d,
10035 0x020c020c,
10036 0x0000014d,
10037 0x020c020c,
10038 0x0000014d,
10039 0x020c020c,
10040 0x0000014d,
10041 0x020c020c,
10042 0x0000014d,
10043 0x020c020c,
10044 0x0000014d,
10045 0x020c020c,
10046 0x0000014d,
10047 0x020c020c,
10048 0x0000014d,
10049 0x020c020c,
10050 0x0000014d,
10051 0x020c020c,
10052 0x0000014d,
10053 0x020c020c,
10054 0x0000014d,
10055 0x020c020c,
10056 0x0000014d,
10057 0x020c020c,
10058 0x0000014d,
10059 0x020c020c,
10060 0x0000014d,
10061 0x020c020c,
10062 0x0000014d,
10063 0x020c020c,
10064 0x0000014d,
10065 0x020c020c,
10066 0x0000014d,
10067 0x020c020c,
10068 0x0000014d,
10069 0x020c020c,
10070 0x0000014d,
10071 0x020c020c,
10072 0x0000014d,
10073 0x020c020c,
10074 0x0000014d,
10075 0x020c020c,
10076 0x0000014d,
10077 0x020c020c,
10078 0x0000014d,
10079 0x020c020c,
10080 0x0000014d,
10081 0x020c020c,
10082 0x0000014d,
10083 0x020c020c,
10084 0x0000014d,
10085 0x020c020c,
10086 0x0000014d,
10087 0x020c020c,
10088 0x0000014d,
10089 0x020c020c,
10090 0x0000014d,
10091 0x020c020c,
10092 0x0000014d,
10093 0x020c020c,
10094 0x0000014d,
10095 0x020c020c,
10096 0x0000014d,
10097 0x020c020c,
10098 0x0000014d,
10099 0x020c020c,
10100 0x0000014d,
10101 0x020c020c,
10102 0x0000014d,
10103 0x020c020c,
10104 0x0000014d,
10105 0x020c020c,
10106 0x0000014d,
10107 0x020c020c,
10108 0x0000014d,
10109 0x020c020c,
10110 0x0000014d,
10111 0x020c020c,
10112 0x0000014d,
10113 0x020c020c,
10114 0x0000014d,
10115 0x020c020c,
10116 0x0000014d,
10117 0x020c020c,
10118 0x0000014d,
10119 0x020c020c,
10120 0x0000014d,
10121 0x020c020c,
10122 0x0000014d,
10123 0x020c020c,
10124 0x0000014d,
10125 0x020c020c,
10126 0x0000014d,
10127 0x020c020c,
10128 0x0000014d,
10129 0x020c020c,
10130 0x0000014d,
10131 0x020c020c,
10132 0x0000014d,
10133 0x020c020c,
10134 0x0000014d,
10135 0x020c020c,
10136 0x0000014d,
10137 0x020c020c,
10138 0x0000014d,
10139 0x020c020c,
10140 0x0000014d,
10141 0x020c020c,
10142 0x0000014d,
10143 0x020c020c,
10144 0x0000014d,
10145 0x020c020c,
10146 0x0000014d,
10147 0x020c020c,
10148 0x0000014d,
10149 0x020c020c,
10150 0x0000014d,
10151 0x020c020c,
10152 0x0000014d,
10153 0x020c020c,
10154 0x0000014d,
10155 0x020c020c,
10156 0x0000014d,
10157 0x020c020c,
10158 0x0000014d,
10159 0x020c020c,
10160 0x0000014d,
10161 0x020c020c,
10162 0x0000014d,
10163 0x020c020c,
10164 0x0000014d,
10165 0x020c020c,
10166 0x0000014d,
10167 0x020c020c,
10168 0x0000014d,
10169 0x020c020c,
10170 0x0000014d,
10171 0x020c020c,
10172 0x0000014d,
10173 0x020c020c,
10174 0x0000014d,
10175 0x020c020c,
10176 0x0000014d,
10177 0x020c020c,
10178 0x0000014d,
10179 0x020c020c,
10180 0x0000014d,
10181 0x020c020c,
10182 0x0000014d,
10183 0x020c020c,
10184 0x0000014d,
10185 0x020c020c,
10186 0x0000014d,
10187 0x020c020c,
10188 0x0000014d,
10189 0x020c020c,
10190 0x0000014d,
10191 0x020c020c,
10192 0x0000014d,
10193 0x020c020c,
10194 0x0000014d,
10195 0x020c020c,
10196 0x0000014d,
10197 0x020c020c,
10198 0x0000014d,
10199 0x020c020c,
10200 0x0000014d,
10201};
10202
10203static const u32 papd_comp_epsilon_tbl_core0_rev7[] = {
10204 0x00000000,
10205 0x00000000,
10206 0x00016023,
10207 0x00006028,
10208 0x00034036,
10209 0x0003402e,
10210 0x0007203c,
10211 0x0006e037,
10212 0x00070030,
10213 0x0009401f,
10214 0x0009a00f,
10215 0x000b600d,
10216 0x000c8007,
10217 0x000ce007,
10218 0x00101fff,
10219 0x00121ff9,
10220 0x0012e004,
10221 0x0014dffc,
10222 0x0016dff6,
10223 0x0018dfe9,
10224 0x001b3fe5,
10225 0x001c5fd0,
10226 0x001ddfc2,
10227 0x001f1fb6,
10228 0x00207fa4,
10229 0x00219f8f,
10230 0x0022ff7d,
10231 0x00247f6c,
10232 0x0024df5b,
10233 0x00267f4b,
10234 0x0027df3b,
10235 0x0029bf3b,
10236 0x002b5f2f,
10237 0x002d3f2e,
10238 0x002f5f2a,
10239 0x002fff15,
10240 0x00315f0b,
10241 0x0032defa,
10242 0x0033beeb,
10243 0x0034fed9,
10244 0x00353ec5,
10245 0x00361eb0,
10246 0x00363e9b,
10247 0x0036be87,
10248 0x0036be70,
10249 0x0038fe67,
10250 0x0044beb2,
10251 0x00513ef3,
10252 0x00595f11,
10253 0x00669f3d,
10254 0x0078dfdf,
10255 0x00a143aa,
10256 0x01642fff,
10257 0x0162afff,
10258 0x01620fff,
10259 0x0160cfff,
10260 0x015f0fff,
10261 0x015dafff,
10262 0x015bcfff,
10263 0x015bcfff,
10264 0x015b4fff,
10265 0x015acfff,
10266 0x01590fff,
10267 0x0156cfff,
10268};
10269
10270static const u32 papd_cal_scalars_tbl_core0_rev7[] = {
10271 0x0b5e002d,
10272 0x0ae2002f,
10273 0x0a3b0032,
10274 0x09a70035,
10275 0x09220038,
10276 0x08ab003b,
10277 0x081f003f,
10278 0x07a20043,
10279 0x07340047,
10280 0x06d2004b,
10281 0x067a004f,
10282 0x06170054,
10283 0x05bf0059,
10284 0x0571005e,
10285 0x051e0064,
10286 0x04d3006a,
10287 0x04910070,
10288 0x044c0077,
10289 0x040f007e,
10290 0x03d90085,
10291 0x03a1008d,
10292 0x036f0095,
10293 0x033d009e,
10294 0x030b00a8,
10295 0x02e000b2,
10296 0x02b900bc,
10297 0x029200c7,
10298 0x026d00d3,
10299 0x024900e0,
10300 0x022900ed,
10301 0x020a00fb,
10302 0x01ec010a,
10303 0x01d20119,
10304 0x01b7012a,
10305 0x019e013c,
10306 0x0188014e,
10307 0x01720162,
10308 0x015d0177,
10309 0x0149018e,
10310 0x013701a5,
10311 0x012601be,
10312 0x011501d8,
10313 0x010601f4,
10314 0x00f70212,
10315 0x00e90231,
10316 0x00dc0253,
10317 0x00d00276,
10318 0x00c4029b,
10319 0x00b902c3,
10320 0x00af02ed,
10321 0x00a50319,
10322 0x009c0348,
10323 0x0093037a,
10324 0x008b03af,
10325 0x008303e6,
10326 0x007c0422,
10327 0x00750460,
10328 0x006e04a3,
10329 0x006804e9,
10330 0x00620533,
10331 0x005d0582,
10332 0x005805d6,
10333 0x0053062e,
10334 0x004e068c,
10335};
10336
10337static const u32 papd_comp_epsilon_tbl_core1_rev7[] = {
10338 0x00000000,
10339 0x00000000,
10340 0x00016023,
10341 0x00006028,
10342 0x00034036,
10343 0x0003402e,
10344 0x0007203c,
10345 0x0006e037,
10346 0x00070030,
10347 0x0009401f,
10348 0x0009a00f,
10349 0x000b600d,
10350 0x000c8007,
10351 0x000ce007,
10352 0x00101fff,
10353 0x00121ff9,
10354 0x0012e004,
10355 0x0014dffc,
10356 0x0016dff6,
10357 0x0018dfe9,
10358 0x001b3fe5,
10359 0x001c5fd0,
10360 0x001ddfc2,
10361 0x001f1fb6,
10362 0x00207fa4,
10363 0x00219f8f,
10364 0x0022ff7d,
10365 0x00247f6c,
10366 0x0024df5b,
10367 0x00267f4b,
10368 0x0027df3b,
10369 0x0029bf3b,
10370 0x002b5f2f,
10371 0x002d3f2e,
10372 0x002f5f2a,
10373 0x002fff15,
10374 0x00315f0b,
10375 0x0032defa,
10376 0x0033beeb,
10377 0x0034fed9,
10378 0x00353ec5,
10379 0x00361eb0,
10380 0x00363e9b,
10381 0x0036be87,
10382 0x0036be70,
10383 0x0038fe67,
10384 0x0044beb2,
10385 0x00513ef3,
10386 0x00595f11,
10387 0x00669f3d,
10388 0x0078dfdf,
10389 0x00a143aa,
10390 0x01642fff,
10391 0x0162afff,
10392 0x01620fff,
10393 0x0160cfff,
10394 0x015f0fff,
10395 0x015dafff,
10396 0x015bcfff,
10397 0x015bcfff,
10398 0x015b4fff,
10399 0x015acfff,
10400 0x01590fff,
10401 0x0156cfff,
10402};
10403
10404static const u32 papd_cal_scalars_tbl_core1_rev7[] = {
10405 0x0b5e002d,
10406 0x0ae2002f,
10407 0x0a3b0032,
10408 0x09a70035,
10409 0x09220038,
10410 0x08ab003b,
10411 0x081f003f,
10412 0x07a20043,
10413 0x07340047,
10414 0x06d2004b,
10415 0x067a004f,
10416 0x06170054,
10417 0x05bf0059,
10418 0x0571005e,
10419 0x051e0064,
10420 0x04d3006a,
10421 0x04910070,
10422 0x044c0077,
10423 0x040f007e,
10424 0x03d90085,
10425 0x03a1008d,
10426 0x036f0095,
10427 0x033d009e,
10428 0x030b00a8,
10429 0x02e000b2,
10430 0x02b900bc,
10431 0x029200c7,
10432 0x026d00d3,
10433 0x024900e0,
10434 0x022900ed,
10435 0x020a00fb,
10436 0x01ec010a,
10437 0x01d20119,
10438 0x01b7012a,
10439 0x019e013c,
10440 0x0188014e,
10441 0x01720162,
10442 0x015d0177,
10443 0x0149018e,
10444 0x013701a5,
10445 0x012601be,
10446 0x011501d8,
10447 0x010601f4,
10448 0x00f70212,
10449 0x00e90231,
10450 0x00dc0253,
10451 0x00d00276,
10452 0x00c4029b,
10453 0x00b902c3,
10454 0x00af02ed,
10455 0x00a50319,
10456 0x009c0348,
10457 0x0093037a,
10458 0x008b03af,
10459 0x008303e6,
10460 0x007c0422,
10461 0x00750460,
10462 0x006e04a3,
10463 0x006804e9,
10464 0x00620533,
10465 0x005d0582,
10466 0x005805d6,
10467 0x0053062e,
10468 0x004e068c,
10469};
10470
10471const struct phytbl_info mimophytbl_info_rev7[] = {
10472 {&frame_struct_rev3,
10473 sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
10474 ,
10475 {&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
10476 11, 0, 16}
10477 ,
10478 {&tmap_tbl_rev7, sizeof(tmap_tbl_rev7) / sizeof(tmap_tbl_rev7[0]), 12,
10479 0, 32}
10480 ,
10481 {&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
10482 13, 0, 32}
10483 ,
10484 {&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
10485 14, 0, 32}
10486 ,
10487 {&noise_var_tbl_rev7,
10488 sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
10489 ,
10490 {&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
10491 16}
10492 ,
10493 {&tdi_tbl20_ant0_rev3,
10494 sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
10495 32}
10496 ,
10497 {&tdi_tbl20_ant1_rev3,
10498 sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
10499 32}
10500 ,
10501 {&tdi_tbl40_ant0_rev3,
10502 sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
10503 32}
10504 ,
10505 {&tdi_tbl40_ant1_rev3,
10506 sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
10507 32}
10508 ,
10509 {&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
10510 20, 0, 32}
10511 ,
10512 {&chanest_tbl_rev3,
10513 sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
10514 ,
10515 {&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
10516 24, 0, 8}
10517 ,
10518 {&est_pwr_lut_core0_rev3,
10519 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
10520 0, 8}
10521 ,
10522 {&est_pwr_lut_core1_rev3,
10523 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
10524 0, 8}
10525 ,
10526 {&adj_pwr_lut_core0_rev3,
10527 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
10528 64, 8}
10529 ,
10530 {&adj_pwr_lut_core1_rev3,
10531 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
10532 64, 8}
10533 ,
10534 {&gainctrl_lut_core0_rev3,
10535 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
10536 26, 192, 32}
10537 ,
10538 {&gainctrl_lut_core1_rev3,
10539 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
10540 27, 192, 32}
10541 ,
10542 {&iq_lut_core0_rev3,
10543 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
10544 ,
10545 {&iq_lut_core1_rev3,
10546 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
10547 ,
10548 {&loft_lut_core0_rev3,
10549 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
10550 16}
10551 ,
10552 {&loft_lut_core1_rev3,
10553 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
10554 16}
10555 ,
10556 {&papd_comp_rfpwr_tbl_core0_rev3,
10557 sizeof(papd_comp_rfpwr_tbl_core0_rev3) /
10558 sizeof(papd_comp_rfpwr_tbl_core0_rev3[0]), 26, 576, 16}
10559 ,
10560 {&papd_comp_rfpwr_tbl_core1_rev3,
10561 sizeof(papd_comp_rfpwr_tbl_core1_rev3) /
10562 sizeof(papd_comp_rfpwr_tbl_core1_rev3[0]), 27, 576, 16}
10563 ,
10564 {&papd_comp_epsilon_tbl_core0_rev7,
10565 sizeof(papd_comp_epsilon_tbl_core0_rev7) /
10566 sizeof(papd_comp_epsilon_tbl_core0_rev7[0]), 31, 0, 32}
10567 ,
10568 {&papd_cal_scalars_tbl_core0_rev7,
10569 sizeof(papd_cal_scalars_tbl_core0_rev7) /
10570 sizeof(papd_cal_scalars_tbl_core0_rev7[0]), 32, 0, 32}
10571 ,
10572 {&papd_comp_epsilon_tbl_core1_rev7,
10573 sizeof(papd_comp_epsilon_tbl_core1_rev7) /
10574 sizeof(papd_comp_epsilon_tbl_core1_rev7[0]), 33, 0, 32}
10575 ,
10576 {&papd_cal_scalars_tbl_core1_rev7,
10577 sizeof(papd_cal_scalars_tbl_core1_rev7) /
10578 sizeof(papd_cal_scalars_tbl_core1_rev7[0]), 34, 0, 32}
10579 ,
10580};
10581
10582const u32 mimophytbl_info_sz_rev7 =
10583 sizeof(mimophytbl_info_rev7) / sizeof(mimophytbl_info_rev7[0]);
10584
10585const struct phytbl_info mimophytbl_info_rev16[] = {
10586 {&noise_var_tbl_rev7,
10587 sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
10588 ,
10589 {&est_pwr_lut_core0_rev3,
10590 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
10591 0, 8}
10592 ,
10593 {&est_pwr_lut_core1_rev3,
10594 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
10595 0, 8}
10596 ,
10597 {&adj_pwr_lut_core0_rev3,
10598 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
10599 64, 8}
10600 ,
10601 {&adj_pwr_lut_core1_rev3,
10602 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
10603 64, 8}
10604 ,
10605 {&gainctrl_lut_core0_rev3,
10606 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
10607 26, 192, 32}
10608 ,
10609 {&gainctrl_lut_core1_rev3,
10610 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
10611 27, 192, 32}
10612 ,
10613 {&iq_lut_core0_rev3,
10614 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
10615 ,
10616 {&iq_lut_core1_rev3,
10617 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
10618 ,
10619 {&loft_lut_core0_rev3,
10620 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
10621 16}
10622 ,
10623 {&loft_lut_core1_rev3,
10624 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
10625 16}
10626 ,
10627};
10628
10629const u32 mimophytbl_info_sz_rev16 =
10630 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 000000000000..dc8a84e85117
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#define ANT_SWCTRL_TBL_REV3_IDX (0)
18
19#include <types.h>
20#include "phy_int.h"
21
22extern const struct phytbl_info mimophytbl_info_rev0[],
23 mimophytbl_info_rev0_volatile[];
24
25extern const u32 mimophytbl_info_sz_rev0,
26 mimophytbl_info_sz_rev0_volatile;
27
28extern const struct phytbl_info mimophytbl_info_rev3[],
29 mimophytbl_info_rev3_volatile[],
30 mimophytbl_info_rev3_volatile1[],
31 mimophytbl_info_rev3_volatile2[],
32 mimophytbl_info_rev3_volatile3[];
33
34extern const u32 mimophytbl_info_sz_rev3,
35 mimophytbl_info_sz_rev3_volatile,
36 mimophytbl_info_sz_rev3_volatile1,
37 mimophytbl_info_sz_rev3_volatile2,
38 mimophytbl_info_sz_rev3_volatile3;
39
40extern const u32 noise_var_tbl_rev3[];
41
42extern const struct phytbl_info mimophytbl_info_rev7[];
43
44extern const u32 mimophytbl_info_sz_rev7;
45
46extern const u32 noise_var_tbl_rev7[];
47
48extern const struct phytbl_info mimophytbl_info_rev16[];
49
50extern 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 000000000000..5926854f62e2
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
@@ -0,0 +1,225 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/*
18 * This is "two-way" interface, acting as the SHIM layer between driver
19 * and PHY layer. The driver can optionally call this translation layer
20 * to do some preprocessing, then reach PHY. On the PHY->driver direction,
21 * all calls go through this layer since PHY doesn't have access to the
22 * driver's brcms_hardware pointer.
23 */
24#include <linux/slab.h>
25#include <net/mac80211.h>
26
27#include "main.h"
28#include "mac80211_if.h"
29#include "phy_shim.h"
30
31/* PHY SHIM module specific state */
32struct phy_shim_info {
33 struct brcms_hardware *wlc_hw; /* pointer to main wlc_hw structure */
34 struct brcms_c_info *wlc; /* pointer to main wlc structure */
35 struct brcms_info *wl; /* pointer to os-specific private state */
36};
37
38struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
39 struct brcms_info *wl,
40 struct brcms_c_info *wlc) {
41 struct phy_shim_info *physhim = NULL;
42
43 physhim = kzalloc(sizeof(struct phy_shim_info), GFP_ATOMIC);
44 if (!physhim)
45 return NULL;
46
47 physhim->wlc_hw = wlc_hw;
48 physhim->wlc = wlc;
49 physhim->wl = wl;
50
51 return physhim;
52}
53
54void wlc_phy_shim_detach(struct phy_shim_info *physhim)
55{
56 kfree(physhim);
57}
58
59struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
60 void (*fn)(struct brcms_phy *pi),
61 void *arg, const char *name)
62{
63 return (struct wlapi_timer *)
64 brcms_init_timer(physhim->wl, (void (*)(void *))fn,
65 arg, name);
66}
67
68void wlapi_free_timer(struct wlapi_timer *t)
69{
70 brcms_free_timer((struct brcms_timer *)t);
71}
72
73void
74wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic)
75{
76 brcms_add_timer((struct brcms_timer *)t, ms, periodic);
77}
78
79bool wlapi_del_timer(struct wlapi_timer *t)
80{
81 return brcms_del_timer((struct brcms_timer *)t);
82}
83
84void wlapi_intrson(struct phy_shim_info *physhim)
85{
86 brcms_intrson(physhim->wl);
87}
88
89u32 wlapi_intrsoff(struct phy_shim_info *physhim)
90{
91 return brcms_intrsoff(physhim->wl);
92}
93
94void wlapi_intrsrestore(struct phy_shim_info *physhim, u32 macintmask)
95{
96 brcms_intrsrestore(physhim->wl, macintmask);
97}
98
99void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, u16 v)
100{
101 brcms_b_write_shm(physhim->wlc_hw, offset, v);
102}
103
104u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset)
105{
106 return brcms_b_read_shm(physhim->wlc_hw, offset);
107}
108
109void
110wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, u16 mask,
111 u16 val, int bands)
112{
113 brcms_b_mhf(physhim->wlc_hw, idx, mask, val, bands);
114}
115
116void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags)
117{
118 brcms_b_corereset(physhim->wlc_hw, flags);
119}
120
121void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim)
122{
123 brcms_c_suspend_mac_and_wait(physhim->wlc);
124}
125
126void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode)
127{
128 brcms_b_switch_macfreq(physhim->wlc_hw, spurmode);
129}
130
131void wlapi_enable_mac(struct phy_shim_info *physhim)
132{
133 brcms_c_enable_mac(physhim->wlc);
134}
135
136void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, u32 val)
137{
138 brcms_b_mctrl(physhim->wlc_hw, mask, val);
139}
140
141void wlapi_bmac_phy_reset(struct phy_shim_info *physhim)
142{
143 brcms_b_phy_reset(physhim->wlc_hw);
144}
145
146void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw)
147{
148 brcms_b_bw_set(physhim->wlc_hw, bw);
149}
150
151u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim)
152{
153 return brcms_b_get_txant(physhim->wlc_hw);
154}
155
156void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk)
157{
158 brcms_b_phyclk_fgc(physhim->wlc_hw, clk);
159}
160
161void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk)
162{
163 brcms_b_macphyclk_set(physhim->wlc_hw, clk);
164}
165
166void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on)
167{
168 brcms_b_core_phypll_ctl(physhim->wlc_hw, on);
169}
170
171void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim)
172{
173 brcms_b_core_phypll_reset(physhim->wlc_hw);
174}
175
176void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *physhim)
177{
178 brcms_c_ucode_wake_override_set(physhim->wlc_hw,
179 BRCMS_WAKE_OVERRIDE_PHYREG);
180}
181
182void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *physhim)
183{
184 brcms_c_ucode_wake_override_clear(physhim->wlc_hw,
185 BRCMS_WAKE_OVERRIDE_PHYREG);
186}
187
188void
189wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int offset,
190 int len, void *buf)
191{
192 brcms_b_write_template_ram(physhim->wlc_hw, offset, len, buf);
193}
194
195u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, u8 rate)
196{
197 return brcms_b_rate_shm_offset(physhim->wlc_hw, rate);
198}
199
200void wlapi_ucode_sample_init(struct phy_shim_info *physhim)
201{
202}
203
204void
205wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint offset, void *buf,
206 int len, u32 sel)
207{
208 brcms_b_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel);
209}
210
211void
212wlapi_copyto_objmem(struct phy_shim_info *physhim, uint offset, const void *buf,
213 int l, u32 sel)
214{
215 brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
216}
217
218char *wlapi_getvar(struct phy_shim_info *physhim, enum brcms_srom_id id)
219{
220 return getvar(physhim->wlc_hw->sih, id);
221}
222int wlapi_getintvar(struct phy_shim_info *physhim, enum brcms_srom_id id)
223{
224 return getintvar(physhim->wlc_hw->sih, id);
225}
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 000000000000..9168c459b185
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
@@ -0,0 +1,182 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/*
18 * phy_shim.h: stuff defined in phy_shim.c and included only by the phy
19 */
20
21#ifndef _BRCM_PHY_SHIM_H_
22#define _BRCM_PHY_SHIM_H_
23
24#include "types.h"
25
26#define RADAR_TYPE_NONE 0 /* Radar type None */
27#define RADAR_TYPE_ETSI_1 1 /* ETSI 1 Radar type */
28#define RADAR_TYPE_ETSI_2 2 /* ETSI 2 Radar type */
29#define RADAR_TYPE_ETSI_3 3 /* ETSI 3 Radar type */
30#define RADAR_TYPE_ITU_E 4 /* ITU E Radar type */
31#define RADAR_TYPE_ITU_K 5 /* ITU K Radar type */
32#define RADAR_TYPE_UNCLASSIFIED 6 /* Unclassified Radar type */
33#define RADAR_TYPE_BIN5 7 /* long pulse radar type */
34#define RADAR_TYPE_STG2 8 /* staggered-2 radar */
35#define RADAR_TYPE_STG3 9 /* staggered-3 radar */
36#define RADAR_TYPE_FRA 10 /* French radar */
37
38/* French radar pulse widths */
39#define FRA_T1_20MHZ 52770
40#define FRA_T2_20MHZ 61538
41#define FRA_T3_20MHZ 66002
42#define FRA_T1_40MHZ 105541
43#define FRA_T2_40MHZ 123077
44#define FRA_T3_40MHZ 132004
45#define FRA_ERR_20MHZ 60
46#define FRA_ERR_40MHZ 120
47
48#define ANTSEL_NA 0 /* No boardlevel selection available */
49#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */
50#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */
51
52/* Rx Antenna diversity control values */
53#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */
54#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */
55#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */
56#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */
57#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */
58#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */
59
60#define WL_ANT_RX_MAX 2 /* max 2 receive antennas */
61#define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */
62#define WL_ANT_IDX_1 0 /* antenna index 1 */
63#define WL_ANT_IDX_2 1 /* antenna index 2 */
64
65/* values for n_preamble_type */
66#define BRCMS_N_PREAMBLE_MIXEDMODE 0
67#define BRCMS_N_PREAMBLE_GF 1
68#define BRCMS_N_PREAMBLE_GF_BRCM 2
69
70#define WL_TX_POWER_RATES_LEGACY 45
71#define WL_TX_POWER_MCS20_FIRST 12
72#define WL_TX_POWER_MCS20_NUM 16
73#define WL_TX_POWER_MCS40_FIRST 28
74#define WL_TX_POWER_MCS40_NUM 17
75
76
77#define WL_TX_POWER_RATES 101
78#define WL_TX_POWER_CCK_FIRST 0
79#define WL_TX_POWER_CCK_NUM 4
80/* Index for first 20MHz OFDM SISO rate */
81#define WL_TX_POWER_OFDM_FIRST 4
82/* Index for first 20MHz OFDM CDD rate */
83#define WL_TX_POWER_OFDM20_CDD_FIRST 12
84/* Index for first 40MHz OFDM SISO rate */
85#define WL_TX_POWER_OFDM40_SISO_FIRST 52
86/* Index for first 40MHz OFDM CDD rate */
87#define WL_TX_POWER_OFDM40_CDD_FIRST 60
88#define WL_TX_POWER_OFDM_NUM 8
89/* Index for first 20MHz MCS SISO rate */
90#define WL_TX_POWER_MCS20_SISO_FIRST 20
91/* Index for first 20MHz MCS CDD rate */
92#define WL_TX_POWER_MCS20_CDD_FIRST 28
93/* Index for first 20MHz MCS STBC rate */
94#define WL_TX_POWER_MCS20_STBC_FIRST 36
95/* Index for first 20MHz MCS SDM rate */
96#define WL_TX_POWER_MCS20_SDM_FIRST 44
97/* Index for first 40MHz MCS SISO rate */
98#define WL_TX_POWER_MCS40_SISO_FIRST 68
99/* Index for first 40MHz MCS CDD rate */
100#define WL_TX_POWER_MCS40_CDD_FIRST 76
101/* Index for first 40MHz MCS STBC rate */
102#define WL_TX_POWER_MCS40_STBC_FIRST 84
103/* Index for first 40MHz MCS SDM rate */
104#define WL_TX_POWER_MCS40_SDM_FIRST 92
105#define WL_TX_POWER_MCS_1_STREAM_NUM 8
106#define WL_TX_POWER_MCS_2_STREAM_NUM 8
107/* Index for 40MHz rate MCS 32 */
108#define WL_TX_POWER_MCS_32 100
109#define WL_TX_POWER_MCS_32_NUM 1
110
111/* sslpnphy specifics */
112/* Index for first 20MHz MCS SISO rate */
113#define WL_TX_POWER_MCS20_SISO_FIRST_SSN 12
114
115/* struct tx_power::flags bits */
116#define WL_TX_POWER_F_ENABLED 1
117#define WL_TX_POWER_F_HW 2
118#define WL_TX_POWER_F_MIMO 4
119#define WL_TX_POWER_F_SISO 8
120
121/* values to force tx/rx chain */
122#define BRCMS_N_TXRX_CHAIN0 0
123#define BRCMS_N_TXRX_CHAIN1 1
124
125struct brcms_phy;
126
127extern struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
128 struct brcms_info *wl,
129 struct brcms_c_info *wlc);
130extern void wlc_phy_shim_detach(struct phy_shim_info *physhim);
131
132/* PHY to WL utility functions */
133extern struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
134 void (*fn) (struct brcms_phy *pi),
135 void *arg, const char *name);
136extern void wlapi_free_timer(struct wlapi_timer *t);
137extern void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic);
138extern bool wlapi_del_timer(struct wlapi_timer *t);
139extern void wlapi_intrson(struct phy_shim_info *physhim);
140extern u32 wlapi_intrsoff(struct phy_shim_info *physhim);
141extern void wlapi_intrsrestore(struct phy_shim_info *physhim,
142 u32 macintmask);
143
144extern void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset,
145 u16 v);
146extern u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset);
147extern void wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx,
148 u16 mask, u16 val, int bands);
149extern void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags);
150extern void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim);
151extern void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode);
152extern void wlapi_enable_mac(struct phy_shim_info *physhim);
153extern void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask,
154 u32 val);
155extern void wlapi_bmac_phy_reset(struct phy_shim_info *physhim);
156extern void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw);
157extern void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk);
158extern void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk);
159extern void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on);
160extern void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim);
161extern void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *
162 physhim);
163extern void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *
164 physhim);
165extern void wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int o,
166 int len, void *buf);
167extern u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim,
168 u8 rate);
169extern void wlapi_ucode_sample_init(struct phy_shim_info *physhim);
170extern void wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint,
171 void *buf, int, u32 sel);
172extern void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint,
173 const void *buf, int, u32);
174
175extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim,
176 u32 phy_mode);
177extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim);
178extern char *wlapi_getvar(struct phy_shim_info *physhim, enum brcms_srom_id id);
179extern int wlapi_getintvar(struct phy_shim_info *physhim,
180 enum brcms_srom_id id);
181
182#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 000000000000..3b36e3acfd74
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c
@@ -0,0 +1,458 @@
1/*
2 * Copyright (c) 2011 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/delay.h>
18#include <linux/io.h>
19
20#include <brcm_hw_ids.h>
21#include <chipcommon.h>
22#include <brcmu_utils.h>
23#include "pub.h"
24#include "aiutils.h"
25#include "pmu.h"
26
27/*
28 * external LPO crystal frequency
29 */
30#define EXT_ILP_HZ 32768
31
32/*
33 * Duration for ILP clock frequency measurment in milliseconds
34 *
35 * remark: 1000 must be an integer multiple of this duration
36 */
37#define ILP_CALC_DUR 10
38
39/* Fields in pmucontrol */
40#define PCTL_ILP_DIV_MASK 0xffff0000
41#define PCTL_ILP_DIV_SHIFT 16
42#define PCTL_PLL_PLLCTL_UPD 0x00000400 /* rev 2 */
43#define PCTL_NOILP_ON_WAIT 0x00000200 /* rev 1 */
44#define PCTL_HT_REQ_EN 0x00000100
45#define PCTL_ALP_REQ_EN 0x00000080
46#define PCTL_XTALFREQ_MASK 0x0000007c
47#define PCTL_XTALFREQ_SHIFT 2
48#define PCTL_ILP_DIV_EN 0x00000002
49#define PCTL_LPO_SEL 0x00000001
50
51/* ILP clock */
52#define ILP_CLOCK 32000
53
54/* ALP clock on pre-PMU chips */
55#define ALP_CLOCK 20000000
56
57/* pmustatus */
58#define PST_EXTLPOAVAIL 0x0100
59#define PST_WDRESET 0x0080
60#define PST_INTPEND 0x0040
61#define PST_SBCLKST 0x0030
62#define PST_SBCLKST_ILP 0x0010
63#define PST_SBCLKST_ALP 0x0020
64#define PST_SBCLKST_HT 0x0030
65#define PST_ALPAVAIL 0x0008
66#define PST_HTAVAIL 0x0004
67#define PST_RESINIT 0x0003
68
69/* PMU resource bit position */
70#define PMURES_BIT(bit) (1 << (bit))
71
72/* PMU corerev and chip specific PLL controls.
73 * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary
74 * number to differentiate different PLLs controlled by the same PMU rev.
75 */
76/* pllcontrol registers:
77 * ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>,
78 * p1div, p2div, _bypass_sdmod
79 */
80#define PMU1_PLL0_PLLCTL0 0
81#define PMU1_PLL0_PLLCTL1 1
82#define PMU1_PLL0_PLLCTL2 2
83#define PMU1_PLL0_PLLCTL3 3
84#define PMU1_PLL0_PLLCTL4 4
85#define PMU1_PLL0_PLLCTL5 5
86
87/* pmu XtalFreqRatio */
88#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF
89#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000
90#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31
91
92/* 4313 resources */
93#define RES4313_BB_PU_RSRC 0
94#define RES4313_ILP_REQ_RSRC 1
95#define RES4313_XTAL_PU_RSRC 2
96#define RES4313_ALP_AVAIL_RSRC 3
97#define RES4313_RADIO_PU_RSRC 4
98#define RES4313_BG_PU_RSRC 5
99#define RES4313_VREG1P4_PU_RSRC 6
100#define RES4313_AFE_PWRSW_RSRC 7
101#define RES4313_RX_PWRSW_RSRC 8
102#define RES4313_TX_PWRSW_RSRC 9
103#define RES4313_BB_PWRSW_RSRC 10
104#define RES4313_SYNTH_PWRSW_RSRC 11
105#define RES4313_MISC_PWRSW_RSRC 12
106#define RES4313_BB_PLL_PWRSW_RSRC 13
107#define RES4313_HT_AVAIL_RSRC 14
108#define RES4313_MACPHY_CLK_AVAIL_RSRC 15
109
110/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
111static void si_pmu_res_masks(struct si_pub *sih, u32 * pmin, u32 * pmax)
112{
113 u32 min_mask = 0, max_mask = 0;
114 uint rsrcs;
115
116 /* # resources */
117 rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
118
119 /* determine min/max rsrc masks */
120 switch (sih->chip) {
121 case BCM43224_CHIP_ID:
122 case BCM43225_CHIP_ID:
123 /* ??? */
124 break;
125
126 case BCM4313_CHIP_ID:
127 min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
128 PMURES_BIT(RES4313_XTAL_PU_RSRC) |
129 PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
130 PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
131 max_mask = 0xffff;
132 break;
133 default:
134 break;
135 }
136
137 *pmin = min_mask;
138 *pmax = max_mask;
139}
140
141static void
142si_pmu_spuravoid_pllupdate(struct si_pub *sih, struct chipcregs __iomem *cc,
143 u8 spuravoid)
144{
145 u32 tmp = 0;
146
147 switch (sih->chip) {
148 case BCM43224_CHIP_ID:
149 case BCM43225_CHIP_ID:
150 if (spuravoid == 1) {
151 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
152 W_REG(&cc->pllcontrol_data, 0x11500010);
153 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
154 W_REG(&cc->pllcontrol_data, 0x000C0C06);
155 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
156 W_REG(&cc->pllcontrol_data, 0x0F600a08);
157 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
158 W_REG(&cc->pllcontrol_data, 0x00000000);
159 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
160 W_REG(&cc->pllcontrol_data, 0x2001E920);
161 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
162 W_REG(&cc->pllcontrol_data, 0x88888815);
163 } else {
164 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
165 W_REG(&cc->pllcontrol_data, 0x11100010);
166 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
167 W_REG(&cc->pllcontrol_data, 0x000c0c06);
168 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
169 W_REG(&cc->pllcontrol_data, 0x03000a08);
170 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
171 W_REG(&cc->pllcontrol_data, 0x00000000);
172 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
173 W_REG(&cc->pllcontrol_data, 0x200005c0);
174 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
175 W_REG(&cc->pllcontrol_data, 0x88888815);
176 }
177 tmp = 1 << 10;
178 break;
179
180 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
181 W_REG(&cc->pllcontrol_data, 0x11100008);
182 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
183 W_REG(&cc->pllcontrol_data, 0x0c000c06);
184 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
185 W_REG(&cc->pllcontrol_data, 0x03000a08);
186 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
187 W_REG(&cc->pllcontrol_data, 0x00000000);
188 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
189 W_REG(&cc->pllcontrol_data, 0x200005c0);
190 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
191 W_REG(&cc->pllcontrol_data, 0x88888855);
192
193 tmp = 1 << 10;
194 break;
195
196 default:
197 /* bail out */
198 return;
199 }
200
201 tmp |= R_REG(&cc->pmucontrol);
202 W_REG(&cc->pmucontrol, tmp);
203}
204
205u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
206{
207 uint delay = PMU_MAX_TRANSITION_DLY;
208
209 switch (sih->chip) {
210 case BCM43224_CHIP_ID:
211 case BCM43225_CHIP_ID:
212 case BCM4313_CHIP_ID:
213 delay = 3700;
214 break;
215 default:
216 break;
217 }
218
219 return (u16) delay;
220}
221
222void si_pmu_sprom_enable(struct si_pub *sih, bool enable)
223{
224 struct chipcregs __iomem *cc;
225 uint origidx;
226
227 /* Remember original core before switch to chipc */
228 origidx = ai_coreidx(sih);
229 cc = ai_setcoreidx(sih, SI_CC_IDX);
230
231 /* Return to original core */
232 ai_setcoreidx(sih, origidx);
233}
234
235/* Read/write a chipcontrol reg */
236u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
237{
238 ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, chipcontrol_addr),
239 ~0, reg);
240 return ai_corereg(sih, SI_CC_IDX,
241 offsetof(struct chipcregs, chipcontrol_data), mask,
242 val);
243}
244
245/* Read/write a regcontrol reg */
246u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
247{
248 ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, regcontrol_addr),
249 ~0, reg);
250 return ai_corereg(sih, SI_CC_IDX,
251 offsetof(struct chipcregs, regcontrol_data), mask,
252 val);
253}
254
255/* Read/write a pllcontrol reg */
256u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
257{
258 ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, pllcontrol_addr),
259 ~0, reg);
260 return ai_corereg(sih, SI_CC_IDX,
261 offsetof(struct chipcregs, pllcontrol_data), mask,
262 val);
263}
264
265/* PMU PLL update */
266void si_pmu_pllupd(struct si_pub *sih)
267{
268 ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, pmucontrol),
269 PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
270}
271
272/* query alp/xtal clock frequency */
273u32 si_pmu_alp_clock(struct si_pub *sih)
274{
275 u32 clock = ALP_CLOCK;
276
277 /* bail out with default */
278 if (!(sih->cccaps & CC_CAP_PMU))
279 return clock;
280
281 switch (sih->chip) {
282 case BCM43224_CHIP_ID:
283 case BCM43225_CHIP_ID:
284 case BCM4313_CHIP_ID:
285 /* always 20Mhz */
286 clock = 20000 * 1000;
287 break;
288 default:
289 break;
290 }
291
292 return clock;
293}
294
295void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid)
296{
297 struct chipcregs __iomem *cc;
298 uint origidx, intr_val;
299
300 /* Remember original core before switch to chipc */
301 cc = (struct chipcregs __iomem *)
302 ai_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
303
304 /* update the pll changes */
305 si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
306
307 /* Return to original core */
308 ai_restore_core(sih, origidx, intr_val);
309}
310
311/* initialize PMU */
312void si_pmu_init(struct si_pub *sih)
313{
314 struct chipcregs __iomem *cc;
315 uint origidx;
316
317 /* Remember original core before switch to chipc */
318 origidx = ai_coreidx(sih);
319 cc = ai_setcoreidx(sih, SI_CC_IDX);
320
321 if (sih->pmurev == 1)
322 AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
323 else if (sih->pmurev >= 2)
324 OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);
325
326 /* Return to original core */
327 ai_setcoreidx(sih, origidx);
328}
329
330/* initialize PMU chip controls and other chip level stuff */
331void si_pmu_chip_init(struct si_pub *sih)
332{
333 uint origidx;
334
335 /* Gate off SPROM clock and chip select signals */
336 si_pmu_sprom_enable(sih, false);
337
338 /* Remember original core */
339 origidx = ai_coreidx(sih);
340
341 /* Return to original core */
342 ai_setcoreidx(sih, origidx);
343}
344
345/* initialize PMU switch/regulators */
346void si_pmu_swreg_init(struct si_pub *sih)
347{
348}
349
350/* initialize PLL */
351void si_pmu_pll_init(struct si_pub *sih, uint xtalfreq)
352{
353 struct chipcregs __iomem *cc;
354 uint origidx;
355
356 /* Remember original core before switch to chipc */
357 origidx = ai_coreidx(sih);
358 cc = ai_setcoreidx(sih, SI_CC_IDX);
359
360 switch (sih->chip) {
361 case BCM4313_CHIP_ID:
362 case BCM43224_CHIP_ID:
363 case BCM43225_CHIP_ID:
364 /* ??? */
365 break;
366 default:
367 break;
368 }
369
370 /* Return to original core */
371 ai_setcoreidx(sih, origidx);
372}
373
374/* initialize PMU resources */
375void si_pmu_res_init(struct si_pub *sih)
376{
377 struct chipcregs __iomem *cc;
378 uint origidx;
379 u32 min_mask = 0, max_mask = 0;
380
381 /* Remember original core before switch to chipc */
382 origidx = ai_coreidx(sih);
383 cc = ai_setcoreidx(sih, SI_CC_IDX);
384
385 /* Determine min/max rsrc masks */
386 si_pmu_res_masks(sih, &min_mask, &max_mask);
387
388 /* It is required to program max_mask first and then min_mask */
389
390 /* Program max resource mask */
391
392 if (max_mask)
393 W_REG(&cc->max_res_mask, max_mask);
394
395 /* Program min resource mask */
396
397 if (min_mask)
398 W_REG(&cc->min_res_mask, min_mask);
399
400 /* Add some delay; allow resources to come up and settle. */
401 mdelay(2);
402
403 /* Return to original core */
404 ai_setcoreidx(sih, origidx);
405}
406
407u32 si_pmu_measure_alpclk(struct si_pub *sih)
408{
409 struct chipcregs __iomem *cc;
410 uint origidx;
411 u32 alp_khz;
412
413 if (sih->pmurev < 10)
414 return 0;
415
416 /* Remember original core before switch to chipc */
417 origidx = ai_coreidx(sih);
418 cc = ai_setcoreidx(sih, SI_CC_IDX);
419
420 if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
421 u32 ilp_ctr, alp_hz;
422
423 /*
424 * Enable the reg to measure the freq,
425 * in case it was disabled before
426 */
427 W_REG(&cc->pmu_xtalfreq,
428 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
429
430 /* Delay for well over 4 ILP clocks */
431 udelay(1000);
432
433 /* Read the latched number of ALP ticks per 4 ILP ticks */
434 ilp_ctr =
435 R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
436
437 /*
438 * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
439 * bit to save power
440 */
441 W_REG(&cc->pmu_xtalfreq, 0);
442
443 /* Calculate ALP frequency */
444 alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
445
446 /*
447 * Round to nearest 100KHz, and at
448 * the same time convert to KHz
449 */
450 alp_khz = (alp_hz + 50000) / 100000 * 100;
451 } else
452 alp_khz = 0;
453
454 /* Return to original core */
455 ai_setcoreidx(sih, origidx);
456
457 return alp_khz;
458}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pmu.h b/drivers/net/wireless/brcm80211/brcmsmac/pmu.h
new file mode 100644
index 000000000000..3a08c620640e
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17
18#ifndef _BRCM_PMU_H_
19#define _BRCM_PMU_H_
20
21#include "types.h"
22
23extern u16 si_pmu_fast_pwrup_delay(struct si_pub *sih);
24extern void si_pmu_sprom_enable(struct si_pub *sih, bool enable);
25extern u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
26extern u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
27extern u32 si_pmu_alp_clock(struct si_pub *sih);
28extern void si_pmu_pllupd(struct si_pub *sih);
29extern void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid);
30extern u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
31extern void si_pmu_init(struct si_pub *sih);
32extern void si_pmu_chip_init(struct si_pub *sih);
33extern void si_pmu_pll_init(struct si_pub *sih, u32 xtalfreq);
34extern void si_pmu_res_init(struct si_pub *sih);
35extern void si_pmu_swreg_init(struct si_pub *sih);
36extern u32 si_pmu_measure_alpclk(struct si_pub *sih);
37
38#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 000000000000..37bb2dcc113f
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -0,0 +1,634 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_PUB_H_
18#define _BRCM_PUB_H_
19
20#include <brcmu_wifi.h>
21#include "types.h"
22#include "defs.h"
23
24enum brcms_srom_id {
25 BRCMS_SROM_NULL,
26 BRCMS_SROM_CONT,
27 BRCMS_SROM_AA2G,
28 BRCMS_SROM_AA5G,
29 BRCMS_SROM_AG0,
30 BRCMS_SROM_AG1,
31 BRCMS_SROM_AG2,
32 BRCMS_SROM_AG3,
33 BRCMS_SROM_ANTSWCTL2G,
34 BRCMS_SROM_ANTSWCTL5G,
35 BRCMS_SROM_ANTSWITCH,
36 BRCMS_SROM_BOARDFLAGS2,
37 BRCMS_SROM_BOARDFLAGS,
38 BRCMS_SROM_BOARDNUM,
39 BRCMS_SROM_BOARDREV,
40 BRCMS_SROM_BOARDTYPE,
41 BRCMS_SROM_BW40PO,
42 BRCMS_SROM_BWDUPPO,
43 BRCMS_SROM_BXA2G,
44 BRCMS_SROM_BXA5G,
45 BRCMS_SROM_CC,
46 BRCMS_SROM_CCK2GPO,
47 BRCMS_SROM_CCKBW202GPO,
48 BRCMS_SROM_CCKBW20UL2GPO,
49 BRCMS_SROM_CCODE,
50 BRCMS_SROM_CDDPO,
51 BRCMS_SROM_DEVID,
52 BRCMS_SROM_ET1MACADDR,
53 BRCMS_SROM_EXTPAGAIN2G,
54 BRCMS_SROM_EXTPAGAIN5G,
55 BRCMS_SROM_FREQOFFSET_CORR,
56 BRCMS_SROM_HW_IQCAL_EN,
57 BRCMS_SROM_IL0MACADDR,
58 BRCMS_SROM_IQCAL_SWP_DIS,
59 BRCMS_SROM_LEDBH0,
60 BRCMS_SROM_LEDBH1,
61 BRCMS_SROM_LEDBH2,
62 BRCMS_SROM_LEDBH3,
63 BRCMS_SROM_LEDDC,
64 BRCMS_SROM_LEGOFDM40DUPPO,
65 BRCMS_SROM_LEGOFDMBW202GPO,
66 BRCMS_SROM_LEGOFDMBW205GHPO,
67 BRCMS_SROM_LEGOFDMBW205GLPO,
68 BRCMS_SROM_LEGOFDMBW205GMPO,
69 BRCMS_SROM_LEGOFDMBW20UL2GPO,
70 BRCMS_SROM_LEGOFDMBW20UL5GHPO,
71 BRCMS_SROM_LEGOFDMBW20UL5GLPO,
72 BRCMS_SROM_LEGOFDMBW20UL5GMPO,
73 BRCMS_SROM_MACADDR,
74 BRCMS_SROM_MCS2GPO0,
75 BRCMS_SROM_MCS2GPO1,
76 BRCMS_SROM_MCS2GPO2,
77 BRCMS_SROM_MCS2GPO3,
78 BRCMS_SROM_MCS2GPO4,
79 BRCMS_SROM_MCS2GPO5,
80 BRCMS_SROM_MCS2GPO6,
81 BRCMS_SROM_MCS2GPO7,
82 BRCMS_SROM_MCS32PO,
83 BRCMS_SROM_MCS5GHPO0,
84 BRCMS_SROM_MCS5GHPO1,
85 BRCMS_SROM_MCS5GHPO2,
86 BRCMS_SROM_MCS5GHPO3,
87 BRCMS_SROM_MCS5GHPO4,
88 BRCMS_SROM_MCS5GHPO5,
89 BRCMS_SROM_MCS5GHPO6,
90 BRCMS_SROM_MCS5GHPO7,
91 BRCMS_SROM_MCS5GLPO0,
92 BRCMS_SROM_MCS5GLPO1,
93 BRCMS_SROM_MCS5GLPO2,
94 BRCMS_SROM_MCS5GLPO3,
95 BRCMS_SROM_MCS5GLPO4,
96 BRCMS_SROM_MCS5GLPO5,
97 BRCMS_SROM_MCS5GLPO6,
98 BRCMS_SROM_MCS5GLPO7,
99 BRCMS_SROM_MCS5GPO0,
100 BRCMS_SROM_MCS5GPO1,
101 BRCMS_SROM_MCS5GPO2,
102 BRCMS_SROM_MCS5GPO3,
103 BRCMS_SROM_MCS5GPO4,
104 BRCMS_SROM_MCS5GPO5,
105 BRCMS_SROM_MCS5GPO6,
106 BRCMS_SROM_MCS5GPO7,
107 BRCMS_SROM_MCSBW202GPO,
108 BRCMS_SROM_MCSBW205GHPO,
109 BRCMS_SROM_MCSBW205GLPO,
110 BRCMS_SROM_MCSBW205GMPO,
111 BRCMS_SROM_MCSBW20UL2GPO,
112 BRCMS_SROM_MCSBW20UL5GHPO,
113 BRCMS_SROM_MCSBW20UL5GLPO,
114 BRCMS_SROM_MCSBW20UL5GMPO,
115 BRCMS_SROM_MCSBW402GPO,
116 BRCMS_SROM_MCSBW405GHPO,
117 BRCMS_SROM_MCSBW405GLPO,
118 BRCMS_SROM_MCSBW405GMPO,
119 BRCMS_SROM_MEASPOWER,
120 BRCMS_SROM_OFDM2GPO,
121 BRCMS_SROM_OFDM5GHPO,
122 BRCMS_SROM_OFDM5GLPO,
123 BRCMS_SROM_OFDM5GPO,
124 BRCMS_SROM_OPO,
125 BRCMS_SROM_PA0B0,
126 BRCMS_SROM_PA0B1,
127 BRCMS_SROM_PA0B2,
128 BRCMS_SROM_PA0ITSSIT,
129 BRCMS_SROM_PA0MAXPWR,
130 BRCMS_SROM_PA1B0,
131 BRCMS_SROM_PA1B1,
132 BRCMS_SROM_PA1B2,
133 BRCMS_SROM_PA1HIB0,
134 BRCMS_SROM_PA1HIB1,
135 BRCMS_SROM_PA1HIB2,
136 BRCMS_SROM_PA1HIMAXPWR,
137 BRCMS_SROM_PA1ITSSIT,
138 BRCMS_SROM_PA1LOB0,
139 BRCMS_SROM_PA1LOB1,
140 BRCMS_SROM_PA1LOB2,
141 BRCMS_SROM_PA1LOMAXPWR,
142 BRCMS_SROM_PA1MAXPWR,
143 BRCMS_SROM_PDETRANGE2G,
144 BRCMS_SROM_PDETRANGE5G,
145 BRCMS_SROM_PHYCAL_TEMPDELTA,
146 BRCMS_SROM_RAWTEMPSENSE,
147 BRCMS_SROM_REGREV,
148 BRCMS_SROM_REV,
149 BRCMS_SROM_RSSISAV2G,
150 BRCMS_SROM_RSSISAV5G,
151 BRCMS_SROM_RSSISMC2G,
152 BRCMS_SROM_RSSISMC5G,
153 BRCMS_SROM_RSSISMF2G,
154 BRCMS_SROM_RSSISMF5G,
155 BRCMS_SROM_RXCHAIN,
156 BRCMS_SROM_RXPO2G,
157 BRCMS_SROM_RXPO5G,
158 BRCMS_SROM_STBCPO,
159 BRCMS_SROM_TEMPCORRX,
160 BRCMS_SROM_TEMPOFFSET,
161 BRCMS_SROM_TEMPSENSE_OPTION,
162 BRCMS_SROM_TEMPSENSE_SLOPE,
163 BRCMS_SROM_TEMPTHRESH,
164 BRCMS_SROM_TRI2G,
165 BRCMS_SROM_TRI5GH,
166 BRCMS_SROM_TRI5GL,
167 BRCMS_SROM_TRI5G,
168 BRCMS_SROM_TRISO2G,
169 BRCMS_SROM_TRISO5G,
170 BRCMS_SROM_TSSIPOS2G,
171 BRCMS_SROM_TSSIPOS5G,
172 BRCMS_SROM_TXCHAIN,
173 BRCMS_SROM_TXPID2GA0,
174 BRCMS_SROM_TXPID2GA1,
175 BRCMS_SROM_TXPID2GA2,
176 BRCMS_SROM_TXPID2GA3,
177 BRCMS_SROM_TXPID5GA0,
178 BRCMS_SROM_TXPID5GA1,
179 BRCMS_SROM_TXPID5GA2,
180 BRCMS_SROM_TXPID5GA3,
181 BRCMS_SROM_TXPID5GHA0,
182 BRCMS_SROM_TXPID5GHA1,
183 BRCMS_SROM_TXPID5GHA2,
184 BRCMS_SROM_TXPID5GHA3,
185 BRCMS_SROM_TXPID5GLA0,
186 BRCMS_SROM_TXPID5GLA1,
187 BRCMS_SROM_TXPID5GLA2,
188 BRCMS_SROM_TXPID5GLA3,
189 /*
190 * per-path identifiers (see srom.c)
191 */
192 BRCMS_SROM_ITT2GA0,
193 BRCMS_SROM_ITT2GA1,
194 BRCMS_SROM_ITT2GA2,
195 BRCMS_SROM_ITT2GA3,
196 BRCMS_SROM_ITT5GA0,
197 BRCMS_SROM_ITT5GA1,
198 BRCMS_SROM_ITT5GA2,
199 BRCMS_SROM_ITT5GA3,
200 BRCMS_SROM_MAXP2GA0,
201 BRCMS_SROM_MAXP2GA1,
202 BRCMS_SROM_MAXP2GA2,
203 BRCMS_SROM_MAXP2GA3,
204 BRCMS_SROM_MAXP5GA0,
205 BRCMS_SROM_MAXP5GA1,
206 BRCMS_SROM_MAXP5GA2,
207 BRCMS_SROM_MAXP5GA3,
208 BRCMS_SROM_MAXP5GHA0,
209 BRCMS_SROM_MAXP5GHA1,
210 BRCMS_SROM_MAXP5GHA2,
211 BRCMS_SROM_MAXP5GHA3,
212 BRCMS_SROM_MAXP5GLA0,
213 BRCMS_SROM_MAXP5GLA1,
214 BRCMS_SROM_MAXP5GLA2,
215 BRCMS_SROM_MAXP5GLA3,
216 BRCMS_SROM_PA2GW0A0,
217 BRCMS_SROM_PA2GW0A1,
218 BRCMS_SROM_PA2GW0A2,
219 BRCMS_SROM_PA2GW0A3,
220 BRCMS_SROM_PA2GW1A0,
221 BRCMS_SROM_PA2GW1A1,
222 BRCMS_SROM_PA2GW1A2,
223 BRCMS_SROM_PA2GW1A3,
224 BRCMS_SROM_PA2GW2A0,
225 BRCMS_SROM_PA2GW2A1,
226 BRCMS_SROM_PA2GW2A2,
227 BRCMS_SROM_PA2GW2A3,
228 BRCMS_SROM_PA2GW3A0,
229 BRCMS_SROM_PA2GW3A1,
230 BRCMS_SROM_PA2GW3A2,
231 BRCMS_SROM_PA2GW3A3,
232 BRCMS_SROM_PA5GHW0A0,
233 BRCMS_SROM_PA5GHW0A1,
234 BRCMS_SROM_PA5GHW0A2,
235 BRCMS_SROM_PA5GHW0A3,
236 BRCMS_SROM_PA5GHW1A0,
237 BRCMS_SROM_PA5GHW1A1,
238 BRCMS_SROM_PA5GHW1A2,
239 BRCMS_SROM_PA5GHW1A3,
240 BRCMS_SROM_PA5GHW2A0,
241 BRCMS_SROM_PA5GHW2A1,
242 BRCMS_SROM_PA5GHW2A2,
243 BRCMS_SROM_PA5GHW2A3,
244 BRCMS_SROM_PA5GHW3A0,
245 BRCMS_SROM_PA5GHW3A1,
246 BRCMS_SROM_PA5GHW3A2,
247 BRCMS_SROM_PA5GHW3A3,
248 BRCMS_SROM_PA5GLW0A0,
249 BRCMS_SROM_PA5GLW0A1,
250 BRCMS_SROM_PA5GLW0A2,
251 BRCMS_SROM_PA5GLW0A3,
252 BRCMS_SROM_PA5GLW1A0,
253 BRCMS_SROM_PA5GLW1A1,
254 BRCMS_SROM_PA5GLW1A2,
255 BRCMS_SROM_PA5GLW1A3,
256 BRCMS_SROM_PA5GLW2A0,
257 BRCMS_SROM_PA5GLW2A1,
258 BRCMS_SROM_PA5GLW2A2,
259 BRCMS_SROM_PA5GLW2A3,
260 BRCMS_SROM_PA5GLW3A0,
261 BRCMS_SROM_PA5GLW3A1,
262 BRCMS_SROM_PA5GLW3A2,
263 BRCMS_SROM_PA5GLW3A3,
264 BRCMS_SROM_PA5GW0A0,
265 BRCMS_SROM_PA5GW0A1,
266 BRCMS_SROM_PA5GW0A2,
267 BRCMS_SROM_PA5GW0A3,
268 BRCMS_SROM_PA5GW1A0,
269 BRCMS_SROM_PA5GW1A1,
270 BRCMS_SROM_PA5GW1A2,
271 BRCMS_SROM_PA5GW1A3,
272 BRCMS_SROM_PA5GW2A0,
273 BRCMS_SROM_PA5GW2A1,
274 BRCMS_SROM_PA5GW2A2,
275 BRCMS_SROM_PA5GW2A3,
276 BRCMS_SROM_PA5GW3A0,
277 BRCMS_SROM_PA5GW3A1,
278 BRCMS_SROM_PA5GW3A2,
279 BRCMS_SROM_PA5GW3A3,
280};
281
282#define BRCMS_NUMRATES 16 /* max # of rates in a rateset */
283#define D11_PHY_HDR_LEN 6 /* Phy header length - 6 bytes */
284
285/* phy types */
286#define PHY_TYPE_A 0 /* Phy type A */
287#define PHY_TYPE_G 2 /* Phy type G */
288#define PHY_TYPE_N 4 /* Phy type N */
289#define PHY_TYPE_LP 5 /* Phy type Low Power A/B/G */
290#define PHY_TYPE_SSN 6 /* Phy type Single Stream N */
291#define PHY_TYPE_LCN 8 /* Phy type Single Stream N */
292#define PHY_TYPE_LCNXN 9 /* Phy type 2-stream N */
293#define PHY_TYPE_HT 7 /* Phy type 3-Stream N */
294
295/* bw */
296#define BRCMS_10_MHZ 10 /* 10Mhz nphy channel bandwidth */
297#define BRCMS_20_MHZ 20 /* 20Mhz nphy channel bandwidth */
298#define BRCMS_40_MHZ 40 /* 40Mhz nphy channel bandwidth */
299
300#define BRCMS_RSSI_MINVAL -200 /* Low value, e.g. for forcing roam */
301#define BRCMS_RSSI_NO_SIGNAL -91 /* NDIS RSSI link quality cutoffs */
302#define BRCMS_RSSI_VERY_LOW -80 /* Very low quality cutoffs */
303#define BRCMS_RSSI_LOW -70 /* Low quality cutoffs */
304#define BRCMS_RSSI_GOOD -68 /* Good quality cutoffs */
305#define BRCMS_RSSI_VERY_GOOD -58 /* Very good quality cutoffs */
306#define BRCMS_RSSI_EXCELLENT -57 /* Excellent quality cutoffs */
307
308/* a large TX Power as an init value to factor out of min() calculations,
309 * keep low enough to fit in an s8, units are .25 dBm
310 */
311#define BRCMS_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */
312
313/* rate related definitions */
314#define BRCMS_RATE_FLAG 0x80 /* Flag to indicate it is a basic rate */
315#define BRCMS_RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */
316
317/* legacy rx Antenna diversity for SISO rates */
318#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */
319#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */
320#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */
321#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */
322#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */
323/* default antdiv setting */
324#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0
325
326/* legacy rx Antenna diversity for SISO rates */
327/* Tx on antenna 0, "legacy term Main" */
328#define ANT_TX_FORCE_0 0
329/* Tx on antenna 1, "legacy term Aux" */
330#define ANT_TX_FORCE_1 1
331/* Tx on phy's last good Rx antenna */
332#define ANT_TX_LAST_RX 3
333/* driver's default tx antenna setting */
334#define ANT_TX_DEF 3
335
336/* Tx Chain values */
337/* def bitmap of txchain */
338#define TXCHAIN_DEF 0x1
339/* default bitmap of tx chains for nphy */
340#define TXCHAIN_DEF_NPHY 0x3
341/* default bitmap of tx chains for nphy */
342#define TXCHAIN_DEF_HTPHY 0x7
343/* def bitmap of rxchain */
344#define RXCHAIN_DEF 0x1
345/* default bitmap of rx chains for nphy */
346#define RXCHAIN_DEF_NPHY 0x3
347/* default bitmap of rx chains for nphy */
348#define RXCHAIN_DEF_HTPHY 0x7
349/* no antenna switch */
350#define ANTSWITCH_NONE 0
351/* antenna switch on 4321CB2, 2of3 */
352#define ANTSWITCH_TYPE_1 1
353/* antenna switch on 4321MPCI, 2of3 */
354#define ANTSWITCH_TYPE_2 2
355/* antenna switch on 4322, 2of3 */
356#define ANTSWITCH_TYPE_3 3
357
358#define RXBUFSZ PKTBUFSZ
359
360#define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */
361
362struct brcm_rateset {
363 /* # rates in this set */
364 u32 count;
365 /* rates in 500kbps units w/hi bit set if basic */
366 u8 rates[WL_NUMRATES];
367};
368
369struct brcms_c_rateset {
370 uint count; /* number of rates in rates[] */
371 /* rates in 500kbps units w/hi bit set if basic */
372 u8 rates[BRCMS_NUMRATES];
373 u8 htphy_membership; /* HT PHY Membership */
374 u8 mcs[MCSSET_LEN]; /* supported mcs index bit map */
375};
376
377/* All the HT-specific default advertised capabilities (including AMPDU)
378 * should be grouped here at one place
379 */
380#define AMPDU_DEF_MPDU_DENSITY 6 /* default mpdu density (110 ==> 4us) */
381
382/* wlc internal bss_info */
383struct brcms_bss_info {
384 u8 BSSID[ETH_ALEN]; /* network BSSID */
385 u16 flags; /* flags for internal attributes */
386 u8 SSID_len; /* the length of SSID */
387 u8 SSID[32]; /* SSID string */
388 s16 RSSI; /* receive signal strength (in dBm) */
389 s16 SNR; /* receive signal SNR in dB */
390 u16 beacon_period; /* units are Kusec */
391 u16 chanspec; /* Channel num, bw, ctrl_sb and band */
392 struct brcms_c_rateset rateset; /* supported rates */
393};
394
395#define MAC80211_PROMISC_BCNS (1 << 0)
396#define MAC80211_SCAN (1 << 1)
397
398/*
399 * Public portion of common driver state structure.
400 * The wlc handle points at this.
401 */
402struct brcms_pub {
403 struct brcms_c_info *wlc;
404 struct ieee80211_hw *ieee_hw;
405 struct scb_ampdu *global_ampdu;
406 uint mac80211_state;
407 uint unit; /* device instance number */
408 uint corerev; /* core revision */
409 struct si_pub *sih; /* SI handle (cookie for siutils calls) */
410 bool up; /* interface up and running */
411 bool hw_off; /* HW is off */
412 bool hw_up; /* one time hw up/down */
413 bool _piomode; /* true if pio mode */
414 uint _nbands; /* # bands supported */
415 uint now; /* # elapsed seconds */
416
417 bool promisc; /* promiscuous destination address */
418 bool delayed_down; /* down delayed */
419 bool associated; /* true:part of [I]BSS, false: not */
420 /* (union of stas_associated, aps_associated) */
421 bool _ampdu; /* ampdu enabled or not */
422 u8 _n_enab; /* bitmap of 11N + HT support */
423
424 u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */
425
426 int bcmerror; /* last bcm error */
427
428 u32 radio_disabled; /* bit vector for radio disabled reasons */
429
430 u16 boardrev; /* version # of particular board */
431 u8 sromrev; /* version # of the srom */
432 char srom_ccode[BRCM_CNTRY_BUF_SZ]; /* Country Code in SROM */
433 u32 boardflags; /* Board specific flags from srom */
434 u32 boardflags2; /* More board flags if sromrev >= 4 */
435 bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */
436
437 struct wl_cnt *_cnt; /* low-level counters in driver */
438};
439
440enum wlc_par_id {
441 IOV_MPC = 1,
442 IOV_RTSTHRESH,
443 IOV_QTXPOWER,
444 IOV_BCN_LI_BCN /* Beacon listen interval in # of beacons */
445};
446
447/***********************************************
448 * Feature-related macros to optimize out code *
449 * *********************************************
450 */
451
452#define ENAB_1x1 0x01
453#define ENAB_2x2 0x02
454#define ENAB_3x3 0x04
455#define ENAB_4x4 0x08
456#define SUPPORT_11N (ENAB_1x1|ENAB_2x2)
457#define SUPPORT_HT (ENAB_1x1|ENAB_2x2|ENAB_3x3)
458
459/* WL11N Support */
460#define AMPDU_AGG_HOST 1
461
462/* pri is priority encoded in the packet. This maps the Packet priority to
463 * enqueue precedence as defined in wlc_prec_map
464 */
465extern const u8 wlc_prio2prec_map[];
466#define BRCMS_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7]
467
468#define BRCMS_PREC_COUNT 16 /* Max precedence level implemented */
469
470/* Mask to describe all precedence levels */
471#define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT)
472
473/*
474 * This maps priority to one precedence higher - Used by PS-Poll response
475 * packets to simulate enqueue-at-head operation, but still maintain the
476 * order on the queue
477 */
478#define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\
479 BRCMS_PREC_COUNT - 1)
480
481/* Define a bitmap of precedences comprised by each AC */
482#define BRCMS_PREC_BMP_AC_BE (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \
483 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \
484 NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) | \
485 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
486#define BRCMS_PREC_BMP_AC_BK (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \
487 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \
488 NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) | \
489 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
490#define BRCMS_PREC_BMP_AC_VI (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \
491 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \
492 NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) | \
493 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
494#define BRCMS_PREC_BMP_AC_VO (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \
495 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \
496 NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) | \
497 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
498
499/* network protection config */
500#define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */
501#define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */
502#define BRCMS_PROT_G_USER 3 /* gmode specified by user */
503#define BRCMS_PROT_OVERLAP 4 /* overlap */
504#define BRCMS_PROT_N_USER 10 /* nmode specified by user */
505#define BRCMS_PROT_N_CFG 11 /* n protection */
506#define BRCMS_PROT_N_CFG_OVR 12 /* n protection override */
507#define BRCMS_PROT_N_NONGF 13 /* non-GF protection */
508#define BRCMS_PROT_N_NONGF_OVR 14 /* non-GF protection override */
509#define BRCMS_PROT_N_PAM_OVR 15 /* n preamble override */
510#define BRCMS_PROT_N_OBSS 16 /* non-HT OBSS present */
511
512/*
513 * 54g modes (basic bits may still be overridden)
514 *
515 * GMODE_LEGACY_B
516 * Rateset: 1b, 2b, 5.5, 11
517 * Preamble: Long
518 * Shortslot: Off
519 * GMODE_AUTO
520 * Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
521 * Extended Rateset: 6, 9, 12, 48
522 * Preamble: Long
523 * Shortslot: Auto
524 * GMODE_ONLY
525 * Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54
526 * Extended Rateset: 6b, 9, 12b, 48
527 * Preamble: Short required
528 * Shortslot: Auto
529 * GMODE_B_DEFERRED
530 * Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
531 * Extended Rateset: 6, 9, 12, 48
532 * Preamble: Long
533 * Shortslot: On
534 * GMODE_PERFORMANCE
535 * Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54
536 * Preamble: Short required
537 * Shortslot: On and required
538 * GMODE_LRS
539 * Rateset: 1b, 2b, 5.5b, 11b
540 * Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54
541 * Preamble: Long
542 * Shortslot: Auto
543 */
544#define GMODE_LEGACY_B 0
545#define GMODE_AUTO 1
546#define GMODE_ONLY 2
547#define GMODE_B_DEFERRED 3
548#define GMODE_PERFORMANCE 4
549#define GMODE_LRS 5
550#define GMODE_MAX 6
551
552/* MCS values greater than this enable multiple streams */
553#define HIGHEST_SINGLE_STREAM_MCS 7
554
555#define MAXBANDS 2 /* Maximum #of bands */
556
557/* max number of antenna configurations */
558#define ANT_SELCFG_MAX 4
559
560struct brcms_antselcfg {
561 u8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */
562 u8 num_antcfg; /* number of available antenna configurations */
563};
564
565/* common functions for every port */
566extern struct brcms_c_info *
567brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit,
568 bool piomode, void __iomem *regsva, struct pci_dev *btparam,
569 uint *perr);
570extern uint brcms_c_detach(struct brcms_c_info *wlc);
571extern int brcms_c_up(struct brcms_c_info *wlc);
572extern uint brcms_c_down(struct brcms_c_info *wlc);
573
574extern bool brcms_c_chipmatch(u16 vendor, u16 device);
575extern void brcms_c_init(struct brcms_c_info *wlc);
576extern void brcms_c_reset(struct brcms_c_info *wlc);
577
578extern void brcms_c_intrson(struct brcms_c_info *wlc);
579extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc);
580extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask);
581extern bool brcms_c_intrsupd(struct brcms_c_info *wlc);
582extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc);
583extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded);
584extern void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
585 struct sk_buff *sdu,
586 struct ieee80211_hw *hw);
587extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid);
588extern void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx,
589 int val);
590extern int brcms_c_get_header_len(void);
591extern void brcms_c_set_addrmatch(struct brcms_c_info *wlc,
592 int match_reg_offset,
593 const u8 *addr);
594extern void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
595 const struct ieee80211_tx_queue_params *arg,
596 bool suspend);
597extern struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc);
598extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
599 struct ieee80211_sta *sta, u16 tid);
600extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
601 u8 ba_wsize, uint max_rx_ampdu_bytes);
602extern char *getvar(struct si_pub *sih, enum brcms_srom_id id);
603extern int getintvar(struct si_pub *sih, enum brcms_srom_id id);
604extern int brcms_c_module_register(struct brcms_pub *pub,
605 const char *name, struct brcms_info *hdl,
606 int (*down_fn)(void *handle));
607extern int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
608 struct brcms_info *hdl);
609extern void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc);
610extern void brcms_c_enable_mac(struct brcms_c_info *wlc);
611extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state);
612extern void brcms_c_scan_start(struct brcms_c_info *wlc);
613extern void brcms_c_scan_stop(struct brcms_c_info *wlc);
614extern int brcms_c_get_curband(struct brcms_c_info *wlc);
615extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc,
616 bool drop);
617extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel);
618extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl);
619extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
620 struct brcm_rateset *currs);
621extern int brcms_c_set_rateset(struct brcms_c_info *wlc,
622 struct brcm_rateset *rs);
623extern int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period);
624extern u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx);
625extern void brcms_c_set_shortslot_override(struct brcms_c_info *wlc,
626 s8 sslot_override);
627extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc,
628 u8 interval);
629extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
630extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
631extern void brcms_c_set_radio_mpc(struct brcms_c_info *wlc, bool mpc);
632extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
633
634#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 000000000000..0a0c0ad4f96f
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/rate.c
@@ -0,0 +1,514 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <brcmu_wifi.h>
18#include <brcmu_utils.h>
19
20#include "d11.h"
21#include "pub.h"
22#include "rate.h"
23
24/*
25 * Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate
26 * value
27 */
28const u8 rate_info[BRCM_MAXRATE + 1] = {
29 /* 0 1 2 3 4 5 6 7 8 9 */
30/* 0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
31/* 10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00,
32/* 20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00,
33/* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
34/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00,
35/* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36/* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37/* 70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
40/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c
41};
42
43/* rates are in units of Kbps */
44const struct brcms_mcs_info mcs_table[MCS_TABLE_SIZE] = {
45 /* MCS 0: SS 1, MOD: BPSK, CR 1/2 */
46 {6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00,
47 BRCM_RATE_6M},
48 /* MCS 1: SS 1, MOD: QPSK, CR 1/2 */
49 {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08,
50 BRCM_RATE_12M},
51 /* MCS 2: SS 1, MOD: QPSK, CR 3/4 */
52 {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A,
53 BRCM_RATE_18M},
54 /* MCS 3: SS 1, MOD: 16QAM, CR 1/2 */
55 {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10,
56 BRCM_RATE_24M},
57 /* MCS 4: SS 1, MOD: 16QAM, CR 3/4 */
58 {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12,
59 BRCM_RATE_36M},
60 /* MCS 5: SS 1, MOD: 64QAM, CR 2/3 */
61 {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19,
62 BRCM_RATE_48M},
63 /* MCS 6: SS 1, MOD: 64QAM, CR 3/4 */
64 {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A,
65 BRCM_RATE_54M},
66 /* MCS 7: SS 1, MOD: 64QAM, CR 5/6 */
67 {65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C,
68 BRCM_RATE_54M},
69 /* MCS 8: SS 2, MOD: BPSK, CR 1/2 */
70 {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40,
71 BRCM_RATE_6M},
72 /* MCS 9: SS 2, MOD: QPSK, CR 1/2 */
73 {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48,
74 BRCM_RATE_12M},
75 /* MCS 10: SS 2, MOD: QPSK, CR 3/4 */
76 {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A,
77 BRCM_RATE_18M},
78 /* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */
79 {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50,
80 BRCM_RATE_24M},
81 /* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */
82 {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52,
83 BRCM_RATE_36M},
84 /* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */
85 {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59,
86 BRCM_RATE_48M},
87 /* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */
88 {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A,
89 BRCM_RATE_54M},
90 /* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */
91 {130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C,
92 BRCM_RATE_54M},
93 /* MCS 16: SS 3, MOD: BPSK, CR 1/2 */
94 {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80,
95 BRCM_RATE_6M},
96 /* MCS 17: SS 3, MOD: QPSK, CR 1/2 */
97 {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88,
98 BRCM_RATE_12M},
99 /* MCS 18: SS 3, MOD: QPSK, CR 3/4 */
100 {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A,
101 BRCM_RATE_18M},
102 /* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */
103 {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90,
104 BRCM_RATE_24M},
105 /* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */
106 {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92,
107 BRCM_RATE_36M},
108 /* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */
109 {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99,
110 BRCM_RATE_48M},
111 /* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */
112 {175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A,
113 BRCM_RATE_54M},
114 /* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */
115 {195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B,
116 BRCM_RATE_54M},
117 /* MCS 24: SS 4, MOD: BPSK, CR 1/2 */
118 {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0,
119 BRCM_RATE_6M},
120 /* MCS 25: SS 4, MOD: QPSK, CR 1/2 */
121 {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8,
122 BRCM_RATE_12M},
123 /* MCS 26: SS 4, MOD: QPSK, CR 3/4 */
124 {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA,
125 BRCM_RATE_18M},
126 /* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */
127 {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0,
128 BRCM_RATE_24M},
129 /* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */
130 {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2,
131 BRCM_RATE_36M},
132 /* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */
133 {208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9,
134 BRCM_RATE_48M},
135 /* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */
136 {234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA,
137 BRCM_RATE_54M},
138 /* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */
139 {260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB,
140 BRCM_RATE_54M},
141 /* MCS 32: SS 1, MOD: BPSK, CR 1/2 */
142 {0, 6000, 0, CEIL(6000 * 10, 9), 0x00, BRCM_RATE_6M},
143};
144
145/*
146 * phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams
147 * Number of spatial streams: always 1 other fields: refer to table 78 of
148 * section 17.3.2.2 of the original .11a standard
149 */
150struct legacy_phycfg {
151 u32 rate_ofdm; /* ofdm mac rate */
152 /* phy ctl byte 3, code rate, modulation type, # of streams */
153 u8 tx_phy_ctl3;
154};
155
156/* Number of legacy_rate_cfg entries in the table */
157#define LEGACY_PHYCFG_TABLE_SIZE 12
158
159/*
160 * In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate
161 * Eventually MIMOPHY would also be converted to this format
162 * 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps
163 */
164static const struct
165legacy_phycfg legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = {
166 {BRCM_RATE_1M, 0x00}, /* CCK 1Mbps, data rate 0 */
167 {BRCM_RATE_2M, 0x08}, /* CCK 2Mbps, data rate 1 */
168 {BRCM_RATE_5M5, 0x10}, /* CCK 5.5Mbps, data rate 2 */
169 {BRCM_RATE_11M, 0x18}, /* CCK 11Mbps, data rate 3 */
170 /* OFDM 6Mbps, code rate 1/2, BPSK, 1 spatial stream */
171 {BRCM_RATE_6M, 0x00},
172 /* OFDM 9Mbps, code rate 3/4, BPSK, 1 spatial stream */
173 {BRCM_RATE_9M, 0x02},
174 /* OFDM 12Mbps, code rate 1/2, QPSK, 1 spatial stream */
175 {BRCM_RATE_12M, 0x08},
176 /* OFDM 18Mbps, code rate 3/4, QPSK, 1 spatial stream */
177 {BRCM_RATE_18M, 0x0A},
178 /* OFDM 24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */
179 {BRCM_RATE_24M, 0x10},
180 /* OFDM 36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */
181 {BRCM_RATE_36M, 0x12},
182 /* OFDM 48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */
183 {BRCM_RATE_48M, 0x19},
184 /* OFDM 54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */
185 {BRCM_RATE_54M, 0x1A},
186};
187
188/* Hardware rates (also encodes default basic rates) */
189
190const struct brcms_c_rateset cck_ofdm_mimo_rates = {
191 12,
192 /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, */
193 { 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
194 /* 54 Mbps */
195 0x6c},
196 0x00,
197 { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198 0x00, 0x00, 0x00, 0x00, 0x00}
199};
200
201const struct brcms_c_rateset ofdm_mimo_rates = {
202 8,
203 /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
204 { 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
205 0x00,
206 { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00, 0x00}
208};
209
210/* Default ratesets that include MCS32 for 40BW channels */
211static const struct brcms_c_rateset cck_ofdm_40bw_mimo_rates = {
212 12,
213 /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48 */
214 { 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
215 /* 54 Mbps */
216 0x6c},
217 0x00,
218 { 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0x00, 0x00, 0x00, 0x00, 0x00}
220};
221
222static const struct brcms_c_rateset ofdm_40bw_mimo_rates = {
223 8,
224 /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
225 { 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
226 0x00,
227 { 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0x00, 0x00, 0x00, 0x00, 0x00}
229};
230
231const struct brcms_c_rateset cck_ofdm_rates = {
232 12,
233 /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48,*/
234 { 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
235 /*54 Mbps */
236 0x6c},
237 0x00,
238 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x00, 0x00, 0x00, 0x00, 0x00}
240};
241
242const struct brcms_c_rateset gphy_legacy_rates = {
243 4,
244 /* 1b, 2b, 5.5b, 11b Mbps */
245 { 0x82, 0x84, 0x8b, 0x96},
246 0x00,
247 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248 0x00, 0x00, 0x00, 0x00, 0x00}
249};
250
251const struct brcms_c_rateset ofdm_rates = {
252 8,
253 /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
254 { 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
255 0x00,
256 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257 0x00, 0x00, 0x00, 0x00, 0x00}
258};
259
260const struct brcms_c_rateset cck_rates = {
261 4,
262 /* 1b, 2b, 5.5, 11 Mbps */
263 { 0x82, 0x84, 0x0b, 0x16},
264 0x00,
265 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
266 0x00, 0x00, 0x00, 0x00, 0x00}
267};
268
269/* check if rateset is valid.
270 * if check_brate is true, rateset without a basic rate is considered NOT valid.
271 */
272static bool brcms_c_rateset_valid(struct brcms_c_rateset *rs, bool check_brate)
273{
274 uint idx;
275
276 if (!rs->count)
277 return false;
278
279 if (!check_brate)
280 return true;
281
282 /* error if no basic rates */
283 for (idx = 0; idx < rs->count; idx++) {
284 if (rs->rates[idx] & BRCMS_RATE_FLAG)
285 return true;
286 }
287 return false;
288}
289
290void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams)
291{
292 int i;
293 for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++)
294 rs->mcs[i] = 0;
295}
296
297/*
298 * filter based on hardware rateset, and sort filtered rateset with basic
299 * bit(s) preserved, and check if resulting rateset is valid.
300*/
301bool
302brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs,
303 const struct brcms_c_rateset *hw_rs,
304 bool check_brate, u8 txstreams)
305{
306 u8 rateset[BRCM_MAXRATE + 1];
307 u8 r;
308 uint count;
309 uint i;
310
311 memset(rateset, 0, sizeof(rateset));
312 count = rs->count;
313
314 for (i = 0; i < count; i++) {
315 /* mask off "basic rate" bit, BRCMS_RATE_FLAG */
316 r = (int)rs->rates[i] & BRCMS_RATE_MASK;
317 if ((r > BRCM_MAXRATE) || (rate_info[r] == 0))
318 continue;
319 rateset[r] = rs->rates[i]; /* preserve basic bit! */
320 }
321
322 /* fill out the rates in order, looking at only supported rates */
323 count = 0;
324 for (i = 0; i < hw_rs->count; i++) {
325 r = hw_rs->rates[i] & BRCMS_RATE_MASK;
326 if (rateset[r])
327 rs->rates[count++] = rateset[r];
328 }
329
330 rs->count = count;
331
332 /* only set the mcs rate bit if the equivalent hw mcs bit is set */
333 for (i = 0; i < MCSSET_LEN; i++)
334 rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]);
335
336 if (brcms_c_rateset_valid(rs, check_brate))
337 return true;
338 else
339 return false;
340}
341
342/* calculate the rate of a rx'd frame and return it as a ratespec */
343u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp)
344{
345 int phy_type;
346 u32 rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT;
347
348 phy_type =
349 ((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT);
350
351 if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) ||
352 (phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) {
353 switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) {
354 case PRXS0_CCK:
355 rspec =
356 cck_phy2mac_rate(
357 ((struct cck_phy_hdr *) plcp)->signal);
358 break;
359 case PRXS0_OFDM:
360 rspec =
361 ofdm_phy2mac_rate(
362 ((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
363 break;
364 case PRXS0_PREN:
365 rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE;
366 if (plcp[0] & MIMO_PLCP_40MHZ) {
367 /* indicate rspec is for 40 MHz mode */
368 rspec &= ~RSPEC_BW_MASK;
369 rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
370 }
371 break;
372 case PRXS0_STDN:
373 /* fallthru */
374 default:
375 /* not supported, error condition */
376 break;
377 }
378 if (plcp3_issgi(plcp[3]))
379 rspec |= RSPEC_SHORT_GI;
380 } else
381 if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM))
382 rspec = ofdm_phy2mac_rate(
383 ((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
384 else
385 rspec = cck_phy2mac_rate(
386 ((struct cck_phy_hdr *) plcp)->signal);
387
388 return rspec;
389}
390
391/* copy rateset src to dst as-is (no masking or sorting) */
392void brcms_c_rateset_copy(const struct brcms_c_rateset *src,
393 struct brcms_c_rateset *dst)
394{
395 memcpy(dst, src, sizeof(struct brcms_c_rateset));
396}
397
398/*
399 * Copy and selectively filter one rateset to another.
400 * 'basic_only' means only copy basic rates.
401 * 'rates' indicates cck (11b) and ofdm rates combinations.
402 * - 0: cck and ofdm
403 * - 1: cck only
404 * - 2: ofdm only
405 * 'xmask' is the copy mask (typically 0x7f or 0xff).
406 */
407void
408brcms_c_rateset_filter(struct brcms_c_rateset *src, struct brcms_c_rateset *dst,
409 bool basic_only, u8 rates, uint xmask, bool mcsallow)
410{
411 uint i;
412 uint r;
413 uint count;
414
415 count = 0;
416 for (i = 0; i < src->count; i++) {
417 r = src->rates[i];
418 if (basic_only && !(r & BRCMS_RATE_FLAG))
419 continue;
420 if (rates == BRCMS_RATES_CCK &&
421 is_ofdm_rate((r & BRCMS_RATE_MASK)))
422 continue;
423 if (rates == BRCMS_RATES_OFDM &&
424 is_cck_rate((r & BRCMS_RATE_MASK)))
425 continue;
426 dst->rates[count++] = r & xmask;
427 }
428 dst->count = count;
429 dst->htphy_membership = src->htphy_membership;
430
431 if (mcsallow && rates != BRCMS_RATES_CCK)
432 memcpy(&dst->mcs[0], &src->mcs[0], MCSSET_LEN);
433 else
434 brcms_c_rateset_mcs_clear(dst);
435}
436
437/* select rateset for a given phy_type and bandtype and filter it, sort it
438 * and fill rs_tgt with result
439 */
440void
441brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt,
442 const struct brcms_c_rateset *rs_hw,
443 uint phy_type, int bandtype, bool cck_only,
444 uint rate_mask, bool mcsallow, u8 bw, u8 txstreams)
445{
446 const struct brcms_c_rateset *rs_dflt;
447 struct brcms_c_rateset rs_sel;
448 if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) ||
449 (PHYTYPE_IS(phy_type, PHY_TYPE_N)) ||
450 (PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) ||
451 (PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) {
452 if (bandtype == BRCM_BAND_5G)
453 rs_dflt = (bw == BRCMS_20_MHZ ?
454 &ofdm_mimo_rates : &ofdm_40bw_mimo_rates);
455 else
456 rs_dflt = (bw == BRCMS_20_MHZ ?
457 &cck_ofdm_mimo_rates :
458 &cck_ofdm_40bw_mimo_rates);
459 } else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) {
460 rs_dflt = (bandtype == BRCM_BAND_5G) ?
461 &ofdm_rates : &cck_ofdm_rates;
462 } else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) {
463 rs_dflt = &ofdm_rates;
464 } else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) {
465 rs_dflt = &cck_ofdm_rates;
466 } else {
467 /* should not happen, error condition */
468 rs_dflt = &cck_rates; /* force cck */
469 }
470
471 /* if hw rateset is not supplied, assign selected rateset to it */
472 if (!rs_hw)
473 rs_hw = rs_dflt;
474
475 brcms_c_rateset_copy(rs_dflt, &rs_sel);
476 brcms_c_rateset_mcs_upd(&rs_sel, txstreams);
477 brcms_c_rateset_filter(&rs_sel, rs_tgt, false,
478 cck_only ? BRCMS_RATES_CCK : BRCMS_RATES_CCK_OFDM,
479 rate_mask, mcsallow);
480 brcms_c_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false,
481 mcsallow ? txstreams : 1);
482}
483
484s16 brcms_c_rate_legacy_phyctl(uint rate)
485{
486 uint i;
487 for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++)
488 if (rate == legacy_phycfg_table[i].rate_ofdm)
489 return legacy_phycfg_table[i].tx_phy_ctl3;
490
491 return -1;
492}
493
494void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset)
495{
496 uint i;
497 for (i = 0; i < MCSSET_LEN; i++)
498 rateset->mcs[i] = 0;
499}
500
501void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, u8 txstreams)
502{
503 memcpy(&rateset->mcs[0], &cck_ofdm_mimo_rates.mcs[0], MCSSET_LEN);
504 brcms_c_rateset_mcs_upd(rateset, txstreams);
505}
506
507/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */
508void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, u8 bw)
509{
510 if (bw == BRCMS_40_MHZ)
511 setbit(rateset->mcs, 32);
512 else
513 clrbit(rateset->mcs, 32);
514}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/rate.h b/drivers/net/wireless/brcm80211/brcmsmac/rate.h
new file mode 100644
index 000000000000..e7b9dc2f2731
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/rate.h
@@ -0,0 +1,250 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_RATE_H_
18#define _BRCM_RATE_H_
19
20#include "types.h"
21#include "d11.h"
22
23extern const u8 rate_info[];
24extern const struct brcms_c_rateset cck_ofdm_mimo_rates;
25extern const struct brcms_c_rateset ofdm_mimo_rates;
26extern const struct brcms_c_rateset cck_ofdm_rates;
27extern const struct brcms_c_rateset ofdm_rates;
28extern const struct brcms_c_rateset cck_rates;
29extern const struct brcms_c_rateset gphy_legacy_rates;
30extern const struct brcms_c_rateset rate_limit_1_2;
31
32struct brcms_mcs_info {
33 /* phy rate in kbps [20Mhz] */
34 u32 phy_rate_20;
35 /* phy rate in kbps [40Mhz] */
36 u32 phy_rate_40;
37 /* phy rate in kbps [20Mhz] with SGI */
38 u32 phy_rate_20_sgi;
39 /* phy rate in kbps [40Mhz] with SGI */
40 u32 phy_rate_40_sgi;
41 /* phy ctl byte 3, code rate, modulation type, # of streams */
42 u8 tx_phy_ctl3;
43 /* matching legacy ofdm rate in 500bkps */
44 u8 leg_ofdm;
45};
46
47#define BRCMS_MAXMCS 32 /* max valid mcs index */
48#define MCS_TABLE_SIZE 33 /* Number of mcs entries in the table */
49extern const struct brcms_mcs_info mcs_table[];
50
51#define MCS_TXS_MASK 0xc0 /* num tx streams - 1 bit mask */
52#define MCS_TXS_SHIFT 6 /* num tx streams - 1 bit shift */
53
54/* returns num tx streams - 1 */
55static inline u8 mcs_2_txstreams(u8 mcs)
56{
57 return (mcs_table[mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT;
58}
59
60static inline uint mcs_2_rate(u8 mcs, bool is40, bool sgi)
61{
62 if (sgi) {
63 if (is40)
64 return mcs_table[mcs].phy_rate_40_sgi;
65 return mcs_table[mcs].phy_rate_20_sgi;
66 }
67 if (is40)
68 return mcs_table[mcs].phy_rate_40;
69
70 return mcs_table[mcs].phy_rate_20;
71}
72
73/* Macro to use the rate_info table */
74#define BRCMS_RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */
75
76/*
77 * rate spec : holds rate and mode specific information required to generate a
78 * tx frame. Legacy CCK and OFDM information is held in the same manner as was
79 * done in the past (in the lower byte) the upper 3 bytes primarily hold MIMO
80 * specific information
81 */
82
83/* rate spec bit fields */
84
85/* Either 500Kbps units or MIMO MCS idx */
86#define RSPEC_RATE_MASK 0x0000007F
87/* mimo MCS is stored in RSPEC_RATE_MASK */
88#define RSPEC_MIMORATE 0x08000000
89/* mimo bw mask */
90#define RSPEC_BW_MASK 0x00000700
91/* mimo bw shift */
92#define RSPEC_BW_SHIFT 8
93/* mimo Space/Time/Frequency mode mask */
94#define RSPEC_STF_MASK 0x00003800
95/* mimo Space/Time/Frequency mode shift */
96#define RSPEC_STF_SHIFT 11
97/* mimo coding type mask */
98#define RSPEC_CT_MASK 0x0000C000
99/* mimo coding type shift */
100#define RSPEC_CT_SHIFT 14
101/* mimo num STC streams per PLCP defn. */
102#define RSPEC_STC_MASK 0x00300000
103/* mimo num STC streams per PLCP defn. */
104#define RSPEC_STC_SHIFT 20
105/* mimo bit indicates adv coding in use */
106#define RSPEC_LDPC_CODING 0x00400000
107/* mimo bit indicates short GI in use */
108#define RSPEC_SHORT_GI 0x00800000
109/* bit indicates override both rate & mode */
110#define RSPEC_OVERRIDE 0x80000000
111/* bit indicates override rate only */
112#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000
113
114static inline bool rspec_active(u32 rspec)
115{
116 return rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE);
117}
118
119static inline u8 rspec_phytxbyte2(u32 rspec)
120{
121 return (rspec & 0xff00) >> 8;
122}
123
124static inline u32 rspec_get_bw(u32 rspec)
125{
126 return (rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT;
127}
128
129static inline bool rspec_issgi(u32 rspec)
130{
131 return (rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI;
132}
133
134static inline bool rspec_is40mhz(u32 rspec)
135{
136 u32 bw = rspec_get_bw(rspec);
137
138 return bw == PHY_TXC1_BW_40MHZ || bw == PHY_TXC1_BW_40MHZ_DUP;
139}
140
141static inline uint rspec2rate(u32 rspec)
142{
143 if (rspec & RSPEC_MIMORATE)
144 return mcs_2_rate(rspec & RSPEC_RATE_MASK, rspec_is40mhz(rspec),
145 rspec_issgi(rspec));
146 return rspec & RSPEC_RATE_MASK;
147}
148
149static inline u8 rspec_mimoplcp3(u32 rspec)
150{
151 return (rspec & 0xf00000) >> 16;
152}
153
154static inline bool plcp3_issgi(u8 plcp)
155{
156 return (plcp & (RSPEC_SHORT_GI >> 16)) != 0;
157}
158
159static inline uint rspec_stc(u32 rspec)
160{
161 return (rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT;
162}
163
164static inline uint rspec_stf(u32 rspec)
165{
166 return (rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT;
167}
168
169static inline bool is_mcs_rate(u32 ratespec)
170{
171 return (ratespec & RSPEC_MIMORATE) != 0;
172}
173
174static inline bool is_ofdm_rate(u32 ratespec)
175{
176 return !is_mcs_rate(ratespec) &&
177 (rate_info[ratespec & RSPEC_RATE_MASK] & BRCMS_RATE_FLAG);
178}
179
180static inline bool is_cck_rate(u32 ratespec)
181{
182 u32 rate = (ratespec & BRCMS_RATE_MASK);
183
184 return !is_mcs_rate(ratespec) && (
185 rate == BRCM_RATE_1M || rate == BRCM_RATE_2M ||
186 rate == BRCM_RATE_5M5 || rate == BRCM_RATE_11M);
187}
188
189static inline bool is_single_stream(u8 mcs)
190{
191 return mcs <= HIGHEST_SINGLE_STREAM_MCS || mcs == 32;
192}
193
194static inline u8 cck_rspec(u8 cck)
195{
196 return cck & RSPEC_RATE_MASK;
197}
198
199/* Convert encoded rate value in plcp header to numerical rates in 500 KHz
200 * increments */
201extern const u8 ofdm_rate_lookup[];
202
203static inline u8 ofdm_phy2mac_rate(u8 rlpt)
204{
205 return ofdm_rate_lookup[rlpt & 0x7];
206}
207
208static inline u8 cck_phy2mac_rate(u8 signal)
209{
210 return signal/5;
211}
212
213/* Rates specified in brcms_c_rateset_filter() */
214#define BRCMS_RATES_CCK_OFDM 0
215#define BRCMS_RATES_CCK 1
216#define BRCMS_RATES_OFDM 2
217
218/* sanitize, and sort a rateset with the basic bit(s) preserved, validate
219 * rateset */
220extern bool
221brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs,
222 const struct brcms_c_rateset *hw_rs,
223 bool check_brate, u8 txstreams);
224/* copy rateset src to dst as-is (no masking or sorting) */
225extern void brcms_c_rateset_copy(const struct brcms_c_rateset *src,
226 struct brcms_c_rateset *dst);
227
228/* would be nice to have these documented ... */
229extern u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp);
230
231extern void brcms_c_rateset_filter(struct brcms_c_rateset *src,
232 struct brcms_c_rateset *dst, bool basic_only, u8 rates, uint xmask,
233 bool mcsallow);
234
235extern void
236brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt,
237 const struct brcms_c_rateset *rs_hw, uint phy_type,
238 int bandtype, bool cck_only, uint rate_mask,
239 bool mcsallow, u8 bw, u8 txstreams);
240
241extern s16 brcms_c_rate_legacy_phyctl(uint rate);
242
243extern void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams);
244extern void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset);
245extern void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset,
246 u8 txstreams);
247extern void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset,
248 u8 bw);
249
250#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 000000000000..51c79c7239b7
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/scb.h
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_SCB_H_
18#define _BRCM_SCB_H_
19
20#include <linux/if_ether.h>
21#include <brcmu_utils.h>
22#include <defs.h>
23#include "types.h"
24
25#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */
26
27#define AMPDU_MAX_SCB_TID NUMPRIO
28
29/* scb flags */
30#define SCB_WMECAP 0x0040
31#define SCB_HTCAP 0x10000 /* HT (MIMO) capable device */
32#define SCB_IS40 0x80000 /* 40MHz capable */
33#define SCB_STBCCAP 0x40000000 /* STBC Capable */
34
35#define SCB_MAGIC 0xbeefcafe
36
37/* structure to store per-tid state for the ampdu initiator */
38struct scb_ampdu_tid_ini {
39 u8 tx_in_transit; /* number of pending mpdus in transit in driver */
40 u8 tid; /* initiator tid for easy lookup */
41 /* tx retry count; indexed by seq modulo */
42 u8 txretry[AMPDU_TX_BA_MAX_WSIZE];
43 struct scb *scb; /* backptr for easy lookup */
44 u8 ba_wsize; /* negotiated ba window size (in pdu) */
45};
46
47struct scb_ampdu {
48 struct scb *scb; /* back pointer for easy reference */
49 u8 mpdu_density; /* mpdu density */
50 u8 max_pdu; /* max pdus allowed in ampdu */
51 u8 release; /* # of mpdus released at a time */
52 u16 min_len; /* min mpdu len to support the density */
53 u32 max_rx_ampdu_bytes; /* max ampdu rcv length; 8k, 16k, 32k, 64k */
54
55 /*
56 * This could easily be a ini[] pointer and we keep this info in wl
57 * itself instead of having mac80211 hold it for us. Also could be made
58 * dynamic per tid instead of static.
59 */
60 /* initiator info - per tid (NUMPRIO): */
61 struct scb_ampdu_tid_ini ini[AMPDU_MAX_SCB_TID];
62};
63
64/* station control block - one per remote MAC address */
65struct scb {
66 u32 magic;
67 u32 flags; /* various bit flags as defined below */
68 u32 flags2; /* various bit flags2 as defined below */
69 u8 state; /* current state bitfield of auth/assoc process */
70 u8 ea[ETH_ALEN]; /* station address */
71 uint fragresid[NUMPRIO];/* #bytes unused in frag buffer per prio */
72
73 u16 seqctl[NUMPRIO]; /* seqctl of last received frame (for dups) */
74 /* seqctl of last received frame (for dups) for non-QoS data and
75 * management */
76 u16 seqctl_nonqos;
77 u16 seqnum[NUMPRIO];/* WME: driver maintained sw seqnum per priority */
78
79 struct scb_ampdu scb_ampdu; /* AMPDU state including per tid info */
80};
81
82#endif /* _BRCM_SCB_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/srom.c b/drivers/net/wireless/brcm80211/brcmsmac/srom.c
new file mode 100644
index 000000000000..99f791048e84
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/srom.c
@@ -0,0 +1,1298 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/kernel.h>
18#include <linux/string.h>
19#include <linux/io.h>
20#include <linux/etherdevice.h>
21#include <linux/crc8.h>
22#include <stdarg.h>
23
24#include <chipcommon.h>
25#include <brcmu_utils.h>
26#include "pub.h"
27#include "nicpci.h"
28#include "aiutils.h"
29#include "otp.h"
30#include "srom.h"
31
32/*
33 * SROM CRC8 polynomial value:
34 *
35 * x^8 + x^7 +x^6 + x^4 + x^2 + 1
36 */
37#define SROM_CRC8_POLY 0xAB
38
39/* Maximum srom: 6 Kilobits == 768 bytes */
40#define SROM_MAX 768
41
42/* PCI fields */
43#define PCI_F0DEVID 48
44
45#define SROM_WORDS 64
46
47#define SROM_SSID 2
48
49#define SROM_WL1LHMAXP 29
50
51#define SROM_WL1LPAB0 30
52#define SROM_WL1LPAB1 31
53#define SROM_WL1LPAB2 32
54
55#define SROM_WL1HPAB0 33
56#define SROM_WL1HPAB1 34
57#define SROM_WL1HPAB2 35
58
59#define SROM_MACHI_IL0 36
60#define SROM_MACMID_IL0 37
61#define SROM_MACLO_IL0 38
62#define SROM_MACHI_ET1 42
63#define SROM_MACMID_ET1 43
64#define SROM_MACLO_ET1 44
65#define SROM3_MACHI 37
66#define SROM3_MACMID 38
67#define SROM3_MACLO 39
68
69#define SROM_BXARSSI2G 40
70#define SROM_BXARSSI5G 41
71
72#define SROM_TRI52G 42
73#define SROM_TRI5GHL 43
74
75#define SROM_RXPO52G 45
76
77#define SROM_AABREV 46
78/* Fields in AABREV */
79#define SROM_BR_MASK 0x00ff
80#define SROM_CC_MASK 0x0f00
81#define SROM_CC_SHIFT 8
82#define SROM_AA0_MASK 0x3000
83#define SROM_AA0_SHIFT 12
84#define SROM_AA1_MASK 0xc000
85#define SROM_AA1_SHIFT 14
86
87#define SROM_WL0PAB0 47
88#define SROM_WL0PAB1 48
89#define SROM_WL0PAB2 49
90
91#define SROM_LEDBH10 50
92#define SROM_LEDBH32 51
93
94#define SROM_WL10MAXP 52
95
96#define SROM_WL1PAB0 53
97#define SROM_WL1PAB1 54
98#define SROM_WL1PAB2 55
99
100#define SROM_ITT 56
101
102#define SROM_BFL 57
103#define SROM_BFL2 28
104#define SROM3_BFL2 61
105
106#define SROM_AG10 58
107
108#define SROM_CCODE 59
109
110#define SROM_OPO 60
111
112#define SROM3_LEDDC 62
113
114#define SROM_CRCREV 63
115
116/* SROM Rev 4: Reallocate the software part of the srom to accommodate
117 * MIMO features. It assumes up to two PCIE functions and 440 bytes
118 * of usable srom i.e. the usable storage in chips with OTP that
119 * implements hardware redundancy.
120 */
121
122#define SROM4_WORDS 220
123
124#define SROM4_SIGN 32
125#define SROM4_SIGNATURE 0x5372
126
127#define SROM4_BREV 33
128
129#define SROM4_BFL0 34
130#define SROM4_BFL1 35
131#define SROM4_BFL2 36
132#define SROM4_BFL3 37
133#define SROM5_BFL0 37
134#define SROM5_BFL1 38
135#define SROM5_BFL2 39
136#define SROM5_BFL3 40
137
138#define SROM4_MACHI 38
139#define SROM4_MACMID 39
140#define SROM4_MACLO 40
141#define SROM5_MACHI 41
142#define SROM5_MACMID 42
143#define SROM5_MACLO 43
144
145#define SROM4_CCODE 41
146#define SROM4_REGREV 42
147#define SROM5_CCODE 34
148#define SROM5_REGREV 35
149
150#define SROM4_LEDBH10 43
151#define SROM4_LEDBH32 44
152#define SROM5_LEDBH10 59
153#define SROM5_LEDBH32 60
154
155#define SROM4_LEDDC 45
156#define SROM5_LEDDC 45
157
158#define SROM4_AA 46
159
160#define SROM4_AG10 47
161#define SROM4_AG32 48
162
163#define SROM4_TXPID2G 49
164#define SROM4_TXPID5G 51
165#define SROM4_TXPID5GL 53
166#define SROM4_TXPID5GH 55
167
168#define SROM4_TXRXC 61
169#define SROM4_TXCHAIN_MASK 0x000f
170#define SROM4_TXCHAIN_SHIFT 0
171#define SROM4_RXCHAIN_MASK 0x00f0
172#define SROM4_RXCHAIN_SHIFT 4
173#define SROM4_SWITCH_MASK 0xff00
174#define SROM4_SWITCH_SHIFT 8
175
176/* Per-path fields */
177#define MAX_PATH_SROM 4
178#define SROM4_PATH0 64
179#define SROM4_PATH1 87
180#define SROM4_PATH2 110
181#define SROM4_PATH3 133
182
183#define SROM4_2G_ITT_MAXP 0
184#define SROM4_2G_PA 1
185#define SROM4_5G_ITT_MAXP 5
186#define SROM4_5GLH_MAXP 6
187#define SROM4_5G_PA 7
188#define SROM4_5GL_PA 11
189#define SROM4_5GH_PA 15
190
191/* All the miriad power offsets */
192#define SROM4_2G_CCKPO 156
193#define SROM4_2G_OFDMPO 157
194#define SROM4_5G_OFDMPO 159
195#define SROM4_5GL_OFDMPO 161
196#define SROM4_5GH_OFDMPO 163
197#define SROM4_2G_MCSPO 165
198#define SROM4_5G_MCSPO 173
199#define SROM4_5GL_MCSPO 181
200#define SROM4_5GH_MCSPO 189
201#define SROM4_CDDPO 197
202#define SROM4_STBCPO 198
203#define SROM4_BW40PO 199
204#define SROM4_BWDUPPO 200
205
206#define SROM4_CRCREV 219
207
208/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6.
209 * This is acombined srom for both MIMO and SISO boards, usable in
210 * the .130 4Kilobit OTP with hardware redundancy.
211 */
212#define SROM8_BREV 65
213
214#define SROM8_BFL0 66
215#define SROM8_BFL1 67
216#define SROM8_BFL2 68
217#define SROM8_BFL3 69
218
219#define SROM8_MACHI 70
220#define SROM8_MACMID 71
221#define SROM8_MACLO 72
222
223#define SROM8_CCODE 73
224#define SROM8_REGREV 74
225
226#define SROM8_LEDBH10 75
227#define SROM8_LEDBH32 76
228
229#define SROM8_LEDDC 77
230
231#define SROM8_AA 78
232
233#define SROM8_AG10 79
234#define SROM8_AG32 80
235
236#define SROM8_TXRXC 81
237
238#define SROM8_BXARSSI2G 82
239#define SROM8_BXARSSI5G 83
240#define SROM8_TRI52G 84
241#define SROM8_TRI5GHL 85
242#define SROM8_RXPO52G 86
243
244#define SROM8_FEM2G 87
245#define SROM8_FEM5G 88
246#define SROM8_FEM_ANTSWLUT_MASK 0xf800
247#define SROM8_FEM_ANTSWLUT_SHIFT 11
248#define SROM8_FEM_TR_ISO_MASK 0x0700
249#define SROM8_FEM_TR_ISO_SHIFT 8
250#define SROM8_FEM_PDET_RANGE_MASK 0x00f8
251#define SROM8_FEM_PDET_RANGE_SHIFT 3
252#define SROM8_FEM_EXTPA_GAIN_MASK 0x0006
253#define SROM8_FEM_EXTPA_GAIN_SHIFT 1
254#define SROM8_FEM_TSSIPOS_MASK 0x0001
255#define SROM8_FEM_TSSIPOS_SHIFT 0
256
257#define SROM8_THERMAL 89
258
259/* Temp sense related entries */
260#define SROM8_MPWR_RAWTS 90
261#define SROM8_TS_SLP_OPT_CORRX 91
262/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable,
263 * IQSWP: IQ CAL swap disable */
264#define SROM8_FOC_HWIQ_IQSWP 92
265
266/* Temperature delta for PHY calibration */
267#define SROM8_PHYCAL_TEMPDELTA 93
268
269/* Per-path offsets & fields */
270#define SROM8_PATH0 96
271#define SROM8_PATH1 112
272#define SROM8_PATH2 128
273#define SROM8_PATH3 144
274
275#define SROM8_2G_ITT_MAXP 0
276#define SROM8_2G_PA 1
277#define SROM8_5G_ITT_MAXP 4
278#define SROM8_5GLH_MAXP 5
279#define SROM8_5G_PA 6
280#define SROM8_5GL_PA 9
281#define SROM8_5GH_PA 12
282
283/* All the miriad power offsets */
284#define SROM8_2G_CCKPO 160
285
286#define SROM8_2G_OFDMPO 161
287#define SROM8_5G_OFDMPO 163
288#define SROM8_5GL_OFDMPO 165
289#define SROM8_5GH_OFDMPO 167
290
291#define SROM8_2G_MCSPO 169
292#define SROM8_5G_MCSPO 177
293#define SROM8_5GL_MCSPO 185
294#define SROM8_5GH_MCSPO 193
295
296#define SROM8_CDDPO 201
297#define SROM8_STBCPO 202
298#define SROM8_BW40PO 203
299#define SROM8_BWDUPPO 204
300
301/* SISO PA parameters are in the path0 spaces */
302#define SROM8_SISO 96
303
304/* Legacy names for SISO PA paramters */
305#define SROM8_W0_ITTMAXP (SROM8_SISO + SROM8_2G_ITT_MAXP)
306#define SROM8_W0_PAB0 (SROM8_SISO + SROM8_2G_PA)
307#define SROM8_W0_PAB1 (SROM8_SISO + SROM8_2G_PA + 1)
308#define SROM8_W0_PAB2 (SROM8_SISO + SROM8_2G_PA + 2)
309#define SROM8_W1_ITTMAXP (SROM8_SISO + SROM8_5G_ITT_MAXP)
310#define SROM8_W1_MAXP_LCHC (SROM8_SISO + SROM8_5GLH_MAXP)
311#define SROM8_W1_PAB0 (SROM8_SISO + SROM8_5G_PA)
312#define SROM8_W1_PAB1 (SROM8_SISO + SROM8_5G_PA + 1)
313#define SROM8_W1_PAB2 (SROM8_SISO + SROM8_5G_PA + 2)
314#define SROM8_W1_PAB0_LC (SROM8_SISO + SROM8_5GL_PA)
315#define SROM8_W1_PAB1_LC (SROM8_SISO + SROM8_5GL_PA + 1)
316#define SROM8_W1_PAB2_LC (SROM8_SISO + SROM8_5GL_PA + 2)
317#define SROM8_W1_PAB0_HC (SROM8_SISO + SROM8_5GH_PA)
318#define SROM8_W1_PAB1_HC (SROM8_SISO + SROM8_5GH_PA + 1)
319#define SROM8_W1_PAB2_HC (SROM8_SISO + SROM8_5GH_PA + 2)
320
321/* SROM REV 9 */
322#define SROM9_2GPO_CCKBW20 160
323#define SROM9_2GPO_CCKBW20UL 161
324#define SROM9_2GPO_LOFDMBW20 162
325#define SROM9_2GPO_LOFDMBW20UL 164
326
327#define SROM9_5GLPO_LOFDMBW20 166
328#define SROM9_5GLPO_LOFDMBW20UL 168
329#define SROM9_5GMPO_LOFDMBW20 170
330#define SROM9_5GMPO_LOFDMBW20UL 172
331#define SROM9_5GHPO_LOFDMBW20 174
332#define SROM9_5GHPO_LOFDMBW20UL 176
333
334#define SROM9_2GPO_MCSBW20 178
335#define SROM9_2GPO_MCSBW20UL 180
336#define SROM9_2GPO_MCSBW40 182
337
338#define SROM9_5GLPO_MCSBW20 184
339#define SROM9_5GLPO_MCSBW20UL 186
340#define SROM9_5GLPO_MCSBW40 188
341#define SROM9_5GMPO_MCSBW20 190
342#define SROM9_5GMPO_MCSBW20UL 192
343#define SROM9_5GMPO_MCSBW40 194
344#define SROM9_5GHPO_MCSBW20 196
345#define SROM9_5GHPO_MCSBW20UL 198
346#define SROM9_5GHPO_MCSBW40 200
347
348#define SROM9_PO_MCS32 202
349#define SROM9_PO_LOFDM40DUP 203
350
351/* SROM flags (see sromvar_t) */
352
353/* value continues as described by the next entry */
354#define SRFL_MORE 1
355#define SRFL_NOFFS 2 /* value bits can't be all one's */
356#define SRFL_PRHEX 4 /* value is in hexdecimal format */
357#define SRFL_PRSIGN 8 /* value is in signed decimal format */
358#define SRFL_CCODE 0x10 /* value is in country code format */
359#define SRFL_ETHADDR 0x20 /* value is an Ethernet address */
360#define SRFL_LEDDC 0x40 /* value is an LED duty cycle */
361/* do not generate a nvram param, entry is for mfgc */
362#define SRFL_NOVAR 0x80
363
364/* Max. nvram variable table size */
365#define MAXSZ_NVRAM_VARS 4096
366
367/*
368 * indicates type of value.
369 */
370enum brcms_srom_var_type {
371 BRCMS_SROM_STRING,
372 BRCMS_SROM_SNUMBER,
373 BRCMS_SROM_UNUMBER
374};
375
376/*
377 * storage type for srom variable.
378 *
379 * var_list: for linked list operations.
380 * varid: identifier of the variable.
381 * var_type: type of variable.
382 * buf: variable value when var_type == BRCMS_SROM_STRING.
383 * uval: unsigned variable value when var_type == BRCMS_SROM_UNUMBER.
384 * sval: signed variable value when var_type == BRCMS_SROM_SNUMBER.
385 */
386struct brcms_srom_list_head {
387 struct list_head var_list;
388 enum brcms_srom_id varid;
389 enum brcms_srom_var_type var_type;
390 union {
391 char buf[0];
392 u32 uval;
393 s32 sval;
394 };
395};
396
397struct brcms_sromvar {
398 enum brcms_srom_id varid;
399 u32 revmask;
400 u32 flags;
401 u16 off;
402 u16 mask;
403};
404
405struct brcms_varbuf {
406 char *base; /* pointer to buffer base */
407 char *buf; /* pointer to current position */
408 unsigned int size; /* current (residual) size in bytes */
409};
410
411/*
412 * Assumptions:
413 * - Ethernet address spans across 3 consecutive words
414 *
415 * Table rules:
416 * - Add multiple entries next to each other if a value spans across multiple
417 * words (even multiple fields in the same word) with each entry except the
418 * last having it's SRFL_MORE bit set.
419 * - Ethernet address entry does not follow above rule and must not have
420 * SRFL_MORE bit set. Its SRFL_ETHADDR bit implies it takes multiple words.
421 * - The last entry's name field must be NULL to indicate the end of the table.
422 * Other entries must have non-NULL name.
423 */
424static const struct brcms_sromvar pci_sromvars[] = {
425 {BRCMS_SROM_DEVID, 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID,
426 0xffff},
427 {BRCMS_SROM_BOARDREV, 0x0000000e, SRFL_PRHEX, SROM_AABREV,
428 SROM_BR_MASK},
429 {BRCMS_SROM_BOARDREV, 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff},
430 {BRCMS_SROM_BOARDREV, 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff},
431 {BRCMS_SROM_BOARDFLAGS, 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff},
432 {BRCMS_SROM_BOARDFLAGS, 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL,
433 0xffff},
434 {BRCMS_SROM_CONT, 0, 0, SROM_BFL2, 0xffff},
435 {BRCMS_SROM_BOARDFLAGS, 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL,
436 0xffff},
437 {BRCMS_SROM_CONT, 0, 0, SROM3_BFL2, 0xffff},
438 {BRCMS_SROM_BOARDFLAGS, 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0,
439 0xffff},
440 {BRCMS_SROM_CONT, 0, 0, SROM4_BFL1, 0xffff},
441 {BRCMS_SROM_BOARDFLAGS, 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0,
442 0xffff},
443 {BRCMS_SROM_CONT, 0, 0, SROM5_BFL1, 0xffff},
444 {BRCMS_SROM_BOARDFLAGS, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0,
445 0xffff},
446 {BRCMS_SROM_CONT, 0, 0, SROM8_BFL1, 0xffff},
447 {BRCMS_SROM_BOARDFLAGS2, 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2,
448 0xffff},
449 {BRCMS_SROM_CONT, 0, 0, SROM4_BFL3, 0xffff},
450 {BRCMS_SROM_BOARDFLAGS2, 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2,
451 0xffff},
452 {BRCMS_SROM_CONT, 0, 0, SROM5_BFL3, 0xffff},
453 {BRCMS_SROM_BOARDFLAGS2, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2,
454 0xffff},
455 {BRCMS_SROM_CONT, 0, 0, SROM8_BFL3, 0xffff},
456 {BRCMS_SROM_BOARDTYPE, 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff},
457 {BRCMS_SROM_BOARDNUM, 0x00000006, 0, SROM_MACLO_IL0, 0xffff},
458 {BRCMS_SROM_BOARDNUM, 0x00000008, 0, SROM3_MACLO, 0xffff},
459 {BRCMS_SROM_BOARDNUM, 0x00000010, 0, SROM4_MACLO, 0xffff},
460 {BRCMS_SROM_BOARDNUM, 0x000000e0, 0, SROM5_MACLO, 0xffff},
461 {BRCMS_SROM_BOARDNUM, 0xffffff00, 0, SROM8_MACLO, 0xffff},
462 {BRCMS_SROM_CC, 0x00000002, 0, SROM_AABREV, SROM_CC_MASK},
463 {BRCMS_SROM_REGREV, 0x00000008, 0, SROM_OPO, 0xff00},
464 {BRCMS_SROM_REGREV, 0x00000010, 0, SROM4_REGREV, 0x00ff},
465 {BRCMS_SROM_REGREV, 0x000000e0, 0, SROM5_REGREV, 0x00ff},
466 {BRCMS_SROM_REGREV, 0xffffff00, 0, SROM8_REGREV, 0x00ff},
467 {BRCMS_SROM_LEDBH0, 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff},
468 {BRCMS_SROM_LEDBH1, 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00},
469 {BRCMS_SROM_LEDBH2, 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff},
470 {BRCMS_SROM_LEDBH3, 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00},
471 {BRCMS_SROM_LEDBH0, 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff},
472 {BRCMS_SROM_LEDBH1, 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00},
473 {BRCMS_SROM_LEDBH2, 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff},
474 {BRCMS_SROM_LEDBH3, 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00},
475 {BRCMS_SROM_LEDBH0, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff},
476 {BRCMS_SROM_LEDBH1, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00},
477 {BRCMS_SROM_LEDBH2, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff},
478 {BRCMS_SROM_LEDBH3, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00},
479 {BRCMS_SROM_LEDBH0, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff},
480 {BRCMS_SROM_LEDBH1, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00},
481 {BRCMS_SROM_LEDBH2, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff},
482 {BRCMS_SROM_LEDBH3, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00},
483 {BRCMS_SROM_PA0B0, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff},
484 {BRCMS_SROM_PA0B1, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff},
485 {BRCMS_SROM_PA0B2, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff},
486 {BRCMS_SROM_PA0ITSSIT, 0x0000000e, 0, SROM_ITT, 0x00ff},
487 {BRCMS_SROM_PA0MAXPWR, 0x0000000e, 0, SROM_WL10MAXP, 0x00ff},
488 {BRCMS_SROM_PA0B0, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff},
489 {BRCMS_SROM_PA0B1, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff},
490 {BRCMS_SROM_PA0B2, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff},
491 {BRCMS_SROM_PA0ITSSIT, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00},
492 {BRCMS_SROM_PA0MAXPWR, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff},
493 {BRCMS_SROM_OPO, 0x0000000c, 0, SROM_OPO, 0x00ff},
494 {BRCMS_SROM_OPO, 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff},
495 {BRCMS_SROM_AA2G, 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK},
496 {BRCMS_SROM_AA2G, 0x000000f0, 0, SROM4_AA, 0x00ff},
497 {BRCMS_SROM_AA2G, 0xffffff00, 0, SROM8_AA, 0x00ff},
498 {BRCMS_SROM_AA5G, 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK},
499 {BRCMS_SROM_AA5G, 0x000000f0, 0, SROM4_AA, 0xff00},
500 {BRCMS_SROM_AA5G, 0xffffff00, 0, SROM8_AA, 0xff00},
501 {BRCMS_SROM_AG0, 0x0000000e, 0, SROM_AG10, 0x00ff},
502 {BRCMS_SROM_AG1, 0x0000000e, 0, SROM_AG10, 0xff00},
503 {BRCMS_SROM_AG0, 0x000000f0, 0, SROM4_AG10, 0x00ff},
504 {BRCMS_SROM_AG1, 0x000000f0, 0, SROM4_AG10, 0xff00},
505 {BRCMS_SROM_AG2, 0x000000f0, 0, SROM4_AG32, 0x00ff},
506 {BRCMS_SROM_AG3, 0x000000f0, 0, SROM4_AG32, 0xff00},
507 {BRCMS_SROM_AG0, 0xffffff00, 0, SROM8_AG10, 0x00ff},
508 {BRCMS_SROM_AG1, 0xffffff00, 0, SROM8_AG10, 0xff00},
509 {BRCMS_SROM_AG2, 0xffffff00, 0, SROM8_AG32, 0x00ff},
510 {BRCMS_SROM_AG3, 0xffffff00, 0, SROM8_AG32, 0xff00},
511 {BRCMS_SROM_PA1B0, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff},
512 {BRCMS_SROM_PA1B1, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff},
513 {BRCMS_SROM_PA1B2, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff},
514 {BRCMS_SROM_PA1LOB0, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff},
515 {BRCMS_SROM_PA1LOB1, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff},
516 {BRCMS_SROM_PA1LOB2, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff},
517 {BRCMS_SROM_PA1HIB0, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff},
518 {BRCMS_SROM_PA1HIB1, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff},
519 {BRCMS_SROM_PA1HIB2, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff},
520 {BRCMS_SROM_PA1ITSSIT, 0x0000000e, 0, SROM_ITT, 0xff00},
521 {BRCMS_SROM_PA1MAXPWR, 0x0000000e, 0, SROM_WL10MAXP, 0xff00},
522 {BRCMS_SROM_PA1LOMAXPWR, 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00},
523 {BRCMS_SROM_PA1HIMAXPWR, 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff},
524 {BRCMS_SROM_PA1B0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff},
525 {BRCMS_SROM_PA1B1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff},
526 {BRCMS_SROM_PA1B2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff},
527 {BRCMS_SROM_PA1LOB0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff},
528 {BRCMS_SROM_PA1LOB1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff},
529 {BRCMS_SROM_PA1LOB2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff},
530 {BRCMS_SROM_PA1HIB0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff},
531 {BRCMS_SROM_PA1HIB1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff},
532 {BRCMS_SROM_PA1HIB2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff},
533 {BRCMS_SROM_PA1ITSSIT, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00},
534 {BRCMS_SROM_PA1MAXPWR, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff},
535 {BRCMS_SROM_PA1LOMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00},
536 {BRCMS_SROM_PA1HIMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff},
537 {BRCMS_SROM_BXA2G, 0x00000008, 0, SROM_BXARSSI2G, 0x1800},
538 {BRCMS_SROM_RSSISAV2G, 0x00000008, 0, SROM_BXARSSI2G, 0x0700},
539 {BRCMS_SROM_RSSISMC2G, 0x00000008, 0, SROM_BXARSSI2G, 0x00f0},
540 {BRCMS_SROM_RSSISMF2G, 0x00000008, 0, SROM_BXARSSI2G, 0x000f},
541 {BRCMS_SROM_BXA2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800},
542 {BRCMS_SROM_RSSISAV2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700},
543 {BRCMS_SROM_RSSISMC2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0},
544 {BRCMS_SROM_RSSISMF2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f},
545 {BRCMS_SROM_BXA5G, 0x00000008, 0, SROM_BXARSSI5G, 0x1800},
546 {BRCMS_SROM_RSSISAV5G, 0x00000008, 0, SROM_BXARSSI5G, 0x0700},
547 {BRCMS_SROM_RSSISMC5G, 0x00000008, 0, SROM_BXARSSI5G, 0x00f0},
548 {BRCMS_SROM_RSSISMF5G, 0x00000008, 0, SROM_BXARSSI5G, 0x000f},
549 {BRCMS_SROM_BXA5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800},
550 {BRCMS_SROM_RSSISAV5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700},
551 {BRCMS_SROM_RSSISMC5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0},
552 {BRCMS_SROM_RSSISMF5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f},
553 {BRCMS_SROM_TRI2G, 0x00000008, 0, SROM_TRI52G, 0x00ff},
554 {BRCMS_SROM_TRI5G, 0x00000008, 0, SROM_TRI52G, 0xff00},
555 {BRCMS_SROM_TRI5GL, 0x00000008, 0, SROM_TRI5GHL, 0x00ff},
556 {BRCMS_SROM_TRI5GH, 0x00000008, 0, SROM_TRI5GHL, 0xff00},
557 {BRCMS_SROM_TRI2G, 0xffffff00, 0, SROM8_TRI52G, 0x00ff},
558 {BRCMS_SROM_TRI5G, 0xffffff00, 0, SROM8_TRI52G, 0xff00},
559 {BRCMS_SROM_TRI5GL, 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff},
560 {BRCMS_SROM_TRI5GH, 0xffffff00, 0, SROM8_TRI5GHL, 0xff00},
561 {BRCMS_SROM_RXPO2G, 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff},
562 {BRCMS_SROM_RXPO5G, 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00},
563 {BRCMS_SROM_RXPO2G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff},
564 {BRCMS_SROM_RXPO5G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00},
565 {BRCMS_SROM_TXCHAIN, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC,
566 SROM4_TXCHAIN_MASK},
567 {BRCMS_SROM_RXCHAIN, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC,
568 SROM4_RXCHAIN_MASK},
569 {BRCMS_SROM_ANTSWITCH, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC,
570 SROM4_SWITCH_MASK},
571 {BRCMS_SROM_TXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC,
572 SROM4_TXCHAIN_MASK},
573 {BRCMS_SROM_RXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC,
574 SROM4_RXCHAIN_MASK},
575 {BRCMS_SROM_ANTSWITCH, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC,
576 SROM4_SWITCH_MASK},
577 {BRCMS_SROM_TSSIPOS2G, 0xffffff00, 0, SROM8_FEM2G,
578 SROM8_FEM_TSSIPOS_MASK},
579 {BRCMS_SROM_EXTPAGAIN2G, 0xffffff00, 0, SROM8_FEM2G,
580 SROM8_FEM_EXTPA_GAIN_MASK},
581 {BRCMS_SROM_PDETRANGE2G, 0xffffff00, 0, SROM8_FEM2G,
582 SROM8_FEM_PDET_RANGE_MASK},
583 {BRCMS_SROM_TRISO2G, 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK},
584 {BRCMS_SROM_ANTSWCTL2G, 0xffffff00, 0, SROM8_FEM2G,
585 SROM8_FEM_ANTSWLUT_MASK},
586 {BRCMS_SROM_TSSIPOS5G, 0xffffff00, 0, SROM8_FEM5G,
587 SROM8_FEM_TSSIPOS_MASK},
588 {BRCMS_SROM_EXTPAGAIN5G, 0xffffff00, 0, SROM8_FEM5G,
589 SROM8_FEM_EXTPA_GAIN_MASK},
590 {BRCMS_SROM_PDETRANGE5G, 0xffffff00, 0, SROM8_FEM5G,
591 SROM8_FEM_PDET_RANGE_MASK},
592 {BRCMS_SROM_TRISO5G, 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK},
593 {BRCMS_SROM_ANTSWCTL5G, 0xffffff00, 0, SROM8_FEM5G,
594 SROM8_FEM_ANTSWLUT_MASK},
595 {BRCMS_SROM_TEMPTHRESH, 0xffffff00, 0, SROM8_THERMAL, 0xff00},
596 {BRCMS_SROM_TEMPOFFSET, 0xffffff00, 0, SROM8_THERMAL, 0x00ff},
597 {BRCMS_SROM_TXPID2GA0, 0x000000f0, 0, SROM4_TXPID2G, 0x00ff},
598 {BRCMS_SROM_TXPID2GA1, 0x000000f0, 0, SROM4_TXPID2G, 0xff00},
599 {BRCMS_SROM_TXPID2GA2, 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff},
600 {BRCMS_SROM_TXPID2GA3, 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00},
601 {BRCMS_SROM_TXPID5GA0, 0x000000f0, 0, SROM4_TXPID5G, 0x00ff},
602 {BRCMS_SROM_TXPID5GA1, 0x000000f0, 0, SROM4_TXPID5G, 0xff00},
603 {BRCMS_SROM_TXPID5GA2, 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff},
604 {BRCMS_SROM_TXPID5GA3, 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00},
605 {BRCMS_SROM_TXPID5GLA0, 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff},
606 {BRCMS_SROM_TXPID5GLA1, 0x000000f0, 0, SROM4_TXPID5GL, 0xff00},
607 {BRCMS_SROM_TXPID5GLA2, 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff},
608 {BRCMS_SROM_TXPID5GLA3, 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00},
609 {BRCMS_SROM_TXPID5GHA0, 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff},
610 {BRCMS_SROM_TXPID5GHA1, 0x000000f0, 0, SROM4_TXPID5GH, 0xff00},
611 {BRCMS_SROM_TXPID5GHA2, 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff},
612 {BRCMS_SROM_TXPID5GHA3, 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00},
613
614 {BRCMS_SROM_CCODE, 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff},
615 {BRCMS_SROM_CCODE, 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff},
616 {BRCMS_SROM_CCODE, 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff},
617 {BRCMS_SROM_CCODE, 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff},
618 {BRCMS_SROM_MACADDR, 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff},
619 {BRCMS_SROM_MACADDR, 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff},
620 {BRCMS_SROM_MACADDR, 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff},
621 {BRCMS_SROM_MACADDR, 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff},
622 {BRCMS_SROM_IL0MACADDR, 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0,
623 0xffff},
624 {BRCMS_SROM_ET1MACADDR, 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1,
625 0xffff},
626 {BRCMS_SROM_LEDDC, 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC,
627 0xffff},
628 {BRCMS_SROM_LEDDC, 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC,
629 0xffff},
630 {BRCMS_SROM_LEDDC, 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC,
631 0xffff},
632 {BRCMS_SROM_LEDDC, 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC,
633 0xffff},
634 {BRCMS_SROM_RAWTEMPSENSE, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS,
635 0x01ff},
636 {BRCMS_SROM_MEASPOWER, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS,
637 0xfe00},
638 {BRCMS_SROM_TEMPSENSE_SLOPE, 0xffffff00, SRFL_PRHEX,
639 SROM8_TS_SLP_OPT_CORRX, 0x00ff},
640 {BRCMS_SROM_TEMPCORRX, 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
641 0xfc00},
642 {BRCMS_SROM_TEMPSENSE_OPTION, 0xffffff00, SRFL_PRHEX,
643 SROM8_TS_SLP_OPT_CORRX, 0x0300},
644 {BRCMS_SROM_FREQOFFSET_CORR, 0xffffff00, SRFL_PRHEX,
645 SROM8_FOC_HWIQ_IQSWP, 0x000f},
646 {BRCMS_SROM_IQCAL_SWP_DIS, 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP,
647 0x0010},
648 {BRCMS_SROM_HW_IQCAL_EN, 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP,
649 0x0020},
650 {BRCMS_SROM_PHYCAL_TEMPDELTA, 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA,
651 0x00ff},
652
653 {BRCMS_SROM_CCK2GPO, 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff},
654 {BRCMS_SROM_CCK2GPO, 0x00000100, 0, SROM8_2G_CCKPO, 0xffff},
655 {BRCMS_SROM_OFDM2GPO, 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff},
656 {BRCMS_SROM_CONT, 0, 0, SROM4_2G_OFDMPO + 1, 0xffff},
657 {BRCMS_SROM_OFDM5GPO, 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff},
658 {BRCMS_SROM_CONT, 0, 0, SROM4_5G_OFDMPO + 1, 0xffff},
659 {BRCMS_SROM_OFDM5GLPO, 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff},
660 {BRCMS_SROM_CONT, 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff},
661 {BRCMS_SROM_OFDM5GHPO, 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff},
662 {BRCMS_SROM_CONT, 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff},
663 {BRCMS_SROM_OFDM2GPO, 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff},
664 {BRCMS_SROM_CONT, 0, 0, SROM8_2G_OFDMPO + 1, 0xffff},
665 {BRCMS_SROM_OFDM5GPO, 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff},
666 {BRCMS_SROM_CONT, 0, 0, SROM8_5G_OFDMPO + 1, 0xffff},
667 {BRCMS_SROM_OFDM5GLPO, 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff},
668 {BRCMS_SROM_CONT, 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff},
669 {BRCMS_SROM_OFDM5GHPO, 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff},
670 {BRCMS_SROM_CONT, 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff},
671 {BRCMS_SROM_MCS2GPO0, 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff},
672 {BRCMS_SROM_MCS2GPO1, 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff},
673 {BRCMS_SROM_MCS2GPO2, 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff},
674 {BRCMS_SROM_MCS2GPO3, 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff},
675 {BRCMS_SROM_MCS2GPO4, 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff},
676 {BRCMS_SROM_MCS2GPO5, 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff},
677 {BRCMS_SROM_MCS2GPO6, 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff},
678 {BRCMS_SROM_MCS2GPO7, 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff},
679 {BRCMS_SROM_MCS5GPO0, 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff},
680 {BRCMS_SROM_MCS5GPO1, 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff},
681 {BRCMS_SROM_MCS5GPO2, 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff},
682 {BRCMS_SROM_MCS5GPO3, 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff},
683 {BRCMS_SROM_MCS5GPO4, 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff},
684 {BRCMS_SROM_MCS5GPO5, 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff},
685 {BRCMS_SROM_MCS5GPO6, 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff},
686 {BRCMS_SROM_MCS5GPO7, 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff},
687 {BRCMS_SROM_MCS5GLPO0, 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff},
688 {BRCMS_SROM_MCS5GLPO1, 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff},
689 {BRCMS_SROM_MCS5GLPO2, 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff},
690 {BRCMS_SROM_MCS5GLPO3, 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff},
691 {BRCMS_SROM_MCS5GLPO4, 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff},
692 {BRCMS_SROM_MCS5GLPO5, 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff},
693 {BRCMS_SROM_MCS5GLPO6, 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff},
694 {BRCMS_SROM_MCS5GLPO7, 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff},
695 {BRCMS_SROM_MCS5GHPO0, 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff},
696 {BRCMS_SROM_MCS5GHPO1, 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff},
697 {BRCMS_SROM_MCS5GHPO2, 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff},
698 {BRCMS_SROM_MCS5GHPO3, 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff},
699 {BRCMS_SROM_MCS5GHPO4, 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff},
700 {BRCMS_SROM_MCS5GHPO5, 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff},
701 {BRCMS_SROM_MCS5GHPO6, 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff},
702 {BRCMS_SROM_MCS5GHPO7, 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff},
703 {BRCMS_SROM_MCS2GPO0, 0x00000100, 0, SROM8_2G_MCSPO, 0xffff},
704 {BRCMS_SROM_MCS2GPO1, 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff},
705 {BRCMS_SROM_MCS2GPO2, 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff},
706 {BRCMS_SROM_MCS2GPO3, 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff},
707 {BRCMS_SROM_MCS2GPO4, 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff},
708 {BRCMS_SROM_MCS2GPO5, 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff},
709 {BRCMS_SROM_MCS2GPO6, 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff},
710 {BRCMS_SROM_MCS2GPO7, 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff},
711 {BRCMS_SROM_MCS5GPO0, 0x00000100, 0, SROM8_5G_MCSPO, 0xffff},
712 {BRCMS_SROM_MCS5GPO1, 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff},
713 {BRCMS_SROM_MCS5GPO2, 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff},
714 {BRCMS_SROM_MCS5GPO3, 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff},
715 {BRCMS_SROM_MCS5GPO4, 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff},
716 {BRCMS_SROM_MCS5GPO5, 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff},
717 {BRCMS_SROM_MCS5GPO6, 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff},
718 {BRCMS_SROM_MCS5GPO7, 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff},
719 {BRCMS_SROM_MCS5GLPO0, 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff},
720 {BRCMS_SROM_MCS5GLPO1, 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff},
721 {BRCMS_SROM_MCS5GLPO2, 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff},
722 {BRCMS_SROM_MCS5GLPO3, 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff},
723 {BRCMS_SROM_MCS5GLPO4, 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff},
724 {BRCMS_SROM_MCS5GLPO5, 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff},
725 {BRCMS_SROM_MCS5GLPO6, 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff},
726 {BRCMS_SROM_MCS5GLPO7, 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff},
727 {BRCMS_SROM_MCS5GHPO0, 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff},
728 {BRCMS_SROM_MCS5GHPO1, 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff},
729 {BRCMS_SROM_MCS5GHPO2, 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff},
730 {BRCMS_SROM_MCS5GHPO3, 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff},
731 {BRCMS_SROM_MCS5GHPO4, 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff},
732 {BRCMS_SROM_MCS5GHPO5, 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff},
733 {BRCMS_SROM_MCS5GHPO6, 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff},
734 {BRCMS_SROM_MCS5GHPO7, 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff},
735 {BRCMS_SROM_CDDPO, 0x000000f0, 0, SROM4_CDDPO, 0xffff},
736 {BRCMS_SROM_STBCPO, 0x000000f0, 0, SROM4_STBCPO, 0xffff},
737 {BRCMS_SROM_BW40PO, 0x000000f0, 0, SROM4_BW40PO, 0xffff},
738 {BRCMS_SROM_BWDUPPO, 0x000000f0, 0, SROM4_BWDUPPO, 0xffff},
739 {BRCMS_SROM_CDDPO, 0x00000100, 0, SROM8_CDDPO, 0xffff},
740 {BRCMS_SROM_STBCPO, 0x00000100, 0, SROM8_STBCPO, 0xffff},
741 {BRCMS_SROM_BW40PO, 0x00000100, 0, SROM8_BW40PO, 0xffff},
742 {BRCMS_SROM_BWDUPPO, 0x00000100, 0, SROM8_BWDUPPO, 0xffff},
743
744 /* power per rate from sromrev 9 */
745 {BRCMS_SROM_CCKBW202GPO, 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff},
746 {BRCMS_SROM_CCKBW20UL2GPO, 0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff},
747 {BRCMS_SROM_LEGOFDMBW202GPO, 0xfffffe00, SRFL_MORE,
748 SROM9_2GPO_LOFDMBW20, 0xffff},
749 {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff},
750 {BRCMS_SROM_LEGOFDMBW20UL2GPO, 0xfffffe00, SRFL_MORE,
751 SROM9_2GPO_LOFDMBW20UL, 0xffff},
752 {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff},
753 {BRCMS_SROM_LEGOFDMBW205GLPO, 0xfffffe00, SRFL_MORE,
754 SROM9_5GLPO_LOFDMBW20, 0xffff},
755 {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff},
756 {BRCMS_SROM_LEGOFDMBW20UL5GLPO, 0xfffffe00, SRFL_MORE,
757 SROM9_5GLPO_LOFDMBW20UL, 0xffff},
758 {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff},
759 {BRCMS_SROM_LEGOFDMBW205GMPO, 0xfffffe00, SRFL_MORE,
760 SROM9_5GMPO_LOFDMBW20, 0xffff},
761 {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff},
762 {BRCMS_SROM_LEGOFDMBW20UL5GMPO, 0xfffffe00, SRFL_MORE,
763 SROM9_5GMPO_LOFDMBW20UL, 0xffff},
764 {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff},
765 {BRCMS_SROM_LEGOFDMBW205GHPO, 0xfffffe00, SRFL_MORE,
766 SROM9_5GHPO_LOFDMBW20, 0xffff},
767 {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff},
768 {BRCMS_SROM_LEGOFDMBW20UL5GHPO, 0xfffffe00, SRFL_MORE,
769 SROM9_5GHPO_LOFDMBW20UL, 0xffff},
770 {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff},
771 {BRCMS_SROM_MCSBW202GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20,
772 0xffff},
773 {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff},
774 {BRCMS_SROM_MCSBW20UL2GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL,
775 0xffff},
776 {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff},
777 {BRCMS_SROM_MCSBW402GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40,
778 0xffff},
779 {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff},
780 {BRCMS_SROM_MCSBW205GLPO, 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20,
781 0xffff},
782 {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff},
783 {BRCMS_SROM_MCSBW20UL5GLPO, 0xfffffe00, SRFL_MORE,
784 SROM9_5GLPO_MCSBW20UL, 0xffff},
785 {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff},
786 {BRCMS_SROM_MCSBW405GLPO, 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40,
787 0xffff},
788 {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff},
789 {BRCMS_SROM_MCSBW205GMPO, 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20,
790 0xffff},
791 {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff},
792 {BRCMS_SROM_MCSBW20UL5GMPO, 0xfffffe00, SRFL_MORE,
793 SROM9_5GMPO_MCSBW20UL, 0xffff},
794 {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff},
795 {BRCMS_SROM_MCSBW405GMPO, 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40,
796 0xffff},
797 {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff},
798 {BRCMS_SROM_MCSBW205GHPO, 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20,
799 0xffff},
800 {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff},
801 {BRCMS_SROM_MCSBW20UL5GHPO, 0xfffffe00, SRFL_MORE,
802 SROM9_5GHPO_MCSBW20UL, 0xffff},
803 {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff},
804 {BRCMS_SROM_MCSBW405GHPO, 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40,
805 0xffff},
806 {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff},
807 {BRCMS_SROM_MCS32PO, 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff},
808 {BRCMS_SROM_LEGOFDM40DUPPO, 0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff},
809
810 {BRCMS_SROM_NULL, 0, 0, 0, 0}
811};
812
813static const struct brcms_sromvar perpath_pci_sromvars[] = {
814 {BRCMS_SROM_MAXP2GA0, 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff},
815 {BRCMS_SROM_ITT2GA0, 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00},
816 {BRCMS_SROM_ITT5GA0, 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00},
817 {BRCMS_SROM_PA2GW0A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff},
818 {BRCMS_SROM_PA2GW1A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff},
819 {BRCMS_SROM_PA2GW2A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff},
820 {BRCMS_SROM_PA2GW3A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff},
821 {BRCMS_SROM_MAXP5GA0, 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff},
822 {BRCMS_SROM_MAXP5GHA0, 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff},
823 {BRCMS_SROM_MAXP5GLA0, 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00},
824 {BRCMS_SROM_PA5GW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff},
825 {BRCMS_SROM_PA5GW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff},
826 {BRCMS_SROM_PA5GW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff},
827 {BRCMS_SROM_PA5GW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff},
828 {BRCMS_SROM_PA5GLW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff},
829 {BRCMS_SROM_PA5GLW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1,
830 0xffff},
831 {BRCMS_SROM_PA5GLW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2,
832 0xffff},
833 {BRCMS_SROM_PA5GLW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3,
834 0xffff},
835 {BRCMS_SROM_PA5GHW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff},
836 {BRCMS_SROM_PA5GHW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1,
837 0xffff},
838 {BRCMS_SROM_PA5GHW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2,
839 0xffff},
840 {BRCMS_SROM_PA5GHW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3,
841 0xffff},
842 {BRCMS_SROM_MAXP2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff},
843 {BRCMS_SROM_ITT2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00},
844 {BRCMS_SROM_ITT5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00},
845 {BRCMS_SROM_PA2GW0A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff},
846 {BRCMS_SROM_PA2GW1A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff},
847 {BRCMS_SROM_PA2GW2A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff},
848 {BRCMS_SROM_MAXP5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff},
849 {BRCMS_SROM_MAXP5GHA0, 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff},
850 {BRCMS_SROM_MAXP5GLA0, 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00},
851 {BRCMS_SROM_PA5GW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff},
852 {BRCMS_SROM_PA5GW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff},
853 {BRCMS_SROM_PA5GW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff},
854 {BRCMS_SROM_PA5GLW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff},
855 {BRCMS_SROM_PA5GLW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 1,
856 0xffff},
857 {BRCMS_SROM_PA5GLW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 2,
858 0xffff},
859 {BRCMS_SROM_PA5GHW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff},
860 {BRCMS_SROM_PA5GHW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 1,
861 0xffff},
862 {BRCMS_SROM_PA5GHW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 2,
863 0xffff},
864 {BRCMS_SROM_NULL, 0, 0, 0, 0}
865};
866
867/* crc table has the same contents for every device instance, so it can be
868 * shared between devices. */
869static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE];
870
871static u16 __iomem *
872srom_window_address(struct si_pub *sih, u8 __iomem *curmap)
873{
874 if (sih->ccrev < 32)
875 return (u16 __iomem *)(curmap + PCI_BAR0_SPROM_OFFSET);
876 if (sih->cccaps & CC_CAP_SROM)
877 return (u16 __iomem *)
878 (curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP);
879
880 return NULL;
881}
882
883/* Parse SROM and create name=value pairs. 'srom' points to
884 * the SROM word array. 'off' specifies the offset of the
885 * first word 'srom' points to, which should be either 0 or
886 * SROM3_SWRG_OFF (full SROM or software region).
887 */
888
889static uint mask_shift(u16 mask)
890{
891 uint i;
892 for (i = 0; i < (sizeof(mask) << 3); i++) {
893 if (mask & (1 << i))
894 return i;
895 }
896 return 0;
897}
898
899static uint mask_width(u16 mask)
900{
901 int i;
902 for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) {
903 if (mask & (1 << i))
904 return (uint) (i - mask_shift(mask) + 1);
905 }
906 return 0;
907}
908
909static inline void ltoh16_buf(u16 *buf, unsigned int size)
910{
911 size /= 2;
912 while (size--)
913 *(buf + size) = le16_to_cpu(*(__le16 *)(buf + size));
914}
915
916static inline void htol16_buf(u16 *buf, unsigned int size)
917{
918 size /= 2;
919 while (size--)
920 *(__le16 *)(buf + size) = cpu_to_le16(*(buf + size));
921}
922
923/*
924 * convert binary srom data into linked list of srom variable items.
925 */
926static void
927_initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
928{
929 struct brcms_srom_list_head *entry;
930 enum brcms_srom_id id;
931 u16 w;
932 u32 val;
933 const struct brcms_sromvar *srv;
934 uint width;
935 uint flags;
936 u32 sr = (1 << sromrev);
937
938 /* first store the srom revision */
939 entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL);
940 entry->varid = BRCMS_SROM_REV;
941 entry->var_type = BRCMS_SROM_UNUMBER;
942 entry->uval = sromrev;
943 list_add(&entry->var_list, var_list);
944
945 for (srv = pci_sromvars; srv->varid != BRCMS_SROM_NULL; srv++) {
946 enum brcms_srom_var_type type;
947 u8 ea[ETH_ALEN];
948 u8 extra_space = 0;
949
950 if ((srv->revmask & sr) == 0)
951 continue;
952
953 flags = srv->flags;
954 id = srv->varid;
955
956 /* This entry is for mfgc only. Don't generate param for it, */
957 if (flags & SRFL_NOVAR)
958 continue;
959
960 if (flags & SRFL_ETHADDR) {
961 /*
962 * stored in string format XX:XX:XX:XX:XX:XX (17 chars)
963 */
964 ea[0] = (srom[srv->off] >> 8) & 0xff;
965 ea[1] = srom[srv->off] & 0xff;
966 ea[2] = (srom[srv->off + 1] >> 8) & 0xff;
967 ea[3] = srom[srv->off + 1] & 0xff;
968 ea[4] = (srom[srv->off + 2] >> 8) & 0xff;
969 ea[5] = srom[srv->off + 2] & 0xff;
970 /* 17 characters + string terminator - union size */
971 extra_space = 18 - sizeof(s32);
972 type = BRCMS_SROM_STRING;
973 } else {
974 w = srom[srv->off];
975 val = (w & srv->mask) >> mask_shift(srv->mask);
976 width = mask_width(srv->mask);
977
978 while (srv->flags & SRFL_MORE) {
979 srv++;
980 if (srv->off == 0)
981 continue;
982
983 w = srom[srv->off];
984 val +=
985 ((w & srv->mask) >> mask_shift(srv->
986 mask)) <<
987 width;
988 width += mask_width(srv->mask);
989 }
990
991 if ((flags & SRFL_NOFFS)
992 && ((int)val == (1 << width) - 1))
993 continue;
994
995 if (flags & SRFL_CCODE) {
996 type = BRCMS_SROM_STRING;
997 } else if (flags & SRFL_LEDDC) {
998 /* LED Powersave duty cycle has to be scaled:
999 *(oncount >> 24) (offcount >> 8)
1000 */
1001 u32 w32 = /* oncount */
1002 (((val >> 8) & 0xff) << 24) |
1003 /* offcount */
1004 (((val & 0xff)) << 8);
1005 type = BRCMS_SROM_UNUMBER;
1006 val = w32;
1007 } else if ((flags & SRFL_PRSIGN)
1008 && (val & (1 << (width - 1)))) {
1009 type = BRCMS_SROM_SNUMBER;
1010 val |= ~0 << width;
1011 } else
1012 type = BRCMS_SROM_UNUMBER;
1013 }
1014
1015 entry = kzalloc(sizeof(struct brcms_srom_list_head) +
1016 extra_space, GFP_KERNEL);
1017 entry->varid = id;
1018 entry->var_type = type;
1019 if (flags & SRFL_ETHADDR) {
1020 snprintf(entry->buf, 18, "%pM", ea);
1021 } else if (flags & SRFL_CCODE) {
1022 if (val == 0)
1023 entry->buf[0] = '\0';
1024 else
1025 snprintf(entry->buf, 3, "%c%c",
1026 (val >> 8), (val & 0xff));
1027 } else {
1028 entry->uval = val;
1029 }
1030
1031 list_add(&entry->var_list, var_list);
1032 }
1033
1034 if (sromrev >= 4) {
1035 /* Do per-path variables */
1036 uint p, pb, psz;
1037
1038 if (sromrev >= 8) {
1039 pb = SROM8_PATH0;
1040 psz = SROM8_PATH1 - SROM8_PATH0;
1041 } else {
1042 pb = SROM4_PATH0;
1043 psz = SROM4_PATH1 - SROM4_PATH0;
1044 }
1045
1046 for (p = 0; p < MAX_PATH_SROM; p++) {
1047 for (srv = perpath_pci_sromvars;
1048 srv->varid != BRCMS_SROM_NULL; srv++) {
1049 if ((srv->revmask & sr) == 0)
1050 continue;
1051
1052 if (srv->flags & SRFL_NOVAR)
1053 continue;
1054
1055 w = srom[pb + srv->off];
1056 val = (w & srv->mask) >> mask_shift(srv->mask);
1057 width = mask_width(srv->mask);
1058
1059 /* Cheating: no per-path var is more than
1060 * 1 word */
1061 if ((srv->flags & SRFL_NOFFS)
1062 && ((int)val == (1 << width) - 1))
1063 continue;
1064
1065 entry =
1066 kzalloc(sizeof(struct brcms_srom_list_head),
1067 GFP_KERNEL);
1068 entry->varid = srv->varid+p;
1069 entry->var_type = BRCMS_SROM_UNUMBER;
1070 entry->uval = val;
1071 list_add(&entry->var_list, var_list);
1072 }
1073 pb += psz;
1074 }
1075 }
1076}
1077
1078/*
1079 * Read in and validate sprom.
1080 * Return 0 on success, nonzero on error.
1081 */
1082static int
1083sprom_read_pci(struct si_pub *sih, u16 __iomem *sprom, uint wordoff,
1084 u16 *buf, uint nwords, bool check_crc)
1085{
1086 int err = 0;
1087 uint i;
1088
1089 /* read the sprom */
1090 for (i = 0; i < nwords; i++)
1091 buf[i] = R_REG(&sprom[wordoff + i]);
1092
1093 if (check_crc) {
1094
1095 if (buf[0] == 0xffff)
1096 /*
1097 * The hardware thinks that an srom that starts with
1098 * 0xffff is blank, regardless of the rest of the
1099 * content, so declare it bad.
1100 */
1101 return -ENODATA;
1102
1103 /* fixup the endianness so crc8 will pass */
1104 htol16_buf(buf, nwords * 2);
1105 if (crc8(brcms_srom_crc8_table, (u8 *) buf, nwords * 2,
1106 CRC8_INIT_VALUE) !=
1107 CRC8_GOOD_VALUE(brcms_srom_crc8_table))
1108 /* DBG only pci always read srom4 first, then srom8/9 */
1109 err = -EIO;
1110
1111 /* now correct the endianness of the byte array */
1112 ltoh16_buf(buf, nwords * 2);
1113 }
1114 return err;
1115}
1116
1117static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz)
1118{
1119 u8 *otp;
1120 uint sz = OTP_SZ_MAX / 2; /* size in words */
1121 int err = 0;
1122
1123 otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC);
1124 if (otp == NULL)
1125 return -ENOMEM;
1126
1127 err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz);
1128
1129 memcpy(buf, otp, bufsz);
1130
1131 kfree(otp);
1132
1133 /* Check CRC */
1134 if (buf[0] == 0xffff)
1135 /* The hardware thinks that an srom that starts with 0xffff
1136 * is blank, regardless of the rest of the content, so declare
1137 * it bad.
1138 */
1139 return -ENODATA;
1140
1141 /* fixup the endianness so crc8 will pass */
1142 htol16_buf(buf, bufsz);
1143 if (crc8(brcms_srom_crc8_table, (u8 *) buf, SROM4_WORDS * 2,
1144 CRC8_INIT_VALUE) != CRC8_GOOD_VALUE(brcms_srom_crc8_table))
1145 err = -EIO;
1146
1147 /* now correct the endianness of the byte array */
1148 ltoh16_buf(buf, bufsz);
1149
1150 return err;
1151}
1152
1153/*
1154 * Initialize nonvolatile variable table from sprom.
1155 * Return 0 on success, nonzero on error.
1156 */
1157static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap)
1158{
1159 u16 *srom;
1160 u16 __iomem *sromwindow;
1161 u8 sromrev = 0;
1162 u32 sr;
1163 int err = 0;
1164
1165 /*
1166 * Apply CRC over SROM content regardless SROM is present or not.
1167 */
1168 srom = kmalloc(SROM_MAX, GFP_ATOMIC);
1169 if (!srom)
1170 return -ENOMEM;
1171
1172 sromwindow = srom_window_address(sih, curmap);
1173
1174 crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY);
1175 if (ai_is_sprom_available(sih)) {
1176 err = sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS,
1177 true);
1178
1179 if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) ||
1180 (((sih->buscoretype == PCIE_CORE_ID)
1181 && (sih->buscorerev >= 6))
1182 || ((sih->buscoretype == PCI_CORE_ID)
1183 && (sih->buscorerev >= 0xe)))) {
1184 /* sromrev >= 4, read more */
1185 err = sprom_read_pci(sih, sromwindow, 0, srom,
1186 SROM4_WORDS, true);
1187 sromrev = srom[SROM4_CRCREV] & 0xff;
1188 } else if (err == 0) {
1189 /* srom is good and is rev < 4 */
1190 /* top word of sprom contains version and crc8 */
1191 sromrev = srom[SROM_CRCREV] & 0xff;
1192 /* bcm4401 sroms misprogrammed */
1193 if (sromrev == 0x10)
1194 sromrev = 1;
1195 }
1196 } else {
1197 /* Use OTP if SPROM not available */
1198 err = otp_read_pci(sih, srom, SROM_MAX);
1199 if (err == 0)
1200 /* OTP only contain SROM rev8/rev9 for now */
1201 sromrev = srom[SROM4_CRCREV] & 0xff;
1202 }
1203
1204 if (!err) {
1205 struct si_info *sii = (struct si_info *)sih;
1206
1207 /* Bitmask for the sromrev */
1208 sr = 1 << sromrev;
1209
1210 /*
1211 * srom version check: Current valid versions: 1, 2, 3, 4, 5, 8,
1212 * 9
1213 */
1214 if ((sr & 0x33e) == 0) {
1215 err = -EINVAL;
1216 goto errout;
1217 }
1218
1219 INIT_LIST_HEAD(&sii->var_list);
1220
1221 /* parse SROM into name=value pairs. */
1222 _initvars_srom_pci(sromrev, srom, &sii->var_list);
1223 }
1224
1225errout:
1226 kfree(srom);
1227 return err;
1228}
1229
1230void srom_free_vars(struct si_pub *sih)
1231{
1232 struct si_info *sii;
1233 struct brcms_srom_list_head *entry, *next;
1234
1235 sii = (struct si_info *)sih;
1236 list_for_each_entry_safe(entry, next, &sii->var_list, var_list) {
1237 list_del(&entry->var_list);
1238 kfree(entry);
1239 }
1240}
1241/*
1242 * Initialize local vars from the right source for this platform.
1243 * Return 0 on success, nonzero on error.
1244 */
1245int srom_var_init(struct si_pub *sih, void __iomem *curmap)
1246{
1247 uint len;
1248
1249 len = 0;
1250
1251 if (curmap != NULL)
1252 return initvars_srom_pci(sih, curmap);
1253
1254 return -EINVAL;
1255}
1256
1257/*
1258 * Search the name=value vars for a specific one and return its value.
1259 * Returns NULL if not found.
1260 */
1261char *getvar(struct si_pub *sih, enum brcms_srom_id id)
1262{
1263 struct si_info *sii;
1264 struct brcms_srom_list_head *entry;
1265
1266 sii = (struct si_info *)sih;
1267
1268 list_for_each_entry(entry, &sii->var_list, var_list)
1269 if (entry->varid == id)
1270 return &entry->buf[0];
1271
1272 /* nothing found */
1273 return NULL;
1274}
1275
1276/*
1277 * Search the vars for a specific one and return its value as
1278 * an integer. Returns 0 if not found.-
1279 */
1280int getintvar(struct si_pub *sih, enum brcms_srom_id id)
1281{
1282 struct si_info *sii;
1283 struct brcms_srom_list_head *entry;
1284 unsigned long res;
1285
1286 sii = (struct si_info *)sih;
1287
1288 list_for_each_entry(entry, &sii->var_list, var_list)
1289 if (entry->varid == id) {
1290 if (entry->var_type == BRCMS_SROM_SNUMBER ||
1291 entry->var_type == BRCMS_SROM_UNUMBER)
1292 return (int)entry->sval;
1293 else if (!kstrtoul(&entry->buf[0], 0, &res))
1294 return (int)res;
1295 }
1296
1297 return 0;
1298}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/srom.h b/drivers/net/wireless/brcm80211/brcmsmac/srom.h
new file mode 100644
index 000000000000..708c43ff51cc
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/srom.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_SROM_H_
18#define _BRCM_SROM_H_
19
20#include "types.h"
21
22/* Prototypes */
23extern int srom_var_init(struct si_pub *sih, void __iomem *curmap);
24extern void srom_free_vars(struct si_pub *sih);
25
26extern int srom_read(struct si_pub *sih, uint bus, void *curmap,
27 uint byteoff, uint nbytes, u16 *buf, bool check_crc);
28
29/* parse standard PCMCIA cis, normally used by SB/PCMCIA/SDIO/SPI/OTP
30 * and extract from it into name=value pairs
31 */
32extern int srom_parsecis(u8 **pcis, uint ciscnt,
33 char **vars, uint *count);
34#endif /* _BRCM_SROM_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.c b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
new file mode 100644
index 000000000000..d8f528eb180c
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
@@ -0,0 +1,436 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <net/mac80211.h>
18
19#include "types.h"
20#include "d11.h"
21#include "rate.h"
22#include "phy/phy_hal.h"
23#include "channel.h"
24#include "main.h"
25#include "stf.h"
26
27#define MIN_SPATIAL_EXPANSION 0
28#define MAX_SPATIAL_EXPANSION 1
29
30#define BRCMS_STF_SS_STBC_RX(wlc) (BRCMS_ISNPHY(wlc->band) && \
31 NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6))
32
33#define NSTS_1 1
34#define NSTS_2 2
35#define NSTS_3 3
36#define NSTS_4 4
37
38static const u8 txcore_default[5] = {
39 (0), /* bitmap of the core enabled */
40 (0x01), /* For Nsts = 1, enable core 1 */
41 (0x03), /* For Nsts = 2, enable core 1 & 2 */
42 (0x07), /* For Nsts = 3, enable core 1, 2 & 3 */
43 (0x0f) /* For Nsts = 4, enable all cores */
44};
45
46static void brcms_c_stf_stbc_rx_ht_update(struct brcms_c_info *wlc, int val)
47{
48 /* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */
49 if (BRCMS_STF_SS_STBC_RX(wlc)) {
50 if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO))
51 return;
52 }
53
54 if (wlc->pub->up) {
55 brcms_c_update_beacon(wlc);
56 brcms_c_update_probe_resp(wlc, true);
57 }
58}
59
60/*
61 * every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to
62 * turn on/off txchain.
63 */
64void brcms_c_tempsense_upd(struct brcms_c_info *wlc)
65{
66 struct brcms_phy_pub *pi = wlc->band->pi;
67 uint active_chains, txchain;
68
69 /* Check if the chip is too hot. Disable one Tx chain, if it is */
70 /* high 4 bits are for Rx chain, low 4 bits are for Tx chain */
71 active_chains = wlc_phy_stf_chain_active_get(pi);
72 txchain = active_chains & 0xf;
73
74 if (wlc->stf->txchain == wlc->stf->hw_txchain) {
75 if (txchain && (txchain < wlc->stf->hw_txchain))
76 /* turn off 1 tx chain */
77 brcms_c_stf_txchain_set(wlc, txchain, true);
78 } else if (wlc->stf->txchain < wlc->stf->hw_txchain) {
79 if (txchain == wlc->stf->hw_txchain)
80 /* turn back on txchain */
81 brcms_c_stf_txchain_set(wlc, txchain, true);
82 }
83}
84
85void
86brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel,
87 u16 chanspec)
88{
89 struct tx_power power;
90 u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id;
91
92 /* Clear previous settings */
93 *ss_algo_channel = 0;
94
95 if (!wlc->pub->up) {
96 *ss_algo_channel = (u16) -1;
97 return;
98 }
99
100 wlc_phy_txpower_get_current(wlc->band->pi, &power,
101 CHSPEC_CHANNEL(chanspec));
102
103 siso_mcs_id = (CHSPEC_IS40(chanspec)) ?
104 WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST;
105 cdd_mcs_id = (CHSPEC_IS40(chanspec)) ?
106 WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST;
107 stbc_mcs_id = (CHSPEC_IS40(chanspec)) ?
108 WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST;
109
110 /* criteria to choose stf mode */
111
112 /*
113 * the "+3dbm (12 0.25db units)" is to account for the fact that with
114 * CDD, tx occurs on both chains
115 */
116 if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12))
117 setbit(ss_algo_channel, PHY_TXC1_MODE_SISO);
118 else
119 setbit(ss_algo_channel, PHY_TXC1_MODE_CDD);
120
121 /*
122 * STBC is ORed into to algo channel as STBC requires per-packet SCB
123 * capability check so cannot be default mode of operation. One of
124 * SISO, CDD have to be set
125 */
126 if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12))
127 setbit(ss_algo_channel, PHY_TXC1_MODE_STBC);
128}
129
130static bool brcms_c_stf_stbc_tx_set(struct brcms_c_info *wlc, s32 int_val)
131{
132 if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON))
133 return false;
134
135 if ((int_val == ON) && (wlc->stf->txstreams == 1))
136 return false;
137
138 wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val;
139 wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val;
140
141 return true;
142}
143
144bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val)
145{
146 if ((int_val != HT_CAP_RX_STBC_NO)
147 && (int_val != HT_CAP_RX_STBC_ONE_STREAM))
148 return false;
149
150 if (BRCMS_STF_SS_STBC_RX(wlc)) {
151 if ((int_val != HT_CAP_RX_STBC_NO)
152 && (wlc->stf->rxstreams == 1))
153 return false;
154 }
155
156 brcms_c_stf_stbc_rx_ht_update(wlc, int_val);
157 return true;
158}
159
160static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts,
161 u8 core_mask)
162{
163 BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n",
164 wlc->pub->unit, Nsts, core_mask);
165
166 if (hweight8(core_mask) > wlc->stf->txstreams)
167 core_mask = 0;
168
169 if ((hweight8(core_mask) == wlc->stf->txstreams) &&
170 ((core_mask & ~wlc->stf->txchain)
171 || !(core_mask & wlc->stf->txchain)))
172 core_mask = wlc->stf->txchain;
173
174 wlc->stf->txcore[Nsts] = core_mask;
175 /* Nsts = 1..4, txcore index = 1..4 */
176 if (Nsts == 1) {
177 /* Needs to update beacon and ucode generated response
178 * frames when 1 stream core map changed
179 */
180 wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT;
181 brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
182 if (wlc->clk) {
183 brcms_c_suspend_mac_and_wait(wlc);
184 brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
185 brcms_c_enable_mac(wlc);
186 }
187 }
188
189 return 0;
190}
191
192static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val)
193{
194 int i;
195 u8 core_mask = 0;
196
197 BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val);
198
199 wlc->stf->spatial_policy = (s8) val;
200 for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
201 core_mask = (val == MAX_SPATIAL_EXPANSION) ?
202 wlc->stf->txchain : txcore_default[i];
203 brcms_c_stf_txcore_set(wlc, (u8) i, core_mask);
204 }
205 return 0;
206}
207
208/*
209 * Centralized txant update function. call it whenever wlc->stf->txant and/or
210 * wlc->stf->txchain change.
211 *
212 * Antennas are controlled by ucode indirectly, which drives PHY or GPIO to
213 * achieve various tx/rx antenna selection schemes
214 *
215 * legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7
216 * means auto(last rx).
217 * for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7
218 * means last rx and do tx-antenna selection for SISO transmissions
219 * for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7
220 * means last rx and do tx-antenna selection for SISO transmissions
221 * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7
222 * means both cores active
223*/
224static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
225{
226 s8 txant;
227
228 txant = (s8) wlc->stf->txant;
229 if (BRCMS_PHY_11N_CAP(wlc->band)) {
230 if (txant == ANT_TX_FORCE_0) {
231 wlc->stf->phytxant = PHY_TXC_ANT_0;
232 } else if (txant == ANT_TX_FORCE_1) {
233 wlc->stf->phytxant = PHY_TXC_ANT_1;
234
235 if (BRCMS_ISNPHY(wlc->band) &&
236 NREV_GE(wlc->band->phyrev, 3)
237 && NREV_LT(wlc->band->phyrev, 7))
238 wlc->stf->phytxant = PHY_TXC_ANT_2;
239 } else {
240 if (BRCMS_ISLCNPHY(wlc->band) ||
241 BRCMS_ISSSLPNPHY(wlc->band))
242 wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST;
243 else {
244 /* catch out of sync wlc->stf->txcore */
245 WARN_ON(wlc->stf->txchain <= 0);
246 wlc->stf->phytxant =
247 wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
248 }
249 }
250 } else {
251 if (txant == ANT_TX_FORCE_0)
252 wlc->stf->phytxant = PHY_TXC_OLD_ANT_0;
253 else if (txant == ANT_TX_FORCE_1)
254 wlc->stf->phytxant = PHY_TXC_OLD_ANT_1;
255 else
256 wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST;
257 }
258
259 brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
260}
261
262int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force)
263{
264 u8 txchain = (u8) int_val;
265 u8 txstreams;
266 uint i;
267
268 if (wlc->stf->txchain == txchain)
269 return 0;
270
271 if ((txchain & ~wlc->stf->hw_txchain)
272 || !(txchain & wlc->stf->hw_txchain))
273 return -EINVAL;
274
275 /*
276 * if nrate override is configured to be non-SISO STF mode, reject
277 * reducing txchain to 1
278 */
279 txstreams = (u8) hweight8(txchain);
280 if (txstreams > MAX_STREAMS_SUPPORTED)
281 return -EINVAL;
282
283 wlc->stf->txchain = txchain;
284 wlc->stf->txstreams = txstreams;
285 brcms_c_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx);
286 brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
287 brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
288 wlc->stf->txant =
289 (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF;
290 _brcms_c_stf_phy_txant_upd(wlc);
291
292 wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
293 wlc->stf->rxchain);
294
295 for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++)
296 brcms_c_stf_txcore_set(wlc, (u8) i, txcore_default[i]);
297
298 return 0;
299}
300
301/*
302 * update wlc->stf->ss_opmode which represents the operational stf_ss mode
303 * we're using
304 */
305int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band)
306{
307 int ret_code = 0;
308 u8 prev_stf_ss;
309 u8 upd_stf_ss;
310
311 prev_stf_ss = wlc->stf->ss_opmode;
312
313 /*
314 * NOTE: opmode can only be SISO or CDD as STBC is decided on a
315 * per-packet basis
316 */
317 if (BRCMS_STBC_CAP_PHY(wlc) &&
318 wlc->stf->ss_algosel_auto
319 && (wlc->stf->ss_algo_channel != (u16) -1)) {
320 upd_stf_ss = (wlc->stf->txstreams == 1 ||
321 isset(&wlc->stf->ss_algo_channel,
322 PHY_TXC1_MODE_SISO)) ?
323 PHY_TXC1_MODE_SISO : PHY_TXC1_MODE_CDD;
324 } else {
325 if (wlc->band != band)
326 return ret_code;
327 upd_stf_ss = (wlc->stf->txstreams == 1) ?
328 PHY_TXC1_MODE_SISO : band->band_stf_ss_mode;
329 }
330 if (prev_stf_ss != upd_stf_ss) {
331 wlc->stf->ss_opmode = upd_stf_ss;
332 brcms_b_band_stf_ss_set(wlc->hw, upd_stf_ss);
333 }
334
335 return ret_code;
336}
337
338int brcms_c_stf_attach(struct brcms_c_info *wlc)
339{
340 wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO;
341 wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD;
342
343 if (BRCMS_ISNPHY(wlc->band) &&
344 (wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON))
345 wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode =
346 PHY_TXC1_MODE_CDD;
347 brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
348 brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
349
350 brcms_c_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO);
351 wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
352 wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
353
354 if (BRCMS_STBC_CAP_PHY(wlc)) {
355 wlc->stf->ss_algosel_auto = true;
356 /* Init the default value */
357 wlc->stf->ss_algo_channel = (u16) -1;
358 }
359 return 0;
360}
361
362void brcms_c_stf_detach(struct brcms_c_info *wlc)
363{
364}
365
366void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
367{
368 _brcms_c_stf_phy_txant_upd(wlc);
369}
370
371void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc)
372{
373 /* get available rx/tx chains */
374 wlc->stf->hw_txchain = (u8) getintvar(wlc->hw->sih, BRCMS_SROM_TXCHAIN);
375 wlc->stf->hw_rxchain = (u8) getintvar(wlc->hw->sih, BRCMS_SROM_RXCHAIN);
376
377 /* these parameter are intended to be used for all PHY types */
378 if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) {
379 if (BRCMS_ISNPHY(wlc->band))
380 wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY;
381 else
382 wlc->stf->hw_txchain = TXCHAIN_DEF;
383 }
384
385 wlc->stf->txchain = wlc->stf->hw_txchain;
386 wlc->stf->txstreams = (u8) hweight8(wlc->stf->hw_txchain);
387
388 if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) {
389 if (BRCMS_ISNPHY(wlc->band))
390 wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY;
391 else
392 wlc->stf->hw_rxchain = RXCHAIN_DEF;
393 }
394
395 wlc->stf->rxchain = wlc->stf->hw_rxchain;
396 wlc->stf->rxstreams = (u8) hweight8(wlc->stf->hw_rxchain);
397
398 /* initialize the txcore table */
399 memcpy(wlc->stf->txcore, txcore_default, sizeof(wlc->stf->txcore));
400
401 /* default spatial_policy */
402 wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION;
403 brcms_c_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION);
404}
405
406static u16 _brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
407 u32 rspec)
408{
409 u16 phytxant = wlc->stf->phytxant;
410
411 if (rspec_stf(rspec) != PHY_TXC1_MODE_SISO)
412 phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
413 else if (wlc->stf->txant == ANT_TX_DEF)
414 phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
415 phytxant &= PHY_TXC_ANT_MASK;
416 return phytxant;
417}
418
419u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, u32 rspec)
420{
421 return _brcms_c_stf_phytxchain_sel(wlc, rspec);
422}
423
424u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, u32 rspec)
425{
426 u16 phytxant = wlc->stf->phytxant;
427 u16 mask = PHY_TXC_ANT_MASK;
428
429 /* for non-siso rates or default setting, use the available chains */
430 if (BRCMS_ISNPHY(wlc->band)) {
431 phytxant = _brcms_c_stf_phytxchain_sel(wlc, rspec);
432 mask = PHY_TXC_HTANT_MASK;
433 }
434 phytxant |= phytxant & mask;
435 return phytxant;
436}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.h b/drivers/net/wireless/brcm80211/brcmsmac/stf.h
new file mode 100644
index 000000000000..19f6580f69be
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_STF_H_
18#define _BRCM_STF_H_
19
20#include "types.h"
21
22extern int brcms_c_stf_attach(struct brcms_c_info *wlc);
23extern void brcms_c_stf_detach(struct brcms_c_info *wlc);
24
25extern void brcms_c_tempsense_upd(struct brcms_c_info *wlc);
26extern void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc,
27 u16 *ss_algo_channel,
28 u16 chanspec);
29extern int brcms_c_stf_ss_update(struct brcms_c_info *wlc,
30 struct brcms_band *band);
31extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
32extern int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val,
33 bool force);
34extern bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val);
35extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
36extern void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc);
37extern u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
38 u32 rspec);
39extern u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc,
40 u32 rspec);
41
42#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 000000000000..27a814b07462
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h
@@ -0,0 +1,352 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_TYPES_H_
18#define _BRCM_TYPES_H_
19
20#include <linux/types.h>
21#include <linux/io.h>
22
23#define WL_CHAN_FREQ_RANGE_2G 0
24#define WL_CHAN_FREQ_RANGE_5GL 1
25#define WL_CHAN_FREQ_RANGE_5GM 2
26#define WL_CHAN_FREQ_RANGE_5GH 3
27
28/* boardflags */
29
30/* Board has gpio 9 controlling the PA */
31#define BFL_PACTRL 0x00000002
32/* Not ok to power down the chip pll and oscillator */
33#define BFL_NOPLLDOWN 0x00000020
34/* Board supports the Front End Module */
35#define BFL_FEM 0x00000800
36/* Board has an external LNA in 2.4GHz band */
37#define BFL_EXTLNA 0x00001000
38/* Board has no PA */
39#define BFL_NOPA 0x00010000
40/* Power topology uses BUCKBOOST */
41#define BFL_BUCKBOOST 0x00200000
42/* Board has FEM and switch to share antenna w/ BT */
43#define BFL_FEM_BT 0x00400000
44/* Power topology doesn't use CBUCK */
45#define BFL_NOCBUCK 0x00800000
46/* Power topology uses PALDO */
47#define BFL_PALDO 0x02000000
48/* Board has an external LNA in 5GHz band */
49#define BFL_EXTLNA_5GHz 0x10000000
50
51/* boardflags2 */
52
53/* Board has an external rxbb regulator */
54#define BFL2_RXBB_INT_REG_DIS 0x00000001
55/* Flag to implement alternative A-band PLL settings */
56#define BFL2_APLL_WAR 0x00000002
57/* Board permits enabling TX Power Control */
58#define BFL2_TXPWRCTRL_EN 0x00000004
59/* Board supports the 2X4 diversity switch */
60#define BFL2_2X4_DIV 0x00000008
61/* Board supports 5G band power gain */
62#define BFL2_5G_PWRGAIN 0x00000010
63/* Board overrides ASPM and Clkreq settings */
64#define BFL2_PCIEWAR_OVR 0x00000020
65#define BFL2_LEGACY 0x00000080
66/* 4321mcm93 board uses Skyworks FEM */
67#define BFL2_SKWRKFEM_BRD 0x00000100
68/* Board has a WAR for clock-harmonic spurs */
69#define BFL2_SPUR_WAR 0x00000200
70/* Flag to narrow G-band PLL loop b/w */
71#define BFL2_GPLL_WAR 0x00000400
72/* Tx CCK pkts on Ant 0 only */
73#define BFL2_SINGLEANT_CCK 0x00001000
74/* WAR to reduce and avoid clock-harmonic spurs in 2G */
75#define BFL2_2G_SPUR_WAR 0x00002000
76/* Flag to widen G-band PLL loop b/w */
77#define BFL2_GPLL_WAR2 0x00010000
78#define BFL2_IPALVLSHIFT_3P3 0x00020000
79/* Use internal envelope detector for TX IQCAL */
80#define BFL2_INTERNDET_TXIQCAL 0x00040000
81/* Keep the buffered Xtal output from radio "ON". Most drivers will turn it
82 * off without this flag to save power. */
83#define BFL2_XTALBUFOUTEN 0x00080000
84
85/*
86 * board specific GPIO assignment, gpio 0-3 are also customer-configurable
87 * led
88 */
89
90/* bit 9 controls the PA on new 4306 boards */
91#define BOARD_GPIO_PACTRL 0x200
92#define BOARD_GPIO_12 0x1000
93#define BOARD_GPIO_13 0x2000
94
95/* **** Core type/rev defaults **** */
96#define D11CONF 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27
97 * also need to update wlc.h MAXCOREREV
98 */
99
100#define NCONF 0x000001ff /* Supported nphy revs:
101 * 0 4321a0
102 * 1 4321a1
103 * 2 4321b0/b1/c0/c1
104 * 3 4322a0
105 * 4 4322a1
106 * 5 4716a0
107 * 6 43222a0, 43224a0
108 * 7 43226a0
109 * 8 5357a0, 43236a0
110 */
111
112#define LCNCONF 0x00000007 /* Supported lcnphy revs:
113 * 0 4313a0, 4336a0, 4330a0
114 * 1
115 * 2 4330a0
116 */
117
118#define SSLPNCONF 0x0000000f /* Supported sslpnphy revs:
119 * 0 4329a0/k0
120 * 1 4329b0/4329C0
121 * 2 4319a0
122 * 3 5356a0
123 */
124
125/********************************************************************
126 * Phy/Core Configuration. Defines macros to to check core phy/rev *
127 * compile-time configuration. Defines default core support. *
128 * ******************************************************************
129 */
130
131/* Basic macros to check a configuration bitmask */
132
133#define CONF_HAS(config, val) ((config) & (1 << (val)))
134#define CONF_MSK(config, mask) ((config) & (mask))
135#define MSK_RANGE(low, hi) ((1 << ((hi)+1)) - (1 << (low)))
136#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high)))
137
138#define CONF_IS(config, val) ((config) == (1 << (val)))
139#define CONF_GE(config, val) ((config) & (0-(1 << (val))))
140#define CONF_GT(config, val) ((config) & (0-2*(1 << (val))))
141#define CONF_LT(config, val) ((config) & ((1 << (val))-1))
142#define CONF_LE(config, val) ((config) & (2*(1 << (val))-1))
143
144/* Wrappers for some of the above, specific to config constants */
145
146#define NCONF_HAS(val) CONF_HAS(NCONF, val)
147#define NCONF_MSK(mask) CONF_MSK(NCONF, mask)
148#define NCONF_IS(val) CONF_IS(NCONF, val)
149#define NCONF_GE(val) CONF_GE(NCONF, val)
150#define NCONF_GT(val) CONF_GT(NCONF, val)
151#define NCONF_LT(val) CONF_LT(NCONF, val)
152#define NCONF_LE(val) CONF_LE(NCONF, val)
153
154#define LCNCONF_HAS(val) CONF_HAS(LCNCONF, val)
155#define LCNCONF_MSK(mask) CONF_MSK(LCNCONF, mask)
156#define LCNCONF_IS(val) CONF_IS(LCNCONF, val)
157#define LCNCONF_GE(val) CONF_GE(LCNCONF, val)
158#define LCNCONF_GT(val) CONF_GT(LCNCONF, val)
159#define LCNCONF_LT(val) CONF_LT(LCNCONF, val)
160#define LCNCONF_LE(val) CONF_LE(LCNCONF, val)
161
162#define D11CONF_HAS(val) CONF_HAS(D11CONF, val)
163#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask)
164#define D11CONF_IS(val) CONF_IS(D11CONF, val)
165#define D11CONF_GE(val) CONF_GE(D11CONF, val)
166#define D11CONF_GT(val) CONF_GT(D11CONF, val)
167#define D11CONF_LT(val) CONF_LT(D11CONF, val)
168#define D11CONF_LE(val) CONF_LE(D11CONF, val)
169
170#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val)
171#define PHYCONF_IS(val) CONF_IS(PHYTYPE, val)
172
173#define NREV_IS(var, val) \
174 (NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val))))
175
176#define NREV_GE(var, val) \
177 (NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val))))
178
179#define NREV_GT(var, val) \
180 (NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val))))
181
182#define NREV_LT(var, val) \
183 (NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val))))
184
185#define NREV_LE(var, val) \
186 (NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val))))
187
188#define LCNREV_IS(var, val) \
189 (LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val))))
190
191#define LCNREV_GE(var, val) \
192 (LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val))))
193
194#define LCNREV_GT(var, val) \
195 (LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val))))
196
197#define LCNREV_LT(var, val) \
198 (LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val))))
199
200#define LCNREV_LE(var, val) \
201 (LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val))))
202
203#define D11REV_IS(var, val) \
204 (D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val))))
205
206#define D11REV_GE(var, val) \
207 (D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val))))
208
209#define D11REV_GT(var, val) \
210 (D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val))))
211
212#define D11REV_LT(var, val) \
213 (D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val))))
214
215#define D11REV_LE(var, val) \
216 (D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val))))
217
218#define PHYTYPE_IS(var, val)\
219 (PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val))))
220
221/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */
222
223#define _PHYCONF_N (1 << PHY_TYPE_N)
224#define _PHYCONF_LCN (1 << PHY_TYPE_LCN)
225#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN)
226
227#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN)
228
229/* Utility macro to identify 802.11n (HT) capable PHYs */
230#define PHYTYPE_11N_CAP(phytype) \
231 (PHYTYPE_IS(phytype, PHY_TYPE_N) || \
232 PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \
233 PHYTYPE_IS(phytype, PHY_TYPE_SSN))
234
235/* Last but not least: shorter wlc-specific var checks */
236#define BRCMS_ISNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_N)
237#define BRCMS_ISLCNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN)
238#define BRCMS_ISSSLPNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN)
239
240#define BRCMS_PHY_11N_CAP(band) PHYTYPE_11N_CAP((band)->phytype)
241
242/**********************************************************************
243 * ------------- End of Core phy/rev configuration. ----------------- *
244 * ********************************************************************
245 */
246
247#define BCMMSG(dev, fmt, args...) \
248do { \
249 if (brcm_msg_level & LOG_TRACE_VAL) \
250 wiphy_err(dev, "%s: " fmt, __func__, ##args); \
251} while (0)
252
253/*
254 * Register access macros.
255 *
256 * These macro's take a pointer to the address to read as one of their
257 * arguments. The macro itself deduces the size of the IO transaction (u8, u16
258 * or u32). Advantage of this approach in combination with using a struct to
259 * define the registers in a register block, is that access size and access
260 * location are defined in only one spot. This reduces the risk of the
261 * programmer trying to use an unsupported transaction size on a register.
262 *
263 */
264
265#define R_REG(r) \
266 ({ \
267 __typeof(*(r)) __osl_v; \
268 switch (sizeof(*(r))) { \
269 case sizeof(u8): \
270 __osl_v = readb((u8 __iomem *)(r)); \
271 break; \
272 case sizeof(u16): \
273 __osl_v = readw((u16 __iomem *)(r)); \
274 break; \
275 case sizeof(u32): \
276 __osl_v = readl((u32 __iomem *)(r)); \
277 break; \
278 } \
279 __osl_v; \
280 })
281
282#define W_REG(r, v) do { \
283 switch (sizeof(*(r))) { \
284 case sizeof(u8): \
285 writeb((u8)((v) & 0xFF), (u8 __iomem *)(r)); \
286 break; \
287 case sizeof(u16): \
288 writew((u16)((v) & 0xFFFF), (u16 __iomem *)(r)); \
289 break; \
290 case sizeof(u32): \
291 writel((u32)(v), (u32 __iomem *)(r)); \
292 break; \
293 } \
294 } while (0)
295
296#ifdef CONFIG_BCM47XX
297/*
298 * bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
299 * transactions. As a fix, a read after write is performed on certain places
300 * in the code. Older chips and the newer 5357 family don't require this fix.
301 */
302#define W_REG_FLUSH(r, v) ({ W_REG((r), (v)); (void)R_REG(r); })
303#else
304#define W_REG_FLUSH(r, v) W_REG((r), (v))
305#endif /* CONFIG_BCM47XX */
306
307#define AND_REG(r, v) W_REG((r), R_REG(r) & (v))
308#define OR_REG(r, v) W_REG((r), R_REG(r) | (v))
309
310#define SET_REG(r, mask, val) \
311 W_REG((r), ((R_REG(r) & ~(mask)) | (val)))
312
313/* multi-bool data type: set of bools, mbool is true if any is set */
314
315/* set one bool */
316#define mboolset(mb, bit) ((mb) |= (bit))
317/* clear one bool */
318#define mboolclr(mb, bit) ((mb) &= ~(bit))
319/* true if one bool is set */
320#define mboolisset(mb, bit) (((mb) & (bit)) != 0)
321#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val)))
322
323#define CEIL(x, y) (((x) + ((y)-1)) / (y))
324
325/* forward declarations */
326struct wiphy;
327struct ieee80211_sta;
328struct ieee80211_tx_queue_params;
329struct brcms_info;
330struct brcms_c_info;
331struct brcms_hardware;
332struct brcms_txq_info;
333struct brcms_band;
334struct dma_pub;
335struct si_pub;
336struct tx_status;
337struct d11rxhdr;
338struct txpwr_limits;
339
340/* iovar structure */
341struct brcmu_iovar {
342 const char *name; /* name for lookup and display */
343 u16 varid; /* id for switch */
344 u16 flags; /* driver-specific flag bits */
345 u16 type; /* base type of argument */
346 u16 minlen; /* min length for buffer vars */
347};
348
349/* brcm_msg_level is a bit vector with defs in defs.h */
350extern u32 brcm_msg_level;
351
352#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 000000000000..80e3ccf865e3
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c
@@ -0,0 +1,109 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <defs.h>
18#include "types.h"
19#include <ucode_loader.h>
20
21enum {
22 D11UCODE_NAMETAG_START = 0,
23 D11LCN0BSINITVALS24,
24 D11LCN0INITVALS24,
25 D11LCN1BSINITVALS24,
26 D11LCN1INITVALS24,
27 D11LCN2BSINITVALS24,
28 D11LCN2INITVALS24,
29 D11N0ABSINITVALS16,
30 D11N0BSINITVALS16,
31 D11N0INITVALS16,
32 D11UCODE_OVERSIGHT16_MIMO,
33 D11UCODE_OVERSIGHT16_MIMOSZ,
34 D11UCODE_OVERSIGHT24_LCN,
35 D11UCODE_OVERSIGHT24_LCNSZ,
36 D11UCODE_OVERSIGHT_BOMMAJOR,
37 D11UCODE_OVERSIGHT_BOMMINOR
38};
39
40int brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode)
41{
42 int rc;
43
44 rc = brcms_check_firmwares(wl);
45
46 rc = rc < 0 ? rc :
47 brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn0bsinitvals24,
48 D11LCN0BSINITVALS24);
49 rc = rc < 0 ?
50 rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn0initvals24,
51 D11LCN0INITVALS24);
52 rc = rc < 0 ?
53 rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn1bsinitvals24,
54 D11LCN1BSINITVALS24);
55 rc = rc < 0 ?
56 rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn1initvals24,
57 D11LCN1INITVALS24);
58 rc = rc < 0 ? rc :
59 brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn2bsinitvals24,
60 D11LCN2BSINITVALS24);
61 rc = rc < 0 ?
62 rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn2initvals24,
63 D11LCN2INITVALS24);
64 rc = rc < 0 ?
65 rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0absinitvals16,
66 D11N0ABSINITVALS16);
67 rc = rc < 0 ?
68 rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0bsinitvals16,
69 D11N0BSINITVALS16);
70 rc = rc < 0 ?
71 rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0initvals16,
72 D11N0INITVALS16);
73 rc = rc < 0 ?
74 rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_16_mimo,
75 D11UCODE_OVERSIGHT16_MIMO);
76 rc = rc < 0 ?
77 rc : brcms_ucode_init_uint(wl, &ucode->bcm43xx_16_mimosz,
78 D11UCODE_OVERSIGHT16_MIMOSZ);
79 rc = rc < 0 ?
80 rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_24_lcn,
81 D11UCODE_OVERSIGHT24_LCN);
82 rc = rc < 0 ?
83 rc : brcms_ucode_init_uint(wl, &ucode->bcm43xx_24_lcnsz,
84 D11UCODE_OVERSIGHT24_LCNSZ);
85 rc = rc < 0 ?
86 rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_bommajor,
87 D11UCODE_OVERSIGHT_BOMMAJOR);
88 rc = rc < 0 ?
89 rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_bomminor,
90 D11UCODE_OVERSIGHT_BOMMINOR);
91 return rc;
92}
93
94void brcms_ucode_data_free(struct brcms_ucode *ucode)
95{
96 brcms_ucode_free_buf((void *)ucode->d11lcn0bsinitvals24);
97 brcms_ucode_free_buf((void *)ucode->d11lcn0initvals24);
98 brcms_ucode_free_buf((void *)ucode->d11lcn1bsinitvals24);
99 brcms_ucode_free_buf((void *)ucode->d11lcn1initvals24);
100 brcms_ucode_free_buf((void *)ucode->d11lcn2bsinitvals24);
101 brcms_ucode_free_buf((void *)ucode->d11lcn2initvals24);
102 brcms_ucode_free_buf((void *)ucode->d11n0absinitvals16);
103 brcms_ucode_free_buf((void *)ucode->d11n0bsinitvals16);
104 brcms_ucode_free_buf((void *)ucode->d11n0initvals16);
105 brcms_ucode_free_buf((void *)ucode->bcm43xx_16_mimo);
106 brcms_ucode_free_buf((void *)ucode->bcm43xx_24_lcn);
107 brcms_ucode_free_buf((void *)ucode->bcm43xx_bommajor);
108 brcms_ucode_free_buf((void *)ucode->bcm43xx_bomminor);
109}
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 000000000000..18750a814b4f
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#ifndef _BRCM_UCODE_H_
17#define _BRCM_UCODE_H_
18
19#include "types.h" /* forward structure declarations */
20
21#define MIN_FW_SIZE 40000 /* minimum firmware file size in bytes */
22#define MAX_FW_SIZE 150000
23
24#define UCODE_LOADER_API_VER 0
25
26struct d11init;
27
28struct brcms_ucode {
29 struct d11init *d11lcn0bsinitvals24;
30 struct d11init *d11lcn0initvals24;
31 struct d11init *d11lcn1bsinitvals24;
32 struct d11init *d11lcn1initvals24;
33 struct d11init *d11lcn2bsinitvals24;
34 struct d11init *d11lcn2initvals24;
35 struct d11init *d11n0absinitvals16;
36 struct d11init *d11n0bsinitvals16;
37 struct d11init *d11n0initvals16;
38 __le32 *bcm43xx_16_mimo;
39 size_t bcm43xx_16_mimosz;
40 __le32 *bcm43xx_24_lcn;
41 size_t bcm43xx_24_lcnsz;
42 u32 *bcm43xx_bommajor;
43 u32 *bcm43xx_bomminor;
44};
45
46extern int
47brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode);
48
49extern void brcms_ucode_data_free(struct brcms_ucode *ucode);
50
51extern int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf,
52 unsigned int idx);
53extern int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes,
54 unsigned int idx);
55extern void brcms_ucode_free_buf(void *);
56extern int brcms_check_firmwares(struct brcms_info *wl);
57
58#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 000000000000..6281c416289e
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmutil/Makefile
@@ -0,0 +1,28 @@
1#
2# Makefile fragment for Broadcom 802.11n Networking Device Driver Utilities
3#
4# Copyright (c) 2011 Broadcom Corporation
5#
6# Permission to use, copy, modify, and/or distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18ccflags-y := \
19 -Idrivers/net/wireless/brcm80211/brcmutil \
20 -Idrivers/net/wireless/brcm80211/include
21
22BRCMUTIL_OFILES := \
23 utils.o
24
25MODULEPFX := brcmutil
26
27obj-$(CONFIG_BRCMUTIL) += $(MODULEPFX).o
28$(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 000000000000..f27c48910827
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c
@@ -0,0 +1,386 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/netdevice.h>
18#include <linux/module.h>
19#include <brcmu_utils.h>
20
21MODULE_AUTHOR("Broadcom Corporation");
22MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver utilities.");
23MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
24MODULE_LICENSE("Dual BSD/GPL");
25
26struct sk_buff *brcmu_pkt_buf_get_skb(uint len)
27{
28 struct sk_buff *skb;
29
30 skb = dev_alloc_skb(len);
31 if (skb) {
32 skb_put(skb, len);
33 skb->priority = 0;
34 }
35
36 return skb;
37}
38EXPORT_SYMBOL(brcmu_pkt_buf_get_skb);
39
40/* Free the driver packet. Free the tag if present */
41void brcmu_pkt_buf_free_skb(struct sk_buff *skb)
42{
43 struct sk_buff *nskb;
44 int nest = 0;
45
46 /* perversion: we use skb->next to chain multi-skb packets */
47 while (skb) {
48 nskb = skb->next;
49 skb->next = NULL;
50
51 if (skb->destructor)
52 /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if
53 * destructor exists
54 */
55 dev_kfree_skb_any(skb);
56 else
57 /* can free immediately (even in_irq()) if destructor
58 * does not exist
59 */
60 dev_kfree_skb(skb);
61
62 nest++;
63 skb = nskb;
64 }
65}
66EXPORT_SYMBOL(brcmu_pkt_buf_free_skb);
67
68
69/* copy a buffer into a pkt buffer chain */
70uint brcmu_pktfrombuf(struct sk_buff *p, uint offset, int len,
71 unsigned char *buf)
72{
73 uint n, ret = 0;
74
75 /* skip 'offset' bytes */
76 for (; p && offset; p = p->next) {
77 if (offset < (uint) (p->len))
78 break;
79 offset -= p->len;
80 }
81
82 if (!p)
83 return 0;
84
85 /* copy the data */
86 for (; p && len; p = p->next) {
87 n = min((uint) (p->len) - offset, (uint) len);
88 memcpy(p->data + offset, buf, n);
89 buf += n;
90 len -= n;
91 ret += n;
92 offset = 0;
93 }
94
95 return ret;
96}
97EXPORT_SYMBOL(brcmu_pktfrombuf);
98
99/* return total length of buffer chain */
100uint brcmu_pkttotlen(struct sk_buff *p)
101{
102 uint total;
103
104 total = 0;
105 for (; p; p = p->next)
106 total += p->len;
107 return total;
108}
109EXPORT_SYMBOL(brcmu_pkttotlen);
110
111/*
112 * osl multiple-precedence packet queue
113 * hi_prec is always >= the number of the highest non-empty precedence
114 */
115struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec,
116 struct sk_buff *p)
117{
118 struct pktq_prec *q;
119
120 if (pktq_full(pq) || pktq_pfull(pq, prec))
121 return NULL;
122
123 q = &pq->q[prec];
124
125 if (q->head)
126 q->tail->prev = p;
127 else
128 q->head = p;
129
130 q->tail = p;
131 q->len++;
132
133 pq->len++;
134
135 if (pq->hi_prec < prec)
136 pq->hi_prec = (u8) prec;
137
138 return p;
139}
140EXPORT_SYMBOL(brcmu_pktq_penq);
141
142struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
143 struct sk_buff *p)
144{
145 struct pktq_prec *q;
146
147 if (pktq_full(pq) || pktq_pfull(pq, prec))
148 return NULL;
149
150 q = &pq->q[prec];
151
152 if (q->head == NULL)
153 q->tail = p;
154
155 p->prev = q->head;
156 q->head = p;
157 q->len++;
158
159 pq->len++;
160
161 if (pq->hi_prec < prec)
162 pq->hi_prec = (u8) prec;
163
164 return p;
165}
166EXPORT_SYMBOL(brcmu_pktq_penq_head);
167
168struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec)
169{
170 struct pktq_prec *q;
171 struct sk_buff *p;
172
173 q = &pq->q[prec];
174
175 p = q->head;
176 if (p == NULL)
177 return NULL;
178
179 q->head = p->prev;
180 if (q->head == NULL)
181 q->tail = NULL;
182
183 q->len--;
184
185 pq->len--;
186
187 p->prev = NULL;
188
189 return p;
190}
191EXPORT_SYMBOL(brcmu_pktq_pdeq);
192
193struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec)
194{
195 struct pktq_prec *q;
196 struct sk_buff *p, *prev;
197
198 q = &pq->q[prec];
199
200 p = q->head;
201 if (p == NULL)
202 return NULL;
203
204 for (prev = NULL; p != q->tail; p = p->prev)
205 prev = p;
206
207 if (prev)
208 prev->prev = NULL;
209 else
210 q->head = NULL;
211
212 q->tail = prev;
213 q->len--;
214
215 pq->len--;
216
217 return p;
218}
219EXPORT_SYMBOL(brcmu_pktq_pdeq_tail);
220
221void
222brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir,
223 bool (*fn)(struct sk_buff *, void *), void *arg)
224{
225 struct pktq_prec *q;
226 struct sk_buff *p, *prev = NULL;
227
228 q = &pq->q[prec];
229 p = q->head;
230 while (p) {
231 if (fn == NULL || (*fn) (p, arg)) {
232 bool head = (p == q->head);
233 if (head)
234 q->head = p->prev;
235 else
236 prev->prev = p->prev;
237 p->prev = NULL;
238 brcmu_pkt_buf_free_skb(p);
239 q->len--;
240 pq->len--;
241 p = (head ? q->head : prev->prev);
242 } else {
243 prev = p;
244 p = p->prev;
245 }
246 }
247
248 if (q->head == NULL)
249 q->tail = NULL;
250}
251EXPORT_SYMBOL(brcmu_pktq_pflush);
252
253void brcmu_pktq_flush(struct pktq *pq, bool dir,
254 bool (*fn)(struct sk_buff *, void *), void *arg)
255{
256 int prec;
257 for (prec = 0; prec < pq->num_prec; prec++)
258 brcmu_pktq_pflush(pq, prec, dir, fn, arg);
259}
260EXPORT_SYMBOL(brcmu_pktq_flush);
261
262void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len)
263{
264 int prec;
265
266 /* pq is variable size; only zero out what's requested */
267 memset(pq, 0,
268 offsetof(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec));
269
270 pq->num_prec = (u16) num_prec;
271
272 pq->max = (u16) max_len;
273
274 for (prec = 0; prec < num_prec; prec++)
275 pq->q[prec].max = pq->max;
276}
277EXPORT_SYMBOL(brcmu_pktq_init);
278
279struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out)
280{
281 int prec;
282
283 if (pq->len == 0)
284 return NULL;
285
286 for (prec = 0; prec < pq->hi_prec; prec++)
287 if (pq->q[prec].head)
288 break;
289
290 if (prec_out)
291 *prec_out = prec;
292
293 return pq->q[prec].tail;
294}
295EXPORT_SYMBOL(brcmu_pktq_peek_tail);
296
297/* Return sum of lengths of a specific set of precedences */
298int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp)
299{
300 int prec, len;
301
302 len = 0;
303
304 for (prec = 0; prec <= pq->hi_prec; prec++)
305 if (prec_bmp & (1 << prec))
306 len += pq->q[prec].len;
307
308 return len;
309}
310EXPORT_SYMBOL(brcmu_pktq_mlen);
311
312/* Priority dequeue from a specific set of precedences */
313struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
314 int *prec_out)
315{
316 struct pktq_prec *q;
317 struct sk_buff *p;
318 int prec;
319
320 if (pq->len == 0)
321 return NULL;
322
323 while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
324 pq->hi_prec--;
325
326 while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL)
327 if (prec-- == 0)
328 return NULL;
329
330 q = &pq->q[prec];
331
332 p = q->head;
333 if (p == NULL)
334 return NULL;
335
336 q->head = p->prev;
337 if (q->head == NULL)
338 q->tail = NULL;
339
340 q->len--;
341
342 if (prec_out)
343 *prec_out = prec;
344
345 pq->len--;
346
347 p->prev = NULL;
348
349 return p;
350}
351EXPORT_SYMBOL(brcmu_pktq_mdeq);
352
353#if defined(BCMDBG)
354/* pretty hex print a pkt buffer chain */
355void brcmu_prpkt(const char *msg, struct sk_buff *p0)
356{
357 struct sk_buff *p;
358
359 if (msg && (msg[0] != '\0'))
360 printk(KERN_DEBUG "%s:\n", msg);
361
362 for (p = p0; p; p = p->next)
363 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len);
364}
365EXPORT_SYMBOL(brcmu_prpkt);
366#endif /* defined(BCMDBG) */
367
368#if defined(BCMDBG)
369/*
370 * print bytes formatted as hex to a string. return the resulting
371 * string length
372 */
373int brcmu_format_hex(char *str, const void *bytes, int len)
374{
375 int i;
376 char *p = str;
377 const u8 *src = (const u8 *)bytes;
378
379 for (i = 0; i < len; i++) {
380 p += snprintf(p, 3, "%02X", *src);
381 src++;
382 }
383 return (int)(p - str);
384}
385EXPORT_SYMBOL(brcmu_format_hex);
386#endif /* defined(BCMDBG) */
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 000000000000..5fb17d53c9b2
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
@@ -0,0 +1,59 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_HW_IDS_H_
18#define _BRCM_HW_IDS_H_
19
20#define BCM4325_D11DUAL_ID 0x431b
21#define BCM4325_D11G_ID 0x431c
22#define BCM4325_D11A_ID 0x431d
23
24#define BCM4329_D11N2G_ID 0x432f /* 4329 802.11n 2.4G device */
25#define BCM4329_D11N5G_ID 0x4330 /* 4329 802.11n 5G device */
26#define BCM4329_D11NDUAL_ID 0x432e
27
28#define BCM4319_D11N_ID 0x4337 /* 4319 802.11n dualband device */
29#define BCM4319_D11N2G_ID 0x4338 /* 4319 802.11n 2.4G device */
30#define BCM4319_D11N5G_ID 0x4339 /* 4319 802.11n 5G device */
31
32#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */
33#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db */
34
35#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */
36
37#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */
38#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */
39
40#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
41
42/* Chip IDs */
43#define BCM4313_CHIP_ID 0x4313 /* 4313 chip id */
44#define BCM4319_CHIP_ID 0x4319 /* 4319 chip id */
45
46#define BCM43224_CHIP_ID 43224 /* 43224 chipcommon chipid */
47#define BCM43225_CHIP_ID 43225 /* 43225 chipcommon chipid */
48#define BCM43421_CHIP_ID 43421 /* 43421 chipcommon chipid */
49#define BCM43235_CHIP_ID 43235 /* 43235 chipcommon chipid */
50#define BCM43236_CHIP_ID 43236 /* 43236 chipcommon chipid */
51#define BCM43238_CHIP_ID 43238 /* 43238 chipcommon chipid */
52#define BCM4329_CHIP_ID 0x4329 /* 4329 chipcommon chipid */
53#define BCM4325_CHIP_ID 0x4325 /* 4325 chipcommon chipid */
54#define BCM4331_CHIP_ID 0x4331 /* 4331 chipcommon chipid */
55#define BCM4336_CHIP_ID 0x4336 /* 4336 chipcommon chipid */
56#define BCM4330_CHIP_ID 0x4330 /* 4330 chipcommon chipid */
57#define BCM6362_CHIP_ID 0x6362 /* 6362 chipcommon chipid */
58
59#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 000000000000..7d0f46e0eb95
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
@@ -0,0 +1,195 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCMU_UTILS_H_
18#define _BRCMU_UTILS_H_
19
20#include <linux/skbuff.h>
21
22/*
23 * Spin at most 'us' microseconds while 'exp' is true.
24 * Caller should explicitly test 'exp' when this completes
25 * and take appropriate error action if 'exp' is still true.
26 */
27#define SPINWAIT(exp, us) { \
28 uint countdown = (us) + 9; \
29 while ((exp) && (countdown >= 10)) {\
30 udelay(10); \
31 countdown -= 10; \
32 } \
33}
34
35/* osl multi-precedence packet queue */
36#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */
37#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */
38
39#define BCME_STRLEN 64 /* Max string length for BCM errors */
40
41/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
42#define PKTBUFSZ 2048
43
44#ifndef setbit
45#ifndef NBBY /* the BSD family defines NBBY */
46#define NBBY 8 /* 8 bits per byte */
47#endif /* #ifndef NBBY */
48#define setbit(a, i) (((u8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
49#define clrbit(a, i) (((u8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
50#define isset(a, i) (((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
51#define isclr(a, i) ((((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
52#endif /* setbit */
53
54#define NBITS(type) (sizeof(type) * 8)
55#define NBITVAL(nbits) (1 << (nbits))
56#define MAXBITVAL(nbits) ((1 << (nbits)) - 1)
57#define NBITMASK(nbits) MAXBITVAL(nbits)
58#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8)
59
60/* crc defines */
61#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */
62#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */
63
64/* 18-bytes of Ethernet address buffer length */
65#define ETHER_ADDR_STR_LEN 18
66
67struct pktq_prec {
68 struct sk_buff *head; /* first packet to dequeue */
69 struct sk_buff *tail; /* last packet to dequeue */
70 u16 len; /* number of queued packets */
71 u16 max; /* maximum number of queued packets */
72};
73
74/* multi-priority pkt queue */
75struct pktq {
76 u16 num_prec; /* number of precedences in use */
77 u16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */
78 u16 max; /* total max packets */
79 u16 len; /* total number of packets */
80 /*
81 * q array must be last since # of elements can be either
82 * PKTQ_MAX_PREC or 1
83 */
84 struct pktq_prec q[PKTQ_MAX_PREC];
85};
86
87/* operations on a specific precedence in packet queue */
88
89static inline int pktq_plen(struct pktq *pq, int prec)
90{
91 return pq->q[prec].len;
92}
93
94static inline int pktq_pavail(struct pktq *pq, int prec)
95{
96 return pq->q[prec].max - pq->q[prec].len;
97}
98
99static inline bool pktq_pfull(struct pktq *pq, int prec)
100{
101 return pq->q[prec].len >= pq->q[prec].max;
102}
103
104static inline bool pktq_pempty(struct pktq *pq, int prec)
105{
106 return pq->q[prec].len == 0;
107}
108
109static inline struct sk_buff *pktq_ppeek(struct pktq *pq, int prec)
110{
111 return pq->q[prec].head;
112}
113
114static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec)
115{
116 return pq->q[prec].tail;
117}
118
119extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec,
120 struct sk_buff *p);
121extern struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
122 struct sk_buff *p);
123extern struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec);
124extern struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec);
125
126/* packet primitives */
127extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len);
128extern void brcmu_pkt_buf_free_skb(struct sk_buff *skb);
129
130/* Empty the queue at particular precedence level */
131/* callback function fn(pkt, arg) returns true if pkt belongs to if */
132extern void brcmu_pktq_pflush(struct pktq *pq, int prec,
133 bool dir, bool (*fn)(struct sk_buff *, void *), void *arg);
134
135/* operations on a set of precedences in packet queue */
136
137extern int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp);
138extern struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
139 int *prec_out);
140
141/* operations on packet queue as a whole */
142
143static inline int pktq_len(struct pktq *pq)
144{
145 return (int)pq->len;
146}
147
148static inline int pktq_max(struct pktq *pq)
149{
150 return (int)pq->max;
151}
152
153static inline int pktq_avail(struct pktq *pq)
154{
155 return (int)(pq->max - pq->len);
156}
157
158static inline bool pktq_full(struct pktq *pq)
159{
160 return pq->len >= pq->max;
161}
162
163static inline bool pktq_empty(struct pktq *pq)
164{
165 return pq->len == 0;
166}
167
168extern void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len);
169/* prec_out may be NULL if caller is not interested in return value */
170extern struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out);
171extern void brcmu_pktq_flush(struct pktq *pq, bool dir,
172 bool (*fn)(struct sk_buff *, void *), void *arg);
173
174/* externs */
175/* packet */
176extern uint brcmu_pktfrombuf(struct sk_buff *p,
177 uint offset, int len, unsigned char *buf);
178extern uint brcmu_pkttotlen(struct sk_buff *p);
179
180/* ip address */
181struct ipv4_addr;
182
183#ifdef BCMDBG
184extern void brcmu_prpkt(const char *msg, struct sk_buff *p0);
185#else
186#define brcmu_prpkt(a, b)
187#endif /* BCMDBG */
188
189/* externs */
190/* format/print */
191#if defined(BCMDBG)
192extern int brcmu_format_hex(char *str, const void *bytes, int len);
193#endif
194
195#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 000000000000..f10d30274c23
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
@@ -0,0 +1,239 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCMU_WIFI_H_
18#define _BRCMU_WIFI_H_
19
20#include <linux/if_ether.h> /* for ETH_ALEN */
21#include <linux/ieee80211.h> /* for WLAN_PMKID_LEN */
22
23/*
24 * A chanspec (u16) holds the channel number, band, bandwidth and control
25 * sideband
26 */
27
28/* channel defines */
29#define CH_UPPER_SB 0x01
30#define CH_LOWER_SB 0x02
31#define CH_EWA_VALID 0x04
32#define CH_20MHZ_APART 4
33#define CH_10MHZ_APART 2
34#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */
35#define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
36#define BRCM_MAX_2G_CHANNEL CH_MAX_2G_CHANNEL /* legacy define */
37
38/* bandstate array indices */
39#define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */
40#define BAND_5G_INDEX 1 /* wlc->bandstate[x] index */
41
42/*
43 * max # supported channels. The max channel no is 216, this is that + 1
44 * rounded up to a multiple of NBBY (8). DO NOT MAKE it > 255: channels are
45 * u8's all over
46*/
47#define MAXCHANNEL 224
48
49#define WL_CHANSPEC_CHAN_MASK 0x00ff
50#define WL_CHANSPEC_CHAN_SHIFT 0
51
52#define WL_CHANSPEC_CTL_SB_MASK 0x0300
53#define WL_CHANSPEC_CTL_SB_SHIFT 8
54#define WL_CHANSPEC_CTL_SB_LOWER 0x0100
55#define WL_CHANSPEC_CTL_SB_UPPER 0x0200
56#define WL_CHANSPEC_CTL_SB_NONE 0x0300
57
58#define WL_CHANSPEC_BW_MASK 0x0C00
59#define WL_CHANSPEC_BW_SHIFT 10
60#define WL_CHANSPEC_BW_10 0x0400
61#define WL_CHANSPEC_BW_20 0x0800
62#define WL_CHANSPEC_BW_40 0x0C00
63
64#define WL_CHANSPEC_BAND_MASK 0xf000
65#define WL_CHANSPEC_BAND_SHIFT 12
66#define WL_CHANSPEC_BAND_5G 0x1000
67#define WL_CHANSPEC_BAND_2G 0x2000
68#define INVCHANSPEC 255
69
70/* used to calculate the chan_freq = chan_factor * 500Mhz + 5 * chan_number */
71#define WF_CHAN_FACTOR_2_4_G 4814 /* 2.4 GHz band, 2407 MHz */
72#define WF_CHAN_FACTOR_5_G 10000 /* 5 GHz band, 5000 MHz */
73#define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */
74
75#define CHSPEC_CHANNEL(chspec) ((u8)((chspec) & WL_CHANSPEC_CHAN_MASK))
76#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK)
77
78#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK)
79#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK)
80
81#define CHSPEC_IS10(chspec) \
82 (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
83
84#define CHSPEC_IS20(chspec) \
85 (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
86
87#ifndef CHSPEC_IS40
88#define CHSPEC_IS40(chspec) \
89 (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
90#endif
91
92#define CHSPEC_IS5G(chspec) \
93 (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
94
95#define CHSPEC_IS2G(chspec) \
96 (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
97
98#define CHSPEC_SB_NONE(chspec) \
99 (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE)
100
101#define CHSPEC_SB_UPPER(chspec) \
102 (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER)
103
104#define CHSPEC_SB_LOWER(chspec) \
105 (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER)
106
107#define CHSPEC_CTL_CHAN(chspec) \
108 ((CHSPEC_SB_LOWER(chspec)) ? \
109 (lower_20_sb(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \
110 (upper_20_sb(((chspec) & WL_CHANSPEC_CHAN_MASK))))
111
112#define CHSPEC2BAND(chspec) (CHSPEC_IS5G(chspec) ? BRCM_BAND_5G : BRCM_BAND_2G)
113
114#define CHANSPEC_STR_LEN 8
115
116static inline int lower_20_sb(int channel)
117{
118 return channel > CH_10MHZ_APART ? (channel - CH_10MHZ_APART) : 0;
119}
120
121static inline int upper_20_sb(int channel)
122{
123 return (channel < (MAXCHANNEL - CH_10MHZ_APART)) ?
124 channel + CH_10MHZ_APART : 0;
125}
126
127static inline int chspec_bandunit(u16 chspec)
128{
129 return CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX;
130}
131
132static inline u16 ch20mhz_chspec(int channel)
133{
134 u16 rc = channel <= CH_MAX_2G_CHANNEL ?
135 WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G;
136
137 return (u16)((u16)channel | WL_CHANSPEC_BW_20 |
138 WL_CHANSPEC_CTL_SB_NONE | rc);
139}
140
141static inline int next_20mhz_chan(int channel)
142{
143 return channel < (MAXCHANNEL - CH_20MHZ_APART) ?
144 channel + CH_20MHZ_APART : 0;
145}
146
147/* defined rate in 500kbps */
148#define BRCM_MAXRATE 108 /* in 500kbps units */
149#define BRCM_RATE_1M 2 /* in 500kbps units */
150#define BRCM_RATE_2M 4 /* in 500kbps units */
151#define BRCM_RATE_5M5 11 /* in 500kbps units */
152#define BRCM_RATE_11M 22 /* in 500kbps units */
153#define BRCM_RATE_6M 12 /* in 500kbps units */
154#define BRCM_RATE_9M 18 /* in 500kbps units */
155#define BRCM_RATE_12M 24 /* in 500kbps units */
156#define BRCM_RATE_18M 36 /* in 500kbps units */
157#define BRCM_RATE_24M 48 /* in 500kbps units */
158#define BRCM_RATE_36M 72 /* in 500kbps units */
159#define BRCM_RATE_48M 96 /* in 500kbps units */
160#define BRCM_RATE_54M 108 /* in 500kbps units */
161
162#define BRCM_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */
163
164#define MCSSET_LEN 16
165
166static inline bool ac_bitmap_tst(u8 bitmap, int prec)
167{
168 return (bitmap & (1 << (prec))) != 0;
169}
170
171/* Enumerate crypto algorithms */
172#define CRYPTO_ALGO_OFF 0
173#define CRYPTO_ALGO_WEP1 1
174#define CRYPTO_ALGO_TKIP 2
175#define CRYPTO_ALGO_WEP128 3
176#define CRYPTO_ALGO_AES_CCM 4
177#define CRYPTO_ALGO_AES_RESERVED1 5
178#define CRYPTO_ALGO_AES_RESERVED2 6
179#define CRYPTO_ALGO_NALG 7
180
181/* wireless security bitvec */
182
183#define WEP_ENABLED 0x0001
184#define TKIP_ENABLED 0x0002
185#define AES_ENABLED 0x0004
186#define WSEC_SWFLAG 0x0008
187/* to go into transition mode without setting wep */
188#define SES_OW_ENABLED 0x0040
189
190/* WPA authentication mode bitvec */
191#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */
192#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */
193#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */
194#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */
195#define WPA_AUTH_RESERVED1 0x0008
196#define WPA_AUTH_RESERVED2 0x0010
197
198#define WPA2_AUTH_RESERVED1 0x0020
199#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */
200#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */
201#define WPA2_AUTH_RESERVED3 0x0200
202#define WPA2_AUTH_RESERVED4 0x0400
203#define WPA2_AUTH_RESERVED5 0x0800
204
205/* pmkid */
206#define MAXPMKID 16
207
208#define DOT11_DEFAULT_RTS_LEN 2347
209#define DOT11_DEFAULT_FRAG_LEN 2346
210
211#define DOT11_ICV_AES_LEN 8
212#define DOT11_QOS_LEN 2
213#define DOT11_IV_MAX_LEN 8
214#define DOT11_A4_HDR_LEN 30
215
216#define HT_CAP_RX_STBC_NO 0x0
217#define HT_CAP_RX_STBC_ONE_STREAM 0x1
218
219struct pmkid {
220 u8 BSSID[ETH_ALEN];
221 u8 PMKID[WLAN_PMKID_LEN];
222};
223
224struct pmkid_list {
225 __le32 npmkid;
226 struct pmkid pmkid[1];
227};
228
229struct pmkid_cand {
230 u8 BSSID[ETH_ALEN];
231 u8 preauth;
232};
233
234struct pmkid_cand_list {
235 u32 npmkid_cand;
236 struct pmkid_cand pmkid_cand[1];
237};
238
239#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 000000000000..fefabc39e646
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/include/chipcommon.h
@@ -0,0 +1,284 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _SBCHIPC_H
18#define _SBCHIPC_H
19
20#include "defs.h" /* for PAD macro */
21
22struct chipcregs {
23 u32 chipid; /* 0x0 */
24 u32 capabilities;
25 u32 corecontrol; /* corerev >= 1 */
26 u32 bist;
27
28 /* OTP */
29 u32 otpstatus; /* 0x10, corerev >= 10 */
30 u32 otpcontrol;
31 u32 otpprog;
32 u32 otplayout; /* corerev >= 23 */
33
34 /* Interrupt control */
35 u32 intstatus; /* 0x20 */
36 u32 intmask;
37
38 /* Chip specific regs */
39 u32 chipcontrol; /* 0x28, rev >= 11 */
40 u32 chipstatus; /* 0x2c, rev >= 11 */
41
42 /* Jtag Master */
43 u32 jtagcmd; /* 0x30, rev >= 10 */
44 u32 jtagir;
45 u32 jtagdr;
46 u32 jtagctrl;
47
48 /* serial flash interface registers */
49 u32 flashcontrol; /* 0x40 */
50 u32 flashaddress;
51 u32 flashdata;
52 u32 PAD[1];
53
54 /* Silicon backplane configuration broadcast control */
55 u32 broadcastaddress; /* 0x50 */
56 u32 broadcastdata;
57
58 /* gpio - cleared only by power-on-reset */
59 u32 gpiopullup; /* 0x58, corerev >= 20 */
60 u32 gpiopulldown; /* 0x5c, corerev >= 20 */
61 u32 gpioin; /* 0x60 */
62 u32 gpioout; /* 0x64 */
63 u32 gpioouten; /* 0x68 */
64 u32 gpiocontrol; /* 0x6C */
65 u32 gpiointpolarity; /* 0x70 */
66 u32 gpiointmask; /* 0x74 */
67
68 /* GPIO events corerev >= 11 */
69 u32 gpioevent;
70 u32 gpioeventintmask;
71
72 /* Watchdog timer */
73 u32 watchdog; /* 0x80 */
74
75 /* GPIO events corerev >= 11 */
76 u32 gpioeventintpolarity;
77
78 /* GPIO based LED powersave registers corerev >= 16 */
79 u32 gpiotimerval; /* 0x88 */
80 u32 gpiotimeroutmask;
81
82 /* clock control */
83 u32 clockcontrol_n; /* 0x90 */
84 u32 clockcontrol_sb; /* aka m0 */
85 u32 clockcontrol_pci; /* aka m1 */
86 u32 clockcontrol_m2; /* mii/uart/mipsref */
87 u32 clockcontrol_m3; /* cpu */
88 u32 clkdiv; /* corerev >= 3 */
89 u32 gpiodebugsel; /* corerev >= 28 */
90 u32 capabilities_ext; /* 0xac */
91
92 /* pll delay registers (corerev >= 4) */
93 u32 pll_on_delay; /* 0xb0 */
94 u32 fref_sel_delay;
95 u32 slow_clk_ctl; /* 5 < corerev < 10 */
96 u32 PAD;
97
98 /* Instaclock registers (corerev >= 10) */
99 u32 system_clk_ctl; /* 0xc0 */
100 u32 clkstatestretch;
101 u32 PAD[2];
102
103 /* Indirect backplane access (corerev >= 22) */
104 u32 bp_addrlow; /* 0xd0 */
105 u32 bp_addrhigh;
106 u32 bp_data;
107 u32 PAD;
108 u32 bp_indaccess;
109 u32 PAD[3];
110
111 /* More clock dividers (corerev >= 32) */
112 u32 clkdiv2;
113 u32 PAD[2];
114
115 /* In AI chips, pointer to erom */
116 u32 eromptr; /* 0xfc */
117
118 /* ExtBus control registers (corerev >= 3) */
119 u32 pcmcia_config; /* 0x100 */
120 u32 pcmcia_memwait;
121 u32 pcmcia_attrwait;
122 u32 pcmcia_iowait;
123 u32 ide_config;
124 u32 ide_memwait;
125 u32 ide_attrwait;
126 u32 ide_iowait;
127 u32 prog_config;
128 u32 prog_waitcount;
129 u32 flash_config;
130 u32 flash_waitcount;
131 u32 SECI_config; /* 0x130 SECI configuration */
132 u32 PAD[3];
133
134 /* Enhanced Coexistence Interface (ECI) registers (corerev >= 21) */
135 u32 eci_output; /* 0x140 */
136 u32 eci_control;
137 u32 eci_inputlo;
138 u32 eci_inputmi;
139 u32 eci_inputhi;
140 u32 eci_inputintpolaritylo;
141 u32 eci_inputintpolaritymi;
142 u32 eci_inputintpolarityhi;
143 u32 eci_intmasklo;
144 u32 eci_intmaskmi;
145 u32 eci_intmaskhi;
146 u32 eci_eventlo;
147 u32 eci_eventmi;
148 u32 eci_eventhi;
149 u32 eci_eventmasklo;
150 u32 eci_eventmaskmi;
151 u32 eci_eventmaskhi;
152 u32 PAD[3];
153
154 /* SROM interface (corerev >= 32) */
155 u32 sromcontrol; /* 0x190 */
156 u32 sromaddress;
157 u32 sromdata;
158 u32 PAD[17];
159
160 /* Clock control and hardware workarounds (corerev >= 20) */
161 u32 clk_ctl_st; /* 0x1e0 */
162 u32 hw_war;
163 u32 PAD[70];
164
165 /* UARTs */
166 u8 uart0data; /* 0x300 */
167 u8 uart0imr;
168 u8 uart0fcr;
169 u8 uart0lcr;
170 u8 uart0mcr;
171 u8 uart0lsr;
172 u8 uart0msr;
173 u8 uart0scratch;
174 u8 PAD[248]; /* corerev >= 1 */
175
176 u8 uart1data; /* 0x400 */
177 u8 uart1imr;
178 u8 uart1fcr;
179 u8 uart1lcr;
180 u8 uart1mcr;
181 u8 uart1lsr;
182 u8 uart1msr;
183 u8 uart1scratch;
184 u32 PAD[126];
185
186 /* PMU registers (corerev >= 20) */
187 u32 pmucontrol; /* 0x600 */
188 u32 pmucapabilities;
189 u32 pmustatus;
190 u32 res_state;
191 u32 res_pending;
192 u32 pmutimer;
193 u32 min_res_mask;
194 u32 max_res_mask;
195 u32 res_table_sel;
196 u32 res_dep_mask;
197 u32 res_updn_timer;
198 u32 res_timer;
199 u32 clkstretch;
200 u32 pmuwatchdog;
201 u32 gpiosel; /* 0x638, rev >= 1 */
202 u32 gpioenable; /* 0x63c, rev >= 1 */
203 u32 res_req_timer_sel;
204 u32 res_req_timer;
205 u32 res_req_mask;
206 u32 PAD;
207 u32 chipcontrol_addr; /* 0x650 */
208 u32 chipcontrol_data; /* 0x654 */
209 u32 regcontrol_addr;
210 u32 regcontrol_data;
211 u32 pllcontrol_addr;
212 u32 pllcontrol_data;
213 u32 pmustrapopt; /* 0x668, corerev >= 28 */
214 u32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */
215 u32 PAD[100];
216 u16 sromotp[768];
217};
218
219/* chipid */
220#define CID_ID_MASK 0x0000ffff /* Chip Id mask */
221#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */
222#define CID_REV_SHIFT 16 /* Chip Revision shift */
223#define CID_PKG_MASK 0x00f00000 /* Package Option mask */
224#define CID_PKG_SHIFT 20 /* Package Option shift */
225#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */
226#define CID_CC_SHIFT 24
227#define CID_TYPE_MASK 0xf0000000 /* Chip Type */
228#define CID_TYPE_SHIFT 28
229
230/* capabilities */
231#define CC_CAP_UARTS_MASK 0x00000003 /* Number of UARTs */
232#define CC_CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */
233#define CC_CAP_UCLKSEL 0x00000018 /* UARTs clock select */
234/* UARTs are driven by internal divided clock */
235#define CC_CAP_UINTCLK 0x00000008
236#define CC_CAP_UARTGPIO 0x00000020 /* UARTs own GPIOs 15:12 */
237#define CC_CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */
238#define CC_CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */
239#define CC_CAP_EXTBUS_FULL 0x00000040 /* ExtBus: PCMCIA, IDE & Prog */
240#define CC_CAP_EXTBUS_PROG 0x00000080 /* ExtBus: ProgIf only */
241#define CC_CAP_FLASH_MASK 0x00000700 /* Type of flash */
242#define CC_CAP_PLL_MASK 0x00038000 /* Type of PLL */
243#define CC_CAP_PWR_CTL 0x00040000 /* Power control */
244#define CC_CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */
245#define CC_CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */
246#define CC_CAP_OTPSIZE_BASE 5 /* OTP Size base */
247#define CC_CAP_JTAGP 0x00400000 /* JTAG Master Present */
248#define CC_CAP_ROM 0x00800000 /* Internal boot rom active */
249#define CC_CAP_BKPLN64 0x08000000 /* 64-bit backplane */
250#define CC_CAP_PMU 0x10000000 /* PMU Present, rev >= 20 */
251#define CC_CAP_SROM 0x40000000 /* Srom Present, rev >= 32 */
252/* Nand flash present, rev >= 35 */
253#define CC_CAP_NFLASH 0x80000000
254
255#define CC_CAP2_SECI 0x00000001 /* SECI Present, rev >= 36 */
256/* GSIO (spi/i2c) present, rev >= 37 */
257#define CC_CAP2_GSIO 0x00000002
258
259/* pmucapabilities */
260#define PCAP_REV_MASK 0x000000ff
261#define PCAP_RC_MASK 0x00001f00
262#define PCAP_RC_SHIFT 8
263#define PCAP_TC_MASK 0x0001e000
264#define PCAP_TC_SHIFT 13
265#define PCAP_PC_MASK 0x001e0000
266#define PCAP_PC_SHIFT 17
267#define PCAP_VC_MASK 0x01e00000
268#define PCAP_VC_SHIFT 21
269#define PCAP_CC_MASK 0x1e000000
270#define PCAP_CC_SHIFT 25
271#define PCAP5_PC_MASK 0x003e0000 /* PMU corerev >= 5 */
272#define PCAP5_PC_SHIFT 17
273#define PCAP5_VC_MASK 0x07c00000
274#define PCAP5_VC_SHIFT 22
275#define PCAP5_CC_MASK 0xf8000000
276#define PCAP5_CC_SHIFT 27
277
278/*
279* Maximum delay for the PMU state transition in us.
280* This is an upper bound intended for spinwaits etc.
281*/
282#define PMU_MAX_TRANSITION_DLY 15000
283
284#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 000000000000..1e5f310af1e7
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/include/defs.h
@@ -0,0 +1,104 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_DEFS_H_
18#define _BRCM_DEFS_H_
19
20#include <linux/types.h>
21
22#define SI_BUS 0
23#define PCI_BUS 1
24#define PCMCIA_BUS 2
25#define SDIO_BUS 3
26#define JTAG_BUS 4
27#define USB_BUS 5
28#define SPI_BUS 6
29
30#define OFF 0
31#define ON 1 /* ON = 1 */
32#define AUTO (-1) /* Auto = -1 */
33
34/*
35 * Priority definitions according 802.1D
36 */
37#define PRIO_8021D_NONE 2
38#define PRIO_8021D_BK 1
39#define PRIO_8021D_BE 0
40#define PRIO_8021D_EE 3
41#define PRIO_8021D_CL 4
42#define PRIO_8021D_VI 5
43#define PRIO_8021D_VO 6
44#define PRIO_8021D_NC 7
45
46#define MAXPRIO 7
47#define NUMPRIO (MAXPRIO + 1)
48
49#define WL_NUMRATES 16 /* max # of rates in a rateset */
50
51#define BRCM_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NUL */
52
53#define BRCM_SET_CHANNEL 30
54#define BRCM_SET_SRL 32
55#define BRCM_SET_LRL 34
56#define BRCM_SET_BCNPRD 76
57
58#define BRCM_GET_CURR_RATESET 114 /* current rateset */
59#define BRCM_GET_PHYLIST 180
60
61/* Bit masks for radio disabled status - returned by WL_GET_RADIO */
62
63#define WL_RADIO_SW_DISABLE (1<<0)
64#define WL_RADIO_HW_DISABLE (1<<1)
65#define WL_RADIO_MPC_DISABLE (1<<2)
66/* some countries don't support any channel */
67#define WL_RADIO_COUNTRY_DISABLE (1<<3)
68
69/* Override bit for SET_TXPWR. if set, ignore other level limits */
70#define WL_TXPWR_OVERRIDE (1U<<31)
71
72/* band types */
73#define BRCM_BAND_AUTO 0 /* auto-select */
74#define BRCM_BAND_5G 1 /* 5 Ghz */
75#define BRCM_BAND_2G 2 /* 2.4 Ghz */
76#define BRCM_BAND_ALL 3 /* all bands */
77
78/* Values for PM */
79#define PM_OFF 0
80#define PM_MAX 1
81
82/* Message levels */
83#define LOG_ERROR_VAL 0x00000001
84#define LOG_TRACE_VAL 0x00000002
85
86#define PM_OFF 0
87#define PM_MAX 1
88#define PM_FAST 2
89
90/*
91 * Sonics Configuration Space Registers.
92 */
93
94/* core sbconfig regs are top 256bytes of regs */
95#define SBCONFIGOFF 0xf00
96
97/* cpp contortions to concatenate w/arg prescan */
98#ifndef PAD
99#define _PADLINE(line) pad ## line
100#define _XSTR(line) _PADLINE(line)
101#define PAD _XSTR(__LINE__)
102#endif
103
104#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 000000000000..4fcb956ad9e0
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/include/soc.h
@@ -0,0 +1,90 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_SOC_H
18#define _BRCM_SOC_H
19
20#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */
21
22/* core codes */
23#define NODEV_CORE_ID 0x700 /* Invalid coreid */
24#define CC_CORE_ID 0x800 /* chipcommon core */
25#define ILINE20_CORE_ID 0x801 /* iline20 core */
26#define SRAM_CORE_ID 0x802 /* sram core */
27#define SDRAM_CORE_ID 0x803 /* sdram core */
28#define PCI_CORE_ID 0x804 /* pci core */
29#define MIPS_CORE_ID 0x805 /* mips core */
30#define ENET_CORE_ID 0x806 /* enet mac core */
31#define CODEC_CORE_ID 0x807 /* v90 codec core */
32#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */
33#define ADSL_CORE_ID 0x809 /* ADSL core */
34#define ILINE100_CORE_ID 0x80a /* iline100 core */
35#define IPSEC_CORE_ID 0x80b /* ipsec core */
36#define UTOPIA_CORE_ID 0x80c /* utopia core */
37#define PCMCIA_CORE_ID 0x80d /* pcmcia core */
38#define SOCRAM_CORE_ID 0x80e /* internal memory core */
39#define MEMC_CORE_ID 0x80f /* memc sdram core */
40#define OFDM_CORE_ID 0x810 /* OFDM phy core */
41#define EXTIF_CORE_ID 0x811 /* external interface core */
42#define D11_CORE_ID 0x812 /* 802.11 MAC core */
43#define APHY_CORE_ID 0x813 /* 802.11a phy core */
44#define BPHY_CORE_ID 0x814 /* 802.11b phy core */
45#define GPHY_CORE_ID 0x815 /* 802.11g phy core */
46#define MIPS33_CORE_ID 0x816 /* mips3302 core */
47#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */
48#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */
49#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */
50#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */
51#define SDIOH_CORE_ID 0x81b /* sdio host core */
52#define ROBO_CORE_ID 0x81c /* roboswitch core */
53#define ATA100_CORE_ID 0x81d /* parallel ATA core */
54#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */
55#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */
56#define PCIE_CORE_ID 0x820 /* pci express core */
57#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */
58#define SRAMC_CORE_ID 0x822 /* SRAM controller core */
59#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */
60#define ARM11_CORE_ID 0x824 /* ARM 1176 core */
61#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */
62#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */
63#define PMU_CORE_ID 0x827 /* PMU core */
64#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */
65#define SDIOD_CORE_ID 0x829 /* SDIO device core */
66#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */
67#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */
68#define MIPS74K_CORE_ID 0x82c /* mips 74k core */
69#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */
70#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */
71#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */
72#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */
73#define SC_CORE_ID 0x831 /* shared common core */
74#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */
75#define SPIH_CORE_ID 0x833 /* SPI host core */
76#define I2S_CORE_ID 0x834 /* I2S core */
77#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */
78#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */
79#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */
80/* Default component, in ai chips it maps all unused address ranges */
81#define DEF_AI_COMP 0xfff
82
83/* Common core control flags */
84#define SICF_BIST_EN 0x8000
85#define SICF_PME_EN 0x4000
86#define SICF_CORE_BITS 0x3ffc
87#define SICF_FGC 0x0002
88#define SICF_CLOCK_EN 0x0001
89
90#endif /* _BRCM_SOC_H */
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index e0441033788c..57703d5209d7 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -54,13 +54,13 @@ config IWLWIFI_DEBUG
54 control which debug output is sent to the kernel log by setting the 54 control which debug output is sent to the kernel log by setting the
55 value in 55 value in
56 56
57 /sys/class/net/wlan0/device/debug_level 57 /sys/module/iwlwifi/parameters/debug
58 58
59 This entry will only exist if this option is enabled. 59 This entry will only exist if this option is enabled.
60 60
61 To set a value, simply echo an 8-byte hex value to the same file: 61 To set a value, simply echo an 8-byte hex value to the same file:
62 62
63 % echo 0x43fff > /sys/class/net/wlan0/device/debug_level 63 % echo 0x43fff > /sys/module/iwlwifi/parameters/debug
64 64
65 You can find the list of debug mask values in: 65 You can find the list of debug mask values in:
66 drivers/net/wireless/iwlwifi/iwl-debug.h 66 drivers/net/wireless/iwlwifi/iwl-debug.h
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index bacafa4a5f48..c73e5ed8db5e 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -3,10 +3,9 @@ obj-$(CONFIG_IWLWIFI) += iwlwifi.o
3iwlwifi-objs := iwl-agn.o iwl-agn-rs.o 3iwlwifi-objs := iwl-agn.o iwl-agn-rs.o
4iwlwifi-objs += iwl-agn-ucode.o iwl-agn-tx.o 4iwlwifi-objs += iwl-agn-ucode.o iwl-agn-tx.o
5iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o 5iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o
6iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o 6iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o
7 7
8iwlwifi-objs += iwl-core.o iwl-eeprom.o iwl-power.o 8iwlwifi-objs += iwl-core.o iwl-eeprom.o iwl-power.o
9iwlwifi-objs += iwl-rx.o iwl-sta.o
10iwlwifi-objs += iwl-scan.o iwl-led.o 9iwlwifi-objs += iwl-scan.o iwl-led.o
11iwlwifi-objs += iwl-agn-rxon.o 10iwlwifi-objs += iwl-agn-rxon.o
12iwlwifi-objs += iwl-5000.o 11iwlwifi-objs += iwl-5000.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 887f9ac434c2..e12b48c2cff6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -39,9 +39,7 @@
39#include "iwl-dev.h" 39#include "iwl-dev.h"
40#include "iwl-core.h" 40#include "iwl-core.h"
41#include "iwl-io.h" 41#include "iwl-io.h"
42#include "iwl-sta.h"
43#include "iwl-agn.h" 42#include "iwl-agn.h"
44#include "iwl-helpers.h"
45#include "iwl-agn-hw.h" 43#include "iwl-agn-hw.h"
46#include "iwl-shared.h" 44#include "iwl-shared.h"
47#include "iwl-cfg.h" 45#include "iwl-cfg.h"
@@ -130,7 +128,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
130 iwlagn_mod_params.num_of_queues; 128 iwlagn_mod_params.num_of_queues;
131 129
132 hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues; 130 hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues;
133 hw_params(priv).max_stations = IWLAGN_STATION_COUNT;
134 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; 131 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
135 132
136 hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; 133 hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index db889581c0e5..79431977a968 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -39,11 +39,8 @@
39#include "iwl-dev.h" 39#include "iwl-dev.h"
40#include "iwl-core.h" 40#include "iwl-core.h"
41#include "iwl-io.h" 41#include "iwl-io.h"
42#include "iwl-sta.h"
43#include "iwl-agn.h" 42#include "iwl-agn.h"
44#include "iwl-helpers.h"
45#include "iwl-agn-hw.h" 43#include "iwl-agn-hw.h"
46#include "iwl-6000-hw.h"
47#include "iwl-shared.h" 44#include "iwl-shared.h"
48#include "iwl-cfg.h" 45#include "iwl-cfg.h"
49 46
@@ -127,7 +124,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
127 iwlagn_mod_params.num_of_queues; 124 iwlagn_mod_params.num_of_queues;
128 125
129 hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues; 126 hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues;
130 hw_params(priv).max_stations = IWLAGN_STATION_COUNT;
131 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; 127 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
132 128
133 hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; 129 hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE;
@@ -341,6 +337,12 @@ struct iwl_cfg iwl105_bgn_cfg = {
341 .ht_params = &iwl2000_ht_params, 337 .ht_params = &iwl2000_ht_params,
342}; 338};
343 339
340struct iwl_cfg iwl105_bgn_d_cfg = {
341 .name = "105D Series 1x1 BGN",
342 IWL_DEVICE_105,
343 .ht_params = &iwl2000_ht_params,
344};
345
344#define IWL_DEVICE_135 \ 346#define IWL_DEVICE_135 \
345 .fw_name_pre = IWL135_FW_PRE, \ 347 .fw_name_pre = IWL135_FW_PRE, \
346 .ucode_api_max = IWL135_UCODE_API_MAX, \ 348 .ucode_api_max = IWL135_UCODE_API_MAX, \
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
deleted file mode 100644
index c0135988e777..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ /dev/null
@@ -1,88 +0,0 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63/*
64 * Please use this file (iwl-5000-hw.h) only for hardware-related definitions.
65 * Use iwl-commands.h for uCode API definitions.
66 */
67
68#ifndef __iwl_5000_hw_h__
69#define __iwl_5000_hw_h__
70
71/* 5150 only */
72#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5)
73
74static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
75{
76 u16 temperature, voltage;
77 __le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(priv,
78 EEPROM_KELVIN_TEMPERATURE);
79
80 temperature = le16_to_cpu(temp_calib[0]);
81 voltage = le16_to_cpu(temp_calib[1]);
82
83 /* offset = temp - volt / coeff */
84 return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
85}
86
87#endif /* __iwl_5000_hw_h__ */
88
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 290701620f03..c511c98a89a8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -40,11 +40,8 @@
40#include "iwl-dev.h" 40#include "iwl-dev.h"
41#include "iwl-core.h" 41#include "iwl-core.h"
42#include "iwl-io.h" 42#include "iwl-io.h"
43#include "iwl-sta.h"
44#include "iwl-helpers.h"
45#include "iwl-agn.h" 43#include "iwl-agn.h"
46#include "iwl-agn-hw.h" 44#include "iwl-agn-hw.h"
47#include "iwl-5000-hw.h"
48#include "iwl-trans.h" 45#include "iwl-trans.h"
49#include "iwl-shared.h" 46#include "iwl-shared.h"
50#include "iwl-cfg.h" 47#include "iwl-cfg.h"
@@ -135,6 +132,21 @@ static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
135 .nrg_th_cca = 62, 132 .nrg_th_cca = 62,
136}; 133};
137 134
135#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5)
136
137static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
138{
139 u16 temperature, voltage;
140 __le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(priv,
141 EEPROM_KELVIN_TEMPERATURE);
142
143 temperature = le16_to_cpu(temp_calib[0]);
144 voltage = le16_to_cpu(temp_calib[1]);
145
146 /* offset = temp - volt / coeff */
147 return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
148}
149
138static void iwl5150_set_ct_threshold(struct iwl_priv *priv) 150static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
139{ 151{
140 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF; 152 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
@@ -158,7 +170,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
158 iwlagn_mod_params.num_of_queues; 170 iwlagn_mod_params.num_of_queues;
159 171
160 hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues; 172 hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues;
161 hw_params(priv).max_stations = IWLAGN_STATION_COUNT;
162 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; 173 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
163 174
164 hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; 175 hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
@@ -195,7 +206,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
195 iwlagn_mod_params.num_of_queues; 206 iwlagn_mod_params.num_of_queues;
196 207
197 hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues; 208 hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues;
198 hw_params(priv).max_stations = IWLAGN_STATION_COUNT;
199 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; 209 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
200 210
201 hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; 211 hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
@@ -241,7 +251,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
241{ 251{
242 /* 252 /*
243 * MULTI-FIXME 253 * MULTI-FIXME
244 * See iwl_mac_channel_switch. 254 * See iwlagn_mac_channel_switch.
245 */ 255 */
246 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 256 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
247 struct iwl5000_channel_switch_cmd cmd; 257 struct iwl5000_channel_switch_cmd cmd;
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
deleted file mode 100644
index b27986e57c92..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
+++ /dev/null
@@ -1,81 +0,0 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63/*
64 * Please use this file (iwl-6000-hw.h) only for hardware-related definitions.
65 * Use iwl-commands.h for uCode API definitions.
66 */
67
68#ifndef __iwl_6000_hw_h__
69#define __iwl_6000_hw_h__
70
71#define IWL60_RTC_INST_LOWER_BOUND (0x000000)
72#define IWL60_RTC_INST_UPPER_BOUND (0x040000)
73#define IWL60_RTC_DATA_LOWER_BOUND (0x800000)
74#define IWL60_RTC_DATA_UPPER_BOUND (0x814000)
75#define IWL60_RTC_INST_SIZE \
76 (IWL60_RTC_INST_UPPER_BOUND - IWL60_RTC_INST_LOWER_BOUND)
77#define IWL60_RTC_DATA_SIZE \
78 (IWL60_RTC_DATA_UPPER_BOUND - IWL60_RTC_DATA_LOWER_BOUND)
79
80#endif /* __iwl_6000_hw_h__ */
81
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 37837f7b6990..c840c78278db 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -39,11 +39,8 @@
39#include "iwl-dev.h" 39#include "iwl-dev.h"
40#include "iwl-core.h" 40#include "iwl-core.h"
41#include "iwl-io.h" 41#include "iwl-io.h"
42#include "iwl-sta.h"
43#include "iwl-agn.h" 42#include "iwl-agn.h"
44#include "iwl-helpers.h"
45#include "iwl-agn-hw.h" 43#include "iwl-agn-hw.h"
46#include "iwl-6000-hw.h"
47#include "iwl-trans.h" 44#include "iwl-trans.h"
48#include "iwl-shared.h" 45#include "iwl-shared.h"
49#include "iwl-cfg.h" 46#include "iwl-cfg.h"
@@ -147,7 +144,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
147 iwlagn_mod_params.num_of_queues; 144 iwlagn_mod_params.num_of_queues;
148 145
149 hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues; 146 hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues;
150 hw_params(priv).max_stations = IWLAGN_STATION_COUNT;
151 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; 147 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
152 148
153 hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; 149 hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE;
@@ -188,7 +184,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
188{ 184{
189 /* 185 /*
190 * MULTI-FIXME 186 * MULTI-FIXME
191 * See iwl_mac_channel_switch. 187 * See iwlagn_mac_channel_switch.
192 */ 188 */
193 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 189 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
194 struct iwl6000_channel_switch_cmd cmd; 190 struct iwl6000_channel_switch_cmd cmd;
@@ -394,6 +390,12 @@ struct iwl_cfg iwl6005_2agn_sff_cfg = {
394 .ht_params = &iwl6000_ht_params, 390 .ht_params = &iwl6000_ht_params,
395}; 391};
396 392
393struct iwl_cfg iwl6005_2agn_d_cfg = {
394 .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN",
395 IWL_DEVICE_6005,
396 .ht_params = &iwl6000_ht_params,
397};
398
397#define IWL_DEVICE_6030 \ 399#define IWL_DEVICE_6030 \
398 .fw_name_pre = IWL6030_FW_PRE, \ 400 .fw_name_pre = IWL6030_FW_PRE, \
399 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ 401 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
index 33951a11327d..123ef5e129d5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
@@ -78,10 +78,23 @@
78#define IWLAGN_RTC_DATA_SIZE (IWLAGN_RTC_DATA_UPPER_BOUND - \ 78#define IWLAGN_RTC_DATA_SIZE (IWLAGN_RTC_DATA_UPPER_BOUND - \
79 IWLAGN_RTC_DATA_LOWER_BOUND) 79 IWLAGN_RTC_DATA_LOWER_BOUND)
80 80
81#define IWL60_RTC_INST_LOWER_BOUND (0x000000)
82#define IWL60_RTC_INST_UPPER_BOUND (0x040000)
83#define IWL60_RTC_DATA_LOWER_BOUND (0x800000)
84#define IWL60_RTC_DATA_UPPER_BOUND (0x814000)
85#define IWL60_RTC_INST_SIZE \
86 (IWL60_RTC_INST_UPPER_BOUND - IWL60_RTC_INST_LOWER_BOUND)
87#define IWL60_RTC_DATA_SIZE \
88 (IWL60_RTC_DATA_UPPER_BOUND - IWL60_RTC_DATA_LOWER_BOUND)
89
81/* RSSI to dBm */ 90/* RSSI to dBm */
82#define IWLAGN_RSSI_OFFSET 44 91#define IWLAGN_RSSI_OFFSET 44
83 92
84#define IWLAGN_DEFAULT_TX_RETRY 15 93#define IWLAGN_DEFAULT_TX_RETRY 15
94#define IWLAGN_MGMT_DFAULT_RETRY_LIMIT 3
95#define IWLAGN_RTS_DFAULT_RETRY_LIMIT 60
96#define IWLAGN_BAR_DFAULT_RETRY_LIMIT 60
97#define IWLAGN_LOW_RETRY_LIMIT 7
85 98
86/* Limit range of txpower output target to be between these values */ 99/* Limit range of txpower output target to be between these values */
87#define IWLAGN_TX_POWER_TARGET_POWER_MIN (0) /* 0 dBm: 1 milliwatt */ 100#define IWLAGN_TX_POWER_TARGET_POWER_MIN (0) /* 0 dBm: 1 milliwatt */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index d30714be515b..1a52ed29f2d6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -35,10 +35,8 @@
35#include "iwl-dev.h" 35#include "iwl-dev.h"
36#include "iwl-core.h" 36#include "iwl-core.h"
37#include "iwl-io.h" 37#include "iwl-io.h"
38#include "iwl-helpers.h"
39#include "iwl-agn-hw.h" 38#include "iwl-agn-hw.h"
40#include "iwl-agn.h" 39#include "iwl-agn.h"
41#include "iwl-sta.h"
42#include "iwl-trans.h" 40#include "iwl-trans.h"
43#include "iwl-shared.h" 41#include "iwl-shared.h"
44 42
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 7d6a3bf64950..66118cea2af3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -36,7 +36,6 @@
36#include <linux/workqueue.h> 36#include <linux/workqueue.h>
37 37
38#include "iwl-dev.h" 38#include "iwl-dev.h"
39#include "iwl-sta.h"
40#include "iwl-core.h" 39#include "iwl-core.h"
41#include "iwl-agn.h" 40#include "iwl-agn.h"
42 41
@@ -2666,8 +2665,7 @@ lq_update:
2666 2665
2667out: 2666out:
2668 tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); 2667 tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
2669 i = index; 2668 lq_sta->last_txrate_idx = index;
2670 lq_sta->last_txrate_idx = i;
2671} 2669}
2672 2670
2673/** 2671/**
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index bdae82e7fa90..f4f6deb829ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -27,6 +27,10 @@
27#ifndef __iwl_agn_rs_h__ 27#ifndef __iwl_agn_rs_h__
28#define __iwl_agn_rs_h__ 28#define __iwl_agn_rs_h__
29 29
30#include <net/mac80211.h>
31
32#include "iwl-commands.h"
33
30struct iwl_rate_info { 34struct iwl_rate_info {
31 u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ 35 u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
32 u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ 36 u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index bcd7f64683aa..5af9e6258a16 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -3,7 +3,7 @@
3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portionhelp of the ieee80211 subsystem header files.
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as 9 * under the terms of version 2 of the GNU General Public License as
@@ -35,9 +35,7 @@
35#include "iwl-eeprom.h" 35#include "iwl-eeprom.h"
36#include "iwl-dev.h" 36#include "iwl-dev.h"
37#include "iwl-core.h" 37#include "iwl-core.h"
38#include "iwl-sta.h"
39#include "iwl-io.h" 38#include "iwl-io.h"
40#include "iwl-helpers.h"
41#include "iwl-agn-calib.h" 39#include "iwl-agn-calib.h"
42#include "iwl-agn.h" 40#include "iwl-agn.h"
43#include "iwl-shared.h" 41#include "iwl-shared.h"
@@ -47,6 +45,7 @@ const char *get_cmd_string(u8 cmd)
47 switch (cmd) { 45 switch (cmd) {
48 IWL_CMD(REPLY_ALIVE); 46 IWL_CMD(REPLY_ALIVE);
49 IWL_CMD(REPLY_ERROR); 47 IWL_CMD(REPLY_ERROR);
48 IWL_CMD(REPLY_ECHO);
50 IWL_CMD(REPLY_RXON); 49 IWL_CMD(REPLY_RXON);
51 IWL_CMD(REPLY_RXON_ASSOC); 50 IWL_CMD(REPLY_RXON_ASSOC);
52 IWL_CMD(REPLY_QOS_PARAM); 51 IWL_CMD(REPLY_QOS_PARAM);
@@ -130,7 +129,7 @@ const char *get_cmd_string(u8 cmd)
130 * 129 *
131 ******************************************************************************/ 130 ******************************************************************************/
132 131
133static int iwl_rx_reply_error(struct iwl_priv *priv, 132static int iwlagn_rx_reply_error(struct iwl_priv *priv,
134 struct iwl_rx_mem_buffer *rxb, 133 struct iwl_rx_mem_buffer *rxb,
135 struct iwl_device_cmd *cmd) 134 struct iwl_device_cmd *cmd)
136{ 135{
@@ -146,14 +145,14 @@ static int iwl_rx_reply_error(struct iwl_priv *priv,
146 return 0; 145 return 0;
147} 146}
148 147
149static int iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, 148static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
150 struct iwl_device_cmd *cmd) 149 struct iwl_device_cmd *cmd)
151{ 150{
152 struct iwl_rx_packet *pkt = rxb_addr(rxb); 151 struct iwl_rx_packet *pkt = rxb_addr(rxb);
153 struct iwl_csa_notification *csa = &(pkt->u.csa_notif); 152 struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
154 /* 153 /*
155 * MULTI-FIXME 154 * MULTI-FIXME
156 * See iwl_mac_channel_switch. 155 * See iwlagn_mac_channel_switch.
157 */ 156 */
158 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 157 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
159 struct iwl_rxon_cmd *rxon = (void *)&ctx->active; 158 struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
@@ -176,7 +175,7 @@ static int iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
176} 175}
177 176
178 177
179static int iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, 178static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv,
180 struct iwl_rx_mem_buffer *rxb, 179 struct iwl_rx_mem_buffer *rxb,
181 struct iwl_device_cmd *cmd) 180 struct iwl_device_cmd *cmd)
182{ 181{
@@ -194,7 +193,7 @@ static int iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
194 return 0; 193 return 0;
195} 194}
196 195
197static int iwl_rx_pm_sleep_notif(struct iwl_priv *priv, 196static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv,
198 struct iwl_rx_mem_buffer *rxb, 197 struct iwl_rx_mem_buffer *rxb,
199 struct iwl_device_cmd *cmd) 198 struct iwl_device_cmd *cmd)
200{ 199{
@@ -207,7 +206,7 @@ static int iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
207 return 0; 206 return 0;
208} 207}
209 208
210static int iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, 209static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
211 struct iwl_rx_mem_buffer *rxb, 210 struct iwl_rx_mem_buffer *rxb,
212 struct iwl_device_cmd *cmd) 211 struct iwl_device_cmd *cmd)
213{ 212{
@@ -221,7 +220,7 @@ static int iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
221 return 0; 220 return 0;
222} 221}
223 222
224static int iwl_rx_beacon_notif(struct iwl_priv *priv, 223static int iwlagn_rx_beacon_notif(struct iwl_priv *priv,
225 struct iwl_rx_mem_buffer *rxb, 224 struct iwl_rx_mem_buffer *rxb,
226 struct iwl_device_cmd *cmd) 225 struct iwl_device_cmd *cmd)
227{ 226{
@@ -242,8 +241,6 @@ static int iwl_rx_beacon_notif(struct iwl_priv *priv,
242 241
243 priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); 242 priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
244 243
245 if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
246 queue_work(priv->shrd->workqueue, &priv->beacon_update);
247 return 0; 244 return 0;
248} 245}
249 246
@@ -259,7 +256,7 @@ static int iwl_rx_beacon_notif(struct iwl_priv *priv,
259 * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal 256 * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
260 * operation state. 257 * operation state.
261 */ 258 */
262static bool iwl_good_ack_health(struct iwl_priv *priv, 259static bool iwlagn_good_ack_health(struct iwl_priv *priv,
263 struct statistics_tx *cur) 260 struct statistics_tx *cur)
264{ 261{
265 int actual_delta, expected_delta, ba_timeout_delta; 262 int actual_delta, expected_delta, ba_timeout_delta;
@@ -284,8 +281,9 @@ static bool iwl_good_ack_health(struct iwl_priv *priv,
284 281
285 if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO && 282 if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO &&
286 ba_timeout_delta > BA_TIMEOUT_CNT) { 283 ba_timeout_delta > BA_TIMEOUT_CNT) {
287 IWL_DEBUG_RADIO(priv, "deltas: actual %d expected %d ba_timeout %d\n", 284 IWL_DEBUG_RADIO(priv,
288 actual_delta, expected_delta, ba_timeout_delta); 285 "deltas: actual %d expected %d ba_timeout %d\n",
286 actual_delta, expected_delta, ba_timeout_delta);
289 287
290#ifdef CONFIG_IWLWIFI_DEBUGFS 288#ifdef CONFIG_IWLWIFI_DEBUGFS
291 /* 289 /*
@@ -313,7 +311,7 @@ static bool iwl_good_ack_health(struct iwl_priv *priv,
313 * When the plcp error is exceeding the thresholds, reset the radio 311 * When the plcp error is exceeding the thresholds, reset the radio
314 * to improve the throughput. 312 * to improve the throughput.
315 */ 313 */
316static bool iwl_good_plcp_health(struct iwl_priv *priv, 314static bool iwlagn_good_plcp_health(struct iwl_priv *priv,
317 struct statistics_rx_phy *cur_ofdm, 315 struct statistics_rx_phy *cur_ofdm,
318 struct statistics_rx_ht_phy *cur_ofdm_ht, 316 struct statistics_rx_ht_phy *cur_ofdm_ht,
319 unsigned int msecs) 317 unsigned int msecs)
@@ -345,11 +343,11 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv,
345 return true; 343 return true;
346} 344}
347 345
348static void iwl_recover_from_statistics(struct iwl_priv *priv, 346static void iwlagn_recover_from_statistics(struct iwl_priv *priv,
349 struct statistics_rx_phy *cur_ofdm, 347 struct statistics_rx_phy *cur_ofdm,
350 struct statistics_rx_ht_phy *cur_ofdm_ht, 348 struct statistics_rx_ht_phy *cur_ofdm_ht,
351 struct statistics_tx *tx, 349 struct statistics_tx *tx,
352 unsigned long stamp) 350 unsigned long stamp)
353{ 351{
354 unsigned int msecs; 352 unsigned int msecs;
355 353
@@ -366,21 +364,21 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv,
366 if (msecs < 99) 364 if (msecs < 99)
367 return; 365 return;
368 366
369 if (iwlagn_mod_params.ack_check && !iwl_good_ack_health(priv, tx)) { 367 if (iwlagn_mod_params.ack_check && !iwlagn_good_ack_health(priv, tx)) {
370 IWL_ERR(priv, "low ack count detected, restart firmware\n"); 368 IWL_ERR(priv, "low ack count detected, restart firmware\n");
371 if (!iwl_force_reset(priv, IWL_FW_RESET, false)) 369 if (!iwl_force_reset(priv, IWL_FW_RESET, false))
372 return; 370 return;
373 } 371 }
374 372
375 if (iwlagn_mod_params.plcp_check && 373 if (iwlagn_mod_params.plcp_check &&
376 !iwl_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) 374 !iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
377 iwl_force_reset(priv, IWL_RF_RESET, false); 375 iwl_force_reset(priv, IWL_RF_RESET, false);
378} 376}
379 377
380/* Calculate noise level, based on measurements during network silence just 378/* Calculate noise level, based on measurements during network silence just
381 * before arriving beacon. This measurement can be done only if we know 379 * before arriving beacon. This measurement can be done only if we know
382 * exactly when to expect beacons, therefore only when we're associated. */ 380 * exactly when to expect beacons, therefore only when we're associated. */
383static void iwl_rx_calc_noise(struct iwl_priv *priv) 381static void iwlagn_rx_calc_noise(struct iwl_priv *priv)
384{ 382{
385 struct statistics_rx_non_phy *rx_info; 383 struct statistics_rx_non_phy *rx_info;
386 int num_active_rx = 0; 384 int num_active_rx = 0;
@@ -446,7 +444,7 @@ static void accum_stats(__le32 *prev, __le32 *cur, __le32 *delta,
446} 444}
447 445
448static void 446static void
449iwl_accumulative_statistics(struct iwl_priv *priv, 447iwlagn_accumulative_statistics(struct iwl_priv *priv,
450 struct statistics_general_common *common, 448 struct statistics_general_common *common,
451 struct statistics_rx_non_phy *rx_non_phy, 449 struct statistics_rx_non_phy *rx_non_phy,
452 struct statistics_rx_phy *rx_ofdm, 450 struct statistics_rx_phy *rx_ofdm,
@@ -475,7 +473,7 @@ iwl_accumulative_statistics(struct iwl_priv *priv,
475} 473}
476#else 474#else
477static inline void 475static inline void
478iwl_accumulative_statistics(struct iwl_priv *priv, 476iwlagn_accumulative_statistics(struct iwl_priv *priv,
479 struct statistics_general_common *common, 477 struct statistics_general_common *common,
480 struct statistics_rx_non_phy *rx_non_phy, 478 struct statistics_rx_non_phy *rx_non_phy,
481 struct statistics_rx_phy *rx_ofdm, 479 struct statistics_rx_phy *rx_ofdm,
@@ -487,7 +485,7 @@ iwl_accumulative_statistics(struct iwl_priv *priv,
487} 485}
488#endif 486#endif
489 487
490static int iwl_rx_statistics(struct iwl_priv *priv, 488static int iwlagn_rx_statistics(struct iwl_priv *priv,
491 struct iwl_rx_mem_buffer *rxb, 489 struct iwl_rx_mem_buffer *rxb,
492 struct iwl_device_cmd *cmd) 490 struct iwl_device_cmd *cmd)
493{ 491{
@@ -550,10 +548,10 @@ static int iwl_rx_statistics(struct iwl_priv *priv,
550 (*flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK) != 548 (*flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
551 (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK); 549 (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK);
552 550
553 iwl_accumulative_statistics(priv, common, rx_non_phy, rx_ofdm, 551 iwlagn_accumulative_statistics(priv, common, rx_non_phy, rx_ofdm,
554 rx_ofdm_ht, rx_cck, tx, bt_activity); 552 rx_ofdm_ht, rx_cck, tx, bt_activity);
555 553
556 iwl_recover_from_statistics(priv, rx_ofdm, rx_ofdm_ht, tx, stamp); 554 iwlagn_recover_from_statistics(priv, rx_ofdm, rx_ofdm_ht, tx, stamp);
557 555
558 priv->statistics.flag = *flag; 556 priv->statistics.flag = *flag;
559 memcpy(&priv->statistics.common, common, sizeof(*common)); 557 memcpy(&priv->statistics.common, common, sizeof(*common));
@@ -581,7 +579,7 @@ static int iwl_rx_statistics(struct iwl_priv *priv,
581 579
582 if (unlikely(!test_bit(STATUS_SCANNING, &priv->shrd->status)) && 580 if (unlikely(!test_bit(STATUS_SCANNING, &priv->shrd->status)) &&
583 (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { 581 (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
584 iwl_rx_calc_noise(priv); 582 iwlagn_rx_calc_noise(priv);
585 queue_work(priv->shrd->workqueue, &priv->run_time_calib_work); 583 queue_work(priv->shrd->workqueue, &priv->run_time_calib_work);
586 } 584 }
587 if (priv->cfg->lib->temperature && change) 585 if (priv->cfg->lib->temperature && change)
@@ -589,7 +587,7 @@ static int iwl_rx_statistics(struct iwl_priv *priv,
589 return 0; 587 return 0;
590} 588}
591 589
592static int iwl_rx_reply_statistics(struct iwl_priv *priv, 590static int iwlagn_rx_reply_statistics(struct iwl_priv *priv,
593 struct iwl_rx_mem_buffer *rxb, 591 struct iwl_rx_mem_buffer *rxb,
594 struct iwl_device_cmd *cmd) 592 struct iwl_device_cmd *cmd)
595{ 593{
@@ -606,13 +604,13 @@ static int iwl_rx_reply_statistics(struct iwl_priv *priv,
606#endif 604#endif
607 IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); 605 IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
608 } 606 }
609 iwl_rx_statistics(priv, rxb, cmd); 607 iwlagn_rx_statistics(priv, rxb, cmd);
610 return 0; 608 return 0;
611} 609}
612 610
613/* Handle notification from uCode that card's power state is changing 611/* Handle notification from uCode that card's power state is changing
614 * due to software, hardware, or critical temperature RFKILL */ 612 * due to software, hardware, or critical temperature RFKILL */
615static int iwl_rx_card_state_notif(struct iwl_priv *priv, 613static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
616 struct iwl_rx_mem_buffer *rxb, 614 struct iwl_rx_mem_buffer *rxb,
617 struct iwl_device_cmd *cmd) 615 struct iwl_device_cmd *cmd)
618{ 616{
@@ -665,7 +663,7 @@ static int iwl_rx_card_state_notif(struct iwl_priv *priv,
665 return 0; 663 return 0;
666} 664}
667 665
668static int iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 666static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv,
669 struct iwl_rx_mem_buffer *rxb, 667 struct iwl_rx_mem_buffer *rxb,
670 struct iwl_device_cmd *cmd) 668 struct iwl_device_cmd *cmd)
671 669
@@ -690,7 +688,7 @@ static int iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
690 688
691/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). 689/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
692 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ 690 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
693static int iwl_rx_reply_rx_phy(struct iwl_priv *priv, 691static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
694 struct iwl_rx_mem_buffer *rxb, 692 struct iwl_rx_mem_buffer *rxb,
695 struct iwl_device_cmd *cmd) 693 struct iwl_device_cmd *cmd)
696{ 694{
@@ -705,7 +703,7 @@ static int iwl_rx_reply_rx_phy(struct iwl_priv *priv,
705/* 703/*
706 * returns non-zero if packet should be dropped 704 * returns non-zero if packet should be dropped
707 */ 705 */
708static int iwl_set_decrypted_flag(struct iwl_priv *priv, 706static int iwlagn_set_decrypted_flag(struct iwl_priv *priv,
709 struct ieee80211_hdr *hdr, 707 struct ieee80211_hdr *hdr,
710 u32 decrypt_res, 708 u32 decrypt_res,
711 struct ieee80211_rx_status *stats) 709 struct ieee80211_rx_status *stats)
@@ -754,7 +752,7 @@ static int iwl_set_decrypted_flag(struct iwl_priv *priv,
754 return 0; 752 return 0;
755} 753}
756 754
757static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, 755static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
758 struct ieee80211_hdr *hdr, 756 struct ieee80211_hdr *hdr,
759 u16 len, 757 u16 len,
760 u32 ampdu_status, 758 u32 ampdu_status,
@@ -774,7 +772,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
774 772
775 /* In case of HW accelerated crypto and bad decryption, drop */ 773 /* In case of HW accelerated crypto and bad decryption, drop */
776 if (!iwlagn_mod_params.sw_crypto && 774 if (!iwlagn_mod_params.sw_crypto &&
777 iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) 775 iwlagn_set_decrypted_flag(priv, hdr, ampdu_status, stats))
778 return; 776 return;
779 777
780 skb = dev_alloc_skb(128); 778 skb = dev_alloc_skb(128);
@@ -812,7 +810,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
812 rxb->page = NULL; 810 rxb->page = NULL;
813} 811}
814 812
815static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) 813static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
816{ 814{
817 u32 decrypt_out = 0; 815 u32 decrypt_out = 0;
818 816
@@ -914,7 +912,7 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv,
914 912
915/* Called for REPLY_RX (legacy ABG frames), or 913/* Called for REPLY_RX (legacy ABG frames), or
916 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ 914 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
917static int iwl_rx_reply_rx(struct iwl_priv *priv, 915static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
918 struct iwl_rx_mem_buffer *rxb, 916 struct iwl_rx_mem_buffer *rxb,
919 struct iwl_device_cmd *cmd) 917 struct iwl_device_cmd *cmd)
920{ 918{
@@ -956,7 +954,7 @@ static int iwl_rx_reply_rx(struct iwl_priv *priv,
956 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu)); 954 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
957 len = le16_to_cpu(amsdu->byte_count); 955 len = le16_to_cpu(amsdu->byte_count);
958 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len); 956 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
959 ampdu_status = iwl_translate_rx_status(priv, 957 ampdu_status = iwlagn_translate_rx_status(priv,
960 le32_to_cpu(rx_pkt_status)); 958 le32_to_cpu(rx_pkt_status));
961 } 959 }
962 960
@@ -1029,7 +1027,7 @@ static int iwl_rx_reply_rx(struct iwl_priv *priv,
1029 if (rate_n_flags & RATE_MCS_SGI_MSK) 1027 if (rate_n_flags & RATE_MCS_SGI_MSK)
1030 rx_status.flag |= RX_FLAG_SHORT_GI; 1028 rx_status.flag |= RX_FLAG_SHORT_GI;
1031 1029
1032 iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status, 1030 iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status,
1033 rxb, &rx_status); 1031 rxb, &rx_status);
1034 return 0; 1032 return 0;
1035} 1033}
@@ -1047,12 +1045,14 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
1047 1045
1048 handlers = priv->rx_handlers; 1046 handlers = priv->rx_handlers;
1049 1047
1050 handlers[REPLY_ERROR] = iwl_rx_reply_error; 1048 handlers[REPLY_ERROR] = iwlagn_rx_reply_error;
1051 handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; 1049 handlers[CHANNEL_SWITCH_NOTIFICATION] = iwlagn_rx_csa;
1052 handlers[SPECTRUM_MEASURE_NOTIFICATION] = iwl_rx_spectrum_measure_notif; 1050 handlers[SPECTRUM_MEASURE_NOTIFICATION] =
1053 handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; 1051 iwlagn_rx_spectrum_measure_notif;
1054 handlers[PM_DEBUG_STATISTIC_NOTIFIC] = iwl_rx_pm_debug_statistics_notif; 1052 handlers[PM_SLEEP_NOTIFICATION] = iwlagn_rx_pm_sleep_notif;
1055 handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif; 1053 handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
1054 iwlagn_rx_pm_debug_statistics_notif;
1055 handlers[BEACON_NOTIFICATION] = iwlagn_rx_beacon_notif;
1056 handlers[REPLY_ADD_STA] = iwl_add_sta_callback; 1056 handlers[REPLY_ADD_STA] = iwl_add_sta_callback;
1057 1057
1058 /* 1058 /*
@@ -1060,20 +1060,22 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
1060 * statistics request from the host as well as for the periodic 1060 * statistics request from the host as well as for the periodic
1061 * statistics notifications (after received beacons) from the uCode. 1061 * statistics notifications (after received beacons) from the uCode.
1062 */ 1062 */
1063 handlers[REPLY_STATISTICS_CMD] = iwl_rx_reply_statistics; 1063 handlers[REPLY_STATISTICS_CMD] = iwlagn_rx_reply_statistics;
1064 handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; 1064 handlers[STATISTICS_NOTIFICATION] = iwlagn_rx_statistics;
1065 1065
1066 iwl_setup_rx_scan_handlers(priv); 1066 iwl_setup_rx_scan_handlers(priv);
1067 1067
1068 handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif; 1068 handlers[CARD_STATE_NOTIFICATION] = iwlagn_rx_card_state_notif;
1069 handlers[MISSED_BEACONS_NOTIFICATION] = iwl_rx_missed_beacon_notif; 1069 handlers[MISSED_BEACONS_NOTIFICATION] =
1070 iwlagn_rx_missed_beacon_notif;
1070 1071
1071 /* Rx handlers */ 1072 /* Rx handlers */
1072 handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy; 1073 handlers[REPLY_RX_PHY_CMD] = iwlagn_rx_reply_rx_phy;
1073 handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx; 1074 handlers[REPLY_RX_MPDU_CMD] = iwlagn_rx_reply_rx;
1074 1075
1075 /* block ack */ 1076 /* block ack */
1076 handlers[REPLY_COMPRESSED_BA] = iwlagn_rx_reply_compressed_ba; 1077 handlers[REPLY_COMPRESSED_BA] =
1078 iwlagn_rx_reply_compressed_ba;
1077 1079
1078 /* init calibration handlers */ 1080 /* init calibration handlers */
1079 priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] = 1081 priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index ca632f9b1cc8..58a381c01c89 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -26,10 +26,8 @@
26 26
27#include "iwl-dev.h" 27#include "iwl-dev.h"
28#include "iwl-agn.h" 28#include "iwl-agn.h"
29#include "iwl-sta.h"
30#include "iwl-core.h" 29#include "iwl-core.h"
31#include "iwl-agn-calib.h" 30#include "iwl-agn-calib.h"
32#include "iwl-helpers.h"
33#include "iwl-trans.h" 31#include "iwl-trans.h"
34#include "iwl-shared.h" 32#include "iwl-shared.h"
35 33
@@ -296,8 +294,8 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
296 return ret; 294 return ret;
297 } 295 }
298 296
299 if ((ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) && 297 if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION &&
300 priv->cfg->ht_params->smps_mode) 298 priv->cfg->ht_params && priv->cfg->ht_params->smps_mode)
301 ieee80211_request_smps(ctx->vif, 299 ieee80211_request_smps(ctx->vif,
302 priv->cfg->ht_params->smps_mode); 300 priv->cfg->ht_params->smps_mode);
303 301
@@ -539,7 +537,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
539 const struct iwl_channel_info *ch_info; 537 const struct iwl_channel_info *ch_info;
540 int ret = 0; 538 int ret = 0;
541 539
542 IWL_DEBUG_MAC80211(priv, "changed %#x", changed); 540 IWL_DEBUG_MAC80211(priv, "enter: changed %#x", changed);
543 541
544 mutex_lock(&priv->shrd->mutex); 542 mutex_lock(&priv->shrd->mutex);
545 543
@@ -657,6 +655,8 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
657 } 655 }
658 out: 656 out:
659 mutex_unlock(&priv->shrd->mutex); 657 mutex_unlock(&priv->shrd->mutex);
658 IWL_DEBUG_MAC80211(priv, "leave\n");
659
660 return ret; 660 return ret;
661} 661}
662 662
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 8f0b86de1863..ed6283623932 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -31,26 +31,834 @@
31 31
32#include "iwl-dev.h" 32#include "iwl-dev.h"
33#include "iwl-core.h" 33#include "iwl-core.h"
34#include "iwl-sta.h"
35#include "iwl-agn.h" 34#include "iwl-agn.h"
36#include "iwl-trans.h" 35#include "iwl-trans.h"
37 36
38static struct iwl_link_quality_cmd * 37/* priv->shrd->sta_lock must be held */
39iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id) 38static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
39{
40
41 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
42 IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u "
43 "addr %pM\n",
44 sta_id, priv->stations[sta_id].sta.sta.addr);
45
46 if (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) {
47 IWL_DEBUG_ASSOC(priv,
48 "STA id %u addr %pM already present in uCode "
49 "(according to driver)\n",
50 sta_id, priv->stations[sta_id].sta.sta.addr);
51 } else {
52 priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
53 IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n",
54 sta_id, priv->stations[sta_id].sta.sta.addr);
55 }
56}
57
58static int iwl_process_add_sta_resp(struct iwl_priv *priv,
59 struct iwl_addsta_cmd *addsta,
60 struct iwl_rx_packet *pkt)
61{
62 u8 sta_id = addsta->sta.sta_id;
63 unsigned long flags;
64 int ret = -EIO;
65
66 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
67 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
68 pkt->hdr.flags);
69 return ret;
70 }
71
72 IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
73 sta_id);
74
75 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
76
77 switch (pkt->u.add_sta.status) {
78 case ADD_STA_SUCCESS_MSK:
79 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
80 iwl_sta_ucode_activate(priv, sta_id);
81 ret = 0;
82 break;
83 case ADD_STA_NO_ROOM_IN_TABLE:
84 IWL_ERR(priv, "Adding station %d failed, no room in table.\n",
85 sta_id);
86 break;
87 case ADD_STA_NO_BLOCK_ACK_RESOURCE:
88 IWL_ERR(priv, "Adding station %d failed, no block ack "
89 "resource.\n", sta_id);
90 break;
91 case ADD_STA_MODIFY_NON_EXIST_STA:
92 IWL_ERR(priv, "Attempting to modify non-existing station %d\n",
93 sta_id);
94 break;
95 default:
96 IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
97 pkt->u.add_sta.status);
98 break;
99 }
100
101 IWL_DEBUG_INFO(priv, "%s station id %u addr %pM\n",
102 priv->stations[sta_id].sta.mode ==
103 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
104 sta_id, priv->stations[sta_id].sta.sta.addr);
105
106 /*
107 * XXX: The MAC address in the command buffer is often changed from
108 * the original sent to the device. That is, the MAC address
109 * written to the command buffer often is not the same MAC address
110 * read from the command buffer when the command returns. This
111 * issue has not yet been resolved and this debugging is left to
112 * observe the problem.
113 */
114 IWL_DEBUG_INFO(priv, "%s station according to cmd buffer %pM\n",
115 priv->stations[sta_id].sta.mode ==
116 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
117 addsta->sta.addr);
118 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
119
120 return ret;
121}
122
123int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
124 struct iwl_device_cmd *cmd)
125{
126 struct iwl_rx_packet *pkt = rxb_addr(rxb);
127 struct iwl_addsta_cmd *addsta =
128 (struct iwl_addsta_cmd *) cmd->payload;
129
130 return iwl_process_add_sta_resp(priv, addsta, pkt);
131}
132
133static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
134{
135 u16 size = (u16)sizeof(struct iwl_addsta_cmd);
136 struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data;
137 memcpy(addsta, cmd, size);
138 /* resrved in 5000 */
139 addsta->rate_n_flags = cpu_to_le16(0);
140 return size;
141}
142
143int iwl_send_add_sta(struct iwl_priv *priv,
144 struct iwl_addsta_cmd *sta, u8 flags)
145{
146 int ret = 0;
147 u8 data[sizeof(*sta)];
148 struct iwl_host_cmd cmd = {
149 .id = REPLY_ADD_STA,
150 .flags = flags,
151 .data = { data, },
152 };
153 u8 sta_id __maybe_unused = sta->sta.sta_id;
154
155 IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n",
156 sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : "");
157
158 if (!(flags & CMD_ASYNC)) {
159 cmd.flags |= CMD_WANT_SKB;
160 might_sleep();
161 }
162
163 cmd.len[0] = iwlagn_build_addsta_hcmd(sta, data);
164 ret = iwl_trans_send_cmd(trans(priv), &cmd);
165
166 if (ret || (flags & CMD_ASYNC))
167 return ret;
168 /*else the command was successfully sent in SYNC mode, need to free
169 * the reply page */
170
171 iwl_free_pages(priv->shrd, cmd.reply_page);
172
173 if (cmd.handler_status)
174 IWL_ERR(priv, "%s - error in the CMD response %d", __func__,
175 cmd.handler_status);
176
177 return cmd.handler_status;
178}
179
180static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
181 struct ieee80211_sta *sta,
182 struct iwl_rxon_context *ctx)
183{
184 struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
185 __le32 sta_flags;
186 u8 mimo_ps_mode;
187
188 if (!sta || !sta_ht_inf->ht_supported)
189 goto done;
190
191 mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
192 IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n",
193 (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ?
194 "static" :
195 (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ?
196 "dynamic" : "disabled");
197
198 sta_flags = priv->stations[index].sta.station_flags;
199
200 sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);
201
202 switch (mimo_ps_mode) {
203 case WLAN_HT_CAP_SM_PS_STATIC:
204 sta_flags |= STA_FLG_MIMO_DIS_MSK;
205 break;
206 case WLAN_HT_CAP_SM_PS_DYNAMIC:
207 sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
208 break;
209 case WLAN_HT_CAP_SM_PS_DISABLED:
210 break;
211 default:
212 IWL_WARN(priv, "Invalid MIMO PS mode %d\n", mimo_ps_mode);
213 break;
214 }
215
216 sta_flags |= cpu_to_le32(
217 (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
218
219 sta_flags |= cpu_to_le32(
220 (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
221
222 if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
223 sta_flags |= STA_FLG_HT40_EN_MSK;
224 else
225 sta_flags &= ~STA_FLG_HT40_EN_MSK;
226
227 priv->stations[index].sta.station_flags = sta_flags;
228 done:
229 return;
230}
231
232/**
233 * iwl_prep_station - Prepare station information for addition
234 *
235 * should be called with sta_lock held
236 */
237u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
238 const u8 *addr, bool is_ap, struct ieee80211_sta *sta)
239{
240 struct iwl_station_entry *station;
241 int i;
242 u8 sta_id = IWL_INVALID_STATION;
243
244 if (is_ap)
245 sta_id = ctx->ap_sta_id;
246 else if (is_broadcast_ether_addr(addr))
247 sta_id = ctx->bcast_sta_id;
248 else
249 for (i = IWL_STA_ID; i < IWLAGN_STATION_COUNT; i++) {
250 if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
251 addr)) {
252 sta_id = i;
253 break;
254 }
255
256 if (!priv->stations[i].used &&
257 sta_id == IWL_INVALID_STATION)
258 sta_id = i;
259 }
260
261 /*
262 * These two conditions have the same outcome, but keep them
263 * separate
264 */
265 if (unlikely(sta_id == IWL_INVALID_STATION))
266 return sta_id;
267
268 /*
269 * uCode is not able to deal with multiple requests to add a
270 * station. Keep track if one is in progress so that we do not send
271 * another.
272 */
273 if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
274 IWL_DEBUG_INFO(priv, "STA %d already in process of being "
275 "added.\n", sta_id);
276 return sta_id;
277 }
278
279 if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
280 (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) &&
281 !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) {
282 IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not "
283 "adding again.\n", sta_id, addr);
284 return sta_id;
285 }
286
287 station = &priv->stations[sta_id];
288 station->used = IWL_STA_DRIVER_ACTIVE;
289 IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n",
290 sta_id, addr);
291 priv->num_stations++;
292
293 /* Set up the REPLY_ADD_STA command to send to device */
294 memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd));
295 memcpy(station->sta.sta.addr, addr, ETH_ALEN);
296 station->sta.mode = 0;
297 station->sta.sta.sta_id = sta_id;
298 station->sta.station_flags = ctx->station_flags;
299 station->ctxid = ctx->ctxid;
300
301 if (sta) {
302 struct iwl_station_priv *sta_priv;
303
304 sta_priv = (void *)sta->drv_priv;
305 sta_priv->ctx = ctx;
306 }
307
308 /*
309 * OK to call unconditionally, since local stations (IBSS BSSID
310 * STA and broadcast STA) pass in a NULL sta, and mac80211
311 * doesn't allow HT IBSS.
312 */
313 iwl_set_ht_add_station(priv, sta_id, sta, ctx);
314
315 return sta_id;
316
317}
318
319#define STA_WAIT_TIMEOUT (HZ/2)
320
321/**
322 * iwl_add_station_common -
323 */
324int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
325 const u8 *addr, bool is_ap,
326 struct ieee80211_sta *sta, u8 *sta_id_r)
327{
328 unsigned long flags_spin;
329 int ret = 0;
330 u8 sta_id;
331 struct iwl_addsta_cmd sta_cmd;
332
333 *sta_id_r = 0;
334 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
335 sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta);
336 if (sta_id == IWL_INVALID_STATION) {
337 IWL_ERR(priv, "Unable to prepare station %pM for addition\n",
338 addr);
339 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
340 return -EINVAL;
341 }
342
343 /*
344 * uCode is not able to deal with multiple requests to add a
345 * station. Keep track if one is in progress so that we do not send
346 * another.
347 */
348 if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
349 IWL_DEBUG_INFO(priv, "STA %d already in process of being "
350 "added.\n", sta_id);
351 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
352 return -EEXIST;
353 }
354
355 if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
356 (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
357 IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not "
358 "adding again.\n", sta_id, addr);
359 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
360 return -EEXIST;
361 }
362
363 priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
364 memcpy(&sta_cmd, &priv->stations[sta_id].sta,
365 sizeof(struct iwl_addsta_cmd));
366 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
367
368 /* Add station to device's station table */
369 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
370 if (ret) {
371 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
372 IWL_ERR(priv, "Adding station %pM failed.\n",
373 priv->stations[sta_id].sta.sta.addr);
374 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
375 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
376 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
377 }
378 *sta_id_r = sta_id;
379 return ret;
380}
381
382/**
383 * iwl_sta_ucode_deactivate - deactivate ucode status for a station
384 *
385 * priv->shrd->sta_lock must be held
386 */
387static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
388{
389 /* Ucode must be active and driver must be non active */
390 if ((priv->stations[sta_id].used &
391 (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) !=
392 IWL_STA_UCODE_ACTIVE)
393 IWL_ERR(priv, "removed non active STA %u\n", sta_id);
394
395 priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE;
396
397 memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry));
398 IWL_DEBUG_ASSOC(priv, "Removed STA %u\n", sta_id);
399}
400
401static int iwl_send_remove_station(struct iwl_priv *priv,
402 const u8 *addr, int sta_id,
403 bool temporary)
404{
405 struct iwl_rx_packet *pkt;
406 int ret;
407
408 unsigned long flags_spin;
409 struct iwl_rem_sta_cmd rm_sta_cmd;
410
411 struct iwl_host_cmd cmd = {
412 .id = REPLY_REMOVE_STA,
413 .len = { sizeof(struct iwl_rem_sta_cmd), },
414 .flags = CMD_SYNC,
415 .data = { &rm_sta_cmd, },
416 };
417
418 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
419 rm_sta_cmd.num_sta = 1;
420 memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN);
421
422 cmd.flags |= CMD_WANT_SKB;
423
424 ret = iwl_trans_send_cmd(trans(priv), &cmd);
425
426 if (ret)
427 return ret;
428
429 pkt = (struct iwl_rx_packet *)cmd.reply_page;
430 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
431 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
432 pkt->hdr.flags);
433 ret = -EIO;
434 }
435
436 if (!ret) {
437 switch (pkt->u.rem_sta.status) {
438 case REM_STA_SUCCESS_MSK:
439 if (!temporary) {
440 spin_lock_irqsave(&priv->shrd->sta_lock,
441 flags_spin);
442 iwl_sta_ucode_deactivate(priv, sta_id);
443 spin_unlock_irqrestore(&priv->shrd->sta_lock,
444 flags_spin);
445 }
446 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
447 break;
448 default:
449 ret = -EIO;
450 IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
451 break;
452 }
453 }
454 iwl_free_pages(priv->shrd, cmd.reply_page);
455
456 return ret;
457}
458
459/**
460 * iwl_remove_station - Remove driver's knowledge of station.
461 */
462int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
463 const u8 *addr)
464{
465 unsigned long flags;
466
467 if (!iwl_is_ready(priv->shrd)) {
468 IWL_DEBUG_INFO(priv,
469 "Unable to remove station %pM, device not ready.\n",
470 addr);
471 /*
472 * It is typical for stations to be removed when we are
473 * going down. Return success since device will be down
474 * soon anyway
475 */
476 return 0;
477 }
478
479 IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
480 sta_id, addr);
481
482 if (WARN_ON(sta_id == IWL_INVALID_STATION))
483 return -EINVAL;
484
485 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
486
487 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
488 IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
489 addr);
490 goto out_err;
491 }
492
493 if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
494 IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n",
495 addr);
496 goto out_err;
497 }
498
499 if (priv->stations[sta_id].used & IWL_STA_LOCAL) {
500 kfree(priv->stations[sta_id].lq);
501 priv->stations[sta_id].lq = NULL;
502 }
503
504 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
505
506 priv->num_stations--;
507
508 if (WARN_ON(priv->num_stations < 0))
509 priv->num_stations = 0;
510
511 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
512
513 return iwl_send_remove_station(priv, addr, sta_id, false);
514out_err:
515 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
516 return -EINVAL;
517}
518
519/**
520 * iwl_clear_ucode_stations - clear ucode station table bits
521 *
522 * This function clears all the bits in the driver indicating
523 * which stations are active in the ucode. Call when something
524 * other than explicit station management would cause this in
525 * the ucode, e.g. unassociated RXON.
526 */
527void iwl_clear_ucode_stations(struct iwl_priv *priv,
528 struct iwl_rxon_context *ctx)
529{
530 int i;
531 unsigned long flags_spin;
532 bool cleared = false;
533
534 IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n");
535
536 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
537 for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
538 if (ctx && ctx->ctxid != priv->stations[i].ctxid)
539 continue;
540
541 if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) {
542 IWL_DEBUG_INFO(priv,
543 "Clearing ucode active for station %d\n", i);
544 priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
545 cleared = true;
546 }
547 }
548 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
549
550 if (!cleared)
551 IWL_DEBUG_INFO(priv,
552 "No active stations found to be cleared\n");
553}
554
555/**
556 * iwl_restore_stations() - Restore driver known stations to device
557 *
558 * All stations considered active by driver, but not present in ucode, is
559 * restored.
560 *
561 * Function sleeps.
562 */
563void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
564{
565 struct iwl_addsta_cmd sta_cmd;
566 struct iwl_link_quality_cmd lq;
567 unsigned long flags_spin;
568 int i;
569 bool found = false;
570 int ret;
571 bool send_lq;
572
573 if (!iwl_is_ready(priv->shrd)) {
574 IWL_DEBUG_INFO(priv,
575 "Not ready yet, not restoring any stations.\n");
576 return;
577 }
578
579 IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
580 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
581 for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
582 if (ctx->ctxid != priv->stations[i].ctxid)
583 continue;
584 if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) &&
585 !(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) {
586 IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n",
587 priv->stations[i].sta.sta.addr);
588 priv->stations[i].sta.mode = 0;
589 priv->stations[i].used |= IWL_STA_UCODE_INPROGRESS;
590 found = true;
591 }
592 }
593
594 for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
595 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
596 memcpy(&sta_cmd, &priv->stations[i].sta,
597 sizeof(struct iwl_addsta_cmd));
598 send_lq = false;
599 if (priv->stations[i].lq) {
600 if (priv->shrd->wowlan)
601 iwl_sta_fill_lq(priv, ctx, i, &lq);
602 else
603 memcpy(&lq, priv->stations[i].lq,
604 sizeof(struct iwl_link_quality_cmd));
605 send_lq = true;
606 }
607 spin_unlock_irqrestore(&priv->shrd->sta_lock,
608 flags_spin);
609 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
610 if (ret) {
611 spin_lock_irqsave(&priv->shrd->sta_lock,
612 flags_spin);
613 IWL_ERR(priv, "Adding station %pM failed.\n",
614 priv->stations[i].sta.sta.addr);
615 priv->stations[i].used &=
616 ~IWL_STA_DRIVER_ACTIVE;
617 priv->stations[i].used &=
618 ~IWL_STA_UCODE_INPROGRESS;
619 spin_unlock_irqrestore(&priv->shrd->sta_lock,
620 flags_spin);
621 }
622 /*
623 * Rate scaling has already been initialized, send
624 * current LQ command
625 */
626 if (send_lq)
627 iwl_send_lq_cmd(priv, ctx, &lq,
628 CMD_SYNC, true);
629 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
630 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
631 }
632 }
633
634 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
635 if (!found)
636 IWL_DEBUG_INFO(priv, "Restoring all known stations .... "
637 "no stations to be restored.\n");
638 else
639 IWL_DEBUG_INFO(priv, "Restoring all known stations .... "
640 "complete.\n");
641}
642
643void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
644{
645 unsigned long flags;
646 int sta_id = ctx->ap_sta_id;
647 int ret;
648 struct iwl_addsta_cmd sta_cmd;
649 struct iwl_link_quality_cmd lq;
650 bool active;
651
652 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
653 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
654 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
655 return;
656 }
657
658 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
659 sta_cmd.mode = 0;
660 memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));
661
662 active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
663 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
664 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
665
666 if (active) {
667 ret = iwl_send_remove_station(
668 priv, priv->stations[sta_id].sta.sta.addr,
669 sta_id, true);
670 if (ret)
671 IWL_ERR(priv, "failed to remove STA %pM (%d)\n",
672 priv->stations[sta_id].sta.sta.addr, ret);
673 }
674 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
675 priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
676 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
677
678 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
679 if (ret)
680 IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
681 priv->stations[sta_id].sta.sta.addr, ret);
682 iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
683}
684
685int iwl_get_free_ucode_key_offset(struct iwl_priv *priv)
686{
687 int i;
688
689 for (i = 0; i < priv->sta_key_max_num; i++)
690 if (!test_and_set_bit(i, &priv->ucode_key_table))
691 return i;
692
693 return WEP_INVALID_OFFSET;
694}
695
696void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
697{
698 unsigned long flags;
699 int i;
700
701 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
702 for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
703 if (!(priv->stations[i].used & IWL_STA_BCAST))
704 continue;
705
706 priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
707 priv->num_stations--;
708 if (WARN_ON(priv->num_stations < 0))
709 priv->num_stations = 0;
710 kfree(priv->stations[i].lq);
711 priv->stations[i].lq = NULL;
712 }
713 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
714}
715
716#ifdef CONFIG_IWLWIFI_DEBUG
717static void iwl_dump_lq_cmd(struct iwl_priv *priv,
718 struct iwl_link_quality_cmd *lq)
719{
720 int i;
721 IWL_DEBUG_RATE(priv, "lq station id 0x%x\n", lq->sta_id);
722 IWL_DEBUG_RATE(priv, "lq ant 0x%X 0x%X\n",
723 lq->general_params.single_stream_ant_msk,
724 lq->general_params.dual_stream_ant_msk);
725
726 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
727 IWL_DEBUG_RATE(priv, "lq index %d 0x%X\n",
728 i, lq->rs_table[i].rate_n_flags);
729}
730#else
731static inline void iwl_dump_lq_cmd(struct iwl_priv *priv,
732 struct iwl_link_quality_cmd *lq)
733{
734}
735#endif
736
737/**
738 * is_lq_table_valid() - Test one aspect of LQ cmd for validity
739 *
740 * It sometimes happens when a HT rate has been in use and we
741 * loose connectivity with AP then mac80211 will first tell us that the
742 * current channel is not HT anymore before removing the station. In such a
743 * scenario the RXON flags will be updated to indicate we are not
744 * communicating HT anymore, but the LQ command may still contain HT rates.
745 * Test for this to prevent driver from sending LQ command between the time
746 * RXON flags are updated and when LQ command is updated.
747 */
748static bool is_lq_table_valid(struct iwl_priv *priv,
749 struct iwl_rxon_context *ctx,
750 struct iwl_link_quality_cmd *lq)
751{
752 int i;
753
754 if (ctx->ht.enabled)
755 return true;
756
757 IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n",
758 ctx->active.channel);
759 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
760 if (le32_to_cpu(lq->rs_table[i].rate_n_flags) &
761 RATE_MCS_HT_MSK) {
762 IWL_DEBUG_INFO(priv,
763 "index %d of LQ expects HT channel\n",
764 i);
765 return false;
766 }
767 }
768 return true;
769}
770
771/**
772 * iwl_send_lq_cmd() - Send link quality command
773 * @init: This command is sent as part of station initialization right
774 * after station has been added.
775 *
776 * The link quality command is sent as the last step of station creation.
777 * This is the special case in which init is set and we call a callback in
778 * this case to clear the state indicating that station creation is in
779 * progress.
780 */
781int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
782 struct iwl_link_quality_cmd *lq, u8 flags, bool init)
783{
784 int ret = 0;
785 unsigned long flags_spin;
786
787 struct iwl_host_cmd cmd = {
788 .id = REPLY_TX_LINK_QUALITY_CMD,
789 .len = { sizeof(struct iwl_link_quality_cmd), },
790 .flags = flags,
791 .data = { lq, },
792 };
793
794 if (WARN_ON(lq->sta_id == IWL_INVALID_STATION))
795 return -EINVAL;
796
797
798 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
799 if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
800 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
801 return -EINVAL;
802 }
803 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
804
805 iwl_dump_lq_cmd(priv, lq);
806 if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
807 return -EINVAL;
808
809 if (is_lq_table_valid(priv, ctx, lq))
810 ret = iwl_trans_send_cmd(trans(priv), &cmd);
811 else
812 ret = -EINVAL;
813
814 if (cmd.flags & CMD_ASYNC)
815 return ret;
816
817 if (init) {
818 IWL_DEBUG_INFO(priv, "init LQ command complete, "
819 "clearing sta addition status for sta %d\n",
820 lq->sta_id);
821 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
822 priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
823 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
824 }
825 return ret;
826}
827
828int iwlagn_mac_sta_remove(struct ieee80211_hw *hw,
829 struct ieee80211_vif *vif,
830 struct ieee80211_sta *sta)
831{
832 struct iwl_priv *priv = hw->priv;
833 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
834 int ret;
835
836 IWL_DEBUG_MAC80211(priv, "enter: received request to remove "
837 "station %pM\n", sta->addr);
838 mutex_lock(&priv->shrd->mutex);
839 IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n",
840 sta->addr);
841 ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr);
842 if (ret)
843 IWL_ERR(priv, "Error removing station %pM\n",
844 sta->addr);
845 mutex_unlock(&priv->shrd->mutex);
846 IWL_DEBUG_MAC80211(priv, "leave\n");
847
848 return ret;
849}
850
851void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
852 u8 sta_id, struct iwl_link_quality_cmd *link_cmd)
40{ 853{
41 int i, r; 854 int i, r;
42 struct iwl_link_quality_cmd *link_cmd;
43 u32 rate_flags = 0; 855 u32 rate_flags = 0;
44 __le32 rate_n_flags; 856 __le32 rate_n_flags;
45 857
46 link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
47 if (!link_cmd) {
48 IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
49 return NULL;
50 }
51
52 lockdep_assert_held(&priv->shrd->mutex); 858 lockdep_assert_held(&priv->shrd->mutex);
53 859
860 memset(link_cmd, 0, sizeof(*link_cmd));
861
54 /* Set up the rate scaling to start at selected rate, fall back 862 /* Set up the rate scaling to start at selected rate, fall back
55 * all the way down to 1M in IEEE order, and then spin on 1M */ 863 * all the way down to 1M in IEEE order, and then spin on 1M */
56 if (priv->band == IEEE80211_BAND_5GHZ) 864 if (priv->band == IEEE80211_BAND_5GHZ)
@@ -82,11 +890,27 @@ iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id)
82 hw_params(priv).valid_tx_ant; 890 hw_params(priv).valid_tx_ant;
83 } 891 }
84 892
85 link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; 893 link_cmd->agg_params.agg_dis_start_th =
894 LINK_QUAL_AGG_DISABLE_START_DEF;
86 link_cmd->agg_params.agg_time_limit = 895 link_cmd->agg_params.agg_time_limit =
87 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); 896 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
88 897
89 link_cmd->sta_id = sta_id; 898 link_cmd->sta_id = sta_id;
899}
900
901static struct iwl_link_quality_cmd *
902iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
903 u8 sta_id)
904{
905 struct iwl_link_quality_cmd *link_cmd;
906
907 link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
908 if (!link_cmd) {
909 IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
910 return NULL;
911 }
912
913 iwl_sta_fill_lq(priv, ctx, sta_id, link_cmd);
90 914
91 return link_cmd; 915 return link_cmd;
92} 916}
@@ -96,7 +920,8 @@ iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id)
96 * 920 *
97 * Function sleeps. 921 * Function sleeps.
98 */ 922 */
99int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 923int iwlagn_add_bssid_station(struct iwl_priv *priv,
924 struct iwl_rxon_context *ctx,
100 const u8 *addr, u8 *sta_id_r) 925 const u8 *addr, u8 *sta_id_r)
101{ 926{
102 int ret; 927 int ret;
@@ -123,7 +948,8 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx
123 /* Set up default rate scaling table in device's station table */ 948 /* Set up default rate scaling table in device's station table */
124 link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); 949 link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id);
125 if (!link_cmd) { 950 if (!link_cmd) {
126 IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n", 951 IWL_ERR(priv,
952 "Unable to initialize rate scaling for station %pM.\n",
127 addr); 953 addr);
128 return -ENOMEM; 954 return -ENOMEM;
129 } 955 }
@@ -215,7 +1041,8 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
215 1041
216 memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); 1042 memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
217 if (iwl_is_rfkill(priv->shrd)) { 1043 if (iwl_is_rfkill(priv->shrd)) {
218 IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); 1044 IWL_DEBUG_WEP(priv,
1045 "Not sending REPLY_WEPKEY command due to RFKILL.\n");
219 /* but keys in device are clear anyway so return success */ 1046 /* but keys in device are clear anyway so return success */
220 return 0; 1047 return 0;
221 } 1048 }
@@ -236,7 +1063,8 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
236 1063
237 if (keyconf->keylen != WEP_KEY_LEN_128 && 1064 if (keyconf->keylen != WEP_KEY_LEN_128 &&
238 keyconf->keylen != WEP_KEY_LEN_64) { 1065 keyconf->keylen != WEP_KEY_LEN_64) {
239 IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen); 1066 IWL_DEBUG_WEP(priv,
1067 "Bad WEP key length %d\n", keyconf->keylen);
240 return -EINVAL; 1068 return -EINVAL;
241 } 1069 }
242 1070
@@ -676,6 +1504,8 @@ void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
676 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; 1504 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
677 int sta_id; 1505 int sta_id;
678 1506
1507 IWL_DEBUG_MAC80211(priv, "enter\n");
1508
679 switch (cmd) { 1509 switch (cmd) {
680 case STA_NOTIFY_SLEEP: 1510 case STA_NOTIFY_SLEEP:
681 WARN_ON(!sta_priv->client); 1511 WARN_ON(!sta_priv->client);
@@ -695,4 +1525,5 @@ void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
695 default: 1525 default:
696 break; 1526 break;
697 } 1527 }
1528 IWL_DEBUG_MAC80211(priv, "leave\n");
698} 1529}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index dcb3bd67d4f9..35a6b71f358c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -35,9 +35,7 @@
35 35
36#include "iwl-dev.h" 36#include "iwl-dev.h"
37#include "iwl-core.h" 37#include "iwl-core.h"
38#include "iwl-sta.h"
39#include "iwl-io.h" 38#include "iwl-io.h"
40#include "iwl-helpers.h"
41#include "iwl-agn-hw.h" 39#include "iwl-agn-hw.h"
42#include "iwl-agn.h" 40#include "iwl-agn.h"
43#include "iwl-trans.h" 41#include "iwl-trans.h"
@@ -113,8 +111,6 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
113 tx_cmd->next_frame_len = 0; 111 tx_cmd->next_frame_len = 0;
114} 112}
115 113
116#define RTS_DFAULT_RETRY_LIMIT 60
117
118static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, 114static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
119 struct iwl_tx_cmd *tx_cmd, 115 struct iwl_tx_cmd *tx_cmd,
120 struct ieee80211_tx_info *info, 116 struct ieee80211_tx_info *info,
@@ -126,17 +122,25 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
126 u8 data_retry_limit; 122 u8 data_retry_limit;
127 u8 rate_plcp; 123 u8 rate_plcp;
128 124
129 /* Set retry limit on DATA packets and Probe Responses*/ 125 if (priv->shrd->wowlan) {
130 if (ieee80211_is_probe_resp(fc)) 126 rts_retry_limit = IWLAGN_LOW_RETRY_LIMIT;
131 data_retry_limit = 3; 127 data_retry_limit = IWLAGN_LOW_RETRY_LIMIT;
132 else 128 } else {
133 data_retry_limit = IWLAGN_DEFAULT_TX_RETRY; 129 /* Set retry limit on RTS packets */
134 tx_cmd->data_retry_limit = data_retry_limit; 130 rts_retry_limit = IWLAGN_RTS_DFAULT_RETRY_LIMIT;
131
132 /* Set retry limit on DATA packets and Probe Responses*/
133 if (ieee80211_is_probe_resp(fc)) {
134 data_retry_limit = IWLAGN_MGMT_DFAULT_RETRY_LIMIT;
135 rts_retry_limit =
136 min(data_retry_limit, rts_retry_limit);
137 } else if (ieee80211_is_back_req(fc))
138 data_retry_limit = IWLAGN_BAR_DFAULT_RETRY_LIMIT;
139 else
140 data_retry_limit = IWLAGN_DEFAULT_TX_RETRY;
141 }
135 142
136 /* Set retry limit on RTS packets */ 143 tx_cmd->data_retry_limit = data_retry_limit;
137 rts_retry_limit = RTS_DFAULT_RETRY_LIMIT;
138 if (data_retry_limit < rts_retry_limit)
139 rts_retry_limit = data_retry_limit;
140 tx_cmd->rts_retry_limit = rts_retry_limit; 144 tx_cmd->rts_retry_limit = rts_retry_limit;
141 145
142 /* DATA packets will use the uCode station table for rate/antenna 146 /* DATA packets will use the uCode station table for rate/antenna
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index b4e1e7c4c314..8ba0dd54e37d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -35,7 +35,6 @@
35#include "iwl-dev.h" 35#include "iwl-dev.h"
36#include "iwl-core.h" 36#include "iwl-core.h"
37#include "iwl-io.h" 37#include "iwl-io.h"
38#include "iwl-helpers.h"
39#include "iwl-agn-hw.h" 38#include "iwl-agn-hw.h"
40#include "iwl-agn.h" 39#include "iwl-agn.h"
41#include "iwl-agn-calib.h" 40#include "iwl-agn-calib.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index d0fd6f063bf8..ccba69b7f8a7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -47,8 +47,6 @@
47#include "iwl-dev.h" 47#include "iwl-dev.h"
48#include "iwl-core.h" 48#include "iwl-core.h"
49#include "iwl-io.h" 49#include "iwl-io.h"
50#include "iwl-helpers.h"
51#include "iwl-sta.h"
52#include "iwl-agn-calib.h" 50#include "iwl-agn-calib.h"
53#include "iwl-agn.h" 51#include "iwl-agn.h"
54#include "iwl-shared.h" 52#include "iwl-shared.h"
@@ -463,7 +461,7 @@ static void iwl_bg_tx_flush(struct work_struct *work)
463static void iwl_free_fw_desc(struct iwl_priv *priv, struct fw_desc *desc) 461static void iwl_free_fw_desc(struct iwl_priv *priv, struct fw_desc *desc)
464{ 462{
465 if (desc->v_addr) 463 if (desc->v_addr)
466 dma_free_coherent(priv->bus->dev, desc->len, 464 dma_free_coherent(bus(priv)->dev, desc->len,
467 desc->v_addr, desc->p_addr); 465 desc->v_addr, desc->p_addr);
468 desc->v_addr = NULL; 466 desc->v_addr = NULL;
469 desc->len = 0; 467 desc->len = 0;
@@ -490,7 +488,7 @@ static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc,
490 return -EINVAL; 488 return -EINVAL;
491 } 489 }
492 490
493 desc->v_addr = dma_alloc_coherent(priv->bus->dev, len, 491 desc->v_addr = dma_alloc_coherent(bus(priv)->dev, len,
494 &desc->p_addr, GFP_KERNEL); 492 &desc->p_addr, GFP_KERNEL);
495 if (!desc->v_addr) 493 if (!desc->v_addr)
496 return -ENOMEM; 494 return -ENOMEM;
@@ -565,7 +563,7 @@ struct iwlagn_ucode_capabilities {
565}; 563};
566 564
567static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); 565static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
568static int iwl_mac_setup_register(struct iwl_priv *priv, 566static int iwlagn_mac_setup_register(struct iwl_priv *priv,
569 struct iwlagn_ucode_capabilities *capa); 567 struct iwlagn_ucode_capabilities *capa);
570 568
571#define UCODE_EXPERIMENTAL_INDEX 100 569#define UCODE_EXPERIMENTAL_INDEX 100
@@ -602,7 +600,7 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
602 priv->firmware_name); 600 priv->firmware_name);
603 601
604 return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, 602 return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
605 priv->bus->dev, 603 bus(priv)->dev,
606 GFP_KERNEL, priv, iwl_ucode_callback); 604 GFP_KERNEL, priv, iwl_ucode_callback);
607} 605}
608 606
@@ -1136,7 +1134,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1136 * 1134 *
1137 * 9. Setup and register with mac80211 and debugfs 1135 * 9. Setup and register with mac80211 and debugfs
1138 **************************************************/ 1136 **************************************************/
1139 err = iwl_mac_setup_register(priv, &ucode_capa); 1137 err = iwlagn_mac_setup_register(priv, &ucode_capa);
1140 if (err) 1138 if (err)
1141 goto out_unbind; 1139 goto out_unbind;
1142 1140
@@ -1161,7 +1159,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1161 iwl_dealloc_ucode(priv); 1159 iwl_dealloc_ucode(priv);
1162 out_unbind: 1160 out_unbind:
1163 complete(&priv->firmware_loading_complete); 1161 complete(&priv->firmware_loading_complete);
1164 device_release_driver(priv->bus->dev); 1162 device_release_driver(bus(priv)->dev);
1165 release_firmware(ucode_raw); 1163 release_firmware(ucode_raw);
1166} 1164}
1167 1165
@@ -1222,7 +1220,7 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg)
1222 }; 1220 };
1223 1221
1224 memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); 1222 memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
1225 calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL; 1223 calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_RT_CFG_ALL;
1226 calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg); 1224 calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg);
1227 1225
1228 return iwl_trans_send_cmd(trans(priv), &cmd); 1226 return iwl_trans_send_cmd(trans(priv), &cmd);
@@ -1642,7 +1640,7 @@ iwlagn_iface_combinations_p2p[] = {
1642 * Not a mac80211 entry point function, but it fits in with all the 1640 * Not a mac80211 entry point function, but it fits in with all the
1643 * other mac80211 functions grouped here. 1641 * other mac80211 functions grouped here.
1644 */ 1642 */
1645static int iwl_mac_setup_register(struct iwl_priv *priv, 1643static int iwlagn_mac_setup_register(struct iwl_priv *priv,
1646 struct iwlagn_ucode_capabilities *capa) 1644 struct iwlagn_ucode_capabilities *capa)
1647{ 1645{
1648 int ret; 1646 int ret;
@@ -1701,7 +1699,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
1701 WIPHY_FLAG_DISABLE_BEACON_HINTS | 1699 WIPHY_FLAG_DISABLE_BEACON_HINTS |
1702 WIPHY_FLAG_IBSS_RSN; 1700 WIPHY_FLAG_IBSS_RSN;
1703 1701
1704 if (priv->ucode_wowlan.code.len && device_can_wakeup(priv->bus->dev)) { 1702 if (priv->ucode_wowlan.code.len && device_can_wakeup(bus(priv)->dev)) {
1705 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | 1703 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
1706 WIPHY_WOWLAN_DISCONNECT | 1704 WIPHY_WOWLAN_DISCONNECT |
1707 WIPHY_WOWLAN_EAP_IDENTITY_REQ | 1705 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
@@ -1855,6 +1853,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
1855 if (iwlagn_mod_params.sw_crypto) 1853 if (iwlagn_mod_params.sw_crypto)
1856 return; 1854 return;
1857 1855
1856 IWL_DEBUG_MAC80211(priv, "enter\n");
1858 mutex_lock(&priv->shrd->mutex); 1857 mutex_lock(&priv->shrd->mutex);
1859 1858
1860 if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif) 1859 if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif)
@@ -1867,6 +1866,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
1867 1866
1868 out: 1867 out:
1869 mutex_unlock(&priv->shrd->mutex); 1868 mutex_unlock(&priv->shrd->mutex);
1869 IWL_DEBUG_MAC80211(priv, "leave\n");
1870} 1870}
1871 1871
1872struct wowlan_key_data { 1872struct wowlan_key_data {
@@ -2034,6 +2034,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
2034 if (WARN_ON(!wowlan)) 2034 if (WARN_ON(!wowlan))
2035 return -EINVAL; 2035 return -EINVAL;
2036 2036
2037 IWL_DEBUG_MAC80211(priv, "enter\n");
2037 mutex_lock(&priv->shrd->mutex); 2038 mutex_lock(&priv->shrd->mutex);
2038 2039
2039 /* Don't attempt WoWLAN when not associated, tear down instead. */ 2040 /* Don't attempt WoWLAN when not associated, tear down instead. */
@@ -2188,7 +2189,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
2188 if (ret) 2189 if (ret)
2189 goto error; 2190 goto error;
2190 2191
2191 device_set_wakeup_enable(priv->bus->dev, true); 2192 device_set_wakeup_enable(bus(priv)->dev, true);
2192 2193
2193 /* Now let the ucode operate on its own */ 2194 /* Now let the ucode operate on its own */
2194 iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, 2195 iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET,
@@ -2203,6 +2204,8 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
2203 out: 2204 out:
2204 mutex_unlock(&priv->shrd->mutex); 2205 mutex_unlock(&priv->shrd->mutex);
2205 kfree(key_data.rsc_tsc); 2206 kfree(key_data.rsc_tsc);
2207 IWL_DEBUG_MAC80211(priv, "leave\n");
2208
2206 return ret; 2209 return ret;
2207} 2210}
2208 2211
@@ -2215,6 +2218,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
2215 u32 base, status = 0xffffffff; 2218 u32 base, status = 0xffffffff;
2216 int ret = -EIO; 2219 int ret = -EIO;
2217 2220
2221 IWL_DEBUG_MAC80211(priv, "enter\n");
2218 mutex_lock(&priv->shrd->mutex); 2222 mutex_lock(&priv->shrd->mutex);
2219 2223
2220 iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, 2224 iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR,
@@ -2251,7 +2255,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
2251 2255
2252 priv->shrd->wowlan = false; 2256 priv->shrd->wowlan = false;
2253 2257
2254 device_set_wakeup_enable(priv->bus->dev, false); 2258 device_set_wakeup_enable(bus(priv)->dev, false);
2255 2259
2256 iwlagn_prepare_restart(priv); 2260 iwlagn_prepare_restart(priv);
2257 2261
@@ -2260,6 +2264,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
2260 iwlagn_set_rxon_chain(priv, ctx); 2264 iwlagn_set_rxon_chain(priv, ctx);
2261 2265
2262 mutex_unlock(&priv->shrd->mutex); 2266 mutex_unlock(&priv->shrd->mutex);
2267 IWL_DEBUG_MAC80211(priv, "leave\n");
2263 2268
2264 ieee80211_resume_disconnect(vif); 2269 ieee80211_resume_disconnect(vif);
2265 2270
@@ -2402,6 +2407,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
2402 if (!(priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)) 2407 if (!(priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE))
2403 return -EACCES; 2408 return -EACCES;
2404 2409
2410 IWL_DEBUG_MAC80211(priv, "enter\n");
2405 mutex_lock(&priv->shrd->mutex); 2411 mutex_lock(&priv->shrd->mutex);
2406 2412
2407 switch (action) { 2413 switch (action) {
@@ -2418,11 +2424,6 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
2418 case IEEE80211_AMPDU_TX_START: 2424 case IEEE80211_AMPDU_TX_START:
2419 IWL_DEBUG_HT(priv, "start Tx\n"); 2425 IWL_DEBUG_HT(priv, "start Tx\n");
2420 ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); 2426 ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn);
2421 if (ret == 0) {
2422 priv->agg_tids_count++;
2423 IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n",
2424 priv->agg_tids_count);
2425 }
2426 break; 2427 break;
2427 case IEEE80211_AMPDU_TX_STOP: 2428 case IEEE80211_AMPDU_TX_STOP:
2428 IWL_DEBUG_HT(priv, "stop Tx\n"); 2429 IWL_DEBUG_HT(priv, "stop Tx\n");
@@ -2434,7 +2435,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
2434 } 2435 }
2435 if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) 2436 if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
2436 ret = 0; 2437 ret = 0;
2437 if (priv->cfg->ht_params && 2438 if (!priv->agg_tids_count && priv->cfg->ht_params &&
2438 priv->cfg->ht_params->use_rts_for_aggregation) { 2439 priv->cfg->ht_params->use_rts_for_aggregation) {
2439 /* 2440 /*
2440 * switch off RTS/CTS if it was previously enabled 2441 * switch off RTS/CTS if it was previously enabled
@@ -2481,6 +2482,9 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
2481 sta_priv->lq_sta.lq.general_params.flags |= 2482 sta_priv->lq_sta.lq.general_params.flags |=
2482 LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; 2483 LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK;
2483 } 2484 }
2485 priv->agg_tids_count++;
2486 IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n",
2487 priv->agg_tids_count);
2484 2488
2485 sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit = 2489 sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit =
2486 sta_priv->max_agg_bufsize; 2490 sta_priv->max_agg_bufsize;
@@ -2494,7 +2498,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
2494 break; 2498 break;
2495 } 2499 }
2496 mutex_unlock(&priv->shrd->mutex); 2500 mutex_unlock(&priv->shrd->mutex);
2497 2501 IWL_DEBUG_MAC80211(priv, "leave\n");
2498 return ret; 2502 return ret;
2499} 2503}
2500 2504
@@ -2506,10 +2510,10 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
2506 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; 2510 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
2507 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 2511 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
2508 bool is_ap = vif->type == NL80211_IFTYPE_STATION; 2512 bool is_ap = vif->type == NL80211_IFTYPE_STATION;
2509 int ret; 2513 int ret = 0;
2510 u8 sta_id; 2514 u8 sta_id;
2511 2515
2512 IWL_DEBUG_INFO(priv, "received request to add station %pM\n", 2516 IWL_DEBUG_MAC80211(priv, "received request to add station %pM\n",
2513 sta->addr); 2517 sta->addr);
2514 mutex_lock(&priv->shrd->mutex); 2518 mutex_lock(&priv->shrd->mutex);
2515 IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", 2519 IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n",
@@ -2526,8 +2530,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
2526 IWL_ERR(priv, "Unable to add station %pM (%d)\n", 2530 IWL_ERR(priv, "Unable to add station %pM (%d)\n",
2527 sta->addr, ret); 2531 sta->addr, ret);
2528 /* Should we return success if return code is EEXIST ? */ 2532 /* Should we return success if return code is EEXIST ? */
2529 mutex_unlock(&priv->shrd->mutex); 2533 goto out;
2530 return ret;
2531 } 2534 }
2532 2535
2533 sta_priv->sta_id = sta_id; 2536 sta_priv->sta_id = sta_id;
@@ -2536,9 +2539,11 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
2536 IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", 2539 IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
2537 sta->addr); 2540 sta->addr);
2538 iwl_rs_rate_init(priv, sta, sta_id); 2541 iwl_rs_rate_init(priv, sta, sta_id);
2542 out:
2539 mutex_unlock(&priv->shrd->mutex); 2543 mutex_unlock(&priv->shrd->mutex);
2544 IWL_DEBUG_MAC80211(priv, "leave\n");
2540 2545
2541 return 0; 2546 return ret;
2542} 2547}
2543 2548
2544static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, 2549static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
@@ -2754,7 +2759,7 @@ static void iwlagn_disable_roc_work(struct work_struct *work)
2754 mutex_unlock(&priv->shrd->mutex); 2759 mutex_unlock(&priv->shrd->mutex);
2755} 2760}
2756 2761
2757static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, 2762static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
2758 struct ieee80211_channel *channel, 2763 struct ieee80211_channel *channel,
2759 enum nl80211_channel_type channel_type, 2764 enum nl80211_channel_type channel_type,
2760 int duration) 2765 int duration)
@@ -2769,6 +2774,7 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw,
2769 if (!(ctx->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT))) 2774 if (!(ctx->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)))
2770 return -EOPNOTSUPP; 2775 return -EOPNOTSUPP;
2771 2776
2777 IWL_DEBUG_MAC80211(priv, "enter\n");
2772 mutex_lock(&priv->shrd->mutex); 2778 mutex_lock(&priv->shrd->mutex);
2773 2779
2774 if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { 2780 if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) {
@@ -2812,27 +2818,32 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw,
2812 2818
2813 out: 2819 out:
2814 mutex_unlock(&priv->shrd->mutex); 2820 mutex_unlock(&priv->shrd->mutex);
2821 IWL_DEBUG_MAC80211(priv, "leave\n");
2815 2822
2816 return err; 2823 return err;
2817} 2824}
2818 2825
2819static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) 2826static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
2820{ 2827{
2821 struct iwl_priv *priv = hw->priv; 2828 struct iwl_priv *priv = hw->priv;
2822 2829
2823 if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN))) 2830 if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
2824 return -EOPNOTSUPP; 2831 return -EOPNOTSUPP;
2825 2832
2833 IWL_DEBUG_MAC80211(priv, "enter\n");
2826 mutex_lock(&priv->shrd->mutex); 2834 mutex_lock(&priv->shrd->mutex);
2827 iwl_scan_cancel_timeout(priv, priv->hw_roc_duration); 2835 iwl_scan_cancel_timeout(priv, priv->hw_roc_duration);
2828 iwlagn_disable_roc(priv); 2836 iwlagn_disable_roc(priv);
2829 mutex_unlock(&priv->shrd->mutex); 2837 mutex_unlock(&priv->shrd->mutex);
2838 IWL_DEBUG_MAC80211(priv, "leave\n");
2830 2839
2831 return 0; 2840 return 0;
2832} 2841}
2833 2842
2834static int iwl_mac_tx_sync(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 2843static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw,
2835 const u8 *bssid, enum ieee80211_tx_sync_type type) 2844 struct ieee80211_vif *vif,
2845 const u8 *bssid,
2846 enum ieee80211_tx_sync_type type)
2836{ 2847{
2837 struct iwl_priv *priv = hw->priv; 2848 struct iwl_priv *priv = hw->priv;
2838 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 2849 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -2840,6 +2851,7 @@ static int iwl_mac_tx_sync(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2840 int ret; 2851 int ret;
2841 u8 sta_id; 2852 u8 sta_id;
2842 2853
2854 IWL_DEBUG_MAC80211(priv, "enter\n");
2843 mutex_lock(&priv->shrd->mutex); 2855 mutex_lock(&priv->shrd->mutex);
2844 2856
2845 if (iwl_is_associated_ctx(ctx)) { 2857 if (iwl_is_associated_ctx(ctx)) {
@@ -2873,10 +2885,12 @@ static int iwl_mac_tx_sync(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2873 iwl_remove_station(priv, sta_id, bssid); 2885 iwl_remove_station(priv, sta_id, bssid);
2874 out: 2886 out:
2875 mutex_unlock(&priv->shrd->mutex); 2887 mutex_unlock(&priv->shrd->mutex);
2888 IWL_DEBUG_MAC80211(priv, "leave\n");
2889
2876 return ret; 2890 return ret;
2877} 2891}
2878 2892
2879static void iwl_mac_finish_tx_sync(struct ieee80211_hw *hw, 2893static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw,
2880 struct ieee80211_vif *vif, 2894 struct ieee80211_vif *vif,
2881 const u8 *bssid, 2895 const u8 *bssid,
2882 enum ieee80211_tx_sync_type type) 2896 enum ieee80211_tx_sync_type type)
@@ -2885,6 +2899,7 @@ static void iwl_mac_finish_tx_sync(struct ieee80211_hw *hw,
2885 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 2899 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
2886 struct iwl_rxon_context *ctx = vif_priv->ctx; 2900 struct iwl_rxon_context *ctx = vif_priv->ctx;
2887 2901
2902 IWL_DEBUG_MAC80211(priv, "enter\n");
2888 mutex_lock(&priv->shrd->mutex); 2903 mutex_lock(&priv->shrd->mutex);
2889 2904
2890 if (iwl_is_associated_ctx(ctx)) 2905 if (iwl_is_associated_ctx(ctx))
@@ -2895,6 +2910,7 @@ static void iwl_mac_finish_tx_sync(struct ieee80211_hw *hw,
2895 /* no need to commit */ 2910 /* no need to commit */
2896 out: 2911 out:
2897 mutex_unlock(&priv->shrd->mutex); 2912 mutex_unlock(&priv->shrd->mutex);
2913 IWL_DEBUG_MAC80211(priv, "leave\n");
2898} 2914}
2899 2915
2900/***************************************************************************** 2916/*****************************************************************************
@@ -3051,11 +3067,12 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
3051#endif 3067#endif
3052} 3068}
3053 3069
3054static void iwl_mac_rssi_callback(struct ieee80211_hw *hw, 3070static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
3055 enum ieee80211_rssi_event rssi_event) 3071 enum ieee80211_rssi_event rssi_event)
3056{ 3072{
3057 struct iwl_priv *priv = hw->priv; 3073 struct iwl_priv *priv = hw->priv;
3058 3074
3075 IWL_DEBUG_MAC80211(priv, "enter\n");
3059 mutex_lock(&priv->shrd->mutex); 3076 mutex_lock(&priv->shrd->mutex);
3060 3077
3061 if (priv->cfg->bt_params && 3078 if (priv->cfg->bt_params &&
@@ -3072,6 +3089,17 @@ static void iwl_mac_rssi_callback(struct ieee80211_hw *hw,
3072 } 3089 }
3073 3090
3074 mutex_unlock(&priv->shrd->mutex); 3091 mutex_unlock(&priv->shrd->mutex);
3092 IWL_DEBUG_MAC80211(priv, "leave\n");
3093}
3094
3095static int iwlagn_mac_set_tim(struct ieee80211_hw *hw,
3096 struct ieee80211_sta *sta, bool set)
3097{
3098 struct iwl_priv *priv = hw->priv;
3099
3100 queue_work(priv->shrd->workqueue, &priv->beacon_update);
3101
3102 return 0;
3075} 3103}
3076 3104
3077struct ieee80211_ops iwlagn_hw_ops = { 3105struct ieee80211_ops iwlagn_hw_ops = {
@@ -3082,31 +3110,32 @@ struct ieee80211_ops iwlagn_hw_ops = {
3082 .suspend = iwlagn_mac_suspend, 3110 .suspend = iwlagn_mac_suspend,
3083 .resume = iwlagn_mac_resume, 3111 .resume = iwlagn_mac_resume,
3084#endif 3112#endif
3085 .add_interface = iwl_mac_add_interface, 3113 .add_interface = iwlagn_mac_add_interface,
3086 .remove_interface = iwl_mac_remove_interface, 3114 .remove_interface = iwlagn_mac_remove_interface,
3087 .change_interface = iwl_mac_change_interface, 3115 .change_interface = iwlagn_mac_change_interface,
3088 .config = iwlagn_mac_config, 3116 .config = iwlagn_mac_config,
3089 .configure_filter = iwlagn_configure_filter, 3117 .configure_filter = iwlagn_configure_filter,
3090 .set_key = iwlagn_mac_set_key, 3118 .set_key = iwlagn_mac_set_key,
3091 .update_tkip_key = iwlagn_mac_update_tkip_key, 3119 .update_tkip_key = iwlagn_mac_update_tkip_key,
3092 .set_rekey_data = iwlagn_mac_set_rekey_data, 3120 .set_rekey_data = iwlagn_mac_set_rekey_data,
3093 .conf_tx = iwl_mac_conf_tx, 3121 .conf_tx = iwlagn_mac_conf_tx,
3094 .bss_info_changed = iwlagn_bss_info_changed, 3122 .bss_info_changed = iwlagn_bss_info_changed,
3095 .ampdu_action = iwlagn_mac_ampdu_action, 3123 .ampdu_action = iwlagn_mac_ampdu_action,
3096 .hw_scan = iwl_mac_hw_scan, 3124 .hw_scan = iwlagn_mac_hw_scan,
3097 .sta_notify = iwlagn_mac_sta_notify, 3125 .sta_notify = iwlagn_mac_sta_notify,
3098 .sta_add = iwlagn_mac_sta_add, 3126 .sta_add = iwlagn_mac_sta_add,
3099 .sta_remove = iwl_mac_sta_remove, 3127 .sta_remove = iwlagn_mac_sta_remove,
3100 .channel_switch = iwlagn_mac_channel_switch, 3128 .channel_switch = iwlagn_mac_channel_switch,
3101 .flush = iwlagn_mac_flush, 3129 .flush = iwlagn_mac_flush,
3102 .tx_last_beacon = iwl_mac_tx_last_beacon, 3130 .tx_last_beacon = iwlagn_mac_tx_last_beacon,
3103 .remain_on_channel = iwl_mac_remain_on_channel, 3131 .remain_on_channel = iwlagn_mac_remain_on_channel,
3104 .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel, 3132 .cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel,
3105 .rssi_callback = iwl_mac_rssi_callback, 3133 .rssi_callback = iwlagn_mac_rssi_callback,
3106 CFG80211_TESTMODE_CMD(iwl_testmode_cmd) 3134 CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd)
3107 CFG80211_TESTMODE_DUMP(iwl_testmode_dump) 3135 CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump)
3108 .tx_sync = iwl_mac_tx_sync, 3136 .tx_sync = iwlagn_mac_tx_sync,
3109 .finish_tx_sync = iwl_mac_finish_tx_sync, 3137 .finish_tx_sync = iwlagn_mac_finish_tx_sync,
3138 .set_tim = iwlagn_mac_set_tim,
3110}; 3139};
3111 3140
3112static u32 iwl_hw_detect(struct iwl_priv *priv) 3141static u32 iwl_hw_detect(struct iwl_priv *priv)
@@ -3182,7 +3211,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
3182 } 3211 }
3183 3212
3184 priv = hw->priv; 3213 priv = hw->priv;
3185 priv->bus = bus;
3186 priv->shrd = &priv->_shrd; 3214 priv->shrd = &priv->_shrd;
3187 bus->shrd = priv->shrd; 3215 bus->shrd = priv->shrd;
3188 priv->shrd->bus = bus; 3216 priv->shrd->bus = bus;
@@ -3196,7 +3224,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
3196 3224
3197 /* At this point both hw and priv are allocated. */ 3225 /* At this point both hw and priv are allocated. */
3198 3226
3199 SET_IEEE80211_DEV(hw, priv->bus->dev); 3227 SET_IEEE80211_DEV(hw, bus(priv)->dev);
3200 3228
3201 IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); 3229 IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
3202 priv->cfg = cfg; 3230 priv->cfg = cfg;
@@ -3350,7 +3378,7 @@ void __devexit iwl_remove(struct iwl_priv * priv)
3350 3378
3351 iwl_dbgfs_unregister(priv); 3379 iwl_dbgfs_unregister(priv);
3352 3380
3353 /* ieee80211_unregister_hw call wil cause iwl_mac_stop to 3381 /* ieee80211_unregister_hw call wil cause iwlagn_mac_stop to
3354 * to be called and iwl_down since we are removing the device 3382 * to be called and iwl_down since we are removing the device
3355 * we need to set STATUS_EXIT_PENDING bit. 3383 * we need to set STATUS_EXIT_PENDING bit.
3356 */ 3384 */
@@ -3376,7 +3404,7 @@ void __devexit iwl_remove(struct iwl_priv * priv)
3376 /*netif_stop_queue(dev); */ 3404 /*netif_stop_queue(dev); */
3377 flush_workqueue(priv->shrd->workqueue); 3405 flush_workqueue(priv->shrd->workqueue);
3378 3406
3379 /* ieee80211_unregister_hw calls iwl_mac_stop, which flushes 3407 /* ieee80211_unregister_hw calls iwlagn_mac_stop, which flushes
3380 * priv->shrd->workqueue... so we can't take down the workqueue 3408 * priv->shrd->workqueue... so we can't take down the workqueue
3381 * until now... */ 3409 * until now... */
3382 destroy_workqueue(priv->shrd->workqueue); 3410 destroy_workqueue(priv->shrd->workqueue);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 2a297d1e6bc7..5b936ec1a541 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -152,10 +152,6 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
152void iwlagn_post_scan(struct iwl_priv *priv); 152void iwlagn_post_scan(struct iwl_priv *priv);
153void iwlagn_disable_roc(struct iwl_priv *priv); 153void iwlagn_disable_roc(struct iwl_priv *priv);
154 154
155/* station mgmt */
156int iwlagn_manage_ibss_station(struct iwl_priv *priv,
157 struct ieee80211_vif *vif, bool add);
158
159/* bt coex */ 155/* bt coex */
160void iwlagn_send_advance_bt_config(struct iwl_priv *priv); 156void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
161int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, 157int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
@@ -175,7 +171,120 @@ static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
175static inline const char *iwl_get_agg_tx_fail_reason(u16 status) { return ""; } 171static inline const char *iwl_get_agg_tx_fail_reason(u16 status) { return ""; }
176#endif 172#endif
177 173
174
178/* station management */ 175/* station management */
176int iwlagn_manage_ibss_station(struct iwl_priv *priv,
177 struct ieee80211_vif *vif, bool add);
178#define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */
179#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */
180#define IWL_STA_UCODE_INPROGRESS BIT(2) /* ucode entry is in process of
181 being activated */
182#define IWL_STA_LOCAL BIT(3) /* station state not directed by mac80211;
183 (this is for the IBSS BSSID stations) */
184#define IWL_STA_BCAST BIT(4) /* this station is the special bcast station */
185
186
187void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
188void iwl_clear_ucode_stations(struct iwl_priv *priv,
189 struct iwl_rxon_context *ctx);
190void iwl_dealloc_bcast_stations(struct iwl_priv *priv);
191int iwl_get_free_ucode_key_offset(struct iwl_priv *priv);
192int iwl_send_add_sta(struct iwl_priv *priv,
193 struct iwl_addsta_cmd *sta, u8 flags);
194int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
195 const u8 *addr, bool is_ap,
196 struct ieee80211_sta *sta, u8 *sta_id_r);
197int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
198 const u8 *addr);
199int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
200 struct ieee80211_sta *sta);
201
202u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
203 const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
204
205void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
206 u8 sta_id, struct iwl_link_quality_cmd *link_cmd);
207int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
208 struct iwl_link_quality_cmd *lq, u8 flags, bool init);
209void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
210int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
211 struct iwl_device_cmd *cmd);
212
213
214/**
215 * iwl_clear_driver_stations - clear knowledge of all stations from driver
216 * @priv: iwl priv struct
217 *
218 * This is called during iwl_down() to make sure that in the case
219 * we're coming there from a hardware restart mac80211 will be
220 * able to reconfigure stations -- if we're getting there in the
221 * normal down flow then the stations will already be cleared.
222 */
223static inline void iwl_clear_driver_stations(struct iwl_priv *priv)
224{
225 unsigned long flags;
226 struct iwl_rxon_context *ctx;
227
228 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
229 memset(priv->stations, 0, sizeof(priv->stations));
230 priv->num_stations = 0;
231
232 priv->ucode_key_table = 0;
233
234 for_each_context(priv, ctx) {
235 /*
236 * Remove all key information that is not stored as part
237 * of station information since mac80211 may not have had
238 * a chance to remove all the keys. When device is
239 * reconfigured by mac80211 after an error all keys will
240 * be reconfigured.
241 */
242 memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys));
243 ctx->key_mapping_keys = 0;
244 }
245
246 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
247}
248
249static inline int iwl_sta_id(struct ieee80211_sta *sta)
250{
251 if (WARN_ON(!sta))
252 return IWL_INVALID_STATION;
253
254 return ((struct iwl_station_priv *)sta->drv_priv)->sta_id;
255}
256
257/**
258 * iwl_sta_id_or_broadcast - return sta_id or broadcast sta
259 * @priv: iwl priv
260 * @context: the current context
261 * @sta: mac80211 station
262 *
263 * In certain circumstances mac80211 passes a station pointer
264 * that may be %NULL, for example during TX or key setup. In
265 * that case, we need to use the broadcast station, so this
266 * inline wraps that pattern.
267 */
268static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv,
269 struct iwl_rxon_context *context,
270 struct ieee80211_sta *sta)
271{
272 int sta_id;
273
274 if (!sta)
275 return context->bcast_sta_id;
276
277 sta_id = iwl_sta_id(sta);
278
279 /*
280 * mac80211 should not be passing a partially
281 * initialised station!
282 */
283 WARN_ON(sta_id == IWL_INVALID_STATION);
284
285 return sta_id;
286}
287
179int iwlagn_alloc_bcast_station(struct iwl_priv *priv, 288int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
180 struct iwl_rxon_context *ctx); 289 struct iwl_rxon_context *ctx);
181int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 290int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
@@ -252,20 +361,22 @@ extern int iwlagn_init_alive_start(struct iwl_priv *priv);
252extern int iwl_alive_start(struct iwl_priv *priv); 361extern int iwl_alive_start(struct iwl_priv *priv);
253/* svtool */ 362/* svtool */
254#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL 363#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
255extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len); 364extern int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data,
256extern int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, 365 int len);
257 struct netlink_callback *cb, 366extern int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw,
258 void *data, int len); 367 struct sk_buff *skb,
368 struct netlink_callback *cb,
369 void *data, int len);
259extern void iwl_testmode_init(struct iwl_priv *priv); 370extern void iwl_testmode_init(struct iwl_priv *priv);
260extern void iwl_testmode_cleanup(struct iwl_priv *priv); 371extern void iwl_testmode_cleanup(struct iwl_priv *priv);
261#else 372#else
262static inline 373static inline
263int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) 374int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
264{ 375{
265 return -ENOSYS; 376 return -ENOSYS;
266} 377}
267static inline 378static inline
268int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, 379int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
269 struct netlink_callback *cb, 380 struct netlink_callback *cb,
270 void *data, int len) 381 void *data, int len)
271{ 382{
diff --git a/drivers/net/wireless/iwlwifi/iwl-cfg.h b/drivers/net/wireless/iwlwifi/iwl-cfg.h
index d4f317cfe8b5..2a2dc4597ba1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-cfg.h
+++ b/drivers/net/wireless/iwlwifi/iwl-cfg.h
@@ -79,6 +79,7 @@ extern struct iwl_cfg iwl6005_2agn_cfg;
79extern struct iwl_cfg iwl6005_2abg_cfg; 79extern struct iwl_cfg iwl6005_2abg_cfg;
80extern struct iwl_cfg iwl6005_2bg_cfg; 80extern struct iwl_cfg iwl6005_2bg_cfg;
81extern struct iwl_cfg iwl6005_2agn_sff_cfg; 81extern struct iwl_cfg iwl6005_2agn_sff_cfg;
82extern struct iwl_cfg iwl6005_2agn_d_cfg;
82extern struct iwl_cfg iwl1030_bgn_cfg; 83extern struct iwl_cfg iwl1030_bgn_cfg;
83extern struct iwl_cfg iwl1030_bg_cfg; 84extern struct iwl_cfg iwl1030_bg_cfg;
84extern struct iwl_cfg iwl6030_2agn_cfg; 85extern struct iwl_cfg iwl6030_2agn_cfg;
@@ -109,6 +110,7 @@ extern struct iwl_cfg iwl6035_2abg_cfg;
109extern struct iwl_cfg iwl6035_2bg_cfg; 110extern struct iwl_cfg iwl6035_2bg_cfg;
110extern struct iwl_cfg iwl105_bg_cfg; 111extern struct iwl_cfg iwl105_bg_cfg;
111extern struct iwl_cfg iwl105_bgn_cfg; 112extern struct iwl_cfg iwl105_bgn_cfg;
113extern struct iwl_cfg iwl105_bgn_d_cfg;
112extern struct iwl_cfg iwl135_bg_cfg; 114extern struct iwl_cfg iwl135_bg_cfg;
113extern struct iwl_cfg iwl135_bgn_cfg; 115extern struct iwl_cfg iwl135_bgn_cfg;
114 116
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 64593aa03ad6..69d5f85d11e2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -89,6 +89,7 @@ struct iwl_priv;
89enum { 89enum {
90 REPLY_ALIVE = 0x1, 90 REPLY_ALIVE = 0x1,
91 REPLY_ERROR = 0x2, 91 REPLY_ERROR = 0x2,
92 REPLY_ECHO = 0x3, /* test command */
92 93
93 /* RXON and QOS commands */ 94 /* RXON and QOS commands */
94 REPLY_RXON = 0x10, 95 REPLY_RXON = 0x10,
@@ -3215,6 +3216,16 @@ enum iwl_ucode_calib_cfg {
3215 IWL_CALIB_CFG_RX_IQ_IDX | \ 3216 IWL_CALIB_CFG_RX_IQ_IDX | \
3216 IWL_CALIB_CFG_CRYSTAL_IDX) 3217 IWL_CALIB_CFG_CRYSTAL_IDX)
3217 3218
3219#define IWL_CALIB_RT_CFG_ALL cpu_to_le32(IWL_CALIB_CFG_RX_BB_IDX | \
3220 IWL_CALIB_CFG_DC_IDX | \
3221 IWL_CALIB_CFG_LO_IDX | \
3222 IWL_CALIB_CFG_TX_IQ_IDX | \
3223 IWL_CALIB_CFG_RX_IQ_IDX | \
3224 IWL_CALIB_CFG_TEMPERATURE_IDX | \
3225 IWL_CALIB_CFG_PAPD_IDX | \
3226 IWL_CALIB_CFG_TX_PWR_IDX | \
3227 IWL_CALIB_CFG_CRYSTAL_IDX)
3228
3218#define IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK cpu_to_le32(BIT(0)) 3229#define IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK cpu_to_le32(BIT(0))
3219 3230
3220struct iwl_calib_cfg_elmnt_s { 3231struct iwl_calib_cfg_elmnt_s {
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 0725603dbf1d..b247a56d5135 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -34,14 +34,11 @@
34#include <net/mac80211.h> 34#include <net/mac80211.h>
35 35
36#include "iwl-eeprom.h" 36#include "iwl-eeprom.h"
37#include "iwl-dev.h" /* FIXME: remove */
38#include "iwl-debug.h" 37#include "iwl-debug.h"
39#include "iwl-core.h" 38#include "iwl-core.h"
40#include "iwl-io.h" 39#include "iwl-io.h"
41#include "iwl-power.h" 40#include "iwl-power.h"
42#include "iwl-sta.h"
43#include "iwl-agn.h" 41#include "iwl-agn.h"
44#include "iwl-helpers.h"
45#include "iwl-shared.h" 42#include "iwl-shared.h"
46#include "iwl-agn.h" 43#include "iwl-agn.h"
47#include "iwl-trans.h" 44#include "iwl-trans.h"
@@ -211,7 +208,7 @@ int iwl_init_geos(struct iwl_priv *priv)
211 if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && 208 if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
212 priv->cfg->sku & EEPROM_SKU_CAP_BAND_52GHZ) { 209 priv->cfg->sku & EEPROM_SKU_CAP_BAND_52GHZ) {
213 char buf[32]; 210 char buf[32];
214 bus_get_hw_id(priv->bus, buf, sizeof(buf)); 211 bus_get_hw_id(bus(priv), buf, sizeof(buf));
215 IWL_INFO(priv, "Incorrectly detected BG card as ABG. " 212 IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
216 "Please send your %s to maintainer.\n", buf); 213 "Please send your %s to maintainer.\n", buf);
217 priv->cfg->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; 214 priv->cfg->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
@@ -323,7 +320,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
323 u16 beacon_int; 320 u16 beacon_int;
324 struct ieee80211_vif *vif = ctx->vif; 321 struct ieee80211_vif *vif = ctx->vif;
325 322
326 conf = ieee80211_get_hw_conf(priv->hw); 323 conf = &priv->hw->conf;
327 324
328 lockdep_assert_held(&priv->shrd->mutex); 325 lockdep_assert_held(&priv->shrd->mutex);
329 326
@@ -804,7 +801,7 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
804{ 801{
805 /* 802 /*
806 * MULTI-FIXME 803 * MULTI-FIXME
807 * See iwl_mac_channel_switch. 804 * See iwlagn_mac_channel_switch.
808 */ 805 */
809 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 806 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
810 807
@@ -979,7 +976,7 @@ int iwl_apm_init(struct iwl_priv *priv)
979 iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, 976 iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG,
980 CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); 977 CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
981 978
982 bus_apm_config(priv->bus); 979 bus_apm_config(bus(priv));
983 980
984 /* Configure analog phase-lock-loop before activating to D0A */ 981 /* Configure analog phase-lock-loop before activating to D0A */
985 if (priv->cfg->base_params->pll_cfg_val) 982 if (priv->cfg->base_params->pll_cfg_val)
@@ -1123,7 +1120,7 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
1123 &statistics_cmd); 1120 &statistics_cmd);
1124} 1121}
1125 1122
1126int iwl_mac_conf_tx(struct ieee80211_hw *hw, 1123int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
1127 struct ieee80211_vif *vif, u16 queue, 1124 struct ieee80211_vif *vif, u16 queue,
1128 const struct ieee80211_tx_queue_params *params) 1125 const struct ieee80211_tx_queue_params *params)
1129{ 1126{
@@ -1170,7 +1167,7 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw,
1170 return 0; 1167 return 0;
1171} 1168}
1172 1169
1173int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw) 1170int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw)
1174{ 1171{
1175 struct iwl_priv *priv = hw->priv; 1172 struct iwl_priv *priv = hw->priv;
1176 1173
@@ -1223,7 +1220,8 @@ static int iwl_setup_interface(struct iwl_priv *priv,
1223 return 0; 1220 return 0;
1224} 1221}
1225 1222
1226int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 1223int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
1224 struct ieee80211_vif *vif)
1227{ 1225{
1228 struct iwl_priv *priv = hw->priv; 1226 struct iwl_priv *priv = hw->priv;
1229 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 1227 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -1319,7 +1317,7 @@ static void iwl_teardown_interface(struct iwl_priv *priv,
1319 priv->bt_traffic_load = priv->last_bt_traffic_load; 1317 priv->bt_traffic_load = priv->last_bt_traffic_load;
1320} 1318}
1321 1319
1322void iwl_mac_remove_interface(struct ieee80211_hw *hw, 1320void iwlagn_mac_remove_interface(struct ieee80211_hw *hw,
1323 struct ieee80211_vif *vif) 1321 struct ieee80211_vif *vif)
1324{ 1322{
1325 struct iwl_priv *priv = hw->priv; 1323 struct iwl_priv *priv = hw->priv;
@@ -1651,8 +1649,9 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
1651 return 0; 1649 return 0;
1652} 1650}
1653 1651
1654int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1652int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
1655 enum nl80211_iftype newtype, bool newp2p) 1653 struct ieee80211_vif *vif,
1654 enum nl80211_iftype newtype, bool newp2p)
1656{ 1655{
1657 struct iwl_priv *priv = hw->priv; 1656 struct iwl_priv *priv = hw->priv;
1658 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); 1657 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
@@ -1662,6 +1661,8 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1662 u32 interface_modes; 1661 u32 interface_modes;
1663 int err; 1662 int err;
1664 1663
1664 IWL_DEBUG_MAC80211(priv, "enter\n");
1665
1665 newtype = ieee80211_iftype_p2p(newtype, newp2p); 1666 newtype = ieee80211_iftype_p2p(newtype, newp2p);
1666 1667
1667 mutex_lock(&priv->shrd->mutex); 1668 mutex_lock(&priv->shrd->mutex);
@@ -1729,13 +1730,42 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1729 1730
1730 out: 1731 out:
1731 mutex_unlock(&priv->shrd->mutex); 1732 mutex_unlock(&priv->shrd->mutex);
1733 IWL_DEBUG_MAC80211(priv, "leave\n");
1734
1732 return err; 1735 return err;
1733} 1736}
1734 1737
1738int iwl_cmd_echo_test(struct iwl_priv *priv)
1739{
1740 int ret;
1741 struct iwl_host_cmd cmd = {
1742 .id = REPLY_ECHO,
1743 .flags = CMD_SYNC,
1744 };
1745
1746 ret = iwl_trans_send_cmd(trans(priv), &cmd);
1747 if (ret)
1748 IWL_ERR(priv, "echo testing fail: 0X%x\n", ret);
1749 else
1750 IWL_DEBUG_INFO(priv, "echo testing pass\n");
1751 return ret;
1752}
1753
1735static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq) 1754static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq)
1736{ 1755{
1737 if (iwl_trans_check_stuck_queue(trans(priv), txq)) { 1756 if (iwl_trans_check_stuck_queue(trans(priv), txq)) {
1738 int ret = iwl_force_reset(priv, IWL_FW_RESET, false); 1757 int ret;
1758 if (txq == priv->shrd->cmd_queue) {
1759 /*
1760 * validate command queue still working
1761 * by sending "ECHO" command
1762 */
1763 if (!iwl_cmd_echo_test(priv))
1764 return 0;
1765 else
1766 IWL_DEBUG_HC(priv, "echo testing fail\n");
1767 }
1768 ret = iwl_force_reset(priv, IWL_FW_RESET, false);
1739 return (ret == -EAGAIN) ? 0 : 1; 1769 return (ret == -EAGAIN) ? 0 : 1;
1740 } 1770 }
1741 return 0; 1771 return 0;
@@ -1760,6 +1790,9 @@ void iwl_bg_watchdog(unsigned long data)
1760 if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) 1790 if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
1761 return; 1791 return;
1762 1792
1793 if (iwl_is_rfkill(priv->shrd))
1794 return;
1795
1763 timeout = priv->cfg->base_params->wd_timeout; 1796 timeout = priv->cfg->base_params->wd_timeout;
1764 if (timeout == 0) 1797 if (timeout == 0)
1765 return; 1798 return;
@@ -1794,6 +1827,28 @@ void iwl_setup_watchdog(struct iwl_priv *priv)
1794 del_timer(&priv->watchdog); 1827 del_timer(&priv->watchdog);
1795} 1828}
1796 1829
1830/**
1831 * iwl_beacon_time_mask_low - mask of lower 32 bit of beacon time
1832 * @priv -- pointer to iwl_priv data structure
1833 * @tsf_bits -- number of bits need to shift for masking)
1834 */
1835static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv,
1836 u16 tsf_bits)
1837{
1838 return (1 << tsf_bits) - 1;
1839}
1840
1841/**
1842 * iwl_beacon_time_mask_high - mask of higher 32 bit of beacon time
1843 * @priv -- pointer to iwl_priv data structure
1844 * @tsf_bits -- number of bits need to shift for masking)
1845 */
1846static inline u32 iwl_beacon_time_mask_high(struct iwl_priv *priv,
1847 u16 tsf_bits)
1848{
1849 return ((1 << (32 - tsf_bits)) - 1) << tsf_bits;
1850}
1851
1797/* 1852/*
1798 * extended beacon time format 1853 * extended beacon time format
1799 * time in usec will be changed into a 32-bit value in extended:internal format 1854 * time in usec will be changed into a 32-bit value in extended:internal format
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index db50b650756c..137da3380704 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -64,6 +64,7 @@
64#define __iwl_core_h__ 64#define __iwl_core_h__
65 65
66#include "iwl-dev.h" 66#include "iwl-dev.h"
67#include "iwl-io.h"
67 68
68/************************ 69/************************
69 * forward declarations * 70 * forward declarations *
@@ -236,10 +237,10 @@ struct iwl_cfg {
236 * L i b * 237 * L i b *
237 ***************************/ 238 ***************************/
238 239
239int iwl_mac_conf_tx(struct ieee80211_hw *hw, 240int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
240 struct ieee80211_vif *vif, u16 queue, 241 struct ieee80211_vif *vif, u16 queue,
241 const struct ieee80211_tx_queue_params *params); 242 const struct ieee80211_tx_queue_params *params);
242int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw); 243int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw);
243void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 244void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
244 int hw_decrypt); 245 int hw_decrypt);
245int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); 246int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
@@ -259,13 +260,14 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
259void iwl_connection_init_rx_config(struct iwl_priv *priv, 260void iwl_connection_init_rx_config(struct iwl_priv *priv,
260 struct iwl_rxon_context *ctx); 261 struct iwl_rxon_context *ctx);
261void iwl_set_rate(struct iwl_priv *priv); 262void iwl_set_rate(struct iwl_priv *priv);
262int iwl_mac_add_interface(struct ieee80211_hw *hw, 263int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
263 struct ieee80211_vif *vif); 264 struct ieee80211_vif *vif);
264void iwl_mac_remove_interface(struct ieee80211_hw *hw, 265void iwlagn_mac_remove_interface(struct ieee80211_hw *hw,
265 struct ieee80211_vif *vif); 266 struct ieee80211_vif *vif);
266int iwl_mac_change_interface(struct ieee80211_hw *hw, 267int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
267 struct ieee80211_vif *vif, 268 struct ieee80211_vif *vif,
268 enum nl80211_iftype newtype, bool newp2p); 269 enum nl80211_iftype newtype, bool newp2p);
270int iwl_cmd_echo_test(struct iwl_priv *priv);
269#ifdef CONFIG_IWLWIFI_DEBUGFS 271#ifdef CONFIG_IWLWIFI_DEBUGFS
270int iwl_alloc_traffic_mem(struct iwl_priv *priv); 272int iwl_alloc_traffic_mem(struct iwl_priv *priv);
271void iwl_free_traffic_mem(struct iwl_priv *priv); 273void iwl_free_traffic_mem(struct iwl_priv *priv);
@@ -321,7 +323,7 @@ void iwl_init_scan_params(struct iwl_priv *priv);
321int iwl_scan_cancel(struct iwl_priv *priv); 323int iwl_scan_cancel(struct iwl_priv *priv);
322void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); 324void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
323void iwl_force_scan_end(struct iwl_priv *priv); 325void iwl_force_scan_end(struct iwl_priv *priv);
324int iwl_mac_hw_scan(struct ieee80211_hw *hw, 326int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
325 struct ieee80211_vif *vif, 327 struct ieee80211_vif *vif,
326 struct cfg80211_scan_request *req); 328 struct cfg80211_scan_request *req);
327void iwl_internal_short_hw_scan(struct iwl_priv *priv); 329void iwl_internal_short_hw_scan(struct iwl_priv *priv);
@@ -381,6 +383,12 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
381 priv->cfg->bt_params->advanced_bt_coexist; 383 priv->cfg->bt_params->advanced_bt_coexist;
382} 384}
383 385
386static inline void iwl_enable_rfkill_int(struct iwl_priv *priv)
387{
388 IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n");
389 iwl_write32(bus(priv), CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
390}
391
384extern bool bt_siso_mode; 392extern bool bt_siso_mode;
385 393
386#endif /* __iwl_core_h__ */ 394#endif /* __iwl_core_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 7014f4124484..69a77e24d229 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -105,10 +105,12 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
105 * 105 *
106 * The active debug levels can be accessed via files 106 * The active debug levels can be accessed via files
107 * 107 *
108 * /sys/module/iwlagn/parameters/debug{50} 108 * /sys/module/iwlwifi/parameters/debug
109 * /sys/class/net/wlan0/device/debug_level
110 *
111 * when CONFIG_IWLWIFI_DEBUG=y. 109 * when CONFIG_IWLWIFI_DEBUG=y.
110 *
111 * /sys/kernel/debug/phy0/iwlwifi/debug/debug_level
112 * when CONFIG_IWLWIFI_DEBUGFS=y.
113 *
112 */ 114 */
113 115
114/* 0x0000000F - 0x00000001 */ 116/* 0x0000000F - 0x00000001 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 6d49dfbee964..a1670e3f8bfa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -349,7 +349,6 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
349 struct iwl_priv *priv = file->private_data; 349 struct iwl_priv *priv = file->private_data;
350 struct iwl_station_entry *station; 350 struct iwl_station_entry *station;
351 struct iwl_tid_data *tid_data; 351 struct iwl_tid_data *tid_data;
352 int max_sta = hw_params(priv).max_stations;
353 char *buf; 352 char *buf;
354 int i, j, pos = 0; 353 int i, j, pos = 0;
355 ssize_t ret; 354 ssize_t ret;
@@ -363,7 +362,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
363 pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n", 362 pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
364 priv->num_stations); 363 priv->num_stations);
365 364
366 for (i = 0; i < max_sta; i++) { 365 for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
367 station = &priv->stations[i]; 366 station = &priv->stations[i];
368 if (!station->used) 367 if (!station->used)
369 continue; 368 continue;
@@ -2444,6 +2443,23 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
2444 return count; 2443 return count;
2445} 2444}
2446 2445
2446static ssize_t iwl_dbgfs_echo_test_write(struct file *file,
2447 const char __user *user_buf,
2448 size_t count, loff_t *ppos)
2449{
2450 struct iwl_priv *priv = file->private_data;
2451 char buf[8];
2452 int buf_size;
2453
2454 memset(buf, 0, sizeof(buf));
2455 buf_size = min(count, sizeof(buf) - 1);
2456 if (copy_from_user(buf, user_buf, buf_size))
2457 return -EFAULT;
2458
2459 iwl_cmd_echo_test(priv);
2460 return count;
2461}
2462
2447DEBUGFS_READ_FILE_OPS(rx_statistics); 2463DEBUGFS_READ_FILE_OPS(rx_statistics);
2448DEBUGFS_READ_FILE_OPS(tx_statistics); 2464DEBUGFS_READ_FILE_OPS(tx_statistics);
2449DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 2465DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -2467,6 +2483,7 @@ DEBUGFS_WRITE_FILE_OPS(wd_timeout);
2467DEBUGFS_READ_FILE_OPS(bt_traffic); 2483DEBUGFS_READ_FILE_OPS(bt_traffic);
2468DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); 2484DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
2469DEBUGFS_READ_FILE_OPS(reply_tx_error); 2485DEBUGFS_READ_FILE_OPS(reply_tx_error);
2486DEBUGFS_WRITE_FILE_OPS(echo_test);
2470 2487
2471#ifdef CONFIG_IWLWIFI_DEBUG 2488#ifdef CONFIG_IWLWIFI_DEBUG
2472static ssize_t iwl_dbgfs_debug_level_read(struct file *file, 2489static ssize_t iwl_dbgfs_debug_level_read(struct file *file,
@@ -2575,6 +2592,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
2575 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); 2592 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
2576 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); 2593 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
2577 DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); 2594 DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
2595 DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR);
2578 if (iwl_advanced_bt_coexist(priv)) 2596 if (iwl_advanced_bt_coexist(priv))
2579 DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); 2597 DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
2580#ifdef CONFIG_IWLWIFI_DEBUG 2598#ifdef CONFIG_IWLWIFI_DEBUG
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 257aa9a407ca..6c00a447963d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -894,9 +894,6 @@ struct iwl_priv {
894 u8 scan_tx_ant[IEEE80211_NUM_BANDS]; 894 u8 scan_tx_ant[IEEE80211_NUM_BANDS];
895 u8 mgmt_tx_ant; 895 u8 mgmt_tx_ant;
896 896
897 /*TODO: remove these pointers - use bus(priv) instead */
898 struct iwl_bus *bus; /* bus specific data */
899
900 /* max number of station keys */ 897 /* max number of station keys */
901 u8 sta_key_max_num; 898 u8 sta_key_max_num;
902 899
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
deleted file mode 100644
index 968fc66e3506..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ /dev/null
@@ -1,72 +0,0 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 *
5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 *
21 * The full GNU General Public License is included in this distribution in the
22 * file called LICENSE.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#ifndef __iwl_helpers_h__
31#define __iwl_helpers_h__
32
33#include <linux/ctype.h>
34#include <net/mac80211.h>
35
36#include "iwl-io.h"
37
38static inline struct ieee80211_conf *ieee80211_get_hw_conf(
39 struct ieee80211_hw *hw)
40{
41 return &hw->conf;
42}
43
44static inline void iwl_enable_rfkill_int(struct iwl_priv *priv)
45{
46 IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n");
47 iwl_write32(bus(priv), CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
48}
49
50/**
51 * iwl_beacon_time_mask_low - mask of lower 32 bit of beacon time
52 * @priv -- pointer to iwl_priv data structure
53 * @tsf_bits -- number of bits need to shift for masking)
54 */
55static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv,
56 u16 tsf_bits)
57{
58 return (1 << tsf_bits) - 1;
59}
60
61/**
62 * iwl_beacon_time_mask_high - mask of higher 32 bit of beacon time
63 * @priv -- pointer to iwl_priv data structure
64 * @tsf_bits -- number of bits need to shift for masking)
65 */
66static inline u32 iwl_beacon_time_mask_high(struct iwl_priv *priv,
67 u16 tsf_bits)
68{
69 return ((1 << (32 - tsf_bits)) - 1) << tsf_bits;
70}
71
72#endif /* __iwl_helpers_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index f149165e8010..eb541735296c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -202,8 +202,7 @@ void iwl_leds_init(struct iwl_priv *priv)
202 break; 202 break;
203 } 203 }
204 204
205 ret = led_classdev_register(priv->bus->dev, 205 ret = led_classdev_register(bus(priv)->dev, &priv->led);
206 &priv->led);
207 if (ret) { 206 if (ret) {
208 kfree(priv->led.name); 207 kfree(priv->led.name);
209 return; 208 return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c
index 1d7bb7423f94..3b6cc66365e5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-pci.c
+++ b/drivers/net/wireless/iwlwifi/iwl-pci.c
@@ -254,6 +254,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
254 {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, 254 {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)},
255 {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)}, 255 {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)},
256 {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)}, 256 {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)},
257 {IWL_PCI_DEVICE(0x0082, 0x1341, iwl6005_2agn_d_cfg)},
257 258
258/* 6x30 Series */ 259/* 6x30 Series */
259 {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, 260 {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)},
@@ -354,6 +355,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
354 {IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)}, 355 {IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)},
355 {IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)}, 356 {IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)},
356 {IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)}, 357 {IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)},
358 {IWL_PCI_DEVICE(0x0894, 0x0822, iwl105_bgn_d_cfg)},
357 359
358/* 135 Series */ 360/* 135 Series */
359 {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)}, 361 {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 62cd781192b0..4eaab204322d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -436,7 +436,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
436/* initialize to default */ 436/* initialize to default */
437void iwl_power_initialize(struct iwl_priv *priv) 437void iwl_power_initialize(struct iwl_priv *priv)
438{ 438{
439 priv->power_data.bus_pm = bus_get_pm_support(priv->bus); 439 priv->power_data.bus_pm = bus_get_pm_support(bus(priv));
440 440
441 priv->power_data.debug_sleep_level_override = -1; 441 priv->power_data.debug_sleep_level_override = -1;
442 442
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index c5c95d5319b1..e5d727f537d0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -33,9 +33,7 @@
33#include "iwl-eeprom.h" 33#include "iwl-eeprom.h"
34#include "iwl-dev.h" 34#include "iwl-dev.h"
35#include "iwl-core.h" 35#include "iwl-core.h"
36#include "iwl-sta.h"
37#include "iwl-io.h" 36#include "iwl-io.h"
38#include "iwl-helpers.h"
39#include "iwl-agn.h" 37#include "iwl-agn.h"
40#include "iwl-trans.h" 38#include "iwl-trans.h"
41 39
@@ -940,7 +938,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
940 return 0; 938 return 0;
941} 939}
942 940
943int iwl_mac_hw_scan(struct ieee80211_hw *hw, 941int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
944 struct ieee80211_vif *vif, 942 struct ieee80211_vif *vif,
945 struct cfg80211_scan_request *req) 943 struct cfg80211_scan_request *req)
946{ 944{
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h
index 3a24b477b8fb..1f7a93c67c45 100644
--- a/drivers/net/wireless/iwlwifi/iwl-shared.h
+++ b/drivers/net/wireless/iwlwifi/iwl-shared.h
@@ -165,7 +165,6 @@ struct iwl_mod_params {
165 * @rx_chains_num: Number of RX chains 165 * @rx_chains_num: Number of RX chains
166 * @valid_tx_ant: usable antennas for TX 166 * @valid_tx_ant: usable antennas for TX
167 * @valid_rx_ant: usable antennas for RX 167 * @valid_rx_ant: usable antennas for RX
168 * @max_stations: the maximal number of stations
169 * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX) 168 * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX)
170 * @sku: sku read from EEPROM 169 * @sku: sku read from EEPROM
171 * @rx_page_order: Rx buffer page order 170 * @rx_page_order: Rx buffer page order
@@ -186,7 +185,6 @@ struct iwl_hw_params {
186 u8 rx_chains_num; 185 u8 rx_chains_num;
187 u8 valid_tx_ant; 186 u8 valid_tx_ant;
188 u8 valid_rx_ant; 187 u8 valid_rx_ant;
189 u8 max_stations;
190 u8 ht40_channel; 188 u8 ht40_channel;
191 bool shadow_reg_enable; 189 bool shadow_reg_enable;
192 u16 sku; 190 u16 sku;
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
deleted file mode 100644
index 580a4d702ff3..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ /dev/null
@@ -1,835 +0,0 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 *
5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 *
21 * The full GNU General Public License is included in this distribution in the
22 * file called LICENSE.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#include <net/mac80211.h>
31#include <linux/etherdevice.h>
32#include <linux/sched.h>
33#include <linux/lockdep.h>
34
35#include "iwl-dev.h"
36#include "iwl-core.h"
37#include "iwl-sta.h"
38#include "iwl-trans.h"
39#include "iwl-agn.h"
40
41/* priv->shrd->sta_lock must be held */
42static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
43{
44
45 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
46 IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u addr %pM\n",
47 sta_id, priv->stations[sta_id].sta.sta.addr);
48
49 if (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) {
50 IWL_DEBUG_ASSOC(priv,
51 "STA id %u addr %pM already present in uCode (according to driver)\n",
52 sta_id, priv->stations[sta_id].sta.sta.addr);
53 } else {
54 priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
55 IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n",
56 sta_id, priv->stations[sta_id].sta.sta.addr);
57 }
58}
59
60static int iwl_process_add_sta_resp(struct iwl_priv *priv,
61 struct iwl_addsta_cmd *addsta,
62 struct iwl_rx_packet *pkt)
63{
64 u8 sta_id = addsta->sta.sta_id;
65 unsigned long flags;
66 int ret = -EIO;
67
68 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
69 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
70 pkt->hdr.flags);
71 return ret;
72 }
73
74 IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
75 sta_id);
76
77 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
78
79 switch (pkt->u.add_sta.status) {
80 case ADD_STA_SUCCESS_MSK:
81 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
82 iwl_sta_ucode_activate(priv, sta_id);
83 ret = 0;
84 break;
85 case ADD_STA_NO_ROOM_IN_TABLE:
86 IWL_ERR(priv, "Adding station %d failed, no room in table.\n",
87 sta_id);
88 break;
89 case ADD_STA_NO_BLOCK_ACK_RESOURCE:
90 IWL_ERR(priv, "Adding station %d failed, no block ack resource.\n",
91 sta_id);
92 break;
93 case ADD_STA_MODIFY_NON_EXIST_STA:
94 IWL_ERR(priv, "Attempting to modify non-existing station %d\n",
95 sta_id);
96 break;
97 default:
98 IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
99 pkt->u.add_sta.status);
100 break;
101 }
102
103 IWL_DEBUG_INFO(priv, "%s station id %u addr %pM\n",
104 priv->stations[sta_id].sta.mode ==
105 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
106 sta_id, priv->stations[sta_id].sta.sta.addr);
107
108 /*
109 * XXX: The MAC address in the command buffer is often changed from
110 * the original sent to the device. That is, the MAC address
111 * written to the command buffer often is not the same MAC address
112 * read from the command buffer when the command returns. This
113 * issue has not yet been resolved and this debugging is left to
114 * observe the problem.
115 */
116 IWL_DEBUG_INFO(priv, "%s station according to cmd buffer %pM\n",
117 priv->stations[sta_id].sta.mode ==
118 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
119 addsta->sta.addr);
120 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
121
122 return ret;
123}
124
125int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
126 struct iwl_device_cmd *cmd)
127{
128 struct iwl_rx_packet *pkt = rxb_addr(rxb);
129 struct iwl_addsta_cmd *addsta =
130 (struct iwl_addsta_cmd *) cmd->payload;
131
132 return iwl_process_add_sta_resp(priv, addsta, pkt);
133}
134
135static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
136{
137 u16 size = (u16)sizeof(struct iwl_addsta_cmd);
138 struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data;
139 memcpy(addsta, cmd, size);
140 /* resrved in 5000 */
141 addsta->rate_n_flags = cpu_to_le16(0);
142 return size;
143}
144
145int iwl_send_add_sta(struct iwl_priv *priv,
146 struct iwl_addsta_cmd *sta, u8 flags)
147{
148 int ret = 0;
149 u8 data[sizeof(*sta)];
150 struct iwl_host_cmd cmd = {
151 .id = REPLY_ADD_STA,
152 .flags = flags,
153 .data = { data, },
154 };
155 u8 sta_id __maybe_unused = sta->sta.sta_id;
156
157 IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n",
158 sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : "");
159
160 if (!(flags & CMD_ASYNC)) {
161 cmd.flags |= CMD_WANT_SKB;
162 might_sleep();
163 }
164
165 cmd.len[0] = iwlagn_build_addsta_hcmd(sta, data);
166 ret = iwl_trans_send_cmd(trans(priv), &cmd);
167
168 if (ret || (flags & CMD_ASYNC))
169 return ret;
170 /*else the command was successfully sent in SYNC mode, need to free
171 * the reply page */
172
173 iwl_free_pages(priv->shrd, cmd.reply_page);
174
175 if (cmd.handler_status)
176 IWL_ERR(priv, "%s - error in the CMD response %d", __func__,
177 cmd.handler_status);
178
179 return cmd.handler_status;
180}
181
182static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
183 struct ieee80211_sta *sta,
184 struct iwl_rxon_context *ctx)
185{
186 struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
187 __le32 sta_flags;
188 u8 mimo_ps_mode;
189
190 if (!sta || !sta_ht_inf->ht_supported)
191 goto done;
192
193 mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
194 IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n",
195 (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ?
196 "static" :
197 (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ?
198 "dynamic" : "disabled");
199
200 sta_flags = priv->stations[index].sta.station_flags;
201
202 sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);
203
204 switch (mimo_ps_mode) {
205 case WLAN_HT_CAP_SM_PS_STATIC:
206 sta_flags |= STA_FLG_MIMO_DIS_MSK;
207 break;
208 case WLAN_HT_CAP_SM_PS_DYNAMIC:
209 sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
210 break;
211 case WLAN_HT_CAP_SM_PS_DISABLED:
212 break;
213 default:
214 IWL_WARN(priv, "Invalid MIMO PS mode %d\n", mimo_ps_mode);
215 break;
216 }
217
218 sta_flags |= cpu_to_le32(
219 (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
220
221 sta_flags |= cpu_to_le32(
222 (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
223
224 if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
225 sta_flags |= STA_FLG_HT40_EN_MSK;
226 else
227 sta_flags &= ~STA_FLG_HT40_EN_MSK;
228
229 priv->stations[index].sta.station_flags = sta_flags;
230 done:
231 return;
232}
233
234/**
235 * iwl_prep_station - Prepare station information for addition
236 *
237 * should be called with sta_lock held
238 */
239u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
240 const u8 *addr, bool is_ap, struct ieee80211_sta *sta)
241{
242 struct iwl_station_entry *station;
243 int i;
244 u8 sta_id = IWL_INVALID_STATION;
245
246 if (is_ap)
247 sta_id = ctx->ap_sta_id;
248 else if (is_broadcast_ether_addr(addr))
249 sta_id = ctx->bcast_sta_id;
250 else
251 for (i = IWL_STA_ID;
252 i < hw_params(priv).max_stations; i++) {
253 if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
254 addr)) {
255 sta_id = i;
256 break;
257 }
258
259 if (!priv->stations[i].used &&
260 sta_id == IWL_INVALID_STATION)
261 sta_id = i;
262 }
263
264 /*
265 * These two conditions have the same outcome, but keep them
266 * separate
267 */
268 if (unlikely(sta_id == IWL_INVALID_STATION))
269 return sta_id;
270
271 /*
272 * uCode is not able to deal with multiple requests to add a
273 * station. Keep track if one is in progress so that we do not send
274 * another.
275 */
276 if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
277 IWL_DEBUG_INFO(priv, "STA %d already in process of being added.\n",
278 sta_id);
279 return sta_id;
280 }
281
282 if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
283 (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) &&
284 !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) {
285 IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not adding again.\n",
286 sta_id, addr);
287 return sta_id;
288 }
289
290 station = &priv->stations[sta_id];
291 station->used = IWL_STA_DRIVER_ACTIVE;
292 IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n",
293 sta_id, addr);
294 priv->num_stations++;
295
296 /* Set up the REPLY_ADD_STA command to send to device */
297 memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd));
298 memcpy(station->sta.sta.addr, addr, ETH_ALEN);
299 station->sta.mode = 0;
300 station->sta.sta.sta_id = sta_id;
301 station->sta.station_flags = ctx->station_flags;
302 station->ctxid = ctx->ctxid;
303
304 if (sta) {
305 struct iwl_station_priv *sta_priv;
306
307 sta_priv = (void *)sta->drv_priv;
308 sta_priv->ctx = ctx;
309 }
310
311 /*
312 * OK to call unconditionally, since local stations (IBSS BSSID
313 * STA and broadcast STA) pass in a NULL sta, and mac80211
314 * doesn't allow HT IBSS.
315 */
316 iwl_set_ht_add_station(priv, sta_id, sta, ctx);
317
318 return sta_id;
319
320}
321
322#define STA_WAIT_TIMEOUT (HZ/2)
323
324/**
325 * iwl_add_station_common -
326 */
327int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
328 const u8 *addr, bool is_ap,
329 struct ieee80211_sta *sta, u8 *sta_id_r)
330{
331 unsigned long flags_spin;
332 int ret = 0;
333 u8 sta_id;
334 struct iwl_addsta_cmd sta_cmd;
335
336 *sta_id_r = 0;
337 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
338 sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta);
339 if (sta_id == IWL_INVALID_STATION) {
340 IWL_ERR(priv, "Unable to prepare station %pM for addition\n",
341 addr);
342 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
343 return -EINVAL;
344 }
345
346 /*
347 * uCode is not able to deal with multiple requests to add a
348 * station. Keep track if one is in progress so that we do not send
349 * another.
350 */
351 if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
352 IWL_DEBUG_INFO(priv, "STA %d already in process of being added.\n",
353 sta_id);
354 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
355 return -EEXIST;
356 }
357
358 if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
359 (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
360 IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not adding again.\n",
361 sta_id, addr);
362 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
363 return -EEXIST;
364 }
365
366 priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
367 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
368 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
369
370 /* Add station to device's station table */
371 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
372 if (ret) {
373 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
374 IWL_ERR(priv, "Adding station %pM failed.\n",
375 priv->stations[sta_id].sta.sta.addr);
376 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
377 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
378 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
379 }
380 *sta_id_r = sta_id;
381 return ret;
382}
383
384/**
385 * iwl_sta_ucode_deactivate - deactivate ucode status for a station
386 *
387 * priv->shrd->sta_lock must be held
388 */
389static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
390{
391 /* Ucode must be active and driver must be non active */
392 if ((priv->stations[sta_id].used &
393 (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) != IWL_STA_UCODE_ACTIVE)
394 IWL_ERR(priv, "removed non active STA %u\n", sta_id);
395
396 priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE;
397
398 memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry));
399 IWL_DEBUG_ASSOC(priv, "Removed STA %u\n", sta_id);
400}
401
402static int iwl_send_remove_station(struct iwl_priv *priv,
403 const u8 *addr, int sta_id,
404 bool temporary)
405{
406 struct iwl_rx_packet *pkt;
407 int ret;
408
409 unsigned long flags_spin;
410 struct iwl_rem_sta_cmd rm_sta_cmd;
411
412 struct iwl_host_cmd cmd = {
413 .id = REPLY_REMOVE_STA,
414 .len = { sizeof(struct iwl_rem_sta_cmd), },
415 .flags = CMD_SYNC,
416 .data = { &rm_sta_cmd, },
417 };
418
419 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
420 rm_sta_cmd.num_sta = 1;
421 memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN);
422
423 cmd.flags |= CMD_WANT_SKB;
424
425 ret = iwl_trans_send_cmd(trans(priv), &cmd);
426
427 if (ret)
428 return ret;
429
430 pkt = (struct iwl_rx_packet *)cmd.reply_page;
431 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
432 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
433 pkt->hdr.flags);
434 ret = -EIO;
435 }
436
437 if (!ret) {
438 switch (pkt->u.rem_sta.status) {
439 case REM_STA_SUCCESS_MSK:
440 if (!temporary) {
441 spin_lock_irqsave(&priv->shrd->sta_lock,
442 flags_spin);
443 iwl_sta_ucode_deactivate(priv, sta_id);
444 spin_unlock_irqrestore(&priv->shrd->sta_lock,
445 flags_spin);
446 }
447 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
448 break;
449 default:
450 ret = -EIO;
451 IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
452 break;
453 }
454 }
455 iwl_free_pages(priv->shrd, cmd.reply_page);
456
457 return ret;
458}
459
460/**
461 * iwl_remove_station - Remove driver's knowledge of station.
462 */
463int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
464 const u8 *addr)
465{
466 unsigned long flags;
467
468 if (!iwl_is_ready(priv->shrd)) {
469 IWL_DEBUG_INFO(priv,
470 "Unable to remove station %pM, device not ready.\n",
471 addr);
472 /*
473 * It is typical for stations to be removed when we are
474 * going down. Return success since device will be down
475 * soon anyway
476 */
477 return 0;
478 }
479
480 IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
481 sta_id, addr);
482
483 if (WARN_ON(sta_id == IWL_INVALID_STATION))
484 return -EINVAL;
485
486 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
487
488 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
489 IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
490 addr);
491 goto out_err;
492 }
493
494 if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
495 IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n",
496 addr);
497 goto out_err;
498 }
499
500 if (priv->stations[sta_id].used & IWL_STA_LOCAL) {
501 kfree(priv->stations[sta_id].lq);
502 priv->stations[sta_id].lq = NULL;
503 }
504
505 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
506
507 priv->num_stations--;
508
509 if (WARN_ON(priv->num_stations < 0))
510 priv->num_stations = 0;
511
512 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
513
514 return iwl_send_remove_station(priv, addr, sta_id, false);
515out_err:
516 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
517 return -EINVAL;
518}
519
520/**
521 * iwl_clear_ucode_stations - clear ucode station table bits
522 *
523 * This function clears all the bits in the driver indicating
524 * which stations are active in the ucode. Call when something
525 * other than explicit station management would cause this in
526 * the ucode, e.g. unassociated RXON.
527 */
528void iwl_clear_ucode_stations(struct iwl_priv *priv,
529 struct iwl_rxon_context *ctx)
530{
531 int i;
532 unsigned long flags_spin;
533 bool cleared = false;
534
535 IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n");
536
537 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
538 for (i = 0; i < hw_params(priv).max_stations; i++) {
539 if (ctx && ctx->ctxid != priv->stations[i].ctxid)
540 continue;
541
542 if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) {
543 IWL_DEBUG_INFO(priv, "Clearing ucode active for station %d\n", i);
544 priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
545 cleared = true;
546 }
547 }
548 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
549
550 if (!cleared)
551 IWL_DEBUG_INFO(priv, "No active stations found to be cleared\n");
552}
553
554/**
555 * iwl_restore_stations() - Restore driver known stations to device
556 *
557 * All stations considered active by driver, but not present in ucode, is
558 * restored.
559 *
560 * Function sleeps.
561 */
562void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
563{
564 struct iwl_addsta_cmd sta_cmd;
565 struct iwl_link_quality_cmd lq;
566 unsigned long flags_spin;
567 int i;
568 bool found = false;
569 int ret;
570 bool send_lq;
571
572 if (!iwl_is_ready(priv->shrd)) {
573 IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n");
574 return;
575 }
576
577 IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
578 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
579 for (i = 0; i < hw_params(priv).max_stations; i++) {
580 if (ctx->ctxid != priv->stations[i].ctxid)
581 continue;
582 if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) &&
583 !(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) {
584 IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n",
585 priv->stations[i].sta.sta.addr);
586 priv->stations[i].sta.mode = 0;
587 priv->stations[i].used |= IWL_STA_UCODE_INPROGRESS;
588 found = true;
589 }
590 }
591
592 for (i = 0; i < hw_params(priv).max_stations; i++) {
593 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
594 memcpy(&sta_cmd, &priv->stations[i].sta,
595 sizeof(struct iwl_addsta_cmd));
596 send_lq = false;
597 if (priv->stations[i].lq) {
598 memcpy(&lq, priv->stations[i].lq,
599 sizeof(struct iwl_link_quality_cmd));
600 send_lq = true;
601 }
602 spin_unlock_irqrestore(&priv->shrd->sta_lock,
603 flags_spin);
604 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
605 if (ret) {
606 spin_lock_irqsave(&priv->shrd->sta_lock,
607 flags_spin);
608 IWL_ERR(priv, "Adding station %pM failed.\n",
609 priv->stations[i].sta.sta.addr);
610 priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE;
611 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
612 spin_unlock_irqrestore(&priv->shrd->sta_lock,
613 flags_spin);
614 }
615 /*
616 * Rate scaling has already been initialized, send
617 * current LQ command
618 */
619 if (send_lq)
620 iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
621 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
622 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
623 }
624 }
625
626 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
627 if (!found)
628 IWL_DEBUG_INFO(priv, "Restoring all known stations .... no stations to be restored.\n");
629 else
630 IWL_DEBUG_INFO(priv, "Restoring all known stations .... complete.\n");
631}
632
633void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
634{
635 unsigned long flags;
636 int sta_id = ctx->ap_sta_id;
637 int ret;
638 struct iwl_addsta_cmd sta_cmd;
639 struct iwl_link_quality_cmd lq;
640 bool active;
641
642 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
643 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
644 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
645 return;
646 }
647
648 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
649 sta_cmd.mode = 0;
650 memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));
651
652 active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
653 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
654 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
655
656 if (active) {
657 ret = iwl_send_remove_station(
658 priv, priv->stations[sta_id].sta.sta.addr,
659 sta_id, true);
660 if (ret)
661 IWL_ERR(priv, "failed to remove STA %pM (%d)\n",
662 priv->stations[sta_id].sta.sta.addr, ret);
663 }
664 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
665 priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
666 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
667
668 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
669 if (ret)
670 IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
671 priv->stations[sta_id].sta.sta.addr, ret);
672 iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
673}
674
675int iwl_get_free_ucode_key_offset(struct iwl_priv *priv)
676{
677 int i;
678
679 for (i = 0; i < priv->sta_key_max_num; i++)
680 if (!test_and_set_bit(i, &priv->ucode_key_table))
681 return i;
682
683 return WEP_INVALID_OFFSET;
684}
685
686void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
687{
688 unsigned long flags;
689 int i;
690
691 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
692 for (i = 0; i < hw_params(priv).max_stations; i++) {
693 if (!(priv->stations[i].used & IWL_STA_BCAST))
694 continue;
695
696 priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
697 priv->num_stations--;
698 if (WARN_ON(priv->num_stations < 0))
699 priv->num_stations = 0;
700 kfree(priv->stations[i].lq);
701 priv->stations[i].lq = NULL;
702 }
703 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
704}
705
706#ifdef CONFIG_IWLWIFI_DEBUG
707static void iwl_dump_lq_cmd(struct iwl_priv *priv,
708 struct iwl_link_quality_cmd *lq)
709{
710 int i;
711 IWL_DEBUG_RATE(priv, "lq station id 0x%x\n", lq->sta_id);
712 IWL_DEBUG_RATE(priv, "lq ant 0x%X 0x%X\n",
713 lq->general_params.single_stream_ant_msk,
714 lq->general_params.dual_stream_ant_msk);
715
716 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
717 IWL_DEBUG_RATE(priv, "lq index %d 0x%X\n",
718 i, lq->rs_table[i].rate_n_flags);
719}
720#else
721static inline void iwl_dump_lq_cmd(struct iwl_priv *priv,
722 struct iwl_link_quality_cmd *lq)
723{
724}
725#endif
726
727/**
728 * is_lq_table_valid() - Test one aspect of LQ cmd for validity
729 *
730 * It sometimes happens when a HT rate has been in use and we
731 * loose connectivity with AP then mac80211 will first tell us that the
732 * current channel is not HT anymore before removing the station. In such a
733 * scenario the RXON flags will be updated to indicate we are not
734 * communicating HT anymore, but the LQ command may still contain HT rates.
735 * Test for this to prevent driver from sending LQ command between the time
736 * RXON flags are updated and when LQ command is updated.
737 */
738static bool is_lq_table_valid(struct iwl_priv *priv,
739 struct iwl_rxon_context *ctx,
740 struct iwl_link_quality_cmd *lq)
741{
742 int i;
743
744 if (ctx->ht.enabled)
745 return true;
746
747 IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n",
748 ctx->active.channel);
749 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
750 if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) {
751 IWL_DEBUG_INFO(priv,
752 "index %d of LQ expects HT channel\n",
753 i);
754 return false;
755 }
756 }
757 return true;
758}
759
760/**
761 * iwl_send_lq_cmd() - Send link quality command
762 * @init: This command is sent as part of station initialization right
763 * after station has been added.
764 *
765 * The link quality command is sent as the last step of station creation.
766 * This is the special case in which init is set and we call a callback in
767 * this case to clear the state indicating that station creation is in
768 * progress.
769 */
770int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
771 struct iwl_link_quality_cmd *lq, u8 flags, bool init)
772{
773 int ret = 0;
774 unsigned long flags_spin;
775
776 struct iwl_host_cmd cmd = {
777 .id = REPLY_TX_LINK_QUALITY_CMD,
778 .len = { sizeof(struct iwl_link_quality_cmd), },
779 .flags = flags,
780 .data = { lq, },
781 };
782
783 if (WARN_ON(lq->sta_id == IWL_INVALID_STATION))
784 return -EINVAL;
785
786
787 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
788 if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
789 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
790 return -EINVAL;
791 }
792 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
793
794 iwl_dump_lq_cmd(priv, lq);
795 if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
796 return -EINVAL;
797
798 if (is_lq_table_valid(priv, ctx, lq))
799 ret = iwl_trans_send_cmd(trans(priv), &cmd);
800 else
801 ret = -EINVAL;
802
803 if (cmd.flags & CMD_ASYNC)
804 return ret;
805
806 if (init) {
807 IWL_DEBUG_INFO(priv, "init LQ command complete, clearing sta addition status for sta %d\n",
808 lq->sta_id);
809 spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
810 priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
811 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
812 }
813 return ret;
814}
815
816int iwl_mac_sta_remove(struct ieee80211_hw *hw,
817 struct ieee80211_vif *vif,
818 struct ieee80211_sta *sta)
819{
820 struct iwl_priv *priv = hw->priv;
821 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
822 int ret;
823
824 IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
825 sta->addr);
826 mutex_lock(&priv->shrd->mutex);
827 IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n",
828 sta->addr);
829 ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr);
830 if (ret)
831 IWL_ERR(priv, "Error removing station %pM\n",
832 sta->addr);
833 mutex_unlock(&priv->shrd->mutex);
834 return ret;
835}
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
deleted file mode 100644
index 1bca0dabde8d..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ /dev/null
@@ -1,141 +0,0 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 *
5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 *
21 * The full GNU General Public License is included in this distribution in the
22 * file called LICENSE.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29#ifndef __iwl_sta_h__
30#define __iwl_sta_h__
31
32#include "iwl-dev.h"
33
34#define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */
35#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */
36#define IWL_STA_UCODE_INPROGRESS BIT(2) /* ucode entry is in process of
37 being activated */
38#define IWL_STA_LOCAL BIT(3) /* station state not directed by mac80211;
39 (this is for the IBSS BSSID stations) */
40#define IWL_STA_BCAST BIT(4) /* this station is the special bcast station */
41
42
43void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
44void iwl_clear_ucode_stations(struct iwl_priv *priv,
45 struct iwl_rxon_context *ctx);
46void iwl_dealloc_bcast_stations(struct iwl_priv *priv);
47int iwl_get_free_ucode_key_offset(struct iwl_priv *priv);
48int iwl_send_add_sta(struct iwl_priv *priv,
49 struct iwl_addsta_cmd *sta, u8 flags);
50int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
51 const u8 *addr, bool is_ap,
52 struct ieee80211_sta *sta, u8 *sta_id_r);
53int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
54 const u8 *addr);
55int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
56 struct ieee80211_sta *sta);
57
58u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
59 const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
60
61int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
62 struct iwl_link_quality_cmd *lq, u8 flags, bool init);
63void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
64int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
65 struct iwl_device_cmd *cmd);
66
67
68/**
69 * iwl_clear_driver_stations - clear knowledge of all stations from driver
70 * @priv: iwl priv struct
71 *
72 * This is called during iwl_down() to make sure that in the case
73 * we're coming there from a hardware restart mac80211 will be
74 * able to reconfigure stations -- if we're getting there in the
75 * normal down flow then the stations will already be cleared.
76 */
77static inline void iwl_clear_driver_stations(struct iwl_priv *priv)
78{
79 unsigned long flags;
80 struct iwl_rxon_context *ctx;
81
82 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
83 memset(priv->stations, 0, sizeof(priv->stations));
84 priv->num_stations = 0;
85
86 priv->ucode_key_table = 0;
87
88 for_each_context(priv, ctx) {
89 /*
90 * Remove all key information that is not stored as part
91 * of station information since mac80211 may not have had
92 * a chance to remove all the keys. When device is
93 * reconfigured by mac80211 after an error all keys will
94 * be reconfigured.
95 */
96 memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys));
97 ctx->key_mapping_keys = 0;
98 }
99
100 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
101}
102
103static inline int iwl_sta_id(struct ieee80211_sta *sta)
104{
105 if (WARN_ON(!sta))
106 return IWL_INVALID_STATION;
107
108 return ((struct iwl_station_priv *)sta->drv_priv)->sta_id;
109}
110
111/**
112 * iwl_sta_id_or_broadcast - return sta_id or broadcast sta
113 * @priv: iwl priv
114 * @context: the current context
115 * @sta: mac80211 station
116 *
117 * In certain circumstances mac80211 passes a station pointer
118 * that may be %NULL, for example during TX or key setup. In
119 * that case, we need to use the broadcast station, so this
120 * inline wraps that pattern.
121 */
122static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv,
123 struct iwl_rxon_context *context,
124 struct ieee80211_sta *sta)
125{
126 int sta_id;
127
128 if (!sta)
129 return context->bcast_sta_id;
130
131 sta_id = iwl_sta_id(sta);
132
133 /*
134 * mac80211 should not be passing a partially
135 * initialised station!
136 */
137 WARN_ON(sta_id == IWL_INVALID_STATION);
138
139 return sta_id;
140}
141#endif /* __iwl_sta_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c
index 3335d31daf89..5e50d88f302b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c
@@ -184,7 +184,7 @@ static void iwl_trace_cleanup(struct iwl_priv *priv)
184 if (priv->testmode_trace.trace_enabled) { 184 if (priv->testmode_trace.trace_enabled) {
185 if (priv->testmode_trace.cpu_addr && 185 if (priv->testmode_trace.cpu_addr &&
186 priv->testmode_trace.dma_addr) 186 priv->testmode_trace.dma_addr)
187 dma_free_coherent(priv->bus->dev, 187 dma_free_coherent(bus(priv)->dev,
188 priv->testmode_trace.total_size, 188 priv->testmode_trace.total_size,
189 priv->testmode_trace.cpu_addr, 189 priv->testmode_trace.cpu_addr,
190 priv->testmode_trace.dma_addr); 190 priv->testmode_trace.dma_addr);
@@ -484,7 +484,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
484 struct iwl_priv *priv = hw->priv; 484 struct iwl_priv *priv = hw->priv;
485 struct sk_buff *skb; 485 struct sk_buff *skb;
486 int status = 0; 486 int status = 0;
487 struct device *dev = priv->bus->dev; 487 struct device *dev = bus(priv)->dev;
488 488
489 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { 489 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
490 case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: 490 case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
@@ -641,7 +641,7 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
641 * @data: pointer to user space message 641 * @data: pointer to user space message
642 * @len: length in byte of @data 642 * @len: length in byte of @data
643 */ 643 */
644int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) 644int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
645{ 645{
646 struct nlattr *tb[IWL_TM_ATTR_MAX]; 646 struct nlattr *tb[IWL_TM_ATTR_MAX];
647 struct iwl_priv *priv = hw->priv; 647 struct iwl_priv *priv = hw->priv;
@@ -706,7 +706,7 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
706 return result; 706 return result;
707} 707}
708 708
709int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, 709int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
710 struct netlink_callback *cb, 710 struct netlink_callback *cb,
711 void *data, int len) 711 void *data, int len)
712{ 712{
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
index b4eff556cd0a..374c68cc1d70 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
@@ -33,7 +33,6 @@
33/*TODO: Remove include to iwl-core.h*/ 33/*TODO: Remove include to iwl-core.h*/
34#include "iwl-core.h" 34#include "iwl-core.h"
35#include "iwl-io.h" 35#include "iwl-io.h"
36#include "iwl-helpers.h"
37#include "iwl-trans-pcie-int.h" 36#include "iwl-trans-pcie-int.h"
38 37
39/****************************************************************************** 38/******************************************************************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
index ee7059dcbbcb..4a0c95302a7e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
@@ -30,14 +30,11 @@
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/sched.h> 31#include <linux/sched.h>
32 32
33/* TODO: remove include to iwl-dev.h */
34#include "iwl-dev.h"
35#include "iwl-debug.h" 33#include "iwl-debug.h"
36#include "iwl-csr.h" 34#include "iwl-csr.h"
37#include "iwl-prph.h" 35#include "iwl-prph.h"
38#include "iwl-io.h" 36#include "iwl-io.h"
39#include "iwl-agn-hw.h" 37#include "iwl-agn-hw.h"
40#include "iwl-helpers.h"
41#include "iwl-trans-pcie-int.h" 38#include "iwl-trans-pcie-int.h"
42 39
43#define IWL_TX_CRC_SIZE 4 40#define IWL_TX_CRC_SIZE 4
@@ -634,8 +631,11 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans,
634 case IWL_AGG_ON: 631 case IWL_AGG_ON:
635 break; 632 break;
636 default: 633 default:
637 IWL_WARN(trans, "Stopping AGG while state not ON" 634 IWL_WARN(trans, "Stopping AGG while state not ON "
638 "or starting\n"); 635 "or starting for %d on %d (%d)\n", sta_id, tid,
636 trans->shrd->tid_data[sta_id][tid].agg.state);
637 spin_unlock_irqrestore(&trans->shrd->sta_lock, flags);
638 return 0;
639 } 639 }
640 640
641 write_ptr = trans_pcie->txq[txq_id].q.write_ptr; 641 write_ptr = trans_pcie->txq[txq_id].q.write_ptr;
@@ -950,6 +950,11 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
950 iwl_hcmd_queue_reclaim(trans, txq_id, index); 950 iwl_hcmd_queue_reclaim(trans, txq_id, index);
951 951
952 if (!(meta->flags & CMD_ASYNC)) { 952 if (!(meta->flags & CMD_ASYNC)) {
953 if (!test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) {
954 IWL_WARN(trans,
955 "HCMD_ACTIVE already clear for command %s\n",
956 get_cmd_string(cmd->hdr.cmd));
957 }
953 clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); 958 clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
954 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", 959 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
955 get_cmd_string(cmd->hdr.cmd)); 960 get_cmd_string(cmd->hdr.cmd));
@@ -1013,11 +1018,19 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
1013 HOST_COMPLETE_TIMEOUT); 1018 HOST_COMPLETE_TIMEOUT);
1014 if (!ret) { 1019 if (!ret) {
1015 if (test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) { 1020 if (test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) {
1021 struct iwl_tx_queue *txq =
1022 &trans_pcie->txq[trans->shrd->cmd_queue];
1023 struct iwl_queue *q = &txq->q;
1024
1016 IWL_ERR(trans, 1025 IWL_ERR(trans,
1017 "Error sending %s: time out after %dms.\n", 1026 "Error sending %s: time out after %dms.\n",
1018 get_cmd_string(cmd->id), 1027 get_cmd_string(cmd->id),
1019 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); 1028 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
1020 1029
1030 IWL_ERR(trans,
1031 "Current CMD queue read_ptr %d write_ptr %d\n",
1032 q->read_ptr, q->write_ptr);
1033
1021 clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); 1034 clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
1022 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command" 1035 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command"
1023 "%s\n", get_cmd_string(cmd->id)); 1036 "%s\n", get_cmd_string(cmd->id));
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index 416e9920e4d9..8e8c75c997ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -406,6 +406,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
406 struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; 406 struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
407 struct iwl_queue *q = &txq->q; 407 struct iwl_queue *q = &txq->q;
408 enum dma_data_direction dma_dir; 408 enum dma_data_direction dma_dir;
409 unsigned long flags;
409 410
410 if (!q->n_bd) 411 if (!q->n_bd)
411 return; 412 return;
@@ -418,12 +419,14 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
418 else 419 else
419 dma_dir = DMA_TO_DEVICE; 420 dma_dir = DMA_TO_DEVICE;
420 421
422 spin_lock_irqsave(&trans->shrd->sta_lock, flags);
421 while (q->write_ptr != q->read_ptr) { 423 while (q->write_ptr != q->read_ptr) {
422 /* The read_ptr needs to bound by q->n_window */ 424 /* The read_ptr needs to bound by q->n_window */
423 iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr), 425 iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr),
424 dma_dir); 426 dma_dir);
425 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); 427 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
426 } 428 }
429 spin_unlock_irqrestore(&trans->shrd->sta_lock, flags);
427} 430}
428 431
429/** 432/**
@@ -1077,7 +1080,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1077 txq_id = 1080 txq_id =
1078 trans_pcie->ac_to_queue[ctx][skb_get_queue_mapping(skb)]; 1081 trans_pcie->ac_to_queue[ctx][skb_get_queue_mapping(skb)];
1079 1082
1080 if (ieee80211_is_data_qos(fc)) { 1083 if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) {
1081 u8 *qc = NULL; 1084 u8 *qc = NULL;
1082 struct iwl_tid_data *tid_data; 1085 struct iwl_tid_data *tid_data;
1083 qc = ieee80211_get_qos_ctl(hdr); 1086 qc = ieee80211_get_qos_ctl(hdr);
@@ -1095,7 +1098,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1095 seq_number += 0x10; 1098 seq_number += 0x10;
1096 /* aggregation is on for this <sta,tid> */ 1099 /* aggregation is on for this <sta,tid> */
1097 if (info->flags & IEEE80211_TX_CTL_AMPDU) { 1100 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1098 WARN_ON(tid_data->agg.state != IWL_AGG_ON); 1101 WARN_ON_ONCE(tid_data->agg.state != IWL_AGG_ON);
1099 txq_id = tid_data->agg.txq_id; 1102 txq_id = tid_data->agg.txq_id;
1100 is_agg = true; 1103 is_agg = true;
1101 } 1104 }
@@ -1206,7 +1209,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1206 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); 1209 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
1207 iwl_txq_update_write_ptr(trans, txq); 1210 iwl_txq_update_write_ptr(trans, txq);
1208 1211
1209 if (ieee80211_is_data_qos(fc)) { 1212 if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) {
1210 trans->shrd->tid_data[sta_id][tid].tfds_in_queue++; 1213 trans->shrd->tid_data[sta_id][tid].tfds_in_queue++;
1211 if (!ieee80211_has_morefrags(fc)) 1214 if (!ieee80211_has_morefrags(fc))
1212 trans->shrd->tid_data[sta_id][tid].seq_number = 1215 trans->shrd->tid_data[sta_id][tid].seq_number =
@@ -1369,16 +1372,22 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans)
1369{ 1372{
1370 /* 1373 /*
1371 * This function is called when system goes into suspend state 1374 * This function is called when system goes into suspend state
1372 * mac80211 will call iwl_mac_stop() from the mac80211 suspend function 1375 * mac80211 will call iwlagn_mac_stop() from the mac80211 suspend
1373 * first but since iwl_mac_stop() has no knowledge of who the caller is, 1376 * function first but since iwlagn_mac_stop() has no knowledge of
1377 * who the caller is,
1374 * it will not call apm_ops.stop() to stop the DMA operation. 1378 * it will not call apm_ops.stop() to stop the DMA operation.
1375 * Calling apm_ops.stop here to make sure we stop the DMA. 1379 * Calling apm_ops.stop here to make sure we stop the DMA.
1376 * 1380 *
1377 * But of course ... if we have configured WoWLAN then we did other 1381 * But of course ... if we have configured WoWLAN then we did other
1378 * things already :-) 1382 * things already :-)
1379 */ 1383 */
1380 if (!trans->shrd->wowlan) 1384 if (!trans->shrd->wowlan) {
1381 iwl_apm_stop(priv(trans)); 1385 iwl_apm_stop(priv(trans));
1386 } else {
1387 iwl_disable_interrupts(trans);
1388 iwl_clear_bit(bus(trans), CSR_GP_CNTRL,
1389 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1390 }
1382 1391
1383 return 0; 1392 return 0;
1384} 1393}
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index ed57e4402800..c42be81e979e 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -187,13 +187,17 @@ static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
187 struct key_params*)) 187 struct key_params*))
188{ 188{
189 struct iwm_priv *iwm = ndev_to_iwm(ndev); 189 struct iwm_priv *iwm = ndev_to_iwm(ndev);
190 struct iwm_key *key = &iwm->keys[key_index]; 190 struct iwm_key *key;
191 struct key_params params; 191 struct key_params params;
192 192
193 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index); 193 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
194 194
195 if (key_index >= IWM_NUM_KEYS)
196 return -ENOENT;
197
195 memset(&params, 0, sizeof(params)); 198 memset(&params, 0, sizeof(params));
196 199
200 key = &iwm->keys[key_index];
197 params.cipher = key->cipher; 201 params.cipher = key->cipher;
198 params.key_len = key->key_len; 202 params.key_len = key->key_len;
199 params.seq_len = key->seq_len; 203 params.seq_len = key->seq_len;
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 610bfcee3cf6..ff6378276ff0 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -1666,28 +1666,20 @@ static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev,
1666 if (dev == priv->mesh_dev) 1666 if (dev == priv->mesh_dev)
1667 return -EOPNOTSUPP; 1667 return -EOPNOTSUPP;
1668 1668
1669 lbs_deb_enter(LBS_DEB_CFG80211);
1670
1671 switch (type) { 1669 switch (type) {
1672 case NL80211_IFTYPE_MONITOR: 1670 case NL80211_IFTYPE_MONITOR:
1673 ret = lbs_set_monitor_mode(priv, 1);
1674 break;
1675 case NL80211_IFTYPE_STATION: 1671 case NL80211_IFTYPE_STATION:
1676 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
1677 ret = lbs_set_monitor_mode(priv, 0);
1678 if (!ret)
1679 ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1);
1680 break;
1681 case NL80211_IFTYPE_ADHOC: 1672 case NL80211_IFTYPE_ADHOC:
1682 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
1683 ret = lbs_set_monitor_mode(priv, 0);
1684 if (!ret)
1685 ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 2);
1686 break; 1673 break;
1687 default: 1674 default:
1688 ret = -ENOTSUPP; 1675 return -EOPNOTSUPP;
1689 } 1676 }
1690 1677
1678 lbs_deb_enter(LBS_DEB_CFG80211);
1679
1680 if (priv->iface_running)
1681 ret = lbs_set_iface_type(priv, type);
1682
1691 if (!ret) 1683 if (!ret)
1692 priv->wdev->iftype = type; 1684 priv->wdev->iftype = type;
1693 1685
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 9304e6fc421f..bc951ab4b681 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -9,6 +9,7 @@
9 9
10#include <linux/netdevice.h> 10#include <linux/netdevice.h>
11#include <linux/firmware.h> 11#include <linux/firmware.h>
12#include <linux/nl80211.h>
12 13
13/* Should be terminated by a NULL entry */ 14/* Should be terminated by a NULL entry */
14struct lbs_fw_table { 15struct lbs_fw_table {
@@ -45,6 +46,7 @@ void lbs_host_to_card_done(struct lbs_private *priv);
45 46
46int lbs_start_iface(struct lbs_private *priv); 47int lbs_start_iface(struct lbs_private *priv);
47int lbs_stop_iface(struct lbs_private *priv); 48int lbs_stop_iface(struct lbs_private *priv);
49int lbs_set_iface_type(struct lbs_private *priv, enum nl80211_iftype type);
48 50
49int lbs_rtap_supported(struct lbs_private *priv); 51int lbs_rtap_supported(struct lbs_private *priv);
50 52
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index c50ae07e2e89..b03779bcd547 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -99,6 +99,32 @@ u8 lbs_data_rate_to_fw_index(u32 rate)
99 return 0; 99 return 0;
100} 100}
101 101
102int lbs_set_iface_type(struct lbs_private *priv, enum nl80211_iftype type)
103{
104 int ret = 0;
105
106 switch (type) {
107 case NL80211_IFTYPE_MONITOR:
108 ret = lbs_set_monitor_mode(priv, 1);
109 break;
110 case NL80211_IFTYPE_STATION:
111 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
112 ret = lbs_set_monitor_mode(priv, 0);
113 if (!ret)
114 ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1);
115 break;
116 case NL80211_IFTYPE_ADHOC:
117 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
118 ret = lbs_set_monitor_mode(priv, 0);
119 if (!ret)
120 ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 2);
121 break;
122 default:
123 ret = -ENOTSUPP;
124 }
125 return ret;
126}
127
102int lbs_start_iface(struct lbs_private *priv) 128int lbs_start_iface(struct lbs_private *priv)
103{ 129{
104 struct cmd_ds_802_11_mac_address cmd; 130 struct cmd_ds_802_11_mac_address cmd;
@@ -120,6 +146,12 @@ int lbs_start_iface(struct lbs_private *priv)
120 goto err; 146 goto err;
121 } 147 }
122 148
149 ret = lbs_set_iface_type(priv, priv->wdev->iftype);
150 if (ret) {
151 lbs_deb_net("set iface type failed\n");
152 goto err;
153 }
154
123 lbs_update_channel(priv); 155 lbs_update_channel(priv);
124 156
125 priv->iface_running = true; 157 priv->iface_running = true;
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index 9e63d16365e3..079e5532e686 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -246,8 +246,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
246 tx_param.next_pkt_len = 0; 246 tx_param.next_pkt_len = 0;
247 247
248 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, 248 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
249 skb_aggr->data, 249 skb_aggr, &tx_param);
250 skb_aggr->len, &tx_param);
251 switch (ret) { 250 switch (ret) {
252 case -EBUSY: 251 case -EBUSY:
253 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); 252 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
diff --git a/drivers/net/wireless/mwifiex/Kconfig b/drivers/net/wireless/mwifiex/Kconfig
index 86962920cef3..8f2797aa0c60 100644
--- a/drivers/net/wireless/mwifiex/Kconfig
+++ b/drivers/net/wireless/mwifiex/Kconfig
@@ -19,3 +19,14 @@ config MWIFIEX_SDIO
19 19
20 If you choose to build it as a module, it will be called 20 If you choose to build it as a module, it will be called
21 mwifiex_sdio. 21 mwifiex_sdio.
22
23config MWIFIEX_PCIE
24 tristate "Marvell WiFi-Ex Driver for PCIE 8766"
25 depends on MWIFIEX && PCI
26 select FW_LOADER
27 ---help---
28 This adds support for wireless adapters based on Marvell
29 8766 chipset with PCIe interface.
30
31 If you choose to build it as a module, it will be called
32 mwifiex_pcie.
diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile
index 42cb733ea33a..b0257ad1bbed 100644
--- a/drivers/net/wireless/mwifiex/Makefile
+++ b/drivers/net/wireless/mwifiex/Makefile
@@ -39,3 +39,6 @@ obj-$(CONFIG_MWIFIEX) += mwifiex.o
39 39
40mwifiex_sdio-y += sdio.o 40mwifiex_sdio-y += sdio.o
41obj-$(CONFIG_MWIFIEX_SDIO) += mwifiex_sdio.o 41obj-$(CONFIG_MWIFIEX_SDIO) += mwifiex_sdio.o
42
43mwifiex_pcie-y += pcie.o
44obj-$(CONFIG_MWIFIEX_PCIE) += mwifiex_pcie.o
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index d0cada5a29a0..f2e6de03805c 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -48,7 +48,7 @@ static u8 adhoc_rates_bg[BG_SUPPORTED_RATES] = { 0x82, 0x84, 0x8b, 0x96,
48 48
49static u8 adhoc_rates_a[A_SUPPORTED_RATES] = { 0x8c, 0x12, 0x98, 0x24, 49static u8 adhoc_rates_a[A_SUPPORTED_RATES] = { 0x8c, 0x12, 0x98, 0x24,
50 0xb0, 0x48, 0x60, 0x6c, 0 }; 50 0xb0, 0x48, 0x60, 0x6c, 0 };
51u8 supported_rates_a[A_SUPPORTED_RATES] = { 0x0c, 0x12, 0x18, 0x24, 51static u8 supported_rates_a[A_SUPPORTED_RATES] = { 0x0c, 0x12, 0x18, 0x24,
52 0xb0, 0x48, 0x60, 0x6c, 0 }; 52 0xb0, 0x48, 0x60, 0x6c, 0 };
53static u16 mwifiex_data_rates[MWIFIEX_SUPPORTED_RATES_EXT] = { 0x02, 0x04, 53static u16 mwifiex_data_rates[MWIFIEX_SUPPORTED_RATES_EXT] = { 0x02, 0x04,
54 0x0B, 0x16, 0x00, 0x0C, 0x12, 0x18, 54 0x0B, 0x16, 0x00, 0x0C, 0x12, 0x18,
@@ -57,19 +57,19 @@ static u16 mwifiex_data_rates[MWIFIEX_SUPPORTED_RATES_EXT] = { 0x02, 0x04,
57 0x75, 0x82, 0x0C, 0x1B, 0x36, 0x51, 57 0x75, 0x82, 0x0C, 0x1B, 0x36, 0x51,
58 0x6C, 0xA2, 0xD8, 0xF3, 0x10E, 0x00 }; 58 0x6C, 0xA2, 0xD8, 0xF3, 0x10E, 0x00 };
59 59
60u8 supported_rates_b[B_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x16, 0 }; 60static u8 supported_rates_b[B_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x16, 0 };
61 61
62u8 supported_rates_g[G_SUPPORTED_RATES] = { 0x0c, 0x12, 0x18, 0x24, 62static u8 supported_rates_g[G_SUPPORTED_RATES] = { 0x0c, 0x12, 0x18, 0x24,
63 0x30, 0x48, 0x60, 0x6c, 0 }; 63 0x30, 0x48, 0x60, 0x6c, 0 };
64 64
65u8 supported_rates_bg[BG_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x0c, 65static u8 supported_rates_bg[BG_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x0c,
66 0x12, 0x16, 0x18, 0x24, 0x30, 0x48, 66 0x12, 0x16, 0x18, 0x24, 0x30, 0x48,
67 0x60, 0x6c, 0 }; 67 0x60, 0x6c, 0 };
68 68
69u16 region_code_index[MWIFIEX_MAX_REGION_CODE] = { 0x10, 0x20, 0x30, 69u16 region_code_index[MWIFIEX_MAX_REGION_CODE] = { 0x10, 0x20, 0x30,
70 0x32, 0x40, 0x41, 0xff }; 70 0x32, 0x40, 0x41, 0xff };
71 71
72u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 }; 72static u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 };
73 73
74/* 74/*
75 * This function maps an index in supported rates table into 75 * This function maps an index in supported rates table into
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index d12e25d0c880..ac278156d390 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -40,8 +40,12 @@ mwifiex_init_cmd_node(struct mwifiex_private *priv,
40{ 40{
41 cmd_node->priv = priv; 41 cmd_node->priv = priv;
42 cmd_node->cmd_oid = cmd_oid; 42 cmd_node->cmd_oid = cmd_oid;
43 cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required; 43 if (priv->adapter->cmd_wait_q_required) {
44 priv->adapter->cmd_wait_q_required = false; 44 cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required;
45 priv->adapter->cmd_wait_q_required = false;
46 cmd_node->cmd_wait_q_woken = false;
47 cmd_node->condition = &cmd_node->cmd_wait_q_woken;
48 }
45 cmd_node->data_buf = data_buf; 49 cmd_node->data_buf = data_buf;
46 cmd_node->cmd_skb = cmd_node->skb; 50 cmd_node->cmd_skb = cmd_node->skb;
47} 51}
@@ -94,7 +98,7 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter,
94 skb_trim(cmd_node->cmd_skb, 0); 98 skb_trim(cmd_node->cmd_skb, 0);
95 99
96 if (cmd_node->resp_skb) { 100 if (cmd_node->resp_skb) {
97 dev_kfree_skb_any(cmd_node->resp_skb); 101 adapter->if_ops.cmdrsp_complete(adapter, cmd_node->resp_skb);
98 cmd_node->resp_skb = NULL; 102 cmd_node->resp_skb = NULL;
99 } 103 }
100} 104}
@@ -176,8 +180,7 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
176 skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN); 180 skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN);
177 181
178 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD, 182 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
179 cmd_node->cmd_skb->data, 183 cmd_node->cmd_skb, NULL);
180 cmd_node->cmd_skb->len, NULL);
181 184
182 skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN); 185 skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN);
183 186
@@ -238,8 +241,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
238 241
239 skb_push(adapter->sleep_cfm, INTF_HEADER_LEN); 242 skb_push(adapter->sleep_cfm, INTF_HEADER_LEN);
240 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD, 243 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
241 adapter->sleep_cfm->data, 244 adapter->sleep_cfm, NULL);
242 adapter->sleep_cfm->len, NULL);
243 skb_pull(adapter->sleep_cfm, INTF_HEADER_LEN); 245 skb_pull(adapter->sleep_cfm, INTF_HEADER_LEN);
244 246
245 if (ret == -1) { 247 if (ret == -1) {
@@ -402,8 +404,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
402 404
403 adapter->event_cause = 0; 405 adapter->event_cause = 0;
404 adapter->event_skb = NULL; 406 adapter->event_skb = NULL;
405 407 adapter->if_ops.event_complete(adapter, skb);
406 dev_kfree_skb_any(skb);
407 408
408 return ret; 409 return ret;
409} 410}
@@ -421,7 +422,6 @@ int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
421 struct mwifiex_adapter *adapter = priv->adapter; 422 struct mwifiex_adapter *adapter = priv->adapter;
422 423
423 adapter->cmd_wait_q_required = true; 424 adapter->cmd_wait_q_required = true;
424 adapter->cmd_wait_q.condition = false;
425 425
426 ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid, 426 ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid,
427 data_buf); 427 data_buf);
@@ -514,10 +514,12 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
514 } 514 }
515 515
516 /* Send command */ 516 /* Send command */
517 if (cmd_no == HostCmd_CMD_802_11_SCAN) 517 if (cmd_no == HostCmd_CMD_802_11_SCAN) {
518 mwifiex_queue_scan_cmd(priv, cmd_node); 518 mwifiex_queue_scan_cmd(priv, cmd_node);
519 else 519 } else {
520 adapter->cmd_queued = cmd_node;
520 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); 521 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
522 }
521 523
522 return ret; 524 return ret;
523} 525}
@@ -538,7 +540,7 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
538 return; 540 return;
539 541
540 if (cmd_node->wait_q_enabled) 542 if (cmd_node->wait_q_enabled)
541 mwifiex_complete_cmd(adapter); 543 mwifiex_complete_cmd(adapter, cmd_node);
542 /* Clean the node */ 544 /* Clean the node */
543 mwifiex_clean_cmd_node(adapter, cmd_node); 545 mwifiex_clean_cmd_node(adapter, cmd_node);
544 546
@@ -885,7 +887,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
885 adapter->curr_cmd->wait_q_enabled = false; 887 adapter->curr_cmd->wait_q_enabled = false;
886 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 888 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
887 adapter->cmd_wait_q.status = -1; 889 adapter->cmd_wait_q.status = -1;
888 mwifiex_complete_cmd(adapter); 890 mwifiex_complete_cmd(adapter, adapter->curr_cmd);
889 } 891 }
890 /* Cancel all pending command */ 892 /* Cancel all pending command */
891 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); 893 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
@@ -896,7 +898,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
896 898
897 if (cmd_node->wait_q_enabled) { 899 if (cmd_node->wait_q_enabled) {
898 adapter->cmd_wait_q.status = -1; 900 adapter->cmd_wait_q.status = -1;
899 mwifiex_complete_cmd(adapter); 901 mwifiex_complete_cmd(adapter, cmd_node);
900 cmd_node->wait_q_enabled = false; 902 cmd_node->wait_q_enabled = false;
901 } 903 }
902 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 904 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
@@ -979,7 +981,7 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
979 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); 981 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
980 } 982 }
981 adapter->cmd_wait_q.status = -1; 983 adapter->cmd_wait_q.status = -1;
982 mwifiex_complete_cmd(adapter); 984 mwifiex_complete_cmd(adapter, adapter->curr_cmd);
983} 985}
984 986
985/* 987/*
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 6ca62c809cb9..ae17ce02a3d0 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -98,7 +98,6 @@ struct mwifiex_802_11_ssid {
98 98
99struct mwifiex_wait_queue { 99struct mwifiex_wait_queue {
100 wait_queue_head_t wait; 100 wait_queue_head_t wait;
101 u16 condition;
102 int status; 101 int status;
103}; 102};
104 103
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index f23ec72ed4fe..0cc5d73cb0c1 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -57,12 +57,6 @@ struct tx_packet_hdr {
57#define GET_FW_DEFAULT_BANDS(adapter) \ 57#define GET_FW_DEFAULT_BANDS(adapter) \
58 ((adapter->fw_cap_info >> 8) & ALL_802_11_BANDS) 58 ((adapter->fw_cap_info >> 8) & ALL_802_11_BANDS)
59 59
60extern u8 supported_rates_b[B_SUPPORTED_RATES];
61extern u8 supported_rates_g[G_SUPPORTED_RATES];
62extern u8 supported_rates_bg[BG_SUPPORTED_RATES];
63extern u8 supported_rates_a[A_SUPPORTED_RATES];
64extern u8 supported_rates_n[N_SUPPORTED_RATES];
65
66#define HostCmd_WEP_KEY_INDEX_MASK 0x3fff 60#define HostCmd_WEP_KEY_INDEX_MASK 0x3fff
67 61
68#define KEY_INFO_ENABLED 0x01 62#define KEY_INFO_ENABLED 0x01
@@ -84,7 +78,8 @@ enum KEY_TYPE_ID {
84 78
85#define MAX_FIRMWARE_POLL_TRIES 100 79#define MAX_FIRMWARE_POLL_TRIES 100
86 80
87#define FIRMWARE_READY 0xfedc 81#define FIRMWARE_READY_SDIO 0xfedc
82#define FIRMWARE_READY_PCIE 0xfedcba00
88 83
89enum MWIFIEX_802_11_PRIVACY_FILTER { 84enum MWIFIEX_802_11_PRIVACY_FILTER {
90 MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL, 85 MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL,
@@ -221,7 +216,7 @@ enum MWIFIEX_802_11_WEP_STATUS {
221#define HostCmd_CMD_802_11_HS_CFG_ENH 0x00e5 216#define HostCmd_CMD_802_11_HS_CFG_ENH 0x00e5
222#define HostCmd_CMD_CAU_REG_ACCESS 0x00ed 217#define HostCmd_CMD_CAU_REG_ACCESS 0x00ed
223#define HostCmd_CMD_SET_BSS_MODE 0x00f7 218#define HostCmd_CMD_SET_BSS_MODE 0x00f7
224 219#define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa
225 220
226enum ENH_PS_MODES { 221enum ENH_PS_MODES {
227 EN_PS = 1, 222 EN_PS = 1,
@@ -1137,6 +1132,30 @@ struct host_cmd_ds_set_bss_mode {
1137 u8 con_type; 1132 u8 con_type;
1138} __packed; 1133} __packed;
1139 1134
1135struct host_cmd_ds_pcie_details {
1136 /* TX buffer descriptor ring address */
1137 u32 txbd_addr_lo;
1138 u32 txbd_addr_hi;
1139 /* TX buffer descriptor ring count */
1140 u32 txbd_count;
1141
1142 /* RX buffer descriptor ring address */
1143 u32 rxbd_addr_lo;
1144 u32 rxbd_addr_hi;
1145 /* RX buffer descriptor ring count */
1146 u32 rxbd_count;
1147
1148 /* Event buffer descriptor ring address */
1149 u32 evtbd_addr_lo;
1150 u32 evtbd_addr_hi;
1151 /* Event buffer descriptor ring count */
1152 u32 evtbd_count;
1153
1154 /* Sleep cookie buffer physical address */
1155 u32 sleep_cookie_addr_lo;
1156 u32 sleep_cookie_addr_hi;
1157} __packed;
1158
1140struct host_cmd_ds_command { 1159struct host_cmd_ds_command {
1141 __le16 command; 1160 __le16 command;
1142 __le16 size; 1161 __le16 size;
@@ -1184,6 +1203,7 @@ struct host_cmd_ds_command {
1184 struct host_cmd_ds_rf_reg_access rf_reg; 1203 struct host_cmd_ds_rf_reg_access rf_reg;
1185 struct host_cmd_ds_pmic_reg_access pmic_reg; 1204 struct host_cmd_ds_pmic_reg_access pmic_reg;
1186 struct host_cmd_ds_set_bss_mode bss_mode; 1205 struct host_cmd_ds_set_bss_mode bss_mode;
1206 struct host_cmd_ds_pcie_details pcie_host_spec;
1187 struct host_cmd_ds_802_11_eeprom_access eeprom; 1207 struct host_cmd_ds_802_11_eeprom_access eeprom;
1188 } params; 1208 } params;
1189} __packed; 1209} __packed;
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index e1076b46401e..d792b3fb7c16 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -191,7 +191,12 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
191 (adapter->sleep_cfm->data); 191 (adapter->sleep_cfm->data);
192 192
193 adapter->cmd_sent = false; 193 adapter->cmd_sent = false;
194 adapter->data_sent = true; 194
195 if (adapter->iface_type == MWIFIEX_PCIE)
196 adapter->data_sent = false;
197 else
198 adapter->data_sent = true;
199
195 adapter->cmd_resp_received = false; 200 adapter->cmd_resp_received = false;
196 adapter->event_received = false; 201 adapter->event_received = false;
197 adapter->data_received = false; 202 adapter->data_received = false;
@@ -278,6 +283,34 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
278} 283}
279 284
280/* 285/*
286 * This function releases the lock variables and frees the locks and
287 * associated locks.
288 */
289static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
290{
291 struct mwifiex_private *priv;
292 s32 i, j;
293
294 /* Free lists */
295 list_del(&adapter->cmd_free_q);
296 list_del(&adapter->cmd_pending_q);
297 list_del(&adapter->scan_pending_q);
298
299 for (i = 0; i < adapter->priv_num; i++)
300 list_del(&adapter->bss_prio_tbl[i].bss_prio_head);
301
302 for (i = 0; i < adapter->priv_num; i++) {
303 if (adapter->priv[i]) {
304 priv = adapter->priv[i];
305 for (j = 0; j < MAX_NUM_TID; ++j)
306 list_del(&priv->wmm.tid_tbl_ptr[j].ra_list);
307 list_del(&priv->tx_ba_stream_tbl_ptr);
308 list_del(&priv->rx_reorder_tbl_ptr);
309 }
310 }
311}
312
313/*
281 * This function frees the adapter structure. 314 * This function frees the adapter structure.
282 * 315 *
283 * The freeing operation is done recursively, by canceling all 316 * The freeing operation is done recursively, by canceling all
@@ -371,34 +404,6 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
371} 404}
372 405
373/* 406/*
374 * This function releases the lock variables and frees the locks and
375 * associated locks.
376 */
377void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
378{
379 struct mwifiex_private *priv;
380 s32 i, j;
381
382 /* Free lists */
383 list_del(&adapter->cmd_free_q);
384 list_del(&adapter->cmd_pending_q);
385 list_del(&adapter->scan_pending_q);
386
387 for (i = 0; i < adapter->priv_num; i++)
388 list_del(&adapter->bss_prio_tbl[i].bss_prio_head);
389
390 for (i = 0; i < adapter->priv_num; i++) {
391 if (adapter->priv[i]) {
392 priv = adapter->priv[i];
393 for (j = 0; j < MAX_NUM_TID; ++j)
394 list_del(&priv->wmm.tid_tbl_ptr[j].ra_list);
395 list_del(&priv->tx_ba_stream_tbl_ptr);
396 list_del(&priv->rx_reorder_tbl_ptr);
397 }
398 }
399}
400
401/*
402 * This function initializes the firmware. 407 * This function initializes the firmware.
403 * 408 *
404 * The following operations are performed sequentially - 409 * The following operations are performed sequentially -
@@ -581,11 +586,13 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
581int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, 586int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
582 struct mwifiex_fw_image *pmfw) 587 struct mwifiex_fw_image *pmfw)
583{ 588{
584 int ret, winner; 589 int ret;
585 u32 poll_num = 1; 590 u32 poll_num = 1;
586 591
592 adapter->winner = 0;
593
587 /* Check if firmware is already running */ 594 /* Check if firmware is already running */
588 ret = adapter->if_ops.check_fw_status(adapter, poll_num, &winner); 595 ret = adapter->if_ops.check_fw_status(adapter, poll_num);
589 if (!ret) { 596 if (!ret) {
590 dev_notice(adapter->dev, 597 dev_notice(adapter->dev,
591 "WLAN FW already running! Skip FW download\n"); 598 "WLAN FW already running! Skip FW download\n");
@@ -594,7 +601,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
594 poll_num = MAX_FIRMWARE_POLL_TRIES; 601 poll_num = MAX_FIRMWARE_POLL_TRIES;
595 602
596 /* Check if we are the winner for downloading FW */ 603 /* Check if we are the winner for downloading FW */
597 if (!winner) { 604 if (!adapter->winner) {
598 dev_notice(adapter->dev, 605 dev_notice(adapter->dev,
599 "Other interface already running!" 606 "Other interface already running!"
600 " Skip FW download\n"); 607 " Skip FW download\n");
@@ -612,7 +619,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
612 619
613poll_fw: 620poll_fw:
614 /* Check if the firmware is downloaded successfully or not */ 621 /* Check if the firmware is downloaded successfully or not */
615 ret = adapter->if_ops.check_fw_status(adapter, poll_num, NULL); 622 ret = adapter->if_ops.check_fw_status(adapter, poll_num);
616 if (ret) { 623 if (ret) {
617 dev_err(adapter->dev, "FW failed to be active in time\n"); 624 dev_err(adapter->dev, "FW failed to be active in time\n");
618 return -1; 625 return -1;
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 4c7491ec3f2b..67e6db7d672d 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -661,7 +661,7 @@ mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
661 */ 661 */
662int 662int
663mwifiex_add_card(void *card, struct semaphore *sem, 663mwifiex_add_card(void *card, struct semaphore *sem,
664 struct mwifiex_if_ops *if_ops) 664 struct mwifiex_if_ops *if_ops, u8 iface_type)
665{ 665{
666 struct mwifiex_adapter *adapter; 666 struct mwifiex_adapter *adapter;
667 char fmt[64]; 667 char fmt[64];
@@ -675,6 +675,8 @@ mwifiex_add_card(void *card, struct semaphore *sem,
675 goto err_init_sw; 675 goto err_init_sw;
676 } 676 }
677 677
678 adapter->iface_type = iface_type;
679
678 adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; 680 adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
679 adapter->surprise_removed = false; 681 adapter->surprise_removed = false;
680 init_waitqueue_head(&adapter->init_wait_q); 682 init_waitqueue_head(&adapter->init_wait_q);
@@ -683,8 +685,8 @@ mwifiex_add_card(void *card, struct semaphore *sem,
683 init_waitqueue_head(&adapter->hs_activate_wait_q); 685 init_waitqueue_head(&adapter->hs_activate_wait_q);
684 adapter->cmd_wait_q_required = false; 686 adapter->cmd_wait_q_required = false;
685 init_waitqueue_head(&adapter->cmd_wait_q.wait); 687 init_waitqueue_head(&adapter->cmd_wait_q.wait);
686 adapter->cmd_wait_q.condition = false;
687 adapter->cmd_wait_q.status = 0; 688 adapter->cmd_wait_q.status = 0;
689 adapter->scan_wait_q_woken = false;
688 690
689 adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE"); 691 adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE");
690 if (!adapter->workqueue) 692 if (!adapter->workqueue)
@@ -825,6 +827,10 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
825 rtnl_unlock(); 827 rtnl_unlock();
826 } 828 }
827 829
830 priv = adapter->priv[0];
831 if (!priv)
832 goto exit_remove;
833
828 wiphy_unregister(priv->wdev->wiphy); 834 wiphy_unregister(priv->wdev->wiphy);
829 wiphy_free(priv->wdev->wiphy); 835 wiphy_free(priv->wdev->wiphy);
830 kfree(priv->wdev); 836 kfree(priv->wdev);
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 907ab746dc4b..30f138b6fa4c 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -37,6 +37,7 @@
37#include "ioctl.h" 37#include "ioctl.h"
38#include "util.h" 38#include "util.h"
39#include "fw.h" 39#include "fw.h"
40#include "pcie.h"
40 41
41extern const char driver_version[]; 42extern const char driver_version[];
42 43
@@ -107,6 +108,8 @@ enum {
107 108
108#define MAX_FREQUENCY_BAND_BG 2484 109#define MAX_FREQUENCY_BAND_BG 2484
109 110
111#define MWIFIEX_EVENT_HEADER_LEN 4
112
110struct mwifiex_dbg { 113struct mwifiex_dbg {
111 u32 num_cmd_host_to_card_failure; 114 u32 num_cmd_host_to_card_failure;
112 u32 num_cmd_sleep_cfm_host_to_card_failure; 115 u32 num_cmd_sleep_cfm_host_to_card_failure;
@@ -156,6 +159,11 @@ enum MWIFIEX_PS_STATE {
156 PS_STATE_SLEEP 159 PS_STATE_SLEEP
157}; 160};
158 161
162enum mwifiex_iface_type {
163 MWIFIEX_SDIO,
164 MWIFIEX_PCIE,
165};
166
159struct mwifiex_add_ba_param { 167struct mwifiex_add_ba_param {
160 u32 tx_win_size; 168 u32 tx_win_size;
161 u32 rx_win_size; 169 u32 rx_win_size;
@@ -512,32 +520,38 @@ struct cmd_ctrl_node {
512 void *data_buf; 520 void *data_buf;
513 u32 wait_q_enabled; 521 u32 wait_q_enabled;
514 struct sk_buff *skb; 522 struct sk_buff *skb;
523 u8 *condition;
524 u8 cmd_wait_q_woken;
515}; 525};
516 526
517struct mwifiex_if_ops { 527struct mwifiex_if_ops {
518 int (*init_if) (struct mwifiex_adapter *); 528 int (*init_if) (struct mwifiex_adapter *);
519 void (*cleanup_if) (struct mwifiex_adapter *); 529 void (*cleanup_if) (struct mwifiex_adapter *);
520 int (*check_fw_status) (struct mwifiex_adapter *, u32, int *); 530 int (*check_fw_status) (struct mwifiex_adapter *, u32);
521 int (*prog_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *); 531 int (*prog_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *);
522 int (*register_dev) (struct mwifiex_adapter *); 532 int (*register_dev) (struct mwifiex_adapter *);
523 void (*unregister_dev) (struct mwifiex_adapter *); 533 void (*unregister_dev) (struct mwifiex_adapter *);
524 int (*enable_int) (struct mwifiex_adapter *); 534 int (*enable_int) (struct mwifiex_adapter *);
525 int (*process_int_status) (struct mwifiex_adapter *); 535 int (*process_int_status) (struct mwifiex_adapter *);
526 int (*host_to_card) (struct mwifiex_adapter *, u8, 536 int (*host_to_card) (struct mwifiex_adapter *, u8, struct sk_buff *,
527 u8 *payload, u32 pkt_len,
528 struct mwifiex_tx_param *); 537 struct mwifiex_tx_param *);
529 int (*wakeup) (struct mwifiex_adapter *); 538 int (*wakeup) (struct mwifiex_adapter *);
530 int (*wakeup_complete) (struct mwifiex_adapter *); 539 int (*wakeup_complete) (struct mwifiex_adapter *);
531 540
541 /* Interface specific functions */
532 void (*update_mp_end_port) (struct mwifiex_adapter *, u16); 542 void (*update_mp_end_port) (struct mwifiex_adapter *, u16);
533 void (*cleanup_mpa_buf) (struct mwifiex_adapter *); 543 void (*cleanup_mpa_buf) (struct mwifiex_adapter *);
544 int (*cmdrsp_complete) (struct mwifiex_adapter *, struct sk_buff *);
545 int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *);
534}; 546};
535 547
536struct mwifiex_adapter { 548struct mwifiex_adapter {
549 u8 iface_type;
537 struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM]; 550 struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM];
538 u8 priv_num; 551 u8 priv_num;
539 const struct firmware *firmware; 552 const struct firmware *firmware;
540 char fw_name[32]; 553 char fw_name[32];
554 int winner;
541 struct device *dev; 555 struct device *dev;
542 bool surprise_removed; 556 bool surprise_removed;
543 u32 fw_release_number; 557 u32 fw_release_number;
@@ -639,10 +653,11 @@ struct mwifiex_adapter {
639 u32 arp_filter_size; 653 u32 arp_filter_size;
640 u16 cmd_wait_q_required; 654 u16 cmd_wait_q_required;
641 struct mwifiex_wait_queue cmd_wait_q; 655 struct mwifiex_wait_queue cmd_wait_q;
656 u8 scan_wait_q_woken;
657 struct cmd_ctrl_node *cmd_queued;
642}; 658};
643 659
644int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 660int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
645void mwifiex_free_lock_list(struct mwifiex_adapter *adapter);
646 661
647int mwifiex_init_fw(struct mwifiex_adapter *adapter); 662int mwifiex_init_fw(struct mwifiex_adapter *adapter);
648 663
@@ -658,7 +673,8 @@ int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb);
658 673
659int mwifiex_process_event(struct mwifiex_adapter *adapter); 674int mwifiex_process_event(struct mwifiex_adapter *adapter);
660 675
661int mwifiex_complete_cmd(struct mwifiex_adapter *adapter); 676int mwifiex_complete_cmd(struct mwifiex_adapter *adapter,
677 struct cmd_ctrl_node *cmd_node);
662 678
663int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, 679int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
664 u16 cmd_action, u32 cmd_oid, void *data_buf); 680 u16 cmd_action, u32 cmd_oid, void *data_buf);
@@ -692,8 +708,6 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
692int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags); 708int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags);
693int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, 709int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
694 struct sk_buff *skb, int status); 710 struct sk_buff *skb, int status);
695int mwifiex_recv_packet_complete(struct mwifiex_adapter *,
696 struct sk_buff *skb, int status);
697void mwifiex_clean_txrx(struct mwifiex_private *priv); 711void mwifiex_clean_txrx(struct mwifiex_private *priv);
698u8 mwifiex_check_last_packet_indication(struct mwifiex_private *priv); 712u8 mwifiex_check_last_packet_indication(struct mwifiex_private *priv);
699void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter); 713void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter);
@@ -723,8 +737,6 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *,
723int mwifiex_process_sta_event(struct mwifiex_private *); 737int mwifiex_process_sta_event(struct mwifiex_private *);
724void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); 738void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb);
725int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); 739int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta);
726int mwifiex_scan_networks(struct mwifiex_private *priv,
727 const struct mwifiex_user_scan_cfg *user_scan_in);
728int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, 740int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
729 struct mwifiex_scan_cmd_config *scan_cfg); 741 struct mwifiex_scan_cmd_config *scan_cfg);
730void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, 742void mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
@@ -872,7 +884,7 @@ struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter
872 *adapter, u8 bss_index); 884 *adapter, u8 bss_index);
873int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, 885int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
874 u32 func_init_shutdown); 886 u32 func_init_shutdown);
875int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *); 887int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8);
876int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *); 888int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *);
877 889
878void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version, 890void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version,
@@ -884,9 +896,6 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
884int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); 896int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter);
885int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, 897int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
886 struct mwifiex_802_11_ssid *req_ssid); 898 struct mwifiex_802_11_ssid *req_ssid);
887int mwifiex_set_hs_params(struct mwifiex_private *priv,
888 u16 action, int cmd_type,
889 struct mwifiex_ds_hs_cfg *hscfg);
890int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); 899int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type);
891int mwifiex_enable_hs(struct mwifiex_adapter *adapter); 900int mwifiex_enable_hs(struct mwifiex_adapter *adapter);
892int mwifiex_disable_auto_ds(struct mwifiex_private *priv); 901int mwifiex_disable_auto_ds(struct mwifiex_private *priv);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
new file mode 100644
index 000000000000..d34acf082d3a
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -0,0 +1,1948 @@
1/*
2 * Marvell Wireless LAN device driver: PCIE specific handling
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include <linux/firmware.h>
21
22#include "decl.h"
23#include "ioctl.h"
24#include "util.h"
25#include "fw.h"
26#include "main.h"
27#include "wmm.h"
28#include "11n.h"
29#include "pcie.h"
30
31#define PCIE_VERSION "1.0"
32#define DRV_NAME "Marvell mwifiex PCIe"
33
34static u8 user_rmmod;
35
36static struct mwifiex_if_ops pcie_ops;
37
38static struct semaphore add_remove_card_sem;
39static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter);
40static int mwifiex_pcie_resume(struct pci_dev *pdev);
41
42/*
43 * This function is called after skb allocation to update
44 * "skb->cb" with physical address of data pointer.
45 */
46static phys_addr_t *mwifiex_update_sk_buff_pa(struct sk_buff *skb)
47{
48 phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb);
49
50 *buf_pa = (phys_addr_t)virt_to_phys(skb->data);
51
52 return buf_pa;
53}
54
55/*
56 * This function reads sleep cookie and checks if FW is ready
57 */
58static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
59{
60 u32 *cookie_addr;
61 struct pcie_service_card *card = adapter->card;
62
63 if (card->sleep_cookie) {
64 cookie_addr = (u32 *)card->sleep_cookie->data;
65 dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n",
66 *cookie_addr);
67 if (*cookie_addr == FW_AWAKE_COOKIE)
68 return true;
69 }
70
71 return false;
72}
73
74/*
75 * This function probes an mwifiex device and registers it. It allocates
76 * the card structure, enables PCIE function number and initiates the
77 * device registration and initialization procedure by adding a logical
78 * interface.
79 */
80static int mwifiex_pcie_probe(struct pci_dev *pdev,
81 const struct pci_device_id *ent)
82{
83 struct pcie_service_card *card;
84
85 pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
86 pdev->vendor, pdev->device, pdev->revision);
87
88 card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
89 if (!card) {
90 pr_err("%s: failed to alloc memory\n", __func__);
91 return -ENOMEM;
92 }
93
94 card->dev = pdev;
95
96 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
97 MWIFIEX_PCIE)) {
98 pr_err("%s failed\n", __func__);
99 kfree(card);
100 return -1;
101 }
102
103 return 0;
104}
105
106/*
107 * This function removes the interface and frees up the card structure.
108 */
109static void mwifiex_pcie_remove(struct pci_dev *pdev)
110{
111 struct pcie_service_card *card;
112 struct mwifiex_adapter *adapter;
113 int i;
114
115 card = pci_get_drvdata(pdev);
116 if (!card)
117 return;
118
119 adapter = card->adapter;
120 if (!adapter || !adapter->priv_num)
121 return;
122
123 if (user_rmmod) {
124#ifdef CONFIG_PM
125 if (adapter->is_suspended)
126 mwifiex_pcie_resume(pdev);
127#endif
128
129 for (i = 0; i < adapter->priv_num; i++)
130 if ((GET_BSS_ROLE(adapter->priv[i]) ==
131 MWIFIEX_BSS_ROLE_STA) &&
132 adapter->priv[i]->media_connected)
133 mwifiex_deauthenticate(adapter->priv[i], NULL);
134
135 mwifiex_disable_auto_ds(mwifiex_get_priv(adapter,
136 MWIFIEX_BSS_ROLE_ANY));
137
138 mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
139 MWIFIEX_BSS_ROLE_ANY),
140 MWIFIEX_FUNC_SHUTDOWN);
141 }
142
143 mwifiex_remove_card(card->adapter, &add_remove_card_sem);
144 kfree(card);
145}
146
147/*
148 * Kernel needs to suspend all functions separately. Therefore all
149 * registered functions must have drivers with suspend and resume
150 * methods. Failing that the kernel simply removes the whole card.
151 *
152 * If already not suspended, this function allocates and sends a host
153 * sleep activate request to the firmware and turns off the traffic.
154 */
155static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
156{
157 struct mwifiex_adapter *adapter;
158 struct pcie_service_card *card;
159 int hs_actived, i;
160
161 if (pdev) {
162 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
163 if (!card || card->adapter) {
164 pr_err("Card or adapter structure is not valid\n");
165 return 0;
166 }
167 } else {
168 pr_err("PCIE device is not specified\n");
169 return 0;
170 }
171
172 adapter = card->adapter;
173
174 hs_actived = mwifiex_enable_hs(adapter);
175
176 /* Indicate device suspended */
177 adapter->is_suspended = true;
178
179 for (i = 0; i < adapter->priv_num; i++)
180 netif_carrier_off(adapter->priv[i]->netdev);
181
182 return 0;
183}
184
185/*
186 * Kernel needs to suspend all functions separately. Therefore all
187 * registered functions must have drivers with suspend and resume
188 * methods. Failing that the kernel simply removes the whole card.
189 *
190 * If already not resumed, this function turns on the traffic and
191 * sends a host sleep cancel request to the firmware.
192 */
193static int mwifiex_pcie_resume(struct pci_dev *pdev)
194{
195 struct mwifiex_adapter *adapter;
196 struct pcie_service_card *card;
197 int i;
198
199 if (pdev) {
200 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
201 if (!card || !card->adapter) {
202 pr_err("Card or adapter structure is not valid\n");
203 return 0;
204 }
205 } else {
206 pr_err("PCIE device is not specified\n");
207 return 0;
208 }
209
210 adapter = card->adapter;
211
212 if (!adapter->is_suspended) {
213 dev_warn(adapter->dev, "Device already resumed\n");
214 return 0;
215 }
216
217 adapter->is_suspended = false;
218
219 for (i = 0; i < adapter->priv_num; i++)
220 if (adapter->priv[i]->media_connected)
221 netif_carrier_on(adapter->priv[i]->netdev);
222
223 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
224 MWIFIEX_ASYNC_CMD);
225
226 return 0;
227}
228
229#define PCIE_VENDOR_ID_MARVELL (0x11ab)
230#define PCIE_DEVICE_ID_MARVELL_88W8766P (0x2b30)
231
232static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
233 {
234 PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
235 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
236 },
237 {},
238};
239
240MODULE_DEVICE_TABLE(pci, mwifiex_ids);
241
242/* PCI Device Driver */
243static struct pci_driver __refdata mwifiex_pcie = {
244 .name = "mwifiex_pcie",
245 .id_table = mwifiex_ids,
246 .probe = mwifiex_pcie_probe,
247 .remove = mwifiex_pcie_remove,
248#ifdef CONFIG_PM
249 /* Power Management Hooks */
250 .suspend = mwifiex_pcie_suspend,
251 .resume = mwifiex_pcie_resume,
252#endif
253};
254
255/*
256 * This function writes data into PCIE card register.
257 */
258static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
259{
260 struct pcie_service_card *card = adapter->card;
261
262 iowrite32(data, card->pci_mmap1 + reg);
263
264 return 0;
265}
266
267/*
268 * This function reads data from PCIE card register.
269 */
270static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
271{
272 struct pcie_service_card *card = adapter->card;
273
274 *data = ioread32(card->pci_mmap1 + reg);
275
276 return 0;
277}
278
279/*
280 * This function wakes up the card.
281 *
282 * A host power up command is written to the card configuration
283 * register to wake up the card.
284 */
285static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
286{
287 int i = 0;
288
289 while (mwifiex_pcie_ok_to_access_hw(adapter)) {
290 i++;
291 udelay(10);
292 /* 50ms max wait */
293 if (i == 50000)
294 break;
295 }
296
297 dev_dbg(adapter->dev, "event: Wakeup device...\n");
298
299 /* Enable interrupts or any chip access will wakeup device */
300 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK, HOST_INTR_MASK)) {
301 dev_warn(adapter->dev, "Enable host interrupt failed\n");
302 return -1;
303 }
304
305 dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
306 adapter->ps_state = PS_STATE_AWAKE;
307
308 return 0;
309}
310
311/*
312 * This function is called after the card has woken up.
313 *
314 * The card configuration register is reset.
315 */
316static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
317{
318 dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");
319
320 return 0;
321}
322
323/*
324 * This function disables the host interrupt.
325 *
326 * The host interrupt mask is read, the disable bit is reset and
327 * written back to the card host interrupt mask register.
328 */
329static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
330{
331 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
332 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
333 0x00000000)) {
334 dev_warn(adapter->dev, "Disable host interrupt failed\n");
335 return -1;
336 }
337 }
338
339 return 0;
340}
341
342/*
343 * This function enables the host interrupt.
344 *
345 * The host interrupt enable mask is written to the card
346 * host interrupt mask register.
347 */
348static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
349{
350 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
351 /* Simply write the mask to the register */
352 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
353 HOST_INTR_MASK)) {
354 dev_warn(adapter->dev, "Enable host interrupt failed\n");
355 return -1;
356 }
357 }
358
359 return 0;
360}
361
362/*
363 * This function creates buffer descriptor ring for TX
364 */
365static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
366{
367 struct pcie_service_card *card = adapter->card;
368 struct sk_buff *skb;
369 int i;
370 phys_addr_t *buf_pa;
371
372 /*
373 * driver maintaines the write pointer and firmware maintaines the read
374 * pointer. The write pointer starts at 0 (zero) while the read pointer
375 * starts at zero with rollover bit set
376 */
377 card->txbd_wrptr = 0;
378 card->txbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;
379
380 /* allocate shared memory for the BD ring and divide the same in to
381 several descriptors */
382 card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
383 MWIFIEX_MAX_TXRX_BD;
384 dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
385 card->txbd_ring_size);
386 card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL);
387 if (!card->txbd_ring_vbase) {
388 dev_err(adapter->dev, "Unable to allocate buffer for txbd ring.\n");
389 kfree(card->txbd_ring_vbase);
390 return -1;
391 }
392 card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase);
393
394 dev_dbg(adapter->dev, "info: txbd_ring - base: %p, pbase: %#x:%x,"
395 "len: %x\n", card->txbd_ring_vbase,
396 (u32)card->txbd_ring_pbase,
397 (u32)((u64)card->txbd_ring_pbase >> 32),
398 card->txbd_ring_size);
399
400 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
401 card->txbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
402 (card->txbd_ring_vbase +
403 (sizeof(struct mwifiex_pcie_buf_desc) * i));
404
405 /* Allocate buffer here so that firmware can DMA data from it */
406 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
407 if (!skb) {
408 dev_err(adapter->dev, "Unable to allocate skb for TX ring.\n");
409 kfree(card->txbd_ring_vbase);
410 return -ENOMEM;
411 }
412 buf_pa = mwifiex_update_sk_buff_pa(skb);
413
414 skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE);
415 dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, "
416 "buf_base: %p, buf_pbase: %#x:%x, "
417 "buf_len: %#x\n", skb, skb->data,
418 (u32)*buf_pa, (u32)(((u64)*buf_pa >> 32)),
419 skb->len);
420
421 card->tx_buf_list[i] = skb;
422 card->txbd_ring[i]->paddr = *buf_pa;
423 card->txbd_ring[i]->len = (u16)skb->len;
424 card->txbd_ring[i]->flags = 0;
425 }
426
427 return 0;
428}
429
430static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
431{
432 struct pcie_service_card *card = adapter->card;
433 int i;
434
435 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
436 if (card->tx_buf_list[i])
437 dev_kfree_skb_any(card->tx_buf_list[i]);
438 card->tx_buf_list[i] = NULL;
439 card->txbd_ring[i]->paddr = 0;
440 card->txbd_ring[i]->len = 0;
441 card->txbd_ring[i]->flags = 0;
442 card->txbd_ring[i] = NULL;
443 }
444
445 kfree(card->txbd_ring_vbase);
446 card->txbd_ring_size = 0;
447 card->txbd_wrptr = 0;
448 card->txbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
449 card->txbd_ring_vbase = NULL;
450
451 return 0;
452}
453
454/*
455 * This function creates buffer descriptor ring for RX
456 */
457static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
458{
459 struct pcie_service_card *card = adapter->card;
460 struct sk_buff *skb;
461 int i;
462 phys_addr_t *buf_pa;
463
464 /*
465 * driver maintaines the read pointer and firmware maintaines the write
466 * pointer. The write pointer starts at 0 (zero) while the read pointer
467 * starts at zero with rollover bit set
468 */
469 card->rxbd_wrptr = 0;
470 card->rxbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;
471
472 card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
473 MWIFIEX_MAX_TXRX_BD;
474 dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
475 card->rxbd_ring_size);
476 card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL);
477 if (!card->rxbd_ring_vbase) {
478 dev_err(adapter->dev, "Unable to allocate buffer for "
479 "rxbd_ring.\n");
480 return -1;
481 }
482 card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase);
483
484 dev_dbg(adapter->dev, "info: rxbd_ring - base: %p, pbase: %#x:%x,"
485 "len: %#x\n", card->rxbd_ring_vbase,
486 (u32)card->rxbd_ring_pbase,
487 (u32)((u64)card->rxbd_ring_pbase >> 32),
488 card->rxbd_ring_size);
489
490 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
491 card->rxbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
492 (card->rxbd_ring_vbase +
493 (sizeof(struct mwifiex_pcie_buf_desc) * i));
494
495 /* Allocate skb here so that firmware can DMA data from it */
496 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
497 if (!skb) {
498 dev_err(adapter->dev, "Unable to allocate skb for RX ring.\n");
499 kfree(card->rxbd_ring_vbase);
500 return -ENOMEM;
501 }
502 buf_pa = mwifiex_update_sk_buff_pa(skb);
503 skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE);
504
505 dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, "
506 "buf_base: %p, buf_pbase: %#x:%x, "
507 "buf_len: %#x\n", skb, skb->data,
508 (u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
509 skb->len);
510
511 card->rx_buf_list[i] = skb;
512 card->rxbd_ring[i]->paddr = *buf_pa;
513 card->rxbd_ring[i]->len = (u16)skb->len;
514 card->rxbd_ring[i]->flags = 0;
515 }
516
517 return 0;
518}
519
520/*
521 * This function deletes Buffer descriptor ring for RX
522 */
523static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
524{
525 struct pcie_service_card *card = adapter->card;
526 int i;
527
528 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
529 if (card->rx_buf_list[i])
530 dev_kfree_skb_any(card->rx_buf_list[i]);
531 card->rx_buf_list[i] = NULL;
532 card->rxbd_ring[i]->paddr = 0;
533 card->rxbd_ring[i]->len = 0;
534 card->rxbd_ring[i]->flags = 0;
535 card->rxbd_ring[i] = NULL;
536 }
537
538 kfree(card->rxbd_ring_vbase);
539 card->rxbd_ring_size = 0;
540 card->rxbd_wrptr = 0;
541 card->rxbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
542 card->rxbd_ring_vbase = NULL;
543
544 return 0;
545}
546
547/*
548 * This function creates buffer descriptor ring for Events
549 */
550static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
551{
552 struct pcie_service_card *card = adapter->card;
553 struct sk_buff *skb;
554 int i;
555 phys_addr_t *buf_pa;
556
557 /*
558 * driver maintaines the read pointer and firmware maintaines the write
559 * pointer. The write pointer starts at 0 (zero) while the read pointer
560 * starts at zero with rollover bit set
561 */
562 card->evtbd_wrptr = 0;
563 card->evtbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;
564
565 card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
566 MWIFIEX_MAX_EVT_BD;
567 dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
568 card->evtbd_ring_size);
569 card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL);
570 if (!card->evtbd_ring_vbase) {
571 dev_err(adapter->dev, "Unable to allocate buffer. "
572 "Terminating download\n");
573 return -1;
574 }
575 card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase);
576
577 dev_dbg(adapter->dev, "info: CMDRSP/EVT bd_ring - base: %p, "
578 "pbase: %#x:%x, len: %#x\n", card->evtbd_ring_vbase,
579 (u32)card->evtbd_ring_pbase,
580 (u32)((u64)card->evtbd_ring_pbase >> 32),
581 card->evtbd_ring_size);
582
583 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
584 card->evtbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
585 (card->evtbd_ring_vbase +
586 (sizeof(struct mwifiex_pcie_buf_desc) * i));
587
588 /* Allocate skb here so that firmware can DMA data from it */
589 skb = dev_alloc_skb(MAX_EVENT_SIZE);
590 if (!skb) {
591 dev_err(adapter->dev, "Unable to allocate skb for EVENT buf.\n");
592 kfree(card->evtbd_ring_vbase);
593 return -ENOMEM;
594 }
595 buf_pa = mwifiex_update_sk_buff_pa(skb);
596 skb_put(skb, MAX_EVENT_SIZE);
597
598 dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, "
599 "buf_base: %p, buf_pbase: %#x:%x, "
600 "buf_len: %#x\n", skb, skb->data,
601 (u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
602 skb->len);
603
604 card->evt_buf_list[i] = skb;
605 card->evtbd_ring[i]->paddr = *buf_pa;
606 card->evtbd_ring[i]->len = (u16)skb->len;
607 card->evtbd_ring[i]->flags = 0;
608 }
609
610 return 0;
611}
612
613/*
614 * This function deletes Buffer descriptor ring for Events
615 */
616static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
617{
618 struct pcie_service_card *card = adapter->card;
619 int i;
620
621 for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
622 if (card->evt_buf_list[i])
623 dev_kfree_skb_any(card->evt_buf_list[i]);
624 card->evt_buf_list[i] = NULL;
625 card->evtbd_ring[i]->paddr = 0;
626 card->evtbd_ring[i]->len = 0;
627 card->evtbd_ring[i]->flags = 0;
628 card->evtbd_ring[i] = NULL;
629 }
630
631 kfree(card->evtbd_ring_vbase);
632 card->evtbd_wrptr = 0;
633 card->evtbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
634 card->evtbd_ring_size = 0;
635 card->evtbd_ring_vbase = NULL;
636
637 return 0;
638}
639
640/*
641 * This function allocates a buffer for CMDRSP
642 */
643static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
644{
645 struct pcie_service_card *card = adapter->card;
646 struct sk_buff *skb;
647
648 /* Allocate memory for receiving command response data */
649 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
650 if (!skb) {
651 dev_err(adapter->dev, "Unable to allocate skb for command "
652 "response data.\n");
653 return -ENOMEM;
654 }
655 mwifiex_update_sk_buff_pa(skb);
656 skb_put(skb, MWIFIEX_UPLD_SIZE);
657 card->cmdrsp_buf = skb;
658
659 skb = NULL;
660 /* Allocate memory for sending command to firmware */
661 skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER);
662 if (!skb) {
663 dev_err(adapter->dev, "Unable to allocate skb for command "
664 "data.\n");
665 return -ENOMEM;
666 }
667 mwifiex_update_sk_buff_pa(skb);
668 skb_put(skb, MWIFIEX_SIZE_OF_CMD_BUFFER);
669 card->cmd_buf = skb;
670
671 return 0;
672}
673
674/*
675 * This function deletes a buffer for CMDRSP
676 */
677static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
678{
679 struct pcie_service_card *card;
680
681 if (!adapter)
682 return 0;
683
684 card = adapter->card;
685
686 if (card && card->cmdrsp_buf)
687 dev_kfree_skb_any(card->cmdrsp_buf);
688
689 if (card && card->cmd_buf)
690 dev_kfree_skb_any(card->cmd_buf);
691
692 return 0;
693}
694
695/*
696 * This function allocates a buffer for sleep cookie
697 */
698static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
699{
700 struct sk_buff *skb;
701 struct pcie_service_card *card = adapter->card;
702
703 /* Allocate memory for sleep cookie */
704 skb = dev_alloc_skb(sizeof(u32));
705 if (!skb) {
706 dev_err(adapter->dev, "Unable to allocate skb for sleep "
707 "cookie!\n");
708 return -ENOMEM;
709 }
710 mwifiex_update_sk_buff_pa(skb);
711 skb_put(skb, sizeof(u32));
712
713 /* Init val of Sleep Cookie */
714 *(u32 *)skb->data = FW_AWAKE_COOKIE;
715
716 dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
717 *((u32 *)skb->data));
718
719 /* Save the sleep cookie */
720 card->sleep_cookie = skb;
721
722 return 0;
723}
724
725/*
726 * This function deletes buffer for sleep cookie
727 */
728static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
729{
730 struct pcie_service_card *card;
731
732 if (!adapter)
733 return 0;
734
735 card = adapter->card;
736
737 if (card && card->sleep_cookie) {
738 dev_kfree_skb_any(card->sleep_cookie);
739 card->sleep_cookie = NULL;
740 }
741
742 return 0;
743}
744
745/*
746 * This function sends data buffer to device
747 */
748static int
749mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb)
750{
751 struct pcie_service_card *card = adapter->card;
752 u32 wrindx, rdptr;
753 phys_addr_t *buf_pa;
754 __le16 *tmp;
755
756 if (!mwifiex_pcie_ok_to_access_hw(adapter))
757 mwifiex_pm_wakeup_card(adapter);
758
759 /* Read the TX ring read pointer set by firmware */
760 if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) {
761 dev_err(adapter->dev, "SEND DATA: failed to read "
762 "REG_TXBD_RDPTR\n");
763 return -1;
764 }
765
766 wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK;
767
768 dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", rdptr,
769 card->txbd_wrptr);
770 if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) !=
771 (rdptr & MWIFIEX_TXBD_MASK)) ||
772 ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) !=
773 (rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
774 struct sk_buff *skb_data;
775 u8 *payload;
776
777 adapter->data_sent = true;
778 skb_data = card->tx_buf_list[wrindx];
779 memcpy(skb_data->data, skb->data, skb->len);
780 payload = skb_data->data;
781 tmp = (__le16 *)&payload[0];
782 *tmp = cpu_to_le16((u16)skb->len);
783 tmp = (__le16 *)&payload[2];
784 *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
785 skb_put(skb_data, MWIFIEX_RX_DATA_BUF_SIZE - skb_data->len);
786 skb_trim(skb_data, skb->len);
787 buf_pa = MWIFIEX_SKB_PACB(skb_data);
788 card->txbd_ring[wrindx]->paddr = *buf_pa;
789 card->txbd_ring[wrindx]->len = (u16)skb_data->len;
790 card->txbd_ring[wrindx]->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
791 MWIFIEX_BD_FLAG_LAST_DESC;
792
793 if ((++card->txbd_wrptr & MWIFIEX_TXBD_MASK) ==
794 MWIFIEX_MAX_TXRX_BD)
795 card->txbd_wrptr = ((card->txbd_wrptr &
796 MWIFIEX_BD_FLAG_ROLLOVER_IND) ^
797 MWIFIEX_BD_FLAG_ROLLOVER_IND);
798
799 /* Write the TX ring write pointer in to REG_TXBD_WRPTR */
800 if (mwifiex_write_reg(adapter, REG_TXBD_WRPTR,
801 card->txbd_wrptr)) {
802 dev_err(adapter->dev, "SEND DATA: failed to write "
803 "REG_TXBD_WRPTR\n");
804 return 0;
805 }
806
807 /* Send the TX ready interrupt */
808 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
809 CPU_INTR_DNLD_RDY)) {
810 dev_err(adapter->dev, "SEND DATA: failed to assert "
811 "door-bell interrupt.\n");
812 return -1;
813 }
814 dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
815 "%#x> and sent packet to firmware "
816 "successfully\n", rdptr,
817 card->txbd_wrptr);
818 } else {
819 dev_dbg(adapter->dev, "info: TX Ring full, can't send anymore "
820 "packets to firmware\n");
821 adapter->data_sent = true;
822 /* Send the TX ready interrupt */
823 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
824 CPU_INTR_DNLD_RDY))
825 dev_err(adapter->dev, "SEND DATA: failed to assert "
826 "door-bell interrupt\n");
827 return -EBUSY;
828 }
829
830 return 0;
831}
832
833/*
834 * This function handles received buffer ring and
835 * dispatches packets to upper
836 */
837static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
838{
839 struct pcie_service_card *card = adapter->card;
840 u32 wrptr, rd_index;
841 int ret = 0;
842 struct sk_buff *skb_tmp = NULL;
843
844 /* Read the RX ring Write pointer set by firmware */
845 if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) {
846 dev_err(adapter->dev, "RECV DATA: failed to read "
847 "REG_TXBD_RDPTR\n");
848 ret = -1;
849 goto done;
850 }
851
852 while (((wrptr & MWIFIEX_RXBD_MASK) !=
853 (card->rxbd_rdptr & MWIFIEX_RXBD_MASK)) ||
854 ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) ==
855 (card->rxbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
856 struct sk_buff *skb_data;
857 u16 rx_len;
858
859 rd_index = card->rxbd_rdptr & MWIFIEX_RXBD_MASK;
860 skb_data = card->rx_buf_list[rd_index];
861
862 /* Get data length from interface header -
863 first byte is len, second byte is type */
864 rx_len = *((u16 *)skb_data->data);
865 dev_dbg(adapter->dev, "info: RECV DATA: Rd=%#x, Wr=%#x, "
866 "Len=%d\n", card->rxbd_rdptr, wrptr, rx_len);
867 skb_tmp = dev_alloc_skb(rx_len);
868 if (!skb_tmp) {
869 dev_dbg(adapter->dev, "info: Failed to alloc skb "
870 "for RX\n");
871 ret = -EBUSY;
872 goto done;
873 }
874
875 skb_put(skb_tmp, rx_len);
876
877 memcpy(skb_tmp->data, skb_data->data + INTF_HEADER_LEN, rx_len);
878 if ((++card->rxbd_rdptr & MWIFIEX_RXBD_MASK) ==
879 MWIFIEX_MAX_TXRX_BD) {
880 card->rxbd_rdptr = ((card->rxbd_rdptr &
881 MWIFIEX_BD_FLAG_ROLLOVER_IND) ^
882 MWIFIEX_BD_FLAG_ROLLOVER_IND);
883 }
884 dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
885 card->rxbd_rdptr, wrptr);
886
887 /* Write the RX ring read pointer in to REG_RXBD_RDPTR */
888 if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR,
889 card->rxbd_rdptr)) {
890 dev_err(adapter->dev, "RECV DATA: failed to "
891 "write REG_RXBD_RDPTR\n");
892 ret = -1;
893 goto done;
894 }
895
896 /* Read the RX ring Write pointer set by firmware */
897 if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) {
898 dev_err(adapter->dev, "RECV DATA: failed to read "
899 "REG_TXBD_RDPTR\n");
900 ret = -1;
901 goto done;
902 }
903 dev_dbg(adapter->dev, "info: RECV DATA: Received packet from "
904 "firmware successfully\n");
905 mwifiex_handle_rx_packet(adapter, skb_tmp);
906 }
907
908done:
909 if (ret && skb_tmp)
910 dev_kfree_skb_any(skb_tmp);
911 return ret;
912}
913
914/*
915 * This function downloads the boot command to device
916 */
917static int
918mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
919{
920 phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb);
921
922 if (!(skb->data && skb->len && *buf_pa)) {
923 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x:%x, "
924 "%x>\n", __func__, skb->data, skb->len,
925 (u32)*buf_pa, (u32)((u64)*buf_pa >> 32));
926 return -1;
927 }
928
929 /* Write the lower 32bits of the physical address to scratch
930 * register 0 */
931 if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) {
932 dev_err(adapter->dev, "%s: failed to write download command "
933 "to boot code.\n", __func__);
934 return -1;
935 }
936
937 /* Write the upper 32bits of the physical address to scratch
938 * register 1 */
939 if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG,
940 (u32)((u64)*buf_pa >> 32))) {
941 dev_err(adapter->dev, "%s: failed to write download command "
942 "to boot code.\n", __func__);
943 return -1;
944 }
945
946 /* Write the command length to scratch register 2 */
947 if (mwifiex_write_reg(adapter, PCIE_SCRATCH_2_REG, skb->len)) {
948 dev_err(adapter->dev, "%s: failed to write command length to "
949 "scratch register 2\n", __func__);
950 return -1;
951 }
952
953 /* Ring the door bell */
954 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
955 CPU_INTR_DOOR_BELL)) {
956 dev_err(adapter->dev, "%s: failed to assert door-bell "
957 "interrupt.\n", __func__);
958 return -1;
959 }
960
961 return 0;
962}
963
964/*
965 * This function downloads commands to the device
966 */
967static int
968mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
969{
970 struct pcie_service_card *card = adapter->card;
971 int ret = 0;
972 phys_addr_t *cmd_buf_pa;
973 phys_addr_t *cmdrsp_buf_pa;
974
975 if (!(skb->data && skb->len)) {
976 dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
977 __func__, skb->data, skb->len);
978 return -1;
979 }
980
981 /* Make sure a command response buffer is available */
982 if (!card->cmdrsp_buf) {
983 dev_err(adapter->dev, "No response buffer available, send "
984 "command failed\n");
985 return -EBUSY;
986 }
987
988 /* Make sure a command buffer is available */
989 if (!card->cmd_buf) {
990 dev_err(adapter->dev, "Command buffer not available\n");
991 return -EBUSY;
992 }
993
994 adapter->cmd_sent = true;
995 /* Copy the given skb in to DMA accessable shared buffer */
996 skb_put(card->cmd_buf, MWIFIEX_SIZE_OF_CMD_BUFFER - card->cmd_buf->len);
997 skb_trim(card->cmd_buf, skb->len);
998 memcpy(card->cmd_buf->data, skb->data, skb->len);
999
1000 /* To send a command, the driver will:
1001 1. Write the 64bit physical address of the data buffer to
1002 SCRATCH1 + SCRATCH0
1003 2. Ring the door bell (i.e. set the door bell interrupt)
1004
1005 In response to door bell interrupt, the firmware will perform
1006 the DMA of the command packet (first header to obtain the total
1007 length and then rest of the command).
1008 */
1009
1010 if (card->cmdrsp_buf) {
1011 cmdrsp_buf_pa = MWIFIEX_SKB_PACB(card->cmdrsp_buf);
1012 /* Write the lower 32bits of the cmdrsp buffer physical
1013 address */
1014 if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO,
1015 (u32)*cmdrsp_buf_pa)) {
1016 dev_err(adapter->dev, "Failed to write download command to boot code.\n");
1017 ret = -1;
1018 goto done;
1019 }
1020 /* Write the upper 32bits of the cmdrsp buffer physical
1021 address */
1022 if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI,
1023 (u32)((u64)*cmdrsp_buf_pa >> 32))) {
1024 dev_err(adapter->dev, "Failed to write download command"
1025 " to boot code.\n");
1026 ret = -1;
1027 goto done;
1028 }
1029 }
1030
1031 cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf);
1032 /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */
1033 if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO,
1034 (u32)*cmd_buf_pa)) {
1035 dev_err(adapter->dev, "Failed to write download command "
1036 "to boot code.\n");
1037 ret = -1;
1038 goto done;
1039 }
1040 /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */
1041 if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI,
1042 (u32)((u64)*cmd_buf_pa >> 32))) {
1043 dev_err(adapter->dev, "Failed to write download command "
1044 "to boot code.\n");
1045 ret = -1;
1046 goto done;
1047 }
1048
1049 /* Write the command length to REG_CMD_SIZE */
1050 if (mwifiex_write_reg(adapter, REG_CMD_SIZE,
1051 card->cmd_buf->len)) {
1052 dev_err(adapter->dev, "Failed to write command length to "
1053 "REG_CMD_SIZE\n");
1054 ret = -1;
1055 goto done;
1056 }
1057
1058 /* Ring the door bell */
1059 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1060 CPU_INTR_DOOR_BELL)) {
1061 dev_err(adapter->dev, "Failed to assert door-bell "
1062 "interrupt.\n");
1063 ret = -1;
1064 goto done;
1065 }
1066
1067done:
1068 if (ret)
1069 adapter->cmd_sent = false;
1070
1071 return 0;
1072}
1073
1074/*
1075 * This function handles command complete interrupt
1076 */
1077static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
1078{
1079 struct pcie_service_card *card = adapter->card;
1080 int count = 0;
1081
1082 dev_dbg(adapter->dev, "info: Rx CMD Response\n");
1083
1084 if (!adapter->curr_cmd) {
1085 skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN);
1086 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
1087 mwifiex_process_sleep_confirm_resp(adapter,
1088 card->cmdrsp_buf->data,
1089 card->cmdrsp_buf->len);
1090 while (mwifiex_pcie_ok_to_access_hw(adapter) &&
1091 (count++ < 10))
1092 udelay(50);
1093 } else {
1094 dev_err(adapter->dev, "There is no command but "
1095 "got cmdrsp\n");
1096 }
1097 memcpy(adapter->upld_buf, card->cmdrsp_buf->data,
1098 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER,
1099 card->cmdrsp_buf->len));
1100 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
1101 } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
1102 skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN);
1103 adapter->curr_cmd->resp_skb = card->cmdrsp_buf;
1104 adapter->cmd_resp_received = true;
1105 /* Take the pointer and set it to CMD node and will
1106 return in the response complete callback */
1107 card->cmdrsp_buf = NULL;
1108
1109 /* Clear the cmd-rsp buffer address in scratch registers. This
1110 will prevent firmware from writing to the same response
1111 buffer again. */
1112 if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, 0)) {
1113 dev_err(adapter->dev, "cmd_done: failed to clear "
1114 "cmd_rsp address.\n");
1115 return -1;
1116 }
1117 /* Write the upper 32bits of the cmdrsp buffer physical
1118 address */
1119 if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, 0)) {
1120 dev_err(adapter->dev, "cmd_done: failed to clear "
1121 "cmd_rsp address.\n");
1122 return -1;
1123 }
1124 }
1125
1126 return 0;
1127}
1128
1129/*
1130 * Command Response processing complete handler
1131 */
1132static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
1133 struct sk_buff *skb)
1134{
1135 struct pcie_service_card *card = adapter->card;
1136
1137 if (skb) {
1138 card->cmdrsp_buf = skb;
1139 skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
1140 }
1141
1142 return 0;
1143}
1144
1145/*
1146 * This function handles firmware event ready interrupt
1147 */
1148static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1149{
1150 struct pcie_service_card *card = adapter->card;
1151 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1152 u32 wrptr, event;
1153
1154 if (adapter->event_received) {
1155 dev_dbg(adapter->dev, "info: Event being processed, "\
1156 "do not process this interrupt just yet\n");
1157 return 0;
1158 }
1159
1160 if (rdptr >= MWIFIEX_MAX_EVT_BD) {
1161 dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
1162 return -1;
1163 }
1164
1165 /* Read the event ring write pointer set by firmware */
1166 if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) {
1167 dev_err(adapter->dev, "EventReady: failed to read REG_EVTBD_WRPTR\n");
1168 return -1;
1169 }
1170
1171 dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
1172 card->evtbd_rdptr, wrptr);
1173 if (((wrptr & MWIFIEX_EVTBD_MASK) !=
1174 (card->evtbd_rdptr & MWIFIEX_EVTBD_MASK)) ||
1175 ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) ==
1176 (card->evtbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
1177 struct sk_buff *skb_cmd;
1178 __le16 data_len = 0;
1179 u16 evt_len;
1180
1181 dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
1182 skb_cmd = card->evt_buf_list[rdptr];
1183 /* Take the pointer and set it to event pointer in adapter
1184 and will return back after event handling callback */
1185 card->evt_buf_list[rdptr] = NULL;
1186 card->evtbd_ring[rdptr]->paddr = 0;
1187 card->evtbd_ring[rdptr]->len = 0;
1188 card->evtbd_ring[rdptr]->flags = 0;
1189
1190 event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
1191 adapter->event_cause = event;
1192 /* The first 4bytes will be the event transfer header
1193 len is 2 bytes followed by type which is 2 bytes */
1194 memcpy(&data_len, skb_cmd->data, sizeof(__le16));
1195 evt_len = le16_to_cpu(data_len);
1196
1197 skb_pull(skb_cmd, INTF_HEADER_LEN);
1198 dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);
1199
1200 if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE))
1201 memcpy(adapter->event_body, skb_cmd->data +
1202 MWIFIEX_EVENT_HEADER_LEN, evt_len -
1203 MWIFIEX_EVENT_HEADER_LEN);
1204
1205 adapter->event_received = true;
1206 adapter->event_skb = skb_cmd;
1207
1208 /* Do not update the event read pointer here, wait till the
1209 buffer is released. This is just to make things simpler,
1210 we need to find a better method of managing these buffers.
1211 */
1212 }
1213
1214 return 0;
1215}
1216
1217/*
1218 * Event processing complete handler
1219 */
1220static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
1221 struct sk_buff *skb)
1222{
1223 struct pcie_service_card *card = adapter->card;
1224 int ret = 0;
1225 u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
1226 u32 wrptr;
1227 phys_addr_t *buf_pa;
1228
1229 if (!skb)
1230 return 0;
1231
1232 if (rdptr >= MWIFIEX_MAX_EVT_BD)
1233 dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
1234 rdptr);
1235
1236 /* Read the event ring write pointer set by firmware */
1237 if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) {
1238 dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_WRPTR\n");
1239 ret = -1;
1240 goto done;
1241 }
1242
1243 if (!card->evt_buf_list[rdptr]) {
1244 skb_push(skb, INTF_HEADER_LEN);
1245 card->evt_buf_list[rdptr] = skb;
1246 buf_pa = MWIFIEX_SKB_PACB(skb);
1247 card->evtbd_ring[rdptr]->paddr = *buf_pa;
1248 card->evtbd_ring[rdptr]->len = (u16)skb->len;
1249 card->evtbd_ring[rdptr]->flags = 0;
1250 skb = NULL;
1251 } else {
1252 dev_dbg(adapter->dev, "info: ERROR: Buffer is still valid at "
1253 "index %d, <%p, %p>\n", rdptr,
1254 card->evt_buf_list[rdptr], skb);
1255 }
1256
1257 if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
1258 card->evtbd_rdptr = ((card->evtbd_rdptr &
1259 MWIFIEX_BD_FLAG_ROLLOVER_IND) ^
1260 MWIFIEX_BD_FLAG_ROLLOVER_IND);
1261 }
1262
1263 dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
1264 card->evtbd_rdptr, wrptr);
1265
1266 /* Write the event ring read pointer in to REG_EVTBD_RDPTR */
1267 if (mwifiex_write_reg(adapter, REG_EVTBD_RDPTR, card->evtbd_rdptr)) {
1268 dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_RDPTR\n");
1269 ret = -1;
1270 goto done;
1271 }
1272
1273done:
1274 /* Free the buffer for failure case */
1275 if (ret && skb)
1276 dev_kfree_skb_any(skb);
1277
1278 dev_dbg(adapter->dev, "info: Check Events Again\n");
1279 ret = mwifiex_pcie_process_event_ready(adapter);
1280
1281 return ret;
1282}
1283
1284/*
1285 * This function downloads the firmware to the card.
1286 *
1287 * Firmware is downloaded to the card in blocks. Every block download
1288 * is tested for CRC errors, and retried a number of times before
1289 * returning failure.
1290 */
1291static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1292 struct mwifiex_fw_image *fw)
1293{
1294 int ret;
1295 u8 *firmware = fw->fw_buf;
1296 u32 firmware_len = fw->fw_len;
1297 u32 offset = 0;
1298 struct sk_buff *skb;
1299 u32 txlen, tx_blocks = 0, tries, len;
1300 u32 block_retry_cnt = 0;
1301
1302 if (!adapter) {
1303 pr_err("adapter structure is not valid\n");
1304 return -1;
1305 }
1306
1307 if (!firmware || !firmware_len) {
1308 dev_err(adapter->dev, "No firmware image found! "
1309 "Terminating download\n");
1310 return -1;
1311 }
1312
1313 dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
1314 firmware_len);
1315
1316 if (mwifiex_pcie_disable_host_int(adapter)) {
1317 dev_err(adapter->dev, "%s: Disabling interrupts"
1318 " failed.\n", __func__);
1319 return -1;
1320 }
1321
1322 skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
1323 if (!skb) {
1324 ret = -ENOMEM;
1325 goto done;
1326 }
1327 mwifiex_update_sk_buff_pa(skb);
1328
1329 /* Perform firmware data transfer */
1330 do {
1331 u32 ireg_intr = 0;
1332
1333 /* More data? */
1334 if (offset >= firmware_len)
1335 break;
1336
1337 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
1338 ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_2_REG,
1339 &len);
1340 if (ret) {
1341 dev_warn(adapter->dev, "Failed reading length from boot code\n");
1342 goto done;
1343 }
1344 if (len)
1345 break;
1346 udelay(10);
1347 }
1348
1349 if (!len) {
1350 break;
1351 } else if (len > MWIFIEX_UPLD_SIZE) {
1352 pr_err("FW download failure @ %d, invalid length %d\n",
1353 offset, len);
1354 ret = -1;
1355 goto done;
1356 }
1357
1358 txlen = len;
1359
1360 if (len & BIT(0)) {
1361 block_retry_cnt++;
1362 if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
1363 pr_err("FW download failure @ %d, over max "
1364 "retry count\n", offset);
1365 ret = -1;
1366 goto done;
1367 }
1368 dev_err(adapter->dev, "FW CRC error indicated by the "
1369 "helper: len = 0x%04X, txlen = "
1370 "%d\n", len, txlen);
1371 len &= ~BIT(0);
1372 /* Setting this to 0 to resend from same offset */
1373 txlen = 0;
1374 } else {
1375 block_retry_cnt = 0;
1376 /* Set blocksize to transfer - checking for
1377 last block */
1378 if (firmware_len - offset < txlen)
1379 txlen = firmware_len - offset;
1380
1381 dev_dbg(adapter->dev, ".");
1382
1383 tx_blocks =
1384 (txlen + MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) /
1385 MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD;
1386
1387 /* Copy payload to buffer */
1388 memmove(skb->data, &firmware[offset], txlen);
1389 }
1390
1391 skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
1392 skb_trim(skb, tx_blocks * MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD);
1393
1394 /* Send the boot command to device */
1395 if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
1396 dev_err(adapter->dev, "Failed to send firmware download command\n");
1397 ret = -1;
1398 goto done;
1399 }
1400 /* Wait for the command done interrupt */
1401 do {
1402 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
1403 &ireg_intr)) {
1404 dev_err(adapter->dev, "%s: Failed to read "
1405 "interrupt status during "
1406 "fw dnld.\n", __func__);
1407 ret = -1;
1408 goto done;
1409 }
1410 } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
1411 CPU_INTR_DOOR_BELL);
1412 offset += txlen;
1413 } while (true);
1414
1415 dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
1416 offset);
1417
1418 ret = 0;
1419
1420done:
1421 dev_kfree_skb_any(skb);
1422 return ret;
1423}
1424
1425/*
1426 * This function checks the firmware status in card.
1427 *
1428 * The winner interface is also determined by this function.
1429 */
1430static int
1431mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
1432{
1433 int ret = 0;
1434 u32 firmware_stat, winner_status;
1435 u32 tries;
1436
1437 /* Mask spurios interrupts */
1438 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
1439 HOST_INTR_MASK)) {
1440 dev_warn(adapter->dev, "Write register failed\n");
1441 return -1;
1442 }
1443
1444 dev_dbg(adapter->dev, "Setting driver ready signature\n");
1445 if (mwifiex_write_reg(adapter, REG_DRV_READY, FIRMWARE_READY_PCIE)) {
1446 dev_err(adapter->dev, "Failed to write driver ready signature\n");
1447 return -1;
1448 }
1449
1450 /* Wait for firmware initialization event */
1451 for (tries = 0; tries < poll_num; tries++) {
1452 if (mwifiex_read_reg(adapter, PCIE_SCRATCH_3_REG,
1453 &firmware_stat))
1454 ret = -1;
1455 else
1456 ret = 0;
1457 if (ret)
1458 continue;
1459 if (firmware_stat == FIRMWARE_READY_PCIE) {
1460 ret = 0;
1461 break;
1462 } else {
1463 mdelay(100);
1464 ret = -1;
1465 }
1466 }
1467
1468 if (ret) {
1469 if (mwifiex_read_reg(adapter, PCIE_SCRATCH_3_REG,
1470 &winner_status))
1471 ret = -1;
1472 else if (!winner_status) {
1473 dev_err(adapter->dev, "PCI-E is the winner\n");
1474 adapter->winner = 1;
1475 ret = -1;
1476 } else {
1477 dev_err(adapter->dev, "PCI-E is not the winner <%#x, %d>, exit download\n",
1478 ret, adapter->winner);
1479 ret = 0;
1480 }
1481 }
1482
1483 return ret;
1484}
1485
1486/*
1487 * This function reads the interrupt status from card.
1488 */
1489static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
1490{
1491 u32 pcie_ireg;
1492 unsigned long flags;
1493
1494 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1495 return;
1496
1497 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
1498 dev_warn(adapter->dev, "Read register failed\n");
1499 return;
1500 }
1501
1502 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
1503
1504 mwifiex_pcie_disable_host_int(adapter);
1505
1506 /* Clear the pending interrupts */
1507 if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
1508 ~pcie_ireg)) {
1509 dev_warn(adapter->dev, "Write register failed\n");
1510 return;
1511 }
1512 spin_lock_irqsave(&adapter->int_lock, flags);
1513 adapter->int_status |= pcie_ireg;
1514 spin_unlock_irqrestore(&adapter->int_lock, flags);
1515
1516 if (pcie_ireg & HOST_INTR_CMD_DONE) {
1517 if ((adapter->ps_state == PS_STATE_SLEEP_CFM) ||
1518 (adapter->ps_state == PS_STATE_SLEEP)) {
1519 mwifiex_pcie_enable_host_int(adapter);
1520 if (mwifiex_write_reg(adapter,
1521 PCIE_CPU_INT_EVENT,
1522 CPU_INTR_SLEEP_CFM_DONE)) {
1523 dev_warn(adapter->dev, "Write register"
1524 " failed\n");
1525 return;
1526
1527 }
1528 }
1529 } else if (!adapter->pps_uapsd_mode &&
1530 adapter->ps_state == PS_STATE_SLEEP) {
1531 /* Potentially for PCIe we could get other
1532 * interrupts like shared. Don't change power
1533 * state until cookie is set */
1534 if (mwifiex_pcie_ok_to_access_hw(adapter))
1535 adapter->ps_state = PS_STATE_AWAKE;
1536 }
1537 }
1538}
1539
1540/*
1541 * Interrupt handler for PCIe root port
1542 *
1543 * This function reads the interrupt status from firmware and assigns
1544 * the main process in workqueue which will handle the interrupt.
1545 */
1546static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
1547{
1548 struct pci_dev *pdev = (struct pci_dev *)context;
1549 struct pcie_service_card *card;
1550 struct mwifiex_adapter *adapter;
1551
1552 if (!pdev) {
1553 pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
1554 goto exit;
1555 }
1556
1557 card = (struct pcie_service_card *) pci_get_drvdata(pdev);
1558 if (!card || !card->adapter) {
1559 pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
1560 card ? card->adapter : NULL);
1561 goto exit;
1562 }
1563 adapter = card->adapter;
1564
1565 if (adapter->surprise_removed)
1566 goto exit;
1567
1568 mwifiex_interrupt_status(adapter);
1569 queue_work(adapter->workqueue, &adapter->main_work);
1570
1571exit:
1572 return IRQ_HANDLED;
1573}
1574
1575/*
1576 * This function checks the current interrupt status.
1577 *
1578 * The following interrupts are checked and handled by this function -
1579 * - Data sent
1580 * - Command sent
1581 * - Command received
1582 * - Packets received
1583 * - Events received
1584 *
1585 * In case of Rx packets received, the packets are uploaded from card to
1586 * host and processed accordingly.
1587 */
1588static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1589{
1590 int ret;
1591 u32 pcie_ireg = 0;
1592 unsigned long flags;
1593
1594 spin_lock_irqsave(&adapter->int_lock, flags);
1595 /* Clear out unused interrupts */
1596 adapter->int_status &= HOST_INTR_MASK;
1597 spin_unlock_irqrestore(&adapter->int_lock, flags);
1598
1599 while (adapter->int_status & HOST_INTR_MASK) {
1600 if (adapter->int_status & HOST_INTR_DNLD_DONE) {
1601 adapter->int_status &= ~HOST_INTR_DNLD_DONE;
1602 if (adapter->data_sent) {
1603 dev_dbg(adapter->dev, "info: DATA sent Interrupt\n");
1604 adapter->data_sent = false;
1605 }
1606 }
1607 if (adapter->int_status & HOST_INTR_UPLD_RDY) {
1608 adapter->int_status &= ~HOST_INTR_UPLD_RDY;
1609 dev_dbg(adapter->dev, "info: Rx DATA\n");
1610 ret = mwifiex_pcie_process_recv_data(adapter);
1611 if (ret)
1612 return ret;
1613 }
1614 if (adapter->int_status & HOST_INTR_EVENT_RDY) {
1615 adapter->int_status &= ~HOST_INTR_EVENT_RDY;
1616 dev_dbg(adapter->dev, "info: Rx EVENT\n");
1617 ret = mwifiex_pcie_process_event_ready(adapter);
1618 if (ret)
1619 return ret;
1620 }
1621
1622 if (adapter->int_status & HOST_INTR_CMD_DONE) {
1623 adapter->int_status &= ~HOST_INTR_CMD_DONE;
1624 if (adapter->cmd_sent) {
1625 dev_dbg(adapter->dev, "info: CMD sent Interrupt\n");
1626 adapter->cmd_sent = false;
1627 }
1628 /* Handle command response */
1629 ret = mwifiex_pcie_process_cmd_complete(adapter);
1630 if (ret)
1631 return ret;
1632 }
1633
1634 if (mwifiex_pcie_ok_to_access_hw(adapter)) {
1635 if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
1636 &pcie_ireg)) {
1637 dev_warn(adapter->dev, "Read register failed\n");
1638 return -1;
1639 }
1640
1641 if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
1642 if (mwifiex_write_reg(adapter,
1643 PCIE_HOST_INT_STATUS, ~pcie_ireg)) {
1644 dev_warn(adapter->dev, "Write register"
1645 " failed\n");
1646 return -1;
1647 }
1648 adapter->int_status |= pcie_ireg;
1649 adapter->int_status &= HOST_INTR_MASK;
1650 }
1651
1652 }
1653 }
1654 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
1655 adapter->cmd_sent, adapter->data_sent);
1656 mwifiex_pcie_enable_host_int(adapter);
1657
1658 return 0;
1659}
1660
1661/*
1662 * This function downloads data from driver to card.
1663 *
1664 * Both commands and data packets are transferred to the card by this
1665 * function.
1666 *
1667 * This function adds the PCIE specific header to the front of the buffer
1668 * before transferring. The header contains the length of the packet and
1669 * the type. The firmware handles the packets based upon this set type.
1670 */
1671static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
1672 struct sk_buff *skb,
1673 struct mwifiex_tx_param *tx_param)
1674{
1675 if (!adapter || !skb) {
1676 dev_err(adapter->dev, "Invalid parameter in %s <%p, %p>\n",
1677 __func__, adapter, skb);
1678 return -1;
1679 }
1680
1681 if (type == MWIFIEX_TYPE_DATA)
1682 return mwifiex_pcie_send_data(adapter, skb);
1683 else if (type == MWIFIEX_TYPE_CMD)
1684 return mwifiex_pcie_send_cmd(adapter, skb);
1685
1686 return 0;
1687}
1688
1689/*
1690 * This function initializes the PCI-E host memory space, WCB rings, etc.
1691 *
1692 * The following initializations steps are followed -
1693 * - Allocate TXBD ring buffers
1694 * - Allocate RXBD ring buffers
1695 * - Allocate event BD ring buffers
1696 * - Allocate command response ring buffer
1697 * - Allocate sleep cookie buffer
1698 */
1699static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
1700{
1701 struct pcie_service_card *card = adapter->card;
1702 int ret;
1703 struct pci_dev *pdev = card->dev;
1704
1705 pci_set_drvdata(pdev, card);
1706
1707 ret = pci_enable_device(pdev);
1708 if (ret)
1709 goto err_enable_dev;
1710
1711 pci_set_master(pdev);
1712
1713 dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
1714 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
1715 if (ret) {
1716 dev_err(adapter->dev, "set_dma_mask(32) failed\n");
1717 goto err_set_dma_mask;
1718 }
1719
1720 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
1721 if (ret) {
1722 dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
1723 goto err_set_dma_mask;
1724 }
1725
1726 ret = pci_request_region(pdev, 0, DRV_NAME);
1727 if (ret) {
1728 dev_err(adapter->dev, "req_reg(0) error\n");
1729 goto err_req_region0;
1730 }
1731 card->pci_mmap = pci_iomap(pdev, 0, 0);
1732 if (!card->pci_mmap) {
1733 dev_err(adapter->dev, "iomap(0) error\n");
1734 goto err_iomap0;
1735 }
1736 ret = pci_request_region(pdev, 2, DRV_NAME);
1737 if (ret) {
1738 dev_err(adapter->dev, "req_reg(2) error\n");
1739 goto err_req_region2;
1740 }
1741 card->pci_mmap1 = pci_iomap(pdev, 2, 0);
1742 if (!card->pci_mmap1) {
1743 dev_err(adapter->dev, "iomap(2) error\n");
1744 goto err_iomap2;
1745 }
1746
1747 dev_dbg(adapter->dev, "PCI memory map Virt0: %p PCI memory map Virt2: "
1748 "%p\n", card->pci_mmap, card->pci_mmap1);
1749
1750 card->cmdrsp_buf = NULL;
1751 ret = mwifiex_pcie_create_txbd_ring(adapter);
1752 if (ret)
1753 goto err_cre_txbd;
1754 ret = mwifiex_pcie_create_rxbd_ring(adapter);
1755 if (ret)
1756 goto err_cre_rxbd;
1757 ret = mwifiex_pcie_create_evtbd_ring(adapter);
1758 if (ret)
1759 goto err_cre_evtbd;
1760 ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
1761 if (ret)
1762 goto err_alloc_cmdbuf;
1763 ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
1764 if (ret)
1765 goto err_alloc_cookie;
1766
1767 return ret;
1768
1769err_alloc_cookie:
1770 mwifiex_pcie_delete_cmdrsp_buf(adapter);
1771err_alloc_cmdbuf:
1772 mwifiex_pcie_delete_evtbd_ring(adapter);
1773err_cre_evtbd:
1774 mwifiex_pcie_delete_rxbd_ring(adapter);
1775err_cre_rxbd:
1776 mwifiex_pcie_delete_txbd_ring(adapter);
1777err_cre_txbd:
1778 pci_iounmap(pdev, card->pci_mmap1);
1779err_iomap2:
1780 pci_release_region(pdev, 2);
1781err_req_region2:
1782 pci_iounmap(pdev, card->pci_mmap);
1783err_iomap0:
1784 pci_release_region(pdev, 0);
1785err_req_region0:
1786err_set_dma_mask:
1787 pci_disable_device(pdev);
1788err_enable_dev:
1789 pci_set_drvdata(pdev, NULL);
1790 return ret;
1791}
1792
1793/*
1794 * This function cleans up the allocated card buffers.
1795 *
1796 * The following are freed by this function -
1797 * - TXBD ring buffers
1798 * - RXBD ring buffers
1799 * - Event BD ring buffers
1800 * - Command response ring buffer
1801 * - Sleep cookie buffer
1802 */
1803static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
1804{
1805 struct pcie_service_card *card = adapter->card;
1806 struct pci_dev *pdev = card->dev;
1807
1808 mwifiex_pcie_delete_sleep_cookie_buf(adapter);
1809 mwifiex_pcie_delete_cmdrsp_buf(adapter);
1810 mwifiex_pcie_delete_evtbd_ring(adapter);
1811 mwifiex_pcie_delete_rxbd_ring(adapter);
1812 mwifiex_pcie_delete_txbd_ring(adapter);
1813 card->cmdrsp_buf = NULL;
1814
1815 dev_dbg(adapter->dev, "Clearing driver ready signature\n");
1816 if (user_rmmod) {
1817 if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000))
1818 dev_err(adapter->dev, "Failed to write driver not-ready signature\n");
1819 }
1820
1821 if (pdev) {
1822 pci_iounmap(pdev, card->pci_mmap);
1823 pci_iounmap(pdev, card->pci_mmap1);
1824
1825 pci_release_regions(pdev);
1826 pci_disable_device(pdev);
1827 pci_set_drvdata(pdev, NULL);
1828 }
1829}
1830
1831/*
1832 * This function registers the PCIE device.
1833 *
1834 * PCIE IRQ is claimed, block size is set and driver data is initialized.
1835 */
1836static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
1837{
1838 int ret;
1839 struct pcie_service_card *card = adapter->card;
1840 struct pci_dev *pdev = card->dev;
1841
1842 /* save adapter pointer in card */
1843 card->adapter = adapter;
1844
1845 ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
1846 "MRVL_PCIE", pdev);
1847 if (ret) {
1848 pr_err("request_irq failed: ret=%d\n", ret);
1849 adapter->card = NULL;
1850 return -1;
1851 }
1852
1853 adapter->dev = &pdev->dev;
1854 strcpy(adapter->fw_name, PCIE8766_DEFAULT_FW_NAME);
1855
1856 return 0;
1857}
1858
1859/*
1860 * This function unregisters the PCIE device.
1861 *
1862 * The PCIE IRQ is released, the function is disabled and driver
1863 * data is set to null.
1864 */
1865static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
1866{
1867 struct pcie_service_card *card = adapter->card;
1868
1869 if (card) {
1870 dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
1871 free_irq(card->dev->irq, card->dev);
1872 }
1873}
1874
1875static struct mwifiex_if_ops pcie_ops = {
1876 .init_if = mwifiex_pcie_init,
1877 .cleanup_if = mwifiex_pcie_cleanup,
1878 .check_fw_status = mwifiex_check_fw_status,
1879 .prog_fw = mwifiex_prog_fw_w_helper,
1880 .register_dev = mwifiex_register_dev,
1881 .unregister_dev = mwifiex_unregister_dev,
1882 .enable_int = mwifiex_pcie_enable_host_int,
1883 .process_int_status = mwifiex_process_int_status,
1884 .host_to_card = mwifiex_pcie_host_to_card,
1885 .wakeup = mwifiex_pm_wakeup_card,
1886 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
1887
1888 /* PCIE specific */
1889 .cmdrsp_complete = mwifiex_pcie_cmdrsp_complete,
1890 .event_complete = mwifiex_pcie_event_complete,
1891 .update_mp_end_port = NULL,
1892 .cleanup_mpa_buf = NULL,
1893};
1894
1895/*
1896 * This function initializes the PCIE driver module.
1897 *
1898 * This initiates the semaphore and registers the device with
1899 * PCIE bus.
1900 */
1901static int mwifiex_pcie_init_module(void)
1902{
1903 int ret;
1904
1905 pr_debug("Marvell 8766 PCIe Driver\n");
1906
1907 sema_init(&add_remove_card_sem, 1);
1908
1909 /* Clear the flag in case user removes the card. */
1910 user_rmmod = 0;
1911
1912 ret = pci_register_driver(&mwifiex_pcie);
1913 if (ret)
1914 pr_err("Driver register failed!\n");
1915 else
1916 pr_debug("info: Driver registered successfully!\n");
1917
1918 return ret;
1919}
1920
1921/*
1922 * This function cleans up the PCIE driver.
1923 *
1924 * The following major steps are followed for cleanup -
1925 * - Resume the device if its suspended
1926 * - Disconnect the device if connected
1927 * - Shutdown the firmware
1928 * - Unregister the device from PCIE bus.
1929 */
1930static void mwifiex_pcie_cleanup_module(void)
1931{
1932 if (!down_interruptible(&add_remove_card_sem))
1933 up(&add_remove_card_sem);
1934
1935 /* Set the flag as user is removing this module. */
1936 user_rmmod = 1;
1937
1938 pci_unregister_driver(&mwifiex_pcie);
1939}
1940
1941module_init(mwifiex_pcie_init_module);
1942module_exit(mwifiex_pcie_cleanup_module);
1943
1944MODULE_AUTHOR("Marvell International Ltd.");
1945MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
1946MODULE_VERSION(PCIE_VERSION);
1947MODULE_LICENSE("GPL v2");
1948MODULE_FIRMWARE("mrvl/pcie8766_uapsta.bin");
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h
new file mode 100644
index 000000000000..445ff21772e2
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/pcie.h
@@ -0,0 +1,148 @@
1/* @file mwifiex_pcie.h
2 *
3 * @brief This file contains definitions for PCI-E interface.
4 * driver.
5 *
6 * Copyright (C) 2011, Marvell International Ltd.
7 *
8 * This software file (the "File") is distributed by Marvell International
9 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
10 * (the "License"). You may use, redistribute and/or modify this File in
11 * accordance with the terms and conditions of the License, a copy of which
12 * is available by writing to the Free Software Foundation, Inc.,
13 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
14 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
15 *
16 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
18 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
19 * this warranty disclaimer.
20 */
21
22#ifndef _MWIFIEX_PCIE_H
23#define _MWIFIEX_PCIE_H
24
25#include <linux/pci.h>
26#include <linux/pcieport_if.h>
27#include <linux/interrupt.h>
28
29#include "main.h"
30
31#define PCIE8766_DEFAULT_FW_NAME "mrvl/pcie8766_uapsta.bin"
32
33/* Constants for Buffer Descriptor (BD) rings */
34#define MWIFIEX_MAX_TXRX_BD 0x20
35#define MWIFIEX_TXBD_MASK 0x3F
36#define MWIFIEX_RXBD_MASK 0x3F
37
38#define MWIFIEX_MAX_EVT_BD 0x04
39#define MWIFIEX_EVTBD_MASK 0x07
40
41/* PCIE INTERNAL REGISTERS */
42#define PCIE_SCRATCH_0_REG 0xC10
43#define PCIE_SCRATCH_1_REG 0xC14
44#define PCIE_CPU_INT_EVENT 0xC18
45#define PCIE_CPU_INT_STATUS 0xC1C
46#define PCIE_HOST_INT_STATUS 0xC30
47#define PCIE_HOST_INT_MASK 0xC34
48#define PCIE_HOST_INT_STATUS_MASK 0xC3C
49#define PCIE_SCRATCH_2_REG 0xC40
50#define PCIE_SCRATCH_3_REG 0xC44
51#define PCIE_SCRATCH_4_REG 0xCC0
52#define PCIE_SCRATCH_5_REG 0xCC4
53#define PCIE_SCRATCH_6_REG 0xCC8
54#define PCIE_SCRATCH_7_REG 0xCCC
55#define PCIE_SCRATCH_8_REG 0xCD0
56#define PCIE_SCRATCH_9_REG 0xCD4
57#define PCIE_SCRATCH_10_REG 0xCD8
58#define PCIE_SCRATCH_11_REG 0xCDC
59#define PCIE_SCRATCH_12_REG 0xCE0
60
61#define CPU_INTR_DNLD_RDY BIT(0)
62#define CPU_INTR_DOOR_BELL BIT(1)
63#define CPU_INTR_SLEEP_CFM_DONE BIT(2)
64#define CPU_INTR_RESET BIT(3)
65
66#define HOST_INTR_DNLD_DONE BIT(0)
67#define HOST_INTR_UPLD_RDY BIT(1)
68#define HOST_INTR_CMD_DONE BIT(2)
69#define HOST_INTR_EVENT_RDY BIT(3)
70#define HOST_INTR_MASK (HOST_INTR_DNLD_DONE | \
71 HOST_INTR_UPLD_RDY | \
72 HOST_INTR_CMD_DONE | \
73 HOST_INTR_EVENT_RDY)
74
75#define MWIFIEX_BD_FLAG_ROLLOVER_IND BIT(7)
76#define MWIFIEX_BD_FLAG_FIRST_DESC BIT(0)
77#define MWIFIEX_BD_FLAG_LAST_DESC BIT(1)
78#define REG_CMD_ADDR_LO PCIE_SCRATCH_0_REG
79#define REG_CMD_ADDR_HI PCIE_SCRATCH_1_REG
80#define REG_CMD_SIZE PCIE_SCRATCH_2_REG
81
82#define REG_CMDRSP_ADDR_LO PCIE_SCRATCH_4_REG
83#define REG_CMDRSP_ADDR_HI PCIE_SCRATCH_5_REG
84
85/* TX buffer description read pointer */
86#define REG_TXBD_RDPTR PCIE_SCRATCH_6_REG
87/* TX buffer description write pointer */
88#define REG_TXBD_WRPTR PCIE_SCRATCH_7_REG
89/* RX buffer description read pointer */
90#define REG_RXBD_RDPTR PCIE_SCRATCH_8_REG
91/* RX buffer description write pointer */
92#define REG_RXBD_WRPTR PCIE_SCRATCH_9_REG
93/* Event buffer description read pointer */
94#define REG_EVTBD_RDPTR PCIE_SCRATCH_10_REG
95/* Event buffer description write pointer */
96#define REG_EVTBD_WRPTR PCIE_SCRATCH_11_REG
97/* Driver ready signature write pointer */
98#define REG_DRV_READY PCIE_SCRATCH_12_REG
99
100/* Max retry number of command write */
101#define MAX_WRITE_IOMEM_RETRY 2
102/* Define PCIE block size for firmware download */
103#define MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD 256
104/* FW awake cookie after FW ready */
105#define FW_AWAKE_COOKIE (0xAA55AA55)
106
107struct mwifiex_pcie_buf_desc {
108 u64 paddr;
109 u16 len;
110 u16 flags;
111} __packed;
112
113struct pcie_service_card {
114 struct pci_dev *dev;
115 struct mwifiex_adapter *adapter;
116
117 u32 txbd_wrptr;
118 u32 txbd_rdptr;
119 u32 txbd_ring_size;
120 u8 *txbd_ring_vbase;
121 phys_addr_t txbd_ring_pbase;
122 struct mwifiex_pcie_buf_desc *txbd_ring[MWIFIEX_MAX_TXRX_BD];
123 struct sk_buff *tx_buf_list[MWIFIEX_MAX_TXRX_BD];
124
125 u32 rxbd_wrptr;
126 u32 rxbd_rdptr;
127 u32 rxbd_ring_size;
128 u8 *rxbd_ring_vbase;
129 phys_addr_t rxbd_ring_pbase;
130 struct mwifiex_pcie_buf_desc *rxbd_ring[MWIFIEX_MAX_TXRX_BD];
131 struct sk_buff *rx_buf_list[MWIFIEX_MAX_TXRX_BD];
132
133 u32 evtbd_wrptr;
134 u32 evtbd_rdptr;
135 u32 evtbd_ring_size;
136 u8 *evtbd_ring_vbase;
137 phys_addr_t evtbd_ring_pbase;
138 struct mwifiex_pcie_buf_desc *evtbd_ring[MWIFIEX_MAX_EVT_BD];
139 struct sk_buff *evt_buf_list[MWIFIEX_MAX_EVT_BD];
140
141 struct sk_buff *cmd_buf;
142 struct sk_buff *cmdrsp_buf;
143 struct sk_buff *sleep_cookie;
144 void __iomem *pci_mmap;
145 void __iomem *pci_mmap1;
146};
147
148#endif /* _MWIFIEX_PCIE_H */
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index ca3761965e85..dae8dbb24a03 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -172,29 +172,6 @@ mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
172} 172}
173 173
174/* 174/*
175 * Sends IOCTL request to start a scan with user configurations.
176 *
177 * This function allocates the IOCTL request buffer, fills it
178 * with requisite parameters and calls the IOCTL handler.
179 *
180 * Upon completion, it also generates a wireless event to notify
181 * applications.
182 */
183int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
184 struct mwifiex_user_scan_cfg *scan_req)
185{
186 int status;
187
188 priv->adapter->cmd_wait_q.condition = false;
189
190 status = mwifiex_scan_networks(priv, scan_req);
191 if (!status)
192 status = mwifiex_wait_queue_complete(priv->adapter);
193
194 return status;
195}
196
197/*
198 * This function checks if wapi is enabled in driver and scanned network is 175 * This function checks if wapi is enabled in driver and scanned network is
199 * compatible with it. 176 * compatible with it.
200 */ 177 */
@@ -1316,8 +1293,8 @@ mwifiex_radio_type_to_band(u8 radio_type)
1316 * order to send the appropriate scan commands to firmware to populate or 1293 * order to send the appropriate scan commands to firmware to populate or
1317 * update the internal driver scan table. 1294 * update the internal driver scan table.
1318 */ 1295 */
1319int mwifiex_scan_networks(struct mwifiex_private *priv, 1296static int mwifiex_scan_networks(struct mwifiex_private *priv,
1320 const struct mwifiex_user_scan_cfg *user_scan_in) 1297 const struct mwifiex_user_scan_cfg *user_scan_in)
1321{ 1298{
1322 int ret = 0; 1299 int ret = 0;
1323 struct mwifiex_adapter *adapter = priv->adapter; 1300 struct mwifiex_adapter *adapter = priv->adapter;
@@ -1380,6 +1357,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
1380 list_del(&cmd_node->list); 1357 list_del(&cmd_node->list);
1381 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1358 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1382 flags); 1359 flags);
1360 adapter->cmd_queued = cmd_node;
1383 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, 1361 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
1384 true); 1362 true);
1385 } else { 1363 } else {
@@ -1398,6 +1376,29 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
1398} 1376}
1399 1377
1400/* 1378/*
1379 * Sends IOCTL request to start a scan with user configurations.
1380 *
1381 * This function allocates the IOCTL request buffer, fills it
1382 * with requisite parameters and calls the IOCTL handler.
1383 *
1384 * Upon completion, it also generates a wireless event to notify
1385 * applications.
1386 */
1387int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
1388 struct mwifiex_user_scan_cfg *scan_req)
1389{
1390 int status;
1391
1392 priv->adapter->scan_wait_q_woken = false;
1393
1394 status = mwifiex_scan_networks(priv, scan_req);
1395 if (!status)
1396 status = mwifiex_wait_queue_complete(priv->adapter);
1397
1398 return status;
1399}
1400
1401/*
1401 * This function prepares a scan command to be sent to the firmware. 1402 * This function prepares a scan command to be sent to the firmware.
1402 * 1403 *
1403 * This uses the scan command configuration sent to the command processing 1404 * This uses the scan command configuration sent to the command processing
@@ -1788,7 +1789,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1788 /* Need to indicate IOCTL complete */ 1789 /* Need to indicate IOCTL complete */
1789 if (adapter->curr_cmd->wait_q_enabled) { 1790 if (adapter->curr_cmd->wait_q_enabled) {
1790 adapter->cmd_wait_q.status = 0; 1791 adapter->cmd_wait_q.status = 0;
1791 mwifiex_complete_cmd(adapter); 1792 mwifiex_complete_cmd(adapter, adapter->curr_cmd);
1792 } 1793 }
1793 if (priv->report_scan_result) 1794 if (priv->report_scan_result)
1794 priv->report_scan_result = false; 1795 priv->report_scan_result = false;
@@ -1845,6 +1846,7 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
1845 unsigned long flags; 1846 unsigned long flags;
1846 1847
1847 cmd_node->wait_q_enabled = true; 1848 cmd_node->wait_q_enabled = true;
1849 cmd_node->condition = &adapter->scan_wait_q_woken;
1848 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 1850 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
1849 list_add_tail(&cmd_node->list, &adapter->scan_pending_q); 1851 list_add_tail(&cmd_node->list, &adapter->scan_pending_q);
1850 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); 1852 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
@@ -1911,7 +1913,7 @@ int mwifiex_request_scan(struct mwifiex_private *priv,
1911 } 1913 }
1912 priv->scan_pending_on_block = true; 1914 priv->scan_pending_on_block = true;
1913 1915
1914 priv->adapter->cmd_wait_q.condition = false; 1916 priv->adapter->scan_wait_q_woken = false;
1915 1917
1916 if (req_ssid && req_ssid->ssid_len != 0) 1918 if (req_ssid && req_ssid->ssid_len != 0)
1917 /* Specific SSID scan */ 1919 /* Specific SSID scan */
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 82098ac483b8..283171bbcedf 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -89,7 +89,8 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
89 return -EIO; 89 return -EIO;
90 } 90 }
91 91
92 if (mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops)) { 92 if (mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops,
93 MWIFIEX_SDIO)) {
93 pr_err("%s: add card failed\n", __func__); 94 pr_err("%s: add card failed\n", __func__);
94 kfree(card); 95 kfree(card);
95 sdio_claim_host(func); 96 sdio_claim_host(func);
@@ -830,7 +831,7 @@ done:
830 * The winner interface is also determined by this function. 831 * The winner interface is also determined by this function.
831 */ 832 */
832static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, 833static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
833 u32 poll_num, int *winner) 834 u32 poll_num)
834{ 835{
835 int ret = 0; 836 int ret = 0;
836 u16 firmware_stat; 837 u16 firmware_stat;
@@ -842,7 +843,7 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
842 ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat); 843 ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat);
843 if (ret) 844 if (ret)
844 continue; 845 continue;
845 if (firmware_stat == FIRMWARE_READY) { 846 if (firmware_stat == FIRMWARE_READY_SDIO) {
846 ret = 0; 847 ret = 0;
847 break; 848 break;
848 } else { 849 } else {
@@ -851,15 +852,15 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
851 } 852 }
852 } 853 }
853 854
854 if (winner && ret) { 855 if (ret) {
855 if (mwifiex_read_reg 856 if (mwifiex_read_reg
856 (adapter, CARD_FW_STATUS0_REG, &winner_status)) 857 (adapter, CARD_FW_STATUS0_REG, &winner_status))
857 winner_status = 0; 858 winner_status = 0;
858 859
859 if (winner_status) 860 if (winner_status)
860 *winner = 0; 861 adapter->winner = 0;
861 else 862 else
862 *winner = 1; 863 adapter->winner = 1;
863 } 864 }
864 return ret; 865 return ret;
865} 866}
@@ -1413,7 +1414,7 @@ tx_curr_single:
1413 * the type. The firmware handles the packets based upon this set type. 1414 * the type. The firmware handles the packets based upon this set type.
1414 */ 1415 */
1415static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, 1416static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
1416 u8 type, u8 *payload, u32 pkt_len, 1417 u8 type, struct sk_buff *skb,
1417 struct mwifiex_tx_param *tx_param) 1418 struct mwifiex_tx_param *tx_param)
1418{ 1419{
1419 struct sdio_mmc_card *card = adapter->card; 1420 struct sdio_mmc_card *card = adapter->card;
@@ -1421,6 +1422,8 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
1421 u32 buf_block_len; 1422 u32 buf_block_len;
1422 u32 blk_size; 1423 u32 blk_size;
1423 u8 port = CTRL_PORT; 1424 u8 port = CTRL_PORT;
1425 u8 *payload = (u8 *)skb->data;
1426 u32 pkt_len = skb->len;
1424 1427
1425 /* Allocate buffer and copy payload */ 1428 /* Allocate buffer and copy payload */
1426 blk_size = MWIFIEX_SDIO_BLOCK_SIZE; 1429 blk_size = MWIFIEX_SDIO_BLOCK_SIZE;
@@ -1722,6 +1725,8 @@ static struct mwifiex_if_ops sdio_ops = {
1722 /* SDIO specific */ 1725 /* SDIO specific */
1723 .update_mp_end_port = mwifiex_update_mp_end_port, 1726 .update_mp_end_port = mwifiex_update_mp_end_port,
1724 .cleanup_mpa_buf = mwifiex_cleanup_mpa_buf, 1727 .cleanup_mpa_buf = mwifiex_cleanup_mpa_buf,
1728 .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete,
1729 .event_complete = mwifiex_sdio_event_complete,
1725}; 1730};
1726 1731
1727/* 1732/*
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 524f78f4ee69..3f711801e58a 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -169,9 +169,6 @@
169/* Rx unit register */ 169/* Rx unit register */
170#define CARD_RX_UNIT_REG 0x63 170#define CARD_RX_UNIT_REG 0x63
171 171
172/* Event header len w/o 4 bytes of interface header */
173#define MWIFIEX_EVENT_HEADER_LEN 4
174
175/* Max retry number of CMD53 write */ 172/* Max retry number of CMD53 write */
176#define MAX_WRITE_IOMEM_RETRY 2 173#define MAX_WRITE_IOMEM_RETRY 2
177 174
@@ -304,4 +301,25 @@ struct sdio_mmc_card {
304 struct mwifiex_sdio_mpa_tx mpa_tx; 301 struct mwifiex_sdio_mpa_tx mpa_tx;
305 struct mwifiex_sdio_mpa_rx mpa_rx; 302 struct mwifiex_sdio_mpa_rx mpa_rx;
306}; 303};
304
305/*
306 * .cmdrsp_complete handler
307 */
308static inline int mwifiex_sdio_cmdrsp_complete(struct mwifiex_adapter *adapter,
309 struct sk_buff *skb)
310{
311 dev_kfree_skb_any(skb);
312 return 0;
313}
314
315/*
316 * .event_complete handler
317 */
318static inline int mwifiex_sdio_event_complete(struct mwifiex_adapter *adapter,
319 struct sk_buff *skb)
320{
321 dev_kfree_skb_any(skb);
322 return 0;
323}
324
307#endif /* _MWIFIEX_SDIO_H */ 325#endif /* _MWIFIEX_SDIO_H */
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index c54ee287b878..ea6518d1c9e3 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -902,6 +902,59 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
902} 902}
903 903
904/* 904/*
905 * This function prepares command to set PCI-Express
906 * host buffer configuration
907 *
908 * Preparation includes -
909 * - Setting command ID, action and proper size
910 * - Setting host buffer configuration
911 * - Ensuring correct endian-ness
912 */
913static int
914mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv,
915 struct host_cmd_ds_command *cmd, u16 action)
916{
917 struct host_cmd_ds_pcie_details *host_spec =
918 &cmd->params.pcie_host_spec;
919 struct pcie_service_card *card = priv->adapter->card;
920 phys_addr_t *buf_pa;
921
922 cmd->command = cpu_to_le16(HostCmd_CMD_PCIE_DESC_DETAILS);
923 cmd->size = cpu_to_le16(sizeof(struct
924 host_cmd_ds_pcie_details) + S_DS_GEN);
925 cmd->result = 0;
926
927 memset(host_spec, 0, sizeof(struct host_cmd_ds_pcie_details));
928
929 if (action == HostCmd_ACT_GEN_SET) {
930 /* Send the ring base addresses and count to firmware */
931 host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase);
932 host_spec->txbd_addr_hi =
933 (u32)(((u64)card->txbd_ring_pbase)>>32);
934 host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD;
935 host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase);
936 host_spec->rxbd_addr_hi =
937 (u32)(((u64)card->rxbd_ring_pbase)>>32);
938 host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD;
939 host_spec->evtbd_addr_lo =
940 (u32)(card->evtbd_ring_pbase);
941 host_spec->evtbd_addr_hi =
942 (u32)(((u64)card->evtbd_ring_pbase)>>32);
943 host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD;
944 if (card->sleep_cookie) {
945 buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie);
946 host_spec->sleep_cookie_addr_lo = (u32) *buf_pa;
947 host_spec->sleep_cookie_addr_hi =
948 (u32) (((u64)*buf_pa) >> 32);
949 dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: "
950 "0x%x\n", host_spec->sleep_cookie_addr_lo);
951 }
952 }
953
954 return 0;
955}
956
957/*
905 * This function prepares the commands before sending them to the firmware. 958 * This function prepares the commands before sending them to the firmware.
906 * 959 *
907 * This is a generic function which calls specific command preparation 960 * This is a generic function which calls specific command preparation
@@ -1079,6 +1132,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1079 host_cmd_ds_set_bss_mode) + S_DS_GEN); 1132 host_cmd_ds_set_bss_mode) + S_DS_GEN);
1080 ret = 0; 1133 ret = 0;
1081 break; 1134 break;
1135 case HostCmd_CMD_PCIE_DESC_DETAILS:
1136 ret = mwifiex_cmd_pcie_host_spec(priv, cmd_ptr, cmd_action);
1137 break;
1082 default: 1138 default:
1083 dev_err(priv->adapter->dev, 1139 dev_err(priv->adapter->dev,
1084 "PREP_CMD: unknown cmd- %#x\n", cmd_no); 1140 "PREP_CMD: unknown cmd- %#x\n", cmd_no);
@@ -1095,6 +1151,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1095 * working state. 1151 * working state.
1096 * 1152 *
1097 * The following commands are issued sequentially - 1153 * The following commands are issued sequentially -
1154 * - Set PCI-Express host buffer configuration (PCIE only)
1098 * - Function init (for first interface only) 1155 * - Function init (for first interface only)
1099 * - Read MAC address (for first interface only) 1156 * - Read MAC address (for first interface only)
1100 * - Reconfigure Tx buffer size (for first interface only) 1157 * - Reconfigure Tx buffer size (for first interface only)
@@ -1116,6 +1173,13 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1116 struct mwifiex_ds_11n_tx_cfg tx_cfg; 1173 struct mwifiex_ds_11n_tx_cfg tx_cfg;
1117 1174
1118 if (first_sta) { 1175 if (first_sta) {
1176 if (priv->adapter->iface_type == MWIFIEX_PCIE) {
1177 ret = mwifiex_send_cmd_async(priv,
1178 HostCmd_CMD_PCIE_DESC_DETAILS,
1179 HostCmd_ACT_GEN_SET, 0, NULL);
1180 if (ret)
1181 return -1;
1182 }
1119 1183
1120 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_FUNC_INIT, 1184 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_FUNC_INIT,
1121 HostCmd_ACT_GEN_SET, 0, NULL); 1185 HostCmd_ACT_GEN_SET, 0, NULL);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 6804239d87bd..7a16b0c417af 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -952,6 +952,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
952 case HostCmd_CMD_11N_CFG: 952 case HostCmd_CMD_11N_CFG:
953 ret = mwifiex_ret_11n_cfg(resp, data_buf); 953 ret = mwifiex_ret_11n_cfg(resp, data_buf);
954 break; 954 break;
955 case HostCmd_CMD_PCIE_DESC_DETAILS:
956 break;
955 default: 957 default:
956 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", 958 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
957 resp->command); 959 resp->command);
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 520800b618e7..ea4a29b7e331 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -55,7 +55,9 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
55{ 55{
56 bool cancel_flag = false; 56 bool cancel_flag = false;
57 int status = adapter->cmd_wait_q.status; 57 int status = adapter->cmd_wait_q.status;
58 struct cmd_ctrl_node *cmd_queued = adapter->cmd_queued;
58 59
60 adapter->cmd_queued = NULL;
59 dev_dbg(adapter->dev, "cmd pending\n"); 61 dev_dbg(adapter->dev, "cmd pending\n");
60 atomic_inc(&adapter->cmd_pending); 62 atomic_inc(&adapter->cmd_pending);
61 63
@@ -64,8 +66,8 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
64 66
65 /* Wait for completion */ 67 /* Wait for completion */
66 wait_event_interruptible(adapter->cmd_wait_q.wait, 68 wait_event_interruptible(adapter->cmd_wait_q.wait,
67 adapter->cmd_wait_q.condition); 69 *(cmd_queued->condition));
68 if (!adapter->cmd_wait_q.condition) 70 if (!*(cmd_queued->condition))
69 cancel_flag = true; 71 cancel_flag = true;
70 72
71 if (cancel_flag) { 73 if (cancel_flag) {
@@ -291,8 +293,8 @@ done:
291 * This function prepares the correct firmware command and 293 * This function prepares the correct firmware command and
292 * issues it. 294 * issues it.
293 */ 295 */
294int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, 296static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
295 int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg) 297 int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg)
296 298
297{ 299{
298 struct mwifiex_adapter *adapter = priv->adapter; 300 struct mwifiex_adapter *adapter = priv->adapter;
@@ -763,7 +765,7 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv,
763 if ((rate[i] & 0x7f) == (rate_cfg->rate & 0x7f)) 765 if ((rate[i] & 0x7f) == (rate_cfg->rate & 0x7f))
764 break; 766 break;
765 } 767 }
766 if (!rate[i] || (i == MWIFIEX_SUPPORTED_RATES)) { 768 if ((i == MWIFIEX_SUPPORTED_RATES) || !rate[i]) {
767 dev_err(adapter->dev, "fixed data rate %#x is out " 769 dev_err(adapter->dev, "fixed data rate %#x is out "
768 "of range\n", rate_cfg->rate); 770 "of range\n", rate_cfg->rate);
769 return -1; 771 return -1;
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index 1822bfad8896..d97facd70e88 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -151,7 +151,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
151 skb_push(skb, INTF_HEADER_LEN); 151 skb_push(skb, INTF_HEADER_LEN);
152 152
153 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, 153 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
154 skb->data, skb->len, NULL); 154 skb, NULL);
155 switch (ret) { 155 switch (ret) {
156 case -EBUSY: 156 case -EBUSY:
157 adapter->data_sent = true; 157 adapter->data_sent = true;
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 6190b2fa57a3..a206f412875f 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -78,7 +78,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
78 (struct txpd *) (head_ptr + INTF_HEADER_LEN); 78 (struct txpd *) (head_ptr + INTF_HEADER_LEN);
79 79
80 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, 80 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
81 skb->data, skb->len, tx_param); 81 skb, tx_param);
82 } 82 }
83 83
84 switch (ret) { 84 switch (ret) {
@@ -87,7 +87,8 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
87 (adapter->pps_uapsd_mode) && 87 (adapter->pps_uapsd_mode) &&
88 (adapter->tx_lock_flag)) { 88 (adapter->tx_lock_flag)) {
89 priv->adapter->tx_lock_flag = false; 89 priv->adapter->tx_lock_flag = false;
90 local_tx_pd->flags = 0; 90 if (local_tx_pd)
91 local_tx_pd->flags = 0;
91 } 92 }
92 dev_dbg(adapter->dev, "data: -EBUSY is returned\n"); 93 dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
93 break; 94 break;
@@ -160,43 +161,3 @@ done:
160 return 0; 161 return 0;
161} 162}
162 163
163/*
164 * Packet receive completion callback handler.
165 *
166 * This function calls another completion callback handler which
167 * updates the statistics, and optionally updates the parent buffer
168 * use count before freeing the received packet.
169 */
170int mwifiex_recv_packet_complete(struct mwifiex_adapter *adapter,
171 struct sk_buff *skb, int status)
172{
173 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
174 struct mwifiex_rxinfo *rx_info_parent;
175 struct mwifiex_private *priv;
176 struct sk_buff *skb_parent;
177 unsigned long flags;
178
179 priv = adapter->priv[rx_info->bss_index];
180
181 if (priv && (status == -1))
182 priv->stats.rx_dropped++;
183
184 if (rx_info->parent) {
185 skb_parent = rx_info->parent;
186 rx_info_parent = MWIFIEX_SKB_RXCB(skb_parent);
187
188 spin_lock_irqsave(&priv->rx_pkt_lock, flags);
189 --rx_info_parent->use_count;
190
191 if (!rx_info_parent->use_count) {
192 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
193 dev_kfree_skb_any(skb_parent);
194 } else {
195 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
196 }
197 } else {
198 dev_kfree_skb_any(skb);
199 }
200
201 return 0;
202}
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index d41291529bc0..06976f517f66 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -185,13 +185,14 @@ int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb)
185 * corresponding waiting function. Otherwise, it processes the 185 * corresponding waiting function. Otherwise, it processes the
186 * IOCTL response and frees the response buffer. 186 * IOCTL response and frees the response buffer.
187 */ 187 */
188int mwifiex_complete_cmd(struct mwifiex_adapter *adapter) 188int mwifiex_complete_cmd(struct mwifiex_adapter *adapter,
189 struct cmd_ctrl_node *cmd_node)
189{ 190{
190 atomic_dec(&adapter->cmd_pending); 191 atomic_dec(&adapter->cmd_pending);
191 dev_dbg(adapter->dev, "cmd completed: status=%d\n", 192 dev_dbg(adapter->dev, "cmd completed: status=%d\n",
192 adapter->cmd_wait_q.status); 193 adapter->cmd_wait_q.status);
193 194
194 adapter->cmd_wait_q.condition = true; 195 *(cmd_node->condition) = true;
195 196
196 if (adapter->cmd_wait_q.status == -ETIMEDOUT) 197 if (adapter->cmd_wait_q.status == -ETIMEDOUT)
197 dev_err(adapter->dev, "cmd timeout\n"); 198 dev_err(adapter->dev, "cmd timeout\n");
diff --git a/drivers/net/wireless/mwifiex/util.h b/drivers/net/wireless/mwifiex/util.h
index 9506afc6c0e4..f6d36b9654a0 100644
--- a/drivers/net/wireless/mwifiex/util.h
+++ b/drivers/net/wireless/mwifiex/util.h
@@ -22,11 +22,16 @@
22 22
23static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb) 23static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb)
24{ 24{
25 return (struct mwifiex_rxinfo *)skb->cb; 25 return (struct mwifiex_rxinfo *)(skb->cb + sizeof(phys_addr_t));
26} 26}
27 27
28static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb) 28static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb)
29{ 29{
30 return (struct mwifiex_txinfo *)skb->cb; 30 return (struct mwifiex_txinfo *)(skb->cb + sizeof(phys_addr_t));
31}
32
33static inline phys_addr_t *MWIFIEX_SKB_PACB(struct sk_buff *skb)
34{
35 return (phys_addr_t *)skb->cb;
31} 36}
32#endif /* !_MWIFIEX_UTIL_H_ */ 37#endif /* !_MWIFIEX_UTIL_H_ */
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index eda24474c1fc..6c239c3c8249 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -1125,8 +1125,8 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
1125 tx_param.next_pkt_len = 1125 tx_param.next_pkt_len =
1126 ((skb_next) ? skb_next->len + 1126 ((skb_next) ? skb_next->len +
1127 sizeof(struct txpd) : 0); 1127 sizeof(struct txpd) : 0);
1128 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, 1128 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, skb,
1129 skb->data, skb->len, &tx_param); 1129 &tx_param);
1130 switch (ret) { 1130 switch (ret) {
1131 case -EBUSY: 1131 case -EBUSY:
1132 dev_dbg(adapter->dev, "data: -EBUSY is returned\n"); 1132 dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 098fc557a88d..d4fdd2a5a739 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -311,6 +311,8 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)
311 IEEE80211_HW_RX_INCLUDES_FCS | 311 IEEE80211_HW_RX_INCLUDES_FCS |
312 IEEE80211_HW_BEACON_FILTER | 312 IEEE80211_HW_BEACON_FILTER |
313 IEEE80211_HW_AMPDU_AGGREGATION | 313 IEEE80211_HW_AMPDU_AGGREGATION |
314 IEEE80211_HW_CONNECTION_MONITOR |
315 /* IEEE80211_HW_SUPPORTS_CQM_RSSI | */
314 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0; 316 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0;
315 317
316 /* swlps or hwlps has been set in diff chip in init_sw_vars */ 318 /* swlps or hwlps has been set in diff chip in init_sw_vars */
@@ -850,7 +852,7 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,
850 *So tcb_desc->hw_rate is just used for 852 *So tcb_desc->hw_rate is just used for
851 *special data and mgt frames 853 *special data and mgt frames
852 */ 854 */
853 if (info->control.rates[0].idx == 0 && 855 if (info->control.rates[0].idx == 0 ||
854 ieee80211_is_nullfunc(fc)) { 856 ieee80211_is_nullfunc(fc)) {
855 tcb_desc->use_driver_rate = true; 857 tcb_desc->use_driver_rate = true;
856 tcb_desc->ratr_index = RATR_INX_WIRELESS_MC; 858 tcb_desc->ratr_index = RATR_INX_WIRELESS_MC;
@@ -1138,7 +1140,7 @@ void rtl_watchdog_wq_callback(void *data)
1138 } 1140 }
1139 1141
1140 /* 1142 /*
1141 *<3> to check if traffic busy, if 1143 *<2> to check if traffic busy, if
1142 * busytraffic we don't change channel 1144 * busytraffic we don't change channel
1143 */ 1145 */
1144 if (mac->link_state >= MAC80211_LINKED) { 1146 if (mac->link_state >= MAC80211_LINKED) {
diff --git a/drivers/net/wireless/rtlwifi/debug.c b/drivers/net/wireless/rtlwifi/debug.c
index b2f897acb238..1b5cb7153a52 100644
--- a/drivers/net/wireless/rtlwifi/debug.c
+++ b/drivers/net/wireless/rtlwifi/debug.c
@@ -28,17 +28,11 @@
28 28
29#include "wifi.h" 29#include "wifi.h"
30 30
31static unsigned int debug = DBG_EMERG;
32module_param(debug, uint, 0);
33MODULE_PARM_DESC(debug, "Set global debug level for rtlwifi (0,2-5)");
34
35void rtl_dbgp_flag_init(struct ieee80211_hw *hw) 31void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
36{ 32{
37 struct rtl_priv *rtlpriv = rtl_priv(hw); 33 struct rtl_priv *rtlpriv = rtl_priv(hw);
38 u8 i; 34 u8 i;
39 35
40 rtlpriv->dbg.global_debuglevel = debug;
41
42 rtlpriv->dbg.global_debugcomponents = 36 rtlpriv->dbg.global_debugcomponents =
43 COMP_ERR | COMP_FW | COMP_INIT | COMP_RECV | COMP_SEND | 37 COMP_ERR | COMP_FW | COMP_INIT | COMP_RECV | COMP_SEND |
44 COMP_MLME | COMP_SCAN | COMP_INTR | COMP_LED | COMP_SEC | 38 COMP_MLME | COMP_SCAN | COMP_INTR | COMP_LED | COMP_SEC |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 9983fa18065a..5380f3b040ac 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -1993,36 +1993,25 @@ call rtl_mac_stop() from the mac80211
1993suspend function first, So there is 1993suspend function first, So there is
1994no need to call hw_disable here. 1994no need to call hw_disable here.
1995****************************************/ 1995****************************************/
1996int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state) 1996int rtl_pci_suspend(struct device *dev)
1997{ 1997{
1998 struct pci_dev *pdev = to_pci_dev(dev);
1998 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 1999 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
1999 struct rtl_priv *rtlpriv = rtl_priv(hw); 2000 struct rtl_priv *rtlpriv = rtl_priv(hw);
2000 2001
2001 rtlpriv->cfg->ops->hw_suspend(hw); 2002 rtlpriv->cfg->ops->hw_suspend(hw);
2002 rtl_deinit_rfkill(hw); 2003 rtl_deinit_rfkill(hw);
2003 2004
2004 pci_save_state(pdev);
2005 pci_disable_device(pdev);
2006 pci_set_power_state(pdev, PCI_D3hot);
2007 return 0; 2005 return 0;
2008} 2006}
2009EXPORT_SYMBOL(rtl_pci_suspend); 2007EXPORT_SYMBOL(rtl_pci_suspend);
2010 2008
2011int rtl_pci_resume(struct pci_dev *pdev) 2009int rtl_pci_resume(struct device *dev)
2012{ 2010{
2013 int ret; 2011 struct pci_dev *pdev = to_pci_dev(dev);
2014 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 2012 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
2015 struct rtl_priv *rtlpriv = rtl_priv(hw); 2013 struct rtl_priv *rtlpriv = rtl_priv(hw);
2016 2014
2017 pci_set_power_state(pdev, PCI_D0);
2018 ret = pci_enable_device(pdev);
2019 if (ret) {
2020 RT_ASSERT(false, ("ERR: <======\n"));
2021 return ret;
2022 }
2023
2024 pci_restore_state(pdev);
2025
2026 rtlpriv->cfg->ops->hw_resume(hw); 2015 rtlpriv->cfg->ops->hw_resume(hw);
2027 rtl_init_rfkill(hw); 2016 rtl_init_rfkill(hw);
2028 return 0; 2017 return 0;
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
index a24e505b202b..ebe0b42c0518 100644
--- a/drivers/net/wireless/rtlwifi/pci.h
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -237,8 +237,8 @@ extern struct rtl_intf_ops rtl_pci_ops;
237int __devinit rtl_pci_probe(struct pci_dev *pdev, 237int __devinit rtl_pci_probe(struct pci_dev *pdev,
238 const struct pci_device_id *id); 238 const struct pci_device_id *id);
239void rtl_pci_disconnect(struct pci_dev *pdev); 239void rtl_pci_disconnect(struct pci_dev *pdev);
240int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state); 240int rtl_pci_suspend(struct device *dev);
241int rtl_pci_resume(struct pci_dev *pdev); 241int rtl_pci_resume(struct device *dev);
242 242
243static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) 243static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
244{ 244{
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
index 11f43196e61d..9fc804d89d65 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
@@ -142,8 +142,22 @@ enum version_8192c {
142 VERSION_UNKNOWN = 0x88, 142 VERSION_UNKNOWN = 0x88,
143}; 143};
144 144
145#define CUT_VERSION_MASK (BIT(6)|BIT(7))
146#define CHIP_VENDOR_UMC BIT(5)
147#define CHIP_VENDOR_UMC_B_CUT BIT(6) /* Chip version for ECO */
148#define IS_VENDOR_UMC_A_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) ? \
149 ((GET_CVID_CUT_VERSION(version)) ? false : true) : false)
145#define IS_CHIP_VER_B(version) ((version & CHIP_VER_B) ? true : false) 150#define IS_CHIP_VER_B(version) ((version & CHIP_VER_B) ? true : false)
151#define IS_VENDOR_UMC_A_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) ? \
152 ((GET_CVID_CUT_VERSION(version)) ? false : true) : false)
146#define IS_92C_SERIAL(version) ((version & CHIP_92C_BITMASK) ? true : false) 153#define IS_92C_SERIAL(version) ((version & CHIP_92C_BITMASK) ? true : false)
154#define IS_CHIP_VENDOR_UMC(version) \
155 ((version & CHIP_VENDOR_UMC) ? true : false)
156#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK)
157#define IS_81xxC_VENDOR_UMC_B_CUT(version) \
158 ((IS_CHIP_VENDOR_UMC(version)) ? \
159 ((GET_CVID_CUT_VERSION(version) == CHIP_VENDOR_UMC_B_CUT) ? \
160 true : false) : false)
147 161
148enum rtl819x_loopback_e { 162enum rtl819x_loopback_e {
149 RTL819X_NO_LOOPBACK = 0, 163 RTL819X_NO_LOOPBACK = 0,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index b7ecb9e44aa9..a48404cc2b96 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -92,6 +92,8 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
92 struct rtl_priv *rtlpriv = rtl_priv(hw); 92 struct rtl_priv *rtlpriv = rtl_priv(hw);
93 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 93 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
94 const struct firmware *firmware; 94 const struct firmware *firmware;
95 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
96 char *fw_name = NULL;
95 97
96 rtl8192ce_bt_reg_init(hw); 98 rtl8192ce_bt_reg_init(hw);
97 99
@@ -129,6 +131,8 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
129 131
130 rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0); 132 rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0);
131 133
134 /* for debug level */
135 rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
132 /* for LPS & IPS */ 136 /* for LPS & IPS */
133 rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; 137 rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
134 rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; 138 rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -159,8 +163,14 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
159 } 163 }
160 164
161 /* request fw */ 165 /* request fw */
162 err = request_firmware(&firmware, rtlpriv->cfg->fw_name, 166 if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
163 rtlpriv->io.dev); 167 !IS_92C_SERIAL(rtlhal->version))
168 fw_name = "rtlwifi/rtl8192cfwU.bin";
169 else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version))
170 fw_name = "rtlwifi/rtl8192cfwU_B.bin";
171 else
172 fw_name = rtlpriv->cfg->fw_name;
173 err = request_firmware(&firmware, fw_name, rtlpriv->io.dev);
164 if (err) { 174 if (err) {
165 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 175 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
166 ("Failed to request firmware!\n")); 176 ("Failed to request firmware!\n"));
@@ -245,6 +255,7 @@ static struct rtl_mod_params rtl92ce_mod_params = {
245 .inactiveps = true, 255 .inactiveps = true,
246 .swctrl_lps = false, 256 .swctrl_lps = false,
247 .fwctrl_lps = true, 257 .fwctrl_lps = true,
258 .debug = DBG_EMERG,
248}; 259};
249 260
250static struct rtl_hal_cfg rtl92ce_hal_cfg = { 261static struct rtl_hal_cfg rtl92ce_hal_cfg = {
@@ -355,8 +366,11 @@ MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
355MODULE_LICENSE("GPL"); 366MODULE_LICENSE("GPL");
356MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless"); 367MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless");
357MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin"); 368MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin");
369MODULE_FIRMWARE("rtlwifi/rtl8192cfwU.bin");
370MODULE_FIRMWARE("rtlwifi/rtl8192cfwU_B.bin");
358 371
359module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444); 372module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444);
373module_param_named(debug, rtl92ce_mod_params.debug, int, 0444);
360module_param_named(ips, rtl92ce_mod_params.inactiveps, bool, 0444); 374module_param_named(ips, rtl92ce_mod_params.inactiveps, bool, 0444);
361module_param_named(swlps, rtl92ce_mod_params.swctrl_lps, bool, 0444); 375module_param_named(swlps, rtl92ce_mod_params.swctrl_lps, bool, 0444);
362module_param_named(fwlps, rtl92ce_mod_params.fwctrl_lps, bool, 0444); 376module_param_named(fwlps, rtl92ce_mod_params.fwctrl_lps, bool, 0444);
@@ -364,18 +378,23 @@ MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
364MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); 378MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
365MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); 379MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
366MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); 380MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
381MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
382
383static const struct dev_pm_ops rtlwifi_pm_ops = {
384 .suspend = rtl_pci_suspend,
385 .resume = rtl_pci_resume,
386 .freeze = rtl_pci_suspend,
387 .thaw = rtl_pci_resume,
388 .poweroff = rtl_pci_suspend,
389 .restore = rtl_pci_resume,
390};
367 391
368static struct pci_driver rtl92ce_driver = { 392static struct pci_driver rtl92ce_driver = {
369 .name = KBUILD_MODNAME, 393 .name = KBUILD_MODNAME,
370 .id_table = rtl92ce_pci_ids, 394 .id_table = rtl92ce_pci_ids,
371 .probe = rtl_pci_probe, 395 .probe = rtl_pci_probe,
372 .remove = rtl_pci_disconnect, 396 .remove = rtl_pci_disconnect,
373 397 .driver.pm = &rtlwifi_pm_ops,
374#ifdef CONFIG_PM
375 .suspend = rtl_pci_suspend,
376 .resume = rtl_pci_resume,
377#endif
378
379}; 398};
380 399
381static int __init rtl92ce_module_init(void) 400static int __init rtl92ce_module_init(void)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/def.h b/drivers/net/wireless/rtlwifi/rtl8192cu/def.h
index c54940ea72fe..d097efb1e717 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/def.h
@@ -50,10 +50,6 @@
50#define IS_VENDOR_UMC(version) \ 50#define IS_VENDOR_UMC(version) \
51 (((version) & CHIP_VENDOR_UMC) ? true : false) 51 (((version) & CHIP_VENDOR_UMC) ? true : false)
52 52
53#define IS_VENDOR_UMC_A_CUT(version) \
54 (((version) & CHIP_VENDOR_UMC) ? (((version) & (BIT(6) | BIT(7))) ? \
55 false : true) : false)
56
57#define IS_VENDOR_8723_A_CUT(version) \ 53#define IS_VENDOR_8723_A_CUT(version) \
58 (((version) & CHIP_VENDOR_UMC) ? (((version) & (BIT(6))) ? \ 54 (((version) & CHIP_VENDOR_UMC) ? (((version) & (BIT(6))) ? \
59 false : true) : false) 55 false : true) : false)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index 424b8a0323e2..feed1ed8d9b6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -60,6 +60,7 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
60 rtlpriv->dm.dm_flag = 0; 60 rtlpriv->dm.dm_flag = 0;
61 rtlpriv->dm.disable_framebursting = 0; 61 rtlpriv->dm.disable_framebursting = 0;
62 rtlpriv->dm.thermalvalue = 0; 62 rtlpriv->dm.thermalvalue = 0;
63 rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
63 rtlpriv->rtlhal.pfirmware = vmalloc(0x4000); 64 rtlpriv->rtlhal.pfirmware = vmalloc(0x4000);
64 if (!rtlpriv->rtlhal.pfirmware) { 65 if (!rtlpriv->rtlhal.pfirmware) {
65 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 66 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
@@ -149,8 +150,14 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
149 150
150static struct rtl_mod_params rtl92cu_mod_params = { 151static struct rtl_mod_params rtl92cu_mod_params = {
151 .sw_crypto = 0, 152 .sw_crypto = 0,
153 .debug = DBG_EMERG,
152}; 154};
153 155
156module_param_named(swenc, rtl92cu_mod_params.sw_crypto, bool, 0444);
157module_param_named(debug, rtl92cu_mod_params.debug, int, 0444);
158MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
159MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
160
154static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = { 161static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = {
155 /* rx */ 162 /* rx */
156 .in_ep_num = RTL92C_USB_BULK_IN_NUM, 163 .in_ep_num = RTL92C_USB_BULK_IN_NUM,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/def.h b/drivers/net/wireless/rtlwifi/rtl8192de/def.h
index aff7e19714ff..946304771748 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/def.h
@@ -122,59 +122,98 @@
122#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \ 122#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
123 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12) 123 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
124 124
125/* 125enum version_8192d {
126 * 92D chip ver: 126 VERSION_TEST_CHIP_88C = 0x0000,
127 * BIT8: IS 92D 127 VERSION_TEST_CHIP_92C = 0x0020,
128 * BIT9: single phy 128 VERSION_TEST_UMC_CHIP_8723 = 0x0081,
129 * BIT10: C-cut 129 VERSION_NORMAL_TSMC_CHIP_88C = 0x0008,
130 * BIT11: D-cut 130 VERSION_NORMAL_TSMC_CHIP_92C = 0x0028,
131 */ 131 VERSION_NORMAL_TSMC_CHIP_92C_1T2R = 0x0018,
132 132 VERSION_NORMAL_UMC_CHIP_88C_A_CUT = 0x0088,
133/* Chip specific */ 133 VERSION_NORMAL_UMC_CHIP_92C_A_CUT = 0x00a8,
134#define CHIP_92C BIT(0) 134 VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT = 0x0098,
135#define CHIP_92C_1T2R BIT(1) 135 VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089,
136#define CHIP_8723 BIT(2) /* RTL8723 With BT feature */ 136 VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089,
137#define CHIP_8723_DRV_REV BIT(3) /* RTL8723 Driver Revised */ 137 VERSION_NORMAL_UMC_CHIP_88C_B_CUT = 0x1088,
138#define NORMAL_CHIP BIT(4) 138 VERSION_NORMAL_UMC_CHIP_92C_B_CUT = 0x10a8,
139#define CHIP_VENDOR_UMC BIT(5) 139 VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT = 0x1090,
140#define CHIP_VENDOR_UMC_B_CUT BIT(6) /* Chip version for ECO */ 140 VERSION_TEST_CHIP_92D_SINGLEPHY = 0x0022,
141 VERSION_TEST_CHIP_92D_DUALPHY = 0x0002,
142 VERSION_NORMAL_CHIP_92D_SINGLEPHY = 0x002a,
143 VERSION_NORMAL_CHIP_92D_DUALPHY = 0x000a,
144 VERSION_NORMAL_CHIP_92D_C_CUT_SINGLEPHY = 0x202a,
145 VERSION_NORMAL_CHIP_92D_C_CUT_DUALPHY = 0x200a,
146 VERSION_NORMAL_CHIP_92D_D_CUT_SINGLEPHY = 0x302a,
147 VERSION_NORMAL_CHIP_92D_D_CUT_DUALPHY = 0x300a,
148 VERSION_NORMAL_CHIP_92D_E_CUT_SINGLEPHY = 0x402a,
149 VERSION_NORMAL_CHIP_92D_E_CUT_DUALPHY = 0x400a,
150};
141 151
142/* for 92D */ 152/* for 92D */
143#define CHIP_92D BIT(8)
144#define CHIP_92D_SINGLEPHY BIT(9) 153#define CHIP_92D_SINGLEPHY BIT(9)
145#define CHIP_92D_C_CUT BIT(10) 154#define C_CUT_VERSION BIT(13)
146#define CHIP_92D_D_CUT BIT(11) 155#define D_CUT_VERSION ((BIT(12)|BIT(13)))
156#define E_CUT_VERSION BIT(14)
157
158/* Chip specific */
159#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3)
160#define CHIP_BONDING_92C_1T2R 0x1
161#define CHIP_BONDING_88C_USB_MCARD 0x2
162#define CHIP_BONDING_88C_USB_HP 0x1
163
164/* [15:12] IC version(CUT): A-cut=0, B-cut=1, C-cut=2, D-cut=3 */
165/* [7] Manufacturer: TSMC=0, UMC=1 */
166/* [6:4] RF type: 1T1R=0, 1T2R=1, 2T2R=2 */
167/* [3] Chip type: TEST=0, NORMAL=1 */
168/* [2:0] IC type: 81xxC=0, 8723=1, 92D=2 */
169#define CHIP_8723 BIT(0)
170#define CHIP_92D BIT(1)
171#define NORMAL_CHIP BIT(3)
172#define RF_TYPE_1T1R (~(BIT(4)|BIT(5)|BIT(6)))
173#define RF_TYPE_1T2R BIT(4)
174#define RF_TYPE_2T2R BIT(5)
175#define CHIP_VENDOR_UMC BIT(7)
176#define B_CUT_VERSION BIT(12)
177
178/* MASK */
179#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2))
180#define CHIP_TYPE_MASK BIT(3)
181#define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6))
182#define MANUFACTUER_MASK BIT(7)
183#define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8))
184#define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12))
147 185
148enum version_8192d {
149 VERSION_TEST_CHIP_88C = 0x00,
150 VERSION_TEST_CHIP_92C = 0x01,
151 VERSION_NORMAL_TSMC_CHIP_88C = 0x10,
152 VERSION_NORMAL_TSMC_CHIP_92C = 0x11,
153 VERSION_NORMAL_TSMC_CHIP_92C_1T2R = 0x13,
154 VERSION_NORMAL_UMC_CHIP_88C_A_CUT = 0x30,
155 VERSION_NORMAL_UMC_CHIP_92C_A_CUT = 0x31,
156 VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT = 0x33,
157 VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT = 0x34,
158 VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT = 0x3c,
159 VERSION_NORMAL_UMC_CHIP_88C_B_CUT = 0x70,
160 VERSION_NORMAL_UMC_CHIP_92C_B_CUT = 0x71,
161 VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT = 0x73,
162 VERSION_TEST_CHIP_92D_SINGLEPHY = 0x300,
163 VERSION_TEST_CHIP_92D_DUALPHY = 0x100,
164 VERSION_NORMAL_CHIP_92D_SINGLEPHY = 0x310,
165 VERSION_NORMAL_CHIP_92D_DUALPHY = 0x110,
166 VERSION_NORMAL_CHIP_92D_C_CUT_SINGLEPHY = 0x710,
167 VERSION_NORMAL_CHIP_92D_C_CUT_DUALPHY = 0x510,
168 VERSION_NORMAL_CHIP_92D_D_CUT_SINGLEPHY = 0xB10,
169 VERSION_NORMAL_CHIP_92D_D_CUT_DUALPHY = 0x910,
170};
171 186
172#define IS_92D_SINGLEPHY(version) \ 187/* Get element */
173 ((version & CHIP_92D_SINGLEPHY) ? true : false) 188#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK)
174#define IS_92D_C_CUT(version) \ 189#define GET_CVID_CHIP_TYPE(version) ((version) & CHIP_TYPE_MASK)
175 ((version & CHIP_92D_C_CUT) ? true : false) 190#define GET_CVID_RF_TYPE(version) ((version) & RF_TYPE_MASK)
176#define IS_92D_D_CUT(version) \ 191#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK)
177 ((version & CHIP_92D_D_CUT) ? true : false) 192#define GET_CVID_ROM_VERSION(version) ((version) & ROM_VERSION_MASK)
193#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK)
194
195#define IS_1T1R(version) ((GET_CVID_RF_TYPE(version)) ? \
196 false : true)
197#define IS_1T2R(version) ((GET_CVID_RF_TYPE(version) == \
198 RF_TYPE_1T2R) ? true : false)
199#define IS_2T2R(version) ((GET_CVID_RF_TYPE(version) == \
200 RF_TYPE_2T2R) ? true : false)
201
202#define IS_92D_SINGLEPHY(version) ((IS_92D(version)) ? \
203 (IS_2T2R(version) ? true : false) : false)
204#define IS_92D(version) ((GET_CVID_IC_TYPE(version) == \
205 CHIP_92D) ? true : false)
206#define IS_92D_C_CUT(version) ((IS_92D(version)) ? \
207 ((GET_CVID_CUT_VERSION(version) == \
208 0x2000) ? true : false) : false)
209#define IS_92D_D_CUT(version) ((IS_92D(version)) ? \
210 ((GET_CVID_CUT_VERSION(version) == \
211 0x3000) ? true : false) : false)
212#define IS_92D_E_CUT(version) ((IS_92D(version)) ? \
213 ((GET_CVID_CUT_VERSION(version) == \
214 0x4000) ? true : false) : false)
215#define CHIP_92D_C_CUT BIT(10)
216#define CHIP_92D_D_CUT BIT(11)
178 217
179enum rf_optype { 218enum rf_optype {
180 RF_OP_BY_SW_3WIRE = 0, 219 RF_OP_BY_SW_3WIRE = 0,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
index 0073cf106af2..f5bd3a3cd34a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
@@ -1608,17 +1608,16 @@ static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw,
1608 tempval[0] = hwinfo[EEPROM_IQK_DELTA] & 0x03; 1608 tempval[0] = hwinfo[EEPROM_IQK_DELTA] & 0x03;
1609 tempval[1] = (hwinfo[EEPROM_LCK_DELTA] & 0x0C) >> 2; 1609 tempval[1] = (hwinfo[EEPROM_LCK_DELTA] & 0x0C) >> 2;
1610 rtlefuse->txpwr_fromeprom = true; 1610 rtlefuse->txpwr_fromeprom = true;
1611 if (IS_92D_D_CUT(rtlpriv->rtlhal.version)) { 1611 if (IS_92D_D_CUT(rtlpriv->rtlhal.version) ||
1612 IS_92D_E_CUT(rtlpriv->rtlhal.version)) {
1612 rtlefuse->internal_pa_5g[0] = 1613 rtlefuse->internal_pa_5g[0] =
1613 !((hwinfo[EEPROM_TSSI_A_5G] & 1614 !((hwinfo[EEPROM_TSSI_A_5G] & BIT(6)) >> 6);
1614 BIT(6)) >> 6);
1615 rtlefuse->internal_pa_5g[1] = 1615 rtlefuse->internal_pa_5g[1] =
1616 !((hwinfo[EEPROM_TSSI_B_5G] & 1616 !((hwinfo[EEPROM_TSSI_B_5G] & BIT(6)) >> 6);
1617 BIT(6)) >> 6); 1617 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1618 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1619 ("Is D cut,Internal PA0 %d Internal PA1 %d\n", 1618 ("Is D cut,Internal PA0 %d Internal PA1 %d\n",
1620 rtlefuse->internal_pa_5g[0], 1619 rtlefuse->internal_pa_5g[0],
1621 rtlefuse->internal_pa_5g[1])) 1620 rtlefuse->internal_pa_5g[1]))
1622 } 1621 }
1623 rtlefuse->eeprom_c9 = hwinfo[EEPROM_RF_OPT6]; 1622 rtlefuse->eeprom_c9 = hwinfo[EEPROM_RF_OPT6];
1624 rtlefuse->eeprom_cc = hwinfo[EEPROM_RF_OPT7]; 1623 rtlefuse->eeprom_cc = hwinfo[EEPROM_RF_OPT7];
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
index c681597c7f20..691f80092185 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
@@ -146,6 +146,8 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
146 146
147 rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD); 147 rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD);
148 148
149 /* for debug level */
150 rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
149 /* for LPS & IPS */ 151 /* for LPS & IPS */
150 rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; 152 rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
151 rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; 153 rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -267,6 +269,7 @@ static struct rtl_mod_params rtl92de_mod_params = {
267 .inactiveps = true, 269 .inactiveps = true,
268 .swctrl_lps = true, 270 .swctrl_lps = true,
269 .fwctrl_lps = false, 271 .fwctrl_lps = false,
272 .debug = DBG_EMERG,
270}; 273};
271 274
272static struct rtl_hal_cfg rtl92de_hal_cfg = { 275static struct rtl_hal_cfg rtl92de_hal_cfg = {
@@ -377,6 +380,7 @@ MODULE_DESCRIPTION("Realtek 8192DE 802.11n Dual Mac PCI wireless");
377MODULE_FIRMWARE("rtlwifi/rtl8192defw.bin"); 380MODULE_FIRMWARE("rtlwifi/rtl8192defw.bin");
378 381
379module_param_named(swenc, rtl92de_mod_params.sw_crypto, bool, 0444); 382module_param_named(swenc, rtl92de_mod_params.sw_crypto, bool, 0444);
383module_param_named(debug, rtl92de_mod_params.debug, int, 0444);
380module_param_named(ips, rtl92de_mod_params.inactiveps, bool, 0444); 384module_param_named(ips, rtl92de_mod_params.inactiveps, bool, 0444);
381module_param_named(swlps, rtl92de_mod_params.swctrl_lps, bool, 0444); 385module_param_named(swlps, rtl92de_mod_params.swctrl_lps, bool, 0444);
382module_param_named(fwlps, rtl92de_mod_params.fwctrl_lps, bool, 0444); 386module_param_named(fwlps, rtl92de_mod_params.fwctrl_lps, bool, 0444);
@@ -384,18 +388,23 @@ MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
384MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); 388MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
385MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); 389MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
386MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); 390MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
391MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
392
393static const struct dev_pm_ops rtlwifi_pm_ops = {
394 .suspend = rtl_pci_suspend,
395 .resume = rtl_pci_resume,
396 .freeze = rtl_pci_suspend,
397 .thaw = rtl_pci_resume,
398 .poweroff = rtl_pci_suspend,
399 .restore = rtl_pci_resume,
400};
387 401
388static struct pci_driver rtl92de_driver = { 402static struct pci_driver rtl92de_driver = {
389 .name = KBUILD_MODNAME, 403 .name = KBUILD_MODNAME,
390 .id_table = rtl92de_pci_ids, 404 .id_table = rtl92de_pci_ids,
391 .probe = rtl_pci_probe, 405 .probe = rtl_pci_probe,
392 .remove = rtl_pci_disconnect, 406 .remove = rtl_pci_disconnect,
393 407 .driver.pm = &rtlwifi_pm_ops,
394#ifdef CONFIG_PM
395 .suspend = rtl_pci_suspend,
396 .resume = rtl_pci_resume,
397#endif
398
399}; 408};
400 409
401/* add global spin lock to solve the problem that 410/* add global spin lock to solve the problem that
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
index d59f66cb7768..c474486e3911 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -1382,7 +1382,7 @@ static void _rtl92se_power_domain_init(struct ieee80211_hw *hw)
1382 rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34); 1382 rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34);
1383 1383
1384 /* Reset MAC-IO and CPU and Core Digital BIT10/11/15 */ 1384 /* Reset MAC-IO and CPU and Core Digital BIT10/11/15 */
1385 tmpu1b = rtl_read_byte(rtlpriv, SYS_FUNC_EN + 1); 1385 tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1386 1386
1387 /* If IPS we need to turn LED on. So we not 1387 /* If IPS we need to turn LED on. So we not
1388 * not disable BIT 3/7 of reg3. */ 1388 * not disable BIT 3/7 of reg3. */
@@ -1391,7 +1391,7 @@ static void _rtl92se_power_domain_init(struct ieee80211_hw *hw)
1391 else 1391 else
1392 tmpu1b &= 0x73; 1392 tmpu1b &= 0x73;
1393 1393
1394 rtl_write_byte(rtlpriv, SYS_FUNC_EN + 1, tmpu1b); 1394 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b);
1395 /* wait for BIT 10/11/15 to pull high automatically!! */ 1395 /* wait for BIT 10/11/15 to pull high automatically!! */
1396 mdelay(1); 1396 mdelay(1);
1397 1397
@@ -1428,15 +1428,15 @@ static void _rtl92se_power_domain_init(struct ieee80211_hw *hw)
1428 rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0))); 1428 rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0)));
1429 1429
1430 /* Set Digital Vdd to Retention isolation Path. */ 1430 /* Set Digital Vdd to Retention isolation Path. */
1431 tmpu2b = rtl_read_word(rtlpriv, SYS_ISO_CTRL); 1431 tmpu2b = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL);
1432 rtl_write_word(rtlpriv, SYS_ISO_CTRL, (tmpu2b | BIT(11))); 1432 rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, (tmpu2b | BIT(11)));
1433 1433
1434 1434
1435 /* For warm reboot NIC disappera bug. */ 1435 /* For warm reboot NIC disappera bug. */
1436 tmpu2b = rtl_read_word(rtlpriv, SYS_FUNC_EN); 1436 tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
1437 rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(13))); 1437 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(13)));
1438 1438
1439 rtl_write_byte(rtlpriv, SYS_ISO_CTRL + 1, 0x68); 1439 rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x68);
1440 1440
1441 /* Enable AFE PLL Macro Block */ 1441 /* Enable AFE PLL Macro Block */
1442 tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL); 1442 tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL);
@@ -1447,17 +1447,17 @@ static void _rtl92se_power_domain_init(struct ieee80211_hw *hw)
1447 mdelay(1); 1447 mdelay(1);
1448 1448
1449 /* Release isolation AFE PLL & MD */ 1449 /* Release isolation AFE PLL & MD */
1450 rtl_write_byte(rtlpriv, SYS_ISO_CTRL, 0xA6); 1450 rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xA6);
1451 1451
1452 /* Enable MAC clock */ 1452 /* Enable MAC clock */
1453 tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR); 1453 tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
1454 rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11))); 1454 rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11)));
1455 1455
1456 /* Enable Core digital and enable IOREG R/W */ 1456 /* Enable Core digital and enable IOREG R/W */
1457 tmpu2b = rtl_read_word(rtlpriv, SYS_FUNC_EN); 1457 tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
1458 rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(11))); 1458 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11)));
1459 /* enable REG_EN */ 1459 /* enable REG_EN */
1460 rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15))); 1460 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15)));
1461 1461
1462 /* Switch the control path. */ 1462 /* Switch the control path. */
1463 tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR); 1463 tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
index ea32ef2d4098..11f125c030ce 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
@@ -735,6 +735,7 @@
735#define HWSET_MAX_SIZE_92S 128 735#define HWSET_MAX_SIZE_92S 128
736#define EFUSE_MAX_SECTION 16 736#define EFUSE_MAX_SECTION 16
737#define EFUSE_REAL_CONTENT_LEN 512 737#define EFUSE_REAL_CONTENT_LEN 512
738#define EFUSE_OOB_PROTECT_BYTES 15
738 739
739#define RTL8190_EEPROM_ID 0x8129 740#define RTL8190_EEPROM_ID 0x8129
740#define EEPROM_HPON 0x02 741#define EEPROM_HPON 0x02
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
index 24bd331a5484..3ec9a0d41baf 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
@@ -160,6 +160,8 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
160 160
161 rtlpci->first_init = true; 161 rtlpci->first_init = true;
162 162
163 /* for debug level */
164 rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
163 /* for LPS & IPS */ 165 /* for LPS & IPS */
164 rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; 166 rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
165 rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; 167 rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -272,6 +274,7 @@ static struct rtl_mod_params rtl92se_mod_params = {
272 .inactiveps = true, 274 .inactiveps = true,
273 .swctrl_lps = true, 275 .swctrl_lps = true,
274 .fwctrl_lps = false, 276 .fwctrl_lps = false,
277 .debug = DBG_EMERG,
275}; 278};
276 279
277/* Because memory R/W bursting will cause system hang/crash 280/* Because memory R/W bursting will cause system hang/crash
@@ -304,6 +307,7 @@ static struct rtl_hal_cfg rtl92se_hal_cfg = {
304 .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE_92S, 307 .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE_92S,
305 .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, 308 .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
306 .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, 309 .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
310 .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES,
307 311
308 .maps[RWCAM] = REG_RWCAM, 312 .maps[RWCAM] = REG_RWCAM,
309 .maps[WCAMI] = REG_WCAMI, 313 .maps[WCAMI] = REG_WCAMI,
@@ -388,6 +392,7 @@ MODULE_DESCRIPTION("Realtek 8192S/8191S 802.11n PCI wireless");
388MODULE_FIRMWARE("rtlwifi/rtl8192sefw.bin"); 392MODULE_FIRMWARE("rtlwifi/rtl8192sefw.bin");
389 393
390module_param_named(swenc, rtl92se_mod_params.sw_crypto, bool, 0444); 394module_param_named(swenc, rtl92se_mod_params.sw_crypto, bool, 0444);
395module_param_named(debug, rtl92se_mod_params.debug, int, 0444);
391module_param_named(ips, rtl92se_mod_params.inactiveps, bool, 0444); 396module_param_named(ips, rtl92se_mod_params.inactiveps, bool, 0444);
392module_param_named(swlps, rtl92se_mod_params.swctrl_lps, bool, 0444); 397module_param_named(swlps, rtl92se_mod_params.swctrl_lps, bool, 0444);
393module_param_named(fwlps, rtl92se_mod_params.fwctrl_lps, bool, 0444); 398module_param_named(fwlps, rtl92se_mod_params.fwctrl_lps, bool, 0444);
@@ -395,18 +400,23 @@ MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
395MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); 400MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
396MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); 401MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
397MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); 402MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
403MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
404
405static const struct dev_pm_ops rtlwifi_pm_ops = {
406 .suspend = rtl_pci_suspend,
407 .resume = rtl_pci_resume,
408 .freeze = rtl_pci_suspend,
409 .thaw = rtl_pci_resume,
410 .poweroff = rtl_pci_suspend,
411 .restore = rtl_pci_resume,
412};
398 413
399static struct pci_driver rtl92se_driver = { 414static struct pci_driver rtl92se_driver = {
400 .name = KBUILD_MODNAME, 415 .name = KBUILD_MODNAME,
401 .id_table = rtl92se_pci_ids, 416 .id_table = rtl92se_pci_ids,
402 .probe = rtl_pci_probe, 417 .probe = rtl_pci_probe,
403 .remove = rtl_pci_disconnect, 418 .remove = rtl_pci_disconnect,
404 419 .driver.pm = &rtlwifi_pm_ops,
405#ifdef CONFIG_PM
406 .suspend = rtl_pci_suspend,
407 .resume = rtl_pci_resume,
408#endif
409
410}; 420};
411 421
412static int __init rtl92se_module_init(void) 422static int __init rtl92se_module_init(void)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
index ba137da082b5..fbebe3ea0a22 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -124,18 +124,15 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
124 u8 i, max_spatial_stream; 124 u8 i, max_spatial_stream;
125 u32 rssi, total_rssi = 0; 125 u32 rssi, total_rssi = 0;
126 bool in_powersavemode = false; 126 bool in_powersavemode = false;
127 bool is_cck_rate; 127 bool is_cck = pstats->is_cck;
128 128
129 is_cck_rate = SE_RX_HAL_IS_CCK_RATE(pdesc);
130 pstats->packet_matchbssid = packet_match_bssid; 129 pstats->packet_matchbssid = packet_match_bssid;
131 pstats->packet_toself = packet_toself; 130 pstats->packet_toself = packet_toself;
132 pstats->is_cck = is_cck_rate;
133 pstats->packet_beacon = packet_beacon; 131 pstats->packet_beacon = packet_beacon;
134 pstats->is_cck = is_cck_rate;
135 pstats->rx_mimo_signalquality[0] = -1; 132 pstats->rx_mimo_signalquality[0] = -1;
136 pstats->rx_mimo_signalquality[1] = -1; 133 pstats->rx_mimo_signalquality[1] = -1;
137 134
138 if (is_cck_rate) { 135 if (is_cck) {
139 u8 report, cck_highpwr; 136 u8 report, cck_highpwr;
140 cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; 137 cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
141 138
@@ -246,9 +243,8 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
246 pstats->rxpower = rx_pwr_all; 243 pstats->rxpower = rx_pwr_all;
247 pstats->recvsignalpower = rx_pwr_all; 244 pstats->recvsignalpower = rx_pwr_all;
248 245
249 if (GET_RX_STATUS_DESC_RX_HT(pdesc) && 246 if (pstats->is_ht && pstats->rate >= DESC92_RATEMCS8 &&
250 GET_RX_STATUS_DESC_RX_MCS(pdesc) >= DESC92_RATEMCS8 && 247 pstats->rate <= DESC92_RATEMCS15)
251 GET_RX_STATUS_DESC_RX_MCS(pdesc) <= DESC92_RATEMCS15)
252 max_spatial_stream = 2; 248 max_spatial_stream = 2;
253 else 249 else
254 max_spatial_stream = 1; 250 max_spatial_stream = 1;
@@ -266,7 +262,7 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
266 } 262 }
267 } 263 }
268 264
269 if (is_cck_rate) 265 if (is_cck)
270 pstats->signalstrength = (u8)(_rtl92se_signal_scale_mapping(hw, 266 pstats->signalstrength = (u8)(_rtl92se_signal_scale_mapping(hw,
271 pwdb_all)); 267 pwdb_all));
272 else if (rf_rx_num != 0) 268 else if (rf_rx_num != 0)
@@ -518,6 +514,8 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
518{ 514{
519 struct rx_fwinfo *p_drvinfo; 515 struct rx_fwinfo *p_drvinfo;
520 u32 phystatus = (u32)GET_RX_STATUS_DESC_PHY_STATUS(pdesc); 516 u32 phystatus = (u32)GET_RX_STATUS_DESC_PHY_STATUS(pdesc);
517 struct ieee80211_hdr *hdr;
518 bool first_ampdu = false;
521 519
522 stats->length = (u16)GET_RX_STATUS_DESC_PKT_LEN(pdesc); 520 stats->length = (u16)GET_RX_STATUS_DESC_PKT_LEN(pdesc);
523 stats->rx_drvinfo_size = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE(pdesc) * 8; 521 stats->rx_drvinfo_size = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE(pdesc) * 8;
@@ -530,8 +528,12 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
530 stats->rate = (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc); 528 stats->rate = (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc);
531 stats->shortpreamble = (u16)GET_RX_STATUS_DESC_SPLCP(pdesc); 529 stats->shortpreamble = (u16)GET_RX_STATUS_DESC_SPLCP(pdesc);
532 stats->isampdu = (bool)(GET_RX_STATUS_DESC_PAGGR(pdesc) == 1); 530 stats->isampdu = (bool)(GET_RX_STATUS_DESC_PAGGR(pdesc) == 1);
531 stats->isfirst_ampdu = (bool) ((GET_RX_STATUS_DESC_PAGGR(pdesc) == 1)
532 && (GET_RX_STATUS_DESC_FAGGR(pdesc) == 1));
533 stats->timestamp_low = GET_RX_STATUS_DESC_TSFL(pdesc); 533 stats->timestamp_low = GET_RX_STATUS_DESC_TSFL(pdesc);
534 stats->rx_is40Mhzpacket = (bool)GET_RX_STATUS_DESC_BW(pdesc); 534 stats->rx_is40Mhzpacket = (bool)GET_RX_STATUS_DESC_BW(pdesc);
535 stats->is_ht = (bool)GET_RX_STATUS_DESC_RX_HT(pdesc);
536 stats->is_cck = SE_RX_HAL_IS_CCK_RATE(pdesc);
535 537
536 if (stats->hwerror) 538 if (stats->hwerror)
537 return false; 539 return false;
@@ -539,30 +541,39 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
539 rx_status->freq = hw->conf.channel->center_freq; 541 rx_status->freq = hw->conf.channel->center_freq;
540 rx_status->band = hw->conf.channel->band; 542 rx_status->band = hw->conf.channel->band;
541 543
542 if (GET_RX_STATUS_DESC_CRC32(pdesc)) 544 hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size
543 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; 545 + stats->rx_bufshift);
544 546
545 if (!GET_RX_STATUS_DESC_SWDEC(pdesc)) 547 if (stats->crc)
546 rx_status->flag |= RX_FLAG_DECRYPTED; 548 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
547 549
548 if (GET_RX_STATUS_DESC_BW(pdesc)) 550 if (stats->rx_is40Mhzpacket)
549 rx_status->flag |= RX_FLAG_40MHZ; 551 rx_status->flag |= RX_FLAG_40MHZ;
550 552
551 if (GET_RX_STATUS_DESC_RX_HT(pdesc)) 553 if (stats->is_ht)
552 rx_status->flag |= RX_FLAG_HT; 554 rx_status->flag |= RX_FLAG_HT;
553 555
554 rx_status->flag |= RX_FLAG_MACTIME_MPDU; 556 rx_status->flag |= RX_FLAG_MACTIME_MPDU;
555 557
556 if (stats->decrypted) 558 /* hw will set stats->decrypted true, if it finds the
557 rx_status->flag |= RX_FLAG_DECRYPTED; 559 * frame is open data frame or mgmt frame,
560 * hw will not decrypt robust managment frame
561 * for IEEE80211w but still set stats->decrypted
562 * true, so here we should set it back to undecrypted
563 * for IEEE80211w frame, and mac80211 sw will help
564 * to decrypt it */
565 if (stats->decrypted) {
566 if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
567 (ieee80211_has_protected(hdr->frame_control)))
568 rx_status->flag &= ~RX_FLAG_DECRYPTED;
569 else
570 rx_status->flag |= RX_FLAG_DECRYPTED;
571 }
558 572
559 rx_status->rate_idx = rtlwifi_rate_mapping(hw, 573 rx_status->rate_idx = rtlwifi_rate_mapping(hw,
560 (bool)GET_RX_STATUS_DESC_RX_HT(pdesc), 574 stats->is_ht, stats->rate, first_ampdu);
561 (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc),
562 (bool)GET_RX_STATUS_DESC_PAGGR(pdesc));
563
564 575
565 rx_status->mactime = GET_RX_STATUS_DESC_TSFL(pdesc); 576 rx_status->mactime = stats->timestamp_low;
566 if (phystatus) { 577 if (phystatus) {
567 p_drvinfo = (struct rx_fwinfo *)(skb->data + 578 p_drvinfo = (struct rx_fwinfo *)(skb->data +
568 stats->rx_bufshift); 579 stats->rx_bufshift);
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 3126485393d9..713c7ddba8eb 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -450,6 +450,7 @@ enum rtl_var_map {
450 EFUSE_HWSET_MAX_SIZE, 450 EFUSE_HWSET_MAX_SIZE,
451 EFUSE_MAX_SECTION_MAP, 451 EFUSE_MAX_SECTION_MAP,
452 EFUSE_REAL_CONTENT_SIZE, 452 EFUSE_REAL_CONTENT_SIZE,
453 EFUSE_OOB_PROTECT_BYTES_LEN,
453 454
454 /*CAM map */ 455 /*CAM map */
455 RWCAM, 456 RWCAM,
@@ -1324,6 +1325,7 @@ struct rtl_stats {
1324 s8 rx_mimo_signalquality[2]; 1325 s8 rx_mimo_signalquality[2];
1325 bool packet_matchbssid; 1326 bool packet_matchbssid;
1326 bool is_cck; 1327 bool is_cck;
1328 bool is_ht;
1327 bool packet_toself; 1329 bool packet_toself;
1328 bool packet_beacon; /*for rssi */ 1330 bool packet_beacon; /*for rssi */
1329 char cck_adc_pwdb[4]; /*for rx path selection */ 1331 char cck_adc_pwdb[4]; /*for rx path selection */
@@ -1485,6 +1487,9 @@ struct rtl_mod_params {
1485 /* default: 0 = using hardware encryption */ 1487 /* default: 0 = using hardware encryption */
1486 int sw_crypto; 1488 int sw_crypto;
1487 1489
1490 /* default: 0 = DBG_EMERG (0)*/
1491 int debug;
1492
1488 /* default: 1 = using no linked power save */ 1493 /* default: 1 = using no linked power save */
1489 bool inactiveps; 1494 bool inactiveps;
1490 1495
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index 399849eeb247..ca044a743191 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -777,7 +777,23 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl)
777 acx->rate_policy.long_retry_limit = c->long_retry_limit; 777 acx->rate_policy.long_retry_limit = c->long_retry_limit;
778 acx->rate_policy.aflags = c->aflags; 778 acx->rate_policy.aflags = c->aflags;
779 779
780 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
781 if (ret < 0) {
782 wl1271_warning("Setting of rate policies failed: %d", ret);
783 goto out;
784 }
780 785
786 /*
787 * configure one rate class for basic p2p operations.
788 * (p2p packets should always go out with OFDM rates, even
789 * if we are currently connected to 11b AP)
790 */
791 acx->rate_policy_idx = cpu_to_le32(ACX_TX_BASIC_RATE_P2P);
792 acx->rate_policy.enabled_rates =
793 cpu_to_le32(CONF_TX_RATE_MASK_BASIC_P2P);
794 acx->rate_policy.short_retry_limit = c->short_retry_limit;
795 acx->rate_policy.long_retry_limit = c->long_retry_limit;
796 acx->rate_policy.aflags = c->aflags;
781 797
782 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); 798 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
783 if (ret < 0) { 799 if (ret < 0) {
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index 556ee4e282d5..e3f93b4b3429 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -656,6 +656,7 @@ struct acx_rate_class {
656 656
657#define ACX_TX_BASIC_RATE 0 657#define ACX_TX_BASIC_RATE 0
658#define ACX_TX_AP_FULL_RATE 1 658#define ACX_TX_AP_FULL_RATE 1
659#define ACX_TX_BASIC_RATE_P2P 2
659#define ACX_TX_AP_MODE_MGMT_RATE 4 660#define ACX_TX_AP_MODE_MGMT_RATE 4
660#define ACX_TX_AP_MODE_BCST_RATE 5 661#define ACX_TX_AP_MODE_BCST_RATE 5
661struct acx_rate_policy { 662struct acx_rate_policy {
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
index 6d5664bfc37d..d4e628db76b0 100644
--- a/drivers/net/wireless/wl12xx/boot.c
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -503,7 +503,8 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
503 BA_SESSION_RX_CONSTRAINT_EVENT_ID | 503 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
504 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID | 504 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
505 INACTIVE_STA_EVENT_ID | 505 INACTIVE_STA_EVENT_ID |
506 MAX_TX_RETRY_EVENT_ID; 506 MAX_TX_RETRY_EVENT_ID |
507 CHANNEL_SWITCH_COMPLETE_EVENT_ID;
507 508
508 ret = wl1271_event_unmask(wl); 509 ret = wl1271_event_unmask(wl);
509 if (ret < 0) { 510 if (ret < 0) {
@@ -769,9 +770,6 @@ int wl1271_load_firmware(struct wl1271 *wl)
769 clk |= (wl->ref_clock << 1) << 4; 770 clk |= (wl->ref_clock << 1) << 4;
770 } 771 }
771 772
772 if (wl->quirks & WL12XX_QUIRK_LPD_MODE)
773 clk |= SCRATCH_ENABLE_LPD;
774
775 wl1271_write32(wl, DRPW_SCRATCH_START, clk); 773 wl1271_write32(wl, DRPW_SCRATCH_START, clk);
776 774
777 wl1271_set_partition(wl, &part_table[PART_WORK]); 775 wl1271_set_partition(wl, &part_table[PART_WORK]);
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 287fe95ecb40..a52299e548fa 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -134,11 +134,6 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
134 /* Override the REF CLK from the NVS with the one from platform data */ 134 /* Override the REF CLK from the NVS with the one from platform data */
135 gen_parms->general_params.ref_clock = wl->ref_clock; 135 gen_parms->general_params.ref_clock = wl->ref_clock;
136 136
137 /* LPD mode enable (bits 6-7) in WL1271 AP mode only */
138 if (wl->quirks & WL12XX_QUIRK_LPD_MODE)
139 gen_parms->general_params.general_settings |=
140 GENERAL_SETTINGS_DRPW_LPD;
141
142 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); 137 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
143 if (ret < 0) { 138 if (ret < 0) {
144 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); 139 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
@@ -1700,3 +1695,61 @@ int wl12xx_croc(struct wl1271 *wl, u8 role_id)
1700out: 1695out:
1701 return ret; 1696 return ret;
1702} 1697}
1698
1699int wl12xx_cmd_channel_switch(struct wl1271 *wl,
1700 struct ieee80211_channel_switch *ch_switch)
1701{
1702 struct wl12xx_cmd_channel_switch *cmd;
1703 int ret;
1704
1705 wl1271_debug(DEBUG_ACX, "cmd channel switch");
1706
1707 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1708 if (!cmd) {
1709 ret = -ENOMEM;
1710 goto out;
1711 }
1712
1713 cmd->channel = ch_switch->channel->hw_value;
1714 cmd->switch_time = ch_switch->count;
1715 cmd->tx_suspend = ch_switch->block_tx;
1716 cmd->flush = 0; /* this value is ignored by the FW */
1717
1718 ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);
1719 if (ret < 0) {
1720 wl1271_error("failed to send channel switch command");
1721 goto out_free;
1722 }
1723
1724out_free:
1725 kfree(cmd);
1726
1727out:
1728 return ret;
1729}
1730
1731int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl)
1732{
1733 struct wl12xx_cmd_stop_channel_switch *cmd;
1734 int ret;
1735
1736 wl1271_debug(DEBUG_ACX, "cmd stop channel switch");
1737
1738 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1739 if (!cmd) {
1740 ret = -ENOMEM;
1741 goto out;
1742 }
1743
1744 ret = wl1271_cmd_send(wl, CMD_STOP_CHANNEL_SWICTH, cmd, sizeof(*cmd), 0);
1745 if (ret < 0) {
1746 wl1271_error("failed to stop channel switch command");
1747 goto out_free;
1748 }
1749
1750out_free:
1751 kfree(cmd);
1752
1753out:
1754 return ret;
1755}
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
index 8e4d11ec0c55..b7bd42769aa7 100644
--- a/drivers/net/wireless/wl12xx/cmd.h
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -79,6 +79,9 @@ int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid);
79int wl12xx_cmd_config_fwlog(struct wl1271 *wl); 79int wl12xx_cmd_config_fwlog(struct wl1271 *wl);
80int wl12xx_cmd_start_fwlog(struct wl1271 *wl); 80int wl12xx_cmd_start_fwlog(struct wl1271 *wl);
81int wl12xx_cmd_stop_fwlog(struct wl1271 *wl); 81int wl12xx_cmd_stop_fwlog(struct wl1271 *wl);
82int wl12xx_cmd_channel_switch(struct wl1271 *wl,
83 struct ieee80211_channel_switch *ch_switch);
84int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl);
82 85
83enum wl1271_commands { 86enum wl1271_commands {
84 CMD_INTERROGATE = 1, /*use this to read information elements*/ 87 CMD_INTERROGATE = 1, /*use this to read information elements*/
@@ -677,4 +680,21 @@ struct wl12xx_cmd_stop_fwlog {
677 struct wl1271_cmd_header header; 680 struct wl1271_cmd_header header;
678} __packed; 681} __packed;
679 682
683struct wl12xx_cmd_channel_switch {
684 struct wl1271_cmd_header header;
685
686 /* The new serving channel */
687 u8 channel;
688 /* Relative time of the serving channel switch in TBTT units */
689 u8 switch_time;
690 /* 1: Suspend TX till switch time; 0: Do not suspend TX */
691 u8 tx_suspend;
692 /* 1: Flush TX at switch time; 0: Do not flush */
693 u8 flush;
694} __packed;
695
696struct wl12xx_cmd_stop_channel_switch {
697 struct wl1271_cmd_header header;
698} __packed;
699
680#endif /* __WL1271_CMD_H__ */ 700#endif /* __WL1271_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h
index 6a6805c3cc74..04bb8fbf93f9 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -416,13 +416,17 @@ struct conf_rx_settings {
416 u8 queue_type; 416 u8 queue_type;
417}; 417};
418 418
419#define CONF_TX_MAX_RATE_CLASSES 8 419#define CONF_TX_MAX_RATE_CLASSES 10
420 420
421#define CONF_TX_RATE_MASK_UNSPECIFIED 0 421#define CONF_TX_RATE_MASK_UNSPECIFIED 0
422#define CONF_TX_RATE_MASK_BASIC (CONF_HW_BIT_RATE_1MBPS | \ 422#define CONF_TX_RATE_MASK_BASIC (CONF_HW_BIT_RATE_1MBPS | \
423 CONF_HW_BIT_RATE_2MBPS) 423 CONF_HW_BIT_RATE_2MBPS)
424#define CONF_TX_RATE_RETRY_LIMIT 10 424#define CONF_TX_RATE_RETRY_LIMIT 10
425 425
426/* basic rates for p2p operations (probe req/resp, etc.) */
427#define CONF_TX_RATE_MASK_BASIC_P2P (CONF_HW_BIT_RATE_6MBPS | \
428 CONF_HW_BIT_RATE_12MBPS | CONF_HW_BIT_RATE_24MBPS)
429
426/* 430/*
427 * Rates supported for data packets when operating as AP. Note the absence 431 * Rates supported for data packets when operating as AP. Note the absence
428 * of the 22Mbps rate. There is a FW limitation on 12 rates so we must drop 432 * of the 22Mbps rate. There is a FW limitation on 12 rates so we must drop
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c
index e66db69f8d17..674ad2a9e409 100644
--- a/drivers/net/wireless/wl12xx/event.c
+++ b/drivers/net/wireless/wl12xx/event.c
@@ -300,6 +300,21 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
300 wl1271_stop_ba_event(wl); 300 wl1271_stop_ba_event(wl);
301 } 301 }
302 302
303 if ((vector & CHANNEL_SWITCH_COMPLETE_EVENT_ID) && !is_ap) {
304 wl1271_debug(DEBUG_EVENT, "CHANNEL_SWITCH_COMPLETE_EVENT_ID. "
305 "status = 0x%x",
306 mbox->channel_switch_status);
307 /*
308 * That event uses for two cases:
309 * 1) channel switch complete with status=0
310 * 2) channel switch failed status=1
311 */
312 if (test_and_clear_bit(WL1271_FLAG_CS_PROGRESS, &wl->flags) &&
313 (wl->vif))
314 ieee80211_chswitch_done(wl->vif,
315 mbox->channel_switch_status ? false : true);
316 }
317
303 if ((vector & DUMMY_PACKET_EVENT_ID)) { 318 if ((vector & DUMMY_PACKET_EVENT_ID)) {
304 wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID"); 319 wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID");
305 if (wl->vif) 320 if (wl->vif)
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index e2d6edd2fcd2..884f82b63219 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -1333,14 +1333,6 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
1333 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)", 1333 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
1334 wl->chip.id); 1334 wl->chip.id);
1335 1335
1336 /*
1337 * 'end-of-transaction flag' and 'LPD mode flag'
1338 * should be set in wl127x AP mode only
1339 */
1340 if (wl->bss_type == BSS_TYPE_AP_BSS)
1341 wl->quirks |= (WL12XX_QUIRK_END_OF_TRANSACTION |
1342 WL12XX_QUIRK_LPD_MODE);
1343
1344 ret = wl1271_setup(wl); 1336 ret = wl1271_setup(wl);
1345 if (ret < 0) 1337 if (ret < 0)
1346 goto out; 1338 goto out;
@@ -2222,6 +2214,11 @@ static int wl1271_unjoin(struct wl1271 *wl)
2222{ 2214{
2223 int ret; 2215 int ret;
2224 2216
2217 if (test_and_clear_bit(WL1271_FLAG_CS_PROGRESS, &wl->flags)) {
2218 wl12xx_cmd_stop_channel_switch(wl);
2219 ieee80211_chswitch_done(wl->vif, false);
2220 }
2221
2225 /* to stop listening to a channel, we disconnect */ 2222 /* to stop listening to a channel, we disconnect */
2226 ret = wl12xx_cmd_role_stop_sta(wl); 2223 ret = wl12xx_cmd_role_stop_sta(wl);
2227 if (ret < 0) 2224 if (ret < 0)
@@ -4130,6 +4127,37 @@ static int wl12xx_set_bitrate_mask(struct ieee80211_hw *hw,
4130 return 0; 4127 return 0;
4131} 4128}
4132 4129
4130static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
4131 struct ieee80211_channel_switch *ch_switch)
4132{
4133 struct wl1271 *wl = hw->priv;
4134 int ret;
4135
4136 wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch");
4137
4138 mutex_lock(&wl->mutex);
4139
4140 if (unlikely(wl->state == WL1271_STATE_OFF)) {
4141 mutex_unlock(&wl->mutex);
4142 ieee80211_chswitch_done(wl->vif, false);
4143 return;
4144 }
4145
4146 ret = wl1271_ps_elp_wakeup(wl);
4147 if (ret < 0)
4148 goto out;
4149
4150 ret = wl12xx_cmd_channel_switch(wl, ch_switch);
4151
4152 if (!ret)
4153 set_bit(WL1271_FLAG_CS_PROGRESS, &wl->flags);
4154
4155 wl1271_ps_elp_sleep(wl);
4156
4157out:
4158 mutex_unlock(&wl->mutex);
4159}
4160
4133static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) 4161static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
4134{ 4162{
4135 struct wl1271 *wl = hw->priv; 4163 struct wl1271 *wl = hw->priv;
@@ -4406,6 +4434,7 @@ static const struct ieee80211_ops wl1271_ops = {
4406 .ampdu_action = wl1271_op_ampdu_action, 4434 .ampdu_action = wl1271_op_ampdu_action,
4407 .tx_frames_pending = wl1271_tx_frames_pending, 4435 .tx_frames_pending = wl1271_tx_frames_pending,
4408 .set_bitrate_mask = wl12xx_set_bitrate_mask, 4436 .set_bitrate_mask = wl12xx_set_bitrate_mask,
4437 .channel_switch = wl12xx_op_channel_switch,
4409 CFG80211_TESTMODE_CMD(wl1271_tm_cmd) 4438 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
4410}; 4439};
4411 4440
@@ -4679,6 +4708,9 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
4679 wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_DFLT_SIZE - 4708 wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_DFLT_SIZE -
4680 sizeof(struct ieee80211_header); 4709 sizeof(struct ieee80211_header);
4681 4710
4711 wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_DFLT_SIZE -
4712 sizeof(struct ieee80211_header);
4713
4682 wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; 4714 wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
4683 4715
4684 /* make sure all our channels fit in the scanned_ch bitmask */ 4716 /* make sure all our channels fit in the scanned_ch bitmask */
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 997f53245011..1ec90fc7505e 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -348,6 +348,7 @@ enum wl12xx_flags {
348 WL1271_FLAG_SOFT_GEMINI, 348 WL1271_FLAG_SOFT_GEMINI,
349 WL1271_FLAG_RX_STREAMING_STARTED, 349 WL1271_FLAG_RX_STREAMING_STARTED,
350 WL1271_FLAG_RECOVERY_IN_PROGRESS, 350 WL1271_FLAG_RECOVERY_IN_PROGRESS,
351 WL1271_FLAG_CS_PROGRESS,
351}; 352};
352 353
353struct wl1271_link { 354struct wl1271_link {
@@ -671,12 +672,6 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen);
671/* WL128X requires aggregated packets to be aligned to the SDIO block size */ 672/* WL128X requires aggregated packets to be aligned to the SDIO block size */
672#define WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT BIT(2) 673#define WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT BIT(2)
673 674
674/*
675 * WL127X AP mode requires Low Power DRPw (LPD) enable to reduce power
676 * consumption
677 */
678#define WL12XX_QUIRK_LPD_MODE BIT(3)
679
680/* Older firmwares did not implement the FW logger over bus feature */ 675/* Older firmwares did not implement the FW logger over bus feature */
681#define WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED BIT(4) 676#define WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED BIT(4)
682 677
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index d497a93748a1..2582e1890335 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -44,7 +44,7 @@ source "drivers/staging/wlan-ng/Kconfig"
44 44
45source "drivers/staging/echo/Kconfig" 45source "drivers/staging/echo/Kconfig"
46 46
47source "drivers/staging/brcm80211/Kconfig" 47
48 48
49source "drivers/staging/comedi/Kconfig" 49source "drivers/staging/comedi/Kconfig"
50 50
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index fe6c6114a668..50d112fe4ca1 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -14,8 +14,8 @@ obj-$(CONFIG_USBIP_CORE) += usbip/
14obj-$(CONFIG_W35UND) += winbond/ 14obj-$(CONFIG_W35UND) += winbond/
15obj-$(CONFIG_PRISM2_USB) += wlan-ng/ 15obj-$(CONFIG_PRISM2_USB) += wlan-ng/
16obj-$(CONFIG_ECHO) += echo/ 16obj-$(CONFIG_ECHO) += echo/
17obj-$(CONFIG_BRCMSMAC) += brcm80211/ 17
18obj-$(CONFIG_BRCMFMAC) += brcm80211/ 18
19obj-$(CONFIG_COMEDI) += comedi/ 19obj-$(CONFIG_COMEDI) += comedi/
20obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ 20obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
21obj-$(CONFIG_ASUS_OLED) += asus_oled/ 21obj-$(CONFIG_ASUS_OLED) += asus_oled/
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 9d797f253d8e..8049bf77d799 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1548,6 +1548,7 @@ enum nl80211_sta_bss_param {
1548 * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute 1548 * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute
1549 * containing info as possible, see &enum nl80211_sta_bss_param 1549 * containing info as possible, see &enum nl80211_sta_bss_param
1550 * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected 1550 * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected
1551 * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update.
1551 * @__NL80211_STA_INFO_AFTER_LAST: internal 1552 * @__NL80211_STA_INFO_AFTER_LAST: internal
1552 * @NL80211_STA_INFO_MAX: highest possible station info attribute 1553 * @NL80211_STA_INFO_MAX: highest possible station info attribute
1553 */ 1554 */
@@ -1569,6 +1570,7 @@ enum nl80211_sta_info {
1569 NL80211_STA_INFO_RX_BITRATE, 1570 NL80211_STA_INFO_RX_BITRATE,
1570 NL80211_STA_INFO_BSS_PARAM, 1571 NL80211_STA_INFO_BSS_PARAM,
1571 NL80211_STA_INFO_CONNECTED_TIME, 1572 NL80211_STA_INFO_CONNECTED_TIME,
1573 NL80211_STA_INFO_STA_FLAGS,
1572 1574
1573 /* keep last */ 1575 /* keep last */
1574 __NL80211_STA_INFO_AFTER_LAST, 1576 __NL80211_STA_INFO_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 74f4f85be32f..92cf1c2c30c9 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -497,6 +497,7 @@ struct station_parameters {
497 * @STATION_INFO_BSS_PARAM: @bss_param filled 497 * @STATION_INFO_BSS_PARAM: @bss_param filled
498 * @STATION_INFO_CONNECTED_TIME: @connected_time filled 498 * @STATION_INFO_CONNECTED_TIME: @connected_time filled
499 * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled 499 * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
500 * @STATION_INFO_STA_FLAGS: @sta_flags filled
500 */ 501 */
501enum station_info_flags { 502enum station_info_flags {
502 STATION_INFO_INACTIVE_TIME = 1<<0, 503 STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -516,7 +517,8 @@ enum station_info_flags {
516 STATION_INFO_RX_BITRATE = 1<<14, 517 STATION_INFO_RX_BITRATE = 1<<14,
517 STATION_INFO_BSS_PARAM = 1<<15, 518 STATION_INFO_BSS_PARAM = 1<<15,
518 STATION_INFO_CONNECTED_TIME = 1<<16, 519 STATION_INFO_CONNECTED_TIME = 1<<16,
519 STATION_INFO_ASSOC_REQ_IES = 1<<17 520 STATION_INFO_ASSOC_REQ_IES = 1<<17,
521 STATION_INFO_STA_FLAGS = 1<<18
520}; 522};
521 523
522/** 524/**
@@ -633,6 +635,7 @@ struct station_info {
633 u32 tx_failed; 635 u32 tx_failed;
634 u32 rx_dropped_misc; 636 u32 rx_dropped_misc;
635 struct sta_bss_parameters bss_param; 637 struct sta_bss_parameters bss_param;
638 struct nl80211_sta_flag_update sta_flags;
636 639
637 int generation; 640 int generation;
638 641
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index cd108dfa1952..dc1123aa8181 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -349,8 +349,6 @@ struct ieee80211_bss_conf {
349 * @IEEE80211_TX_INTFL_RETRANSMISSION: This frame is being retransmitted 349 * @IEEE80211_TX_INTFL_RETRANSMISSION: This frame is being retransmitted
350 * after TX status because the destination was asleep, it must not 350 * after TX status because the destination was asleep, it must not
351 * be modified again (no seqno assignment, crypto, etc.) 351 * be modified again (no seqno assignment, crypto, etc.)
352 * @IEEE80211_TX_INTFL_HAS_RADIOTAP: This frame was injected and still
353 * has a radiotap header at skb->data.
354 * @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211 352 * @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211
355 * MLME command (internal to mac80211 to figure out whether to send TX 353 * MLME command (internal to mac80211 to figure out whether to send TX
356 * status to user space) 354 * status to user space)
@@ -375,6 +373,9 @@ struct ieee80211_bss_conf {
375 * @IEEE80211_TX_CTL_USE_MINRATE: This frame will be sent at lowest rate. 373 * @IEEE80211_TX_CTL_USE_MINRATE: This frame will be sent at lowest rate.
376 * This flag is used to send nullfunc frame at minimum rate when 374 * This flag is used to send nullfunc frame at minimum rate when
377 * the nullfunc is used for connection monitoring purpose. 375 * the nullfunc is used for connection monitoring purpose.
376 * @IEEE80211_TX_CTL_DONTFRAG: Don't fragment this packet even if it
377 * would be fragmented by size (this is optional, only used for
378 * monitor injection).
378 * 379 *
379 * Note: If you have to add new flags to the enumeration, then don't 380 * Note: If you have to add new flags to the enumeration, then don't
380 * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary. 381 * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary.
@@ -399,7 +400,7 @@ enum mac80211_tx_control_flags {
399 IEEE80211_TX_CTL_POLL_RESPONSE = BIT(17), 400 IEEE80211_TX_CTL_POLL_RESPONSE = BIT(17),
400 IEEE80211_TX_CTL_MORE_FRAMES = BIT(18), 401 IEEE80211_TX_CTL_MORE_FRAMES = BIT(18),
401 IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19), 402 IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19),
402 IEEE80211_TX_INTFL_HAS_RADIOTAP = BIT(20), 403 /* hole at 20, use later */
403 IEEE80211_TX_INTFL_NL80211_FRAME_TX = BIT(21), 404 IEEE80211_TX_INTFL_NL80211_FRAME_TX = BIT(21),
404 IEEE80211_TX_CTL_LDPC = BIT(22), 405 IEEE80211_TX_CTL_LDPC = BIT(22),
405 IEEE80211_TX_CTL_STBC = BIT(23) | BIT(24), 406 IEEE80211_TX_CTL_STBC = BIT(23) | BIT(24),
@@ -408,6 +409,7 @@ enum mac80211_tx_control_flags {
408 IEEE80211_TX_CTL_NO_CCK_RATE = BIT(27), 409 IEEE80211_TX_CTL_NO_CCK_RATE = BIT(27),
409 IEEE80211_TX_STATUS_EOSP = BIT(28), 410 IEEE80211_TX_STATUS_EOSP = BIT(28),
410 IEEE80211_TX_CTL_USE_MINRATE = BIT(29), 411 IEEE80211_TX_CTL_USE_MINRATE = BIT(29),
412 IEEE80211_TX_CTL_DONTFRAG = BIT(30),
411}; 413};
412 414
413#define IEEE80211_TX_CTL_STBC_SHIFT 23 415#define IEEE80211_TX_CTL_STBC_SHIFT 23
@@ -2520,7 +2522,7 @@ static inline int ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta,
2520 * The TX headroom reserved by mac80211 for its own tx_status functions. 2522 * The TX headroom reserved by mac80211 for its own tx_status functions.
2521 * This is enough for the radiotap header. 2523 * This is enough for the radiotap header.
2522 */ 2524 */
2523#define IEEE80211_TX_STATUS_HEADROOM 13 2525#define IEEE80211_TX_STATUS_HEADROOM 14
2524 2526
2525/** 2527/**
2526 * ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames 2528 * ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 55ee5a31756f..ebd7fb101fbf 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -344,7 +344,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
344 STATION_INFO_RX_BITRATE | 344 STATION_INFO_RX_BITRATE |
345 STATION_INFO_RX_DROP_MISC | 345 STATION_INFO_RX_DROP_MISC |
346 STATION_INFO_BSS_PARAM | 346 STATION_INFO_BSS_PARAM |
347 STATION_INFO_CONNECTED_TIME; 347 STATION_INFO_CONNECTED_TIME |
348 STATION_INFO_STA_FLAGS;
348 349
349 do_posix_clock_monotonic_gettime(&uptime); 350 do_posix_clock_monotonic_gettime(&uptime);
350 sinfo->connected_time = uptime.tv_sec - sta->last_connected; 351 sinfo->connected_time = uptime.tv_sec - sta->last_connected;
@@ -404,6 +405,23 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
404 sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; 405 sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
405 sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period; 406 sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period;
406 sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int; 407 sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int;
408
409 sinfo->sta_flags.set = 0;
410 sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
411 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
412 BIT(NL80211_STA_FLAG_WME) |
413 BIT(NL80211_STA_FLAG_MFP) |
414 BIT(NL80211_STA_FLAG_AUTHENTICATED);
415 if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
416 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
417 if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE))
418 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
419 if (test_sta_flag(sta, WLAN_STA_WME))
420 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME);
421 if (test_sta_flag(sta, WLAN_STA_MFP))
422 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP);
423 if (test_sta_flag(sta, WLAN_STA_AUTH))
424 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
407} 425}
408 426
409 427
@@ -1886,7 +1904,7 @@ ieee80211_offchan_tx_done(struct ieee80211_work *wk, struct sk_buff *skb)
1886 * so in that case userspace will have to deal with it. 1904 * so in that case userspace will have to deal with it.
1887 */ 1905 */
1888 1906
1889 if (wk->offchan_tx.wait && wk->offchan_tx.frame) 1907 if (wk->offchan_tx.wait && !wk->offchan_tx.status)
1890 cfg80211_mgmt_tx_status(wk->sdata->dev, 1908 cfg80211_mgmt_tx_status(wk->sdata->dev,
1891 (unsigned long) wk->offchan_tx.frame, 1909 (unsigned long) wk->offchan_tx.frame,
1892 wk->ie, wk->ie_len, false, GFP_KERNEL); 1910 wk->ie, wk->ie_len, false, GFP_KERNEL);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 9fa5f8a674bc..4c3d1f591bec 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -136,7 +136,6 @@ typedef unsigned __bitwise__ ieee80211_tx_result;
136#define TX_DROP ((__force ieee80211_tx_result) 1u) 136#define TX_DROP ((__force ieee80211_tx_result) 1u)
137#define TX_QUEUED ((__force ieee80211_tx_result) 2u) 137#define TX_QUEUED ((__force ieee80211_tx_result) 2u)
138 138
139#define IEEE80211_TX_FRAGMENTED BIT(0)
140#define IEEE80211_TX_UNICAST BIT(1) 139#define IEEE80211_TX_UNICAST BIT(1)
141#define IEEE80211_TX_PS_BUFFERED BIT(2) 140#define IEEE80211_TX_PS_BUFFERED BIT(2)
142 141
@@ -149,7 +148,6 @@ struct ieee80211_tx_data {
149 148
150 struct ieee80211_channel *channel; 149 struct ieee80211_channel *channel;
151 150
152 u16 ethertype;
153 unsigned int flags; 151 unsigned int flags;
154}; 152};
155 153
@@ -346,6 +344,7 @@ struct ieee80211_work {
346 struct { 344 struct {
347 struct sk_buff *frame; 345 struct sk_buff *frame;
348 u32 wait; 346 u32 wait;
347 bool status;
349 } offchan_tx; 348 } offchan_tx;
350 }; 349 };
351 350
@@ -1178,18 +1177,6 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1178netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, 1177netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1179 struct net_device *dev); 1178 struct net_device *dev);
1180 1179
1181/*
1182 * radiotap header for status frames
1183 */
1184struct ieee80211_tx_status_rtap_hdr {
1185 struct ieee80211_radiotap_header hdr;
1186 u8 rate;
1187 u8 padding_for_rate;
1188 __le16 tx_flags;
1189 u8 data_retries;
1190} __packed;
1191
1192
1193/* HT */ 1180/* HT */
1194void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, 1181void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
1195 struct ieee80211_ht_cap *ht_cap_ie, 1182 struct ieee80211_ht_cap *ht_cap_ie,
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 17b038aeac9b..d4ee6d234a78 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -904,12 +904,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
904 * and we need some headroom for passing the frame to monitor 904 * and we need some headroom for passing the frame to monitor
905 * interfaces, but never both at the same time. 905 * interfaces, but never both at the same time.
906 */ 906 */
907#ifndef __CHECKER__
908 BUILD_BUG_ON(IEEE80211_TX_STATUS_HEADROOM !=
909 sizeof(struct ieee80211_tx_status_rtap_hdr));
910#endif
911 local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom, 907 local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom,
912 sizeof(struct ieee80211_tx_status_rtap_hdr)); 908 IEEE80211_TX_STATUS_HEADROOM);
913 909
914 debugfs_hw_add(local); 910 debugfs_hw_add(local);
915 911
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 6df7913d7ca4..174040a42887 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -789,11 +789,20 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
789 struct ieee802_11_elems elems; 789 struct ieee802_11_elems elems;
790 size_t baselen; 790 size_t baselen;
791 u32 last_hop_metric; 791 u32 last_hop_metric;
792 struct sta_info *sta;
792 793
793 /* need action_code */ 794 /* need action_code */
794 if (len < IEEE80211_MIN_ACTION_SIZE + 1) 795 if (len < IEEE80211_MIN_ACTION_SIZE + 1)
795 return; 796 return;
796 797
798 rcu_read_lock();
799 sta = sta_info_get(sdata, mgmt->sa);
800 if (!sta || sta->plink_state != NL80211_PLINK_ESTAB) {
801 rcu_read_unlock();
802 return;
803 }
804 rcu_read_unlock();
805
797 baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt; 806 baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt;
798 ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, 807 ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable,
799 len - baselen, &elems); 808 len - baselen, &elems);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 830e60f65779..397343a59275 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -254,6 +254,7 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
254 req->ie, req->ie_len, band, 254 req->ie, req->ie_len, band,
255 req->rates[band], 0); 255 req->rates[band], 0);
256 local->hw_scan_req->ie_len = ielen; 256 local->hw_scan_req->ie_len = ielen;
257 local->hw_scan_req->no_cck = req->no_cck;
257 258
258 return true; 259 return true;
259} 260}
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 58b1c2bb26d2..ce962d2c8782 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1203,11 +1203,9 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata,
1203 memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN); 1203 memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
1204 memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN); 1204 memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN);
1205 1205
1206 skb->priority = tid;
1207 skb_set_queue_mapping(skb, ieee802_1d_to_ac[tid]);
1206 if (qos) { 1208 if (qos) {
1207 skb->priority = tid;
1208
1209 skb_set_queue_mapping(skb, ieee802_1d_to_ac[tid]);
1210
1211 nullfunc->qos_ctrl = cpu_to_le16(tid); 1209 nullfunc->qos_ctrl = cpu_to_le16(tid);
1212 1210
1213 if (reason == IEEE80211_FRAME_RELEASE_UAPSD) 1211 if (reason == IEEE80211_FRAME_RELEASE_UAPSD)
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 864a9c3bcf46..df643cedf9b9 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -228,6 +228,102 @@ static void ieee80211_set_bar_pending(struct sta_info *sta, u8 tid, u16 ssn)
228 tid_tx->bar_pending = true; 228 tid_tx->bar_pending = true;
229} 229}
230 230
231static int ieee80211_tx_radiotap_len(struct ieee80211_tx_info *info)
232{
233 int len = sizeof(struct ieee80211_radiotap_header);
234
235 /* IEEE80211_RADIOTAP_RATE rate */
236 if (info->status.rates[0].idx >= 0 &&
237 !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS))
238 len += 2;
239
240 /* IEEE80211_RADIOTAP_TX_FLAGS */
241 len += 2;
242
243 /* IEEE80211_RADIOTAP_DATA_RETRIES */
244 len += 1;
245
246 /* IEEE80211_TX_RC_MCS */
247 if (info->status.rates[0].idx >= 0 &&
248 info->status.rates[0].flags & IEEE80211_TX_RC_MCS)
249 len += 3;
250
251 return len;
252}
253
254static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
255 *sband, struct sk_buff *skb,
256 int retry_count, int rtap_len)
257{
258 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
259 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
260 struct ieee80211_radiotap_header *rthdr;
261 unsigned char *pos;
262 __le16 txflags;
263
264 rthdr = (struct ieee80211_radiotap_header *) skb_push(skb, rtap_len);
265
266 memset(rthdr, 0, rtap_len);
267 rthdr->it_len = cpu_to_le16(rtap_len);
268 rthdr->it_present =
269 cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
270 (1 << IEEE80211_RADIOTAP_DATA_RETRIES));
271 pos = (unsigned char *)(rthdr + 1);
272
273 /*
274 * XXX: Once radiotap gets the bitmap reset thing the vendor
275 * extensions proposal contains, we can actually report
276 * the whole set of tries we did.
277 */
278
279 /* IEEE80211_RADIOTAP_RATE */
280 if (info->status.rates[0].idx >= 0 &&
281 !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) {
282 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
283 *pos = sband->bitrates[info->status.rates[0].idx].bitrate / 5;
284 /* padding for tx flags */
285 pos += 2;
286 }
287
288 /* IEEE80211_RADIOTAP_TX_FLAGS */
289 txflags = 0;
290 if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
291 !is_multicast_ether_addr(hdr->addr1))
292 txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);
293
294 if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
295 (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
296 txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS);
297 else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
298 txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS);
299
300 put_unaligned_le16(txflags, pos);
301 pos += 2;
302
303 /* IEEE80211_RADIOTAP_DATA_RETRIES */
304 /* for now report the total retry_count */
305 *pos = retry_count;
306 pos++;
307
308 /* IEEE80211_TX_RC_MCS */
309 if (info->status.rates[0].idx >= 0 &&
310 info->status.rates[0].flags & IEEE80211_TX_RC_MCS) {
311 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS);
312 pos[0] = IEEE80211_RADIOTAP_MCS_HAVE_MCS |
313 IEEE80211_RADIOTAP_MCS_HAVE_GI |
314 IEEE80211_RADIOTAP_MCS_HAVE_BW;
315 if (info->status.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
316 pos[1] |= IEEE80211_RADIOTAP_MCS_SGI;
317 if (info->status.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
318 pos[1] |= IEEE80211_RADIOTAP_MCS_BW_40;
319 if (info->status.rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD)
320 pos[1] |= IEEE80211_RADIOTAP_MCS_FMT_GF;
321 pos[2] = info->status.rates[0].idx;
322 pos += 3;
323 }
324
325}
326
231/* 327/*
232 * Use a static threshold for now, best value to be determined 328 * Use a static threshold for now, best value to be determined
233 * by testing ... 329 * by testing ...
@@ -246,7 +342,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
246 u16 frag, type; 342 u16 frag, type;
247 __le16 fc; 343 __le16 fc;
248 struct ieee80211_supported_band *sband; 344 struct ieee80211_supported_band *sband;
249 struct ieee80211_tx_status_rtap_hdr *rthdr;
250 struct ieee80211_sub_if_data *sdata; 345 struct ieee80211_sub_if_data *sdata;
251 struct net_device *prev_dev = NULL; 346 struct net_device *prev_dev = NULL;
252 struct sta_info *sta, *tmp; 347 struct sta_info *sta, *tmp;
@@ -256,6 +351,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
256 bool acked; 351 bool acked;
257 struct ieee80211_bar *bar; 352 struct ieee80211_bar *bar;
258 u16 tid; 353 u16 tid;
354 int rtap_len;
259 355
260 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 356 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
261 if (info->status.rates[i].idx < 0) { 357 if (info->status.rates[i].idx < 0) {
@@ -429,7 +525,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
429 continue; 525 continue;
430 if (wk->offchan_tx.frame != skb) 526 if (wk->offchan_tx.frame != skb)
431 continue; 527 continue;
432 wk->offchan_tx.frame = NULL; 528 wk->offchan_tx.status = true;
433 break; 529 break;
434 } 530 }
435 rcu_read_unlock(); 531 rcu_read_unlock();
@@ -460,44 +556,13 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
460 } 556 }
461 557
462 /* send frame to monitor interfaces now */ 558 /* send frame to monitor interfaces now */
463 559 rtap_len = ieee80211_tx_radiotap_len(info);
464 if (skb_headroom(skb) < sizeof(*rthdr)) { 560 if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) {
465 printk(KERN_ERR "ieee80211_tx_status: headroom too small\n"); 561 printk(KERN_ERR "ieee80211_tx_status: headroom too small\n");
466 dev_kfree_skb(skb); 562 dev_kfree_skb(skb);
467 return; 563 return;
468 } 564 }
469 565 ieee80211_add_tx_radiotap_header(sband, skb, retry_count, rtap_len);
470 rthdr = (struct ieee80211_tx_status_rtap_hdr *)
471 skb_push(skb, sizeof(*rthdr));
472
473 memset(rthdr, 0, sizeof(*rthdr));
474 rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
475 rthdr->hdr.it_present =
476 cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
477 (1 << IEEE80211_RADIOTAP_DATA_RETRIES) |
478 (1 << IEEE80211_RADIOTAP_RATE));
479
480 if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
481 !is_multicast_ether_addr(hdr->addr1))
482 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);
483
484 /*
485 * XXX: Once radiotap gets the bitmap reset thing the vendor
486 * extensions proposal contains, we can actually report
487 * the whole set of tries we did.
488 */
489 if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
490 (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
491 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS);
492 else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
493 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS);
494 if (info->status.rates[0].idx >= 0 &&
495 !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS))
496 rthdr->rate = sband->bitrates[
497 info->status.rates[0].idx].bitrate / 5;
498
499 /* for now report the total retry_count */
500 rthdr->data_retries = retry_count;
501 566
502 /* XXX: is this sufficient for BPF? */ 567 /* XXX: is this sufficient for BPF? */
503 skb_set_mac_header(skb, 0); 568 skb_set_mac_header(skb, 0);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ad2ee4a90ec4..48bbb96d8edb 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -898,7 +898,10 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
898 int hdrlen; 898 int hdrlen;
899 int fragnum; 899 int fragnum;
900 900
901 if (!(tx->flags & IEEE80211_TX_FRAGMENTED)) 901 if (info->flags & IEEE80211_TX_CTL_DONTFRAG)
902 return TX_CONTINUE;
903
904 if (tx->local->ops->set_frag_threshold)
902 return TX_CONTINUE; 905 return TX_CONTINUE;
903 906
904 /* 907 /*
@@ -911,7 +914,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
911 914
912 hdrlen = ieee80211_hdrlen(hdr->frame_control); 915 hdrlen = ieee80211_hdrlen(hdr->frame_control);
913 916
914 /* internal error, why is TX_FRAGMENTED set? */ 917 /* internal error, why isn't DONTFRAG set? */
915 if (WARN_ON(skb->len + FCS_LEN <= frag_threshold)) 918 if (WARN_ON(skb->len + FCS_LEN <= frag_threshold))
916 return TX_DROP; 919 return TX_DROP;
917 920
@@ -1032,108 +1035,6 @@ ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx)
1032 1035
1033/* actual transmit path */ 1036/* actual transmit path */
1034 1037
1035/*
1036 * deal with packet injection down monitor interface
1037 * with Radiotap Header -- only called for monitor mode interface
1038 */
1039static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
1040 struct sk_buff *skb)
1041{
1042 /*
1043 * this is the moment to interpret and discard the radiotap header that
1044 * must be at the start of the packet injected in Monitor mode
1045 *
1046 * Need to take some care with endian-ness since radiotap
1047 * args are little-endian
1048 */
1049
1050 struct ieee80211_radiotap_iterator iterator;
1051 struct ieee80211_radiotap_header *rthdr =
1052 (struct ieee80211_radiotap_header *) skb->data;
1053 bool hw_frag;
1054 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1055 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len,
1056 NULL);
1057 u16 txflags;
1058
1059 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
1060 tx->flags &= ~IEEE80211_TX_FRAGMENTED;
1061
1062 /* packet is fragmented in HW if we have a non-NULL driver callback */
1063 hw_frag = (tx->local->ops->set_frag_threshold != NULL);
1064
1065 /*
1066 * for every radiotap entry that is present
1067 * (ieee80211_radiotap_iterator_next returns -ENOENT when no more
1068 * entries present, or -EINVAL on error)
1069 */
1070
1071 while (!ret) {
1072 ret = ieee80211_radiotap_iterator_next(&iterator);
1073
1074 if (ret)
1075 continue;
1076
1077 /* see if this argument is something we can use */
1078 switch (iterator.this_arg_index) {
1079 /*
1080 * You must take care when dereferencing iterator.this_arg
1081 * for multibyte types... the pointer is not aligned. Use
1082 * get_unaligned((type *)iterator.this_arg) to dereference
1083 * iterator.this_arg for type "type" safely on all arches.
1084 */
1085 case IEEE80211_RADIOTAP_FLAGS:
1086 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) {
1087 /*
1088 * this indicates that the skb we have been
1089 * handed has the 32-bit FCS CRC at the end...
1090 * we should react to that by snipping it off
1091 * because it will be recomputed and added
1092 * on transmission
1093 */
1094 if (skb->len < (iterator._max_length + FCS_LEN))
1095 return false;
1096
1097 skb_trim(skb, skb->len - FCS_LEN);
1098 }
1099 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP)
1100 info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT;
1101 if ((*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) &&
1102 !hw_frag)
1103 tx->flags |= IEEE80211_TX_FRAGMENTED;
1104 break;
1105
1106 case IEEE80211_RADIOTAP_TX_FLAGS:
1107 txflags = le16_to_cpu(get_unaligned((__le16*)
1108 iterator.this_arg));
1109 if (txflags & IEEE80211_RADIOTAP_F_TX_NOACK)
1110 info->flags |= IEEE80211_TX_CTL_NO_ACK;
1111 break;
1112
1113 /*
1114 * Please update the file
1115 * Documentation/networking/mac80211-injection.txt
1116 * when parsing new fields here.
1117 */
1118
1119 default:
1120 break;
1121 }
1122 }
1123
1124 if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */
1125 return false;
1126
1127 /*
1128 * remove the radiotap header
1129 * iterator->_max_length was sanity-checked against
1130 * skb->len by iterator init
1131 */
1132 skb_pull(skb, iterator._max_length);
1133
1134 return true;
1135}
1136
1137static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, 1038static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
1138 struct sk_buff *skb, 1039 struct sk_buff *skb,
1139 struct ieee80211_tx_info *info, 1040 struct ieee80211_tx_info *info,
@@ -1198,7 +1099,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1198 struct ieee80211_local *local = sdata->local; 1099 struct ieee80211_local *local = sdata->local;
1199 struct ieee80211_hdr *hdr; 1100 struct ieee80211_hdr *hdr;
1200 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1101 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1201 int hdrlen, tid; 1102 int tid;
1202 u8 *qc; 1103 u8 *qc;
1203 1104
1204 memset(tx, 0, sizeof(*tx)); 1105 memset(tx, 0, sizeof(*tx));
@@ -1206,26 +1107,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1206 tx->local = local; 1107 tx->local = local;
1207 tx->sdata = sdata; 1108 tx->sdata = sdata;
1208 tx->channel = local->hw.conf.channel; 1109 tx->channel = local->hw.conf.channel;
1209 /*
1210 * Set this flag (used below to indicate "automatic fragmentation"),
1211 * it will be cleared/left by radiotap as desired.
1212 * Only valid when fragmentation is done by the stack.
1213 */
1214 if (!local->ops->set_frag_threshold)
1215 tx->flags |= IEEE80211_TX_FRAGMENTED;
1216
1217 /* process and remove the injection radiotap header */
1218 if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) {
1219 if (!__ieee80211_parse_tx_radiotap(tx, skb))
1220 return TX_DROP;
1221
1222 /*
1223 * __ieee80211_parse_tx_radiotap has now removed
1224 * the radiotap header that was present and pre-filled
1225 * 'tx' with tx control information.
1226 */
1227 info->flags &= ~IEEE80211_TX_INTFL_HAS_RADIOTAP;
1228 }
1229 1110
1230 /* 1111 /*
1231 * If this flag is set to true anywhere, and we get here, 1112 * If this flag is set to true anywhere, and we get here,
@@ -1281,13 +1162,11 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1281 */ 1162 */
1282 } 1163 }
1283 1164
1284 if (tx->flags & IEEE80211_TX_FRAGMENTED) { 1165 if (!(info->flags & IEEE80211_TX_CTL_DONTFRAG)) {
1285 if ((tx->flags & IEEE80211_TX_UNICAST) && 1166 if (!(tx->flags & IEEE80211_TX_UNICAST) ||
1286 skb->len + FCS_LEN > local->hw.wiphy->frag_threshold && 1167 skb->len + FCS_LEN <= local->hw.wiphy->frag_threshold ||
1287 !(info->flags & IEEE80211_TX_CTL_AMPDU)) 1168 info->flags & IEEE80211_TX_CTL_AMPDU)
1288 tx->flags |= IEEE80211_TX_FRAGMENTED; 1169 info->flags |= IEEE80211_TX_CTL_DONTFRAG;
1289 else
1290 tx->flags &= ~IEEE80211_TX_FRAGMENTED;
1291 } 1170 }
1292 1171
1293 if (!tx->sta) 1172 if (!tx->sta)
@@ -1295,11 +1174,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1295 else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT)) 1174 else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT))
1296 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; 1175 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
1297 1176
1298 hdrlen = ieee80211_hdrlen(hdr->frame_control);
1299 if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) {
1300 u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)];
1301 tx->ethertype = (pos[0] << 8) | pos[1];
1302 }
1303 info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT; 1177 info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT;
1304 1178
1305 return TX_CONTINUE; 1179 return TX_CONTINUE;
@@ -1510,11 +1384,6 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
1510 tail_need = max_t(int, tail_need, 0); 1384 tail_need = max_t(int, tail_need, 0);
1511 } 1385 }
1512 1386
1513 if (head_need || tail_need) {
1514 /* Sorry. Can't account for this any more */
1515 skb_orphan(skb);
1516 }
1517
1518 if (skb_cloned(skb)) 1387 if (skb_cloned(skb))
1519 I802_DEBUG_INC(local->tx_expand_skb_head_cloned); 1388 I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
1520 else if (head_need || tail_need) 1389 else if (head_need || tail_need)
@@ -1528,9 +1397,6 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
1528 return -ENOMEM; 1397 return -ENOMEM;
1529 } 1398 }
1530 1399
1531 /* update truesize too */
1532 skb->truesize += head_need + tail_need;
1533
1534 return 0; 1400 return 0;
1535} 1401}
1536 1402
@@ -1539,55 +1405,11 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
1539 struct ieee80211_local *local = sdata->local; 1405 struct ieee80211_local *local = sdata->local;
1540 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1406 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1541 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1407 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1542 struct ieee80211_sub_if_data *tmp_sdata;
1543 int headroom; 1408 int headroom;
1544 bool may_encrypt; 1409 bool may_encrypt;
1545 1410
1546 rcu_read_lock(); 1411 rcu_read_lock();
1547 1412
1548 if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) {
1549 int hdrlen;
1550 u16 len_rthdr;
1551
1552 info->flags |= IEEE80211_TX_CTL_INJECTED |
1553 IEEE80211_TX_INTFL_HAS_RADIOTAP;
1554
1555 len_rthdr = ieee80211_get_radiotap_len(skb->data);
1556 hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
1557 hdrlen = ieee80211_hdrlen(hdr->frame_control);
1558
1559 /* check the header is complete in the frame */
1560 if (likely(skb->len >= len_rthdr + hdrlen)) {
1561 /*
1562 * We process outgoing injected frames that have a
1563 * local address we handle as though they are our
1564 * own frames.
1565 * This code here isn't entirely correct, the local
1566 * MAC address is not necessarily enough to find
1567 * the interface to use; for that proper VLAN/WDS
1568 * support we will need a different mechanism.
1569 */
1570
1571 list_for_each_entry_rcu(tmp_sdata, &local->interfaces,
1572 list) {
1573 if (!ieee80211_sdata_running(tmp_sdata))
1574 continue;
1575 if (tmp_sdata->vif.type ==
1576 NL80211_IFTYPE_MONITOR ||
1577 tmp_sdata->vif.type ==
1578 NL80211_IFTYPE_AP_VLAN ||
1579 tmp_sdata->vif.type ==
1580 NL80211_IFTYPE_WDS)
1581 continue;
1582 if (compare_ether_addr(tmp_sdata->vif.addr,
1583 hdr->addr2) == 0) {
1584 sdata = tmp_sdata;
1585 break;
1586 }
1587 }
1588 }
1589 }
1590
1591 may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT); 1413 may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT);
1592 1414
1593 headroom = local->tx_headroom; 1415 headroom = local->tx_headroom;
@@ -1619,6 +1441,89 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
1619 rcu_read_unlock(); 1441 rcu_read_unlock();
1620} 1442}
1621 1443
1444static bool ieee80211_parse_tx_radiotap(struct sk_buff *skb)
1445{
1446 struct ieee80211_radiotap_iterator iterator;
1447 struct ieee80211_radiotap_header *rthdr =
1448 (struct ieee80211_radiotap_header *) skb->data;
1449 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1450 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len,
1451 NULL);
1452 u16 txflags;
1453
1454 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
1455 IEEE80211_TX_CTL_DONTFRAG;
1456
1457 /*
1458 * for every radiotap entry that is present
1459 * (ieee80211_radiotap_iterator_next returns -ENOENT when no more
1460 * entries present, or -EINVAL on error)
1461 */
1462
1463 while (!ret) {
1464 ret = ieee80211_radiotap_iterator_next(&iterator);
1465
1466 if (ret)
1467 continue;
1468
1469 /* see if this argument is something we can use */
1470 switch (iterator.this_arg_index) {
1471 /*
1472 * You must take care when dereferencing iterator.this_arg
1473 * for multibyte types... the pointer is not aligned. Use
1474 * get_unaligned((type *)iterator.this_arg) to dereference
1475 * iterator.this_arg for type "type" safely on all arches.
1476 */
1477 case IEEE80211_RADIOTAP_FLAGS:
1478 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) {
1479 /*
1480 * this indicates that the skb we have been
1481 * handed has the 32-bit FCS CRC at the end...
1482 * we should react to that by snipping it off
1483 * because it will be recomputed and added
1484 * on transmission
1485 */
1486 if (skb->len < (iterator._max_length + FCS_LEN))
1487 return false;
1488
1489 skb_trim(skb, skb->len - FCS_LEN);
1490 }
1491 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP)
1492 info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT;
1493 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG)
1494 info->flags &= ~IEEE80211_TX_CTL_DONTFRAG;
1495 break;
1496
1497 case IEEE80211_RADIOTAP_TX_FLAGS:
1498 txflags = get_unaligned_le16(iterator.this_arg);
1499 if (txflags & IEEE80211_RADIOTAP_F_TX_NOACK)
1500 info->flags |= IEEE80211_TX_CTL_NO_ACK;
1501 break;
1502
1503 /*
1504 * Please update the file
1505 * Documentation/networking/mac80211-injection.txt
1506 * when parsing new fields here.
1507 */
1508
1509 default:
1510 break;
1511 }
1512 }
1513
1514 if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */
1515 return false;
1516
1517 /*
1518 * remove the radiotap header
1519 * iterator->_max_length was sanity-checked against
1520 * skb->len by iterator init
1521 */
1522 skb_pull(skb, iterator._max_length);
1523
1524 return true;
1525}
1526
1622netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, 1527netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1623 struct net_device *dev) 1528 struct net_device *dev)
1624{ 1529{
@@ -1628,8 +1533,9 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1628 (struct ieee80211_radiotap_header *)skb->data; 1533 (struct ieee80211_radiotap_header *)skb->data;
1629 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1534 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1630 struct ieee80211_hdr *hdr; 1535 struct ieee80211_hdr *hdr;
1536 struct ieee80211_sub_if_data *tmp_sdata, *sdata;
1631 u16 len_rthdr; 1537 u16 len_rthdr;
1632 u8 *payload; 1538 int hdrlen;
1633 1539
1634 /* 1540 /*
1635 * Frame injection is not allowed if beaconing is not allowed 1541 * Frame injection is not allowed if beaconing is not allowed
@@ -1680,30 +1586,65 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1680 skb_set_network_header(skb, len_rthdr); 1586 skb_set_network_header(skb, len_rthdr);
1681 skb_set_transport_header(skb, len_rthdr); 1587 skb_set_transport_header(skb, len_rthdr);
1682 1588
1589 if (skb->len < len_rthdr + 2)
1590 goto fail;
1591
1592 hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
1593 hdrlen = ieee80211_hdrlen(hdr->frame_control);
1594
1595 if (skb->len < len_rthdr + hdrlen)
1596 goto fail;
1597
1683 /* 1598 /*
1684 * Initialize skb->protocol if the injected frame is a data frame 1599 * Initialize skb->protocol if the injected frame is a data frame
1685 * carrying a rfc1042 header 1600 * carrying a rfc1042 header
1686 */ 1601 */
1687 if (skb->len > len_rthdr + 2) { 1602 if (ieee80211_is_data(hdr->frame_control) &&
1688 hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); 1603 skb->len >= len_rthdr + hdrlen + sizeof(rfc1042_header) + 2) {
1689 if (ieee80211_is_data(hdr->frame_control) && 1604 u8 *payload = (u8 *)hdr + hdrlen;
1690 skb->len >= len_rthdr + 1605
1691 ieee80211_hdrlen(hdr->frame_control) + 1606 if (compare_ether_addr(payload, rfc1042_header) == 0)
1692 sizeof(rfc1042_header) + 2) { 1607 skb->protocol = cpu_to_be16((payload[6] << 8) |
1693 payload = (u8 *)hdr + 1608 payload[7]);
1694 ieee80211_hdrlen(hdr->frame_control);
1695 if (compare_ether_addr(payload, rfc1042_header) == 0)
1696 skb->protocol = cpu_to_be16((payload[6] << 8) |
1697 payload[7]);
1698 }
1699 } 1609 }
1700 1610
1701 memset(info, 0, sizeof(*info)); 1611 memset(info, 0, sizeof(*info));
1702 1612
1703 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; 1613 info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
1614 IEEE80211_TX_CTL_INJECTED;
1615
1616 /* process and remove the injection radiotap header */
1617 if (!ieee80211_parse_tx_radiotap(skb))
1618 goto fail;
1619
1620 rcu_read_lock();
1621
1622 /*
1623 * We process outgoing injected frames that have a local address
1624 * we handle as though they are non-injected frames.
1625 * This code here isn't entirely correct, the local MAC address
1626 * isn't always enough to find the interface to use; for proper
1627 * VLAN/WDS support we will need a different mechanism (which
1628 * likely isn't going to be monitor interfaces).
1629 */
1630 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1631
1632 list_for_each_entry_rcu(tmp_sdata, &local->interfaces, list) {
1633 if (!ieee80211_sdata_running(tmp_sdata))
1634 continue;
1635 if (tmp_sdata->vif.type == NL80211_IFTYPE_MONITOR ||
1636 tmp_sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
1637 tmp_sdata->vif.type == NL80211_IFTYPE_WDS)
1638 continue;
1639 if (compare_ether_addr(tmp_sdata->vif.addr, hdr->addr2) == 0) {
1640 sdata = tmp_sdata;
1641 break;
1642 }
1643 }
1644
1645 ieee80211_xmit(sdata, skb);
1646 rcu_read_unlock();
1704 1647
1705 /* pass the radiotap header up to xmit */
1706 ieee80211_xmit(IEEE80211_DEV_TO_SUB_IF(dev), skb);
1707 return NETDEV_TX_OK; 1648 return NETDEV_TX_OK;
1708 1649
1709fail: 1650fail:
@@ -1955,11 +1896,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1955 * Drop unicast frames to unauthorised stations unless they are 1896 * Drop unicast frames to unauthorised stations unless they are
1956 * EAPOL frames from the local station. 1897 * EAPOL frames from the local station.
1957 */ 1898 */
1958 if (!ieee80211_vif_is_mesh(&sdata->vif) && 1899 if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) &&
1959 unlikely(!is_multicast_ether_addr(hdr.addr1) && !authorized && 1900 !is_multicast_ether_addr(hdr.addr1) && !authorized &&
1960 !(cpu_to_be16(ethertype) == sdata->control_port_protocol && 1901 (cpu_to_be16(ethertype) != sdata->control_port_protocol ||
1961 compare_ether_addr(sdata->vif.addr, 1902 compare_ether_addr(sdata->vif.addr, skb->data + ETH_ALEN)))) {
1962 skb->data + ETH_ALEN) == 0))) {
1963#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1903#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1964 if (net_ratelimit()) 1904 if (net_ratelimit())
1965 printk(KERN_DEBUG "%s: dropped frame to %pM" 1905 printk(KERN_DEBUG "%s: dropped frame to %pM"
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index af374fab1a12..94472eb34d76 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -577,7 +577,7 @@ ieee80211_offchannel_tx(struct ieee80211_work *wk)
577 /* 577 /*
578 * After this, offchan_tx.frame remains but now is no 578 * After this, offchan_tx.frame remains but now is no
579 * longer a valid pointer -- we still need it as the 579 * longer a valid pointer -- we still need it as the
580 * cookie for canceling this work. 580 * cookie for canceling this work/status matching.
581 */ 581 */
582 ieee80211_tx_skb(wk->sdata, wk->offchan_tx.frame); 582 ieee80211_tx_skb(wk->sdata, wk->offchan_tx.frame);
583 583
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 7bc8702808fa..f614ce7bb6e3 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -53,7 +53,8 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
53 } 53 }
54 54
55 if (info->control.hw_key && 55 if (info->control.hw_key &&
56 !(tx->flags & IEEE80211_TX_FRAGMENTED) && 56 (info->flags & IEEE80211_TX_CTL_DONTFRAG ||
57 tx->local->ops->set_frag_threshold) &&
57 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) { 58 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
58 /* hwaccel - with no need for SW-generated MMIC */ 59 /* hwaccel - with no need for SW-generated MMIC */
59 return TX_CONTINUE; 60 return TX_CONTINUE;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index edf655aeea00..48260c2d092a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2344,6 +2344,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
2344 2344
2345 nla_nest_end(msg, bss_param); 2345 nla_nest_end(msg, bss_param);
2346 } 2346 }
2347 if (sinfo->filled & STATION_INFO_STA_FLAGS)
2348 NLA_PUT(msg, NL80211_STA_INFO_STA_FLAGS,
2349 sizeof(struct nl80211_sta_flag_update),
2350 &sinfo->sta_flags);
2347 nla_nest_end(msg, sinfoattr); 2351 nla_nest_end(msg, sinfoattr);
2348 2352
2349 if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES) 2353 if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)