diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2009-03-30 22:30:33 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-04-22 16:54:38 -0400 |
commit | 203c4805e91786f9a010bc7945a0fde70c9da28e (patch) | |
tree | 00415276b2fe65713f066ffe07b11ad2d8b6bea8 /drivers/net/wireless/ath9k | |
parent | 1878f77e13b9d720b78c4f818b94bfd4a7f596e5 (diff) |
atheros: put atheros wireless drivers into ath/
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k')
28 files changed, 0 insertions, 30093 deletions
diff --git a/drivers/net/wireless/ath9k/Kconfig b/drivers/net/wireless/ath9k/Kconfig deleted file mode 100644 index 0ed1ac312aa6..000000000000 --- a/drivers/net/wireless/ath9k/Kconfig +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | config ATH9K | ||
2 | tristate "Atheros 802.11n wireless cards support" | ||
3 | depends on PCI && MAC80211 && WLAN_80211 | ||
4 | depends on RFKILL || RFKILL=n | ||
5 | select ATH_COMMON | ||
6 | select MAC80211_LEDS | ||
7 | select LEDS_CLASS | ||
8 | select NEW_LEDS | ||
9 | ---help--- | ||
10 | This module adds support for wireless adapters based on | ||
11 | Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets. | ||
12 | |||
13 | If you choose to build a module, it'll be called ath9k. | ||
14 | |||
15 | config ATH9K_DEBUG | ||
16 | bool "Atheros ath9k debugging" | ||
17 | depends on ATH9K | ||
18 | ---help--- | ||
19 | Say Y, if you need ath9k to display debug messages. | ||
20 | Pass the debug mask as a module parameter: | ||
21 | |||
22 | modprobe ath9k debug=0x00002000 | ||
23 | |||
24 | Look in ath9k/core.h for possible debug masks | ||
diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath9k/Makefile deleted file mode 100644 index 783bc39eb2ff..000000000000 --- a/drivers/net/wireless/ath9k/Makefile +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | ath9k-y += hw.o \ | ||
2 | eeprom.o \ | ||
3 | mac.o \ | ||
4 | calib.o \ | ||
5 | ani.o \ | ||
6 | phy.o \ | ||
7 | beacon.o \ | ||
8 | main.o \ | ||
9 | recv.o \ | ||
10 | xmit.o \ | ||
11 | virtual.o \ | ||
12 | rc.o | ||
13 | |||
14 | ath9k-$(CONFIG_PCI) += pci.o | ||
15 | ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o | ||
16 | ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o | ||
17 | |||
18 | obj-$(CONFIG_ATH9K) += ath9k.o | ||
diff --git a/drivers/net/wireless/ath9k/ahb.c b/drivers/net/wireless/ath9k/ahb.c deleted file mode 100644 index 0e65c51ba176..000000000000 --- a/drivers/net/wireless/ath9k/ahb.c +++ /dev/null | |||
@@ -1,192 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | ||
3 | * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org> | ||
4 | * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org> | ||
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 | ||
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
17 | */ | ||
18 | |||
19 | #include <linux/nl80211.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/ath9k_platform.h> | ||
22 | #include "ath9k.h" | ||
23 | |||
24 | /* return bus cachesize in 4B word units */ | ||
25 | static void ath_ahb_read_cachesize(struct ath_softc *sc, int *csz) | ||
26 | { | ||
27 | *csz = L1_CACHE_BYTES >> 2; | ||
28 | } | ||
29 | |||
30 | static void ath_ahb_cleanup(struct ath_softc *sc) | ||
31 | { | ||
32 | iounmap(sc->mem); | ||
33 | } | ||
34 | |||
35 | static bool ath_ahb_eeprom_read(struct ath_hw *ah, u32 off, u16 *data) | ||
36 | { | ||
37 | struct ath_softc *sc = ah->ah_sc; | ||
38 | struct platform_device *pdev = to_platform_device(sc->dev); | ||
39 | struct ath9k_platform_data *pdata; | ||
40 | |||
41 | pdata = (struct ath9k_platform_data *) pdev->dev.platform_data; | ||
42 | if (off >= (ARRAY_SIZE(pdata->eeprom_data))) { | ||
43 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
44 | "%s: flash read failed, offset %08x is out of range\n", | ||
45 | __func__, off); | ||
46 | return false; | ||
47 | } | ||
48 | |||
49 | *data = pdata->eeprom_data[off]; | ||
50 | return true; | ||
51 | } | ||
52 | |||
53 | static struct ath_bus_ops ath_ahb_bus_ops = { | ||
54 | .read_cachesize = ath_ahb_read_cachesize, | ||
55 | .cleanup = ath_ahb_cleanup, | ||
56 | |||
57 | .eeprom_read = ath_ahb_eeprom_read, | ||
58 | }; | ||
59 | |||
60 | static int ath_ahb_probe(struct platform_device *pdev) | ||
61 | { | ||
62 | void __iomem *mem; | ||
63 | struct ath_wiphy *aphy; | ||
64 | struct ath_softc *sc; | ||
65 | struct ieee80211_hw *hw; | ||
66 | struct resource *res; | ||
67 | int irq; | ||
68 | int ret = 0; | ||
69 | struct ath_hw *ah; | ||
70 | |||
71 | if (!pdev->dev.platform_data) { | ||
72 | dev_err(&pdev->dev, "no platform data specified\n"); | ||
73 | ret = -EINVAL; | ||
74 | goto err_out; | ||
75 | } | ||
76 | |||
77 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
78 | if (res == NULL) { | ||
79 | dev_err(&pdev->dev, "no memory resource found\n"); | ||
80 | ret = -ENXIO; | ||
81 | goto err_out; | ||
82 | } | ||
83 | |||
84 | mem = ioremap_nocache(res->start, res->end - res->start + 1); | ||
85 | if (mem == NULL) { | ||
86 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
87 | ret = -ENOMEM; | ||
88 | goto err_out; | ||
89 | } | ||
90 | |||
91 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
92 | if (res == NULL) { | ||
93 | dev_err(&pdev->dev, "no IRQ resource found\n"); | ||
94 | ret = -ENXIO; | ||
95 | goto err_iounmap; | ||
96 | } | ||
97 | |||
98 | irq = res->start; | ||
99 | |||
100 | hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + | ||
101 | sizeof(struct ath_softc), &ath9k_ops); | ||
102 | if (hw == NULL) { | ||
103 | dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); | ||
104 | ret = -ENOMEM; | ||
105 | goto err_iounmap; | ||
106 | } | ||
107 | |||
108 | SET_IEEE80211_DEV(hw, &pdev->dev); | ||
109 | platform_set_drvdata(pdev, hw); | ||
110 | |||
111 | aphy = hw->priv; | ||
112 | sc = (struct ath_softc *) (aphy + 1); | ||
113 | aphy->sc = sc; | ||
114 | aphy->hw = hw; | ||
115 | sc->pri_wiphy = aphy; | ||
116 | sc->hw = hw; | ||
117 | sc->dev = &pdev->dev; | ||
118 | sc->mem = mem; | ||
119 | sc->bus_ops = &ath_ahb_bus_ops; | ||
120 | sc->irq = irq; | ||
121 | |||
122 | ret = ath_attach(AR5416_AR9100_DEVID, sc); | ||
123 | if (ret != 0) { | ||
124 | dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret); | ||
125 | ret = -ENODEV; | ||
126 | goto err_free_hw; | ||
127 | } | ||
128 | |||
129 | ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); | ||
130 | if (ret) { | ||
131 | dev_err(&pdev->dev, "request_irq failed, err=%d\n", ret); | ||
132 | ret = -EIO; | ||
133 | goto err_detach; | ||
134 | } | ||
135 | |||
136 | ah = sc->sc_ah; | ||
137 | printk(KERN_INFO | ||
138 | "%s: Atheros AR%s MAC/BB Rev:%x, " | ||
139 | "AR%s RF Rev:%x, mem=0x%lx, irq=%d\n", | ||
140 | wiphy_name(hw->wiphy), | ||
141 | ath_mac_bb_name(ah->hw_version.macVersion), | ||
142 | ah->hw_version.macRev, | ||
143 | ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)), | ||
144 | ah->hw_version.phyRev, | ||
145 | (unsigned long)mem, irq); | ||
146 | |||
147 | return 0; | ||
148 | |||
149 | err_detach: | ||
150 | ath_detach(sc); | ||
151 | err_free_hw: | ||
152 | ieee80211_free_hw(hw); | ||
153 | platform_set_drvdata(pdev, NULL); | ||
154 | err_iounmap: | ||
155 | iounmap(mem); | ||
156 | err_out: | ||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | static int ath_ahb_remove(struct platform_device *pdev) | ||
161 | { | ||
162 | struct ieee80211_hw *hw = platform_get_drvdata(pdev); | ||
163 | |||
164 | if (hw) { | ||
165 | struct ath_wiphy *aphy = hw->priv; | ||
166 | struct ath_softc *sc = aphy->sc; | ||
167 | |||
168 | ath_cleanup(sc); | ||
169 | platform_set_drvdata(pdev, NULL); | ||
170 | } | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static struct platform_driver ath_ahb_driver = { | ||
176 | .probe = ath_ahb_probe, | ||
177 | .remove = ath_ahb_remove, | ||
178 | .driver = { | ||
179 | .name = "ath9k", | ||
180 | .owner = THIS_MODULE, | ||
181 | }, | ||
182 | }; | ||
183 | |||
184 | int ath_ahb_init(void) | ||
185 | { | ||
186 | return platform_driver_register(&ath_ahb_driver); | ||
187 | } | ||
188 | |||
189 | void ath_ahb_exit(void) | ||
190 | { | ||
191 | platform_driver_unregister(&ath_ahb_driver); | ||
192 | } | ||
diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath9k/ani.c deleted file mode 100644 index 1aeafb511ddd..000000000000 --- a/drivers/net/wireless/ath9k/ani.c +++ /dev/null | |||
@@ -1,822 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 "ath9k.h" | ||
18 | |||
19 | static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, | ||
20 | struct ath9k_channel *chan) | ||
21 | { | ||
22 | int i; | ||
23 | |||
24 | for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { | ||
25 | if (ah->ani[i].c && | ||
26 | ah->ani[i].c->channel == chan->channel) | ||
27 | return i; | ||
28 | if (ah->ani[i].c == NULL) { | ||
29 | ah->ani[i].c = chan; | ||
30 | return i; | ||
31 | } | ||
32 | } | ||
33 | |||
34 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
35 | "No more channel states left. Using channel 0\n"); | ||
36 | |||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static bool ath9k_hw_ani_control(struct ath_hw *ah, | ||
41 | enum ath9k_ani_cmd cmd, int param) | ||
42 | { | ||
43 | struct ar5416AniState *aniState = ah->curani; | ||
44 | |||
45 | switch (cmd & ah->ani_function) { | ||
46 | case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{ | ||
47 | u32 level = param; | ||
48 | |||
49 | if (level >= ARRAY_SIZE(ah->totalSizeDesired)) { | ||
50 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
51 | "level out of range (%u > %u)\n", | ||
52 | level, | ||
53 | (unsigned)ARRAY_SIZE(ah->totalSizeDesired)); | ||
54 | return false; | ||
55 | } | ||
56 | |||
57 | REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, | ||
58 | AR_PHY_DESIRED_SZ_TOT_DES, | ||
59 | ah->totalSizeDesired[level]); | ||
60 | REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, | ||
61 | AR_PHY_AGC_CTL1_COARSE_LOW, | ||
62 | ah->coarse_low[level]); | ||
63 | REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, | ||
64 | AR_PHY_AGC_CTL1_COARSE_HIGH, | ||
65 | ah->coarse_high[level]); | ||
66 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, | ||
67 | AR_PHY_FIND_SIG_FIRPWR, | ||
68 | ah->firpwr[level]); | ||
69 | |||
70 | if (level > aniState->noiseImmunityLevel) | ||
71 | ah->stats.ast_ani_niup++; | ||
72 | else if (level < aniState->noiseImmunityLevel) | ||
73 | ah->stats.ast_ani_nidown++; | ||
74 | aniState->noiseImmunityLevel = level; | ||
75 | break; | ||
76 | } | ||
77 | case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ | ||
78 | const int m1ThreshLow[] = { 127, 50 }; | ||
79 | const int m2ThreshLow[] = { 127, 40 }; | ||
80 | const int m1Thresh[] = { 127, 0x4d }; | ||
81 | const int m2Thresh[] = { 127, 0x40 }; | ||
82 | const int m2CountThr[] = { 31, 16 }; | ||
83 | const int m2CountThrLow[] = { 63, 48 }; | ||
84 | u32 on = param ? 1 : 0; | ||
85 | |||
86 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, | ||
87 | AR_PHY_SFCORR_LOW_M1_THRESH_LOW, | ||
88 | m1ThreshLow[on]); | ||
89 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, | ||
90 | AR_PHY_SFCORR_LOW_M2_THRESH_LOW, | ||
91 | m2ThreshLow[on]); | ||
92 | REG_RMW_FIELD(ah, AR_PHY_SFCORR, | ||
93 | AR_PHY_SFCORR_M1_THRESH, | ||
94 | m1Thresh[on]); | ||
95 | REG_RMW_FIELD(ah, AR_PHY_SFCORR, | ||
96 | AR_PHY_SFCORR_M2_THRESH, | ||
97 | m2Thresh[on]); | ||
98 | REG_RMW_FIELD(ah, AR_PHY_SFCORR, | ||
99 | AR_PHY_SFCORR_M2COUNT_THR, | ||
100 | m2CountThr[on]); | ||
101 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, | ||
102 | AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, | ||
103 | m2CountThrLow[on]); | ||
104 | |||
105 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
106 | AR_PHY_SFCORR_EXT_M1_THRESH_LOW, | ||
107 | m1ThreshLow[on]); | ||
108 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
109 | AR_PHY_SFCORR_EXT_M2_THRESH_LOW, | ||
110 | m2ThreshLow[on]); | ||
111 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
112 | AR_PHY_SFCORR_EXT_M1_THRESH, | ||
113 | m1Thresh[on]); | ||
114 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
115 | AR_PHY_SFCORR_EXT_M2_THRESH, | ||
116 | m2Thresh[on]); | ||
117 | |||
118 | if (on) | ||
119 | REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, | ||
120 | AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); | ||
121 | else | ||
122 | REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, | ||
123 | AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); | ||
124 | |||
125 | if (!on != aniState->ofdmWeakSigDetectOff) { | ||
126 | if (on) | ||
127 | ah->stats.ast_ani_ofdmon++; | ||
128 | else | ||
129 | ah->stats.ast_ani_ofdmoff++; | ||
130 | aniState->ofdmWeakSigDetectOff = !on; | ||
131 | } | ||
132 | break; | ||
133 | } | ||
134 | case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{ | ||
135 | const int weakSigThrCck[] = { 8, 6 }; | ||
136 | u32 high = param ? 1 : 0; | ||
137 | |||
138 | REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, | ||
139 | AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, | ||
140 | weakSigThrCck[high]); | ||
141 | if (high != aniState->cckWeakSigThreshold) { | ||
142 | if (high) | ||
143 | ah->stats.ast_ani_cckhigh++; | ||
144 | else | ||
145 | ah->stats.ast_ani_ccklow++; | ||
146 | aniState->cckWeakSigThreshold = high; | ||
147 | } | ||
148 | break; | ||
149 | } | ||
150 | case ATH9K_ANI_FIRSTEP_LEVEL:{ | ||
151 | const int firstep[] = { 0, 4, 8 }; | ||
152 | u32 level = param; | ||
153 | |||
154 | if (level >= ARRAY_SIZE(firstep)) { | ||
155 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
156 | "level out of range (%u > %u)\n", | ||
157 | level, | ||
158 | (unsigned) ARRAY_SIZE(firstep)); | ||
159 | return false; | ||
160 | } | ||
161 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, | ||
162 | AR_PHY_FIND_SIG_FIRSTEP, | ||
163 | firstep[level]); | ||
164 | if (level > aniState->firstepLevel) | ||
165 | ah->stats.ast_ani_stepup++; | ||
166 | else if (level < aniState->firstepLevel) | ||
167 | ah->stats.ast_ani_stepdown++; | ||
168 | aniState->firstepLevel = level; | ||
169 | break; | ||
170 | } | ||
171 | case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ | ||
172 | const int cycpwrThr1[] = | ||
173 | { 2, 4, 6, 8, 10, 12, 14, 16 }; | ||
174 | u32 level = param; | ||
175 | |||
176 | if (level >= ARRAY_SIZE(cycpwrThr1)) { | ||
177 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
178 | "level out of range (%u > %u)\n", | ||
179 | level, | ||
180 | (unsigned) | ||
181 | ARRAY_SIZE(cycpwrThr1)); | ||
182 | return false; | ||
183 | } | ||
184 | REG_RMW_FIELD(ah, AR_PHY_TIMING5, | ||
185 | AR_PHY_TIMING5_CYCPWR_THR1, | ||
186 | cycpwrThr1[level]); | ||
187 | if (level > aniState->spurImmunityLevel) | ||
188 | ah->stats.ast_ani_spurup++; | ||
189 | else if (level < aniState->spurImmunityLevel) | ||
190 | ah->stats.ast_ani_spurdown++; | ||
191 | aniState->spurImmunityLevel = level; | ||
192 | break; | ||
193 | } | ||
194 | case ATH9K_ANI_PRESENT: | ||
195 | break; | ||
196 | default: | ||
197 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
198 | "invalid cmd %u\n", cmd); | ||
199 | return false; | ||
200 | } | ||
201 | |||
202 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, "ANI parameters:\n"); | ||
203 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
204 | "noiseImmunityLevel=%d, spurImmunityLevel=%d, " | ||
205 | "ofdmWeakSigDetectOff=%d\n", | ||
206 | aniState->noiseImmunityLevel, aniState->spurImmunityLevel, | ||
207 | !aniState->ofdmWeakSigDetectOff); | ||
208 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
209 | "cckWeakSigThreshold=%d, " | ||
210 | "firstepLevel=%d, listenTime=%d\n", | ||
211 | aniState->cckWeakSigThreshold, aniState->firstepLevel, | ||
212 | aniState->listenTime); | ||
213 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
214 | "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", | ||
215 | aniState->cycleCount, aniState->ofdmPhyErrCount, | ||
216 | aniState->cckPhyErrCount); | ||
217 | |||
218 | return true; | ||
219 | } | ||
220 | |||
221 | static void ath9k_hw_update_mibstats(struct ath_hw *ah, | ||
222 | struct ath9k_mib_stats *stats) | ||
223 | { | ||
224 | stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL); | ||
225 | stats->rts_bad += REG_READ(ah, AR_RTS_FAIL); | ||
226 | stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL); | ||
227 | stats->rts_good += REG_READ(ah, AR_RTS_OK); | ||
228 | stats->beacons += REG_READ(ah, AR_BEACON_CNT); | ||
229 | } | ||
230 | |||
231 | static void ath9k_ani_restart(struct ath_hw *ah) | ||
232 | { | ||
233 | struct ar5416AniState *aniState; | ||
234 | |||
235 | if (!DO_ANI(ah)) | ||
236 | return; | ||
237 | |||
238 | aniState = ah->curani; | ||
239 | |||
240 | aniState->listenTime = 0; | ||
241 | if (ah->has_hw_phycounters) { | ||
242 | if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) { | ||
243 | aniState->ofdmPhyErrBase = 0; | ||
244 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
245 | "OFDM Trigger is too high for hw counters\n"); | ||
246 | } else { | ||
247 | aniState->ofdmPhyErrBase = | ||
248 | AR_PHY_COUNTMAX - aniState->ofdmTrigHigh; | ||
249 | } | ||
250 | if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) { | ||
251 | aniState->cckPhyErrBase = 0; | ||
252 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
253 | "CCK Trigger is too high for hw counters\n"); | ||
254 | } else { | ||
255 | aniState->cckPhyErrBase = | ||
256 | AR_PHY_COUNTMAX - aniState->cckTrigHigh; | ||
257 | } | ||
258 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
259 | "Writing ofdmbase=%u cckbase=%u\n", | ||
260 | aniState->ofdmPhyErrBase, | ||
261 | aniState->cckPhyErrBase); | ||
262 | REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); | ||
263 | REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); | ||
264 | REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); | ||
265 | REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); | ||
266 | |||
267 | ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); | ||
268 | } | ||
269 | aniState->ofdmPhyErrCount = 0; | ||
270 | aniState->cckPhyErrCount = 0; | ||
271 | } | ||
272 | |||
273 | static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) | ||
274 | { | ||
275 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; | ||
276 | struct ar5416AniState *aniState; | ||
277 | int32_t rssi; | ||
278 | |||
279 | if (!DO_ANI(ah)) | ||
280 | return; | ||
281 | |||
282 | aniState = ah->curani; | ||
283 | |||
284 | if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { | ||
285 | if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, | ||
286 | aniState->noiseImmunityLevel + 1)) { | ||
287 | return; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) { | ||
292 | if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, | ||
293 | aniState->spurImmunityLevel + 1)) { | ||
294 | return; | ||
295 | } | ||
296 | } | ||
297 | |||
298 | if (ah->opmode == NL80211_IFTYPE_AP) { | ||
299 | if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { | ||
300 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, | ||
301 | aniState->firstepLevel + 1); | ||
302 | } | ||
303 | return; | ||
304 | } | ||
305 | rssi = BEACON_RSSI(ah); | ||
306 | if (rssi > aniState->rssiThrHigh) { | ||
307 | if (!aniState->ofdmWeakSigDetectOff) { | ||
308 | if (ath9k_hw_ani_control(ah, | ||
309 | ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, | ||
310 | false)) { | ||
311 | ath9k_hw_ani_control(ah, | ||
312 | ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); | ||
313 | return; | ||
314 | } | ||
315 | } | ||
316 | if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { | ||
317 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, | ||
318 | aniState->firstepLevel + 1); | ||
319 | return; | ||
320 | } | ||
321 | } else if (rssi > aniState->rssiThrLow) { | ||
322 | if (aniState->ofdmWeakSigDetectOff) | ||
323 | ath9k_hw_ani_control(ah, | ||
324 | ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, | ||
325 | true); | ||
326 | if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) | ||
327 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, | ||
328 | aniState->firstepLevel + 1); | ||
329 | return; | ||
330 | } else { | ||
331 | if (conf->channel->band == IEEE80211_BAND_2GHZ) { | ||
332 | if (!aniState->ofdmWeakSigDetectOff) | ||
333 | ath9k_hw_ani_control(ah, | ||
334 | ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, | ||
335 | false); | ||
336 | if (aniState->firstepLevel > 0) | ||
337 | ath9k_hw_ani_control(ah, | ||
338 | ATH9K_ANI_FIRSTEP_LEVEL, 0); | ||
339 | return; | ||
340 | } | ||
341 | } | ||
342 | } | ||
343 | |||
344 | static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah) | ||
345 | { | ||
346 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; | ||
347 | struct ar5416AniState *aniState; | ||
348 | int32_t rssi; | ||
349 | |||
350 | if (!DO_ANI(ah)) | ||
351 | return; | ||
352 | |||
353 | aniState = ah->curani; | ||
354 | if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { | ||
355 | if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, | ||
356 | aniState->noiseImmunityLevel + 1)) { | ||
357 | return; | ||
358 | } | ||
359 | } | ||
360 | if (ah->opmode == NL80211_IFTYPE_AP) { | ||
361 | if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { | ||
362 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, | ||
363 | aniState->firstepLevel + 1); | ||
364 | } | ||
365 | return; | ||
366 | } | ||
367 | rssi = BEACON_RSSI(ah); | ||
368 | if (rssi > aniState->rssiThrLow) { | ||
369 | if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) | ||
370 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, | ||
371 | aniState->firstepLevel + 1); | ||
372 | } else { | ||
373 | if (conf->channel->band == IEEE80211_BAND_2GHZ) { | ||
374 | if (aniState->firstepLevel > 0) | ||
375 | ath9k_hw_ani_control(ah, | ||
376 | ATH9K_ANI_FIRSTEP_LEVEL, 0); | ||
377 | } | ||
378 | } | ||
379 | } | ||
380 | |||
381 | static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) | ||
382 | { | ||
383 | struct ar5416AniState *aniState; | ||
384 | int32_t rssi; | ||
385 | |||
386 | aniState = ah->curani; | ||
387 | |||
388 | if (ah->opmode == NL80211_IFTYPE_AP) { | ||
389 | if (aniState->firstepLevel > 0) { | ||
390 | if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, | ||
391 | aniState->firstepLevel - 1)) | ||
392 | return; | ||
393 | } | ||
394 | } else { | ||
395 | rssi = BEACON_RSSI(ah); | ||
396 | if (rssi > aniState->rssiThrHigh) { | ||
397 | /* XXX: Handle me */ | ||
398 | } else if (rssi > aniState->rssiThrLow) { | ||
399 | if (aniState->ofdmWeakSigDetectOff) { | ||
400 | if (ath9k_hw_ani_control(ah, | ||
401 | ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, | ||
402 | true) == true) | ||
403 | return; | ||
404 | } | ||
405 | if (aniState->firstepLevel > 0) { | ||
406 | if (ath9k_hw_ani_control(ah, | ||
407 | ATH9K_ANI_FIRSTEP_LEVEL, | ||
408 | aniState->firstepLevel - 1) == true) | ||
409 | return; | ||
410 | } | ||
411 | } else { | ||
412 | if (aniState->firstepLevel > 0) { | ||
413 | if (ath9k_hw_ani_control(ah, | ||
414 | ATH9K_ANI_FIRSTEP_LEVEL, | ||
415 | aniState->firstepLevel - 1) == true) | ||
416 | return; | ||
417 | } | ||
418 | } | ||
419 | } | ||
420 | |||
421 | if (aniState->spurImmunityLevel > 0) { | ||
422 | if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, | ||
423 | aniState->spurImmunityLevel - 1)) | ||
424 | return; | ||
425 | } | ||
426 | |||
427 | if (aniState->noiseImmunityLevel > 0) { | ||
428 | ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, | ||
429 | aniState->noiseImmunityLevel - 1); | ||
430 | return; | ||
431 | } | ||
432 | } | ||
433 | |||
434 | static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) | ||
435 | { | ||
436 | struct ar5416AniState *aniState; | ||
437 | u32 txFrameCount, rxFrameCount, cycleCount; | ||
438 | int32_t listenTime; | ||
439 | |||
440 | txFrameCount = REG_READ(ah, AR_TFCNT); | ||
441 | rxFrameCount = REG_READ(ah, AR_RFCNT); | ||
442 | cycleCount = REG_READ(ah, AR_CCCNT); | ||
443 | |||
444 | aniState = ah->curani; | ||
445 | if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) { | ||
446 | |||
447 | listenTime = 0; | ||
448 | ah->stats.ast_ani_lzero++; | ||
449 | } else { | ||
450 | int32_t ccdelta = cycleCount - aniState->cycleCount; | ||
451 | int32_t rfdelta = rxFrameCount - aniState->rxFrameCount; | ||
452 | int32_t tfdelta = txFrameCount - aniState->txFrameCount; | ||
453 | listenTime = (ccdelta - rfdelta - tfdelta) / 44000; | ||
454 | } | ||
455 | aniState->cycleCount = cycleCount; | ||
456 | aniState->txFrameCount = txFrameCount; | ||
457 | aniState->rxFrameCount = rxFrameCount; | ||
458 | |||
459 | return listenTime; | ||
460 | } | ||
461 | |||
462 | void ath9k_ani_reset(struct ath_hw *ah) | ||
463 | { | ||
464 | struct ar5416AniState *aniState; | ||
465 | struct ath9k_channel *chan = ah->curchan; | ||
466 | int index; | ||
467 | |||
468 | if (!DO_ANI(ah)) | ||
469 | return; | ||
470 | |||
471 | index = ath9k_hw_get_ani_channel_idx(ah, chan); | ||
472 | aniState = &ah->ani[index]; | ||
473 | ah->curani = aniState; | ||
474 | |||
475 | if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION | ||
476 | && ah->opmode != NL80211_IFTYPE_ADHOC) { | ||
477 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
478 | "Reset ANI state opmode %u\n", ah->opmode); | ||
479 | ah->stats.ast_ani_reset++; | ||
480 | |||
481 | ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); | ||
482 | ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); | ||
483 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0); | ||
484 | ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, | ||
485 | !ATH9K_ANI_USE_OFDM_WEAK_SIG); | ||
486 | ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR, | ||
487 | ATH9K_ANI_CCK_WEAK_SIG_THR); | ||
488 | |||
489 | ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | | ||
490 | ATH9K_RX_FILTER_PHYERR); | ||
491 | |||
492 | if (ah->opmode == NL80211_IFTYPE_AP) { | ||
493 | ah->curani->ofdmTrigHigh = | ||
494 | ah->config.ofdm_trig_high; | ||
495 | ah->curani->ofdmTrigLow = | ||
496 | ah->config.ofdm_trig_low; | ||
497 | ah->curani->cckTrigHigh = | ||
498 | ah->config.cck_trig_high; | ||
499 | ah->curani->cckTrigLow = | ||
500 | ah->config.cck_trig_low; | ||
501 | } | ||
502 | ath9k_ani_restart(ah); | ||
503 | return; | ||
504 | } | ||
505 | |||
506 | if (aniState->noiseImmunityLevel != 0) | ||
507 | ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, | ||
508 | aniState->noiseImmunityLevel); | ||
509 | if (aniState->spurImmunityLevel != 0) | ||
510 | ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, | ||
511 | aniState->spurImmunityLevel); | ||
512 | if (aniState->ofdmWeakSigDetectOff) | ||
513 | ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, | ||
514 | !aniState->ofdmWeakSigDetectOff); | ||
515 | if (aniState->cckWeakSigThreshold) | ||
516 | ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR, | ||
517 | aniState->cckWeakSigThreshold); | ||
518 | if (aniState->firstepLevel != 0) | ||
519 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, | ||
520 | aniState->firstepLevel); | ||
521 | if (ah->has_hw_phycounters) { | ||
522 | ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & | ||
523 | ~ATH9K_RX_FILTER_PHYERR); | ||
524 | ath9k_ani_restart(ah); | ||
525 | REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); | ||
526 | REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); | ||
527 | |||
528 | } else { | ||
529 | ath9k_ani_restart(ah); | ||
530 | ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | | ||
531 | ATH9K_RX_FILTER_PHYERR); | ||
532 | } | ||
533 | } | ||
534 | |||
535 | void ath9k_hw_ani_monitor(struct ath_hw *ah, | ||
536 | const struct ath9k_node_stats *stats, | ||
537 | struct ath9k_channel *chan) | ||
538 | { | ||
539 | struct ar5416AniState *aniState; | ||
540 | int32_t listenTime; | ||
541 | |||
542 | if (!DO_ANI(ah)) | ||
543 | return; | ||
544 | |||
545 | aniState = ah->curani; | ||
546 | ah->stats.ast_nodestats = *stats; | ||
547 | |||
548 | listenTime = ath9k_hw_ani_get_listen_time(ah); | ||
549 | if (listenTime < 0) { | ||
550 | ah->stats.ast_ani_lneg++; | ||
551 | ath9k_ani_restart(ah); | ||
552 | return; | ||
553 | } | ||
554 | |||
555 | aniState->listenTime += listenTime; | ||
556 | |||
557 | if (ah->has_hw_phycounters) { | ||
558 | u32 phyCnt1, phyCnt2; | ||
559 | u32 ofdmPhyErrCnt, cckPhyErrCnt; | ||
560 | |||
561 | ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); | ||
562 | |||
563 | phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); | ||
564 | phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); | ||
565 | |||
566 | if (phyCnt1 < aniState->ofdmPhyErrBase || | ||
567 | phyCnt2 < aniState->cckPhyErrBase) { | ||
568 | if (phyCnt1 < aniState->ofdmPhyErrBase) { | ||
569 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
570 | "phyCnt1 0x%x, resetting " | ||
571 | "counter value to 0x%x\n", | ||
572 | phyCnt1, aniState->ofdmPhyErrBase); | ||
573 | REG_WRITE(ah, AR_PHY_ERR_1, | ||
574 | aniState->ofdmPhyErrBase); | ||
575 | REG_WRITE(ah, AR_PHY_ERR_MASK_1, | ||
576 | AR_PHY_ERR_OFDM_TIMING); | ||
577 | } | ||
578 | if (phyCnt2 < aniState->cckPhyErrBase) { | ||
579 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
580 | "phyCnt2 0x%x, resetting " | ||
581 | "counter value to 0x%x\n", | ||
582 | phyCnt2, aniState->cckPhyErrBase); | ||
583 | REG_WRITE(ah, AR_PHY_ERR_2, | ||
584 | aniState->cckPhyErrBase); | ||
585 | REG_WRITE(ah, AR_PHY_ERR_MASK_2, | ||
586 | AR_PHY_ERR_CCK_TIMING); | ||
587 | } | ||
588 | return; | ||
589 | } | ||
590 | |||
591 | ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; | ||
592 | ah->stats.ast_ani_ofdmerrs += | ||
593 | ofdmPhyErrCnt - aniState->ofdmPhyErrCount; | ||
594 | aniState->ofdmPhyErrCount = ofdmPhyErrCnt; | ||
595 | |||
596 | cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; | ||
597 | ah->stats.ast_ani_cckerrs += | ||
598 | cckPhyErrCnt - aniState->cckPhyErrCount; | ||
599 | aniState->cckPhyErrCount = cckPhyErrCnt; | ||
600 | } | ||
601 | |||
602 | if (aniState->listenTime > 5 * ah->aniperiod) { | ||
603 | if (aniState->ofdmPhyErrCount <= aniState->listenTime * | ||
604 | aniState->ofdmTrigLow / 1000 && | ||
605 | aniState->cckPhyErrCount <= aniState->listenTime * | ||
606 | aniState->cckTrigLow / 1000) | ||
607 | ath9k_hw_ani_lower_immunity(ah); | ||
608 | ath9k_ani_restart(ah); | ||
609 | } else if (aniState->listenTime > ah->aniperiod) { | ||
610 | if (aniState->ofdmPhyErrCount > aniState->listenTime * | ||
611 | aniState->ofdmTrigHigh / 1000) { | ||
612 | ath9k_hw_ani_ofdm_err_trigger(ah); | ||
613 | ath9k_ani_restart(ah); | ||
614 | } else if (aniState->cckPhyErrCount > | ||
615 | aniState->listenTime * aniState->cckTrigHigh / | ||
616 | 1000) { | ||
617 | ath9k_hw_ani_cck_err_trigger(ah); | ||
618 | ath9k_ani_restart(ah); | ||
619 | } | ||
620 | } | ||
621 | } | ||
622 | |||
623 | bool ath9k_hw_phycounters(struct ath_hw *ah) | ||
624 | { | ||
625 | return ah->has_hw_phycounters ? true : false; | ||
626 | } | ||
627 | |||
628 | void ath9k_enable_mib_counters(struct ath_hw *ah) | ||
629 | { | ||
630 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n"); | ||
631 | |||
632 | ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); | ||
633 | |||
634 | REG_WRITE(ah, AR_FILT_OFDM, 0); | ||
635 | REG_WRITE(ah, AR_FILT_CCK, 0); | ||
636 | REG_WRITE(ah, AR_MIBC, | ||
637 | ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS) | ||
638 | & 0x0f); | ||
639 | REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); | ||
640 | REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); | ||
641 | } | ||
642 | |||
643 | /* Freeze the MIB counters, get the stats and then clear them */ | ||
644 | void ath9k_hw_disable_mib_counters(struct ath_hw *ah) | ||
645 | { | ||
646 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disable MIB counters\n"); | ||
647 | REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC); | ||
648 | ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); | ||
649 | REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC); | ||
650 | REG_WRITE(ah, AR_FILT_OFDM, 0); | ||
651 | REG_WRITE(ah, AR_FILT_CCK, 0); | ||
652 | } | ||
653 | |||
654 | u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, | ||
655 | u32 *rxc_pcnt, | ||
656 | u32 *rxf_pcnt, | ||
657 | u32 *txf_pcnt) | ||
658 | { | ||
659 | static u32 cycles, rx_clear, rx_frame, tx_frame; | ||
660 | u32 good = 1; | ||
661 | |||
662 | u32 rc = REG_READ(ah, AR_RCCNT); | ||
663 | u32 rf = REG_READ(ah, AR_RFCNT); | ||
664 | u32 tf = REG_READ(ah, AR_TFCNT); | ||
665 | u32 cc = REG_READ(ah, AR_CCCNT); | ||
666 | |||
667 | if (cycles == 0 || cycles > cc) { | ||
668 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
669 | "cycle counter wrap. ExtBusy = 0\n"); | ||
670 | good = 0; | ||
671 | } else { | ||
672 | u32 cc_d = cc - cycles; | ||
673 | u32 rc_d = rc - rx_clear; | ||
674 | u32 rf_d = rf - rx_frame; | ||
675 | u32 tf_d = tf - tx_frame; | ||
676 | |||
677 | if (cc_d != 0) { | ||
678 | *rxc_pcnt = rc_d * 100 / cc_d; | ||
679 | *rxf_pcnt = rf_d * 100 / cc_d; | ||
680 | *txf_pcnt = tf_d * 100 / cc_d; | ||
681 | } else { | ||
682 | good = 0; | ||
683 | } | ||
684 | } | ||
685 | |||
686 | cycles = cc; | ||
687 | rx_frame = rf; | ||
688 | rx_clear = rc; | ||
689 | tx_frame = tf; | ||
690 | |||
691 | return good; | ||
692 | } | ||
693 | |||
694 | /* | ||
695 | * Process a MIB interrupt. We may potentially be invoked because | ||
696 | * any of the MIB counters overflow/trigger so don't assume we're | ||
697 | * here because a PHY error counter triggered. | ||
698 | */ | ||
699 | void ath9k_hw_procmibevent(struct ath_hw *ah, | ||
700 | const struct ath9k_node_stats *stats) | ||
701 | { | ||
702 | u32 phyCnt1, phyCnt2; | ||
703 | |||
704 | /* Reset these counters regardless */ | ||
705 | REG_WRITE(ah, AR_FILT_OFDM, 0); | ||
706 | REG_WRITE(ah, AR_FILT_CCK, 0); | ||
707 | if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING)) | ||
708 | REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); | ||
709 | |||
710 | /* Clear the mib counters and save them in the stats */ | ||
711 | ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); | ||
712 | ah->stats.ast_nodestats = *stats; | ||
713 | |||
714 | if (!DO_ANI(ah)) | ||
715 | return; | ||
716 | |||
717 | /* NB: these are not reset-on-read */ | ||
718 | phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); | ||
719 | phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); | ||
720 | if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || | ||
721 | ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) { | ||
722 | struct ar5416AniState *aniState = ah->curani; | ||
723 | u32 ofdmPhyErrCnt, cckPhyErrCnt; | ||
724 | |||
725 | /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */ | ||
726 | ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; | ||
727 | ah->stats.ast_ani_ofdmerrs += | ||
728 | ofdmPhyErrCnt - aniState->ofdmPhyErrCount; | ||
729 | aniState->ofdmPhyErrCount = ofdmPhyErrCnt; | ||
730 | |||
731 | cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; | ||
732 | ah->stats.ast_ani_cckerrs += | ||
733 | cckPhyErrCnt - aniState->cckPhyErrCount; | ||
734 | aniState->cckPhyErrCount = cckPhyErrCnt; | ||
735 | |||
736 | /* | ||
737 | * NB: figure out which counter triggered. If both | ||
738 | * trigger we'll only deal with one as the processing | ||
739 | * clobbers the error counter so the trigger threshold | ||
740 | * check will never be true. | ||
741 | */ | ||
742 | if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh) | ||
743 | ath9k_hw_ani_ofdm_err_trigger(ah); | ||
744 | if (aniState->cckPhyErrCount > aniState->cckTrigHigh) | ||
745 | ath9k_hw_ani_cck_err_trigger(ah); | ||
746 | /* NB: always restart to insure the h/w counters are reset */ | ||
747 | ath9k_ani_restart(ah); | ||
748 | } | ||
749 | } | ||
750 | |||
751 | void ath9k_hw_ani_setup(struct ath_hw *ah) | ||
752 | { | ||
753 | int i; | ||
754 | |||
755 | const int totalSizeDesired[] = { -55, -55, -55, -55, -62 }; | ||
756 | const int coarseHigh[] = { -14, -14, -14, -14, -12 }; | ||
757 | const int coarseLow[] = { -64, -64, -64, -64, -70 }; | ||
758 | const int firpwr[] = { -78, -78, -78, -78, -80 }; | ||
759 | |||
760 | for (i = 0; i < 5; i++) { | ||
761 | ah->totalSizeDesired[i] = totalSizeDesired[i]; | ||
762 | ah->coarse_high[i] = coarseHigh[i]; | ||
763 | ah->coarse_low[i] = coarseLow[i]; | ||
764 | ah->firpwr[i] = firpwr[i]; | ||
765 | } | ||
766 | } | ||
767 | |||
768 | void ath9k_hw_ani_attach(struct ath_hw *ah) | ||
769 | { | ||
770 | int i; | ||
771 | |||
772 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Attach ANI\n"); | ||
773 | |||
774 | ah->has_hw_phycounters = 1; | ||
775 | |||
776 | memset(ah->ani, 0, sizeof(ah->ani)); | ||
777 | for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { | ||
778 | ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH; | ||
779 | ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW; | ||
780 | ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH; | ||
781 | ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW; | ||
782 | ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; | ||
783 | ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; | ||
784 | ah->ani[i].ofdmWeakSigDetectOff = | ||
785 | !ATH9K_ANI_USE_OFDM_WEAK_SIG; | ||
786 | ah->ani[i].cckWeakSigThreshold = | ||
787 | ATH9K_ANI_CCK_WEAK_SIG_THR; | ||
788 | ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; | ||
789 | ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL; | ||
790 | if (ah->has_hw_phycounters) { | ||
791 | ah->ani[i].ofdmPhyErrBase = | ||
792 | AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH; | ||
793 | ah->ani[i].cckPhyErrBase = | ||
794 | AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH; | ||
795 | } | ||
796 | } | ||
797 | if (ah->has_hw_phycounters) { | ||
798 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
799 | "Setting OfdmErrBase = 0x%08x\n", | ||
800 | ah->ani[0].ofdmPhyErrBase); | ||
801 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n", | ||
802 | ah->ani[0].cckPhyErrBase); | ||
803 | |||
804 | REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase); | ||
805 | REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase); | ||
806 | ath9k_enable_mib_counters(ah); | ||
807 | } | ||
808 | ah->aniperiod = ATH9K_ANI_PERIOD; | ||
809 | if (ah->config.enable_ani) | ||
810 | ah->proc_phyerr |= HAL_PROCESS_ANI; | ||
811 | } | ||
812 | |||
813 | void ath9k_hw_ani_detach(struct ath_hw *ah) | ||
814 | { | ||
815 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detach ANI\n"); | ||
816 | |||
817 | if (ah->has_hw_phycounters) { | ||
818 | ath9k_hw_disable_mib_counters(ah); | ||
819 | REG_WRITE(ah, AR_PHY_ERR_1, 0); | ||
820 | REG_WRITE(ah, AR_PHY_ERR_2, 0); | ||
821 | } | ||
822 | } | ||
diff --git a/drivers/net/wireless/ath9k/ani.h b/drivers/net/wireless/ath9k/ani.h deleted file mode 100644 index 08b4e7ed5ff0..000000000000 --- a/drivers/net/wireless/ath9k/ani.h +++ /dev/null | |||
@@ -1,138 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 ANI_H | ||
18 | #define ANI_H | ||
19 | |||
20 | #define HAL_PROCESS_ANI 0x00000001 | ||
21 | #define ATH9K_RSSI_EP_MULTIPLIER (1<<7) | ||
22 | |||
23 | #define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI)) | ||
24 | |||
25 | #define HAL_EP_RND(x, mul) \ | ||
26 | ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) | ||
27 | #define BEACON_RSSI(ahp) \ | ||
28 | HAL_EP_RND(ahp->stats.ast_nodestats.ns_avgbrssi, \ | ||
29 | ATH9K_RSSI_EP_MULTIPLIER) | ||
30 | |||
31 | #define ATH9K_ANI_OFDM_TRIG_HIGH 500 | ||
32 | #define ATH9K_ANI_OFDM_TRIG_LOW 200 | ||
33 | #define ATH9K_ANI_CCK_TRIG_HIGH 200 | ||
34 | #define ATH9K_ANI_CCK_TRIG_LOW 100 | ||
35 | #define ATH9K_ANI_NOISE_IMMUNE_LVL 4 | ||
36 | #define ATH9K_ANI_USE_OFDM_WEAK_SIG true | ||
37 | #define ATH9K_ANI_CCK_WEAK_SIG_THR false | ||
38 | #define ATH9K_ANI_SPUR_IMMUNE_LVL 7 | ||
39 | #define ATH9K_ANI_FIRSTEP_LVL 0 | ||
40 | #define ATH9K_ANI_RSSI_THR_HIGH 40 | ||
41 | #define ATH9K_ANI_RSSI_THR_LOW 7 | ||
42 | #define ATH9K_ANI_PERIOD 100 | ||
43 | |||
44 | #define HAL_NOISE_IMMUNE_MAX 4 | ||
45 | #define HAL_SPUR_IMMUNE_MAX 7 | ||
46 | #define HAL_FIRST_STEP_MAX 2 | ||
47 | |||
48 | enum ath9k_ani_cmd { | ||
49 | ATH9K_ANI_PRESENT = 0x1, | ||
50 | ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2, | ||
51 | ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4, | ||
52 | ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8, | ||
53 | ATH9K_ANI_FIRSTEP_LEVEL = 0x10, | ||
54 | ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20, | ||
55 | ATH9K_ANI_MODE = 0x40, | ||
56 | ATH9K_ANI_PHYERR_RESET = 0x80, | ||
57 | ATH9K_ANI_ALL = 0xff | ||
58 | }; | ||
59 | |||
60 | struct ath9k_mib_stats { | ||
61 | u32 ackrcv_bad; | ||
62 | u32 rts_bad; | ||
63 | u32 rts_good; | ||
64 | u32 fcs_bad; | ||
65 | u32 beacons; | ||
66 | }; | ||
67 | |||
68 | struct ath9k_node_stats { | ||
69 | u32 ns_avgbrssi; | ||
70 | u32 ns_avgrssi; | ||
71 | u32 ns_avgtxrssi; | ||
72 | u32 ns_avgtxrate; | ||
73 | }; | ||
74 | |||
75 | struct ar5416AniState { | ||
76 | struct ath9k_channel *c; | ||
77 | u8 noiseImmunityLevel; | ||
78 | u8 spurImmunityLevel; | ||
79 | u8 firstepLevel; | ||
80 | u8 ofdmWeakSigDetectOff; | ||
81 | u8 cckWeakSigThreshold; | ||
82 | u32 listenTime; | ||
83 | u32 ofdmTrigHigh; | ||
84 | u32 ofdmTrigLow; | ||
85 | int32_t cckTrigHigh; | ||
86 | int32_t cckTrigLow; | ||
87 | int32_t rssiThrLow; | ||
88 | int32_t rssiThrHigh; | ||
89 | u32 noiseFloor; | ||
90 | u32 txFrameCount; | ||
91 | u32 rxFrameCount; | ||
92 | u32 cycleCount; | ||
93 | u32 ofdmPhyErrCount; | ||
94 | u32 cckPhyErrCount; | ||
95 | u32 ofdmPhyErrBase; | ||
96 | u32 cckPhyErrBase; | ||
97 | int16_t pktRssi[2]; | ||
98 | int16_t ofdmErrRssi[2]; | ||
99 | int16_t cckErrRssi[2]; | ||
100 | }; | ||
101 | |||
102 | struct ar5416Stats { | ||
103 | u32 ast_ani_niup; | ||
104 | u32 ast_ani_nidown; | ||
105 | u32 ast_ani_spurup; | ||
106 | u32 ast_ani_spurdown; | ||
107 | u32 ast_ani_ofdmon; | ||
108 | u32 ast_ani_ofdmoff; | ||
109 | u32 ast_ani_cckhigh; | ||
110 | u32 ast_ani_ccklow; | ||
111 | u32 ast_ani_stepup; | ||
112 | u32 ast_ani_stepdown; | ||
113 | u32 ast_ani_ofdmerrs; | ||
114 | u32 ast_ani_cckerrs; | ||
115 | u32 ast_ani_reset; | ||
116 | u32 ast_ani_lzero; | ||
117 | u32 ast_ani_lneg; | ||
118 | struct ath9k_mib_stats ast_mibstats; | ||
119 | struct ath9k_node_stats ast_nodestats; | ||
120 | }; | ||
121 | #define ah_mibStats stats.ast_mibstats | ||
122 | |||
123 | void ath9k_ani_reset(struct ath_hw *ah); | ||
124 | void ath9k_hw_ani_monitor(struct ath_hw *ah, | ||
125 | const struct ath9k_node_stats *stats, | ||
126 | struct ath9k_channel *chan); | ||
127 | bool ath9k_hw_phycounters(struct ath_hw *ah); | ||
128 | void ath9k_enable_mib_counters(struct ath_hw *ah); | ||
129 | void ath9k_hw_disable_mib_counters(struct ath_hw *ah); | ||
130 | u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt, | ||
131 | u32 *rxf_pcnt, u32 *txf_pcnt); | ||
132 | void ath9k_hw_procmibevent(struct ath_hw *ah, | ||
133 | const struct ath9k_node_stats *stats); | ||
134 | void ath9k_hw_ani_setup(struct ath_hw *ah); | ||
135 | void ath9k_hw_ani_attach(struct ath_hw *ah); | ||
136 | void ath9k_hw_ani_detach(struct ath_hw *ah); | ||
137 | |||
138 | #endif /* ANI_H */ | ||
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h deleted file mode 100644 index c92d46fa9d51..000000000000 --- a/drivers/net/wireless/ath9k/ath9k.h +++ /dev/null | |||
@@ -1,730 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 ATH9K_H | ||
18 | #define ATH9K_H | ||
19 | |||
20 | #include <linux/etherdevice.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <net/mac80211.h> | ||
23 | #include <linux/leds.h> | ||
24 | #include <linux/rfkill.h> | ||
25 | |||
26 | #include "hw.h" | ||
27 | #include "rc.h" | ||
28 | #include "debug.h" | ||
29 | |||
30 | struct ath_node; | ||
31 | |||
32 | /* Macro to expand scalars to 64-bit objects */ | ||
33 | |||
34 | #define ito64(x) (sizeof(x) == 8) ? \ | ||
35 | (((unsigned long long int)(x)) & (0xff)) : \ | ||
36 | (sizeof(x) == 16) ? \ | ||
37 | (((unsigned long long int)(x)) & 0xffff) : \ | ||
38 | ((sizeof(x) == 32) ? \ | ||
39 | (((unsigned long long int)(x)) & 0xffffffff) : \ | ||
40 | (unsigned long long int)(x)) | ||
41 | |||
42 | /* increment with wrap-around */ | ||
43 | #define INCR(_l, _sz) do { \ | ||
44 | (_l)++; \ | ||
45 | (_l) &= ((_sz) - 1); \ | ||
46 | } while (0) | ||
47 | |||
48 | /* decrement with wrap-around */ | ||
49 | #define DECR(_l, _sz) do { \ | ||
50 | (_l)--; \ | ||
51 | (_l) &= ((_sz) - 1); \ | ||
52 | } while (0) | ||
53 | |||
54 | #define A_MAX(a, b) ((a) > (b) ? (a) : (b)) | ||
55 | |||
56 | #define ASSERT(exp) BUG_ON(!(exp)) | ||
57 | |||
58 | #define TSF_TO_TU(_h,_l) \ | ||
59 | ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) | ||
60 | |||
61 | #define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i)) | ||
62 | |||
63 | static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
64 | |||
65 | struct ath_config { | ||
66 | u32 ath_aggr_prot; | ||
67 | u16 txpowlimit; | ||
68 | u8 cabqReadytime; | ||
69 | }; | ||
70 | |||
71 | /*************************/ | ||
72 | /* Descriptor Management */ | ||
73 | /*************************/ | ||
74 | |||
75 | #define ATH_TXBUF_RESET(_bf) do { \ | ||
76 | (_bf)->bf_stale = false; \ | ||
77 | (_bf)->bf_lastbf = NULL; \ | ||
78 | (_bf)->bf_next = NULL; \ | ||
79 | memset(&((_bf)->bf_state), 0, \ | ||
80 | sizeof(struct ath_buf_state)); \ | ||
81 | } while (0) | ||
82 | |||
83 | #define ATH_RXBUF_RESET(_bf) do { \ | ||
84 | (_bf)->bf_stale = false; \ | ||
85 | } while (0) | ||
86 | |||
87 | /** | ||
88 | * enum buffer_type - Buffer type flags | ||
89 | * | ||
90 | * @BUF_HT: Send this buffer using HT capabilities | ||
91 | * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX) | ||
92 | * @BUF_AGGR: Indicates whether the buffer can be aggregated | ||
93 | * (used in aggregation scheduling) | ||
94 | * @BUF_RETRY: Indicates whether the buffer is retried | ||
95 | * @BUF_XRETRY: To denote excessive retries of the buffer | ||
96 | */ | ||
97 | enum buffer_type { | ||
98 | BUF_HT = BIT(1), | ||
99 | BUF_AMPDU = BIT(2), | ||
100 | BUF_AGGR = BIT(3), | ||
101 | BUF_RETRY = BIT(4), | ||
102 | BUF_XRETRY = BIT(5), | ||
103 | }; | ||
104 | |||
105 | struct ath_buf_state { | ||
106 | int bfs_nframes; | ||
107 | u16 bfs_al; | ||
108 | u16 bfs_frmlen; | ||
109 | int bfs_seqno; | ||
110 | int bfs_tidno; | ||
111 | int bfs_retries; | ||
112 | u8 bf_type; | ||
113 | u32 bfs_keyix; | ||
114 | enum ath9k_key_type bfs_keytype; | ||
115 | }; | ||
116 | |||
117 | #define bf_nframes bf_state.bfs_nframes | ||
118 | #define bf_al bf_state.bfs_al | ||
119 | #define bf_frmlen bf_state.bfs_frmlen | ||
120 | #define bf_retries bf_state.bfs_retries | ||
121 | #define bf_seqno bf_state.bfs_seqno | ||
122 | #define bf_tidno bf_state.bfs_tidno | ||
123 | #define bf_keyix bf_state.bfs_keyix | ||
124 | #define bf_keytype bf_state.bfs_keytype | ||
125 | #define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT) | ||
126 | #define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) | ||
127 | #define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR) | ||
128 | #define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY) | ||
129 | #define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY) | ||
130 | |||
131 | struct ath_buf { | ||
132 | struct list_head list; | ||
133 | struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or | ||
134 | an aggregate) */ | ||
135 | struct ath_buf *bf_next; /* next subframe in the aggregate */ | ||
136 | struct sk_buff *bf_mpdu; /* enclosing frame structure */ | ||
137 | struct ath_desc *bf_desc; /* virtual addr of desc */ | ||
138 | dma_addr_t bf_daddr; /* physical addr of desc */ | ||
139 | dma_addr_t bf_buf_addr; /* physical addr of data buffer */ | ||
140 | bool bf_stale; | ||
141 | u16 bf_flags; | ||
142 | struct ath_buf_state bf_state; | ||
143 | dma_addr_t bf_dmacontext; | ||
144 | }; | ||
145 | |||
146 | struct ath_descdma { | ||
147 | struct ath_desc *dd_desc; | ||
148 | dma_addr_t dd_desc_paddr; | ||
149 | u32 dd_desc_len; | ||
150 | struct ath_buf *dd_bufptr; | ||
151 | }; | ||
152 | |||
153 | int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | ||
154 | struct list_head *head, const char *name, | ||
155 | int nbuf, int ndesc); | ||
156 | void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, | ||
157 | struct list_head *head); | ||
158 | |||
159 | /***********/ | ||
160 | /* RX / TX */ | ||
161 | /***********/ | ||
162 | |||
163 | #define ATH_MAX_ANTENNA 3 | ||
164 | #define ATH_RXBUF 512 | ||
165 | #define WME_NUM_TID 16 | ||
166 | #define ATH_TXBUF 512 | ||
167 | #define ATH_TXMAXTRY 13 | ||
168 | #define ATH_11N_TXMAXTRY 10 | ||
169 | #define ATH_MGT_TXMAXTRY 4 | ||
170 | #define WME_BA_BMP_SIZE 64 | ||
171 | #define WME_MAX_BA WME_BA_BMP_SIZE | ||
172 | #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) | ||
173 | |||
174 | #define TID_TO_WME_AC(_tid) \ | ||
175 | ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ | ||
176 | (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \ | ||
177 | (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ | ||
178 | WME_AC_VO) | ||
179 | |||
180 | #define WME_AC_BE 0 | ||
181 | #define WME_AC_BK 1 | ||
182 | #define WME_AC_VI 2 | ||
183 | #define WME_AC_VO 3 | ||
184 | #define WME_NUM_AC 4 | ||
185 | |||
186 | #define ADDBA_EXCHANGE_ATTEMPTS 10 | ||
187 | #define ATH_AGGR_DELIM_SZ 4 | ||
188 | #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ | ||
189 | /* number of delimiters for encryption padding */ | ||
190 | #define ATH_AGGR_ENCRYPTDELIM 10 | ||
191 | /* minimum h/w qdepth to be sustained to maximize aggregation */ | ||
192 | #define ATH_AGGR_MIN_QDEPTH 2 | ||
193 | #define ATH_AMPDU_SUBFRAME_DEFAULT 32 | ||
194 | #define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1) | ||
195 | #define ATH_AMPDU_LIMIT_DEFAULT ATH_AMPDU_LIMIT_MAX | ||
196 | |||
197 | #define IEEE80211_SEQ_SEQ_SHIFT 4 | ||
198 | #define IEEE80211_SEQ_MAX 4096 | ||
199 | #define IEEE80211_MIN_AMPDU_BUF 0x8 | ||
200 | #define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13 | ||
201 | #define IEEE80211_WEP_IVLEN 3 | ||
202 | #define IEEE80211_WEP_KIDLEN 1 | ||
203 | #define IEEE80211_WEP_CRCLEN 4 | ||
204 | #define IEEE80211_MAX_MPDU_LEN (3840 + FCS_LEN + \ | ||
205 | (IEEE80211_WEP_IVLEN + \ | ||
206 | IEEE80211_WEP_KIDLEN + \ | ||
207 | IEEE80211_WEP_CRCLEN)) | ||
208 | |||
209 | /* return whether a bit at index _n in bitmap _bm is set | ||
210 | * _sz is the size of the bitmap */ | ||
211 | #define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \ | ||
212 | ((_bm)[(_n) >> 5] & (1 << ((_n) & 31)))) | ||
213 | |||
214 | /* return block-ack bitmap index given sequence and starting sequence */ | ||
215 | #define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1)) | ||
216 | |||
217 | /* returns delimiter padding required given the packet length */ | ||
218 | #define ATH_AGGR_GET_NDELIM(_len) \ | ||
219 | (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \ | ||
220 | (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2) | ||
221 | |||
222 | #define BAW_WITHIN(_start, _bawsz, _seqno) \ | ||
223 | ((((_seqno) - (_start)) & 4095) < (_bawsz)) | ||
224 | |||
225 | #define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum) | ||
226 | #define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low) | ||
227 | #define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA) | ||
228 | #define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) | ||
229 | |||
230 | enum ATH_AGGR_STATUS { | ||
231 | ATH_AGGR_DONE, | ||
232 | ATH_AGGR_BAW_CLOSED, | ||
233 | ATH_AGGR_LIMITED, | ||
234 | }; | ||
235 | |||
236 | struct ath_txq { | ||
237 | u32 axq_qnum; | ||
238 | u32 *axq_link; | ||
239 | struct list_head axq_q; | ||
240 | spinlock_t axq_lock; | ||
241 | u32 axq_depth; | ||
242 | u8 axq_aggr_depth; | ||
243 | u32 axq_totalqueued; | ||
244 | bool stopped; | ||
245 | struct ath_buf *axq_linkbuf; | ||
246 | |||
247 | /* first desc of the last descriptor that contains CTS */ | ||
248 | struct ath_desc *axq_lastdsWithCTS; | ||
249 | |||
250 | /* final desc of the gating desc that determines whether | ||
251 | lastdsWithCTS has been DMA'ed or not */ | ||
252 | struct ath_desc *axq_gatingds; | ||
253 | |||
254 | struct list_head axq_acq; | ||
255 | }; | ||
256 | |||
257 | #define AGGR_CLEANUP BIT(1) | ||
258 | #define AGGR_ADDBA_COMPLETE BIT(2) | ||
259 | #define AGGR_ADDBA_PROGRESS BIT(3) | ||
260 | |||
261 | struct ath_atx_tid { | ||
262 | struct list_head list; | ||
263 | struct list_head buf_q; | ||
264 | struct ath_node *an; | ||
265 | struct ath_atx_ac *ac; | ||
266 | struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; | ||
267 | u16 seq_start; | ||
268 | u16 seq_next; | ||
269 | u16 baw_size; | ||
270 | int tidno; | ||
271 | int baw_head; /* first un-acked tx buffer */ | ||
272 | int baw_tail; /* next unused tx buffer slot */ | ||
273 | int sched; | ||
274 | int paused; | ||
275 | u8 state; | ||
276 | int addba_exchangeattempts; | ||
277 | }; | ||
278 | |||
279 | struct ath_atx_ac { | ||
280 | int sched; | ||
281 | int qnum; | ||
282 | struct list_head list; | ||
283 | struct list_head tid_q; | ||
284 | }; | ||
285 | |||
286 | struct ath_tx_control { | ||
287 | struct ath_txq *txq; | ||
288 | int if_id; | ||
289 | enum ath9k_internal_frame_type frame_type; | ||
290 | }; | ||
291 | |||
292 | #define ATH_TX_ERROR 0x01 | ||
293 | #define ATH_TX_XRETRY 0x02 | ||
294 | #define ATH_TX_BAR 0x04 | ||
295 | |||
296 | struct ath_node { | ||
297 | struct ath_softc *an_sc; | ||
298 | struct ath_atx_tid tid[WME_NUM_TID]; | ||
299 | struct ath_atx_ac ac[WME_NUM_AC]; | ||
300 | u16 maxampdu; | ||
301 | u8 mpdudensity; | ||
302 | }; | ||
303 | |||
304 | struct ath_tx { | ||
305 | u16 seq_no; | ||
306 | u32 txqsetup; | ||
307 | int hwq_map[ATH9K_WME_AC_VO+1]; | ||
308 | spinlock_t txbuflock; | ||
309 | struct list_head txbuf; | ||
310 | struct ath_txq txq[ATH9K_NUM_TX_QUEUES]; | ||
311 | struct ath_descdma txdma; | ||
312 | }; | ||
313 | |||
314 | struct ath_rx { | ||
315 | u8 defant; | ||
316 | u8 rxotherant; | ||
317 | u32 *rxlink; | ||
318 | int bufsize; | ||
319 | unsigned int rxfilter; | ||
320 | spinlock_t rxflushlock; | ||
321 | spinlock_t rxbuflock; | ||
322 | struct list_head rxbuf; | ||
323 | struct ath_descdma rxdma; | ||
324 | }; | ||
325 | |||
326 | int ath_startrecv(struct ath_softc *sc); | ||
327 | bool ath_stoprecv(struct ath_softc *sc); | ||
328 | void ath_flushrecv(struct ath_softc *sc); | ||
329 | u32 ath_calcrxfilter(struct ath_softc *sc); | ||
330 | int ath_rx_init(struct ath_softc *sc, int nbufs); | ||
331 | void ath_rx_cleanup(struct ath_softc *sc); | ||
332 | int ath_rx_tasklet(struct ath_softc *sc, int flush); | ||
333 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); | ||
334 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); | ||
335 | int ath_tx_setup(struct ath_softc *sc, int haltype); | ||
336 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); | ||
337 | void ath_draintxq(struct ath_softc *sc, | ||
338 | struct ath_txq *txq, bool retry_tx); | ||
339 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); | ||
340 | void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); | ||
341 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); | ||
342 | int ath_tx_init(struct ath_softc *sc, int nbufs); | ||
343 | void ath_tx_cleanup(struct ath_softc *sc); | ||
344 | struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb); | ||
345 | int ath_txq_update(struct ath_softc *sc, int qnum, | ||
346 | struct ath9k_tx_queue_info *q); | ||
347 | int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
348 | struct ath_tx_control *txctl); | ||
349 | void ath_tx_tasklet(struct ath_softc *sc); | ||
350 | void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
351 | bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno); | ||
352 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | ||
353 | u16 tid, u16 *ssn); | ||
354 | int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | ||
355 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | ||
356 | |||
357 | /********/ | ||
358 | /* VIFs */ | ||
359 | /********/ | ||
360 | |||
361 | struct ath_vif { | ||
362 | int av_bslot; | ||
363 | __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ | ||
364 | enum nl80211_iftype av_opmode; | ||
365 | struct ath_buf *av_bcbuf; | ||
366 | struct ath_tx_control av_btxctl; | ||
367 | u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */ | ||
368 | }; | ||
369 | |||
370 | /*******************/ | ||
371 | /* Beacon Handling */ | ||
372 | /*******************/ | ||
373 | |||
374 | /* | ||
375 | * Regardless of the number of beacons we stagger, (i.e. regardless of the | ||
376 | * number of BSSIDs) if a given beacon does not go out even after waiting this | ||
377 | * number of beacon intervals, the game's up. | ||
378 | */ | ||
379 | #define BSTUCK_THRESH (9 * ATH_BCBUF) | ||
380 | #define ATH_BCBUF 4 | ||
381 | #define ATH_DEFAULT_BINTVAL 100 /* TU */ | ||
382 | #define ATH_DEFAULT_BMISS_LIMIT 10 | ||
383 | #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) | ||
384 | |||
385 | struct ath_beacon_config { | ||
386 | u16 beacon_interval; | ||
387 | u16 listen_interval; | ||
388 | u16 dtim_period; | ||
389 | u16 bmiss_timeout; | ||
390 | u8 dtim_count; | ||
391 | }; | ||
392 | |||
393 | struct ath_beacon { | ||
394 | enum { | ||
395 | OK, /* no change needed */ | ||
396 | UPDATE, /* update pending */ | ||
397 | COMMIT /* beacon sent, commit change */ | ||
398 | } updateslot; /* slot time update fsm */ | ||
399 | |||
400 | u32 beaconq; | ||
401 | u32 bmisscnt; | ||
402 | u32 ast_be_xmit; | ||
403 | u64 bc_tstamp; | ||
404 | struct ieee80211_vif *bslot[ATH_BCBUF]; | ||
405 | struct ath_wiphy *bslot_aphy[ATH_BCBUF]; | ||
406 | int slottime; | ||
407 | int slotupdate; | ||
408 | struct ath9k_tx_queue_info beacon_qi; | ||
409 | struct ath_descdma bdma; | ||
410 | struct ath_txq *cabq; | ||
411 | struct list_head bbuf; | ||
412 | }; | ||
413 | |||
414 | void ath_beacon_tasklet(unsigned long data); | ||
415 | void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif); | ||
416 | int ath_beaconq_setup(struct ath_hw *ah); | ||
417 | int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif); | ||
418 | void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); | ||
419 | |||
420 | /*******/ | ||
421 | /* ANI */ | ||
422 | /*******/ | ||
423 | |||
424 | #define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */ | ||
425 | #define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */ | ||
426 | #define ATH_ANI_POLLINTERVAL 100 /* 100 ms */ | ||
427 | #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ | ||
428 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ | ||
429 | |||
430 | struct ath_ani { | ||
431 | bool caldone; | ||
432 | int16_t noise_floor; | ||
433 | unsigned int longcal_timer; | ||
434 | unsigned int shortcal_timer; | ||
435 | unsigned int resetcal_timer; | ||
436 | unsigned int checkani_timer; | ||
437 | struct timer_list timer; | ||
438 | }; | ||
439 | |||
440 | /********************/ | ||
441 | /* LED Control */ | ||
442 | /********************/ | ||
443 | |||
444 | #define ATH_LED_PIN 1 | ||
445 | #define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */ | ||
446 | #define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */ | ||
447 | |||
448 | enum ath_led_type { | ||
449 | ATH_LED_RADIO, | ||
450 | ATH_LED_ASSOC, | ||
451 | ATH_LED_TX, | ||
452 | ATH_LED_RX | ||
453 | }; | ||
454 | |||
455 | struct ath_led { | ||
456 | struct ath_softc *sc; | ||
457 | struct led_classdev led_cdev; | ||
458 | enum ath_led_type led_type; | ||
459 | char name[32]; | ||
460 | bool registered; | ||
461 | }; | ||
462 | |||
463 | /* Rfkill */ | ||
464 | #define ATH_RFKILL_POLL_INTERVAL 2000 /* msecs */ | ||
465 | |||
466 | struct ath_rfkill { | ||
467 | struct rfkill *rfkill; | ||
468 | struct delayed_work rfkill_poll; | ||
469 | char rfkill_name[32]; | ||
470 | }; | ||
471 | |||
472 | /********************/ | ||
473 | /* Main driver core */ | ||
474 | /********************/ | ||
475 | |||
476 | /* | ||
477 | * Default cache line size, in bytes. | ||
478 | * Used when PCI device not fully initialized by bootrom/BIOS | ||
479 | */ | ||
480 | #define DEFAULT_CACHELINE 32 | ||
481 | #define ATH_DEFAULT_NOISE_FLOOR -95 | ||
482 | #define ATH_REGCLASSIDS_MAX 10 | ||
483 | #define ATH_CABQ_READY_TIME 80 /* % of beacon interval */ | ||
484 | #define ATH_MAX_SW_RETRIES 10 | ||
485 | #define ATH_CHAN_MAX 255 | ||
486 | #define IEEE80211_WEP_NKID 4 /* number of key ids */ | ||
487 | |||
488 | /* | ||
489 | * The key cache is used for h/w cipher state and also for | ||
490 | * tracking station state such as the current tx antenna. | ||
491 | * We also setup a mapping table between key cache slot indices | ||
492 | * and station state to short-circuit node lookups on rx. | ||
493 | * Different parts have different size key caches. We handle | ||
494 | * up to ATH_KEYMAX entries (could dynamically allocate state). | ||
495 | */ | ||
496 | #define ATH_KEYMAX 128 /* max key cache size we handle */ | ||
497 | |||
498 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ | ||
499 | #define ATH_RSSI_DUMMY_MARKER 0x127 | ||
500 | #define ATH_RATE_DUMMY_MARKER 0 | ||
501 | |||
502 | #define SC_OP_INVALID BIT(0) | ||
503 | #define SC_OP_BEACONS BIT(1) | ||
504 | #define SC_OP_RXAGGR BIT(2) | ||
505 | #define SC_OP_TXAGGR BIT(3) | ||
506 | #define SC_OP_FULL_RESET BIT(4) | ||
507 | #define SC_OP_PREAMBLE_SHORT BIT(5) | ||
508 | #define SC_OP_PROTECT_ENABLE BIT(6) | ||
509 | #define SC_OP_RXFLUSH BIT(7) | ||
510 | #define SC_OP_LED_ASSOCIATED BIT(8) | ||
511 | #define SC_OP_RFKILL_REGISTERED BIT(9) | ||
512 | #define SC_OP_RFKILL_SW_BLOCKED BIT(10) | ||
513 | #define SC_OP_RFKILL_HW_BLOCKED BIT(11) | ||
514 | #define SC_OP_WAIT_FOR_BEACON BIT(12) | ||
515 | #define SC_OP_LED_ON BIT(13) | ||
516 | #define SC_OP_SCANNING BIT(14) | ||
517 | #define SC_OP_TSF_RESET BIT(15) | ||
518 | |||
519 | struct ath_bus_ops { | ||
520 | void (*read_cachesize)(struct ath_softc *sc, int *csz); | ||
521 | void (*cleanup)(struct ath_softc *sc); | ||
522 | bool (*eeprom_read)(struct ath_hw *ah, u32 off, u16 *data); | ||
523 | }; | ||
524 | |||
525 | struct ath_wiphy; | ||
526 | |||
527 | struct ath_softc { | ||
528 | struct ieee80211_hw *hw; | ||
529 | struct device *dev; | ||
530 | |||
531 | spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */ | ||
532 | struct ath_wiphy *pri_wiphy; | ||
533 | struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may | ||
534 | * have NULL entries */ | ||
535 | int num_sec_wiphy; /* number of sec_wiphy pointers in the array */ | ||
536 | int chan_idx; | ||
537 | int chan_is_ht; | ||
538 | struct ath_wiphy *next_wiphy; | ||
539 | struct work_struct chan_work; | ||
540 | int wiphy_select_failures; | ||
541 | unsigned long wiphy_select_first_fail; | ||
542 | struct delayed_work wiphy_work; | ||
543 | unsigned long wiphy_scheduler_int; | ||
544 | int wiphy_scheduler_index; | ||
545 | |||
546 | struct tasklet_struct intr_tq; | ||
547 | struct tasklet_struct bcon_tasklet; | ||
548 | struct ath_hw *sc_ah; | ||
549 | void __iomem *mem; | ||
550 | int irq; | ||
551 | spinlock_t sc_resetlock; | ||
552 | spinlock_t sc_serial_rw; | ||
553 | struct mutex mutex; | ||
554 | |||
555 | u8 curbssid[ETH_ALEN]; | ||
556 | u8 bssidmask[ETH_ALEN]; | ||
557 | u32 intrstatus; | ||
558 | u32 sc_flags; /* SC_OP_* */ | ||
559 | u16 curtxpow; | ||
560 | u16 curaid; | ||
561 | u16 cachelsz; | ||
562 | u8 nbcnvifs; | ||
563 | u16 nvifs; | ||
564 | u8 tx_chainmask; | ||
565 | u8 rx_chainmask; | ||
566 | u32 keymax; | ||
567 | DECLARE_BITMAP(keymap, ATH_KEYMAX); | ||
568 | u8 splitmic; | ||
569 | atomic_t ps_usecount; | ||
570 | enum ath9k_int imask; | ||
571 | enum ath9k_ht_extprotspacing ht_extprotspacing; | ||
572 | enum ath9k_ht_macmode tx_chan_width; | ||
573 | |||
574 | struct ath_config config; | ||
575 | struct ath_rx rx; | ||
576 | struct ath_tx tx; | ||
577 | struct ath_beacon beacon; | ||
578 | struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; | ||
579 | struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX]; | ||
580 | struct ath_rate_table *cur_rate_table; | ||
581 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | ||
582 | |||
583 | struct ath_led radio_led; | ||
584 | struct ath_led assoc_led; | ||
585 | struct ath_led tx_led; | ||
586 | struct ath_led rx_led; | ||
587 | struct delayed_work ath_led_blink_work; | ||
588 | int led_on_duration; | ||
589 | int led_off_duration; | ||
590 | int led_on_cnt; | ||
591 | int led_off_cnt; | ||
592 | |||
593 | struct ath_rfkill rf_kill; | ||
594 | struct ath_ani ani; | ||
595 | struct ath9k_node_stats nodestats; | ||
596 | #ifdef CONFIG_ATH9K_DEBUG | ||
597 | struct ath9k_debug debug; | ||
598 | #endif | ||
599 | struct ath_bus_ops *bus_ops; | ||
600 | }; | ||
601 | |||
602 | struct ath_wiphy { | ||
603 | struct ath_softc *sc; /* shared for all virtual wiphys */ | ||
604 | struct ieee80211_hw *hw; | ||
605 | enum ath_wiphy_state { | ||
606 | ATH_WIPHY_INACTIVE, | ||
607 | ATH_WIPHY_ACTIVE, | ||
608 | ATH_WIPHY_PAUSING, | ||
609 | ATH_WIPHY_PAUSED, | ||
610 | ATH_WIPHY_SCAN, | ||
611 | } state; | ||
612 | int chan_idx; | ||
613 | int chan_is_ht; | ||
614 | }; | ||
615 | |||
616 | int ath_reset(struct ath_softc *sc, bool retry_tx); | ||
617 | int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); | ||
618 | int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); | ||
619 | int ath_cabq_update(struct ath_softc *); | ||
620 | |||
621 | static inline void ath_read_cachesize(struct ath_softc *sc, int *csz) | ||
622 | { | ||
623 | sc->bus_ops->read_cachesize(sc, csz); | ||
624 | } | ||
625 | |||
626 | static inline void ath_bus_cleanup(struct ath_softc *sc) | ||
627 | { | ||
628 | sc->bus_ops->cleanup(sc); | ||
629 | } | ||
630 | |||
631 | extern struct ieee80211_ops ath9k_ops; | ||
632 | |||
633 | irqreturn_t ath_isr(int irq, void *dev); | ||
634 | void ath_cleanup(struct ath_softc *sc); | ||
635 | int ath_attach(u16 devid, struct ath_softc *sc); | ||
636 | void ath_detach(struct ath_softc *sc); | ||
637 | const char *ath_mac_bb_name(u32 mac_bb_version); | ||
638 | const char *ath_rf_name(u16 rf_version); | ||
639 | void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); | ||
640 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, | ||
641 | struct ath9k_channel *ichan); | ||
642 | void ath_update_chainmask(struct ath_softc *sc, int is_ht); | ||
643 | int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | ||
644 | struct ath9k_channel *hchan); | ||
645 | void ath_radio_enable(struct ath_softc *sc); | ||
646 | void ath_radio_disable(struct ath_softc *sc); | ||
647 | |||
648 | #ifdef CONFIG_PCI | ||
649 | int ath_pci_init(void); | ||
650 | void ath_pci_exit(void); | ||
651 | #else | ||
652 | static inline int ath_pci_init(void) { return 0; }; | ||
653 | static inline void ath_pci_exit(void) {}; | ||
654 | #endif | ||
655 | |||
656 | #ifdef CONFIG_ATHEROS_AR71XX | ||
657 | int ath_ahb_init(void); | ||
658 | void ath_ahb_exit(void); | ||
659 | #else | ||
660 | static inline int ath_ahb_init(void) { return 0; }; | ||
661 | static inline void ath_ahb_exit(void) {}; | ||
662 | #endif | ||
663 | |||
664 | static inline void ath9k_ps_wakeup(struct ath_softc *sc) | ||
665 | { | ||
666 | if (atomic_inc_return(&sc->ps_usecount) == 1) | ||
667 | if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) { | ||
668 | sc->sc_ah->restore_mode = sc->sc_ah->power_mode; | ||
669 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); | ||
670 | } | ||
671 | } | ||
672 | |||
673 | static inline void ath9k_ps_restore(struct ath_softc *sc) | ||
674 | { | ||
675 | if (atomic_dec_and_test(&sc->ps_usecount)) | ||
676 | if ((sc->hw->conf.flags & IEEE80211_CONF_PS) && | ||
677 | !(sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) | ||
678 | ath9k_hw_setpower(sc->sc_ah, | ||
679 | sc->sc_ah->restore_mode); | ||
680 | } | ||
681 | |||
682 | |||
683 | void ath9k_set_bssid_mask(struct ieee80211_hw *hw); | ||
684 | int ath9k_wiphy_add(struct ath_softc *sc); | ||
685 | int ath9k_wiphy_del(struct ath_wiphy *aphy); | ||
686 | void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
687 | int ath9k_wiphy_pause(struct ath_wiphy *aphy); | ||
688 | int ath9k_wiphy_unpause(struct ath_wiphy *aphy); | ||
689 | int ath9k_wiphy_select(struct ath_wiphy *aphy); | ||
690 | void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int); | ||
691 | void ath9k_wiphy_chan_work(struct work_struct *work); | ||
692 | bool ath9k_wiphy_started(struct ath_softc *sc); | ||
693 | void ath9k_wiphy_pause_all_forced(struct ath_softc *sc, | ||
694 | struct ath_wiphy *selected); | ||
695 | bool ath9k_wiphy_scanning(struct ath_softc *sc); | ||
696 | void ath9k_wiphy_work(struct work_struct *work); | ||
697 | |||
698 | /* | ||
699 | * Read and write, they both share the same lock. We do this to serialize | ||
700 | * reads and writes on Atheros 802.11n PCI devices only. This is required | ||
701 | * as the FIFO on these devices can only accept sanely 2 requests. After | ||
702 | * that the device goes bananas. Serializing the reads/writes prevents this | ||
703 | * from happening. | ||
704 | */ | ||
705 | |||
706 | static inline void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val) | ||
707 | { | ||
708 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | ||
709 | unsigned long flags; | ||
710 | spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags); | ||
711 | iowrite32(val, ah->ah_sc->mem + reg_offset); | ||
712 | spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags); | ||
713 | } else | ||
714 | iowrite32(val, ah->ah_sc->mem + reg_offset); | ||
715 | } | ||
716 | |||
717 | static inline unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset) | ||
718 | { | ||
719 | u32 val; | ||
720 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | ||
721 | unsigned long flags; | ||
722 | spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags); | ||
723 | val = ioread32(ah->ah_sc->mem + reg_offset); | ||
724 | spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags); | ||
725 | } else | ||
726 | val = ioread32(ah->ah_sc->mem + reg_offset); | ||
727 | return val; | ||
728 | } | ||
729 | |||
730 | #endif /* ATH9K_H */ | ||
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c deleted file mode 100644 index eb4759fc6a0d..000000000000 --- a/drivers/net/wireless/ath9k/beacon.c +++ /dev/null | |||
@@ -1,743 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 "ath9k.h" | ||
18 | |||
19 | #define FUDGE 2 | ||
20 | |||
21 | /* | ||
22 | * This function will modify certain transmit queue properties depending on | ||
23 | * the operating mode of the station (AP or AdHoc). Parameters are AIFS | ||
24 | * settings and channel width min/max | ||
25 | */ | ||
26 | static int ath_beaconq_config(struct ath_softc *sc) | ||
27 | { | ||
28 | struct ath_hw *ah = sc->sc_ah; | ||
29 | struct ath9k_tx_queue_info qi; | ||
30 | |||
31 | ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi); | ||
32 | if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { | ||
33 | /* Always burst out beacon and CAB traffic. */ | ||
34 | qi.tqi_aifs = 1; | ||
35 | qi.tqi_cwmin = 0; | ||
36 | qi.tqi_cwmax = 0; | ||
37 | } else { | ||
38 | /* Adhoc mode; important thing is to use 2x cwmin. */ | ||
39 | qi.tqi_aifs = sc->beacon.beacon_qi.tqi_aifs; | ||
40 | qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin; | ||
41 | qi.tqi_cwmax = sc->beacon.beacon_qi.tqi_cwmax; | ||
42 | } | ||
43 | |||
44 | if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) { | ||
45 | DPRINTF(sc, ATH_DBG_FATAL, | ||
46 | "Unable to update h/w beacon queue parameters\n"); | ||
47 | return 0; | ||
48 | } else { | ||
49 | ath9k_hw_resettxqueue(ah, sc->beacon.beaconq); | ||
50 | return 1; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | /* | ||
55 | * Associates the beacon frame buffer with a transmit descriptor. Will set | ||
56 | * up all required antenna switch parameters, rate codes, and channel flags. | ||
57 | * Beacons are always sent out at the lowest rate, and are not retried. | ||
58 | */ | ||
59 | static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | ||
60 | struct ath_buf *bf) | ||
61 | { | ||
62 | struct sk_buff *skb = bf->bf_mpdu; | ||
63 | struct ath_hw *ah = sc->sc_ah; | ||
64 | struct ath_desc *ds; | ||
65 | struct ath9k_11n_rate_series series[4]; | ||
66 | struct ath_rate_table *rt; | ||
67 | int flags, antenna, ctsrate = 0, ctsduration = 0; | ||
68 | u8 rate; | ||
69 | |||
70 | ds = bf->bf_desc; | ||
71 | flags = ATH9K_TXDESC_NOACK; | ||
72 | |||
73 | if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || | ||
74 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) && | ||
75 | (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) { | ||
76 | ds->ds_link = bf->bf_daddr; /* self-linked */ | ||
77 | flags |= ATH9K_TXDESC_VEOL; | ||
78 | /* Let hardware handle antenna switching. */ | ||
79 | antenna = 0; | ||
80 | } else { | ||
81 | ds->ds_link = 0; | ||
82 | /* | ||
83 | * Switch antenna every beacon. | ||
84 | * Should only switch every beacon period, not for every SWBA | ||
85 | * XXX assumes two antennae | ||
86 | */ | ||
87 | antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1); | ||
88 | } | ||
89 | |||
90 | ds->ds_data = bf->bf_buf_addr; | ||
91 | |||
92 | rt = sc->cur_rate_table; | ||
93 | rate = rt->info[0].ratecode; | ||
94 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) | ||
95 | rate |= rt->info[0].short_preamble; | ||
96 | |||
97 | ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN, | ||
98 | ATH9K_PKT_TYPE_BEACON, | ||
99 | MAX_RATE_POWER, | ||
100 | ATH9K_TXKEYIX_INVALID, | ||
101 | ATH9K_KEY_TYPE_CLEAR, | ||
102 | flags); | ||
103 | |||
104 | /* NB: beacon's BufLen must be a multiple of 4 bytes */ | ||
105 | ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4), | ||
106 | true, true, ds); | ||
107 | |||
108 | memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); | ||
109 | series[0].Tries = 1; | ||
110 | series[0].Rate = rate; | ||
111 | series[0].ChSel = sc->tx_chainmask; | ||
112 | series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0; | ||
113 | ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration, | ||
114 | series, 4, 0); | ||
115 | } | ||
116 | |||
117 | static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, | ||
118 | struct ieee80211_vif *vif) | ||
119 | { | ||
120 | struct ath_wiphy *aphy = hw->priv; | ||
121 | struct ath_softc *sc = aphy->sc; | ||
122 | struct ath_buf *bf; | ||
123 | struct ath_vif *avp; | ||
124 | struct sk_buff *skb; | ||
125 | struct ath_txq *cabq; | ||
126 | struct ieee80211_tx_info *info; | ||
127 | int cabq_depth; | ||
128 | |||
129 | if (aphy->state != ATH_WIPHY_ACTIVE) | ||
130 | return NULL; | ||
131 | |||
132 | avp = (void *)vif->drv_priv; | ||
133 | cabq = sc->beacon.cabq; | ||
134 | |||
135 | if (avp->av_bcbuf == NULL) | ||
136 | return NULL; | ||
137 | |||
138 | /* Release the old beacon first */ | ||
139 | |||
140 | bf = avp->av_bcbuf; | ||
141 | skb = bf->bf_mpdu; | ||
142 | if (skb) { | ||
143 | dma_unmap_single(sc->dev, bf->bf_dmacontext, | ||
144 | skb->len, DMA_TO_DEVICE); | ||
145 | dev_kfree_skb_any(skb); | ||
146 | } | ||
147 | |||
148 | /* Get a new beacon from mac80211 */ | ||
149 | |||
150 | skb = ieee80211_beacon_get(hw, vif); | ||
151 | bf->bf_mpdu = skb; | ||
152 | if (skb == NULL) | ||
153 | return NULL; | ||
154 | ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp = | ||
155 | avp->tsf_adjust; | ||
156 | |||
157 | info = IEEE80211_SKB_CB(skb); | ||
158 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
159 | /* | ||
160 | * TODO: make sure the seq# gets assigned properly (vs. other | ||
161 | * TX frames) | ||
162 | */ | ||
163 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
164 | sc->tx.seq_no += 0x10; | ||
165 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
166 | hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); | ||
167 | } | ||
168 | |||
169 | bf->bf_buf_addr = bf->bf_dmacontext = | ||
170 | dma_map_single(sc->dev, skb->data, | ||
171 | skb->len, DMA_TO_DEVICE); | ||
172 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { | ||
173 | dev_kfree_skb_any(skb); | ||
174 | bf->bf_mpdu = NULL; | ||
175 | DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error on beaconing\n"); | ||
176 | return NULL; | ||
177 | } | ||
178 | |||
179 | skb = ieee80211_get_buffered_bc(hw, vif); | ||
180 | |||
181 | /* | ||
182 | * if the CABQ traffic from previous DTIM is pending and the current | ||
183 | * beacon is also a DTIM. | ||
184 | * 1) if there is only one vif let the cab traffic continue. | ||
185 | * 2) if there are more than one vif and we are using staggered | ||
186 | * beacons, then drain the cabq by dropping all the frames in | ||
187 | * the cabq so that the current vifs cab traffic can be scheduled. | ||
188 | */ | ||
189 | spin_lock_bh(&cabq->axq_lock); | ||
190 | cabq_depth = cabq->axq_depth; | ||
191 | spin_unlock_bh(&cabq->axq_lock); | ||
192 | |||
193 | if (skb && cabq_depth) { | ||
194 | if (sc->nvifs > 1) { | ||
195 | DPRINTF(sc, ATH_DBG_BEACON, | ||
196 | "Flushing previous cabq traffic\n"); | ||
197 | ath_draintxq(sc, cabq, false); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | ath_beacon_setup(sc, avp, bf); | ||
202 | |||
203 | while (skb) { | ||
204 | ath_tx_cabq(hw, skb); | ||
205 | skb = ieee80211_get_buffered_bc(hw, vif); | ||
206 | } | ||
207 | |||
208 | return bf; | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * Startup beacon transmission for adhoc mode when they are sent entirely | ||
213 | * by the hardware using the self-linked descriptor + veol trick. | ||
214 | */ | ||
215 | static void ath_beacon_start_adhoc(struct ath_softc *sc, | ||
216 | struct ieee80211_vif *vif) | ||
217 | { | ||
218 | struct ath_hw *ah = sc->sc_ah; | ||
219 | struct ath_buf *bf; | ||
220 | struct ath_vif *avp; | ||
221 | struct sk_buff *skb; | ||
222 | |||
223 | avp = (void *)vif->drv_priv; | ||
224 | |||
225 | if (avp->av_bcbuf == NULL) | ||
226 | return; | ||
227 | |||
228 | bf = avp->av_bcbuf; | ||
229 | skb = bf->bf_mpdu; | ||
230 | |||
231 | ath_beacon_setup(sc, avp, bf); | ||
232 | |||
233 | /* NB: caller is known to have already stopped tx dma */ | ||
234 | ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr); | ||
235 | ath9k_hw_txstart(ah, sc->beacon.beaconq); | ||
236 | DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n", | ||
237 | sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc); | ||
238 | } | ||
239 | |||
240 | int ath_beaconq_setup(struct ath_hw *ah) | ||
241 | { | ||
242 | struct ath9k_tx_queue_info qi; | ||
243 | |||
244 | memset(&qi, 0, sizeof(qi)); | ||
245 | qi.tqi_aifs = 1; | ||
246 | qi.tqi_cwmin = 0; | ||
247 | qi.tqi_cwmax = 0; | ||
248 | /* NB: don't enable any interrupts */ | ||
249 | return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); | ||
250 | } | ||
251 | |||
252 | int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) | ||
253 | { | ||
254 | struct ath_softc *sc = aphy->sc; | ||
255 | struct ath_vif *avp; | ||
256 | struct ath_buf *bf; | ||
257 | struct sk_buff *skb; | ||
258 | __le64 tstamp; | ||
259 | |||
260 | avp = (void *)vif->drv_priv; | ||
261 | |||
262 | /* Allocate a beacon descriptor if we haven't done so. */ | ||
263 | if (!avp->av_bcbuf) { | ||
264 | /* Allocate beacon state for hostap/ibss. We know | ||
265 | * a buffer is available. */ | ||
266 | avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf, | ||
267 | struct ath_buf, list); | ||
268 | list_del(&avp->av_bcbuf->list); | ||
269 | |||
270 | if (sc->sc_ah->opmode == NL80211_IFTYPE_AP || | ||
271 | !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) { | ||
272 | int slot; | ||
273 | /* | ||
274 | * Assign the vif to a beacon xmit slot. As | ||
275 | * above, this cannot fail to find one. | ||
276 | */ | ||
277 | avp->av_bslot = 0; | ||
278 | for (slot = 0; slot < ATH_BCBUF; slot++) | ||
279 | if (sc->beacon.bslot[slot] == NULL) { | ||
280 | /* | ||
281 | * XXX hack, space out slots to better | ||
282 | * deal with misses | ||
283 | */ | ||
284 | if (slot+1 < ATH_BCBUF && | ||
285 | sc->beacon.bslot[slot+1] == NULL) { | ||
286 | avp->av_bslot = slot+1; | ||
287 | break; | ||
288 | } | ||
289 | avp->av_bslot = slot; | ||
290 | /* NB: keep looking for a double slot */ | ||
291 | } | ||
292 | BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL); | ||
293 | sc->beacon.bslot[avp->av_bslot] = vif; | ||
294 | sc->beacon.bslot_aphy[avp->av_bslot] = aphy; | ||
295 | sc->nbcnvifs++; | ||
296 | } | ||
297 | } | ||
298 | |||
299 | /* release the previous beacon frame, if it already exists. */ | ||
300 | bf = avp->av_bcbuf; | ||
301 | if (bf->bf_mpdu != NULL) { | ||
302 | skb = bf->bf_mpdu; | ||
303 | dma_unmap_single(sc->dev, bf->bf_dmacontext, | ||
304 | skb->len, DMA_TO_DEVICE); | ||
305 | dev_kfree_skb_any(skb); | ||
306 | bf->bf_mpdu = NULL; | ||
307 | } | ||
308 | |||
309 | /* NB: the beacon data buffer must be 32-bit aligned. */ | ||
310 | skb = ieee80211_beacon_get(sc->hw, vif); | ||
311 | if (skb == NULL) { | ||
312 | DPRINTF(sc, ATH_DBG_BEACON, "cannot get skb\n"); | ||
313 | return -ENOMEM; | ||
314 | } | ||
315 | |||
316 | tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; | ||
317 | sc->beacon.bc_tstamp = le64_to_cpu(tstamp); | ||
318 | /* Calculate a TSF adjustment factor required for staggered beacons. */ | ||
319 | if (avp->av_bslot > 0) { | ||
320 | u64 tsfadjust; | ||
321 | int intval; | ||
322 | |||
323 | intval = sc->hw->conf.beacon_int ? | ||
324 | sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL; | ||
325 | |||
326 | /* | ||
327 | * Calculate the TSF offset for this beacon slot, i.e., the | ||
328 | * number of usecs that need to be added to the timestamp field | ||
329 | * in Beacon and Probe Response frames. Beacon slot 0 is | ||
330 | * processed at the correct offset, so it does not require TSF | ||
331 | * adjustment. Other slots are adjusted to get the timestamp | ||
332 | * close to the TBTT for the BSS. | ||
333 | */ | ||
334 | tsfadjust = intval * avp->av_bslot / ATH_BCBUF; | ||
335 | avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); | ||
336 | |||
337 | DPRINTF(sc, ATH_DBG_BEACON, | ||
338 | "stagger beacons, bslot %d intval %u tsfadjust %llu\n", | ||
339 | avp->av_bslot, intval, (unsigned long long)tsfadjust); | ||
340 | |||
341 | ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp = | ||
342 | avp->tsf_adjust; | ||
343 | } else | ||
344 | avp->tsf_adjust = cpu_to_le64(0); | ||
345 | |||
346 | bf->bf_mpdu = skb; | ||
347 | bf->bf_buf_addr = bf->bf_dmacontext = | ||
348 | dma_map_single(sc->dev, skb->data, | ||
349 | skb->len, DMA_TO_DEVICE); | ||
350 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { | ||
351 | dev_kfree_skb_any(skb); | ||
352 | bf->bf_mpdu = NULL; | ||
353 | DPRINTF(sc, ATH_DBG_FATAL, | ||
354 | "dma_mapping_error on beacon alloc\n"); | ||
355 | return -ENOMEM; | ||
356 | } | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) | ||
362 | { | ||
363 | if (avp->av_bcbuf != NULL) { | ||
364 | struct ath_buf *bf; | ||
365 | |||
366 | if (avp->av_bslot != -1) { | ||
367 | sc->beacon.bslot[avp->av_bslot] = NULL; | ||
368 | sc->beacon.bslot_aphy[avp->av_bslot] = NULL; | ||
369 | sc->nbcnvifs--; | ||
370 | } | ||
371 | |||
372 | bf = avp->av_bcbuf; | ||
373 | if (bf->bf_mpdu != NULL) { | ||
374 | struct sk_buff *skb = bf->bf_mpdu; | ||
375 | dma_unmap_single(sc->dev, bf->bf_dmacontext, | ||
376 | skb->len, DMA_TO_DEVICE); | ||
377 | dev_kfree_skb_any(skb); | ||
378 | bf->bf_mpdu = NULL; | ||
379 | } | ||
380 | list_add_tail(&bf->list, &sc->beacon.bbuf); | ||
381 | |||
382 | avp->av_bcbuf = NULL; | ||
383 | } | ||
384 | } | ||
385 | |||
386 | void ath_beacon_tasklet(unsigned long data) | ||
387 | { | ||
388 | struct ath_softc *sc = (struct ath_softc *)data; | ||
389 | struct ath_hw *ah = sc->sc_ah; | ||
390 | struct ath_buf *bf = NULL; | ||
391 | struct ieee80211_vif *vif; | ||
392 | struct ath_wiphy *aphy; | ||
393 | int slot; | ||
394 | u32 bfaddr, bc = 0, tsftu; | ||
395 | u64 tsf; | ||
396 | u16 intval; | ||
397 | |||
398 | /* | ||
399 | * Check if the previous beacon has gone out. If | ||
400 | * not don't try to post another, skip this period | ||
401 | * and wait for the next. Missed beacons indicate | ||
402 | * a problem and should not occur. If we miss too | ||
403 | * many consecutive beacons reset the device. | ||
404 | */ | ||
405 | if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) { | ||
406 | sc->beacon.bmisscnt++; | ||
407 | |||
408 | if (sc->beacon.bmisscnt < BSTUCK_THRESH) { | ||
409 | DPRINTF(sc, ATH_DBG_BEACON, | ||
410 | "missed %u consecutive beacons\n", | ||
411 | sc->beacon.bmisscnt); | ||
412 | } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { | ||
413 | DPRINTF(sc, ATH_DBG_BEACON, | ||
414 | "beacon is officially stuck\n"); | ||
415 | ath_reset(sc, false); | ||
416 | } | ||
417 | |||
418 | return; | ||
419 | } | ||
420 | |||
421 | if (sc->beacon.bmisscnt != 0) { | ||
422 | DPRINTF(sc, ATH_DBG_BEACON, | ||
423 | "resume beacon xmit after %u misses\n", | ||
424 | sc->beacon.bmisscnt); | ||
425 | sc->beacon.bmisscnt = 0; | ||
426 | } | ||
427 | |||
428 | /* | ||
429 | * Generate beacon frames. we are sending frames | ||
430 | * staggered so calculate the slot for this frame based | ||
431 | * on the tsf to safeguard against missing an swba. | ||
432 | */ | ||
433 | |||
434 | intval = sc->hw->conf.beacon_int ? | ||
435 | sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL; | ||
436 | |||
437 | tsf = ath9k_hw_gettsf64(ah); | ||
438 | tsftu = TSF_TO_TU(tsf>>32, tsf); | ||
439 | slot = ((tsftu % intval) * ATH_BCBUF) / intval; | ||
440 | /* | ||
441 | * Reverse the slot order to get slot 0 on the TBTT offset that does | ||
442 | * not require TSF adjustment and other slots adding | ||
443 | * slot/ATH_BCBUF * beacon_int to timestamp. For example, with | ||
444 | * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 .. | ||
445 | * and slot 0 is at correct offset to TBTT. | ||
446 | */ | ||
447 | slot = ATH_BCBUF - slot - 1; | ||
448 | vif = sc->beacon.bslot[slot]; | ||
449 | aphy = sc->beacon.bslot_aphy[slot]; | ||
450 | |||
451 | DPRINTF(sc, ATH_DBG_BEACON, | ||
452 | "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", | ||
453 | slot, tsf, tsftu, intval, vif); | ||
454 | |||
455 | bfaddr = 0; | ||
456 | if (vif) { | ||
457 | bf = ath_beacon_generate(aphy->hw, vif); | ||
458 | if (bf != NULL) { | ||
459 | bfaddr = bf->bf_daddr; | ||
460 | bc = 1; | ||
461 | } | ||
462 | } | ||
463 | |||
464 | /* | ||
465 | * Handle slot time change when a non-ERP station joins/leaves | ||
466 | * an 11g network. The 802.11 layer notifies us via callback, | ||
467 | * we mark updateslot, then wait one beacon before effecting | ||
468 | * the change. This gives associated stations at least one | ||
469 | * beacon interval to note the state change. | ||
470 | * | ||
471 | * NB: The slot time change state machine is clocked according | ||
472 | * to whether we are bursting or staggering beacons. We | ||
473 | * recognize the request to update and record the current | ||
474 | * slot then don't transition until that slot is reached | ||
475 | * again. If we miss a beacon for that slot then we'll be | ||
476 | * slow to transition but we'll be sure at least one beacon | ||
477 | * interval has passed. When bursting slot is always left | ||
478 | * set to ATH_BCBUF so this check is a noop. | ||
479 | */ | ||
480 | if (sc->beacon.updateslot == UPDATE) { | ||
481 | sc->beacon.updateslot = COMMIT; /* commit next beacon */ | ||
482 | sc->beacon.slotupdate = slot; | ||
483 | } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) { | ||
484 | ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime); | ||
485 | sc->beacon.updateslot = OK; | ||
486 | } | ||
487 | if (bfaddr != 0) { | ||
488 | /* | ||
489 | * Stop any current dma and put the new frame(s) on the queue. | ||
490 | * This should never fail since we check above that no frames | ||
491 | * are still pending on the queue. | ||
492 | */ | ||
493 | if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) { | ||
494 | DPRINTF(sc, ATH_DBG_FATAL, | ||
495 | "beacon queue %u did not stop?\n", sc->beacon.beaconq); | ||
496 | } | ||
497 | |||
498 | /* NB: cabq traffic should already be queued and primed */ | ||
499 | ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr); | ||
500 | ath9k_hw_txstart(ah, sc->beacon.beaconq); | ||
501 | |||
502 | sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */ | ||
503 | } | ||
504 | } | ||
505 | |||
506 | /* | ||
507 | * For multi-bss ap support beacons are either staggered evenly over N slots or | ||
508 | * burst together. For the former arrange for the SWBA to be delivered for each | ||
509 | * slot. Slots that are not occupied will generate nothing. | ||
510 | */ | ||
511 | static void ath_beacon_config_ap(struct ath_softc *sc, | ||
512 | struct ath_beacon_config *conf, | ||
513 | struct ath_vif *avp) | ||
514 | { | ||
515 | u32 nexttbtt, intval; | ||
516 | |||
517 | /* Configure the timers only when the TSF has to be reset */ | ||
518 | |||
519 | if (!(sc->sc_flags & SC_OP_TSF_RESET)) | ||
520 | return; | ||
521 | |||
522 | /* NB: the beacon interval is kept internally in TU's */ | ||
523 | intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; | ||
524 | intval /= ATH_BCBUF; /* for staggered beacons */ | ||
525 | nexttbtt = intval; | ||
526 | intval |= ATH9K_BEACON_RESET_TSF; | ||
527 | |||
528 | /* | ||
529 | * In AP mode we enable the beacon timers and SWBA interrupts to | ||
530 | * prepare beacon frames. | ||
531 | */ | ||
532 | intval |= ATH9K_BEACON_ENA; | ||
533 | sc->imask |= ATH9K_INT_SWBA; | ||
534 | ath_beaconq_config(sc); | ||
535 | |||
536 | /* Set the computed AP beacon timers */ | ||
537 | |||
538 | ath9k_hw_set_interrupts(sc->sc_ah, 0); | ||
539 | ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval); | ||
540 | sc->beacon.bmisscnt = 0; | ||
541 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | ||
542 | |||
543 | /* Clear the reset TSF flag, so that subsequent beacon updation | ||
544 | will not reset the HW TSF. */ | ||
545 | |||
546 | sc->sc_flags &= ~SC_OP_TSF_RESET; | ||
547 | } | ||
548 | |||
549 | /* | ||
550 | * This sets up the beacon timers according to the timestamp of the last | ||
551 | * received beacon and the current TSF, configures PCF and DTIM | ||
552 | * handling, programs the sleep registers so the hardware will wakeup in | ||
553 | * time to receive beacons, and configures the beacon miss handling so | ||
554 | * we'll receive a BMISS interrupt when we stop seeing beacons from the AP | ||
555 | * we've associated with. | ||
556 | */ | ||
557 | static void ath_beacon_config_sta(struct ath_softc *sc, | ||
558 | struct ath_beacon_config *conf, | ||
559 | struct ath_vif *avp) | ||
560 | { | ||
561 | struct ath9k_beacon_state bs; | ||
562 | int dtimperiod, dtimcount, sleepduration; | ||
563 | int cfpperiod, cfpcount; | ||
564 | u32 nexttbtt = 0, intval, tsftu; | ||
565 | u64 tsf; | ||
566 | |||
567 | memset(&bs, 0, sizeof(bs)); | ||
568 | intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; | ||
569 | |||
570 | /* | ||
571 | * Setup dtim and cfp parameters according to | ||
572 | * last beacon we received (which may be none). | ||
573 | */ | ||
574 | dtimperiod = conf->dtim_period; | ||
575 | if (dtimperiod <= 0) /* NB: 0 if not known */ | ||
576 | dtimperiod = 1; | ||
577 | dtimcount = conf->dtim_count; | ||
578 | if (dtimcount >= dtimperiod) /* NB: sanity check */ | ||
579 | dtimcount = 0; | ||
580 | cfpperiod = 1; /* NB: no PCF support yet */ | ||
581 | cfpcount = 0; | ||
582 | |||
583 | sleepduration = conf->listen_interval * intval; | ||
584 | if (sleepduration <= 0) | ||
585 | sleepduration = intval; | ||
586 | |||
587 | /* | ||
588 | * Pull nexttbtt forward to reflect the current | ||
589 | * TSF and calculate dtim+cfp state for the result. | ||
590 | */ | ||
591 | tsf = ath9k_hw_gettsf64(sc->sc_ah); | ||
592 | tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE; | ||
593 | do { | ||
594 | nexttbtt += intval; | ||
595 | if (--dtimcount < 0) { | ||
596 | dtimcount = dtimperiod - 1; | ||
597 | if (--cfpcount < 0) | ||
598 | cfpcount = cfpperiod - 1; | ||
599 | } | ||
600 | } while (nexttbtt < tsftu); | ||
601 | |||
602 | bs.bs_intval = intval; | ||
603 | bs.bs_nexttbtt = nexttbtt; | ||
604 | bs.bs_dtimperiod = dtimperiod*intval; | ||
605 | bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval; | ||
606 | bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod; | ||
607 | bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod; | ||
608 | bs.bs_cfpmaxduration = 0; | ||
609 | |||
610 | /* | ||
611 | * Calculate the number of consecutive beacons to miss* before taking | ||
612 | * a BMISS interrupt. The configuration is specified in TU so we only | ||
613 | * need calculate based on the beacon interval. Note that we clamp the | ||
614 | * result to at most 15 beacons. | ||
615 | */ | ||
616 | if (sleepduration > intval) { | ||
617 | bs.bs_bmissthreshold = conf->listen_interval * | ||
618 | ATH_DEFAULT_BMISS_LIMIT / 2; | ||
619 | } else { | ||
620 | bs.bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, intval); | ||
621 | if (bs.bs_bmissthreshold > 15) | ||
622 | bs.bs_bmissthreshold = 15; | ||
623 | else if (bs.bs_bmissthreshold <= 0) | ||
624 | bs.bs_bmissthreshold = 1; | ||
625 | } | ||
626 | |||
627 | /* | ||
628 | * Calculate sleep duration. The configuration is given in ms. | ||
629 | * We ensure a multiple of the beacon period is used. Also, if the sleep | ||
630 | * duration is greater than the DTIM period then it makes senses | ||
631 | * to make it a multiple of that. | ||
632 | * | ||
633 | * XXX fixed at 100ms | ||
634 | */ | ||
635 | |||
636 | bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration); | ||
637 | if (bs.bs_sleepduration > bs.bs_dtimperiod) | ||
638 | bs.bs_sleepduration = bs.bs_dtimperiod; | ||
639 | |||
640 | /* TSF out of range threshold fixed at 1 second */ | ||
641 | bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; | ||
642 | |||
643 | DPRINTF(sc, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu); | ||
644 | DPRINTF(sc, ATH_DBG_BEACON, | ||
645 | "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", | ||
646 | bs.bs_bmissthreshold, bs.bs_sleepduration, | ||
647 | bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext); | ||
648 | |||
649 | /* Set the computed STA beacon timers */ | ||
650 | |||
651 | ath9k_hw_set_interrupts(sc->sc_ah, 0); | ||
652 | ath9k_hw_set_sta_beacon_timers(sc->sc_ah, &bs); | ||
653 | sc->imask |= ATH9K_INT_BMISS; | ||
654 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | ||
655 | } | ||
656 | |||
657 | static void ath_beacon_config_adhoc(struct ath_softc *sc, | ||
658 | struct ath_beacon_config *conf, | ||
659 | struct ath_vif *avp, | ||
660 | struct ieee80211_vif *vif) | ||
661 | { | ||
662 | u64 tsf; | ||
663 | u32 tsftu, intval, nexttbtt; | ||
664 | |||
665 | intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; | ||
666 | |||
667 | /* Pull nexttbtt forward to reflect the current TSF */ | ||
668 | |||
669 | nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp); | ||
670 | if (nexttbtt == 0) | ||
671 | nexttbtt = intval; | ||
672 | else if (intval) | ||
673 | nexttbtt = roundup(nexttbtt, intval); | ||
674 | |||
675 | tsf = ath9k_hw_gettsf64(sc->sc_ah); | ||
676 | tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE; | ||
677 | do { | ||
678 | nexttbtt += intval; | ||
679 | } while (nexttbtt < tsftu); | ||
680 | |||
681 | DPRINTF(sc, ATH_DBG_BEACON, | ||
682 | "IBSS nexttbtt %u intval %u (%u)\n", | ||
683 | nexttbtt, intval, conf->beacon_interval); | ||
684 | |||
685 | /* | ||
686 | * In IBSS mode enable the beacon timers but only enable SWBA interrupts | ||
687 | * if we need to manually prepare beacon frames. Otherwise we use a | ||
688 | * self-linked tx descriptor and let the hardware deal with things. | ||
689 | */ | ||
690 | intval |= ATH9K_BEACON_ENA; | ||
691 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) | ||
692 | sc->imask |= ATH9K_INT_SWBA; | ||
693 | |||
694 | ath_beaconq_config(sc); | ||
695 | |||
696 | /* Set the computed ADHOC beacon timers */ | ||
697 | |||
698 | ath9k_hw_set_interrupts(sc->sc_ah, 0); | ||
699 | ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval); | ||
700 | sc->beacon.bmisscnt = 0; | ||
701 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | ||
702 | |||
703 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL) | ||
704 | ath_beacon_start_adhoc(sc, vif); | ||
705 | } | ||
706 | |||
707 | void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) | ||
708 | { | ||
709 | struct ath_beacon_config conf; | ||
710 | |||
711 | /* Setup the beacon configuration parameters */ | ||
712 | |||
713 | memset(&conf, 0, sizeof(struct ath_beacon_config)); | ||
714 | conf.beacon_interval = sc->hw->conf.beacon_int ? | ||
715 | sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL; | ||
716 | conf.listen_interval = 1; | ||
717 | conf.dtim_period = conf.beacon_interval; | ||
718 | conf.dtim_count = 1; | ||
719 | conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval; | ||
720 | |||
721 | if (vif) { | ||
722 | struct ath_vif *avp = (struct ath_vif *)vif->drv_priv; | ||
723 | |||
724 | switch(avp->av_opmode) { | ||
725 | case NL80211_IFTYPE_AP: | ||
726 | ath_beacon_config_ap(sc, &conf, avp); | ||
727 | break; | ||
728 | case NL80211_IFTYPE_ADHOC: | ||
729 | case NL80211_IFTYPE_MESH_POINT: | ||
730 | ath_beacon_config_adhoc(sc, &conf, avp, vif); | ||
731 | break; | ||
732 | case NL80211_IFTYPE_STATION: | ||
733 | ath_beacon_config_sta(sc, &conf, avp); | ||
734 | break; | ||
735 | default: | ||
736 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
737 | "Unsupported beaconing mode\n"); | ||
738 | return; | ||
739 | } | ||
740 | |||
741 | sc->sc_flags |= SC_OP_BEACONS; | ||
742 | } | ||
743 | } | ||
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c deleted file mode 100644 index e2d62e97131c..000000000000 --- a/drivers/net/wireless/ath9k/calib.c +++ /dev/null | |||
@@ -1,1060 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 "ath9k.h" | ||
18 | |||
19 | /* We can tune this as we go by monitoring really low values */ | ||
20 | #define ATH9K_NF_TOO_LOW -60 | ||
21 | |||
22 | /* AR5416 may return very high value (like -31 dBm), in those cases the nf | ||
23 | * is incorrect and we should use the static NF value. Later we can try to | ||
24 | * find out why they are reporting these values */ | ||
25 | |||
26 | static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf) | ||
27 | { | ||
28 | if (nf > ATH9K_NF_TOO_LOW) { | ||
29 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
30 | "noise floor value detected (%d) is " | ||
31 | "lower than what we think is a " | ||
32 | "reasonable value (%d)\n", | ||
33 | nf, ATH9K_NF_TOO_LOW); | ||
34 | return false; | ||
35 | } | ||
36 | return true; | ||
37 | } | ||
38 | |||
39 | static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer) | ||
40 | { | ||
41 | int16_t nfval; | ||
42 | int16_t sort[ATH9K_NF_CAL_HIST_MAX]; | ||
43 | int i, j; | ||
44 | |||
45 | for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++) | ||
46 | sort[i] = nfCalBuffer[i]; | ||
47 | |||
48 | for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) { | ||
49 | for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) { | ||
50 | if (sort[j] > sort[j - 1]) { | ||
51 | nfval = sort[j]; | ||
52 | sort[j] = sort[j - 1]; | ||
53 | sort[j - 1] = nfval; | ||
54 | } | ||
55 | } | ||
56 | } | ||
57 | nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1]; | ||
58 | |||
59 | return nfval; | ||
60 | } | ||
61 | |||
62 | static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h, | ||
63 | int16_t *nfarray) | ||
64 | { | ||
65 | int i; | ||
66 | |||
67 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
68 | h[i].nfCalBuffer[h[i].currIndex] = nfarray[i]; | ||
69 | |||
70 | if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX) | ||
71 | h[i].currIndex = 0; | ||
72 | |||
73 | if (h[i].invalidNFcount > 0) { | ||
74 | if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE || | ||
75 | nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) { | ||
76 | h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX; | ||
77 | } else { | ||
78 | h[i].invalidNFcount--; | ||
79 | h[i].privNF = nfarray[i]; | ||
80 | } | ||
81 | } else { | ||
82 | h[i].privNF = | ||
83 | ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer); | ||
84 | } | ||
85 | } | ||
86 | return; | ||
87 | } | ||
88 | |||
89 | static void ath9k_hw_do_getnf(struct ath_hw *ah, | ||
90 | int16_t nfarray[NUM_NF_READINGS]) | ||
91 | { | ||
92 | int16_t nf; | ||
93 | |||
94 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
95 | nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR); | ||
96 | else | ||
97 | nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR); | ||
98 | |||
99 | if (nf & 0x100) | ||
100 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
101 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
102 | "NF calibrated [ctl] [chain 0] is %d\n", nf); | ||
103 | nfarray[0] = nf; | ||
104 | |||
105 | if (!AR_SREV_9285(ah)) { | ||
106 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
107 | nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), | ||
108 | AR9280_PHY_CH1_MINCCA_PWR); | ||
109 | else | ||
110 | nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), | ||
111 | AR_PHY_CH1_MINCCA_PWR); | ||
112 | |||
113 | if (nf & 0x100) | ||
114 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
115 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
116 | "NF calibrated [ctl] [chain 1] is %d\n", nf); | ||
117 | nfarray[1] = nf; | ||
118 | |||
119 | if (!AR_SREV_9280(ah)) { | ||
120 | nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), | ||
121 | AR_PHY_CH2_MINCCA_PWR); | ||
122 | if (nf & 0x100) | ||
123 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
124 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
125 | "NF calibrated [ctl] [chain 2] is %d\n", nf); | ||
126 | nfarray[2] = nf; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
131 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), | ||
132 | AR9280_PHY_EXT_MINCCA_PWR); | ||
133 | else | ||
134 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), | ||
135 | AR_PHY_EXT_MINCCA_PWR); | ||
136 | |||
137 | if (nf & 0x100) | ||
138 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
139 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
140 | "NF calibrated [ext] [chain 0] is %d\n", nf); | ||
141 | nfarray[3] = nf; | ||
142 | |||
143 | if (!AR_SREV_9285(ah)) { | ||
144 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
145 | nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), | ||
146 | AR9280_PHY_CH1_EXT_MINCCA_PWR); | ||
147 | else | ||
148 | nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), | ||
149 | AR_PHY_CH1_EXT_MINCCA_PWR); | ||
150 | |||
151 | if (nf & 0x100) | ||
152 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
153 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
154 | "NF calibrated [ext] [chain 1] is %d\n", nf); | ||
155 | nfarray[4] = nf; | ||
156 | |||
157 | if (!AR_SREV_9280(ah)) { | ||
158 | nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), | ||
159 | AR_PHY_CH2_EXT_MINCCA_PWR); | ||
160 | if (nf & 0x100) | ||
161 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
162 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
163 | "NF calibrated [ext] [chain 2] is %d\n", nf); | ||
164 | nfarray[5] = nf; | ||
165 | } | ||
166 | } | ||
167 | } | ||
168 | |||
169 | static bool getNoiseFloorThresh(struct ath_hw *ah, | ||
170 | enum ieee80211_band band, | ||
171 | int16_t *nft) | ||
172 | { | ||
173 | switch (band) { | ||
174 | case IEEE80211_BAND_5GHZ: | ||
175 | *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_5); | ||
176 | break; | ||
177 | case IEEE80211_BAND_2GHZ: | ||
178 | *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_2); | ||
179 | break; | ||
180 | default: | ||
181 | BUG_ON(1); | ||
182 | return false; | ||
183 | } | ||
184 | |||
185 | return true; | ||
186 | } | ||
187 | |||
188 | static void ath9k_hw_setup_calibration(struct ath_hw *ah, | ||
189 | struct hal_cal_list *currCal) | ||
190 | { | ||
191 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0), | ||
192 | AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX, | ||
193 | currCal->calData->calCountMax); | ||
194 | |||
195 | switch (currCal->calData->calType) { | ||
196 | case IQ_MISMATCH_CAL: | ||
197 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); | ||
198 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
199 | "starting IQ Mismatch Calibration\n"); | ||
200 | break; | ||
201 | case ADC_GAIN_CAL: | ||
202 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN); | ||
203 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
204 | "starting ADC Gain Calibration\n"); | ||
205 | break; | ||
206 | case ADC_DC_CAL: | ||
207 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER); | ||
208 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
209 | "starting ADC DC Calibration\n"); | ||
210 | break; | ||
211 | case ADC_DC_INIT_CAL: | ||
212 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT); | ||
213 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
214 | "starting Init ADC DC Calibration\n"); | ||
215 | break; | ||
216 | } | ||
217 | |||
218 | REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0), | ||
219 | AR_PHY_TIMING_CTRL4_DO_CAL); | ||
220 | } | ||
221 | |||
222 | static void ath9k_hw_reset_calibration(struct ath_hw *ah, | ||
223 | struct hal_cal_list *currCal) | ||
224 | { | ||
225 | int i; | ||
226 | |||
227 | ath9k_hw_setup_calibration(ah, currCal); | ||
228 | |||
229 | currCal->calState = CAL_RUNNING; | ||
230 | |||
231 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
232 | ah->meas0.sign[i] = 0; | ||
233 | ah->meas1.sign[i] = 0; | ||
234 | ah->meas2.sign[i] = 0; | ||
235 | ah->meas3.sign[i] = 0; | ||
236 | } | ||
237 | |||
238 | ah->cal_samples = 0; | ||
239 | } | ||
240 | |||
241 | static void ath9k_hw_per_calibration(struct ath_hw *ah, | ||
242 | struct ath9k_channel *ichan, | ||
243 | u8 rxchainmask, | ||
244 | struct hal_cal_list *currCal, | ||
245 | bool *isCalDone) | ||
246 | { | ||
247 | *isCalDone = false; | ||
248 | |||
249 | if (currCal->calState == CAL_RUNNING) { | ||
250 | if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) & | ||
251 | AR_PHY_TIMING_CTRL4_DO_CAL)) { | ||
252 | |||
253 | currCal->calData->calCollect(ah); | ||
254 | ah->cal_samples++; | ||
255 | |||
256 | if (ah->cal_samples >= currCal->calData->calNumSamples) { | ||
257 | int i, numChains = 0; | ||
258 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
259 | if (rxchainmask & (1 << i)) | ||
260 | numChains++; | ||
261 | } | ||
262 | |||
263 | currCal->calData->calPostProc(ah, numChains); | ||
264 | ichan->CalValid |= currCal->calData->calType; | ||
265 | currCal->calState = CAL_DONE; | ||
266 | *isCalDone = true; | ||
267 | } else { | ||
268 | ath9k_hw_setup_calibration(ah, currCal); | ||
269 | } | ||
270 | } | ||
271 | } else if (!(ichan->CalValid & currCal->calData->calType)) { | ||
272 | ath9k_hw_reset_calibration(ah, currCal); | ||
273 | } | ||
274 | } | ||
275 | |||
276 | /* Assumes you are talking about the currently configured channel */ | ||
277 | static bool ath9k_hw_iscal_supported(struct ath_hw *ah, | ||
278 | enum hal_cal_types calType) | ||
279 | { | ||
280 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; | ||
281 | |||
282 | switch (calType & ah->supp_cals) { | ||
283 | case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */ | ||
284 | return true; | ||
285 | case ADC_GAIN_CAL: | ||
286 | case ADC_DC_CAL: | ||
287 | if (conf->channel->band == IEEE80211_BAND_5GHZ && | ||
288 | conf_is_ht20(conf)) | ||
289 | return true; | ||
290 | break; | ||
291 | } | ||
292 | return false; | ||
293 | } | ||
294 | |||
295 | static void ath9k_hw_iqcal_collect(struct ath_hw *ah) | ||
296 | { | ||
297 | int i; | ||
298 | |||
299 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
300 | ah->totalPowerMeasI[i] += | ||
301 | REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||
302 | ah->totalPowerMeasQ[i] += | ||
303 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||
304 | ah->totalIqCorrMeas[i] += | ||
305 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||
306 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
307 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", | ||
308 | ah->cal_samples, i, ah->totalPowerMeasI[i], | ||
309 | ah->totalPowerMeasQ[i], | ||
310 | ah->totalIqCorrMeas[i]); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah) | ||
315 | { | ||
316 | int i; | ||
317 | |||
318 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
319 | ah->totalAdcIOddPhase[i] += | ||
320 | REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||
321 | ah->totalAdcIEvenPhase[i] += | ||
322 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||
323 | ah->totalAdcQOddPhase[i] += | ||
324 | REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||
325 | ah->totalAdcQEvenPhase[i] += | ||
326 | REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); | ||
327 | |||
328 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
329 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " | ||
330 | "oddq=0x%08x; evenq=0x%08x;\n", | ||
331 | ah->cal_samples, i, | ||
332 | ah->totalAdcIOddPhase[i], | ||
333 | ah->totalAdcIEvenPhase[i], | ||
334 | ah->totalAdcQOddPhase[i], | ||
335 | ah->totalAdcQEvenPhase[i]); | ||
336 | } | ||
337 | } | ||
338 | |||
339 | static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah) | ||
340 | { | ||
341 | int i; | ||
342 | |||
343 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
344 | ah->totalAdcDcOffsetIOddPhase[i] += | ||
345 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||
346 | ah->totalAdcDcOffsetIEvenPhase[i] += | ||
347 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||
348 | ah->totalAdcDcOffsetQOddPhase[i] += | ||
349 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||
350 | ah->totalAdcDcOffsetQEvenPhase[i] += | ||
351 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); | ||
352 | |||
353 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
354 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " | ||
355 | "oddq=0x%08x; evenq=0x%08x;\n", | ||
356 | ah->cal_samples, i, | ||
357 | ah->totalAdcDcOffsetIOddPhase[i], | ||
358 | ah->totalAdcDcOffsetIEvenPhase[i], | ||
359 | ah->totalAdcDcOffsetQOddPhase[i], | ||
360 | ah->totalAdcDcOffsetQEvenPhase[i]); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | ||
365 | { | ||
366 | u32 powerMeasQ, powerMeasI, iqCorrMeas; | ||
367 | u32 qCoffDenom, iCoffDenom; | ||
368 | int32_t qCoff, iCoff; | ||
369 | int iqCorrNeg, i; | ||
370 | |||
371 | for (i = 0; i < numChains; i++) { | ||
372 | powerMeasI = ah->totalPowerMeasI[i]; | ||
373 | powerMeasQ = ah->totalPowerMeasQ[i]; | ||
374 | iqCorrMeas = ah->totalIqCorrMeas[i]; | ||
375 | |||
376 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
377 | "Starting IQ Cal and Correction for Chain %d\n", | ||
378 | i); | ||
379 | |||
380 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
381 | "Orignal: Chn %diq_corr_meas = 0x%08x\n", | ||
382 | i, ah->totalIqCorrMeas[i]); | ||
383 | |||
384 | iqCorrNeg = 0; | ||
385 | |||
386 | if (iqCorrMeas > 0x80000000) { | ||
387 | iqCorrMeas = (0xffffffff - iqCorrMeas) + 1; | ||
388 | iqCorrNeg = 1; | ||
389 | } | ||
390 | |||
391 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
392 | "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI); | ||
393 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
394 | "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ); | ||
395 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n", | ||
396 | iqCorrNeg); | ||
397 | |||
398 | iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128; | ||
399 | qCoffDenom = powerMeasQ / 64; | ||
400 | |||
401 | if (powerMeasQ != 0) { | ||
402 | iCoff = iqCorrMeas / iCoffDenom; | ||
403 | qCoff = powerMeasI / qCoffDenom - 64; | ||
404 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
405 | "Chn %d iCoff = 0x%08x\n", i, iCoff); | ||
406 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
407 | "Chn %d qCoff = 0x%08x\n", i, qCoff); | ||
408 | |||
409 | iCoff = iCoff & 0x3f; | ||
410 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
411 | "New: Chn %d iCoff = 0x%08x\n", i, iCoff); | ||
412 | if (iqCorrNeg == 0x0) | ||
413 | iCoff = 0x40 - iCoff; | ||
414 | |||
415 | if (qCoff > 15) | ||
416 | qCoff = 15; | ||
417 | else if (qCoff <= -16) | ||
418 | qCoff = 16; | ||
419 | |||
420 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
421 | "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", | ||
422 | i, iCoff, qCoff); | ||
423 | |||
424 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), | ||
425 | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, | ||
426 | iCoff); | ||
427 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), | ||
428 | AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, | ||
429 | qCoff); | ||
430 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
431 | "IQ Cal and Correction done for Chain %d\n", | ||
432 | i); | ||
433 | } | ||
434 | } | ||
435 | |||
436 | REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0), | ||
437 | AR_PHY_TIMING_CTRL4_IQCORR_ENABLE); | ||
438 | } | ||
439 | |||
440 | static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains) | ||
441 | { | ||
442 | u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset; | ||
443 | u32 qGainMismatch, iGainMismatch, val, i; | ||
444 | |||
445 | for (i = 0; i < numChains; i++) { | ||
446 | iOddMeasOffset = ah->totalAdcIOddPhase[i]; | ||
447 | iEvenMeasOffset = ah->totalAdcIEvenPhase[i]; | ||
448 | qOddMeasOffset = ah->totalAdcQOddPhase[i]; | ||
449 | qEvenMeasOffset = ah->totalAdcQEvenPhase[i]; | ||
450 | |||
451 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
452 | "Starting ADC Gain Cal for Chain %d\n", i); | ||
453 | |||
454 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
455 | "Chn %d pwr_meas_odd_i = 0x%08x\n", i, | ||
456 | iOddMeasOffset); | ||
457 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
458 | "Chn %d pwr_meas_even_i = 0x%08x\n", i, | ||
459 | iEvenMeasOffset); | ||
460 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
461 | "Chn %d pwr_meas_odd_q = 0x%08x\n", i, | ||
462 | qOddMeasOffset); | ||
463 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
464 | "Chn %d pwr_meas_even_q = 0x%08x\n", i, | ||
465 | qEvenMeasOffset); | ||
466 | |||
467 | if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) { | ||
468 | iGainMismatch = | ||
469 | ((iEvenMeasOffset * 32) / | ||
470 | iOddMeasOffset) & 0x3f; | ||
471 | qGainMismatch = | ||
472 | ((qOddMeasOffset * 32) / | ||
473 | qEvenMeasOffset) & 0x3f; | ||
474 | |||
475 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
476 | "Chn %d gain_mismatch_i = 0x%08x\n", i, | ||
477 | iGainMismatch); | ||
478 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
479 | "Chn %d gain_mismatch_q = 0x%08x\n", i, | ||
480 | qGainMismatch); | ||
481 | |||
482 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); | ||
483 | val &= 0xfffff000; | ||
484 | val |= (qGainMismatch) | (iGainMismatch << 6); | ||
485 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); | ||
486 | |||
487 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
488 | "ADC Gain Cal done for Chain %d\n", i); | ||
489 | } | ||
490 | } | ||
491 | |||
492 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), | ||
493 | REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) | | ||
494 | AR_PHY_NEW_ADC_GAIN_CORR_ENABLE); | ||
495 | } | ||
496 | |||
497 | static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains) | ||
498 | { | ||
499 | u32 iOddMeasOffset, iEvenMeasOffset, val, i; | ||
500 | int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch; | ||
501 | const struct hal_percal_data *calData = | ||
502 | ah->cal_list_curr->calData; | ||
503 | u32 numSamples = | ||
504 | (1 << (calData->calCountMax + 5)) * calData->calNumSamples; | ||
505 | |||
506 | for (i = 0; i < numChains; i++) { | ||
507 | iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i]; | ||
508 | iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i]; | ||
509 | qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i]; | ||
510 | qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i]; | ||
511 | |||
512 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
513 | "Starting ADC DC Offset Cal for Chain %d\n", i); | ||
514 | |||
515 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
516 | "Chn %d pwr_meas_odd_i = %d\n", i, | ||
517 | iOddMeasOffset); | ||
518 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
519 | "Chn %d pwr_meas_even_i = %d\n", i, | ||
520 | iEvenMeasOffset); | ||
521 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
522 | "Chn %d pwr_meas_odd_q = %d\n", i, | ||
523 | qOddMeasOffset); | ||
524 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
525 | "Chn %d pwr_meas_even_q = %d\n", i, | ||
526 | qEvenMeasOffset); | ||
527 | |||
528 | iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) / | ||
529 | numSamples) & 0x1ff; | ||
530 | qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) / | ||
531 | numSamples) & 0x1ff; | ||
532 | |||
533 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
534 | "Chn %d dc_offset_mismatch_i = 0x%08x\n", i, | ||
535 | iDcMismatch); | ||
536 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
537 | "Chn %d dc_offset_mismatch_q = 0x%08x\n", i, | ||
538 | qDcMismatch); | ||
539 | |||
540 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); | ||
541 | val &= 0xc0000fff; | ||
542 | val |= (qDcMismatch << 12) | (iDcMismatch << 21); | ||
543 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); | ||
544 | |||
545 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
546 | "ADC DC Offset Cal done for Chain %d\n", i); | ||
547 | } | ||
548 | |||
549 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), | ||
550 | REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) | | ||
551 | AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE); | ||
552 | } | ||
553 | |||
554 | /* This is done for the currently configured channel */ | ||
555 | bool ath9k_hw_reset_calvalid(struct ath_hw *ah) | ||
556 | { | ||
557 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; | ||
558 | struct hal_cal_list *currCal = ah->cal_list_curr; | ||
559 | |||
560 | if (!ah->curchan) | ||
561 | return true; | ||
562 | |||
563 | if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah)) | ||
564 | return true; | ||
565 | |||
566 | if (currCal == NULL) | ||
567 | return true; | ||
568 | |||
569 | if (currCal->calState != CAL_DONE) { | ||
570 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
571 | "Calibration state incorrect, %d\n", | ||
572 | currCal->calState); | ||
573 | return true; | ||
574 | } | ||
575 | |||
576 | if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType)) | ||
577 | return true; | ||
578 | |||
579 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
580 | "Resetting Cal %d state for channel %u\n", | ||
581 | currCal->calData->calType, conf->channel->center_freq); | ||
582 | |||
583 | ah->curchan->CalValid &= ~currCal->calData->calType; | ||
584 | currCal->calState = CAL_WAITING; | ||
585 | |||
586 | return false; | ||
587 | } | ||
588 | |||
589 | void ath9k_hw_start_nfcal(struct ath_hw *ah) | ||
590 | { | ||
591 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, | ||
592 | AR_PHY_AGC_CONTROL_ENABLE_NF); | ||
593 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, | ||
594 | AR_PHY_AGC_CONTROL_NO_UPDATE_NF); | ||
595 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); | ||
596 | } | ||
597 | |||
598 | void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) | ||
599 | { | ||
600 | struct ath9k_nfcal_hist *h; | ||
601 | int i, j; | ||
602 | int32_t val; | ||
603 | const u32 ar5416_cca_regs[6] = { | ||
604 | AR_PHY_CCA, | ||
605 | AR_PHY_CH1_CCA, | ||
606 | AR_PHY_CH2_CCA, | ||
607 | AR_PHY_EXT_CCA, | ||
608 | AR_PHY_CH1_EXT_CCA, | ||
609 | AR_PHY_CH2_EXT_CCA | ||
610 | }; | ||
611 | u8 chainmask; | ||
612 | |||
613 | if (AR_SREV_9285(ah)) | ||
614 | chainmask = 0x9; | ||
615 | else if (AR_SREV_9280(ah)) | ||
616 | chainmask = 0x1B; | ||
617 | else | ||
618 | chainmask = 0x3F; | ||
619 | |||
620 | h = ah->nfCalHist; | ||
621 | |||
622 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
623 | if (chainmask & (1 << i)) { | ||
624 | val = REG_READ(ah, ar5416_cca_regs[i]); | ||
625 | val &= 0xFFFFFE00; | ||
626 | val |= (((u32) (h[i].privNF) << 1) & 0x1ff); | ||
627 | REG_WRITE(ah, ar5416_cca_regs[i], val); | ||
628 | } | ||
629 | } | ||
630 | |||
631 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
632 | AR_PHY_AGC_CONTROL_ENABLE_NF); | ||
633 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
634 | AR_PHY_AGC_CONTROL_NO_UPDATE_NF); | ||
635 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); | ||
636 | |||
637 | for (j = 0; j < 1000; j++) { | ||
638 | if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & | ||
639 | AR_PHY_AGC_CONTROL_NF) == 0) | ||
640 | break; | ||
641 | udelay(10); | ||
642 | } | ||
643 | |||
644 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
645 | if (chainmask & (1 << i)) { | ||
646 | val = REG_READ(ah, ar5416_cca_regs[i]); | ||
647 | val &= 0xFFFFFE00; | ||
648 | val |= (((u32) (-50) << 1) & 0x1ff); | ||
649 | REG_WRITE(ah, ar5416_cca_regs[i], val); | ||
650 | } | ||
651 | } | ||
652 | } | ||
653 | |||
654 | int16_t ath9k_hw_getnf(struct ath_hw *ah, | ||
655 | struct ath9k_channel *chan) | ||
656 | { | ||
657 | int16_t nf, nfThresh; | ||
658 | int16_t nfarray[NUM_NF_READINGS] = { 0 }; | ||
659 | struct ath9k_nfcal_hist *h; | ||
660 | struct ieee80211_channel *c = chan->chan; | ||
661 | |||
662 | chan->channelFlags &= (~CHANNEL_CW_INT); | ||
663 | if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { | ||
664 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
665 | "NF did not complete in calibration window\n"); | ||
666 | nf = 0; | ||
667 | chan->rawNoiseFloor = nf; | ||
668 | return chan->rawNoiseFloor; | ||
669 | } else { | ||
670 | ath9k_hw_do_getnf(ah, nfarray); | ||
671 | nf = nfarray[0]; | ||
672 | if (getNoiseFloorThresh(ah, c->band, &nfThresh) | ||
673 | && nf > nfThresh) { | ||
674 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
675 | "noise floor failed detected; " | ||
676 | "detected %d, threshold %d\n", | ||
677 | nf, nfThresh); | ||
678 | chan->channelFlags |= CHANNEL_CW_INT; | ||
679 | } | ||
680 | } | ||
681 | |||
682 | h = ah->nfCalHist; | ||
683 | |||
684 | ath9k_hw_update_nfcal_hist_buffer(h, nfarray); | ||
685 | chan->rawNoiseFloor = h[0].privNF; | ||
686 | |||
687 | return chan->rawNoiseFloor; | ||
688 | } | ||
689 | |||
690 | void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah) | ||
691 | { | ||
692 | int i, j; | ||
693 | |||
694 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
695 | ah->nfCalHist[i].currIndex = 0; | ||
696 | ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE; | ||
697 | ah->nfCalHist[i].invalidNFcount = | ||
698 | AR_PHY_CCA_FILTERWINDOW_LENGTH; | ||
699 | for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) { | ||
700 | ah->nfCalHist[i].nfCalBuffer[j] = | ||
701 | AR_PHY_CCA_MAX_GOOD_VALUE; | ||
702 | } | ||
703 | } | ||
704 | } | ||
705 | |||
706 | s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) | ||
707 | { | ||
708 | s16 nf; | ||
709 | |||
710 | if (chan->rawNoiseFloor == 0) | ||
711 | nf = -96; | ||
712 | else | ||
713 | nf = chan->rawNoiseFloor; | ||
714 | |||
715 | if (!ath9k_hw_nf_in_range(ah, nf)) | ||
716 | nf = ATH_DEFAULT_NOISE_FLOOR; | ||
717 | |||
718 | return nf; | ||
719 | } | ||
720 | |||
721 | static void ath9k_olc_temp_compensation(struct ath_hw *ah) | ||
722 | { | ||
723 | u32 rddata, i; | ||
724 | int delta, currPDADC, regval; | ||
725 | |||
726 | rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4); | ||
727 | |||
728 | currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT); | ||
729 | |||
730 | if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G)) | ||
731 | delta = (currPDADC - ah->initPDADC + 4) / 8; | ||
732 | else | ||
733 | delta = (currPDADC - ah->initPDADC + 5) / 10; | ||
734 | |||
735 | if (delta != ah->PDADCdelta) { | ||
736 | ah->PDADCdelta = delta; | ||
737 | for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) { | ||
738 | regval = ah->originalGain[i] - delta; | ||
739 | if (regval < 0) | ||
740 | regval = 0; | ||
741 | |||
742 | REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4, | ||
743 | AR_PHY_TX_GAIN, regval); | ||
744 | } | ||
745 | } | ||
746 | } | ||
747 | |||
748 | static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah) | ||
749 | { | ||
750 | |||
751 | u32 regVal; | ||
752 | int i, offset, offs_6_1, offs_0; | ||
753 | u32 ccomp_org, reg_field; | ||
754 | u32 regList[][2] = { | ||
755 | { 0x786c, 0 }, | ||
756 | { 0x7854, 0 }, | ||
757 | { 0x7820, 0 }, | ||
758 | { 0x7824, 0 }, | ||
759 | { 0x7868, 0 }, | ||
760 | { 0x783c, 0 }, | ||
761 | { 0x7838, 0 }, | ||
762 | }; | ||
763 | |||
764 | if (AR_SREV_9285_11(ah)) { | ||
765 | REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); | ||
766 | udelay(10); | ||
767 | } | ||
768 | |||
769 | for (i = 0; i < ARRAY_SIZE(regList); i++) | ||
770 | regList[i][1] = REG_READ(ah, regList[i][0]); | ||
771 | |||
772 | regVal = REG_READ(ah, 0x7834); | ||
773 | regVal &= (~(0x1)); | ||
774 | REG_WRITE(ah, 0x7834, regVal); | ||
775 | regVal = REG_READ(ah, 0x9808); | ||
776 | regVal |= (0x1 << 27); | ||
777 | REG_WRITE(ah, 0x9808, regVal); | ||
778 | |||
779 | REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1); | ||
780 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1); | ||
781 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1); | ||
782 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1); | ||
783 | REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0); | ||
784 | REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0); | ||
785 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0); | ||
786 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 1); | ||
787 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0); | ||
788 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0); | ||
789 | REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7); | ||
790 | REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0); | ||
791 | ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP); | ||
792 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 7); | ||
793 | |||
794 | REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0); | ||
795 | udelay(30); | ||
796 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0); | ||
797 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0); | ||
798 | |||
799 | for (i = 6; i > 0; i--) { | ||
800 | regVal = REG_READ(ah, 0x7834); | ||
801 | regVal |= (1 << (19 + i)); | ||
802 | REG_WRITE(ah, 0x7834, regVal); | ||
803 | udelay(1); | ||
804 | regVal = REG_READ(ah, 0x7834); | ||
805 | regVal &= (~(0x1 << (19 + i))); | ||
806 | reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9); | ||
807 | regVal |= (reg_field << (19 + i)); | ||
808 | REG_WRITE(ah, 0x7834, regVal); | ||
809 | } | ||
810 | |||
811 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1); | ||
812 | udelay(1); | ||
813 | reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9); | ||
814 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field); | ||
815 | offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS); | ||
816 | offs_0 = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP); | ||
817 | |||
818 | offset = (offs_6_1<<1) | offs_0; | ||
819 | offset = offset - 0; | ||
820 | offs_6_1 = offset>>1; | ||
821 | offs_0 = offset & 1; | ||
822 | |||
823 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1); | ||
824 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0); | ||
825 | |||
826 | regVal = REG_READ(ah, 0x7834); | ||
827 | regVal |= 0x1; | ||
828 | REG_WRITE(ah, 0x7834, regVal); | ||
829 | regVal = REG_READ(ah, 0x9808); | ||
830 | regVal &= (~(0x1 << 27)); | ||
831 | REG_WRITE(ah, 0x9808, regVal); | ||
832 | |||
833 | for (i = 0; i < ARRAY_SIZE(regList); i++) | ||
834 | REG_WRITE(ah, regList[i][0], regList[i][1]); | ||
835 | |||
836 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org); | ||
837 | |||
838 | if (AR_SREV_9285_11(ah)) | ||
839 | REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); | ||
840 | |||
841 | } | ||
842 | |||
843 | bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, | ||
844 | u8 rxchainmask, bool longcal, | ||
845 | bool *isCalDone) | ||
846 | { | ||
847 | struct hal_cal_list *currCal = ah->cal_list_curr; | ||
848 | |||
849 | *isCalDone = true; | ||
850 | |||
851 | if (currCal && | ||
852 | (currCal->calState == CAL_RUNNING || | ||
853 | currCal->calState == CAL_WAITING)) { | ||
854 | ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal, | ||
855 | isCalDone); | ||
856 | if (*isCalDone) { | ||
857 | ah->cal_list_curr = currCal = currCal->calNext; | ||
858 | |||
859 | if (currCal->calState == CAL_WAITING) { | ||
860 | *isCalDone = false; | ||
861 | ath9k_hw_reset_calibration(ah, currCal); | ||
862 | } | ||
863 | } | ||
864 | } | ||
865 | |||
866 | if (longcal) { | ||
867 | if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah)) | ||
868 | ath9k_hw_9285_pa_cal(ah); | ||
869 | |||
870 | if (OLC_FOR_AR9280_20_LATER) | ||
871 | ath9k_olc_temp_compensation(ah); | ||
872 | ath9k_hw_getnf(ah, chan); | ||
873 | ath9k_hw_loadnf(ah, ah->curchan); | ||
874 | ath9k_hw_start_nfcal(ah); | ||
875 | |||
876 | if (chan->channelFlags & CHANNEL_CW_INT) | ||
877 | chan->channelFlags &= ~CHANNEL_CW_INT; | ||
878 | } | ||
879 | |||
880 | return true; | ||
881 | } | ||
882 | |||
883 | static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan) | ||
884 | { | ||
885 | REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); | ||
886 | if (chan->channelFlags & CHANNEL_HT20) { | ||
887 | REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE); | ||
888 | REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN); | ||
889 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
890 | AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
891 | REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE); | ||
892 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); | ||
893 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, | ||
894 | AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) { | ||
895 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset " | ||
896 | "calibration failed to complete in " | ||
897 | "1ms; noisy ??\n"); | ||
898 | return false; | ||
899 | } | ||
900 | REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN); | ||
901 | REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE); | ||
902 | REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); | ||
903 | } | ||
904 | REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); | ||
905 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
906 | REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE); | ||
907 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); | ||
908 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, | ||
909 | 0, AH_WAIT_TIMEOUT)) { | ||
910 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset calibration " | ||
911 | "failed to complete in 1ms; noisy ??\n"); | ||
912 | return false; | ||
913 | } | ||
914 | |||
915 | REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); | ||
916 | REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); | ||
917 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
918 | |||
919 | return true; | ||
920 | } | ||
921 | |||
922 | bool ath9k_hw_init_cal(struct ath_hw *ah, | ||
923 | struct ath9k_channel *chan) | ||
924 | { | ||
925 | if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) { | ||
926 | if (!ar9285_clc(ah, chan)) | ||
927 | return false; | ||
928 | } else if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
929 | REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); | ||
930 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
931 | REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); | ||
932 | |||
933 | /* Kick off the cal */ | ||
934 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | ||
935 | REG_READ(ah, AR_PHY_AGC_CONTROL) | | ||
936 | AR_PHY_AGC_CONTROL_CAL); | ||
937 | |||
938 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, | ||
939 | AR_PHY_AGC_CONTROL_CAL, 0, | ||
940 | AH_WAIT_TIMEOUT)) { | ||
941 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
942 | "offset calibration failed to complete in 1ms; " | ||
943 | "noisy environment?\n"); | ||
944 | return false; | ||
945 | } | ||
946 | |||
947 | REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); | ||
948 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
949 | REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); | ||
950 | } | ||
951 | |||
952 | /* Calibrate the AGC */ | ||
953 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | ||
954 | REG_READ(ah, AR_PHY_AGC_CONTROL) | | ||
955 | AR_PHY_AGC_CONTROL_CAL); | ||
956 | |||
957 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, | ||
958 | 0, AH_WAIT_TIMEOUT)) { | ||
959 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
960 | "offset calibration failed to complete in 1ms; " | ||
961 | "noisy environment?\n"); | ||
962 | return false; | ||
963 | } | ||
964 | |||
965 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
966 | REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); | ||
967 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
968 | } | ||
969 | |||
970 | /* Do PA Calibration */ | ||
971 | if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah)) | ||
972 | ath9k_hw_9285_pa_cal(ah); | ||
973 | |||
974 | /* Do NF Calibration */ | ||
975 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | ||
976 | REG_READ(ah, AR_PHY_AGC_CONTROL) | | ||
977 | AR_PHY_AGC_CONTROL_NF); | ||
978 | |||
979 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; | ||
980 | |||
981 | if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { | ||
982 | if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) { | ||
983 | INIT_CAL(&ah->adcgain_caldata); | ||
984 | INSERT_CAL(ah, &ah->adcgain_caldata); | ||
985 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
986 | "enabling ADC Gain Calibration.\n"); | ||
987 | } | ||
988 | if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) { | ||
989 | INIT_CAL(&ah->adcdc_caldata); | ||
990 | INSERT_CAL(ah, &ah->adcdc_caldata); | ||
991 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
992 | "enabling ADC DC Calibration.\n"); | ||
993 | } | ||
994 | if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { | ||
995 | INIT_CAL(&ah->iq_caldata); | ||
996 | INSERT_CAL(ah, &ah->iq_caldata); | ||
997 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
998 | "enabling IQ Calibration.\n"); | ||
999 | } | ||
1000 | |||
1001 | ah->cal_list_curr = ah->cal_list; | ||
1002 | |||
1003 | if (ah->cal_list_curr) | ||
1004 | ath9k_hw_reset_calibration(ah, ah->cal_list_curr); | ||
1005 | } | ||
1006 | |||
1007 | chan->CalValid = 0; | ||
1008 | |||
1009 | return true; | ||
1010 | } | ||
1011 | |||
1012 | const struct hal_percal_data iq_cal_multi_sample = { | ||
1013 | IQ_MISMATCH_CAL, | ||
1014 | MAX_CAL_SAMPLES, | ||
1015 | PER_MIN_LOG_COUNT, | ||
1016 | ath9k_hw_iqcal_collect, | ||
1017 | ath9k_hw_iqcalibrate | ||
1018 | }; | ||
1019 | const struct hal_percal_data iq_cal_single_sample = { | ||
1020 | IQ_MISMATCH_CAL, | ||
1021 | MIN_CAL_SAMPLES, | ||
1022 | PER_MAX_LOG_COUNT, | ||
1023 | ath9k_hw_iqcal_collect, | ||
1024 | ath9k_hw_iqcalibrate | ||
1025 | }; | ||
1026 | const struct hal_percal_data adc_gain_cal_multi_sample = { | ||
1027 | ADC_GAIN_CAL, | ||
1028 | MAX_CAL_SAMPLES, | ||
1029 | PER_MIN_LOG_COUNT, | ||
1030 | ath9k_hw_adc_gaincal_collect, | ||
1031 | ath9k_hw_adc_gaincal_calibrate | ||
1032 | }; | ||
1033 | const struct hal_percal_data adc_gain_cal_single_sample = { | ||
1034 | ADC_GAIN_CAL, | ||
1035 | MIN_CAL_SAMPLES, | ||
1036 | PER_MAX_LOG_COUNT, | ||
1037 | ath9k_hw_adc_gaincal_collect, | ||
1038 | ath9k_hw_adc_gaincal_calibrate | ||
1039 | }; | ||
1040 | const struct hal_percal_data adc_dc_cal_multi_sample = { | ||
1041 | ADC_DC_CAL, | ||
1042 | MAX_CAL_SAMPLES, | ||
1043 | PER_MIN_LOG_COUNT, | ||
1044 | ath9k_hw_adc_dccal_collect, | ||
1045 | ath9k_hw_adc_dccal_calibrate | ||
1046 | }; | ||
1047 | const struct hal_percal_data adc_dc_cal_single_sample = { | ||
1048 | ADC_DC_CAL, | ||
1049 | MIN_CAL_SAMPLES, | ||
1050 | PER_MAX_LOG_COUNT, | ||
1051 | ath9k_hw_adc_dccal_collect, | ||
1052 | ath9k_hw_adc_dccal_calibrate | ||
1053 | }; | ||
1054 | const struct hal_percal_data adc_init_dc_cal = { | ||
1055 | ADC_DC_INIT_CAL, | ||
1056 | MIN_CAL_SAMPLES, | ||
1057 | INIT_LOG_COUNT, | ||
1058 | ath9k_hw_adc_dccal_collect, | ||
1059 | ath9k_hw_adc_dccal_calibrate | ||
1060 | }; | ||
diff --git a/drivers/net/wireless/ath9k/calib.h b/drivers/net/wireless/ath9k/calib.h deleted file mode 100644 index 1c74bd50700d..000000000000 --- a/drivers/net/wireless/ath9k/calib.h +++ /dev/null | |||
@@ -1,124 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 CALIB_H | ||
18 | #define CALIB_H | ||
19 | |||
20 | extern const struct hal_percal_data iq_cal_multi_sample; | ||
21 | extern const struct hal_percal_data iq_cal_single_sample; | ||
22 | extern const struct hal_percal_data adc_gain_cal_multi_sample; | ||
23 | extern const struct hal_percal_data adc_gain_cal_single_sample; | ||
24 | extern const struct hal_percal_data adc_dc_cal_multi_sample; | ||
25 | extern const struct hal_percal_data adc_dc_cal_single_sample; | ||
26 | extern const struct hal_percal_data adc_init_dc_cal; | ||
27 | |||
28 | #define AR_PHY_CCA_MAX_GOOD_VALUE -85 | ||
29 | #define AR_PHY_CCA_MAX_HIGH_VALUE -62 | ||
30 | #define AR_PHY_CCA_MIN_BAD_VALUE -140 | ||
31 | #define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3 | ||
32 | #define AR_PHY_CCA_FILTERWINDOW_LENGTH 5 | ||
33 | |||
34 | #define NUM_NF_READINGS 6 | ||
35 | #define ATH9K_NF_CAL_HIST_MAX 5 | ||
36 | |||
37 | struct ar5416IniArray { | ||
38 | u32 *ia_array; | ||
39 | u32 ia_rows; | ||
40 | u32 ia_columns; | ||
41 | }; | ||
42 | |||
43 | #define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \ | ||
44 | (iniarray)->ia_array = (u32 *)(array); \ | ||
45 | (iniarray)->ia_rows = (rows); \ | ||
46 | (iniarray)->ia_columns = (columns); \ | ||
47 | } while (0) | ||
48 | |||
49 | #define INI_RA(iniarray, row, column) \ | ||
50 | (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)]) | ||
51 | |||
52 | #define INIT_CAL(_perCal) do { \ | ||
53 | (_perCal)->calState = CAL_WAITING; \ | ||
54 | (_perCal)->calNext = NULL; \ | ||
55 | } while (0) | ||
56 | |||
57 | #define INSERT_CAL(_ahp, _perCal) \ | ||
58 | do { \ | ||
59 | if ((_ahp)->cal_list_last == NULL) { \ | ||
60 | (_ahp)->cal_list = \ | ||
61 | (_ahp)->cal_list_last = (_perCal); \ | ||
62 | ((_ahp)->cal_list_last)->calNext = (_perCal); \ | ||
63 | } else { \ | ||
64 | ((_ahp)->cal_list_last)->calNext = (_perCal); \ | ||
65 | (_ahp)->cal_list_last = (_perCal); \ | ||
66 | (_perCal)->calNext = (_ahp)->cal_list; \ | ||
67 | } \ | ||
68 | } while (0) | ||
69 | |||
70 | enum hal_cal_types { | ||
71 | ADC_DC_INIT_CAL = 0x1, | ||
72 | ADC_GAIN_CAL = 0x2, | ||
73 | ADC_DC_CAL = 0x4, | ||
74 | IQ_MISMATCH_CAL = 0x8 | ||
75 | }; | ||
76 | |||
77 | enum hal_cal_state { | ||
78 | CAL_INACTIVE, | ||
79 | CAL_WAITING, | ||
80 | CAL_RUNNING, | ||
81 | CAL_DONE | ||
82 | }; | ||
83 | |||
84 | #define MIN_CAL_SAMPLES 1 | ||
85 | #define MAX_CAL_SAMPLES 64 | ||
86 | #define INIT_LOG_COUNT 5 | ||
87 | #define PER_MIN_LOG_COUNT 2 | ||
88 | #define PER_MAX_LOG_COUNT 10 | ||
89 | |||
90 | struct hal_percal_data { | ||
91 | enum hal_cal_types calType; | ||
92 | u32 calNumSamples; | ||
93 | u32 calCountMax; | ||
94 | void (*calCollect) (struct ath_hw *); | ||
95 | void (*calPostProc) (struct ath_hw *, u8); | ||
96 | }; | ||
97 | |||
98 | struct hal_cal_list { | ||
99 | const struct hal_percal_data *calData; | ||
100 | enum hal_cal_state calState; | ||
101 | struct hal_cal_list *calNext; | ||
102 | }; | ||
103 | |||
104 | struct ath9k_nfcal_hist { | ||
105 | int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX]; | ||
106 | u8 currIndex; | ||
107 | int16_t privNF; | ||
108 | u8 invalidNFcount; | ||
109 | }; | ||
110 | |||
111 | bool ath9k_hw_reset_calvalid(struct ath_hw *ah); | ||
112 | void ath9k_hw_start_nfcal(struct ath_hw *ah); | ||
113 | void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan); | ||
114 | int16_t ath9k_hw_getnf(struct ath_hw *ah, | ||
115 | struct ath9k_channel *chan); | ||
116 | void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah); | ||
117 | s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan); | ||
118 | bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, | ||
119 | u8 rxchainmask, bool longcal, | ||
120 | bool *isCalDone); | ||
121 | bool ath9k_hw_init_cal(struct ath_hw *ah, | ||
122 | struct ath9k_channel *chan); | ||
123 | |||
124 | #endif /* CALIB_H */ | ||
diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath9k/debug.c deleted file mode 100644 index 97df20cbf528..000000000000 --- a/drivers/net/wireless/ath9k/debug.c +++ /dev/null | |||
@@ -1,562 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 <asm/unaligned.h> | ||
18 | |||
19 | #include "ath9k.h" | ||
20 | |||
21 | static unsigned int ath9k_debug = DBG_DEFAULT; | ||
22 | module_param_named(debug, ath9k_debug, uint, 0); | ||
23 | |||
24 | static struct dentry *ath9k_debugfs_root; | ||
25 | |||
26 | void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...) | ||
27 | { | ||
28 | if (!sc) | ||
29 | return; | ||
30 | |||
31 | if (sc->debug.debug_mask & dbg_mask) { | ||
32 | va_list args; | ||
33 | |||
34 | va_start(args, fmt); | ||
35 | printk(KERN_DEBUG "ath9k: "); | ||
36 | vprintk(fmt, args); | ||
37 | va_end(args); | ||
38 | } | ||
39 | } | ||
40 | |||
41 | static int ath9k_debugfs_open(struct inode *inode, struct file *file) | ||
42 | { | ||
43 | file->private_data = inode->i_private; | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | static ssize_t read_file_dma(struct file *file, char __user *user_buf, | ||
48 | size_t count, loff_t *ppos) | ||
49 | { | ||
50 | struct ath_softc *sc = file->private_data; | ||
51 | struct ath_hw *ah = sc->sc_ah; | ||
52 | char buf[1024]; | ||
53 | unsigned int len = 0; | ||
54 | u32 val[ATH9K_NUM_DMA_DEBUG_REGS]; | ||
55 | int i, qcuOffset = 0, dcuOffset = 0; | ||
56 | u32 *qcuBase = &val[0], *dcuBase = &val[4]; | ||
57 | |||
58 | REG_WRITE(ah, AR_MACMISC, | ||
59 | ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) | | ||
60 | (AR_MACMISC_MISC_OBS_BUS_1 << | ||
61 | AR_MACMISC_MISC_OBS_BUS_MSB_S))); | ||
62 | |||
63 | len += snprintf(buf + len, sizeof(buf) - len, | ||
64 | "Raw DMA Debug values:\n"); | ||
65 | |||
66 | for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) { | ||
67 | if (i % 4 == 0) | ||
68 | len += snprintf(buf + len, sizeof(buf) - len, "\n"); | ||
69 | |||
70 | val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32))); | ||
71 | len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ", | ||
72 | i, val[i]); | ||
73 | } | ||
74 | |||
75 | len += snprintf(buf + len, sizeof(buf) - len, "\n\n"); | ||
76 | len += snprintf(buf + len, sizeof(buf) - len, | ||
77 | "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); | ||
78 | |||
79 | for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) { | ||
80 | if (i == 8) { | ||
81 | qcuOffset = 0; | ||
82 | qcuBase++; | ||
83 | } | ||
84 | |||
85 | if (i == 6) { | ||
86 | dcuOffset = 0; | ||
87 | dcuBase++; | ||
88 | } | ||
89 | |||
90 | len += snprintf(buf + len, sizeof(buf) - len, | ||
91 | "%2d %2x %1x %2x %2x\n", | ||
92 | i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, | ||
93 | (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3), | ||
94 | val[2] & (0x7 << (i * 3)) >> (i * 3), | ||
95 | (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); | ||
96 | } | ||
97 | |||
98 | len += snprintf(buf + len, sizeof(buf) - len, "\n"); | ||
99 | |||
100 | len += snprintf(buf + len, sizeof(buf) - len, | ||
101 | "qcu_stitch state: %2x qcu_fetch state: %2x\n", | ||
102 | (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22); | ||
103 | len += snprintf(buf + len, sizeof(buf) - len, | ||
104 | "qcu_complete state: %2x dcu_complete state: %2x\n", | ||
105 | (val[3] & 0x1c000000) >> 26, (val[6] & 0x3)); | ||
106 | len += snprintf(buf + len, sizeof(buf) - len, | ||
107 | "dcu_arb state: %2x dcu_fp state: %2x\n", | ||
108 | (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27); | ||
109 | len += snprintf(buf + len, sizeof(buf) - len, | ||
110 | "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n", | ||
111 | (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10); | ||
112 | len += snprintf(buf + len, sizeof(buf) - len, | ||
113 | "txfifo_valid_0: %1d txfifo_valid_1: %1d\n", | ||
114 | (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12); | ||
115 | len += snprintf(buf + len, sizeof(buf) - len, | ||
116 | "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", | ||
117 | (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); | ||
118 | |||
119 | len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n", | ||
120 | REG_READ(ah, AR_OBS_BUS_1)); | ||
121 | len += snprintf(buf + len, sizeof(buf) - len, | ||
122 | "AR_CR: 0x%x \n", REG_READ(ah, AR_CR)); | ||
123 | |||
124 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
125 | } | ||
126 | |||
127 | static const struct file_operations fops_dma = { | ||
128 | .read = read_file_dma, | ||
129 | .open = ath9k_debugfs_open, | ||
130 | .owner = THIS_MODULE | ||
131 | }; | ||
132 | |||
133 | |||
134 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) | ||
135 | { | ||
136 | if (status) | ||
137 | sc->debug.stats.istats.total++; | ||
138 | if (status & ATH9K_INT_RX) | ||
139 | sc->debug.stats.istats.rxok++; | ||
140 | if (status & ATH9K_INT_RXEOL) | ||
141 | sc->debug.stats.istats.rxeol++; | ||
142 | if (status & ATH9K_INT_RXORN) | ||
143 | sc->debug.stats.istats.rxorn++; | ||
144 | if (status & ATH9K_INT_TX) | ||
145 | sc->debug.stats.istats.txok++; | ||
146 | if (status & ATH9K_INT_TXURN) | ||
147 | sc->debug.stats.istats.txurn++; | ||
148 | if (status & ATH9K_INT_MIB) | ||
149 | sc->debug.stats.istats.mib++; | ||
150 | if (status & ATH9K_INT_RXPHY) | ||
151 | sc->debug.stats.istats.rxphyerr++; | ||
152 | if (status & ATH9K_INT_RXKCM) | ||
153 | sc->debug.stats.istats.rx_keycache_miss++; | ||
154 | if (status & ATH9K_INT_SWBA) | ||
155 | sc->debug.stats.istats.swba++; | ||
156 | if (status & ATH9K_INT_BMISS) | ||
157 | sc->debug.stats.istats.bmiss++; | ||
158 | if (status & ATH9K_INT_BNR) | ||
159 | sc->debug.stats.istats.bnr++; | ||
160 | if (status & ATH9K_INT_CST) | ||
161 | sc->debug.stats.istats.cst++; | ||
162 | if (status & ATH9K_INT_GTT) | ||
163 | sc->debug.stats.istats.gtt++; | ||
164 | if (status & ATH9K_INT_TIM) | ||
165 | sc->debug.stats.istats.tim++; | ||
166 | if (status & ATH9K_INT_CABEND) | ||
167 | sc->debug.stats.istats.cabend++; | ||
168 | if (status & ATH9K_INT_DTIMSYNC) | ||
169 | sc->debug.stats.istats.dtimsync++; | ||
170 | if (status & ATH9K_INT_DTIM) | ||
171 | sc->debug.stats.istats.dtim++; | ||
172 | } | ||
173 | |||
174 | static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, | ||
175 | size_t count, loff_t *ppos) | ||
176 | { | ||
177 | struct ath_softc *sc = file->private_data; | ||
178 | char buf[512]; | ||
179 | unsigned int len = 0; | ||
180 | |||
181 | len += snprintf(buf + len, sizeof(buf) - len, | ||
182 | "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok); | ||
183 | len += snprintf(buf + len, sizeof(buf) - len, | ||
184 | "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol); | ||
185 | len += snprintf(buf + len, sizeof(buf) - len, | ||
186 | "%8s: %10u\n", "RXORN", sc->debug.stats.istats.rxorn); | ||
187 | len += snprintf(buf + len, sizeof(buf) - len, | ||
188 | "%8s: %10u\n", "TX", sc->debug.stats.istats.txok); | ||
189 | len += snprintf(buf + len, sizeof(buf) - len, | ||
190 | "%8s: %10u\n", "TXURN", sc->debug.stats.istats.txurn); | ||
191 | len += snprintf(buf + len, sizeof(buf) - len, | ||
192 | "%8s: %10u\n", "MIB", sc->debug.stats.istats.mib); | ||
193 | len += snprintf(buf + len, sizeof(buf) - len, | ||
194 | "%8s: %10u\n", "RXPHY", sc->debug.stats.istats.rxphyerr); | ||
195 | len += snprintf(buf + len, sizeof(buf) - len, | ||
196 | "%8s: %10u\n", "RXKCM", sc->debug.stats.istats.rx_keycache_miss); | ||
197 | len += snprintf(buf + len, sizeof(buf) - len, | ||
198 | "%8s: %10u\n", "SWBA", sc->debug.stats.istats.swba); | ||
199 | len += snprintf(buf + len, sizeof(buf) - len, | ||
200 | "%8s: %10u\n", "BMISS", sc->debug.stats.istats.bmiss); | ||
201 | len += snprintf(buf + len, sizeof(buf) - len, | ||
202 | "%8s: %10u\n", "BNR", sc->debug.stats.istats.bnr); | ||
203 | len += snprintf(buf + len, sizeof(buf) - len, | ||
204 | "%8s: %10u\n", "CST", sc->debug.stats.istats.cst); | ||
205 | len += snprintf(buf + len, sizeof(buf) - len, | ||
206 | "%8s: %10u\n", "GTT", sc->debug.stats.istats.gtt); | ||
207 | len += snprintf(buf + len, sizeof(buf) - len, | ||
208 | "%8s: %10u\n", "TIM", sc->debug.stats.istats.tim); | ||
209 | len += snprintf(buf + len, sizeof(buf) - len, | ||
210 | "%8s: %10u\n", "CABEND", sc->debug.stats.istats.cabend); | ||
211 | len += snprintf(buf + len, sizeof(buf) - len, | ||
212 | "%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync); | ||
213 | len += snprintf(buf + len, sizeof(buf) - len, | ||
214 | "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim); | ||
215 | len += snprintf(buf + len, sizeof(buf) - len, | ||
216 | "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total); | ||
217 | |||
218 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
219 | } | ||
220 | |||
221 | static const struct file_operations fops_interrupt = { | ||
222 | .read = read_file_interrupt, | ||
223 | .open = ath9k_debugfs_open, | ||
224 | .owner = THIS_MODULE | ||
225 | }; | ||
226 | |||
227 | static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb) | ||
228 | { | ||
229 | struct ath_tx_info_priv *tx_info_priv = NULL; | ||
230 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
231 | struct ieee80211_tx_rate *rates = tx_info->status.rates; | ||
232 | int final_ts_idx, idx; | ||
233 | |||
234 | tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
235 | final_ts_idx = tx_info_priv->tx.ts_rateindex; | ||
236 | idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate; | ||
237 | |||
238 | sc->debug.stats.n_rcstats[idx].success++; | ||
239 | } | ||
240 | |||
241 | static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb) | ||
242 | { | ||
243 | struct ath_tx_info_priv *tx_info_priv = NULL; | ||
244 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
245 | struct ieee80211_tx_rate *rates = tx_info->status.rates; | ||
246 | int final_ts_idx, idx; | ||
247 | |||
248 | tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
249 | final_ts_idx = tx_info_priv->tx.ts_rateindex; | ||
250 | idx = rates[final_ts_idx].idx; | ||
251 | |||
252 | sc->debug.stats.legacy_rcstats[idx].success++; | ||
253 | } | ||
254 | |||
255 | void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb) | ||
256 | { | ||
257 | if (conf_is_ht(&sc->hw->conf)) | ||
258 | ath_debug_stat_11n_rc(sc, skb); | ||
259 | else | ||
260 | ath_debug_stat_legacy_rc(sc, skb); | ||
261 | } | ||
262 | |||
263 | /* FIXME: legacy rates, later on .. */ | ||
264 | void ath_debug_stat_retries(struct ath_softc *sc, int rix, | ||
265 | int xretries, int retries, u8 per) | ||
266 | { | ||
267 | if (conf_is_ht(&sc->hw->conf)) { | ||
268 | int idx = sc->cur_rate_table->info[rix].dot11rate; | ||
269 | |||
270 | sc->debug.stats.n_rcstats[idx].xretries += xretries; | ||
271 | sc->debug.stats.n_rcstats[idx].retries += retries; | ||
272 | sc->debug.stats.n_rcstats[idx].per = per; | ||
273 | } | ||
274 | } | ||
275 | |||
276 | static ssize_t ath_read_file_stat_11n_rc(struct file *file, | ||
277 | char __user *user_buf, | ||
278 | size_t count, loff_t *ppos) | ||
279 | { | ||
280 | struct ath_softc *sc = file->private_data; | ||
281 | char buf[1024]; | ||
282 | unsigned int len = 0; | ||
283 | int i = 0; | ||
284 | |||
285 | len += sprintf(buf, "%7s %13s %8s %8s %6s\n\n", "Rate", "Success", | ||
286 | "Retries", "XRetries", "PER"); | ||
287 | |||
288 | for (i = 0; i <= 15; i++) { | ||
289 | len += snprintf(buf + len, sizeof(buf) - len, | ||
290 | "%5s%3d: %8u %8u %8u %8u\n", "MCS", i, | ||
291 | sc->debug.stats.n_rcstats[i].success, | ||
292 | sc->debug.stats.n_rcstats[i].retries, | ||
293 | sc->debug.stats.n_rcstats[i].xretries, | ||
294 | sc->debug.stats.n_rcstats[i].per); | ||
295 | } | ||
296 | |||
297 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
298 | } | ||
299 | |||
300 | static ssize_t ath_read_file_stat_legacy_rc(struct file *file, | ||
301 | char __user *user_buf, | ||
302 | size_t count, loff_t *ppos) | ||
303 | { | ||
304 | struct ath_softc *sc = file->private_data; | ||
305 | char buf[512]; | ||
306 | unsigned int len = 0; | ||
307 | int i = 0; | ||
308 | |||
309 | len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success"); | ||
310 | |||
311 | for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) { | ||
312 | len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n", | ||
313 | sc->cur_rate_table->info[i].ratekbps / 1000, | ||
314 | sc->debug.stats.legacy_rcstats[i].success); | ||
315 | } | ||
316 | |||
317 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
318 | } | ||
319 | |||
320 | static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, | ||
321 | size_t count, loff_t *ppos) | ||
322 | { | ||
323 | struct ath_softc *sc = file->private_data; | ||
324 | |||
325 | if (sc->cur_rate_table == NULL) | ||
326 | return 0; | ||
327 | |||
328 | if (conf_is_ht(&sc->hw->conf)) | ||
329 | return ath_read_file_stat_11n_rc(file, user_buf, count, ppos); | ||
330 | else | ||
331 | return ath_read_file_stat_legacy_rc(file, user_buf, count ,ppos); | ||
332 | } | ||
333 | |||
334 | static const struct file_operations fops_rcstat = { | ||
335 | .read = read_file_rcstat, | ||
336 | .open = ath9k_debugfs_open, | ||
337 | .owner = THIS_MODULE | ||
338 | }; | ||
339 | |||
340 | static const char * ath_wiphy_state_str(enum ath_wiphy_state state) | ||
341 | { | ||
342 | switch (state) { | ||
343 | case ATH_WIPHY_INACTIVE: | ||
344 | return "INACTIVE"; | ||
345 | case ATH_WIPHY_ACTIVE: | ||
346 | return "ACTIVE"; | ||
347 | case ATH_WIPHY_PAUSING: | ||
348 | return "PAUSING"; | ||
349 | case ATH_WIPHY_PAUSED: | ||
350 | return "PAUSED"; | ||
351 | case ATH_WIPHY_SCAN: | ||
352 | return "SCAN"; | ||
353 | } | ||
354 | return "?"; | ||
355 | } | ||
356 | |||
357 | static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, | ||
358 | size_t count, loff_t *ppos) | ||
359 | { | ||
360 | struct ath_softc *sc = file->private_data; | ||
361 | char buf[512]; | ||
362 | unsigned int len = 0; | ||
363 | int i; | ||
364 | u8 addr[ETH_ALEN]; | ||
365 | |||
366 | len += snprintf(buf + len, sizeof(buf) - len, | ||
367 | "primary: %s (%s chan=%d ht=%d)\n", | ||
368 | wiphy_name(sc->pri_wiphy->hw->wiphy), | ||
369 | ath_wiphy_state_str(sc->pri_wiphy->state), | ||
370 | sc->pri_wiphy->chan_idx, sc->pri_wiphy->chan_is_ht); | ||
371 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
372 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
373 | if (aphy == NULL) | ||
374 | continue; | ||
375 | len += snprintf(buf + len, sizeof(buf) - len, | ||
376 | "secondary: %s (%s chan=%d ht=%d)\n", | ||
377 | wiphy_name(aphy->hw->wiphy), | ||
378 | ath_wiphy_state_str(aphy->state), | ||
379 | aphy->chan_idx, aphy->chan_is_ht); | ||
380 | } | ||
381 | |||
382 | put_unaligned_le32(REG_READ(sc->sc_ah, AR_STA_ID0), addr); | ||
383 | put_unaligned_le16(REG_READ(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); | ||
384 | len += snprintf(buf + len, sizeof(buf) - len, | ||
385 | "addr: %pM\n", addr); | ||
386 | put_unaligned_le32(REG_READ(sc->sc_ah, AR_BSSMSKL), addr); | ||
387 | put_unaligned_le16(REG_READ(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4); | ||
388 | len += snprintf(buf + len, sizeof(buf) - len, | ||
389 | "addrmask: %pM\n", addr); | ||
390 | |||
391 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
392 | } | ||
393 | |||
394 | static struct ath_wiphy * get_wiphy(struct ath_softc *sc, const char *name) | ||
395 | { | ||
396 | int i; | ||
397 | if (strcmp(name, wiphy_name(sc->pri_wiphy->hw->wiphy)) == 0) | ||
398 | return sc->pri_wiphy; | ||
399 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
400 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
401 | if (aphy && strcmp(name, wiphy_name(aphy->hw->wiphy)) == 0) | ||
402 | return aphy; | ||
403 | } | ||
404 | return NULL; | ||
405 | } | ||
406 | |||
407 | static int del_wiphy(struct ath_softc *sc, const char *name) | ||
408 | { | ||
409 | struct ath_wiphy *aphy = get_wiphy(sc, name); | ||
410 | if (!aphy) | ||
411 | return -ENOENT; | ||
412 | return ath9k_wiphy_del(aphy); | ||
413 | } | ||
414 | |||
415 | static int pause_wiphy(struct ath_softc *sc, const char *name) | ||
416 | { | ||
417 | struct ath_wiphy *aphy = get_wiphy(sc, name); | ||
418 | if (!aphy) | ||
419 | return -ENOENT; | ||
420 | return ath9k_wiphy_pause(aphy); | ||
421 | } | ||
422 | |||
423 | static int unpause_wiphy(struct ath_softc *sc, const char *name) | ||
424 | { | ||
425 | struct ath_wiphy *aphy = get_wiphy(sc, name); | ||
426 | if (!aphy) | ||
427 | return -ENOENT; | ||
428 | return ath9k_wiphy_unpause(aphy); | ||
429 | } | ||
430 | |||
431 | static int select_wiphy(struct ath_softc *sc, const char *name) | ||
432 | { | ||
433 | struct ath_wiphy *aphy = get_wiphy(sc, name); | ||
434 | if (!aphy) | ||
435 | return -ENOENT; | ||
436 | return ath9k_wiphy_select(aphy); | ||
437 | } | ||
438 | |||
439 | static int schedule_wiphy(struct ath_softc *sc, const char *msec) | ||
440 | { | ||
441 | ath9k_wiphy_set_scheduler(sc, simple_strtoul(msec, NULL, 0)); | ||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | static ssize_t write_file_wiphy(struct file *file, const char __user *user_buf, | ||
446 | size_t count, loff_t *ppos) | ||
447 | { | ||
448 | struct ath_softc *sc = file->private_data; | ||
449 | char buf[50]; | ||
450 | size_t len; | ||
451 | |||
452 | len = min(count, sizeof(buf) - 1); | ||
453 | if (copy_from_user(buf, user_buf, len)) | ||
454 | return -EFAULT; | ||
455 | buf[len] = '\0'; | ||
456 | if (len > 0 && buf[len - 1] == '\n') | ||
457 | buf[len - 1] = '\0'; | ||
458 | |||
459 | if (strncmp(buf, "add", 3) == 0) { | ||
460 | int res = ath9k_wiphy_add(sc); | ||
461 | if (res < 0) | ||
462 | return res; | ||
463 | } else if (strncmp(buf, "del=", 4) == 0) { | ||
464 | int res = del_wiphy(sc, buf + 4); | ||
465 | if (res < 0) | ||
466 | return res; | ||
467 | } else if (strncmp(buf, "pause=", 6) == 0) { | ||
468 | int res = pause_wiphy(sc, buf + 6); | ||
469 | if (res < 0) | ||
470 | return res; | ||
471 | } else if (strncmp(buf, "unpause=", 8) == 0) { | ||
472 | int res = unpause_wiphy(sc, buf + 8); | ||
473 | if (res < 0) | ||
474 | return res; | ||
475 | } else if (strncmp(buf, "select=", 7) == 0) { | ||
476 | int res = select_wiphy(sc, buf + 7); | ||
477 | if (res < 0) | ||
478 | return res; | ||
479 | } else if (strncmp(buf, "schedule=", 9) == 0) { | ||
480 | int res = schedule_wiphy(sc, buf + 9); | ||
481 | if (res < 0) | ||
482 | return res; | ||
483 | } else | ||
484 | return -EOPNOTSUPP; | ||
485 | |||
486 | return count; | ||
487 | } | ||
488 | |||
489 | static const struct file_operations fops_wiphy = { | ||
490 | .read = read_file_wiphy, | ||
491 | .write = write_file_wiphy, | ||
492 | .open = ath9k_debugfs_open, | ||
493 | .owner = THIS_MODULE | ||
494 | }; | ||
495 | |||
496 | |||
497 | int ath9k_init_debug(struct ath_softc *sc) | ||
498 | { | ||
499 | sc->debug.debug_mask = ath9k_debug; | ||
500 | |||
501 | if (!ath9k_debugfs_root) | ||
502 | return -ENOENT; | ||
503 | |||
504 | sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy), | ||
505 | ath9k_debugfs_root); | ||
506 | if (!sc->debug.debugfs_phy) | ||
507 | goto err; | ||
508 | |||
509 | sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO, | ||
510 | sc->debug.debugfs_phy, sc, &fops_dma); | ||
511 | if (!sc->debug.debugfs_dma) | ||
512 | goto err; | ||
513 | |||
514 | sc->debug.debugfs_interrupt = debugfs_create_file("interrupt", | ||
515 | S_IRUGO, | ||
516 | sc->debug.debugfs_phy, | ||
517 | sc, &fops_interrupt); | ||
518 | if (!sc->debug.debugfs_interrupt) | ||
519 | goto err; | ||
520 | |||
521 | sc->debug.debugfs_rcstat = debugfs_create_file("rcstat", | ||
522 | S_IRUGO, | ||
523 | sc->debug.debugfs_phy, | ||
524 | sc, &fops_rcstat); | ||
525 | if (!sc->debug.debugfs_rcstat) | ||
526 | goto err; | ||
527 | |||
528 | sc->debug.debugfs_wiphy = debugfs_create_file( | ||
529 | "wiphy", S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc, | ||
530 | &fops_wiphy); | ||
531 | if (!sc->debug.debugfs_wiphy) | ||
532 | goto err; | ||
533 | |||
534 | return 0; | ||
535 | err: | ||
536 | ath9k_exit_debug(sc); | ||
537 | return -ENOMEM; | ||
538 | } | ||
539 | |||
540 | void ath9k_exit_debug(struct ath_softc *sc) | ||
541 | { | ||
542 | debugfs_remove(sc->debug.debugfs_wiphy); | ||
543 | debugfs_remove(sc->debug.debugfs_rcstat); | ||
544 | debugfs_remove(sc->debug.debugfs_interrupt); | ||
545 | debugfs_remove(sc->debug.debugfs_dma); | ||
546 | debugfs_remove(sc->debug.debugfs_phy); | ||
547 | } | ||
548 | |||
549 | int ath9k_debug_create_root(void) | ||
550 | { | ||
551 | ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); | ||
552 | if (!ath9k_debugfs_root) | ||
553 | return -ENOENT; | ||
554 | |||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | void ath9k_debug_remove_root(void) | ||
559 | { | ||
560 | debugfs_remove(ath9k_debugfs_root); | ||
561 | ath9k_debugfs_root = NULL; | ||
562 | } | ||
diff --git a/drivers/net/wireless/ath9k/debug.h b/drivers/net/wireless/ath9k/debug.h deleted file mode 100644 index 23298b90b52b..000000000000 --- a/drivers/net/wireless/ath9k/debug.h +++ /dev/null | |||
@@ -1,161 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 DEBUG_H | ||
18 | #define DEBUG_H | ||
19 | |||
20 | enum ATH_DEBUG { | ||
21 | ATH_DBG_RESET = 0x00000001, | ||
22 | ATH_DBG_QUEUE = 0x00000002, | ||
23 | ATH_DBG_EEPROM = 0x00000004, | ||
24 | ATH_DBG_CALIBRATE = 0x00000008, | ||
25 | ATH_DBG_INTERRUPT = 0x00000010, | ||
26 | ATH_DBG_REGULATORY = 0x00000020, | ||
27 | ATH_DBG_ANI = 0x00000040, | ||
28 | ATH_DBG_XMIT = 0x00000080, | ||
29 | ATH_DBG_BEACON = 0x00000100, | ||
30 | ATH_DBG_CONFIG = 0x00000200, | ||
31 | ATH_DBG_FATAL = 0x00000400, | ||
32 | ATH_DBG_ANY = 0xffffffff | ||
33 | }; | ||
34 | |||
35 | #define DBG_DEFAULT (ATH_DBG_FATAL) | ||
36 | |||
37 | #ifdef CONFIG_ATH9K_DEBUG | ||
38 | |||
39 | /** | ||
40 | * struct ath_interrupt_stats - Contains statistics about interrupts | ||
41 | * @total: Total no. of interrupts generated so far | ||
42 | * @rxok: RX with no errors | ||
43 | * @rxeol: RX with no more RXDESC available | ||
44 | * @rxorn: RX FIFO overrun | ||
45 | * @txok: TX completed at the requested rate | ||
46 | * @txurn: TX FIFO underrun | ||
47 | * @mib: MIB regs reaching its threshold | ||
48 | * @rxphyerr: RX with phy errors | ||
49 | * @rx_keycache_miss: RX with key cache misses | ||
50 | * @swba: Software Beacon Alert | ||
51 | * @bmiss: Beacon Miss | ||
52 | * @bnr: Beacon Not Ready | ||
53 | * @cst: Carrier Sense TImeout | ||
54 | * @gtt: Global TX Timeout | ||
55 | * @tim: RX beacon TIM occurrence | ||
56 | * @cabend: RX End of CAB traffic | ||
57 | * @dtimsync: DTIM sync lossage | ||
58 | * @dtim: RX Beacon with DTIM | ||
59 | */ | ||
60 | struct ath_interrupt_stats { | ||
61 | u32 total; | ||
62 | u32 rxok; | ||
63 | u32 rxeol; | ||
64 | u32 rxorn; | ||
65 | u32 txok; | ||
66 | u32 txeol; | ||
67 | u32 txurn; | ||
68 | u32 mib; | ||
69 | u32 rxphyerr; | ||
70 | u32 rx_keycache_miss; | ||
71 | u32 swba; | ||
72 | u32 bmiss; | ||
73 | u32 bnr; | ||
74 | u32 cst; | ||
75 | u32 gtt; | ||
76 | u32 tim; | ||
77 | u32 cabend; | ||
78 | u32 dtimsync; | ||
79 | u32 dtim; | ||
80 | }; | ||
81 | |||
82 | struct ath_legacy_rc_stats { | ||
83 | u32 success; | ||
84 | }; | ||
85 | |||
86 | struct ath_11n_rc_stats { | ||
87 | u32 success; | ||
88 | u32 retries; | ||
89 | u32 xretries; | ||
90 | u8 per; | ||
91 | }; | ||
92 | |||
93 | struct ath_stats { | ||
94 | struct ath_interrupt_stats istats; | ||
95 | struct ath_legacy_rc_stats legacy_rcstats[12]; /* max(11a,11b,11g) */ | ||
96 | struct ath_11n_rc_stats n_rcstats[16]; /* 0..15 MCS rates */ | ||
97 | }; | ||
98 | |||
99 | struct ath9k_debug { | ||
100 | int debug_mask; | ||
101 | struct dentry *debugfs_phy; | ||
102 | struct dentry *debugfs_dma; | ||
103 | struct dentry *debugfs_interrupt; | ||
104 | struct dentry *debugfs_rcstat; | ||
105 | struct dentry *debugfs_wiphy; | ||
106 | struct ath_stats stats; | ||
107 | }; | ||
108 | |||
109 | void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...); | ||
110 | int ath9k_init_debug(struct ath_softc *sc); | ||
111 | void ath9k_exit_debug(struct ath_softc *sc); | ||
112 | int ath9k_debug_create_root(void); | ||
113 | void ath9k_debug_remove_root(void); | ||
114 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); | ||
115 | void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb); | ||
116 | void ath_debug_stat_retries(struct ath_softc *sc, int rix, | ||
117 | int xretries, int retries, u8 per); | ||
118 | |||
119 | #else | ||
120 | |||
121 | static inline void DPRINTF(struct ath_softc *sc, int dbg_mask, | ||
122 | const char *fmt, ...) | ||
123 | { | ||
124 | } | ||
125 | |||
126 | static inline int ath9k_init_debug(struct ath_softc *sc) | ||
127 | { | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static inline void ath9k_exit_debug(struct ath_softc *sc) | ||
132 | { | ||
133 | } | ||
134 | |||
135 | static inline int ath9k_debug_create_root(void) | ||
136 | { | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static inline void ath9k_debug_remove_root(void) | ||
141 | { | ||
142 | } | ||
143 | |||
144 | static inline void ath_debug_stat_interrupt(struct ath_softc *sc, | ||
145 | enum ath9k_int status) | ||
146 | { | ||
147 | } | ||
148 | |||
149 | static inline void ath_debug_stat_rc(struct ath_softc *sc, | ||
150 | struct sk_buff *skb) | ||
151 | { | ||
152 | } | ||
153 | |||
154 | static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix, | ||
155 | int xretries, int retries, u8 per) | ||
156 | { | ||
157 | } | ||
158 | |||
159 | #endif /* CONFIG_ATH9K_DEBUG */ | ||
160 | |||
161 | #endif /* DEBUG_H */ | ||
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c deleted file mode 100644 index 44fee5ae8925..000000000000 --- a/drivers/net/wireless/ath9k/eeprom.c +++ /dev/null | |||
@@ -1,2813 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 "ath9k.h" | ||
18 | |||
19 | static void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, | ||
20 | u32 reg, u32 mask, | ||
21 | u32 shift, u32 val) | ||
22 | { | ||
23 | u32 regVal; | ||
24 | |||
25 | regVal = REG_READ(ah, reg) & ~mask; | ||
26 | regVal |= (val << shift) & mask; | ||
27 | |||
28 | REG_WRITE(ah, reg, regVal); | ||
29 | |||
30 | if (ah->config.analog_shiftreg) | ||
31 | udelay(100); | ||
32 | |||
33 | return; | ||
34 | } | ||
35 | |||
36 | static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) | ||
37 | { | ||
38 | |||
39 | if (fbin == AR5416_BCHAN_UNUSED) | ||
40 | return fbin; | ||
41 | |||
42 | return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); | ||
43 | } | ||
44 | |||
45 | static inline int16_t ath9k_hw_interpolate(u16 target, | ||
46 | u16 srcLeft, u16 srcRight, | ||
47 | int16_t targetLeft, | ||
48 | int16_t targetRight) | ||
49 | { | ||
50 | int16_t rv; | ||
51 | |||
52 | if (srcRight == srcLeft) { | ||
53 | rv = targetLeft; | ||
54 | } else { | ||
55 | rv = (int16_t) (((target - srcLeft) * targetRight + | ||
56 | (srcRight - target) * targetLeft) / | ||
57 | (srcRight - srcLeft)); | ||
58 | } | ||
59 | return rv; | ||
60 | } | ||
61 | |||
62 | static inline bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, | ||
63 | u16 listSize, u16 *indexL, | ||
64 | u16 *indexR) | ||
65 | { | ||
66 | u16 i; | ||
67 | |||
68 | if (target <= pList[0]) { | ||
69 | *indexL = *indexR = 0; | ||
70 | return true; | ||
71 | } | ||
72 | if (target >= pList[listSize - 1]) { | ||
73 | *indexL = *indexR = (u16) (listSize - 1); | ||
74 | return true; | ||
75 | } | ||
76 | |||
77 | for (i = 0; i < listSize - 1; i++) { | ||
78 | if (pList[i] == target) { | ||
79 | *indexL = *indexR = i; | ||
80 | return true; | ||
81 | } | ||
82 | if (target < pList[i + 1]) { | ||
83 | *indexL = i; | ||
84 | *indexR = (u16) (i + 1); | ||
85 | return false; | ||
86 | } | ||
87 | } | ||
88 | return false; | ||
89 | } | ||
90 | |||
91 | static inline bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data) | ||
92 | { | ||
93 | struct ath_softc *sc = ah->ah_sc; | ||
94 | |||
95 | return sc->bus_ops->eeprom_read(ah, off, data); | ||
96 | } | ||
97 | |||
98 | static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList, | ||
99 | u8 *pVpdList, u16 numIntercepts, | ||
100 | u8 *pRetVpdList) | ||
101 | { | ||
102 | u16 i, k; | ||
103 | u8 currPwr = pwrMin; | ||
104 | u16 idxL = 0, idxR = 0; | ||
105 | |||
106 | for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) { | ||
107 | ath9k_hw_get_lower_upper_index(currPwr, pPwrList, | ||
108 | numIntercepts, &(idxL), | ||
109 | &(idxR)); | ||
110 | if (idxR < 1) | ||
111 | idxR = 1; | ||
112 | if (idxL == numIntercepts - 1) | ||
113 | idxL = (u16) (numIntercepts - 2); | ||
114 | if (pPwrList[idxL] == pPwrList[idxR]) | ||
115 | k = pVpdList[idxL]; | ||
116 | else | ||
117 | k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] + | ||
118 | (pPwrList[idxR] - currPwr) * pVpdList[idxL]) / | ||
119 | (pPwrList[idxR] - pPwrList[idxL])); | ||
120 | pRetVpdList[i] = (u8) k; | ||
121 | currPwr += 2; | ||
122 | } | ||
123 | |||
124 | return true; | ||
125 | } | ||
126 | |||
127 | static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah, | ||
128 | struct ath9k_channel *chan, | ||
129 | struct cal_target_power_leg *powInfo, | ||
130 | u16 numChannels, | ||
131 | struct cal_target_power_leg *pNewPower, | ||
132 | u16 numRates, bool isExtTarget) | ||
133 | { | ||
134 | struct chan_centers centers; | ||
135 | u16 clo, chi; | ||
136 | int i; | ||
137 | int matchIndex = -1, lowIndex = -1; | ||
138 | u16 freq; | ||
139 | |||
140 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
141 | freq = (isExtTarget) ? centers.ext_center : centers.ctl_center; | ||
142 | |||
143 | if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, | ||
144 | IS_CHAN_2GHZ(chan))) { | ||
145 | matchIndex = 0; | ||
146 | } else { | ||
147 | for (i = 0; (i < numChannels) && | ||
148 | (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) { | ||
149 | if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel, | ||
150 | IS_CHAN_2GHZ(chan))) { | ||
151 | matchIndex = i; | ||
152 | break; | ||
153 | } else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel, | ||
154 | IS_CHAN_2GHZ(chan))) && | ||
155 | (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel, | ||
156 | IS_CHAN_2GHZ(chan)))) { | ||
157 | lowIndex = i - 1; | ||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | if ((matchIndex == -1) && (lowIndex == -1)) | ||
162 | matchIndex = i - 1; | ||
163 | } | ||
164 | |||
165 | if (matchIndex != -1) { | ||
166 | *pNewPower = powInfo[matchIndex]; | ||
167 | } else { | ||
168 | clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel, | ||
169 | IS_CHAN_2GHZ(chan)); | ||
170 | chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel, | ||
171 | IS_CHAN_2GHZ(chan)); | ||
172 | |||
173 | for (i = 0; i < numRates; i++) { | ||
174 | pNewPower->tPow2x[i] = | ||
175 | (u8)ath9k_hw_interpolate(freq, clo, chi, | ||
176 | powInfo[lowIndex].tPow2x[i], | ||
177 | powInfo[lowIndex + 1].tPow2x[i]); | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | |||
182 | static void ath9k_get_txgain_index(struct ath_hw *ah, | ||
183 | struct ath9k_channel *chan, | ||
184 | struct calDataPerFreqOpLoop *rawDatasetOpLoop, | ||
185 | u8 *calChans, u16 availPiers, u8 *pwr, u8 *pcdacIdx) | ||
186 | { | ||
187 | u8 pcdac, i = 0; | ||
188 | u16 idxL = 0, idxR = 0, numPiers; | ||
189 | bool match; | ||
190 | struct chan_centers centers; | ||
191 | |||
192 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
193 | |||
194 | for (numPiers = 0; numPiers < availPiers; numPiers++) | ||
195 | if (calChans[numPiers] == AR5416_BCHAN_UNUSED) | ||
196 | break; | ||
197 | |||
198 | match = ath9k_hw_get_lower_upper_index( | ||
199 | (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), | ||
200 | calChans, numPiers, &idxL, &idxR); | ||
201 | if (match) { | ||
202 | pcdac = rawDatasetOpLoop[idxL].pcdac[0][0]; | ||
203 | *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0]; | ||
204 | } else { | ||
205 | pcdac = rawDatasetOpLoop[idxR].pcdac[0][0]; | ||
206 | *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] + | ||
207 | rawDatasetOpLoop[idxR].pwrPdg[0][0])/2; | ||
208 | } | ||
209 | |||
210 | while (pcdac > ah->originalGain[i] && | ||
211 | i < (AR9280_TX_GAIN_TABLE_SIZE - 1)) | ||
212 | i++; | ||
213 | |||
214 | *pcdacIdx = i; | ||
215 | return; | ||
216 | } | ||
217 | |||
218 | static void ath9k_olc_get_pdadcs(struct ath_hw *ah, | ||
219 | u32 initTxGain, | ||
220 | int txPower, | ||
221 | u8 *pPDADCValues) | ||
222 | { | ||
223 | u32 i; | ||
224 | u32 offset; | ||
225 | |||
226 | REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0, | ||
227 | AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3); | ||
228 | REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1, | ||
229 | AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3); | ||
230 | |||
231 | REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7, | ||
232 | AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain); | ||
233 | |||
234 | offset = txPower; | ||
235 | for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++) | ||
236 | if (i < offset) | ||
237 | pPDADCValues[i] = 0x0; | ||
238 | else | ||
239 | pPDADCValues[i] = 0xFF; | ||
240 | } | ||
241 | |||
242 | |||
243 | |||
244 | |||
245 | static void ath9k_hw_get_target_powers(struct ath_hw *ah, | ||
246 | struct ath9k_channel *chan, | ||
247 | struct cal_target_power_ht *powInfo, | ||
248 | u16 numChannels, | ||
249 | struct cal_target_power_ht *pNewPower, | ||
250 | u16 numRates, bool isHt40Target) | ||
251 | { | ||
252 | struct chan_centers centers; | ||
253 | u16 clo, chi; | ||
254 | int i; | ||
255 | int matchIndex = -1, lowIndex = -1; | ||
256 | u16 freq; | ||
257 | |||
258 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
259 | freq = isHt40Target ? centers.synth_center : centers.ctl_center; | ||
260 | |||
261 | if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) { | ||
262 | matchIndex = 0; | ||
263 | } else { | ||
264 | for (i = 0; (i < numChannels) && | ||
265 | (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) { | ||
266 | if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel, | ||
267 | IS_CHAN_2GHZ(chan))) { | ||
268 | matchIndex = i; | ||
269 | break; | ||
270 | } else | ||
271 | if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel, | ||
272 | IS_CHAN_2GHZ(chan))) && | ||
273 | (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel, | ||
274 | IS_CHAN_2GHZ(chan)))) { | ||
275 | lowIndex = i - 1; | ||
276 | break; | ||
277 | } | ||
278 | } | ||
279 | if ((matchIndex == -1) && (lowIndex == -1)) | ||
280 | matchIndex = i - 1; | ||
281 | } | ||
282 | |||
283 | if (matchIndex != -1) { | ||
284 | *pNewPower = powInfo[matchIndex]; | ||
285 | } else { | ||
286 | clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel, | ||
287 | IS_CHAN_2GHZ(chan)); | ||
288 | chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel, | ||
289 | IS_CHAN_2GHZ(chan)); | ||
290 | |||
291 | for (i = 0; i < numRates; i++) { | ||
292 | pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq, | ||
293 | clo, chi, | ||
294 | powInfo[lowIndex].tPow2x[i], | ||
295 | powInfo[lowIndex + 1].tPow2x[i]); | ||
296 | } | ||
297 | } | ||
298 | } | ||
299 | |||
300 | static u16 ath9k_hw_get_max_edge_power(u16 freq, | ||
301 | struct cal_ctl_edges *pRdEdgesPower, | ||
302 | bool is2GHz, int num_band_edges) | ||
303 | { | ||
304 | u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; | ||
305 | int i; | ||
306 | |||
307 | for (i = 0; (i < num_band_edges) && | ||
308 | (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) { | ||
309 | if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { | ||
310 | twiceMaxEdgePower = pRdEdgesPower[i].tPower; | ||
311 | break; | ||
312 | } else if ((i > 0) && | ||
313 | (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, | ||
314 | is2GHz))) { | ||
315 | if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel, | ||
316 | is2GHz) < freq && | ||
317 | pRdEdgesPower[i - 1].flag) { | ||
318 | twiceMaxEdgePower = | ||
319 | pRdEdgesPower[i - 1].tPower; | ||
320 | } | ||
321 | break; | ||
322 | } | ||
323 | } | ||
324 | |||
325 | return twiceMaxEdgePower; | ||
326 | } | ||
327 | |||
328 | /****************************************/ | ||
329 | /* EEPROM Operations for 4K sized cards */ | ||
330 | /****************************************/ | ||
331 | |||
332 | static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah) | ||
333 | { | ||
334 | return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF); | ||
335 | } | ||
336 | |||
337 | static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah) | ||
338 | { | ||
339 | return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF); | ||
340 | } | ||
341 | |||
342 | static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) | ||
343 | { | ||
344 | #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) | ||
345 | u16 *eep_data = (u16 *)&ah->eeprom.map4k; | ||
346 | int addr, eep_start_loc = 0; | ||
347 | |||
348 | eep_start_loc = 64; | ||
349 | |||
350 | if (!ath9k_hw_use_flash(ah)) { | ||
351 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
352 | "Reading from EEPROM, not flash\n"); | ||
353 | } | ||
354 | |||
355 | for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { | ||
356 | if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) { | ||
357 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
358 | "Unable to read eeprom region \n"); | ||
359 | return false; | ||
360 | } | ||
361 | eep_data++; | ||
362 | } | ||
363 | |||
364 | return true; | ||
365 | #undef SIZE_EEPROM_4K | ||
366 | } | ||
367 | |||
368 | static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) | ||
369 | { | ||
370 | #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) | ||
371 | struct ar5416_eeprom_4k *eep = | ||
372 | (struct ar5416_eeprom_4k *) &ah->eeprom.map4k; | ||
373 | u16 *eepdata, temp, magic, magic2; | ||
374 | u32 sum = 0, el; | ||
375 | bool need_swap = false; | ||
376 | int i, addr; | ||
377 | |||
378 | |||
379 | if (!ath9k_hw_use_flash(ah)) { | ||
380 | if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, | ||
381 | &magic)) { | ||
382 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
383 | "Reading Magic # failed\n"); | ||
384 | return false; | ||
385 | } | ||
386 | |||
387 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
388 | "Read Magic = 0x%04X\n", magic); | ||
389 | |||
390 | if (magic != AR5416_EEPROM_MAGIC) { | ||
391 | magic2 = swab16(magic); | ||
392 | |||
393 | if (magic2 == AR5416_EEPROM_MAGIC) { | ||
394 | need_swap = true; | ||
395 | eepdata = (u16 *) (&ah->eeprom); | ||
396 | |||
397 | for (addr = 0; addr < EEPROM_4K_SIZE; addr++) { | ||
398 | temp = swab16(*eepdata); | ||
399 | *eepdata = temp; | ||
400 | eepdata++; | ||
401 | } | ||
402 | } else { | ||
403 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
404 | "Invalid EEPROM Magic. " | ||
405 | "endianness mismatch.\n"); | ||
406 | return -EINVAL; | ||
407 | } | ||
408 | } | ||
409 | } | ||
410 | |||
411 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n", | ||
412 | need_swap ? "True" : "False"); | ||
413 | |||
414 | if (need_swap) | ||
415 | el = swab16(ah->eeprom.map4k.baseEepHeader.length); | ||
416 | else | ||
417 | el = ah->eeprom.map4k.baseEepHeader.length; | ||
418 | |||
419 | if (el > sizeof(struct ar5416_eeprom_4k)) | ||
420 | el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16); | ||
421 | else | ||
422 | el = el / sizeof(u16); | ||
423 | |||
424 | eepdata = (u16 *)(&ah->eeprom); | ||
425 | |||
426 | for (i = 0; i < el; i++) | ||
427 | sum ^= *eepdata++; | ||
428 | |||
429 | if (need_swap) { | ||
430 | u32 integer; | ||
431 | u16 word; | ||
432 | |||
433 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
434 | "EEPROM Endianness is not native.. Changing\n"); | ||
435 | |||
436 | word = swab16(eep->baseEepHeader.length); | ||
437 | eep->baseEepHeader.length = word; | ||
438 | |||
439 | word = swab16(eep->baseEepHeader.checksum); | ||
440 | eep->baseEepHeader.checksum = word; | ||
441 | |||
442 | word = swab16(eep->baseEepHeader.version); | ||
443 | eep->baseEepHeader.version = word; | ||
444 | |||
445 | word = swab16(eep->baseEepHeader.regDmn[0]); | ||
446 | eep->baseEepHeader.regDmn[0] = word; | ||
447 | |||
448 | word = swab16(eep->baseEepHeader.regDmn[1]); | ||
449 | eep->baseEepHeader.regDmn[1] = word; | ||
450 | |||
451 | word = swab16(eep->baseEepHeader.rfSilent); | ||
452 | eep->baseEepHeader.rfSilent = word; | ||
453 | |||
454 | word = swab16(eep->baseEepHeader.blueToothOptions); | ||
455 | eep->baseEepHeader.blueToothOptions = word; | ||
456 | |||
457 | word = swab16(eep->baseEepHeader.deviceCap); | ||
458 | eep->baseEepHeader.deviceCap = word; | ||
459 | |||
460 | integer = swab32(eep->modalHeader.antCtrlCommon); | ||
461 | eep->modalHeader.antCtrlCommon = integer; | ||
462 | |||
463 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
464 | integer = swab32(eep->modalHeader.antCtrlChain[i]); | ||
465 | eep->modalHeader.antCtrlChain[i] = integer; | ||
466 | } | ||
467 | |||
468 | for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { | ||
469 | word = swab16(eep->modalHeader.spurChans[i].spurChan); | ||
470 | eep->modalHeader.spurChans[i].spurChan = word; | ||
471 | } | ||
472 | } | ||
473 | |||
474 | if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER || | ||
475 | ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { | ||
476 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
477 | "Bad EEPROM checksum 0x%x or revision 0x%04x\n", | ||
478 | sum, ah->eep_ops->get_eeprom_ver(ah)); | ||
479 | return -EINVAL; | ||
480 | } | ||
481 | |||
482 | return 0; | ||
483 | #undef EEPROM_4K_SIZE | ||
484 | } | ||
485 | |||
486 | static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, | ||
487 | enum eeprom_param param) | ||
488 | { | ||
489 | struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; | ||
490 | struct modal_eep_4k_header *pModal = &eep->modalHeader; | ||
491 | struct base_eep_header_4k *pBase = &eep->baseEepHeader; | ||
492 | |||
493 | switch (param) { | ||
494 | case EEP_NFTHRESH_2: | ||
495 | return pModal->noiseFloorThreshCh[0]; | ||
496 | case AR_EEPROM_MAC(0): | ||
497 | return pBase->macAddr[0] << 8 | pBase->macAddr[1]; | ||
498 | case AR_EEPROM_MAC(1): | ||
499 | return pBase->macAddr[2] << 8 | pBase->macAddr[3]; | ||
500 | case AR_EEPROM_MAC(2): | ||
501 | return pBase->macAddr[4] << 8 | pBase->macAddr[5]; | ||
502 | case EEP_REG_0: | ||
503 | return pBase->regDmn[0]; | ||
504 | case EEP_REG_1: | ||
505 | return pBase->regDmn[1]; | ||
506 | case EEP_OP_CAP: | ||
507 | return pBase->deviceCap; | ||
508 | case EEP_OP_MODE: | ||
509 | return pBase->opCapFlags; | ||
510 | case EEP_RF_SILENT: | ||
511 | return pBase->rfSilent; | ||
512 | case EEP_OB_2: | ||
513 | return pModal->ob_01; | ||
514 | case EEP_DB_2: | ||
515 | return pModal->db1_01; | ||
516 | case EEP_MINOR_REV: | ||
517 | return pBase->version & AR5416_EEP_VER_MINOR_MASK; | ||
518 | case EEP_TX_MASK: | ||
519 | return pBase->txMask; | ||
520 | case EEP_RX_MASK: | ||
521 | return pBase->rxMask; | ||
522 | case EEP_FRAC_N_5G: | ||
523 | return 0; | ||
524 | default: | ||
525 | return 0; | ||
526 | } | ||
527 | } | ||
528 | |||
529 | static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, | ||
530 | struct ath9k_channel *chan, | ||
531 | struct cal_data_per_freq_4k *pRawDataSet, | ||
532 | u8 *bChans, u16 availPiers, | ||
533 | u16 tPdGainOverlap, int16_t *pMinCalPower, | ||
534 | u16 *pPdGainBoundaries, u8 *pPDADCValues, | ||
535 | u16 numXpdGains) | ||
536 | { | ||
537 | #define TMP_VAL_VPD_TABLE \ | ||
538 | ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep)); | ||
539 | int i, j, k; | ||
540 | int16_t ss; | ||
541 | u16 idxL = 0, idxR = 0, numPiers; | ||
542 | static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS] | ||
543 | [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; | ||
544 | static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS] | ||
545 | [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; | ||
546 | static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS] | ||
547 | [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; | ||
548 | |||
549 | u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; | ||
550 | u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS]; | ||
551 | u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS]; | ||
552 | int16_t vpdStep; | ||
553 | int16_t tmpVal; | ||
554 | u16 sizeCurrVpdTable, maxIndex, tgtIndex; | ||
555 | bool match; | ||
556 | int16_t minDelta = 0; | ||
557 | struct chan_centers centers; | ||
558 | #define PD_GAIN_BOUNDARY_DEFAULT 58; | ||
559 | |||
560 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
561 | |||
562 | for (numPiers = 0; numPiers < availPiers; numPiers++) { | ||
563 | if (bChans[numPiers] == AR5416_BCHAN_UNUSED) | ||
564 | break; | ||
565 | } | ||
566 | |||
567 | match = ath9k_hw_get_lower_upper_index( | ||
568 | (u8)FREQ2FBIN(centers.synth_center, | ||
569 | IS_CHAN_2GHZ(chan)), bChans, numPiers, | ||
570 | &idxL, &idxR); | ||
571 | |||
572 | if (match) { | ||
573 | for (i = 0; i < numXpdGains; i++) { | ||
574 | minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; | ||
575 | maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; | ||
576 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], | ||
577 | pRawDataSet[idxL].pwrPdg[i], | ||
578 | pRawDataSet[idxL].vpdPdg[i], | ||
579 | AR5416_EEP4K_PD_GAIN_ICEPTS, | ||
580 | vpdTableI[i]); | ||
581 | } | ||
582 | } else { | ||
583 | for (i = 0; i < numXpdGains; i++) { | ||
584 | pVpdL = pRawDataSet[idxL].vpdPdg[i]; | ||
585 | pPwrL = pRawDataSet[idxL].pwrPdg[i]; | ||
586 | pVpdR = pRawDataSet[idxR].vpdPdg[i]; | ||
587 | pPwrR = pRawDataSet[idxR].pwrPdg[i]; | ||
588 | |||
589 | minPwrT4[i] = max(pPwrL[0], pPwrR[0]); | ||
590 | |||
591 | maxPwrT4[i] = | ||
592 | min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1], | ||
593 | pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]); | ||
594 | |||
595 | |||
596 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], | ||
597 | pPwrL, pVpdL, | ||
598 | AR5416_EEP4K_PD_GAIN_ICEPTS, | ||
599 | vpdTableL[i]); | ||
600 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], | ||
601 | pPwrR, pVpdR, | ||
602 | AR5416_EEP4K_PD_GAIN_ICEPTS, | ||
603 | vpdTableR[i]); | ||
604 | |||
605 | for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { | ||
606 | vpdTableI[i][j] = | ||
607 | (u8)(ath9k_hw_interpolate((u16) | ||
608 | FREQ2FBIN(centers. | ||
609 | synth_center, | ||
610 | IS_CHAN_2GHZ | ||
611 | (chan)), | ||
612 | bChans[idxL], bChans[idxR], | ||
613 | vpdTableL[i][j], vpdTableR[i][j])); | ||
614 | } | ||
615 | } | ||
616 | } | ||
617 | |||
618 | *pMinCalPower = (int16_t)(minPwrT4[0] / 2); | ||
619 | |||
620 | k = 0; | ||
621 | |||
622 | for (i = 0; i < numXpdGains; i++) { | ||
623 | if (i == (numXpdGains - 1)) | ||
624 | pPdGainBoundaries[i] = | ||
625 | (u16)(maxPwrT4[i] / 2); | ||
626 | else | ||
627 | pPdGainBoundaries[i] = | ||
628 | (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4); | ||
629 | |||
630 | pPdGainBoundaries[i] = | ||
631 | min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); | ||
632 | |||
633 | if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { | ||
634 | minDelta = pPdGainBoundaries[0] - 23; | ||
635 | pPdGainBoundaries[0] = 23; | ||
636 | } else { | ||
637 | minDelta = 0; | ||
638 | } | ||
639 | |||
640 | if (i == 0) { | ||
641 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
642 | ss = (int16_t)(0 - (minPwrT4[i] / 2)); | ||
643 | else | ||
644 | ss = 0; | ||
645 | } else { | ||
646 | ss = (int16_t)((pPdGainBoundaries[i - 1] - | ||
647 | (minPwrT4[i] / 2)) - | ||
648 | tPdGainOverlap + 1 + minDelta); | ||
649 | } | ||
650 | vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); | ||
651 | vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); | ||
652 | |||
653 | while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { | ||
654 | tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); | ||
655 | pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); | ||
656 | ss++; | ||
657 | } | ||
658 | |||
659 | sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1); | ||
660 | tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap - | ||
661 | (minPwrT4[i] / 2)); | ||
662 | maxIndex = (tgtIndex < sizeCurrVpdTable) ? | ||
663 | tgtIndex : sizeCurrVpdTable; | ||
664 | |||
665 | while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) | ||
666 | pPDADCValues[k++] = vpdTableI[i][ss++]; | ||
667 | |||
668 | vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - | ||
669 | vpdTableI[i][sizeCurrVpdTable - 2]); | ||
670 | vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); | ||
671 | |||
672 | if (tgtIndex >= maxIndex) { | ||
673 | while ((ss <= tgtIndex) && | ||
674 | (k < (AR5416_NUM_PDADC_VALUES - 1))) { | ||
675 | tmpVal = (int16_t) TMP_VAL_VPD_TABLE; | ||
676 | pPDADCValues[k++] = (u8)((tmpVal > 255) ? | ||
677 | 255 : tmpVal); | ||
678 | ss++; | ||
679 | } | ||
680 | } | ||
681 | } | ||
682 | |||
683 | while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) { | ||
684 | pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT; | ||
685 | i++; | ||
686 | } | ||
687 | |||
688 | while (k < AR5416_NUM_PDADC_VALUES) { | ||
689 | pPDADCValues[k] = pPDADCValues[k - 1]; | ||
690 | k++; | ||
691 | } | ||
692 | |||
693 | return; | ||
694 | #undef TMP_VAL_VPD_TABLE | ||
695 | } | ||
696 | |||
697 | static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, | ||
698 | struct ath9k_channel *chan, | ||
699 | int16_t *pTxPowerIndexOffset) | ||
700 | { | ||
701 | struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; | ||
702 | struct cal_data_per_freq_4k *pRawDataset; | ||
703 | u8 *pCalBChans = NULL; | ||
704 | u16 pdGainOverlap_t2; | ||
705 | static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; | ||
706 | u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK]; | ||
707 | u16 numPiers, i, j; | ||
708 | int16_t tMinCalPower; | ||
709 | u16 numXpdGain, xpdMask; | ||
710 | u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 }; | ||
711 | u32 reg32, regOffset, regChainOffset; | ||
712 | |||
713 | xpdMask = pEepData->modalHeader.xpdGain; | ||
714 | |||
715 | if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= | ||
716 | AR5416_EEP_MINOR_VER_2) { | ||
717 | pdGainOverlap_t2 = | ||
718 | pEepData->modalHeader.pdGainOverlap; | ||
719 | } else { | ||
720 | pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), | ||
721 | AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); | ||
722 | } | ||
723 | |||
724 | pCalBChans = pEepData->calFreqPier2G; | ||
725 | numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS; | ||
726 | |||
727 | numXpdGain = 0; | ||
728 | |||
729 | for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) { | ||
730 | if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) { | ||
731 | if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS) | ||
732 | break; | ||
733 | xpdGainValues[numXpdGain] = | ||
734 | (u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i); | ||
735 | numXpdGain++; | ||
736 | } | ||
737 | } | ||
738 | |||
739 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, | ||
740 | (numXpdGain - 1) & 0x3); | ||
741 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1, | ||
742 | xpdGainValues[0]); | ||
743 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2, | ||
744 | xpdGainValues[1]); | ||
745 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0); | ||
746 | |||
747 | for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) { | ||
748 | if (AR_SREV_5416_20_OR_LATER(ah) && | ||
749 | (ah->rxchainmask == 5 || ah->txchainmask == 5) && | ||
750 | (i != 0)) { | ||
751 | regChainOffset = (i == 1) ? 0x2000 : 0x1000; | ||
752 | } else | ||
753 | regChainOffset = i * 0x1000; | ||
754 | |||
755 | if (pEepData->baseEepHeader.txMask & (1 << i)) { | ||
756 | pRawDataset = pEepData->calPierData2G[i]; | ||
757 | |||
758 | ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan, | ||
759 | pRawDataset, pCalBChans, | ||
760 | numPiers, pdGainOverlap_t2, | ||
761 | &tMinCalPower, gainBoundaries, | ||
762 | pdadcValues, numXpdGain); | ||
763 | |||
764 | if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { | ||
765 | REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, | ||
766 | SM(pdGainOverlap_t2, | ||
767 | AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | ||
768 | | SM(gainBoundaries[0], | ||
769 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) | ||
770 | | SM(gainBoundaries[1], | ||
771 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) | ||
772 | | SM(gainBoundaries[2], | ||
773 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) | ||
774 | | SM(gainBoundaries[3], | ||
775 | AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); | ||
776 | } | ||
777 | |||
778 | regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; | ||
779 | for (j = 0; j < 32; j++) { | ||
780 | reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) | | ||
781 | ((pdadcValues[4 * j + 1] & 0xFF) << 8) | | ||
782 | ((pdadcValues[4 * j + 2] & 0xFF) << 16)| | ||
783 | ((pdadcValues[4 * j + 3] & 0xFF) << 24); | ||
784 | REG_WRITE(ah, regOffset, reg32); | ||
785 | |||
786 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
787 | "PDADC (%d,%4x): %4.4x %8.8x\n", | ||
788 | i, regChainOffset, regOffset, | ||
789 | reg32); | ||
790 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
791 | "PDADC: Chain %d | " | ||
792 | "PDADC %3d Value %3d | " | ||
793 | "PDADC %3d Value %3d | " | ||
794 | "PDADC %3d Value %3d | " | ||
795 | "PDADC %3d Value %3d |\n", | ||
796 | i, 4 * j, pdadcValues[4 * j], | ||
797 | 4 * j + 1, pdadcValues[4 * j + 1], | ||
798 | 4 * j + 2, pdadcValues[4 * j + 2], | ||
799 | 4 * j + 3, | ||
800 | pdadcValues[4 * j + 3]); | ||
801 | |||
802 | regOffset += 4; | ||
803 | } | ||
804 | } | ||
805 | } | ||
806 | |||
807 | *pTxPowerIndexOffset = 0; | ||
808 | |||
809 | return true; | ||
810 | } | ||
811 | |||
812 | static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, | ||
813 | struct ath9k_channel *chan, | ||
814 | int16_t *ratesArray, | ||
815 | u16 cfgCtl, | ||
816 | u16 AntennaReduction, | ||
817 | u16 twiceMaxRegulatoryPower, | ||
818 | u16 powerLimit) | ||
819 | { | ||
820 | struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; | ||
821 | u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; | ||
822 | static const u16 tpScaleReductionTable[5] = | ||
823 | { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; | ||
824 | |||
825 | int i; | ||
826 | int16_t twiceLargestAntenna; | ||
827 | struct cal_ctl_data_4k *rep; | ||
828 | struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { | ||
829 | 0, { 0, 0, 0, 0} | ||
830 | }; | ||
831 | struct cal_target_power_leg targetPowerOfdmExt = { | ||
832 | 0, { 0, 0, 0, 0} }, targetPowerCckExt = { | ||
833 | 0, { 0, 0, 0, 0 } | ||
834 | }; | ||
835 | struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { | ||
836 | 0, {0, 0, 0, 0} | ||
837 | }; | ||
838 | u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; | ||
839 | u16 ctlModesFor11g[] = | ||
840 | { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, | ||
841 | CTL_2GHT40 | ||
842 | }; | ||
843 | u16 numCtlModes, *pCtlMode, ctlMode, freq; | ||
844 | struct chan_centers centers; | ||
845 | int tx_chainmask; | ||
846 | u16 twiceMinEdgePower; | ||
847 | |||
848 | tx_chainmask = ah->txchainmask; | ||
849 | |||
850 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
851 | |||
852 | twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0]; | ||
853 | |||
854 | twiceLargestAntenna = (int16_t)min(AntennaReduction - | ||
855 | twiceLargestAntenna, 0); | ||
856 | |||
857 | maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; | ||
858 | |||
859 | if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) { | ||
860 | maxRegAllowedPower -= | ||
861 | (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2); | ||
862 | } | ||
863 | |||
864 | scaledPower = min(powerLimit, maxRegAllowedPower); | ||
865 | scaledPower = max((u16)0, scaledPower); | ||
866 | |||
867 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; | ||
868 | pCtlMode = ctlModesFor11g; | ||
869 | |||
870 | ath9k_hw_get_legacy_target_powers(ah, chan, | ||
871 | pEepData->calTargetPowerCck, | ||
872 | AR5416_NUM_2G_CCK_TARGET_POWERS, | ||
873 | &targetPowerCck, 4, false); | ||
874 | ath9k_hw_get_legacy_target_powers(ah, chan, | ||
875 | pEepData->calTargetPower2G, | ||
876 | AR5416_NUM_2G_20_TARGET_POWERS, | ||
877 | &targetPowerOfdm, 4, false); | ||
878 | ath9k_hw_get_target_powers(ah, chan, | ||
879 | pEepData->calTargetPower2GHT20, | ||
880 | AR5416_NUM_2G_20_TARGET_POWERS, | ||
881 | &targetPowerHt20, 8, false); | ||
882 | |||
883 | if (IS_CHAN_HT40(chan)) { | ||
884 | numCtlModes = ARRAY_SIZE(ctlModesFor11g); | ||
885 | ath9k_hw_get_target_powers(ah, chan, | ||
886 | pEepData->calTargetPower2GHT40, | ||
887 | AR5416_NUM_2G_40_TARGET_POWERS, | ||
888 | &targetPowerHt40, 8, true); | ||
889 | ath9k_hw_get_legacy_target_powers(ah, chan, | ||
890 | pEepData->calTargetPowerCck, | ||
891 | AR5416_NUM_2G_CCK_TARGET_POWERS, | ||
892 | &targetPowerCckExt, 4, true); | ||
893 | ath9k_hw_get_legacy_target_powers(ah, chan, | ||
894 | pEepData->calTargetPower2G, | ||
895 | AR5416_NUM_2G_20_TARGET_POWERS, | ||
896 | &targetPowerOfdmExt, 4, true); | ||
897 | } | ||
898 | |||
899 | for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { | ||
900 | bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || | ||
901 | (pCtlMode[ctlMode] == CTL_2GHT40); | ||
902 | if (isHt40CtlMode) | ||
903 | freq = centers.synth_center; | ||
904 | else if (pCtlMode[ctlMode] & EXT_ADDITIVE) | ||
905 | freq = centers.ext_center; | ||
906 | else | ||
907 | freq = centers.ctl_center; | ||
908 | |||
909 | if (ah->eep_ops->get_eeprom_ver(ah) == 14 && | ||
910 | ah->eep_ops->get_eeprom_rev(ah) <= 2) | ||
911 | twiceMaxEdgePower = AR5416_MAX_RATE_POWER; | ||
912 | |||
913 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
914 | "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, " | ||
915 | "EXT_ADDITIVE %d\n", | ||
916 | ctlMode, numCtlModes, isHt40CtlMode, | ||
917 | (pCtlMode[ctlMode] & EXT_ADDITIVE)); | ||
918 | |||
919 | for (i = 0; (i < AR5416_NUM_CTLS) && | ||
920 | pEepData->ctlIndex[i]; i++) { | ||
921 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
922 | " LOOP-Ctlidx %d: cfgCtl 0x%2.2x " | ||
923 | "pCtlMode 0x%2.2x ctlIndex 0x%2.2x " | ||
924 | "chan %d\n", | ||
925 | i, cfgCtl, pCtlMode[ctlMode], | ||
926 | pEepData->ctlIndex[i], chan->channel); | ||
927 | |||
928 | if ((((cfgCtl & ~CTL_MODE_M) | | ||
929 | (pCtlMode[ctlMode] & CTL_MODE_M)) == | ||
930 | pEepData->ctlIndex[i]) || | ||
931 | (((cfgCtl & ~CTL_MODE_M) | | ||
932 | (pCtlMode[ctlMode] & CTL_MODE_M)) == | ||
933 | ((pEepData->ctlIndex[i] & CTL_MODE_M) | | ||
934 | SD_NO_CTL))) { | ||
935 | rep = &(pEepData->ctlData[i]); | ||
936 | |||
937 | twiceMinEdgePower = | ||
938 | ath9k_hw_get_max_edge_power(freq, | ||
939 | rep->ctlEdges[ar5416_get_ntxchains | ||
940 | (tx_chainmask) - 1], | ||
941 | IS_CHAN_2GHZ(chan), | ||
942 | AR5416_EEP4K_NUM_BAND_EDGES); | ||
943 | |||
944 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
945 | " MATCH-EE_IDX %d: ch %d is2 %d " | ||
946 | "2xMinEdge %d chainmask %d chains %d\n", | ||
947 | i, freq, IS_CHAN_2GHZ(chan), | ||
948 | twiceMinEdgePower, tx_chainmask, | ||
949 | ar5416_get_ntxchains | ||
950 | (tx_chainmask)); | ||
951 | if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { | ||
952 | twiceMaxEdgePower = | ||
953 | min(twiceMaxEdgePower, | ||
954 | twiceMinEdgePower); | ||
955 | } else { | ||
956 | twiceMaxEdgePower = twiceMinEdgePower; | ||
957 | break; | ||
958 | } | ||
959 | } | ||
960 | } | ||
961 | |||
962 | minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); | ||
963 | |||
964 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
965 | " SEL-Min ctlMode %d pCtlMode %d " | ||
966 | "2xMaxEdge %d sP %d minCtlPwr %d\n", | ||
967 | ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, | ||
968 | scaledPower, minCtlPower); | ||
969 | |||
970 | switch (pCtlMode[ctlMode]) { | ||
971 | case CTL_11B: | ||
972 | for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); | ||
973 | i++) { | ||
974 | targetPowerCck.tPow2x[i] = | ||
975 | min((u16)targetPowerCck.tPow2x[i], | ||
976 | minCtlPower); | ||
977 | } | ||
978 | break; | ||
979 | case CTL_11G: | ||
980 | for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); | ||
981 | i++) { | ||
982 | targetPowerOfdm.tPow2x[i] = | ||
983 | min((u16)targetPowerOfdm.tPow2x[i], | ||
984 | minCtlPower); | ||
985 | } | ||
986 | break; | ||
987 | case CTL_2GHT20: | ||
988 | for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); | ||
989 | i++) { | ||
990 | targetPowerHt20.tPow2x[i] = | ||
991 | min((u16)targetPowerHt20.tPow2x[i], | ||
992 | minCtlPower); | ||
993 | } | ||
994 | break; | ||
995 | case CTL_11B_EXT: | ||
996 | targetPowerCckExt.tPow2x[0] = min((u16) | ||
997 | targetPowerCckExt.tPow2x[0], | ||
998 | minCtlPower); | ||
999 | break; | ||
1000 | case CTL_11G_EXT: | ||
1001 | targetPowerOfdmExt.tPow2x[0] = min((u16) | ||
1002 | targetPowerOfdmExt.tPow2x[0], | ||
1003 | minCtlPower); | ||
1004 | break; | ||
1005 | case CTL_2GHT40: | ||
1006 | for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); | ||
1007 | i++) { | ||
1008 | targetPowerHt40.tPow2x[i] = | ||
1009 | min((u16)targetPowerHt40.tPow2x[i], | ||
1010 | minCtlPower); | ||
1011 | } | ||
1012 | break; | ||
1013 | default: | ||
1014 | break; | ||
1015 | } | ||
1016 | } | ||
1017 | |||
1018 | ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = | ||
1019 | ratesArray[rate18mb] = ratesArray[rate24mb] = | ||
1020 | targetPowerOfdm.tPow2x[0]; | ||
1021 | ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; | ||
1022 | ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; | ||
1023 | ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; | ||
1024 | ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; | ||
1025 | |||
1026 | for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) | ||
1027 | ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; | ||
1028 | |||
1029 | ratesArray[rate1l] = targetPowerCck.tPow2x[0]; | ||
1030 | ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1]; | ||
1031 | ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2]; | ||
1032 | ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3]; | ||
1033 | |||
1034 | if (IS_CHAN_HT40(chan)) { | ||
1035 | for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { | ||
1036 | ratesArray[rateHt40_0 + i] = | ||
1037 | targetPowerHt40.tPow2x[i]; | ||
1038 | } | ||
1039 | ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; | ||
1040 | ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; | ||
1041 | ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; | ||
1042 | ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; | ||
1043 | } | ||
1044 | return true; | ||
1045 | } | ||
1046 | |||
1047 | static int ath9k_hw_4k_set_txpower(struct ath_hw *ah, | ||
1048 | struct ath9k_channel *chan, | ||
1049 | u16 cfgCtl, | ||
1050 | u8 twiceAntennaReduction, | ||
1051 | u8 twiceMaxRegulatoryPower, | ||
1052 | u8 powerLimit) | ||
1053 | { | ||
1054 | struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; | ||
1055 | struct modal_eep_4k_header *pModal = &pEepData->modalHeader; | ||
1056 | int16_t ratesArray[Ar5416RateSize]; | ||
1057 | int16_t txPowerIndexOffset = 0; | ||
1058 | u8 ht40PowerIncForPdadc = 2; | ||
1059 | int i; | ||
1060 | |||
1061 | memset(ratesArray, 0, sizeof(ratesArray)); | ||
1062 | |||
1063 | if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= | ||
1064 | AR5416_EEP_MINOR_VER_2) { | ||
1065 | ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; | ||
1066 | } | ||
1067 | |||
1068 | if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan, | ||
1069 | &ratesArray[0], cfgCtl, | ||
1070 | twiceAntennaReduction, | ||
1071 | twiceMaxRegulatoryPower, | ||
1072 | powerLimit)) { | ||
1073 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
1074 | "ath9k_hw_set_txpower: unable to set " | ||
1075 | "tx power per rate table\n"); | ||
1076 | return -EIO; | ||
1077 | } | ||
1078 | |||
1079 | if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) { | ||
1080 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
1081 | "ath9k_hw_set_txpower: unable to set power table\n"); | ||
1082 | return -EIO; | ||
1083 | } | ||
1084 | |||
1085 | for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { | ||
1086 | ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); | ||
1087 | if (ratesArray[i] > AR5416_MAX_RATE_POWER) | ||
1088 | ratesArray[i] = AR5416_MAX_RATE_POWER; | ||
1089 | } | ||
1090 | |||
1091 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
1092 | for (i = 0; i < Ar5416RateSize; i++) | ||
1093 | ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2; | ||
1094 | } | ||
1095 | |||
1096 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, | ||
1097 | ATH9K_POW_SM(ratesArray[rate18mb], 24) | ||
1098 | | ATH9K_POW_SM(ratesArray[rate12mb], 16) | ||
1099 | | ATH9K_POW_SM(ratesArray[rate9mb], 8) | ||
1100 | | ATH9K_POW_SM(ratesArray[rate6mb], 0)); | ||
1101 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, | ||
1102 | ATH9K_POW_SM(ratesArray[rate54mb], 24) | ||
1103 | | ATH9K_POW_SM(ratesArray[rate48mb], 16) | ||
1104 | | ATH9K_POW_SM(ratesArray[rate36mb], 8) | ||
1105 | | ATH9K_POW_SM(ratesArray[rate24mb], 0)); | ||
1106 | |||
1107 | if (IS_CHAN_2GHZ(chan)) { | ||
1108 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, | ||
1109 | ATH9K_POW_SM(ratesArray[rate2s], 24) | ||
1110 | | ATH9K_POW_SM(ratesArray[rate2l], 16) | ||
1111 | | ATH9K_POW_SM(ratesArray[rateXr], 8) | ||
1112 | | ATH9K_POW_SM(ratesArray[rate1l], 0)); | ||
1113 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, | ||
1114 | ATH9K_POW_SM(ratesArray[rate11s], 24) | ||
1115 | | ATH9K_POW_SM(ratesArray[rate11l], 16) | ||
1116 | | ATH9K_POW_SM(ratesArray[rate5_5s], 8) | ||
1117 | | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); | ||
1118 | } | ||
1119 | |||
1120 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, | ||
1121 | ATH9K_POW_SM(ratesArray[rateHt20_3], 24) | ||
1122 | | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) | ||
1123 | | ATH9K_POW_SM(ratesArray[rateHt20_1], 8) | ||
1124 | | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)); | ||
1125 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, | ||
1126 | ATH9K_POW_SM(ratesArray[rateHt20_7], 24) | ||
1127 | | ATH9K_POW_SM(ratesArray[rateHt20_6], 16) | ||
1128 | | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) | ||
1129 | | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); | ||
1130 | |||
1131 | if (IS_CHAN_HT40(chan)) { | ||
1132 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, | ||
1133 | ATH9K_POW_SM(ratesArray[rateHt40_3] + | ||
1134 | ht40PowerIncForPdadc, 24) | ||
1135 | | ATH9K_POW_SM(ratesArray[rateHt40_2] + | ||
1136 | ht40PowerIncForPdadc, 16) | ||
1137 | | ATH9K_POW_SM(ratesArray[rateHt40_1] + | ||
1138 | ht40PowerIncForPdadc, 8) | ||
1139 | | ATH9K_POW_SM(ratesArray[rateHt40_0] + | ||
1140 | ht40PowerIncForPdadc, 0)); | ||
1141 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, | ||
1142 | ATH9K_POW_SM(ratesArray[rateHt40_7] + | ||
1143 | ht40PowerIncForPdadc, 24) | ||
1144 | | ATH9K_POW_SM(ratesArray[rateHt40_6] + | ||
1145 | ht40PowerIncForPdadc, 16) | ||
1146 | | ATH9K_POW_SM(ratesArray[rateHt40_5] + | ||
1147 | ht40PowerIncForPdadc, 8) | ||
1148 | | ATH9K_POW_SM(ratesArray[rateHt40_4] + | ||
1149 | ht40PowerIncForPdadc, 0)); | ||
1150 | |||
1151 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, | ||
1152 | ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) | ||
1153 | | ATH9K_POW_SM(ratesArray[rateExtCck], 16) | ||
1154 | | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) | ||
1155 | | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); | ||
1156 | } | ||
1157 | |||
1158 | i = rate6mb; | ||
1159 | |||
1160 | if (IS_CHAN_HT40(chan)) | ||
1161 | i = rateHt40_0; | ||
1162 | else if (IS_CHAN_HT20(chan)) | ||
1163 | i = rateHt20_0; | ||
1164 | |||
1165 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
1166 | ah->regulatory.max_power_level = | ||
1167 | ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2; | ||
1168 | else | ||
1169 | ah->regulatory.max_power_level = ratesArray[i]; | ||
1170 | |||
1171 | return 0; | ||
1172 | } | ||
1173 | |||
1174 | static void ath9k_hw_4k_set_addac(struct ath_hw *ah, | ||
1175 | struct ath9k_channel *chan) | ||
1176 | { | ||
1177 | struct modal_eep_4k_header *pModal; | ||
1178 | struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; | ||
1179 | u8 biaslevel; | ||
1180 | |||
1181 | if (ah->hw_version.macVersion != AR_SREV_VERSION_9160) | ||
1182 | return; | ||
1183 | |||
1184 | if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7) | ||
1185 | return; | ||
1186 | |||
1187 | pModal = &eep->modalHeader; | ||
1188 | |||
1189 | if (pModal->xpaBiasLvl != 0xff) { | ||
1190 | biaslevel = pModal->xpaBiasLvl; | ||
1191 | INI_RA(&ah->iniAddac, 7, 1) = | ||
1192 | (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3; | ||
1193 | } | ||
1194 | } | ||
1195 | |||
1196 | static void ath9k_hw_4k_set_gain(struct ath_hw *ah, | ||
1197 | struct modal_eep_4k_header *pModal, | ||
1198 | struct ar5416_eeprom_4k *eep, | ||
1199 | u8 txRxAttenLocal, int regChainOffset) | ||
1200 | { | ||
1201 | REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, | ||
1202 | pModal->antCtrlChain[0]); | ||
1203 | |||
1204 | REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, | ||
1205 | (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) & | ||
1206 | ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | | ||
1207 | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | | ||
1208 | SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | | ||
1209 | SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); | ||
1210 | |||
1211 | if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= | ||
1212 | AR5416_EEP_MINOR_VER_3) { | ||
1213 | txRxAttenLocal = pModal->txRxAttenCh[0]; | ||
1214 | |||
1215 | REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, | ||
1216 | AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]); | ||
1217 | REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, | ||
1218 | AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]); | ||
1219 | REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, | ||
1220 | AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, | ||
1221 | pModal->xatten2Margin[0]); | ||
1222 | REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, | ||
1223 | AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]); | ||
1224 | } | ||
1225 | |||
1226 | REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, | ||
1227 | AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); | ||
1228 | REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, | ||
1229 | AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); | ||
1230 | |||
1231 | if (AR_SREV_9285_11(ah)) | ||
1232 | REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); | ||
1233 | } | ||
1234 | |||
1235 | static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, | ||
1236 | struct ath9k_channel *chan) | ||
1237 | { | ||
1238 | struct modal_eep_4k_header *pModal; | ||
1239 | struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; | ||
1240 | u8 txRxAttenLocal; | ||
1241 | u8 ob[5], db1[5], db2[5]; | ||
1242 | u8 ant_div_control1, ant_div_control2; | ||
1243 | u32 regVal; | ||
1244 | |||
1245 | pModal = &eep->modalHeader; | ||
1246 | txRxAttenLocal = 23; | ||
1247 | |||
1248 | REG_WRITE(ah, AR_PHY_SWITCH_COM, | ||
1249 | ah->eep_ops->get_eeprom_antenna_cfg(ah, chan)); | ||
1250 | |||
1251 | /* Single chain for 4K EEPROM*/ | ||
1252 | ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal, 0); | ||
1253 | |||
1254 | /* Initialize Ant Diversity settings from EEPROM */ | ||
1255 | if (pModal->version == 3) { | ||
1256 | ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf); | ||
1257 | ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf); | ||
1258 | regVal = REG_READ(ah, 0x99ac); | ||
1259 | regVal &= (~(0x7f000000)); | ||
1260 | regVal |= ((ant_div_control1 & 0x1) << 24); | ||
1261 | regVal |= (((ant_div_control1 >> 1) & 0x1) << 29); | ||
1262 | regVal |= (((ant_div_control1 >> 2) & 0x1) << 30); | ||
1263 | regVal |= ((ant_div_control2 & 0x3) << 25); | ||
1264 | regVal |= (((ant_div_control2 >> 2) & 0x3) << 27); | ||
1265 | REG_WRITE(ah, 0x99ac, regVal); | ||
1266 | regVal = REG_READ(ah, 0x99ac); | ||
1267 | regVal = REG_READ(ah, 0xa208); | ||
1268 | regVal &= (~(0x1 << 13)); | ||
1269 | regVal |= (((ant_div_control1 >> 3) & 0x1) << 13); | ||
1270 | REG_WRITE(ah, 0xa208, regVal); | ||
1271 | regVal = REG_READ(ah, 0xa208); | ||
1272 | } | ||
1273 | |||
1274 | if (pModal->version >= 2) { | ||
1275 | ob[0] = (pModal->ob_01 & 0xf); | ||
1276 | ob[1] = (pModal->ob_01 >> 4) & 0xf; | ||
1277 | ob[2] = (pModal->ob_234 & 0xf); | ||
1278 | ob[3] = ((pModal->ob_234 >> 4) & 0xf); | ||
1279 | ob[4] = ((pModal->ob_234 >> 8) & 0xf); | ||
1280 | |||
1281 | db1[0] = (pModal->db1_01 & 0xf); | ||
1282 | db1[1] = ((pModal->db1_01 >> 4) & 0xf); | ||
1283 | db1[2] = (pModal->db1_234 & 0xf); | ||
1284 | db1[3] = ((pModal->db1_234 >> 4) & 0xf); | ||
1285 | db1[4] = ((pModal->db1_234 >> 8) & 0xf); | ||
1286 | |||
1287 | db2[0] = (pModal->db2_01 & 0xf); | ||
1288 | db2[1] = ((pModal->db2_01 >> 4) & 0xf); | ||
1289 | db2[2] = (pModal->db2_234 & 0xf); | ||
1290 | db2[3] = ((pModal->db2_234 >> 4) & 0xf); | ||
1291 | db2[4] = ((pModal->db2_234 >> 8) & 0xf); | ||
1292 | |||
1293 | } else if (pModal->version == 1) { | ||
1294 | ob[0] = (pModal->ob_01 & 0xf); | ||
1295 | ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf; | ||
1296 | db1[0] = (pModal->db1_01 & 0xf); | ||
1297 | db1[1] = db1[2] = db1[3] = | ||
1298 | db1[4] = ((pModal->db1_01 >> 4) & 0xf); | ||
1299 | db2[0] = (pModal->db2_01 & 0xf); | ||
1300 | db2[1] = db2[2] = db2[3] = | ||
1301 | db2[4] = ((pModal->db2_01 >> 4) & 0xf); | ||
1302 | } else { | ||
1303 | int i; | ||
1304 | for (i = 0; i < 5; i++) { | ||
1305 | ob[i] = pModal->ob_01; | ||
1306 | db1[i] = pModal->db1_01; | ||
1307 | db2[i] = pModal->db1_01; | ||
1308 | } | ||
1309 | } | ||
1310 | |||
1311 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
1312 | AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]); | ||
1313 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
1314 | AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]); | ||
1315 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
1316 | AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]); | ||
1317 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
1318 | AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]); | ||
1319 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
1320 | AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]); | ||
1321 | |||
1322 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
1323 | AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]); | ||
1324 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
1325 | AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]); | ||
1326 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, | ||
1327 | AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]); | ||
1328 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | ||
1329 | AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]); | ||
1330 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | ||
1331 | AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]); | ||
1332 | |||
1333 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | ||
1334 | AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]); | ||
1335 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | ||
1336 | AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]); | ||
1337 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | ||
1338 | AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]); | ||
1339 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | ||
1340 | AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]); | ||
1341 | ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, | ||
1342 | AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]); | ||
1343 | |||
1344 | |||
1345 | if (AR_SREV_9285_11(ah)) | ||
1346 | REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); | ||
1347 | |||
1348 | REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, | ||
1349 | pModal->switchSettling); | ||
1350 | REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, | ||
1351 | pModal->adcDesiredSize); | ||
1352 | |||
1353 | REG_WRITE(ah, AR_PHY_RF_CTL4, | ||
1354 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) | | ||
1355 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) | | ||
1356 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) | | ||
1357 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); | ||
1358 | |||
1359 | REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, | ||
1360 | pModal->txEndToRxOn); | ||
1361 | REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, | ||
1362 | pModal->thresh62); | ||
1363 | REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, | ||
1364 | pModal->thresh62); | ||
1365 | |||
1366 | if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= | ||
1367 | AR5416_EEP_MINOR_VER_2) { | ||
1368 | REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START, | ||
1369 | pModal->txFrameToDataStart); | ||
1370 | REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON, | ||
1371 | pModal->txFrameToPaOn); | ||
1372 | } | ||
1373 | |||
1374 | if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= | ||
1375 | AR5416_EEP_MINOR_VER_3) { | ||
1376 | if (IS_CHAN_HT40(chan)) | ||
1377 | REG_RMW_FIELD(ah, AR_PHY_SETTLING, | ||
1378 | AR_PHY_SETTLING_SWITCH, | ||
1379 | pModal->swSettleHt40); | ||
1380 | } | ||
1381 | } | ||
1382 | |||
1383 | static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah, | ||
1384 | struct ath9k_channel *chan) | ||
1385 | { | ||
1386 | struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; | ||
1387 | struct modal_eep_4k_header *pModal = &eep->modalHeader; | ||
1388 | |||
1389 | return pModal->antCtrlCommon & 0xFFFF; | ||
1390 | } | ||
1391 | |||
1392 | static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah, | ||
1393 | enum ieee80211_band freq_band) | ||
1394 | { | ||
1395 | return 1; | ||
1396 | } | ||
1397 | |||
1398 | static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) | ||
1399 | { | ||
1400 | #define EEP_MAP4K_SPURCHAN \ | ||
1401 | (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan) | ||
1402 | |||
1403 | u16 spur_val = AR_NO_SPUR; | ||
1404 | |||
1405 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
1406 | "Getting spur idx %d is2Ghz. %d val %x\n", | ||
1407 | i, is2GHz, ah->config.spurchans[i][is2GHz]); | ||
1408 | |||
1409 | switch (ah->config.spurmode) { | ||
1410 | case SPUR_DISABLE: | ||
1411 | break; | ||
1412 | case SPUR_ENABLE_IOCTL: | ||
1413 | spur_val = ah->config.spurchans[i][is2GHz]; | ||
1414 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
1415 | "Getting spur val from new loc. %d\n", spur_val); | ||
1416 | break; | ||
1417 | case SPUR_ENABLE_EEPROM: | ||
1418 | spur_val = EEP_MAP4K_SPURCHAN; | ||
1419 | break; | ||
1420 | } | ||
1421 | |||
1422 | return spur_val; | ||
1423 | |||
1424 | #undef EEP_MAP4K_SPURCHAN | ||
1425 | } | ||
1426 | |||
1427 | static struct eeprom_ops eep_4k_ops = { | ||
1428 | .check_eeprom = ath9k_hw_4k_check_eeprom, | ||
1429 | .get_eeprom = ath9k_hw_4k_get_eeprom, | ||
1430 | .fill_eeprom = ath9k_hw_4k_fill_eeprom, | ||
1431 | .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver, | ||
1432 | .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev, | ||
1433 | .get_num_ant_config = ath9k_hw_4k_get_num_ant_config, | ||
1434 | .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg, | ||
1435 | .set_board_values = ath9k_hw_4k_set_board_values, | ||
1436 | .set_addac = ath9k_hw_4k_set_addac, | ||
1437 | .set_txpower = ath9k_hw_4k_set_txpower, | ||
1438 | .get_spur_channel = ath9k_hw_4k_get_spur_channel | ||
1439 | }; | ||
1440 | |||
1441 | /************************************************/ | ||
1442 | /* EEPROM Operations for non-4K (Default) cards */ | ||
1443 | /************************************************/ | ||
1444 | |||
1445 | static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah) | ||
1446 | { | ||
1447 | return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF); | ||
1448 | } | ||
1449 | |||
1450 | static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah) | ||
1451 | { | ||
1452 | return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF); | ||
1453 | } | ||
1454 | |||
1455 | static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah) | ||
1456 | { | ||
1457 | #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16)) | ||
1458 | u16 *eep_data = (u16 *)&ah->eeprom.def; | ||
1459 | int addr, ar5416_eep_start_loc = 0x100; | ||
1460 | |||
1461 | for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) { | ||
1462 | if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc, | ||
1463 | eep_data)) { | ||
1464 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
1465 | "Unable to read eeprom region\n"); | ||
1466 | return false; | ||
1467 | } | ||
1468 | eep_data++; | ||
1469 | } | ||
1470 | return true; | ||
1471 | #undef SIZE_EEPROM_DEF | ||
1472 | } | ||
1473 | |||
1474 | static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) | ||
1475 | { | ||
1476 | struct ar5416_eeprom_def *eep = | ||
1477 | (struct ar5416_eeprom_def *) &ah->eeprom.def; | ||
1478 | u16 *eepdata, temp, magic, magic2; | ||
1479 | u32 sum = 0, el; | ||
1480 | bool need_swap = false; | ||
1481 | int i, addr, size; | ||
1482 | |||
1483 | if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { | ||
1484 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n"); | ||
1485 | return false; | ||
1486 | } | ||
1487 | |||
1488 | if (!ath9k_hw_use_flash(ah)) { | ||
1489 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
1490 | "Read Magic = 0x%04X\n", magic); | ||
1491 | |||
1492 | if (magic != AR5416_EEPROM_MAGIC) { | ||
1493 | magic2 = swab16(magic); | ||
1494 | |||
1495 | if (magic2 == AR5416_EEPROM_MAGIC) { | ||
1496 | size = sizeof(struct ar5416_eeprom_def); | ||
1497 | need_swap = true; | ||
1498 | eepdata = (u16 *) (&ah->eeprom); | ||
1499 | |||
1500 | for (addr = 0; addr < size / sizeof(u16); addr++) { | ||
1501 | temp = swab16(*eepdata); | ||
1502 | *eepdata = temp; | ||
1503 | eepdata++; | ||
1504 | } | ||
1505 | } else { | ||
1506 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
1507 | "Invalid EEPROM Magic. " | ||
1508 | "Endianness mismatch.\n"); | ||
1509 | return -EINVAL; | ||
1510 | } | ||
1511 | } | ||
1512 | } | ||
1513 | |||
1514 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n", | ||
1515 | need_swap ? "True" : "False"); | ||
1516 | |||
1517 | if (need_swap) | ||
1518 | el = swab16(ah->eeprom.def.baseEepHeader.length); | ||
1519 | else | ||
1520 | el = ah->eeprom.def.baseEepHeader.length; | ||
1521 | |||
1522 | if (el > sizeof(struct ar5416_eeprom_def)) | ||
1523 | el = sizeof(struct ar5416_eeprom_def) / sizeof(u16); | ||
1524 | else | ||
1525 | el = el / sizeof(u16); | ||
1526 | |||
1527 | eepdata = (u16 *)(&ah->eeprom); | ||
1528 | |||
1529 | for (i = 0; i < el; i++) | ||
1530 | sum ^= *eepdata++; | ||
1531 | |||
1532 | if (need_swap) { | ||
1533 | u32 integer, j; | ||
1534 | u16 word; | ||
1535 | |||
1536 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
1537 | "EEPROM Endianness is not native.. Changing.\n"); | ||
1538 | |||
1539 | word = swab16(eep->baseEepHeader.length); | ||
1540 | eep->baseEepHeader.length = word; | ||
1541 | |||
1542 | word = swab16(eep->baseEepHeader.checksum); | ||
1543 | eep->baseEepHeader.checksum = word; | ||
1544 | |||
1545 | word = swab16(eep->baseEepHeader.version); | ||
1546 | eep->baseEepHeader.version = word; | ||
1547 | |||
1548 | word = swab16(eep->baseEepHeader.regDmn[0]); | ||
1549 | eep->baseEepHeader.regDmn[0] = word; | ||
1550 | |||
1551 | word = swab16(eep->baseEepHeader.regDmn[1]); | ||
1552 | eep->baseEepHeader.regDmn[1] = word; | ||
1553 | |||
1554 | word = swab16(eep->baseEepHeader.rfSilent); | ||
1555 | eep->baseEepHeader.rfSilent = word; | ||
1556 | |||
1557 | word = swab16(eep->baseEepHeader.blueToothOptions); | ||
1558 | eep->baseEepHeader.blueToothOptions = word; | ||
1559 | |||
1560 | word = swab16(eep->baseEepHeader.deviceCap); | ||
1561 | eep->baseEepHeader.deviceCap = word; | ||
1562 | |||
1563 | for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) { | ||
1564 | struct modal_eep_header *pModal = | ||
1565 | &eep->modalHeader[j]; | ||
1566 | integer = swab32(pModal->antCtrlCommon); | ||
1567 | pModal->antCtrlCommon = integer; | ||
1568 | |||
1569 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
1570 | integer = swab32(pModal->antCtrlChain[i]); | ||
1571 | pModal->antCtrlChain[i] = integer; | ||
1572 | } | ||
1573 | |||
1574 | for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { | ||
1575 | word = swab16(pModal->spurChans[i].spurChan); | ||
1576 | pModal->spurChans[i].spurChan = word; | ||
1577 | } | ||
1578 | } | ||
1579 | } | ||
1580 | |||
1581 | if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER || | ||
1582 | ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) { | ||
1583 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
1584 | "Bad EEPROM checksum 0x%x or revision 0x%04x\n", | ||
1585 | sum, ah->eep_ops->get_eeprom_ver(ah)); | ||
1586 | return -EINVAL; | ||
1587 | } | ||
1588 | |||
1589 | return 0; | ||
1590 | } | ||
1591 | |||
1592 | static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah, | ||
1593 | enum eeprom_param param) | ||
1594 | { | ||
1595 | struct ar5416_eeprom_def *eep = &ah->eeprom.def; | ||
1596 | struct modal_eep_header *pModal = eep->modalHeader; | ||
1597 | struct base_eep_header *pBase = &eep->baseEepHeader; | ||
1598 | |||
1599 | switch (param) { | ||
1600 | case EEP_NFTHRESH_5: | ||
1601 | return pModal[0].noiseFloorThreshCh[0]; | ||
1602 | case EEP_NFTHRESH_2: | ||
1603 | return pModal[1].noiseFloorThreshCh[0]; | ||
1604 | case AR_EEPROM_MAC(0): | ||
1605 | return pBase->macAddr[0] << 8 | pBase->macAddr[1]; | ||
1606 | case AR_EEPROM_MAC(1): | ||
1607 | return pBase->macAddr[2] << 8 | pBase->macAddr[3]; | ||
1608 | case AR_EEPROM_MAC(2): | ||
1609 | return pBase->macAddr[4] << 8 | pBase->macAddr[5]; | ||
1610 | case EEP_REG_0: | ||
1611 | return pBase->regDmn[0]; | ||
1612 | case EEP_REG_1: | ||
1613 | return pBase->regDmn[1]; | ||
1614 | case EEP_OP_CAP: | ||
1615 | return pBase->deviceCap; | ||
1616 | case EEP_OP_MODE: | ||
1617 | return pBase->opCapFlags; | ||
1618 | case EEP_RF_SILENT: | ||
1619 | return pBase->rfSilent; | ||
1620 | case EEP_OB_5: | ||
1621 | return pModal[0].ob; | ||
1622 | case EEP_DB_5: | ||
1623 | return pModal[0].db; | ||
1624 | case EEP_OB_2: | ||
1625 | return pModal[1].ob; | ||
1626 | case EEP_DB_2: | ||
1627 | return pModal[1].db; | ||
1628 | case EEP_MINOR_REV: | ||
1629 | return AR5416_VER_MASK; | ||
1630 | case EEP_TX_MASK: | ||
1631 | return pBase->txMask; | ||
1632 | case EEP_RX_MASK: | ||
1633 | return pBase->rxMask; | ||
1634 | case EEP_RXGAIN_TYPE: | ||
1635 | return pBase->rxGainType; | ||
1636 | case EEP_TXGAIN_TYPE: | ||
1637 | return pBase->txGainType; | ||
1638 | case EEP_OL_PWRCTRL: | ||
1639 | if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) | ||
1640 | return pBase->openLoopPwrCntl ? true : false; | ||
1641 | else | ||
1642 | return false; | ||
1643 | case EEP_RC_CHAIN_MASK: | ||
1644 | if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) | ||
1645 | return pBase->rcChainMask; | ||
1646 | else | ||
1647 | return 0; | ||
1648 | case EEP_DAC_HPWR_5G: | ||
1649 | if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) | ||
1650 | return pBase->dacHiPwrMode_5G; | ||
1651 | else | ||
1652 | return 0; | ||
1653 | case EEP_FRAC_N_5G: | ||
1654 | if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22) | ||
1655 | return pBase->frac_n_5g; | ||
1656 | else | ||
1657 | return 0; | ||
1658 | default: | ||
1659 | return 0; | ||
1660 | } | ||
1661 | } | ||
1662 | |||
1663 | static void ath9k_hw_def_set_gain(struct ath_hw *ah, | ||
1664 | struct modal_eep_header *pModal, | ||
1665 | struct ar5416_eeprom_def *eep, | ||
1666 | u8 txRxAttenLocal, int regChainOffset, int i) | ||
1667 | { | ||
1668 | if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { | ||
1669 | txRxAttenLocal = pModal->txRxAttenCh[i]; | ||
1670 | |||
1671 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
1672 | REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, | ||
1673 | AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, | ||
1674 | pModal->bswMargin[i]); | ||
1675 | REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, | ||
1676 | AR_PHY_GAIN_2GHZ_XATTEN1_DB, | ||
1677 | pModal->bswAtten[i]); | ||
1678 | REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, | ||
1679 | AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, | ||
1680 | pModal->xatten2Margin[i]); | ||
1681 | REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, | ||
1682 | AR_PHY_GAIN_2GHZ_XATTEN2_DB, | ||
1683 | pModal->xatten2Db[i]); | ||
1684 | } else { | ||
1685 | REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, | ||
1686 | (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & | ||
1687 | ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) | ||
1688 | | SM(pModal-> bswMargin[i], | ||
1689 | AR_PHY_GAIN_2GHZ_BSW_MARGIN)); | ||
1690 | REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, | ||
1691 | (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & | ||
1692 | ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) | ||
1693 | | SM(pModal->bswAtten[i], | ||
1694 | AR_PHY_GAIN_2GHZ_BSW_ATTEN)); | ||
1695 | } | ||
1696 | } | ||
1697 | |||
1698 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
1699 | REG_RMW_FIELD(ah, | ||
1700 | AR_PHY_RXGAIN + regChainOffset, | ||
1701 | AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); | ||
1702 | REG_RMW_FIELD(ah, | ||
1703 | AR_PHY_RXGAIN + regChainOffset, | ||
1704 | AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]); | ||
1705 | } else { | ||
1706 | REG_WRITE(ah, | ||
1707 | AR_PHY_RXGAIN + regChainOffset, | ||
1708 | (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) & | ||
1709 | ~AR_PHY_RXGAIN_TXRX_ATTEN) | ||
1710 | | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN)); | ||
1711 | REG_WRITE(ah, | ||
1712 | AR_PHY_GAIN_2GHZ + regChainOffset, | ||
1713 | (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & | ||
1714 | ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) | | ||
1715 | SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN)); | ||
1716 | } | ||
1717 | } | ||
1718 | |||
1719 | static void ath9k_hw_def_set_board_values(struct ath_hw *ah, | ||
1720 | struct ath9k_channel *chan) | ||
1721 | { | ||
1722 | struct modal_eep_header *pModal; | ||
1723 | struct ar5416_eeprom_def *eep = &ah->eeprom.def; | ||
1724 | int i, regChainOffset; | ||
1725 | u8 txRxAttenLocal; | ||
1726 | |||
1727 | pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); | ||
1728 | txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; | ||
1729 | |||
1730 | REG_WRITE(ah, AR_PHY_SWITCH_COM, | ||
1731 | ah->eep_ops->get_eeprom_antenna_cfg(ah, chan)); | ||
1732 | |||
1733 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
1734 | if (AR_SREV_9280(ah)) { | ||
1735 | if (i >= 2) | ||
1736 | break; | ||
1737 | } | ||
1738 | |||
1739 | if (AR_SREV_5416_20_OR_LATER(ah) && | ||
1740 | (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0)) | ||
1741 | regChainOffset = (i == 1) ? 0x2000 : 0x1000; | ||
1742 | else | ||
1743 | regChainOffset = i * 0x1000; | ||
1744 | |||
1745 | REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, | ||
1746 | pModal->antCtrlChain[i]); | ||
1747 | |||
1748 | REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset, | ||
1749 | (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) & | ||
1750 | ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | | ||
1751 | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | | ||
1752 | SM(pModal->iqCalICh[i], | ||
1753 | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | | ||
1754 | SM(pModal->iqCalQCh[i], | ||
1755 | AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); | ||
1756 | |||
1757 | if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) | ||
1758 | ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal, | ||
1759 | regChainOffset, i); | ||
1760 | } | ||
1761 | |||
1762 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
1763 | if (IS_CHAN_2GHZ(chan)) { | ||
1764 | ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0, | ||
1765 | AR_AN_RF2G1_CH0_OB, | ||
1766 | AR_AN_RF2G1_CH0_OB_S, | ||
1767 | pModal->ob); | ||
1768 | ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0, | ||
1769 | AR_AN_RF2G1_CH0_DB, | ||
1770 | AR_AN_RF2G1_CH0_DB_S, | ||
1771 | pModal->db); | ||
1772 | ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1, | ||
1773 | AR_AN_RF2G1_CH1_OB, | ||
1774 | AR_AN_RF2G1_CH1_OB_S, | ||
1775 | pModal->ob_ch1); | ||
1776 | ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1, | ||
1777 | AR_AN_RF2G1_CH1_DB, | ||
1778 | AR_AN_RF2G1_CH1_DB_S, | ||
1779 | pModal->db_ch1); | ||
1780 | } else { | ||
1781 | ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0, | ||
1782 | AR_AN_RF5G1_CH0_OB5, | ||
1783 | AR_AN_RF5G1_CH0_OB5_S, | ||
1784 | pModal->ob); | ||
1785 | ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0, | ||
1786 | AR_AN_RF5G1_CH0_DB5, | ||
1787 | AR_AN_RF5G1_CH0_DB5_S, | ||
1788 | pModal->db); | ||
1789 | ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1, | ||
1790 | AR_AN_RF5G1_CH1_OB5, | ||
1791 | AR_AN_RF5G1_CH1_OB5_S, | ||
1792 | pModal->ob_ch1); | ||
1793 | ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1, | ||
1794 | AR_AN_RF5G1_CH1_DB5, | ||
1795 | AR_AN_RF5G1_CH1_DB5_S, | ||
1796 | pModal->db_ch1); | ||
1797 | } | ||
1798 | ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, | ||
1799 | AR_AN_TOP2_XPABIAS_LVL, | ||
1800 | AR_AN_TOP2_XPABIAS_LVL_S, | ||
1801 | pModal->xpaBiasLvl); | ||
1802 | ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, | ||
1803 | AR_AN_TOP2_LOCALBIAS, | ||
1804 | AR_AN_TOP2_LOCALBIAS_S, | ||
1805 | pModal->local_bias); | ||
1806 | REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, | ||
1807 | pModal->force_xpaon); | ||
1808 | } | ||
1809 | |||
1810 | REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, | ||
1811 | pModal->switchSettling); | ||
1812 | REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, | ||
1813 | pModal->adcDesiredSize); | ||
1814 | |||
1815 | if (!AR_SREV_9280_10_OR_LATER(ah)) | ||
1816 | REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, | ||
1817 | AR_PHY_DESIRED_SZ_PGA, | ||
1818 | pModal->pgaDesiredSize); | ||
1819 | |||
1820 | REG_WRITE(ah, AR_PHY_RF_CTL4, | ||
1821 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) | ||
1822 | | SM(pModal->txEndToXpaOff, | ||
1823 | AR_PHY_RF_CTL4_TX_END_XPAB_OFF) | ||
1824 | | SM(pModal->txFrameToXpaOn, | ||
1825 | AR_PHY_RF_CTL4_FRAME_XPAA_ON) | ||
1826 | | SM(pModal->txFrameToXpaOn, | ||
1827 | AR_PHY_RF_CTL4_FRAME_XPAB_ON)); | ||
1828 | |||
1829 | REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, | ||
1830 | pModal->txEndToRxOn); | ||
1831 | |||
1832 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
1833 | REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, | ||
1834 | pModal->thresh62); | ||
1835 | REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, | ||
1836 | AR_PHY_EXT_CCA0_THRESH62, | ||
1837 | pModal->thresh62); | ||
1838 | } else { | ||
1839 | REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62, | ||
1840 | pModal->thresh62); | ||
1841 | REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, | ||
1842 | AR_PHY_EXT_CCA_THRESH62, | ||
1843 | pModal->thresh62); | ||
1844 | } | ||
1845 | |||
1846 | if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) { | ||
1847 | REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, | ||
1848 | AR_PHY_TX_END_DATA_START, | ||
1849 | pModal->txFrameToDataStart); | ||
1850 | REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON, | ||
1851 | pModal->txFrameToPaOn); | ||
1852 | } | ||
1853 | |||
1854 | if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { | ||
1855 | if (IS_CHAN_HT40(chan)) | ||
1856 | REG_RMW_FIELD(ah, AR_PHY_SETTLING, | ||
1857 | AR_PHY_SETTLING_SWITCH, | ||
1858 | pModal->swSettleHt40); | ||
1859 | } | ||
1860 | |||
1861 | if (AR_SREV_9280_20_OR_LATER(ah) && | ||
1862 | AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) | ||
1863 | REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL, | ||
1864 | AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK, | ||
1865 | pModal->miscBits); | ||
1866 | |||
1867 | |||
1868 | if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) { | ||
1869 | if (IS_CHAN_2GHZ(chan)) | ||
1870 | REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, | ||
1871 | eep->baseEepHeader.dacLpMode); | ||
1872 | else if (eep->baseEepHeader.dacHiPwrMode_5G) | ||
1873 | REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0); | ||
1874 | else | ||
1875 | REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, | ||
1876 | eep->baseEepHeader.dacLpMode); | ||
1877 | |||
1878 | REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP, | ||
1879 | pModal->miscBits >> 2); | ||
1880 | |||
1881 | REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9, | ||
1882 | AR_PHY_TX_DESIRED_SCALE_CCK, | ||
1883 | eep->baseEepHeader.desiredScaleCCK); | ||
1884 | } | ||
1885 | } | ||
1886 | |||
1887 | static void ath9k_hw_def_set_addac(struct ath_hw *ah, | ||
1888 | struct ath9k_channel *chan) | ||
1889 | { | ||
1890 | #define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt]) | ||
1891 | struct modal_eep_header *pModal; | ||
1892 | struct ar5416_eeprom_def *eep = &ah->eeprom.def; | ||
1893 | u8 biaslevel; | ||
1894 | |||
1895 | if (ah->hw_version.macVersion != AR_SREV_VERSION_9160) | ||
1896 | return; | ||
1897 | |||
1898 | if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7) | ||
1899 | return; | ||
1900 | |||
1901 | pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); | ||
1902 | |||
1903 | if (pModal->xpaBiasLvl != 0xff) { | ||
1904 | biaslevel = pModal->xpaBiasLvl; | ||
1905 | } else { | ||
1906 | u16 resetFreqBin, freqBin, freqCount = 0; | ||
1907 | struct chan_centers centers; | ||
1908 | |||
1909 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
1910 | |||
1911 | resetFreqBin = FREQ2FBIN(centers.synth_center, | ||
1912 | IS_CHAN_2GHZ(chan)); | ||
1913 | freqBin = XPA_LVL_FREQ(0) & 0xff; | ||
1914 | biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14); | ||
1915 | |||
1916 | freqCount++; | ||
1917 | |||
1918 | while (freqCount < 3) { | ||
1919 | if (XPA_LVL_FREQ(freqCount) == 0x0) | ||
1920 | break; | ||
1921 | |||
1922 | freqBin = XPA_LVL_FREQ(freqCount) & 0xff; | ||
1923 | if (resetFreqBin >= freqBin) | ||
1924 | biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14); | ||
1925 | else | ||
1926 | break; | ||
1927 | freqCount++; | ||
1928 | } | ||
1929 | } | ||
1930 | |||
1931 | if (IS_CHAN_2GHZ(chan)) { | ||
1932 | INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac, | ||
1933 | 7, 1) & (~0x18)) | biaslevel << 3; | ||
1934 | } else { | ||
1935 | INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac, | ||
1936 | 6, 1) & (~0xc0)) | biaslevel << 6; | ||
1937 | } | ||
1938 | #undef XPA_LVL_FREQ | ||
1939 | } | ||
1940 | |||
1941 | static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, | ||
1942 | struct ath9k_channel *chan, | ||
1943 | struct cal_data_per_freq *pRawDataSet, | ||
1944 | u8 *bChans, u16 availPiers, | ||
1945 | u16 tPdGainOverlap, int16_t *pMinCalPower, | ||
1946 | u16 *pPdGainBoundaries, u8 *pPDADCValues, | ||
1947 | u16 numXpdGains) | ||
1948 | { | ||
1949 | int i, j, k; | ||
1950 | int16_t ss; | ||
1951 | u16 idxL = 0, idxR = 0, numPiers; | ||
1952 | static u8 vpdTableL[AR5416_NUM_PD_GAINS] | ||
1953 | [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; | ||
1954 | static u8 vpdTableR[AR5416_NUM_PD_GAINS] | ||
1955 | [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; | ||
1956 | static u8 vpdTableI[AR5416_NUM_PD_GAINS] | ||
1957 | [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; | ||
1958 | |||
1959 | u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; | ||
1960 | u8 minPwrT4[AR5416_NUM_PD_GAINS]; | ||
1961 | u8 maxPwrT4[AR5416_NUM_PD_GAINS]; | ||
1962 | int16_t vpdStep; | ||
1963 | int16_t tmpVal; | ||
1964 | u16 sizeCurrVpdTable, maxIndex, tgtIndex; | ||
1965 | bool match; | ||
1966 | int16_t minDelta = 0; | ||
1967 | struct chan_centers centers; | ||
1968 | |||
1969 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
1970 | |||
1971 | for (numPiers = 0; numPiers < availPiers; numPiers++) { | ||
1972 | if (bChans[numPiers] == AR5416_BCHAN_UNUSED) | ||
1973 | break; | ||
1974 | } | ||
1975 | |||
1976 | match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center, | ||
1977 | IS_CHAN_2GHZ(chan)), | ||
1978 | bChans, numPiers, &idxL, &idxR); | ||
1979 | |||
1980 | if (match) { | ||
1981 | for (i = 0; i < numXpdGains; i++) { | ||
1982 | minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; | ||
1983 | maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; | ||
1984 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], | ||
1985 | pRawDataSet[idxL].pwrPdg[i], | ||
1986 | pRawDataSet[idxL].vpdPdg[i], | ||
1987 | AR5416_PD_GAIN_ICEPTS, | ||
1988 | vpdTableI[i]); | ||
1989 | } | ||
1990 | } else { | ||
1991 | for (i = 0; i < numXpdGains; i++) { | ||
1992 | pVpdL = pRawDataSet[idxL].vpdPdg[i]; | ||
1993 | pPwrL = pRawDataSet[idxL].pwrPdg[i]; | ||
1994 | pVpdR = pRawDataSet[idxR].vpdPdg[i]; | ||
1995 | pPwrR = pRawDataSet[idxR].pwrPdg[i]; | ||
1996 | |||
1997 | minPwrT4[i] = max(pPwrL[0], pPwrR[0]); | ||
1998 | |||
1999 | maxPwrT4[i] = | ||
2000 | min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], | ||
2001 | pPwrR[AR5416_PD_GAIN_ICEPTS - 1]); | ||
2002 | |||
2003 | |||
2004 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], | ||
2005 | pPwrL, pVpdL, | ||
2006 | AR5416_PD_GAIN_ICEPTS, | ||
2007 | vpdTableL[i]); | ||
2008 | ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], | ||
2009 | pPwrR, pVpdR, | ||
2010 | AR5416_PD_GAIN_ICEPTS, | ||
2011 | vpdTableR[i]); | ||
2012 | |||
2013 | for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { | ||
2014 | vpdTableI[i][j] = | ||
2015 | (u8)(ath9k_hw_interpolate((u16) | ||
2016 | FREQ2FBIN(centers. | ||
2017 | synth_center, | ||
2018 | IS_CHAN_2GHZ | ||
2019 | (chan)), | ||
2020 | bChans[idxL], bChans[idxR], | ||
2021 | vpdTableL[i][j], vpdTableR[i][j])); | ||
2022 | } | ||
2023 | } | ||
2024 | } | ||
2025 | |||
2026 | *pMinCalPower = (int16_t)(minPwrT4[0] / 2); | ||
2027 | |||
2028 | k = 0; | ||
2029 | |||
2030 | for (i = 0; i < numXpdGains; i++) { | ||
2031 | if (i == (numXpdGains - 1)) | ||
2032 | pPdGainBoundaries[i] = | ||
2033 | (u16)(maxPwrT4[i] / 2); | ||
2034 | else | ||
2035 | pPdGainBoundaries[i] = | ||
2036 | (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4); | ||
2037 | |||
2038 | pPdGainBoundaries[i] = | ||
2039 | min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); | ||
2040 | |||
2041 | if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { | ||
2042 | minDelta = pPdGainBoundaries[0] - 23; | ||
2043 | pPdGainBoundaries[0] = 23; | ||
2044 | } else { | ||
2045 | minDelta = 0; | ||
2046 | } | ||
2047 | |||
2048 | if (i == 0) { | ||
2049 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
2050 | ss = (int16_t)(0 - (minPwrT4[i] / 2)); | ||
2051 | else | ||
2052 | ss = 0; | ||
2053 | } else { | ||
2054 | ss = (int16_t)((pPdGainBoundaries[i - 1] - | ||
2055 | (minPwrT4[i] / 2)) - | ||
2056 | tPdGainOverlap + 1 + minDelta); | ||
2057 | } | ||
2058 | vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); | ||
2059 | vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); | ||
2060 | |||
2061 | while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { | ||
2062 | tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); | ||
2063 | pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); | ||
2064 | ss++; | ||
2065 | } | ||
2066 | |||
2067 | sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1); | ||
2068 | tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap - | ||
2069 | (minPwrT4[i] / 2)); | ||
2070 | maxIndex = (tgtIndex < sizeCurrVpdTable) ? | ||
2071 | tgtIndex : sizeCurrVpdTable; | ||
2072 | |||
2073 | while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { | ||
2074 | pPDADCValues[k++] = vpdTableI[i][ss++]; | ||
2075 | } | ||
2076 | |||
2077 | vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - | ||
2078 | vpdTableI[i][sizeCurrVpdTable - 2]); | ||
2079 | vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); | ||
2080 | |||
2081 | if (tgtIndex > maxIndex) { | ||
2082 | while ((ss <= tgtIndex) && | ||
2083 | (k < (AR5416_NUM_PDADC_VALUES - 1))) { | ||
2084 | tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] + | ||
2085 | (ss - maxIndex + 1) * vpdStep)); | ||
2086 | pPDADCValues[k++] = (u8)((tmpVal > 255) ? | ||
2087 | 255 : tmpVal); | ||
2088 | ss++; | ||
2089 | } | ||
2090 | } | ||
2091 | } | ||
2092 | |||
2093 | while (i < AR5416_PD_GAINS_IN_MASK) { | ||
2094 | pPdGainBoundaries[i] = pPdGainBoundaries[i - 1]; | ||
2095 | i++; | ||
2096 | } | ||
2097 | |||
2098 | while (k < AR5416_NUM_PDADC_VALUES) { | ||
2099 | pPDADCValues[k] = pPDADCValues[k - 1]; | ||
2100 | k++; | ||
2101 | } | ||
2102 | |||
2103 | return; | ||
2104 | } | ||
2105 | |||
2106 | static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, | ||
2107 | struct ath9k_channel *chan, | ||
2108 | int16_t *pTxPowerIndexOffset) | ||
2109 | { | ||
2110 | #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x) | ||
2111 | #define SM_PDGAIN_B(x, y) \ | ||
2112 | SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y) | ||
2113 | |||
2114 | struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; | ||
2115 | struct cal_data_per_freq *pRawDataset; | ||
2116 | u8 *pCalBChans = NULL; | ||
2117 | u16 pdGainOverlap_t2; | ||
2118 | static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; | ||
2119 | u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK]; | ||
2120 | u16 numPiers, i, j; | ||
2121 | int16_t tMinCalPower; | ||
2122 | u16 numXpdGain, xpdMask; | ||
2123 | u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 }; | ||
2124 | u32 reg32, regOffset, regChainOffset; | ||
2125 | int16_t modalIdx; | ||
2126 | |||
2127 | modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; | ||
2128 | xpdMask = pEepData->modalHeader[modalIdx].xpdGain; | ||
2129 | |||
2130 | if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= | ||
2131 | AR5416_EEP_MINOR_VER_2) { | ||
2132 | pdGainOverlap_t2 = | ||
2133 | pEepData->modalHeader[modalIdx].pdGainOverlap; | ||
2134 | } else { | ||
2135 | pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), | ||
2136 | AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); | ||
2137 | } | ||
2138 | |||
2139 | if (IS_CHAN_2GHZ(chan)) { | ||
2140 | pCalBChans = pEepData->calFreqPier2G; | ||
2141 | numPiers = AR5416_NUM_2G_CAL_PIERS; | ||
2142 | } else { | ||
2143 | pCalBChans = pEepData->calFreqPier5G; | ||
2144 | numPiers = AR5416_NUM_5G_CAL_PIERS; | ||
2145 | } | ||
2146 | |||
2147 | if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) { | ||
2148 | pRawDataset = pEepData->calPierData2G[0]; | ||
2149 | ah->initPDADC = ((struct calDataPerFreqOpLoop *) | ||
2150 | pRawDataset)->vpdPdg[0][0]; | ||
2151 | } | ||
2152 | |||
2153 | numXpdGain = 0; | ||
2154 | |||
2155 | for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { | ||
2156 | if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { | ||
2157 | if (numXpdGain >= AR5416_NUM_PD_GAINS) | ||
2158 | break; | ||
2159 | xpdGainValues[numXpdGain] = | ||
2160 | (u16)(AR5416_PD_GAINS_IN_MASK - i); | ||
2161 | numXpdGain++; | ||
2162 | } | ||
2163 | } | ||
2164 | |||
2165 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, | ||
2166 | (numXpdGain - 1) & 0x3); | ||
2167 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1, | ||
2168 | xpdGainValues[0]); | ||
2169 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2, | ||
2170 | xpdGainValues[1]); | ||
2171 | REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, | ||
2172 | xpdGainValues[2]); | ||
2173 | |||
2174 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
2175 | if (AR_SREV_5416_20_OR_LATER(ah) && | ||
2176 | (ah->rxchainmask == 5 || ah->txchainmask == 5) && | ||
2177 | (i != 0)) { | ||
2178 | regChainOffset = (i == 1) ? 0x2000 : 0x1000; | ||
2179 | } else | ||
2180 | regChainOffset = i * 0x1000; | ||
2181 | |||
2182 | if (pEepData->baseEepHeader.txMask & (1 << i)) { | ||
2183 | if (IS_CHAN_2GHZ(chan)) | ||
2184 | pRawDataset = pEepData->calPierData2G[i]; | ||
2185 | else | ||
2186 | pRawDataset = pEepData->calPierData5G[i]; | ||
2187 | |||
2188 | |||
2189 | if (OLC_FOR_AR9280_20_LATER) { | ||
2190 | u8 pcdacIdx; | ||
2191 | u8 txPower; | ||
2192 | |||
2193 | ath9k_get_txgain_index(ah, chan, | ||
2194 | (struct calDataPerFreqOpLoop *)pRawDataset, | ||
2195 | pCalBChans, numPiers, &txPower, &pcdacIdx); | ||
2196 | ath9k_olc_get_pdadcs(ah, pcdacIdx, | ||
2197 | txPower/2, pdadcValues); | ||
2198 | } else { | ||
2199 | ath9k_hw_get_def_gain_boundaries_pdadcs(ah, | ||
2200 | chan, pRawDataset, | ||
2201 | pCalBChans, numPiers, | ||
2202 | pdGainOverlap_t2, | ||
2203 | &tMinCalPower, | ||
2204 | gainBoundaries, | ||
2205 | pdadcValues, | ||
2206 | numXpdGain); | ||
2207 | } | ||
2208 | |||
2209 | if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { | ||
2210 | if (OLC_FOR_AR9280_20_LATER) { | ||
2211 | REG_WRITE(ah, | ||
2212 | AR_PHY_TPCRG5 + regChainOffset, | ||
2213 | SM(0x6, | ||
2214 | AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | | ||
2215 | SM_PD_GAIN(1) | SM_PD_GAIN(2) | | ||
2216 | SM_PD_GAIN(3) | SM_PD_GAIN(4)); | ||
2217 | } else { | ||
2218 | REG_WRITE(ah, | ||
2219 | AR_PHY_TPCRG5 + regChainOffset, | ||
2220 | SM(pdGainOverlap_t2, | ||
2221 | AR_PHY_TPCRG5_PD_GAIN_OVERLAP)| | ||
2222 | SM_PDGAIN_B(0, 1) | | ||
2223 | SM_PDGAIN_B(1, 2) | | ||
2224 | SM_PDGAIN_B(2, 3) | | ||
2225 | SM_PDGAIN_B(3, 4)); | ||
2226 | } | ||
2227 | } | ||
2228 | |||
2229 | regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; | ||
2230 | for (j = 0; j < 32; j++) { | ||
2231 | reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) | | ||
2232 | ((pdadcValues[4 * j + 1] & 0xFF) << 8) | | ||
2233 | ((pdadcValues[4 * j + 2] & 0xFF) << 16)| | ||
2234 | ((pdadcValues[4 * j + 3] & 0xFF) << 24); | ||
2235 | REG_WRITE(ah, regOffset, reg32); | ||
2236 | |||
2237 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
2238 | "PDADC (%d,%4x): %4.4x %8.8x\n", | ||
2239 | i, regChainOffset, regOffset, | ||
2240 | reg32); | ||
2241 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
2242 | "PDADC: Chain %d | PDADC %3d " | ||
2243 | "Value %3d | PDADC %3d Value %3d | " | ||
2244 | "PDADC %3d Value %3d | PDADC %3d " | ||
2245 | "Value %3d |\n", | ||
2246 | i, 4 * j, pdadcValues[4 * j], | ||
2247 | 4 * j + 1, pdadcValues[4 * j + 1], | ||
2248 | 4 * j + 2, pdadcValues[4 * j + 2], | ||
2249 | 4 * j + 3, | ||
2250 | pdadcValues[4 * j + 3]); | ||
2251 | |||
2252 | regOffset += 4; | ||
2253 | } | ||
2254 | } | ||
2255 | } | ||
2256 | |||
2257 | *pTxPowerIndexOffset = 0; | ||
2258 | |||
2259 | return true; | ||
2260 | #undef SM_PD_GAIN | ||
2261 | #undef SM_PDGAIN_B | ||
2262 | } | ||
2263 | |||
2264 | static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, | ||
2265 | struct ath9k_channel *chan, | ||
2266 | int16_t *ratesArray, | ||
2267 | u16 cfgCtl, | ||
2268 | u16 AntennaReduction, | ||
2269 | u16 twiceMaxRegulatoryPower, | ||
2270 | u16 powerLimit) | ||
2271 | { | ||
2272 | #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ | ||
2273 | #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */ | ||
2274 | |||
2275 | struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; | ||
2276 | u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; | ||
2277 | static const u16 tpScaleReductionTable[5] = | ||
2278 | { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; | ||
2279 | |||
2280 | int i; | ||
2281 | int16_t twiceLargestAntenna; | ||
2282 | struct cal_ctl_data *rep; | ||
2283 | struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { | ||
2284 | 0, { 0, 0, 0, 0} | ||
2285 | }; | ||
2286 | struct cal_target_power_leg targetPowerOfdmExt = { | ||
2287 | 0, { 0, 0, 0, 0} }, targetPowerCckExt = { | ||
2288 | 0, { 0, 0, 0, 0 } | ||
2289 | }; | ||
2290 | struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { | ||
2291 | 0, {0, 0, 0, 0} | ||
2292 | }; | ||
2293 | u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; | ||
2294 | u16 ctlModesFor11a[] = | ||
2295 | { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 }; | ||
2296 | u16 ctlModesFor11g[] = | ||
2297 | { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, | ||
2298 | CTL_2GHT40 | ||
2299 | }; | ||
2300 | u16 numCtlModes, *pCtlMode, ctlMode, freq; | ||
2301 | struct chan_centers centers; | ||
2302 | int tx_chainmask; | ||
2303 | u16 twiceMinEdgePower; | ||
2304 | |||
2305 | tx_chainmask = ah->txchainmask; | ||
2306 | |||
2307 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
2308 | |||
2309 | twiceLargestAntenna = max( | ||
2310 | pEepData->modalHeader | ||
2311 | [IS_CHAN_2GHZ(chan)].antennaGainCh[0], | ||
2312 | pEepData->modalHeader | ||
2313 | [IS_CHAN_2GHZ(chan)].antennaGainCh[1]); | ||
2314 | |||
2315 | twiceLargestAntenna = max((u8)twiceLargestAntenna, | ||
2316 | pEepData->modalHeader | ||
2317 | [IS_CHAN_2GHZ(chan)].antennaGainCh[2]); | ||
2318 | |||
2319 | twiceLargestAntenna = (int16_t)min(AntennaReduction - | ||
2320 | twiceLargestAntenna, 0); | ||
2321 | |||
2322 | maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; | ||
2323 | |||
2324 | if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) { | ||
2325 | maxRegAllowedPower -= | ||
2326 | (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2); | ||
2327 | } | ||
2328 | |||
2329 | scaledPower = min(powerLimit, maxRegAllowedPower); | ||
2330 | |||
2331 | switch (ar5416_get_ntxchains(tx_chainmask)) { | ||
2332 | case 1: | ||
2333 | break; | ||
2334 | case 2: | ||
2335 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | ||
2336 | break; | ||
2337 | case 3: | ||
2338 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | ||
2339 | break; | ||
2340 | } | ||
2341 | |||
2342 | scaledPower = max((u16)0, scaledPower); | ||
2343 | |||
2344 | if (IS_CHAN_2GHZ(chan)) { | ||
2345 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - | ||
2346 | SUB_NUM_CTL_MODES_AT_2G_40; | ||
2347 | pCtlMode = ctlModesFor11g; | ||
2348 | |||
2349 | ath9k_hw_get_legacy_target_powers(ah, chan, | ||
2350 | pEepData->calTargetPowerCck, | ||
2351 | AR5416_NUM_2G_CCK_TARGET_POWERS, | ||
2352 | &targetPowerCck, 4, false); | ||
2353 | ath9k_hw_get_legacy_target_powers(ah, chan, | ||
2354 | pEepData->calTargetPower2G, | ||
2355 | AR5416_NUM_2G_20_TARGET_POWERS, | ||
2356 | &targetPowerOfdm, 4, false); | ||
2357 | ath9k_hw_get_target_powers(ah, chan, | ||
2358 | pEepData->calTargetPower2GHT20, | ||
2359 | AR5416_NUM_2G_20_TARGET_POWERS, | ||
2360 | &targetPowerHt20, 8, false); | ||
2361 | |||
2362 | if (IS_CHAN_HT40(chan)) { | ||
2363 | numCtlModes = ARRAY_SIZE(ctlModesFor11g); | ||
2364 | ath9k_hw_get_target_powers(ah, chan, | ||
2365 | pEepData->calTargetPower2GHT40, | ||
2366 | AR5416_NUM_2G_40_TARGET_POWERS, | ||
2367 | &targetPowerHt40, 8, true); | ||
2368 | ath9k_hw_get_legacy_target_powers(ah, chan, | ||
2369 | pEepData->calTargetPowerCck, | ||
2370 | AR5416_NUM_2G_CCK_TARGET_POWERS, | ||
2371 | &targetPowerCckExt, 4, true); | ||
2372 | ath9k_hw_get_legacy_target_powers(ah, chan, | ||
2373 | pEepData->calTargetPower2G, | ||
2374 | AR5416_NUM_2G_20_TARGET_POWERS, | ||
2375 | &targetPowerOfdmExt, 4, true); | ||
2376 | } | ||
2377 | } else { | ||
2378 | numCtlModes = ARRAY_SIZE(ctlModesFor11a) - | ||
2379 | SUB_NUM_CTL_MODES_AT_5G_40; | ||
2380 | pCtlMode = ctlModesFor11a; | ||
2381 | |||
2382 | ath9k_hw_get_legacy_target_powers(ah, chan, | ||
2383 | pEepData->calTargetPower5G, | ||
2384 | AR5416_NUM_5G_20_TARGET_POWERS, | ||
2385 | &targetPowerOfdm, 4, false); | ||
2386 | ath9k_hw_get_target_powers(ah, chan, | ||
2387 | pEepData->calTargetPower5GHT20, | ||
2388 | AR5416_NUM_5G_20_TARGET_POWERS, | ||
2389 | &targetPowerHt20, 8, false); | ||
2390 | |||
2391 | if (IS_CHAN_HT40(chan)) { | ||
2392 | numCtlModes = ARRAY_SIZE(ctlModesFor11a); | ||
2393 | ath9k_hw_get_target_powers(ah, chan, | ||
2394 | pEepData->calTargetPower5GHT40, | ||
2395 | AR5416_NUM_5G_40_TARGET_POWERS, | ||
2396 | &targetPowerHt40, 8, true); | ||
2397 | ath9k_hw_get_legacy_target_powers(ah, chan, | ||
2398 | pEepData->calTargetPower5G, | ||
2399 | AR5416_NUM_5G_20_TARGET_POWERS, | ||
2400 | &targetPowerOfdmExt, 4, true); | ||
2401 | } | ||
2402 | } | ||
2403 | |||
2404 | for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { | ||
2405 | bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || | ||
2406 | (pCtlMode[ctlMode] == CTL_2GHT40); | ||
2407 | if (isHt40CtlMode) | ||
2408 | freq = centers.synth_center; | ||
2409 | else if (pCtlMode[ctlMode] & EXT_ADDITIVE) | ||
2410 | freq = centers.ext_center; | ||
2411 | else | ||
2412 | freq = centers.ctl_center; | ||
2413 | |||
2414 | if (ah->eep_ops->get_eeprom_ver(ah) == 14 && | ||
2415 | ah->eep_ops->get_eeprom_rev(ah) <= 2) | ||
2416 | twiceMaxEdgePower = AR5416_MAX_RATE_POWER; | ||
2417 | |||
2418 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
2419 | "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, " | ||
2420 | "EXT_ADDITIVE %d\n", | ||
2421 | ctlMode, numCtlModes, isHt40CtlMode, | ||
2422 | (pCtlMode[ctlMode] & EXT_ADDITIVE)); | ||
2423 | |||
2424 | for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { | ||
2425 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
2426 | " LOOP-Ctlidx %d: cfgCtl 0x%2.2x " | ||
2427 | "pCtlMode 0x%2.2x ctlIndex 0x%2.2x " | ||
2428 | "chan %d\n", | ||
2429 | i, cfgCtl, pCtlMode[ctlMode], | ||
2430 | pEepData->ctlIndex[i], chan->channel); | ||
2431 | |||
2432 | if ((((cfgCtl & ~CTL_MODE_M) | | ||
2433 | (pCtlMode[ctlMode] & CTL_MODE_M)) == | ||
2434 | pEepData->ctlIndex[i]) || | ||
2435 | (((cfgCtl & ~CTL_MODE_M) | | ||
2436 | (pCtlMode[ctlMode] & CTL_MODE_M)) == | ||
2437 | ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) { | ||
2438 | rep = &(pEepData->ctlData[i]); | ||
2439 | |||
2440 | twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq, | ||
2441 | rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1], | ||
2442 | IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES); | ||
2443 | |||
2444 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
2445 | " MATCH-EE_IDX %d: ch %d is2 %d " | ||
2446 | "2xMinEdge %d chainmask %d chains %d\n", | ||
2447 | i, freq, IS_CHAN_2GHZ(chan), | ||
2448 | twiceMinEdgePower, tx_chainmask, | ||
2449 | ar5416_get_ntxchains | ||
2450 | (tx_chainmask)); | ||
2451 | if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { | ||
2452 | twiceMaxEdgePower = min(twiceMaxEdgePower, | ||
2453 | twiceMinEdgePower); | ||
2454 | } else { | ||
2455 | twiceMaxEdgePower = twiceMinEdgePower; | ||
2456 | break; | ||
2457 | } | ||
2458 | } | ||
2459 | } | ||
2460 | |||
2461 | minCtlPower = min(twiceMaxEdgePower, scaledPower); | ||
2462 | |||
2463 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
2464 | " SEL-Min ctlMode %d pCtlMode %d " | ||
2465 | "2xMaxEdge %d sP %d minCtlPwr %d\n", | ||
2466 | ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, | ||
2467 | scaledPower, minCtlPower); | ||
2468 | |||
2469 | switch (pCtlMode[ctlMode]) { | ||
2470 | case CTL_11B: | ||
2471 | for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) { | ||
2472 | targetPowerCck.tPow2x[i] = | ||
2473 | min((u16)targetPowerCck.tPow2x[i], | ||
2474 | minCtlPower); | ||
2475 | } | ||
2476 | break; | ||
2477 | case CTL_11A: | ||
2478 | case CTL_11G: | ||
2479 | for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) { | ||
2480 | targetPowerOfdm.tPow2x[i] = | ||
2481 | min((u16)targetPowerOfdm.tPow2x[i], | ||
2482 | minCtlPower); | ||
2483 | } | ||
2484 | break; | ||
2485 | case CTL_5GHT20: | ||
2486 | case CTL_2GHT20: | ||
2487 | for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) { | ||
2488 | targetPowerHt20.tPow2x[i] = | ||
2489 | min((u16)targetPowerHt20.tPow2x[i], | ||
2490 | minCtlPower); | ||
2491 | } | ||
2492 | break; | ||
2493 | case CTL_11B_EXT: | ||
2494 | targetPowerCckExt.tPow2x[0] = min((u16) | ||
2495 | targetPowerCckExt.tPow2x[0], | ||
2496 | minCtlPower); | ||
2497 | break; | ||
2498 | case CTL_11A_EXT: | ||
2499 | case CTL_11G_EXT: | ||
2500 | targetPowerOfdmExt.tPow2x[0] = min((u16) | ||
2501 | targetPowerOfdmExt.tPow2x[0], | ||
2502 | minCtlPower); | ||
2503 | break; | ||
2504 | case CTL_5GHT40: | ||
2505 | case CTL_2GHT40: | ||
2506 | for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { | ||
2507 | targetPowerHt40.tPow2x[i] = | ||
2508 | min((u16)targetPowerHt40.tPow2x[i], | ||
2509 | minCtlPower); | ||
2510 | } | ||
2511 | break; | ||
2512 | default: | ||
2513 | break; | ||
2514 | } | ||
2515 | } | ||
2516 | |||
2517 | ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = | ||
2518 | ratesArray[rate18mb] = ratesArray[rate24mb] = | ||
2519 | targetPowerOfdm.tPow2x[0]; | ||
2520 | ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; | ||
2521 | ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; | ||
2522 | ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; | ||
2523 | ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; | ||
2524 | |||
2525 | for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) | ||
2526 | ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; | ||
2527 | |||
2528 | if (IS_CHAN_2GHZ(chan)) { | ||
2529 | ratesArray[rate1l] = targetPowerCck.tPow2x[0]; | ||
2530 | ratesArray[rate2s] = ratesArray[rate2l] = | ||
2531 | targetPowerCck.tPow2x[1]; | ||
2532 | ratesArray[rate5_5s] = ratesArray[rate5_5l] = | ||
2533 | targetPowerCck.tPow2x[2]; | ||
2534 | ; | ||
2535 | ratesArray[rate11s] = ratesArray[rate11l] = | ||
2536 | targetPowerCck.tPow2x[3]; | ||
2537 | ; | ||
2538 | } | ||
2539 | if (IS_CHAN_HT40(chan)) { | ||
2540 | for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { | ||
2541 | ratesArray[rateHt40_0 + i] = | ||
2542 | targetPowerHt40.tPow2x[i]; | ||
2543 | } | ||
2544 | ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; | ||
2545 | ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; | ||
2546 | ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; | ||
2547 | if (IS_CHAN_2GHZ(chan)) { | ||
2548 | ratesArray[rateExtCck] = | ||
2549 | targetPowerCckExt.tPow2x[0]; | ||
2550 | } | ||
2551 | } | ||
2552 | return true; | ||
2553 | } | ||
2554 | |||
2555 | static int ath9k_hw_def_set_txpower(struct ath_hw *ah, | ||
2556 | struct ath9k_channel *chan, | ||
2557 | u16 cfgCtl, | ||
2558 | u8 twiceAntennaReduction, | ||
2559 | u8 twiceMaxRegulatoryPower, | ||
2560 | u8 powerLimit) | ||
2561 | { | ||
2562 | #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta) | ||
2563 | struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; | ||
2564 | struct modal_eep_header *pModal = | ||
2565 | &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]); | ||
2566 | int16_t ratesArray[Ar5416RateSize]; | ||
2567 | int16_t txPowerIndexOffset = 0; | ||
2568 | u8 ht40PowerIncForPdadc = 2; | ||
2569 | int i, cck_ofdm_delta = 0; | ||
2570 | |||
2571 | memset(ratesArray, 0, sizeof(ratesArray)); | ||
2572 | |||
2573 | if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= | ||
2574 | AR5416_EEP_MINOR_VER_2) { | ||
2575 | ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; | ||
2576 | } | ||
2577 | |||
2578 | if (!ath9k_hw_set_def_power_per_rate_table(ah, chan, | ||
2579 | &ratesArray[0], cfgCtl, | ||
2580 | twiceAntennaReduction, | ||
2581 | twiceMaxRegulatoryPower, | ||
2582 | powerLimit)) { | ||
2583 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
2584 | "ath9k_hw_set_txpower: unable to set " | ||
2585 | "tx power per rate table\n"); | ||
2586 | return -EIO; | ||
2587 | } | ||
2588 | |||
2589 | if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) { | ||
2590 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
2591 | "ath9k_hw_set_txpower: unable to set power table\n"); | ||
2592 | return -EIO; | ||
2593 | } | ||
2594 | |||
2595 | for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { | ||
2596 | ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); | ||
2597 | if (ratesArray[i] > AR5416_MAX_RATE_POWER) | ||
2598 | ratesArray[i] = AR5416_MAX_RATE_POWER; | ||
2599 | } | ||
2600 | |||
2601 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
2602 | for (i = 0; i < Ar5416RateSize; i++) | ||
2603 | ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2; | ||
2604 | } | ||
2605 | |||
2606 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, | ||
2607 | ATH9K_POW_SM(ratesArray[rate18mb], 24) | ||
2608 | | ATH9K_POW_SM(ratesArray[rate12mb], 16) | ||
2609 | | ATH9K_POW_SM(ratesArray[rate9mb], 8) | ||
2610 | | ATH9K_POW_SM(ratesArray[rate6mb], 0)); | ||
2611 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, | ||
2612 | ATH9K_POW_SM(ratesArray[rate54mb], 24) | ||
2613 | | ATH9K_POW_SM(ratesArray[rate48mb], 16) | ||
2614 | | ATH9K_POW_SM(ratesArray[rate36mb], 8) | ||
2615 | | ATH9K_POW_SM(ratesArray[rate24mb], 0)); | ||
2616 | |||
2617 | if (IS_CHAN_2GHZ(chan)) { | ||
2618 | if (OLC_FOR_AR9280_20_LATER) { | ||
2619 | cck_ofdm_delta = 2; | ||
2620 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, | ||
2621 | ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24) | ||
2622 | | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16) | ||
2623 | | ATH9K_POW_SM(ratesArray[rateXr], 8) | ||
2624 | | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0)); | ||
2625 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, | ||
2626 | ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24) | ||
2627 | | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16) | ||
2628 | | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8) | ||
2629 | | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0)); | ||
2630 | } else { | ||
2631 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, | ||
2632 | ATH9K_POW_SM(ratesArray[rate2s], 24) | ||
2633 | | ATH9K_POW_SM(ratesArray[rate2l], 16) | ||
2634 | | ATH9K_POW_SM(ratesArray[rateXr], 8) | ||
2635 | | ATH9K_POW_SM(ratesArray[rate1l], 0)); | ||
2636 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, | ||
2637 | ATH9K_POW_SM(ratesArray[rate11s], 24) | ||
2638 | | ATH9K_POW_SM(ratesArray[rate11l], 16) | ||
2639 | | ATH9K_POW_SM(ratesArray[rate5_5s], 8) | ||
2640 | | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); | ||
2641 | } | ||
2642 | } | ||
2643 | |||
2644 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, | ||
2645 | ATH9K_POW_SM(ratesArray[rateHt20_3], 24) | ||
2646 | | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) | ||
2647 | | ATH9K_POW_SM(ratesArray[rateHt20_1], 8) | ||
2648 | | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)); | ||
2649 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, | ||
2650 | ATH9K_POW_SM(ratesArray[rateHt20_7], 24) | ||
2651 | | ATH9K_POW_SM(ratesArray[rateHt20_6], 16) | ||
2652 | | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) | ||
2653 | | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); | ||
2654 | |||
2655 | if (IS_CHAN_HT40(chan)) { | ||
2656 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, | ||
2657 | ATH9K_POW_SM(ratesArray[rateHt40_3] + | ||
2658 | ht40PowerIncForPdadc, 24) | ||
2659 | | ATH9K_POW_SM(ratesArray[rateHt40_2] + | ||
2660 | ht40PowerIncForPdadc, 16) | ||
2661 | | ATH9K_POW_SM(ratesArray[rateHt40_1] + | ||
2662 | ht40PowerIncForPdadc, 8) | ||
2663 | | ATH9K_POW_SM(ratesArray[rateHt40_0] + | ||
2664 | ht40PowerIncForPdadc, 0)); | ||
2665 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, | ||
2666 | ATH9K_POW_SM(ratesArray[rateHt40_7] + | ||
2667 | ht40PowerIncForPdadc, 24) | ||
2668 | | ATH9K_POW_SM(ratesArray[rateHt40_6] + | ||
2669 | ht40PowerIncForPdadc, 16) | ||
2670 | | ATH9K_POW_SM(ratesArray[rateHt40_5] + | ||
2671 | ht40PowerIncForPdadc, 8) | ||
2672 | | ATH9K_POW_SM(ratesArray[rateHt40_4] + | ||
2673 | ht40PowerIncForPdadc, 0)); | ||
2674 | if (OLC_FOR_AR9280_20_LATER) { | ||
2675 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, | ||
2676 | ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) | ||
2677 | | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16) | ||
2678 | | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) | ||
2679 | | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0)); | ||
2680 | } else { | ||
2681 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, | ||
2682 | ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) | ||
2683 | | ATH9K_POW_SM(ratesArray[rateExtCck], 16) | ||
2684 | | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) | ||
2685 | | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); | ||
2686 | } | ||
2687 | } | ||
2688 | |||
2689 | REG_WRITE(ah, AR_PHY_POWER_TX_SUB, | ||
2690 | ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) | ||
2691 | | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)); | ||
2692 | |||
2693 | i = rate6mb; | ||
2694 | |||
2695 | if (IS_CHAN_HT40(chan)) | ||
2696 | i = rateHt40_0; | ||
2697 | else if (IS_CHAN_HT20(chan)) | ||
2698 | i = rateHt20_0; | ||
2699 | |||
2700 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
2701 | ah->regulatory.max_power_level = | ||
2702 | ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2; | ||
2703 | else | ||
2704 | ah->regulatory.max_power_level = ratesArray[i]; | ||
2705 | |||
2706 | switch(ar5416_get_ntxchains(ah->txchainmask)) { | ||
2707 | case 1: | ||
2708 | break; | ||
2709 | case 2: | ||
2710 | ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN; | ||
2711 | break; | ||
2712 | case 3: | ||
2713 | ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; | ||
2714 | break; | ||
2715 | default: | ||
2716 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
2717 | "Invalid chainmask configuration\n"); | ||
2718 | break; | ||
2719 | } | ||
2720 | |||
2721 | return 0; | ||
2722 | } | ||
2723 | |||
2724 | static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, | ||
2725 | enum ieee80211_band freq_band) | ||
2726 | { | ||
2727 | struct ar5416_eeprom_def *eep = &ah->eeprom.def; | ||
2728 | struct modal_eep_header *pModal = | ||
2729 | &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]); | ||
2730 | struct base_eep_header *pBase = &eep->baseEepHeader; | ||
2731 | u8 num_ant_config; | ||
2732 | |||
2733 | num_ant_config = 1; | ||
2734 | |||
2735 | if (pBase->version >= 0x0E0D) | ||
2736 | if (pModal->useAnt1) | ||
2737 | num_ant_config += 1; | ||
2738 | |||
2739 | return num_ant_config; | ||
2740 | } | ||
2741 | |||
2742 | static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah, | ||
2743 | struct ath9k_channel *chan) | ||
2744 | { | ||
2745 | struct ar5416_eeprom_def *eep = &ah->eeprom.def; | ||
2746 | struct modal_eep_header *pModal = | ||
2747 | &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); | ||
2748 | |||
2749 | return pModal->antCtrlCommon & 0xFFFF; | ||
2750 | } | ||
2751 | |||
2752 | static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) | ||
2753 | { | ||
2754 | #define EEP_DEF_SPURCHAN \ | ||
2755 | (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan) | ||
2756 | |||
2757 | u16 spur_val = AR_NO_SPUR; | ||
2758 | |||
2759 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
2760 | "Getting spur idx %d is2Ghz. %d val %x\n", | ||
2761 | i, is2GHz, ah->config.spurchans[i][is2GHz]); | ||
2762 | |||
2763 | switch (ah->config.spurmode) { | ||
2764 | case SPUR_DISABLE: | ||
2765 | break; | ||
2766 | case SPUR_ENABLE_IOCTL: | ||
2767 | spur_val = ah->config.spurchans[i][is2GHz]; | ||
2768 | DPRINTF(ah->ah_sc, ATH_DBG_ANI, | ||
2769 | "Getting spur val from new loc. %d\n", spur_val); | ||
2770 | break; | ||
2771 | case SPUR_ENABLE_EEPROM: | ||
2772 | spur_val = EEP_DEF_SPURCHAN; | ||
2773 | break; | ||
2774 | } | ||
2775 | |||
2776 | return spur_val; | ||
2777 | |||
2778 | #undef EEP_DEF_SPURCHAN | ||
2779 | } | ||
2780 | |||
2781 | static struct eeprom_ops eep_def_ops = { | ||
2782 | .check_eeprom = ath9k_hw_def_check_eeprom, | ||
2783 | .get_eeprom = ath9k_hw_def_get_eeprom, | ||
2784 | .fill_eeprom = ath9k_hw_def_fill_eeprom, | ||
2785 | .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver, | ||
2786 | .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev, | ||
2787 | .get_num_ant_config = ath9k_hw_def_get_num_ant_config, | ||
2788 | .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg, | ||
2789 | .set_board_values = ath9k_hw_def_set_board_values, | ||
2790 | .set_addac = ath9k_hw_def_set_addac, | ||
2791 | .set_txpower = ath9k_hw_def_set_txpower, | ||
2792 | .get_spur_channel = ath9k_hw_def_get_spur_channel | ||
2793 | }; | ||
2794 | |||
2795 | int ath9k_hw_eeprom_attach(struct ath_hw *ah) | ||
2796 | { | ||
2797 | int status; | ||
2798 | |||
2799 | if (AR_SREV_9285(ah)) { | ||
2800 | ah->eep_map = EEP_MAP_4KBITS; | ||
2801 | ah->eep_ops = &eep_4k_ops; | ||
2802 | } else { | ||
2803 | ah->eep_map = EEP_MAP_DEFAULT; | ||
2804 | ah->eep_ops = &eep_def_ops; | ||
2805 | } | ||
2806 | |||
2807 | if (!ah->eep_ops->fill_eeprom(ah)) | ||
2808 | return -EIO; | ||
2809 | |||
2810 | status = ah->eep_ops->check_eeprom(ah); | ||
2811 | |||
2812 | return status; | ||
2813 | } | ||
diff --git a/drivers/net/wireless/ath9k/eeprom.h b/drivers/net/wireless/ath9k/eeprom.h deleted file mode 100644 index 9a7715df5cff..000000000000 --- a/drivers/net/wireless/ath9k/eeprom.h +++ /dev/null | |||
@@ -1,509 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 EEPROM_H | ||
18 | #define EEPROM_H | ||
19 | |||
20 | #include <net/wireless.h> | ||
21 | |||
22 | #define AH_USE_EEPROM 0x1 | ||
23 | |||
24 | #ifdef __BIG_ENDIAN | ||
25 | #define AR5416_EEPROM_MAGIC 0x5aa5 | ||
26 | #else | ||
27 | #define AR5416_EEPROM_MAGIC 0xa55a | ||
28 | #endif | ||
29 | |||
30 | #define CTRY_DEBUG 0x1ff | ||
31 | #define CTRY_DEFAULT 0 | ||
32 | |||
33 | #define AR_EEPROM_EEPCAP_COMPRESS_DIS 0x0001 | ||
34 | #define AR_EEPROM_EEPCAP_AES_DIS 0x0002 | ||
35 | #define AR_EEPROM_EEPCAP_FASTFRAME_DIS 0x0004 | ||
36 | #define AR_EEPROM_EEPCAP_BURST_DIS 0x0008 | ||
37 | #define AR_EEPROM_EEPCAP_MAXQCU 0x01F0 | ||
38 | #define AR_EEPROM_EEPCAP_MAXQCU_S 4 | ||
39 | #define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN 0x0200 | ||
40 | #define AR_EEPROM_EEPCAP_KC_ENTRIES 0xF000 | ||
41 | #define AR_EEPROM_EEPCAP_KC_ENTRIES_S 12 | ||
42 | |||
43 | #define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND 0x0040 | ||
44 | #define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN 0x0080 | ||
45 | #define AR_EEPROM_EEREGCAP_EN_KK_U2 0x0100 | ||
46 | #define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND 0x0200 | ||
47 | #define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD 0x0400 | ||
48 | #define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A 0x0800 | ||
49 | |||
50 | #define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0 0x4000 | ||
51 | #define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000 | ||
52 | |||
53 | #define AR5416_EEPROM_MAGIC_OFFSET 0x0 | ||
54 | #define AR5416_EEPROM_S 2 | ||
55 | #define AR5416_EEPROM_OFFSET 0x2000 | ||
56 | #define AR5416_EEPROM_MAX 0xae0 | ||
57 | |||
58 | #define AR5416_EEPROM_START_ADDR \ | ||
59 | (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200 | ||
60 | |||
61 | #define SD_NO_CTL 0xE0 | ||
62 | #define NO_CTL 0xff | ||
63 | #define CTL_MODE_M 7 | ||
64 | #define CTL_11A 0 | ||
65 | #define CTL_11B 1 | ||
66 | #define CTL_11G 2 | ||
67 | #define CTL_2GHT20 5 | ||
68 | #define CTL_5GHT20 6 | ||
69 | #define CTL_2GHT40 7 | ||
70 | #define CTL_5GHT40 8 | ||
71 | |||
72 | #define EXT_ADDITIVE (0x8000) | ||
73 | #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) | ||
74 | #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) | ||
75 | #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) | ||
76 | |||
77 | #define SUB_NUM_CTL_MODES_AT_5G_40 2 | ||
78 | #define SUB_NUM_CTL_MODES_AT_2G_40 3 | ||
79 | |||
80 | #define INCREASE_MAXPOW_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ | ||
81 | #define INCREASE_MAXPOW_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */ | ||
82 | |||
83 | /* | ||
84 | * For AR9285 and later chipsets, the following bits are not being programmed | ||
85 | * in EEPROM and so need to be enabled always. | ||
86 | * | ||
87 | * Bit 0: en_fcc_mid | ||
88 | * Bit 1: en_jap_mid | ||
89 | * Bit 2: en_fcc_dfs_ht40 | ||
90 | * Bit 3: en_jap_ht40 | ||
91 | * Bit 4: en_jap_dfs_ht40 | ||
92 | */ | ||
93 | #define AR9285_RDEXT_DEFAULT 0x1F | ||
94 | |||
95 | #define AR_EEPROM_MAC(i) (0x1d+(i)) | ||
96 | #define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) | ||
97 | #define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5)) | ||
98 | #define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM)) | ||
99 | |||
100 | #define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) | ||
101 | #define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \ | ||
102 | ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) | ||
103 | |||
104 | #define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c | ||
105 | #define AR_EEPROM_RFSILENT_GPIO_SEL_S 2 | ||
106 | #define AR_EEPROM_RFSILENT_POLARITY 0x0002 | ||
107 | #define AR_EEPROM_RFSILENT_POLARITY_S 1 | ||
108 | |||
109 | #define EEP_RFSILENT_ENABLED 0x0001 | ||
110 | #define EEP_RFSILENT_ENABLED_S 0 | ||
111 | #define EEP_RFSILENT_POLARITY 0x0002 | ||
112 | #define EEP_RFSILENT_POLARITY_S 1 | ||
113 | #define EEP_RFSILENT_GPIO_SEL 0x001c | ||
114 | #define EEP_RFSILENT_GPIO_SEL_S 2 | ||
115 | |||
116 | #define AR5416_OPFLAGS_11A 0x01 | ||
117 | #define AR5416_OPFLAGS_11G 0x02 | ||
118 | #define AR5416_OPFLAGS_N_5G_HT40 0x04 | ||
119 | #define AR5416_OPFLAGS_N_2G_HT40 0x08 | ||
120 | #define AR5416_OPFLAGS_N_5G_HT20 0x10 | ||
121 | #define AR5416_OPFLAGS_N_2G_HT20 0x20 | ||
122 | |||
123 | #define AR5416_EEP_NO_BACK_VER 0x1 | ||
124 | #define AR5416_EEP_VER 0xE | ||
125 | #define AR5416_EEP_VER_MINOR_MASK 0x0FFF | ||
126 | #define AR5416_EEP_MINOR_VER_2 0x2 | ||
127 | #define AR5416_EEP_MINOR_VER_3 0x3 | ||
128 | #define AR5416_EEP_MINOR_VER_7 0x7 | ||
129 | #define AR5416_EEP_MINOR_VER_9 0x9 | ||
130 | #define AR5416_EEP_MINOR_VER_16 0x10 | ||
131 | #define AR5416_EEP_MINOR_VER_17 0x11 | ||
132 | #define AR5416_EEP_MINOR_VER_19 0x13 | ||
133 | #define AR5416_EEP_MINOR_VER_20 0x14 | ||
134 | #define AR5416_EEP_MINOR_VER_22 0x16 | ||
135 | |||
136 | #define AR5416_NUM_5G_CAL_PIERS 8 | ||
137 | #define AR5416_NUM_2G_CAL_PIERS 4 | ||
138 | #define AR5416_NUM_5G_20_TARGET_POWERS 8 | ||
139 | #define AR5416_NUM_5G_40_TARGET_POWERS 8 | ||
140 | #define AR5416_NUM_2G_CCK_TARGET_POWERS 3 | ||
141 | #define AR5416_NUM_2G_20_TARGET_POWERS 4 | ||
142 | #define AR5416_NUM_2G_40_TARGET_POWERS 4 | ||
143 | #define AR5416_NUM_CTLS 24 | ||
144 | #define AR5416_NUM_BAND_EDGES 8 | ||
145 | #define AR5416_NUM_PD_GAINS 4 | ||
146 | #define AR5416_PD_GAINS_IN_MASK 4 | ||
147 | #define AR5416_PD_GAIN_ICEPTS 5 | ||
148 | #define AR5416_EEPROM_MODAL_SPURS 5 | ||
149 | #define AR5416_MAX_RATE_POWER 63 | ||
150 | #define AR5416_NUM_PDADC_VALUES 128 | ||
151 | #define AR5416_BCHAN_UNUSED 0xFF | ||
152 | #define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64 | ||
153 | #define AR5416_MAX_CHAINS 3 | ||
154 | #define AR5416_PWR_TABLE_OFFSET -5 | ||
155 | |||
156 | /* Rx gain type values */ | ||
157 | #define AR5416_EEP_RXGAIN_23DB_BACKOFF 0 | ||
158 | #define AR5416_EEP_RXGAIN_13DB_BACKOFF 1 | ||
159 | #define AR5416_EEP_RXGAIN_ORIG 2 | ||
160 | |||
161 | /* Tx gain type values */ | ||
162 | #define AR5416_EEP_TXGAIN_ORIGINAL 0 | ||
163 | #define AR5416_EEP_TXGAIN_HIGH_POWER 1 | ||
164 | |||
165 | #define AR5416_EEP4K_START_LOC 64 | ||
166 | #define AR5416_EEP4K_NUM_2G_CAL_PIERS 3 | ||
167 | #define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3 | ||
168 | #define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS 3 | ||
169 | #define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS 3 | ||
170 | #define AR5416_EEP4K_NUM_CTLS 12 | ||
171 | #define AR5416_EEP4K_NUM_BAND_EDGES 4 | ||
172 | #define AR5416_EEP4K_NUM_PD_GAINS 2 | ||
173 | #define AR5416_EEP4K_PD_GAINS_IN_MASK 4 | ||
174 | #define AR5416_EEP4K_PD_GAIN_ICEPTS 5 | ||
175 | #define AR5416_EEP4K_MAX_CHAINS 1 | ||
176 | |||
177 | #define AR9280_TX_GAIN_TABLE_SIZE 22 | ||
178 | |||
179 | enum eeprom_param { | ||
180 | EEP_NFTHRESH_5, | ||
181 | EEP_NFTHRESH_2, | ||
182 | EEP_MAC_MSW, | ||
183 | EEP_MAC_MID, | ||
184 | EEP_MAC_LSW, | ||
185 | EEP_REG_0, | ||
186 | EEP_REG_1, | ||
187 | EEP_OP_CAP, | ||
188 | EEP_OP_MODE, | ||
189 | EEP_RF_SILENT, | ||
190 | EEP_OB_5, | ||
191 | EEP_DB_5, | ||
192 | EEP_OB_2, | ||
193 | EEP_DB_2, | ||
194 | EEP_MINOR_REV, | ||
195 | EEP_TX_MASK, | ||
196 | EEP_RX_MASK, | ||
197 | EEP_RXGAIN_TYPE, | ||
198 | EEP_TXGAIN_TYPE, | ||
199 | EEP_OL_PWRCTRL, | ||
200 | EEP_RC_CHAIN_MASK, | ||
201 | EEP_DAC_HPWR_5G, | ||
202 | EEP_FRAC_N_5G | ||
203 | }; | ||
204 | |||
205 | enum ar5416_rates { | ||
206 | rate6mb, rate9mb, rate12mb, rate18mb, | ||
207 | rate24mb, rate36mb, rate48mb, rate54mb, | ||
208 | rate1l, rate2l, rate2s, rate5_5l, | ||
209 | rate5_5s, rate11l, rate11s, rateXr, | ||
210 | rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3, | ||
211 | rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7, | ||
212 | rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3, | ||
213 | rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7, | ||
214 | rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm, | ||
215 | Ar5416RateSize | ||
216 | }; | ||
217 | |||
218 | enum ath9k_hal_freq_band { | ||
219 | ATH9K_HAL_FREQ_BAND_5GHZ = 0, | ||
220 | ATH9K_HAL_FREQ_BAND_2GHZ = 1 | ||
221 | }; | ||
222 | |||
223 | struct base_eep_header { | ||
224 | u16 length; | ||
225 | u16 checksum; | ||
226 | u16 version; | ||
227 | u8 opCapFlags; | ||
228 | u8 eepMisc; | ||
229 | u16 regDmn[2]; | ||
230 | u8 macAddr[6]; | ||
231 | u8 rxMask; | ||
232 | u8 txMask; | ||
233 | u16 rfSilent; | ||
234 | u16 blueToothOptions; | ||
235 | u16 deviceCap; | ||
236 | u32 binBuildNumber; | ||
237 | u8 deviceType; | ||
238 | u8 pwdclkind; | ||
239 | u8 futureBase_1[2]; | ||
240 | u8 rxGainType; | ||
241 | u8 dacHiPwrMode_5G; | ||
242 | u8 openLoopPwrCntl; | ||
243 | u8 dacLpMode; | ||
244 | u8 txGainType; | ||
245 | u8 rcChainMask; | ||
246 | u8 desiredScaleCCK; | ||
247 | u8 power_table_offset; | ||
248 | u8 frac_n_5g; | ||
249 | u8 futureBase_3[21]; | ||
250 | } __packed; | ||
251 | |||
252 | struct base_eep_header_4k { | ||
253 | u16 length; | ||
254 | u16 checksum; | ||
255 | u16 version; | ||
256 | u8 opCapFlags; | ||
257 | u8 eepMisc; | ||
258 | u16 regDmn[2]; | ||
259 | u8 macAddr[6]; | ||
260 | u8 rxMask; | ||
261 | u8 txMask; | ||
262 | u16 rfSilent; | ||
263 | u16 blueToothOptions; | ||
264 | u16 deviceCap; | ||
265 | u32 binBuildNumber; | ||
266 | u8 deviceType; | ||
267 | u8 txGainType; | ||
268 | } __packed; | ||
269 | |||
270 | |||
271 | struct spur_chan { | ||
272 | u16 spurChan; | ||
273 | u8 spurRangeLow; | ||
274 | u8 spurRangeHigh; | ||
275 | } __packed; | ||
276 | |||
277 | struct modal_eep_header { | ||
278 | u32 antCtrlChain[AR5416_MAX_CHAINS]; | ||
279 | u32 antCtrlCommon; | ||
280 | u8 antennaGainCh[AR5416_MAX_CHAINS]; | ||
281 | u8 switchSettling; | ||
282 | u8 txRxAttenCh[AR5416_MAX_CHAINS]; | ||
283 | u8 rxTxMarginCh[AR5416_MAX_CHAINS]; | ||
284 | u8 adcDesiredSize; | ||
285 | u8 pgaDesiredSize; | ||
286 | u8 xlnaGainCh[AR5416_MAX_CHAINS]; | ||
287 | u8 txEndToXpaOff; | ||
288 | u8 txEndToRxOn; | ||
289 | u8 txFrameToXpaOn; | ||
290 | u8 thresh62; | ||
291 | u8 noiseFloorThreshCh[AR5416_MAX_CHAINS]; | ||
292 | u8 xpdGain; | ||
293 | u8 xpd; | ||
294 | u8 iqCalICh[AR5416_MAX_CHAINS]; | ||
295 | u8 iqCalQCh[AR5416_MAX_CHAINS]; | ||
296 | u8 pdGainOverlap; | ||
297 | u8 ob; | ||
298 | u8 db; | ||
299 | u8 xpaBiasLvl; | ||
300 | u8 pwrDecreaseFor2Chain; | ||
301 | u8 pwrDecreaseFor3Chain; | ||
302 | u8 txFrameToDataStart; | ||
303 | u8 txFrameToPaOn; | ||
304 | u8 ht40PowerIncForPdadc; | ||
305 | u8 bswAtten[AR5416_MAX_CHAINS]; | ||
306 | u8 bswMargin[AR5416_MAX_CHAINS]; | ||
307 | u8 swSettleHt40; | ||
308 | u8 xatten2Db[AR5416_MAX_CHAINS]; | ||
309 | u8 xatten2Margin[AR5416_MAX_CHAINS]; | ||
310 | u8 ob_ch1; | ||
311 | u8 db_ch1; | ||
312 | u8 useAnt1:1, | ||
313 | force_xpaon:1, | ||
314 | local_bias:1, | ||
315 | femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1; | ||
316 | u8 miscBits; | ||
317 | u16 xpaBiasLvlFreq[3]; | ||
318 | u8 futureModal[6]; | ||
319 | |||
320 | struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; | ||
321 | } __packed; | ||
322 | |||
323 | struct calDataPerFreqOpLoop { | ||
324 | u8 pwrPdg[2][5]; | ||
325 | u8 vpdPdg[2][5]; | ||
326 | u8 pcdac[2][5]; | ||
327 | u8 empty[2][5]; | ||
328 | } __packed; | ||
329 | |||
330 | struct modal_eep_4k_header { | ||
331 | u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS]; | ||
332 | u32 antCtrlCommon; | ||
333 | u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS]; | ||
334 | u8 switchSettling; | ||
335 | u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS]; | ||
336 | u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS]; | ||
337 | u8 adcDesiredSize; | ||
338 | u8 pgaDesiredSize; | ||
339 | u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS]; | ||
340 | u8 txEndToXpaOff; | ||
341 | u8 txEndToRxOn; | ||
342 | u8 txFrameToXpaOn; | ||
343 | u8 thresh62; | ||
344 | u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS]; | ||
345 | u8 xpdGain; | ||
346 | u8 xpd; | ||
347 | u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS]; | ||
348 | u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS]; | ||
349 | u8 pdGainOverlap; | ||
350 | u8 ob_01; | ||
351 | u8 db1_01; | ||
352 | u8 xpaBiasLvl; | ||
353 | u8 txFrameToDataStart; | ||
354 | u8 txFrameToPaOn; | ||
355 | u8 ht40PowerIncForPdadc; | ||
356 | u8 bswAtten[AR5416_EEP4K_MAX_CHAINS]; | ||
357 | u8 bswMargin[AR5416_EEP4K_MAX_CHAINS]; | ||
358 | u8 swSettleHt40; | ||
359 | u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS]; | ||
360 | u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS]; | ||
361 | u8 db2_01; | ||
362 | u8 version; | ||
363 | u16 ob_234; | ||
364 | u16 db1_234; | ||
365 | u16 db2_234; | ||
366 | u8 futureModal[4]; | ||
367 | |||
368 | struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; | ||
369 | } __packed; | ||
370 | |||
371 | |||
372 | struct cal_data_per_freq { | ||
373 | u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; | ||
374 | u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; | ||
375 | } __packed; | ||
376 | |||
377 | struct cal_data_per_freq_4k { | ||
378 | u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS]; | ||
379 | u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS]; | ||
380 | } __packed; | ||
381 | |||
382 | struct cal_target_power_leg { | ||
383 | u8 bChannel; | ||
384 | u8 tPow2x[4]; | ||
385 | } __packed; | ||
386 | |||
387 | struct cal_target_power_ht { | ||
388 | u8 bChannel; | ||
389 | u8 tPow2x[8]; | ||
390 | } __packed; | ||
391 | |||
392 | |||
393 | #ifdef __BIG_ENDIAN_BITFIELD | ||
394 | struct cal_ctl_edges { | ||
395 | u8 bChannel; | ||
396 | u8 flag:2, tPower:6; | ||
397 | } __packed; | ||
398 | #else | ||
399 | struct cal_ctl_edges { | ||
400 | u8 bChannel; | ||
401 | u8 tPower:6, flag:2; | ||
402 | } __packed; | ||
403 | #endif | ||
404 | |||
405 | struct cal_ctl_data { | ||
406 | struct cal_ctl_edges | ||
407 | ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; | ||
408 | } __packed; | ||
409 | |||
410 | struct cal_ctl_data_4k { | ||
411 | struct cal_ctl_edges | ||
412 | ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES]; | ||
413 | } __packed; | ||
414 | |||
415 | struct ar5416_eeprom_def { | ||
416 | struct base_eep_header baseEepHeader; | ||
417 | u8 custData[64]; | ||
418 | struct modal_eep_header modalHeader[2]; | ||
419 | u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS]; | ||
420 | u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS]; | ||
421 | struct cal_data_per_freq | ||
422 | calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS]; | ||
423 | struct cal_data_per_freq | ||
424 | calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS]; | ||
425 | struct cal_target_power_leg | ||
426 | calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS]; | ||
427 | struct cal_target_power_ht | ||
428 | calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS]; | ||
429 | struct cal_target_power_ht | ||
430 | calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS]; | ||
431 | struct cal_target_power_leg | ||
432 | calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS]; | ||
433 | struct cal_target_power_leg | ||
434 | calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS]; | ||
435 | struct cal_target_power_ht | ||
436 | calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS]; | ||
437 | struct cal_target_power_ht | ||
438 | calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS]; | ||
439 | u8 ctlIndex[AR5416_NUM_CTLS]; | ||
440 | struct cal_ctl_data ctlData[AR5416_NUM_CTLS]; | ||
441 | u8 padding; | ||
442 | } __packed; | ||
443 | |||
444 | struct ar5416_eeprom_4k { | ||
445 | struct base_eep_header_4k baseEepHeader; | ||
446 | u8 custData[20]; | ||
447 | struct modal_eep_4k_header modalHeader; | ||
448 | u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS]; | ||
449 | struct cal_data_per_freq_4k | ||
450 | calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS]; | ||
451 | struct cal_target_power_leg | ||
452 | calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS]; | ||
453 | struct cal_target_power_leg | ||
454 | calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS]; | ||
455 | struct cal_target_power_ht | ||
456 | calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS]; | ||
457 | struct cal_target_power_ht | ||
458 | calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS]; | ||
459 | u8 ctlIndex[AR5416_EEP4K_NUM_CTLS]; | ||
460 | struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS]; | ||
461 | u8 padding; | ||
462 | } __packed; | ||
463 | |||
464 | enum reg_ext_bitmap { | ||
465 | REG_EXT_JAPAN_MIDBAND = 1, | ||
466 | REG_EXT_FCC_DFS_HT40 = 2, | ||
467 | REG_EXT_JAPAN_NONDFS_HT40 = 3, | ||
468 | REG_EXT_JAPAN_DFS_HT40 = 4 | ||
469 | }; | ||
470 | |||
471 | struct ath9k_country_entry { | ||
472 | u16 countryCode; | ||
473 | u16 regDmnEnum; | ||
474 | u16 regDmn5G; | ||
475 | u16 regDmn2G; | ||
476 | u8 isMultidomain; | ||
477 | u8 iso[3]; | ||
478 | }; | ||
479 | |||
480 | enum ath9k_eep_map { | ||
481 | EEP_MAP_DEFAULT = 0x0, | ||
482 | EEP_MAP_4KBITS, | ||
483 | EEP_MAP_MAX | ||
484 | }; | ||
485 | |||
486 | struct eeprom_ops { | ||
487 | int (*check_eeprom)(struct ath_hw *hw); | ||
488 | u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param); | ||
489 | bool (*fill_eeprom)(struct ath_hw *hw); | ||
490 | int (*get_eeprom_ver)(struct ath_hw *hw); | ||
491 | int (*get_eeprom_rev)(struct ath_hw *hw); | ||
492 | u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band); | ||
493 | u16 (*get_eeprom_antenna_cfg)(struct ath_hw *hw, | ||
494 | struct ath9k_channel *chan); | ||
495 | void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan); | ||
496 | void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan); | ||
497 | int (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan, | ||
498 | u16 cfgCtl, u8 twiceAntennaReduction, | ||
499 | u8 twiceMaxRegulatoryPower, u8 powerLimit); | ||
500 | u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz); | ||
501 | }; | ||
502 | |||
503 | #define ar5416_get_ntxchains(_txchainmask) \ | ||
504 | (((_txchainmask >> 2) & 1) + \ | ||
505 | ((_txchainmask >> 1) & 1) + (_txchainmask & 1)) | ||
506 | |||
507 | int ath9k_hw_eeprom_attach(struct ath_hw *ah); | ||
508 | |||
509 | #endif /* EEPROM_H */ | ||
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c deleted file mode 100644 index 24299e65fdcf..000000000000 --- a/drivers/net/wireless/ath9k/hw.c +++ /dev/null | |||
@@ -1,3861 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 <linux/io.h> | ||
18 | #include <asm/unaligned.h> | ||
19 | |||
20 | #include "ath9k.h" | ||
21 | #include "initvals.h" | ||
22 | |||
23 | static int btcoex_enable; | ||
24 | module_param(btcoex_enable, bool, 0); | ||
25 | MODULE_PARM_DESC(btcoex_enable, "Enable Bluetooth coexistence support"); | ||
26 | |||
27 | #define ATH9K_CLOCK_RATE_CCK 22 | ||
28 | #define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 | ||
29 | #define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 | ||
30 | |||
31 | static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); | ||
32 | static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan, | ||
33 | enum ath9k_ht_macmode macmode); | ||
34 | static u32 ath9k_hw_ini_fixup(struct ath_hw *ah, | ||
35 | struct ar5416_eeprom_def *pEepData, | ||
36 | u32 reg, u32 value); | ||
37 | static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan); | ||
38 | static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan); | ||
39 | |||
40 | /********************/ | ||
41 | /* Helper Functions */ | ||
42 | /********************/ | ||
43 | |||
44 | static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks) | ||
45 | { | ||
46 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; | ||
47 | |||
48 | if (!ah->curchan) /* should really check for CCK instead */ | ||
49 | return clks / ATH9K_CLOCK_RATE_CCK; | ||
50 | if (conf->channel->band == IEEE80211_BAND_2GHZ) | ||
51 | return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM; | ||
52 | |||
53 | return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM; | ||
54 | } | ||
55 | |||
56 | static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks) | ||
57 | { | ||
58 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; | ||
59 | |||
60 | if (conf_is_ht40(conf)) | ||
61 | return ath9k_hw_mac_usec(ah, clks) / 2; | ||
62 | else | ||
63 | return ath9k_hw_mac_usec(ah, clks); | ||
64 | } | ||
65 | |||
66 | static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) | ||
67 | { | ||
68 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; | ||
69 | |||
70 | if (!ah->curchan) /* should really check for CCK instead */ | ||
71 | return usecs *ATH9K_CLOCK_RATE_CCK; | ||
72 | if (conf->channel->band == IEEE80211_BAND_2GHZ) | ||
73 | return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM; | ||
74 | return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM; | ||
75 | } | ||
76 | |||
77 | static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs) | ||
78 | { | ||
79 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; | ||
80 | |||
81 | if (conf_is_ht40(conf)) | ||
82 | return ath9k_hw_mac_clks(ah, usecs) * 2; | ||
83 | else | ||
84 | return ath9k_hw_mac_clks(ah, usecs); | ||
85 | } | ||
86 | |||
87 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) | ||
88 | { | ||
89 | int i; | ||
90 | |||
91 | BUG_ON(timeout < AH_TIME_QUANTUM); | ||
92 | |||
93 | for (i = 0; i < (timeout / AH_TIME_QUANTUM); i++) { | ||
94 | if ((REG_READ(ah, reg) & mask) == val) | ||
95 | return true; | ||
96 | |||
97 | udelay(AH_TIME_QUANTUM); | ||
98 | } | ||
99 | |||
100 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | ||
101 | "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", | ||
102 | timeout, reg, REG_READ(ah, reg), mask, val); | ||
103 | |||
104 | return false; | ||
105 | } | ||
106 | |||
107 | u32 ath9k_hw_reverse_bits(u32 val, u32 n) | ||
108 | { | ||
109 | u32 retval; | ||
110 | int i; | ||
111 | |||
112 | for (i = 0, retval = 0; i < n; i++) { | ||
113 | retval = (retval << 1) | (val & 1); | ||
114 | val >>= 1; | ||
115 | } | ||
116 | return retval; | ||
117 | } | ||
118 | |||
119 | bool ath9k_get_channel_edges(struct ath_hw *ah, | ||
120 | u16 flags, u16 *low, | ||
121 | u16 *high) | ||
122 | { | ||
123 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
124 | |||
125 | if (flags & CHANNEL_5GHZ) { | ||
126 | *low = pCap->low_5ghz_chan; | ||
127 | *high = pCap->high_5ghz_chan; | ||
128 | return true; | ||
129 | } | ||
130 | if ((flags & CHANNEL_2GHZ)) { | ||
131 | *low = pCap->low_2ghz_chan; | ||
132 | *high = pCap->high_2ghz_chan; | ||
133 | return true; | ||
134 | } | ||
135 | return false; | ||
136 | } | ||
137 | |||
138 | u16 ath9k_hw_computetxtime(struct ath_hw *ah, | ||
139 | struct ath_rate_table *rates, | ||
140 | u32 frameLen, u16 rateix, | ||
141 | bool shortPreamble) | ||
142 | { | ||
143 | u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime; | ||
144 | u32 kbps; | ||
145 | |||
146 | kbps = rates->info[rateix].ratekbps; | ||
147 | |||
148 | if (kbps == 0) | ||
149 | return 0; | ||
150 | |||
151 | switch (rates->info[rateix].phy) { | ||
152 | case WLAN_RC_PHY_CCK: | ||
153 | phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; | ||
154 | if (shortPreamble && rates->info[rateix].short_preamble) | ||
155 | phyTime >>= 1; | ||
156 | numBits = frameLen << 3; | ||
157 | txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps); | ||
158 | break; | ||
159 | case WLAN_RC_PHY_OFDM: | ||
160 | if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) { | ||
161 | bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000; | ||
162 | numBits = OFDM_PLCP_BITS + (frameLen << 3); | ||
163 | numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol); | ||
164 | txTime = OFDM_SIFS_TIME_QUARTER | ||
165 | + OFDM_PREAMBLE_TIME_QUARTER | ||
166 | + (numSymbols * OFDM_SYMBOL_TIME_QUARTER); | ||
167 | } else if (ah->curchan && | ||
168 | IS_CHAN_HALF_RATE(ah->curchan)) { | ||
169 | bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000; | ||
170 | numBits = OFDM_PLCP_BITS + (frameLen << 3); | ||
171 | numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol); | ||
172 | txTime = OFDM_SIFS_TIME_HALF + | ||
173 | OFDM_PREAMBLE_TIME_HALF | ||
174 | + (numSymbols * OFDM_SYMBOL_TIME_HALF); | ||
175 | } else { | ||
176 | bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000; | ||
177 | numBits = OFDM_PLCP_BITS + (frameLen << 3); | ||
178 | numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol); | ||
179 | txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME | ||
180 | + (numSymbols * OFDM_SYMBOL_TIME); | ||
181 | } | ||
182 | break; | ||
183 | default: | ||
184 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
185 | "Unknown phy %u (rate ix %u)\n", | ||
186 | rates->info[rateix].phy, rateix); | ||
187 | txTime = 0; | ||
188 | break; | ||
189 | } | ||
190 | |||
191 | return txTime; | ||
192 | } | ||
193 | |||
194 | void ath9k_hw_get_channel_centers(struct ath_hw *ah, | ||
195 | struct ath9k_channel *chan, | ||
196 | struct chan_centers *centers) | ||
197 | { | ||
198 | int8_t extoff; | ||
199 | |||
200 | if (!IS_CHAN_HT40(chan)) { | ||
201 | centers->ctl_center = centers->ext_center = | ||
202 | centers->synth_center = chan->channel; | ||
203 | return; | ||
204 | } | ||
205 | |||
206 | if ((chan->chanmode == CHANNEL_A_HT40PLUS) || | ||
207 | (chan->chanmode == CHANNEL_G_HT40PLUS)) { | ||
208 | centers->synth_center = | ||
209 | chan->channel + HT40_CHANNEL_CENTER_SHIFT; | ||
210 | extoff = 1; | ||
211 | } else { | ||
212 | centers->synth_center = | ||
213 | chan->channel - HT40_CHANNEL_CENTER_SHIFT; | ||
214 | extoff = -1; | ||
215 | } | ||
216 | |||
217 | centers->ctl_center = | ||
218 | centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT); | ||
219 | centers->ext_center = | ||
220 | centers->synth_center + (extoff * | ||
221 | ((ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ? | ||
222 | HT40_CHANNEL_CENTER_SHIFT : 15)); | ||
223 | } | ||
224 | |||
225 | /******************/ | ||
226 | /* Chip Revisions */ | ||
227 | /******************/ | ||
228 | |||
229 | static void ath9k_hw_read_revisions(struct ath_hw *ah) | ||
230 | { | ||
231 | u32 val; | ||
232 | |||
233 | val = REG_READ(ah, AR_SREV) & AR_SREV_ID; | ||
234 | |||
235 | if (val == 0xFF) { | ||
236 | val = REG_READ(ah, AR_SREV); | ||
237 | ah->hw_version.macVersion = | ||
238 | (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S; | ||
239 | ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); | ||
240 | ah->is_pciexpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1; | ||
241 | } else { | ||
242 | if (!AR_SREV_9100(ah)) | ||
243 | ah->hw_version.macVersion = MS(val, AR_SREV_VERSION); | ||
244 | |||
245 | ah->hw_version.macRev = val & AR_SREV_REVISION; | ||
246 | |||
247 | if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) | ||
248 | ah->is_pciexpress = true; | ||
249 | } | ||
250 | } | ||
251 | |||
252 | static int ath9k_hw_get_radiorev(struct ath_hw *ah) | ||
253 | { | ||
254 | u32 val; | ||
255 | int i; | ||
256 | |||
257 | REG_WRITE(ah, AR_PHY(0x36), 0x00007058); | ||
258 | |||
259 | for (i = 0; i < 8; i++) | ||
260 | REG_WRITE(ah, AR_PHY(0x20), 0x00010000); | ||
261 | val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff; | ||
262 | val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4); | ||
263 | |||
264 | return ath9k_hw_reverse_bits(val, 8); | ||
265 | } | ||
266 | |||
267 | /************************************/ | ||
268 | /* HW Attach, Detach, Init Routines */ | ||
269 | /************************************/ | ||
270 | |||
271 | static void ath9k_hw_disablepcie(struct ath_hw *ah) | ||
272 | { | ||
273 | if (AR_SREV_9100(ah)) | ||
274 | return; | ||
275 | |||
276 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); | ||
277 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); | ||
278 | REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029); | ||
279 | REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824); | ||
280 | REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579); | ||
281 | REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000); | ||
282 | REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); | ||
283 | REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); | ||
284 | REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007); | ||
285 | |||
286 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); | ||
287 | } | ||
288 | |||
289 | static bool ath9k_hw_chip_test(struct ath_hw *ah) | ||
290 | { | ||
291 | u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) }; | ||
292 | u32 regHold[2]; | ||
293 | u32 patternData[4] = { 0x55555555, | ||
294 | 0xaaaaaaaa, | ||
295 | 0x66666666, | ||
296 | 0x99999999 }; | ||
297 | int i, j; | ||
298 | |||
299 | for (i = 0; i < 2; i++) { | ||
300 | u32 addr = regAddr[i]; | ||
301 | u32 wrData, rdData; | ||
302 | |||
303 | regHold[i] = REG_READ(ah, addr); | ||
304 | for (j = 0; j < 0x100; j++) { | ||
305 | wrData = (j << 16) | j; | ||
306 | REG_WRITE(ah, addr, wrData); | ||
307 | rdData = REG_READ(ah, addr); | ||
308 | if (rdData != wrData) { | ||
309 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
310 | "address test failed " | ||
311 | "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", | ||
312 | addr, wrData, rdData); | ||
313 | return false; | ||
314 | } | ||
315 | } | ||
316 | for (j = 0; j < 4; j++) { | ||
317 | wrData = patternData[j]; | ||
318 | REG_WRITE(ah, addr, wrData); | ||
319 | rdData = REG_READ(ah, addr); | ||
320 | if (wrData != rdData) { | ||
321 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
322 | "address test failed " | ||
323 | "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", | ||
324 | addr, wrData, rdData); | ||
325 | return false; | ||
326 | } | ||
327 | } | ||
328 | REG_WRITE(ah, regAddr[i], regHold[i]); | ||
329 | } | ||
330 | udelay(100); | ||
331 | |||
332 | return true; | ||
333 | } | ||
334 | |||
335 | static const char *ath9k_hw_devname(u16 devid) | ||
336 | { | ||
337 | switch (devid) { | ||
338 | case AR5416_DEVID_PCI: | ||
339 | return "Atheros 5416"; | ||
340 | case AR5416_DEVID_PCIE: | ||
341 | return "Atheros 5418"; | ||
342 | case AR9160_DEVID_PCI: | ||
343 | return "Atheros 9160"; | ||
344 | case AR5416_AR9100_DEVID: | ||
345 | return "Atheros 9100"; | ||
346 | case AR9280_DEVID_PCI: | ||
347 | case AR9280_DEVID_PCIE: | ||
348 | return "Atheros 9280"; | ||
349 | case AR9285_DEVID_PCIE: | ||
350 | return "Atheros 9285"; | ||
351 | } | ||
352 | |||
353 | return NULL; | ||
354 | } | ||
355 | |||
356 | static void ath9k_hw_set_defaults(struct ath_hw *ah) | ||
357 | { | ||
358 | int i; | ||
359 | |||
360 | ah->config.dma_beacon_response_time = 2; | ||
361 | ah->config.sw_beacon_response_time = 10; | ||
362 | ah->config.additional_swba_backoff = 0; | ||
363 | ah->config.ack_6mb = 0x0; | ||
364 | ah->config.cwm_ignore_extcca = 0; | ||
365 | ah->config.pcie_powersave_enable = 0; | ||
366 | ah->config.pcie_clock_req = 0; | ||
367 | ah->config.pcie_waen = 0; | ||
368 | ah->config.analog_shiftreg = 1; | ||
369 | ah->config.ht_enable = 1; | ||
370 | ah->config.ofdm_trig_low = 200; | ||
371 | ah->config.ofdm_trig_high = 500; | ||
372 | ah->config.cck_trig_high = 200; | ||
373 | ah->config.cck_trig_low = 100; | ||
374 | ah->config.enable_ani = 1; | ||
375 | ah->config.diversity_control = 0; | ||
376 | ah->config.antenna_switch_swap = 0; | ||
377 | |||
378 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | ||
379 | ah->config.spurchans[i][0] = AR_NO_SPUR; | ||
380 | ah->config.spurchans[i][1] = AR_NO_SPUR; | ||
381 | } | ||
382 | |||
383 | ah->config.intr_mitigation = true; | ||
384 | |||
385 | /* | ||
386 | * We need this for PCI devices only (Cardbus, PCI, miniPCI) | ||
387 | * _and_ if on non-uniprocessor systems (Multiprocessor/HT). | ||
388 | * This means we use it for all AR5416 devices, and the few | ||
389 | * minor PCI AR9280 devices out there. | ||
390 | * | ||
391 | * Serialization is required because these devices do not handle | ||
392 | * well the case of two concurrent reads/writes due to the latency | ||
393 | * involved. During one read/write another read/write can be issued | ||
394 | * on another CPU while the previous read/write may still be working | ||
395 | * on our hardware, if we hit this case the hardware poops in a loop. | ||
396 | * We prevent this by serializing reads and writes. | ||
397 | * | ||
398 | * This issue is not present on PCI-Express devices or pre-AR5416 | ||
399 | * devices (legacy, 802.11abg). | ||
400 | */ | ||
401 | if (num_possible_cpus() > 1) | ||
402 | ah->config.serialize_regmode = SER_REG_MODE_AUTO; | ||
403 | } | ||
404 | |||
405 | static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc, | ||
406 | int *status) | ||
407 | { | ||
408 | struct ath_hw *ah; | ||
409 | |||
410 | ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); | ||
411 | if (ah == NULL) { | ||
412 | DPRINTF(sc, ATH_DBG_FATAL, | ||
413 | "Cannot allocate memory for state block\n"); | ||
414 | *status = -ENOMEM; | ||
415 | return NULL; | ||
416 | } | ||
417 | |||
418 | ah->ah_sc = sc; | ||
419 | ah->hw_version.magic = AR5416_MAGIC; | ||
420 | ah->regulatory.country_code = CTRY_DEFAULT; | ||
421 | ah->hw_version.devid = devid; | ||
422 | ah->hw_version.subvendorid = 0; | ||
423 | |||
424 | ah->ah_flags = 0; | ||
425 | if ((devid == AR5416_AR9100_DEVID)) | ||
426 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; | ||
427 | if (!AR_SREV_9100(ah)) | ||
428 | ah->ah_flags = AH_USE_EEPROM; | ||
429 | |||
430 | ah->regulatory.power_limit = MAX_RATE_POWER; | ||
431 | ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX; | ||
432 | ah->atim_window = 0; | ||
433 | ah->diversity_control = ah->config.diversity_control; | ||
434 | ah->antenna_switch_swap = | ||
435 | ah->config.antenna_switch_swap; | ||
436 | ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE; | ||
437 | ah->beacon_interval = 100; | ||
438 | ah->enable_32kHz_clock = DONT_USE_32KHZ; | ||
439 | ah->slottime = (u32) -1; | ||
440 | ah->acktimeout = (u32) -1; | ||
441 | ah->ctstimeout = (u32) -1; | ||
442 | ah->globaltxtimeout = (u32) -1; | ||
443 | |||
444 | ah->gbeacon_rate = 0; | ||
445 | |||
446 | return ah; | ||
447 | } | ||
448 | |||
449 | static int ath9k_hw_rfattach(struct ath_hw *ah) | ||
450 | { | ||
451 | bool rfStatus = false; | ||
452 | int ecode = 0; | ||
453 | |||
454 | rfStatus = ath9k_hw_init_rf(ah, &ecode); | ||
455 | if (!rfStatus) { | ||
456 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
457 | "RF setup failed, status: %u\n", ecode); | ||
458 | return ecode; | ||
459 | } | ||
460 | |||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | static int ath9k_hw_rf_claim(struct ath_hw *ah) | ||
465 | { | ||
466 | u32 val; | ||
467 | |||
468 | REG_WRITE(ah, AR_PHY(0), 0x00000007); | ||
469 | |||
470 | val = ath9k_hw_get_radiorev(ah); | ||
471 | switch (val & AR_RADIO_SREV_MAJOR) { | ||
472 | case 0: | ||
473 | val = AR_RAD5133_SREV_MAJOR; | ||
474 | break; | ||
475 | case AR_RAD5133_SREV_MAJOR: | ||
476 | case AR_RAD5122_SREV_MAJOR: | ||
477 | case AR_RAD2133_SREV_MAJOR: | ||
478 | case AR_RAD2122_SREV_MAJOR: | ||
479 | break; | ||
480 | default: | ||
481 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
482 | "Radio Chip Rev 0x%02X not supported\n", | ||
483 | val & AR_RADIO_SREV_MAJOR); | ||
484 | return -EOPNOTSUPP; | ||
485 | } | ||
486 | |||
487 | ah->hw_version.analog5GhzRev = val; | ||
488 | |||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static int ath9k_hw_init_macaddr(struct ath_hw *ah) | ||
493 | { | ||
494 | u32 sum; | ||
495 | int i; | ||
496 | u16 eeval; | ||
497 | |||
498 | sum = 0; | ||
499 | for (i = 0; i < 3; i++) { | ||
500 | eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i)); | ||
501 | sum += eeval; | ||
502 | ah->macaddr[2 * i] = eeval >> 8; | ||
503 | ah->macaddr[2 * i + 1] = eeval & 0xff; | ||
504 | } | ||
505 | if (sum == 0 || sum == 0xffff * 3) | ||
506 | return -EADDRNOTAVAIL; | ||
507 | |||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | static void ath9k_hw_init_rxgain_ini(struct ath_hw *ah) | ||
512 | { | ||
513 | u32 rxgain_type; | ||
514 | |||
515 | if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) { | ||
516 | rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE); | ||
517 | |||
518 | if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF) | ||
519 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
520 | ar9280Modes_backoff_13db_rxgain_9280_2, | ||
521 | ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6); | ||
522 | else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF) | ||
523 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
524 | ar9280Modes_backoff_23db_rxgain_9280_2, | ||
525 | ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6); | ||
526 | else | ||
527 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
528 | ar9280Modes_original_rxgain_9280_2, | ||
529 | ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6); | ||
530 | } else { | ||
531 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
532 | ar9280Modes_original_rxgain_9280_2, | ||
533 | ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6); | ||
534 | } | ||
535 | } | ||
536 | |||
537 | static void ath9k_hw_init_txgain_ini(struct ath_hw *ah) | ||
538 | { | ||
539 | u32 txgain_type; | ||
540 | |||
541 | if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) { | ||
542 | txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); | ||
543 | |||
544 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) | ||
545 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
546 | ar9280Modes_high_power_tx_gain_9280_2, | ||
547 | ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6); | ||
548 | else | ||
549 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
550 | ar9280Modes_original_tx_gain_9280_2, | ||
551 | ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6); | ||
552 | } else { | ||
553 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
554 | ar9280Modes_original_tx_gain_9280_2, | ||
555 | ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6); | ||
556 | } | ||
557 | } | ||
558 | |||
559 | static int ath9k_hw_post_attach(struct ath_hw *ah) | ||
560 | { | ||
561 | int ecode; | ||
562 | |||
563 | if (!ath9k_hw_chip_test(ah)) | ||
564 | return -ENODEV; | ||
565 | |||
566 | ecode = ath9k_hw_rf_claim(ah); | ||
567 | if (ecode != 0) | ||
568 | return ecode; | ||
569 | |||
570 | ecode = ath9k_hw_eeprom_attach(ah); | ||
571 | if (ecode != 0) | ||
572 | return ecode; | ||
573 | |||
574 | DPRINTF(ah->ah_sc, ATH_DBG_CONFIG, "Eeprom VER: %d, REV: %d\n", | ||
575 | ah->eep_ops->get_eeprom_ver(ah), ah->eep_ops->get_eeprom_rev(ah)); | ||
576 | |||
577 | ecode = ath9k_hw_rfattach(ah); | ||
578 | if (ecode != 0) | ||
579 | return ecode; | ||
580 | |||
581 | if (!AR_SREV_9100(ah)) { | ||
582 | ath9k_hw_ani_setup(ah); | ||
583 | ath9k_hw_ani_attach(ah); | ||
584 | } | ||
585 | |||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, | ||
590 | int *status) | ||
591 | { | ||
592 | struct ath_hw *ah; | ||
593 | int ecode; | ||
594 | u32 i, j; | ||
595 | |||
596 | ah = ath9k_hw_newstate(devid, sc, status); | ||
597 | if (ah == NULL) | ||
598 | return NULL; | ||
599 | |||
600 | ath9k_hw_set_defaults(ah); | ||
601 | |||
602 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { | ||
603 | DPRINTF(sc, ATH_DBG_FATAL, "Couldn't reset chip\n"); | ||
604 | ecode = -EIO; | ||
605 | goto bad; | ||
606 | } | ||
607 | |||
608 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { | ||
609 | DPRINTF(sc, ATH_DBG_FATAL, "Couldn't wakeup chip\n"); | ||
610 | ecode = -EIO; | ||
611 | goto bad; | ||
612 | } | ||
613 | |||
614 | if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) { | ||
615 | if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || | ||
616 | (AR_SREV_9280(ah) && !ah->is_pciexpress)) { | ||
617 | ah->config.serialize_regmode = | ||
618 | SER_REG_MODE_ON; | ||
619 | } else { | ||
620 | ah->config.serialize_regmode = | ||
621 | SER_REG_MODE_OFF; | ||
622 | } | ||
623 | } | ||
624 | |||
625 | DPRINTF(sc, ATH_DBG_RESET, "serialize_regmode is %d\n", | ||
626 | ah->config.serialize_regmode); | ||
627 | |||
628 | if ((ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCI) && | ||
629 | (ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) && | ||
630 | (ah->hw_version.macVersion != AR_SREV_VERSION_9160) && | ||
631 | (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) { | ||
632 | DPRINTF(sc, ATH_DBG_FATAL, | ||
633 | "Mac Chip Rev 0x%02x.%x is not supported by " | ||
634 | "this driver\n", ah->hw_version.macVersion, | ||
635 | ah->hw_version.macRev); | ||
636 | ecode = -EOPNOTSUPP; | ||
637 | goto bad; | ||
638 | } | ||
639 | |||
640 | if (AR_SREV_9100(ah)) { | ||
641 | ah->iq_caldata.calData = &iq_cal_multi_sample; | ||
642 | ah->supp_cals = IQ_MISMATCH_CAL; | ||
643 | ah->is_pciexpress = false; | ||
644 | } | ||
645 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); | ||
646 | |||
647 | if (AR_SREV_9160_10_OR_LATER(ah)) { | ||
648 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
649 | ah->iq_caldata.calData = &iq_cal_single_sample; | ||
650 | ah->adcgain_caldata.calData = | ||
651 | &adc_gain_cal_single_sample; | ||
652 | ah->adcdc_caldata.calData = | ||
653 | &adc_dc_cal_single_sample; | ||
654 | ah->adcdc_calinitdata.calData = | ||
655 | &adc_init_dc_cal; | ||
656 | } else { | ||
657 | ah->iq_caldata.calData = &iq_cal_multi_sample; | ||
658 | ah->adcgain_caldata.calData = | ||
659 | &adc_gain_cal_multi_sample; | ||
660 | ah->adcdc_caldata.calData = | ||
661 | &adc_dc_cal_multi_sample; | ||
662 | ah->adcdc_calinitdata.calData = | ||
663 | &adc_init_dc_cal; | ||
664 | } | ||
665 | ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL; | ||
666 | } | ||
667 | |||
668 | ah->ani_function = ATH9K_ANI_ALL; | ||
669 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
670 | ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; | ||
671 | |||
672 | if (AR_SREV_9285_12_OR_LATER(ah)) { | ||
673 | |||
674 | INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2, | ||
675 | ARRAY_SIZE(ar9285Modes_9285_1_2), 6); | ||
676 | INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2, | ||
677 | ARRAY_SIZE(ar9285Common_9285_1_2), 2); | ||
678 | |||
679 | if (ah->config.pcie_clock_req) { | ||
680 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
681 | ar9285PciePhy_clkreq_off_L1_9285_1_2, | ||
682 | ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2); | ||
683 | } else { | ||
684 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
685 | ar9285PciePhy_clkreq_always_on_L1_9285_1_2, | ||
686 | ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2), | ||
687 | 2); | ||
688 | } | ||
689 | } else if (AR_SREV_9285_10_OR_LATER(ah)) { | ||
690 | INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285, | ||
691 | ARRAY_SIZE(ar9285Modes_9285), 6); | ||
692 | INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285, | ||
693 | ARRAY_SIZE(ar9285Common_9285), 2); | ||
694 | |||
695 | if (ah->config.pcie_clock_req) { | ||
696 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
697 | ar9285PciePhy_clkreq_off_L1_9285, | ||
698 | ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2); | ||
699 | } else { | ||
700 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
701 | ar9285PciePhy_clkreq_always_on_L1_9285, | ||
702 | ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2); | ||
703 | } | ||
704 | } else if (AR_SREV_9280_20_OR_LATER(ah)) { | ||
705 | INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2, | ||
706 | ARRAY_SIZE(ar9280Modes_9280_2), 6); | ||
707 | INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2, | ||
708 | ARRAY_SIZE(ar9280Common_9280_2), 2); | ||
709 | |||
710 | if (ah->config.pcie_clock_req) { | ||
711 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
712 | ar9280PciePhy_clkreq_off_L1_9280, | ||
713 | ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2); | ||
714 | } else { | ||
715 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
716 | ar9280PciePhy_clkreq_always_on_L1_9280, | ||
717 | ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2); | ||
718 | } | ||
719 | INIT_INI_ARRAY(&ah->iniModesAdditional, | ||
720 | ar9280Modes_fast_clock_9280_2, | ||
721 | ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); | ||
722 | } else if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
723 | INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280, | ||
724 | ARRAY_SIZE(ar9280Modes_9280), 6); | ||
725 | INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280, | ||
726 | ARRAY_SIZE(ar9280Common_9280), 2); | ||
727 | } else if (AR_SREV_9160_10_OR_LATER(ah)) { | ||
728 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160, | ||
729 | ARRAY_SIZE(ar5416Modes_9160), 6); | ||
730 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160, | ||
731 | ARRAY_SIZE(ar5416Common_9160), 2); | ||
732 | INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160, | ||
733 | ARRAY_SIZE(ar5416Bank0_9160), 2); | ||
734 | INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160, | ||
735 | ARRAY_SIZE(ar5416BB_RfGain_9160), 3); | ||
736 | INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160, | ||
737 | ARRAY_SIZE(ar5416Bank1_9160), 2); | ||
738 | INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160, | ||
739 | ARRAY_SIZE(ar5416Bank2_9160), 2); | ||
740 | INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160, | ||
741 | ARRAY_SIZE(ar5416Bank3_9160), 3); | ||
742 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160, | ||
743 | ARRAY_SIZE(ar5416Bank6_9160), 3); | ||
744 | INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160, | ||
745 | ARRAY_SIZE(ar5416Bank6TPC_9160), 3); | ||
746 | INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160, | ||
747 | ARRAY_SIZE(ar5416Bank7_9160), 2); | ||
748 | if (AR_SREV_9160_11(ah)) { | ||
749 | INIT_INI_ARRAY(&ah->iniAddac, | ||
750 | ar5416Addac_91601_1, | ||
751 | ARRAY_SIZE(ar5416Addac_91601_1), 2); | ||
752 | } else { | ||
753 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160, | ||
754 | ARRAY_SIZE(ar5416Addac_9160), 2); | ||
755 | } | ||
756 | } else if (AR_SREV_9100_OR_LATER(ah)) { | ||
757 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100, | ||
758 | ARRAY_SIZE(ar5416Modes_9100), 6); | ||
759 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100, | ||
760 | ARRAY_SIZE(ar5416Common_9100), 2); | ||
761 | INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100, | ||
762 | ARRAY_SIZE(ar5416Bank0_9100), 2); | ||
763 | INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100, | ||
764 | ARRAY_SIZE(ar5416BB_RfGain_9100), 3); | ||
765 | INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100, | ||
766 | ARRAY_SIZE(ar5416Bank1_9100), 2); | ||
767 | INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100, | ||
768 | ARRAY_SIZE(ar5416Bank2_9100), 2); | ||
769 | INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100, | ||
770 | ARRAY_SIZE(ar5416Bank3_9100), 3); | ||
771 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100, | ||
772 | ARRAY_SIZE(ar5416Bank6_9100), 3); | ||
773 | INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100, | ||
774 | ARRAY_SIZE(ar5416Bank6TPC_9100), 3); | ||
775 | INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100, | ||
776 | ARRAY_SIZE(ar5416Bank7_9100), 2); | ||
777 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100, | ||
778 | ARRAY_SIZE(ar5416Addac_9100), 2); | ||
779 | } else { | ||
780 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes, | ||
781 | ARRAY_SIZE(ar5416Modes), 6); | ||
782 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common, | ||
783 | ARRAY_SIZE(ar5416Common), 2); | ||
784 | INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0, | ||
785 | ARRAY_SIZE(ar5416Bank0), 2); | ||
786 | INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain, | ||
787 | ARRAY_SIZE(ar5416BB_RfGain), 3); | ||
788 | INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1, | ||
789 | ARRAY_SIZE(ar5416Bank1), 2); | ||
790 | INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2, | ||
791 | ARRAY_SIZE(ar5416Bank2), 2); | ||
792 | INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3, | ||
793 | ARRAY_SIZE(ar5416Bank3), 3); | ||
794 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6, | ||
795 | ARRAY_SIZE(ar5416Bank6), 3); | ||
796 | INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC, | ||
797 | ARRAY_SIZE(ar5416Bank6TPC), 3); | ||
798 | INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7, | ||
799 | ARRAY_SIZE(ar5416Bank7), 2); | ||
800 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac, | ||
801 | ARRAY_SIZE(ar5416Addac), 2); | ||
802 | } | ||
803 | |||
804 | if (ah->is_pciexpress) | ||
805 | ath9k_hw_configpcipowersave(ah, 0); | ||
806 | else | ||
807 | ath9k_hw_disablepcie(ah); | ||
808 | |||
809 | ecode = ath9k_hw_post_attach(ah); | ||
810 | if (ecode != 0) | ||
811 | goto bad; | ||
812 | |||
813 | if (AR_SREV_9285_12_OR_LATER(ah)) { | ||
814 | u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); | ||
815 | |||
816 | /* txgain table */ | ||
817 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) { | ||
818 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
819 | ar9285Modes_high_power_tx_gain_9285_1_2, | ||
820 | ARRAY_SIZE(ar9285Modes_high_power_tx_gain_9285_1_2), 6); | ||
821 | } else { | ||
822 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
823 | ar9285Modes_original_tx_gain_9285_1_2, | ||
824 | ARRAY_SIZE(ar9285Modes_original_tx_gain_9285_1_2), 6); | ||
825 | } | ||
826 | |||
827 | } | ||
828 | |||
829 | /* rxgain table */ | ||
830 | if (AR_SREV_9280_20(ah)) | ||
831 | ath9k_hw_init_rxgain_ini(ah); | ||
832 | |||
833 | /* txgain table */ | ||
834 | if (AR_SREV_9280_20(ah)) | ||
835 | ath9k_hw_init_txgain_ini(ah); | ||
836 | |||
837 | ath9k_hw_fill_cap_info(ah); | ||
838 | |||
839 | if ((ah->hw_version.devid == AR9280_DEVID_PCI) && | ||
840 | test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) { | ||
841 | |||
842 | /* EEPROM Fixup */ | ||
843 | for (i = 0; i < ah->iniModes.ia_rows; i++) { | ||
844 | u32 reg = INI_RA(&ah->iniModes, i, 0); | ||
845 | |||
846 | for (j = 1; j < ah->iniModes.ia_columns; j++) { | ||
847 | u32 val = INI_RA(&ah->iniModes, i, j); | ||
848 | |||
849 | INI_RA(&ah->iniModes, i, j) = | ||
850 | ath9k_hw_ini_fixup(ah, | ||
851 | &ah->eeprom.def, | ||
852 | reg, val); | ||
853 | } | ||
854 | } | ||
855 | } | ||
856 | |||
857 | ecode = ath9k_hw_init_macaddr(ah); | ||
858 | if (ecode != 0) { | ||
859 | DPRINTF(sc, ATH_DBG_FATAL, | ||
860 | "Failed to initialize MAC address\n"); | ||
861 | goto bad; | ||
862 | } | ||
863 | |||
864 | if (AR_SREV_9285(ah)) | ||
865 | ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S); | ||
866 | else | ||
867 | ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); | ||
868 | |||
869 | ath9k_init_nfcal_hist_buffer(ah); | ||
870 | |||
871 | return ah; | ||
872 | bad: | ||
873 | if (ah) | ||
874 | ath9k_hw_detach(ah); | ||
875 | if (status) | ||
876 | *status = ecode; | ||
877 | |||
878 | return NULL; | ||
879 | } | ||
880 | |||
881 | static void ath9k_hw_init_bb(struct ath_hw *ah, | ||
882 | struct ath9k_channel *chan) | ||
883 | { | ||
884 | u32 synthDelay; | ||
885 | |||
886 | synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; | ||
887 | if (IS_CHAN_B(chan)) | ||
888 | synthDelay = (4 * synthDelay) / 22; | ||
889 | else | ||
890 | synthDelay /= 10; | ||
891 | |||
892 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | ||
893 | |||
894 | udelay(synthDelay + BASE_ACTIVATE_DELAY); | ||
895 | } | ||
896 | |||
897 | static void ath9k_hw_init_qos(struct ath_hw *ah) | ||
898 | { | ||
899 | REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa); | ||
900 | REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210); | ||
901 | |||
902 | REG_WRITE(ah, AR_QOS_NO_ACK, | ||
903 | SM(2, AR_QOS_NO_ACK_TWO_BIT) | | ||
904 | SM(5, AR_QOS_NO_ACK_BIT_OFF) | | ||
905 | SM(0, AR_QOS_NO_ACK_BYTE_OFF)); | ||
906 | |||
907 | REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL); | ||
908 | REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF); | ||
909 | REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF); | ||
910 | REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF); | ||
911 | REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); | ||
912 | } | ||
913 | |||
914 | static void ath9k_hw_init_pll(struct ath_hw *ah, | ||
915 | struct ath9k_channel *chan) | ||
916 | { | ||
917 | u32 pll; | ||
918 | |||
919 | if (AR_SREV_9100(ah)) { | ||
920 | if (chan && IS_CHAN_5GHZ(chan)) | ||
921 | pll = 0x1450; | ||
922 | else | ||
923 | pll = 0x1458; | ||
924 | } else { | ||
925 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
926 | pll = SM(0x5, AR_RTC_9160_PLL_REFDIV); | ||
927 | |||
928 | if (chan && IS_CHAN_HALF_RATE(chan)) | ||
929 | pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL); | ||
930 | else if (chan && IS_CHAN_QUARTER_RATE(chan)) | ||
931 | pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL); | ||
932 | |||
933 | if (chan && IS_CHAN_5GHZ(chan)) { | ||
934 | pll |= SM(0x28, AR_RTC_9160_PLL_DIV); | ||
935 | |||
936 | |||
937 | if (AR_SREV_9280_20(ah)) { | ||
938 | if (((chan->channel % 20) == 0) | ||
939 | || ((chan->channel % 10) == 0)) | ||
940 | pll = 0x2850; | ||
941 | else | ||
942 | pll = 0x142c; | ||
943 | } | ||
944 | } else { | ||
945 | pll |= SM(0x2c, AR_RTC_9160_PLL_DIV); | ||
946 | } | ||
947 | |||
948 | } else if (AR_SREV_9160_10_OR_LATER(ah)) { | ||
949 | |||
950 | pll = SM(0x5, AR_RTC_9160_PLL_REFDIV); | ||
951 | |||
952 | if (chan && IS_CHAN_HALF_RATE(chan)) | ||
953 | pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL); | ||
954 | else if (chan && IS_CHAN_QUARTER_RATE(chan)) | ||
955 | pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL); | ||
956 | |||
957 | if (chan && IS_CHAN_5GHZ(chan)) | ||
958 | pll |= SM(0x50, AR_RTC_9160_PLL_DIV); | ||
959 | else | ||
960 | pll |= SM(0x58, AR_RTC_9160_PLL_DIV); | ||
961 | } else { | ||
962 | pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2; | ||
963 | |||
964 | if (chan && IS_CHAN_HALF_RATE(chan)) | ||
965 | pll |= SM(0x1, AR_RTC_PLL_CLKSEL); | ||
966 | else if (chan && IS_CHAN_QUARTER_RATE(chan)) | ||
967 | pll |= SM(0x2, AR_RTC_PLL_CLKSEL); | ||
968 | |||
969 | if (chan && IS_CHAN_5GHZ(chan)) | ||
970 | pll |= SM(0xa, AR_RTC_PLL_DIV); | ||
971 | else | ||
972 | pll |= SM(0xb, AR_RTC_PLL_DIV); | ||
973 | } | ||
974 | } | ||
975 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); | ||
976 | |||
977 | udelay(RTC_PLL_SETTLE_DELAY); | ||
978 | |||
979 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); | ||
980 | } | ||
981 | |||
982 | static void ath9k_hw_init_chain_masks(struct ath_hw *ah) | ||
983 | { | ||
984 | int rx_chainmask, tx_chainmask; | ||
985 | |||
986 | rx_chainmask = ah->rxchainmask; | ||
987 | tx_chainmask = ah->txchainmask; | ||
988 | |||
989 | switch (rx_chainmask) { | ||
990 | case 0x5: | ||
991 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | ||
992 | AR_PHY_SWAP_ALT_CHAIN); | ||
993 | case 0x3: | ||
994 | if (((ah)->hw_version.macVersion <= AR_SREV_VERSION_9160)) { | ||
995 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7); | ||
996 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7); | ||
997 | break; | ||
998 | } | ||
999 | case 0x1: | ||
1000 | case 0x2: | ||
1001 | case 0x7: | ||
1002 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); | ||
1003 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); | ||
1004 | break; | ||
1005 | default: | ||
1006 | break; | ||
1007 | } | ||
1008 | |||
1009 | REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask); | ||
1010 | if (tx_chainmask == 0x5) { | ||
1011 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | ||
1012 | AR_PHY_SWAP_ALT_CHAIN); | ||
1013 | } | ||
1014 | if (AR_SREV_9100(ah)) | ||
1015 | REG_WRITE(ah, AR_PHY_ANALOG_SWAP, | ||
1016 | REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001); | ||
1017 | } | ||
1018 | |||
1019 | static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | ||
1020 | enum nl80211_iftype opmode) | ||
1021 | { | ||
1022 | ah->mask_reg = AR_IMR_TXERR | | ||
1023 | AR_IMR_TXURN | | ||
1024 | AR_IMR_RXERR | | ||
1025 | AR_IMR_RXORN | | ||
1026 | AR_IMR_BCNMISC; | ||
1027 | |||
1028 | if (ah->config.intr_mitigation) | ||
1029 | ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; | ||
1030 | else | ||
1031 | ah->mask_reg |= AR_IMR_RXOK; | ||
1032 | |||
1033 | ah->mask_reg |= AR_IMR_TXOK; | ||
1034 | |||
1035 | if (opmode == NL80211_IFTYPE_AP) | ||
1036 | ah->mask_reg |= AR_IMR_MIB; | ||
1037 | |||
1038 | REG_WRITE(ah, AR_IMR, ah->mask_reg); | ||
1039 | REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT); | ||
1040 | |||
1041 | if (!AR_SREV_9100(ah)) { | ||
1042 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); | ||
1043 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT); | ||
1044 | REG_WRITE(ah, AR_INTR_SYNC_MASK, 0); | ||
1045 | } | ||
1046 | } | ||
1047 | |||
1048 | static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) | ||
1049 | { | ||
1050 | if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { | ||
1051 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad ack timeout %u\n", us); | ||
1052 | ah->acktimeout = (u32) -1; | ||
1053 | return false; | ||
1054 | } else { | ||
1055 | REG_RMW_FIELD(ah, AR_TIME_OUT, | ||
1056 | AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us)); | ||
1057 | ah->acktimeout = us; | ||
1058 | return true; | ||
1059 | } | ||
1060 | } | ||
1061 | |||
1062 | static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) | ||
1063 | { | ||
1064 | if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { | ||
1065 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad cts timeout %u\n", us); | ||
1066 | ah->ctstimeout = (u32) -1; | ||
1067 | return false; | ||
1068 | } else { | ||
1069 | REG_RMW_FIELD(ah, AR_TIME_OUT, | ||
1070 | AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us)); | ||
1071 | ah->ctstimeout = us; | ||
1072 | return true; | ||
1073 | } | ||
1074 | } | ||
1075 | |||
1076 | static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) | ||
1077 | { | ||
1078 | if (tu > 0xFFFF) { | ||
1079 | DPRINTF(ah->ah_sc, ATH_DBG_XMIT, | ||
1080 | "bad global tx timeout %u\n", tu); | ||
1081 | ah->globaltxtimeout = (u32) -1; | ||
1082 | return false; | ||
1083 | } else { | ||
1084 | REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu); | ||
1085 | ah->globaltxtimeout = tu; | ||
1086 | return true; | ||
1087 | } | ||
1088 | } | ||
1089 | |||
1090 | static void ath9k_hw_init_user_settings(struct ath_hw *ah) | ||
1091 | { | ||
1092 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ah->misc_mode 0x%x\n", | ||
1093 | ah->misc_mode); | ||
1094 | |||
1095 | if (ah->misc_mode != 0) | ||
1096 | REG_WRITE(ah, AR_PCU_MISC, | ||
1097 | REG_READ(ah, AR_PCU_MISC) | ah->misc_mode); | ||
1098 | if (ah->slottime != (u32) -1) | ||
1099 | ath9k_hw_setslottime(ah, ah->slottime); | ||
1100 | if (ah->acktimeout != (u32) -1) | ||
1101 | ath9k_hw_set_ack_timeout(ah, ah->acktimeout); | ||
1102 | if (ah->ctstimeout != (u32) -1) | ||
1103 | ath9k_hw_set_cts_timeout(ah, ah->ctstimeout); | ||
1104 | if (ah->globaltxtimeout != (u32) -1) | ||
1105 | ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); | ||
1106 | } | ||
1107 | |||
1108 | const char *ath9k_hw_probe(u16 vendorid, u16 devid) | ||
1109 | { | ||
1110 | return vendorid == ATHEROS_VENDOR_ID ? | ||
1111 | ath9k_hw_devname(devid) : NULL; | ||
1112 | } | ||
1113 | |||
1114 | void ath9k_hw_detach(struct ath_hw *ah) | ||
1115 | { | ||
1116 | if (!AR_SREV_9100(ah)) | ||
1117 | ath9k_hw_ani_detach(ah); | ||
1118 | |||
1119 | ath9k_hw_rfdetach(ah); | ||
1120 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); | ||
1121 | kfree(ah); | ||
1122 | } | ||
1123 | |||
1124 | struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error) | ||
1125 | { | ||
1126 | struct ath_hw *ah = NULL; | ||
1127 | |||
1128 | switch (devid) { | ||
1129 | case AR5416_DEVID_PCI: | ||
1130 | case AR5416_DEVID_PCIE: | ||
1131 | case AR5416_AR9100_DEVID: | ||
1132 | case AR9160_DEVID_PCI: | ||
1133 | case AR9280_DEVID_PCI: | ||
1134 | case AR9280_DEVID_PCIE: | ||
1135 | case AR9285_DEVID_PCIE: | ||
1136 | ah = ath9k_hw_do_attach(devid, sc, error); | ||
1137 | break; | ||
1138 | default: | ||
1139 | *error = -ENXIO; | ||
1140 | break; | ||
1141 | } | ||
1142 | |||
1143 | return ah; | ||
1144 | } | ||
1145 | |||
1146 | /*******/ | ||
1147 | /* INI */ | ||
1148 | /*******/ | ||
1149 | |||
1150 | static void ath9k_hw_override_ini(struct ath_hw *ah, | ||
1151 | struct ath9k_channel *chan) | ||
1152 | { | ||
1153 | /* | ||
1154 | * Set the RX_ABORT and RX_DIS and clear if off only after | ||
1155 | * RXE is set for MAC. This prevents frames with corrupted | ||
1156 | * descriptor status. | ||
1157 | */ | ||
1158 | REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); | ||
1159 | |||
1160 | |||
1161 | if (!AR_SREV_5416_20_OR_LATER(ah) || | ||
1162 | AR_SREV_9280_10_OR_LATER(ah)) | ||
1163 | return; | ||
1164 | |||
1165 | REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); | ||
1166 | } | ||
1167 | |||
1168 | static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah, | ||
1169 | struct ar5416_eeprom_def *pEepData, | ||
1170 | u32 reg, u32 value) | ||
1171 | { | ||
1172 | struct base_eep_header *pBase = &(pEepData->baseEepHeader); | ||
1173 | |||
1174 | switch (ah->hw_version.devid) { | ||
1175 | case AR9280_DEVID_PCI: | ||
1176 | if (reg == 0x7894) { | ||
1177 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
1178 | "ini VAL: %x EEPROM: %x\n", value, | ||
1179 | (pBase->version & 0xff)); | ||
1180 | |||
1181 | if ((pBase->version & 0xff) > 0x0a) { | ||
1182 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
1183 | "PWDCLKIND: %d\n", | ||
1184 | pBase->pwdclkind); | ||
1185 | value &= ~AR_AN_TOP2_PWDCLKIND; | ||
1186 | value |= AR_AN_TOP2_PWDCLKIND & | ||
1187 | (pBase->pwdclkind << AR_AN_TOP2_PWDCLKIND_S); | ||
1188 | } else { | ||
1189 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
1190 | "PWDCLKIND Earlier Rev\n"); | ||
1191 | } | ||
1192 | |||
1193 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
1194 | "final ini VAL: %x\n", value); | ||
1195 | } | ||
1196 | break; | ||
1197 | } | ||
1198 | |||
1199 | return value; | ||
1200 | } | ||
1201 | |||
1202 | static u32 ath9k_hw_ini_fixup(struct ath_hw *ah, | ||
1203 | struct ar5416_eeprom_def *pEepData, | ||
1204 | u32 reg, u32 value) | ||
1205 | { | ||
1206 | if (ah->eep_map == EEP_MAP_4KBITS) | ||
1207 | return value; | ||
1208 | else | ||
1209 | return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value); | ||
1210 | } | ||
1211 | |||
1212 | static void ath9k_olc_init(struct ath_hw *ah) | ||
1213 | { | ||
1214 | u32 i; | ||
1215 | |||
1216 | for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++) | ||
1217 | ah->originalGain[i] = | ||
1218 | MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4), | ||
1219 | AR_PHY_TX_GAIN); | ||
1220 | ah->PDADCdelta = 0; | ||
1221 | } | ||
1222 | |||
1223 | static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, | ||
1224 | struct ath9k_channel *chan) | ||
1225 | { | ||
1226 | u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band); | ||
1227 | |||
1228 | if (IS_CHAN_B(chan)) | ||
1229 | ctl |= CTL_11B; | ||
1230 | else if (IS_CHAN_G(chan)) | ||
1231 | ctl |= CTL_11G; | ||
1232 | else | ||
1233 | ctl |= CTL_11A; | ||
1234 | |||
1235 | return ctl; | ||
1236 | } | ||
1237 | |||
1238 | static int ath9k_hw_process_ini(struct ath_hw *ah, | ||
1239 | struct ath9k_channel *chan, | ||
1240 | enum ath9k_ht_macmode macmode) | ||
1241 | { | ||
1242 | int i, regWrites = 0; | ||
1243 | struct ieee80211_channel *channel = chan->chan; | ||
1244 | u32 modesIndex, freqIndex; | ||
1245 | int status; | ||
1246 | |||
1247 | switch (chan->chanmode) { | ||
1248 | case CHANNEL_A: | ||
1249 | case CHANNEL_A_HT20: | ||
1250 | modesIndex = 1; | ||
1251 | freqIndex = 1; | ||
1252 | break; | ||
1253 | case CHANNEL_A_HT40PLUS: | ||
1254 | case CHANNEL_A_HT40MINUS: | ||
1255 | modesIndex = 2; | ||
1256 | freqIndex = 1; | ||
1257 | break; | ||
1258 | case CHANNEL_G: | ||
1259 | case CHANNEL_G_HT20: | ||
1260 | case CHANNEL_B: | ||
1261 | modesIndex = 4; | ||
1262 | freqIndex = 2; | ||
1263 | break; | ||
1264 | case CHANNEL_G_HT40PLUS: | ||
1265 | case CHANNEL_G_HT40MINUS: | ||
1266 | modesIndex = 3; | ||
1267 | freqIndex = 2; | ||
1268 | break; | ||
1269 | |||
1270 | default: | ||
1271 | return -EINVAL; | ||
1272 | } | ||
1273 | |||
1274 | REG_WRITE(ah, AR_PHY(0), 0x00000007); | ||
1275 | REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); | ||
1276 | ah->eep_ops->set_addac(ah, chan); | ||
1277 | |||
1278 | if (AR_SREV_5416_22_OR_LATER(ah)) { | ||
1279 | REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites); | ||
1280 | } else { | ||
1281 | struct ar5416IniArray temp; | ||
1282 | u32 addacSize = | ||
1283 | sizeof(u32) * ah->iniAddac.ia_rows * | ||
1284 | ah->iniAddac.ia_columns; | ||
1285 | |||
1286 | memcpy(ah->addac5416_21, | ||
1287 | ah->iniAddac.ia_array, addacSize); | ||
1288 | |||
1289 | (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0; | ||
1290 | |||
1291 | temp.ia_array = ah->addac5416_21; | ||
1292 | temp.ia_columns = ah->iniAddac.ia_columns; | ||
1293 | temp.ia_rows = ah->iniAddac.ia_rows; | ||
1294 | REG_WRITE_ARRAY(&temp, 1, regWrites); | ||
1295 | } | ||
1296 | |||
1297 | REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); | ||
1298 | |||
1299 | for (i = 0; i < ah->iniModes.ia_rows; i++) { | ||
1300 | u32 reg = INI_RA(&ah->iniModes, i, 0); | ||
1301 | u32 val = INI_RA(&ah->iniModes, i, modesIndex); | ||
1302 | |||
1303 | REG_WRITE(ah, reg, val); | ||
1304 | |||
1305 | if (reg >= 0x7800 && reg < 0x78a0 | ||
1306 | && ah->config.analog_shiftreg) { | ||
1307 | udelay(100); | ||
1308 | } | ||
1309 | |||
1310 | DO_DELAY(regWrites); | ||
1311 | } | ||
1312 | |||
1313 | if (AR_SREV_9280(ah)) | ||
1314 | REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites); | ||
1315 | |||
1316 | if (AR_SREV_9280(ah) || (AR_SREV_9285(ah) && | ||
1317 | AR_SREV_9285_12_OR_LATER(ah))) | ||
1318 | REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); | ||
1319 | |||
1320 | for (i = 0; i < ah->iniCommon.ia_rows; i++) { | ||
1321 | u32 reg = INI_RA(&ah->iniCommon, i, 0); | ||
1322 | u32 val = INI_RA(&ah->iniCommon, i, 1); | ||
1323 | |||
1324 | REG_WRITE(ah, reg, val); | ||
1325 | |||
1326 | if (reg >= 0x7800 && reg < 0x78a0 | ||
1327 | && ah->config.analog_shiftreg) { | ||
1328 | udelay(100); | ||
1329 | } | ||
1330 | |||
1331 | DO_DELAY(regWrites); | ||
1332 | } | ||
1333 | |||
1334 | ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites); | ||
1335 | |||
1336 | if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) { | ||
1337 | REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, | ||
1338 | regWrites); | ||
1339 | } | ||
1340 | |||
1341 | ath9k_hw_override_ini(ah, chan); | ||
1342 | ath9k_hw_set_regs(ah, chan, macmode); | ||
1343 | ath9k_hw_init_chain_masks(ah); | ||
1344 | |||
1345 | if (OLC_FOR_AR9280_20_LATER) | ||
1346 | ath9k_olc_init(ah); | ||
1347 | |||
1348 | status = ah->eep_ops->set_txpower(ah, chan, | ||
1349 | ath9k_regd_get_ctl(&ah->regulatory, chan), | ||
1350 | channel->max_antenna_gain * 2, | ||
1351 | channel->max_power * 2, | ||
1352 | min((u32) MAX_RATE_POWER, | ||
1353 | (u32) ah->regulatory.power_limit)); | ||
1354 | if (status != 0) { | ||
1355 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
1356 | "Error initializing transmit power\n"); | ||
1357 | return -EIO; | ||
1358 | } | ||
1359 | |||
1360 | if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { | ||
1361 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
1362 | "ar5416SetRfRegs failed\n"); | ||
1363 | return -EIO; | ||
1364 | } | ||
1365 | |||
1366 | return 0; | ||
1367 | } | ||
1368 | |||
1369 | /****************************************/ | ||
1370 | /* Reset and Channel Switching Routines */ | ||
1371 | /****************************************/ | ||
1372 | |||
1373 | static void ath9k_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan) | ||
1374 | { | ||
1375 | u32 rfMode = 0; | ||
1376 | |||
1377 | if (chan == NULL) | ||
1378 | return; | ||
1379 | |||
1380 | rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan)) | ||
1381 | ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; | ||
1382 | |||
1383 | if (!AR_SREV_9280_10_OR_LATER(ah)) | ||
1384 | rfMode |= (IS_CHAN_5GHZ(chan)) ? | ||
1385 | AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; | ||
1386 | |||
1387 | if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) | ||
1388 | rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); | ||
1389 | |||
1390 | REG_WRITE(ah, AR_PHY_MODE, rfMode); | ||
1391 | } | ||
1392 | |||
1393 | static void ath9k_hw_mark_phy_inactive(struct ath_hw *ah) | ||
1394 | { | ||
1395 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); | ||
1396 | } | ||
1397 | |||
1398 | static inline void ath9k_hw_set_dma(struct ath_hw *ah) | ||
1399 | { | ||
1400 | u32 regval; | ||
1401 | |||
1402 | regval = REG_READ(ah, AR_AHB_MODE); | ||
1403 | REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN); | ||
1404 | |||
1405 | regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK; | ||
1406 | REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B); | ||
1407 | |||
1408 | REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level); | ||
1409 | |||
1410 | regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK; | ||
1411 | REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B); | ||
1412 | |||
1413 | REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); | ||
1414 | |||
1415 | if (AR_SREV_9285(ah)) { | ||
1416 | REG_WRITE(ah, AR_PCU_TXBUF_CTRL, | ||
1417 | AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE); | ||
1418 | } else { | ||
1419 | REG_WRITE(ah, AR_PCU_TXBUF_CTRL, | ||
1420 | AR_PCU_TXBUF_CTRL_USABLE_SIZE); | ||
1421 | } | ||
1422 | } | ||
1423 | |||
1424 | static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) | ||
1425 | { | ||
1426 | u32 val; | ||
1427 | |||
1428 | val = REG_READ(ah, AR_STA_ID1); | ||
1429 | val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC); | ||
1430 | switch (opmode) { | ||
1431 | case NL80211_IFTYPE_AP: | ||
1432 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP | ||
1433 | | AR_STA_ID1_KSRCH_MODE); | ||
1434 | REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); | ||
1435 | break; | ||
1436 | case NL80211_IFTYPE_ADHOC: | ||
1437 | case NL80211_IFTYPE_MESH_POINT: | ||
1438 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC | ||
1439 | | AR_STA_ID1_KSRCH_MODE); | ||
1440 | REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); | ||
1441 | break; | ||
1442 | case NL80211_IFTYPE_STATION: | ||
1443 | case NL80211_IFTYPE_MONITOR: | ||
1444 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); | ||
1445 | break; | ||
1446 | } | ||
1447 | } | ||
1448 | |||
1449 | static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, | ||
1450 | u32 coef_scaled, | ||
1451 | u32 *coef_mantissa, | ||
1452 | u32 *coef_exponent) | ||
1453 | { | ||
1454 | u32 coef_exp, coef_man; | ||
1455 | |||
1456 | for (coef_exp = 31; coef_exp > 0; coef_exp--) | ||
1457 | if ((coef_scaled >> coef_exp) & 0x1) | ||
1458 | break; | ||
1459 | |||
1460 | coef_exp = 14 - (coef_exp - COEF_SCALE_S); | ||
1461 | |||
1462 | coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1)); | ||
1463 | |||
1464 | *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp); | ||
1465 | *coef_exponent = coef_exp - 16; | ||
1466 | } | ||
1467 | |||
1468 | static void ath9k_hw_set_delta_slope(struct ath_hw *ah, | ||
1469 | struct ath9k_channel *chan) | ||
1470 | { | ||
1471 | u32 coef_scaled, ds_coef_exp, ds_coef_man; | ||
1472 | u32 clockMhzScaled = 0x64000000; | ||
1473 | struct chan_centers centers; | ||
1474 | |||
1475 | if (IS_CHAN_HALF_RATE(chan)) | ||
1476 | clockMhzScaled = clockMhzScaled >> 1; | ||
1477 | else if (IS_CHAN_QUARTER_RATE(chan)) | ||
1478 | clockMhzScaled = clockMhzScaled >> 2; | ||
1479 | |||
1480 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
1481 | coef_scaled = clockMhzScaled / centers.synth_center; | ||
1482 | |||
1483 | ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man, | ||
1484 | &ds_coef_exp); | ||
1485 | |||
1486 | REG_RMW_FIELD(ah, AR_PHY_TIMING3, | ||
1487 | AR_PHY_TIMING3_DSC_MAN, ds_coef_man); | ||
1488 | REG_RMW_FIELD(ah, AR_PHY_TIMING3, | ||
1489 | AR_PHY_TIMING3_DSC_EXP, ds_coef_exp); | ||
1490 | |||
1491 | coef_scaled = (9 * coef_scaled) / 10; | ||
1492 | |||
1493 | ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man, | ||
1494 | &ds_coef_exp); | ||
1495 | |||
1496 | REG_RMW_FIELD(ah, AR_PHY_HALFGI, | ||
1497 | AR_PHY_HALFGI_DSC_MAN, ds_coef_man); | ||
1498 | REG_RMW_FIELD(ah, AR_PHY_HALFGI, | ||
1499 | AR_PHY_HALFGI_DSC_EXP, ds_coef_exp); | ||
1500 | } | ||
1501 | |||
1502 | static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | ||
1503 | { | ||
1504 | u32 rst_flags; | ||
1505 | u32 tmpReg; | ||
1506 | |||
1507 | if (AR_SREV_9100(ah)) { | ||
1508 | u32 val = REG_READ(ah, AR_RTC_DERIVED_CLK); | ||
1509 | val &= ~AR_RTC_DERIVED_CLK_PERIOD; | ||
1510 | val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD); | ||
1511 | REG_WRITE(ah, AR_RTC_DERIVED_CLK, val); | ||
1512 | (void)REG_READ(ah, AR_RTC_DERIVED_CLK); | ||
1513 | } | ||
1514 | |||
1515 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | | ||
1516 | AR_RTC_FORCE_WAKE_ON_INT); | ||
1517 | |||
1518 | if (AR_SREV_9100(ah)) { | ||
1519 | rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD | | ||
1520 | AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET; | ||
1521 | } else { | ||
1522 | tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE); | ||
1523 | if (tmpReg & | ||
1524 | (AR_INTR_SYNC_LOCAL_TIMEOUT | | ||
1525 | AR_INTR_SYNC_RADM_CPL_TIMEOUT)) { | ||
1526 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); | ||
1527 | REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); | ||
1528 | } else { | ||
1529 | REG_WRITE(ah, AR_RC, AR_RC_AHB); | ||
1530 | } | ||
1531 | |||
1532 | rst_flags = AR_RTC_RC_MAC_WARM; | ||
1533 | if (type == ATH9K_RESET_COLD) | ||
1534 | rst_flags |= AR_RTC_RC_MAC_COLD; | ||
1535 | } | ||
1536 | |||
1537 | REG_WRITE(ah, AR_RTC_RC, rst_flags); | ||
1538 | udelay(50); | ||
1539 | |||
1540 | REG_WRITE(ah, AR_RTC_RC, 0); | ||
1541 | if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) { | ||
1542 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | ||
1543 | "RTC stuck in MAC reset\n"); | ||
1544 | return false; | ||
1545 | } | ||
1546 | |||
1547 | if (!AR_SREV_9100(ah)) | ||
1548 | REG_WRITE(ah, AR_RC, 0); | ||
1549 | |||
1550 | ath9k_hw_init_pll(ah, NULL); | ||
1551 | |||
1552 | if (AR_SREV_9100(ah)) | ||
1553 | udelay(50); | ||
1554 | |||
1555 | return true; | ||
1556 | } | ||
1557 | |||
1558 | static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) | ||
1559 | { | ||
1560 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | | ||
1561 | AR_RTC_FORCE_WAKE_ON_INT); | ||
1562 | |||
1563 | REG_WRITE(ah, AR_RTC_RESET, 0); | ||
1564 | udelay(2); | ||
1565 | REG_WRITE(ah, AR_RTC_RESET, 1); | ||
1566 | |||
1567 | if (!ath9k_hw_wait(ah, | ||
1568 | AR_RTC_STATUS, | ||
1569 | AR_RTC_STATUS_M, | ||
1570 | AR_RTC_STATUS_ON, | ||
1571 | AH_WAIT_TIMEOUT)) { | ||
1572 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "RTC not waking up\n"); | ||
1573 | return false; | ||
1574 | } | ||
1575 | |||
1576 | ath9k_hw_read_revisions(ah); | ||
1577 | |||
1578 | return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM); | ||
1579 | } | ||
1580 | |||
1581 | static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) | ||
1582 | { | ||
1583 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, | ||
1584 | AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); | ||
1585 | |||
1586 | switch (type) { | ||
1587 | case ATH9K_RESET_POWER_ON: | ||
1588 | return ath9k_hw_set_reset_power_on(ah); | ||
1589 | break; | ||
1590 | case ATH9K_RESET_WARM: | ||
1591 | case ATH9K_RESET_COLD: | ||
1592 | return ath9k_hw_set_reset(ah, type); | ||
1593 | break; | ||
1594 | default: | ||
1595 | return false; | ||
1596 | } | ||
1597 | } | ||
1598 | |||
1599 | static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan, | ||
1600 | enum ath9k_ht_macmode macmode) | ||
1601 | { | ||
1602 | u32 phymode; | ||
1603 | u32 enableDacFifo = 0; | ||
1604 | |||
1605 | if (AR_SREV_9285_10_OR_LATER(ah)) | ||
1606 | enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) & | ||
1607 | AR_PHY_FC_ENABLE_DAC_FIFO); | ||
1608 | |||
1609 | phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 | ||
1610 | | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo; | ||
1611 | |||
1612 | if (IS_CHAN_HT40(chan)) { | ||
1613 | phymode |= AR_PHY_FC_DYN2040_EN; | ||
1614 | |||
1615 | if ((chan->chanmode == CHANNEL_A_HT40PLUS) || | ||
1616 | (chan->chanmode == CHANNEL_G_HT40PLUS)) | ||
1617 | phymode |= AR_PHY_FC_DYN2040_PRI_CH; | ||
1618 | |||
1619 | if (ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_25) | ||
1620 | phymode |= AR_PHY_FC_DYN2040_EXT_CH; | ||
1621 | } | ||
1622 | REG_WRITE(ah, AR_PHY_TURBO, phymode); | ||
1623 | |||
1624 | ath9k_hw_set11nmac2040(ah, macmode); | ||
1625 | |||
1626 | REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S); | ||
1627 | REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); | ||
1628 | } | ||
1629 | |||
1630 | static bool ath9k_hw_chip_reset(struct ath_hw *ah, | ||
1631 | struct ath9k_channel *chan) | ||
1632 | { | ||
1633 | if (OLC_FOR_AR9280_20_LATER) { | ||
1634 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) | ||
1635 | return false; | ||
1636 | } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) | ||
1637 | return false; | ||
1638 | |||
1639 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) | ||
1640 | return false; | ||
1641 | |||
1642 | ah->chip_fullsleep = false; | ||
1643 | ath9k_hw_init_pll(ah, chan); | ||
1644 | ath9k_hw_set_rfmode(ah, chan); | ||
1645 | |||
1646 | return true; | ||
1647 | } | ||
1648 | |||
1649 | static bool ath9k_hw_channel_change(struct ath_hw *ah, | ||
1650 | struct ath9k_channel *chan, | ||
1651 | enum ath9k_ht_macmode macmode) | ||
1652 | { | ||
1653 | struct ieee80211_channel *channel = chan->chan; | ||
1654 | u32 synthDelay, qnum; | ||
1655 | |||
1656 | for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { | ||
1657 | if (ath9k_hw_numtxpending(ah, qnum)) { | ||
1658 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, | ||
1659 | "Transmit frames pending on queue %d\n", qnum); | ||
1660 | return false; | ||
1661 | } | ||
1662 | } | ||
1663 | |||
1664 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN); | ||
1665 | if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN, | ||
1666 | AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) { | ||
1667 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
1668 | "Could not kill baseband RX\n"); | ||
1669 | return false; | ||
1670 | } | ||
1671 | |||
1672 | ath9k_hw_set_regs(ah, chan, macmode); | ||
1673 | |||
1674 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
1675 | if (!(ath9k_hw_ar9280_set_channel(ah, chan))) { | ||
1676 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
1677 | "Failed to set channel\n"); | ||
1678 | return false; | ||
1679 | } | ||
1680 | } else { | ||
1681 | if (!(ath9k_hw_set_channel(ah, chan))) { | ||
1682 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
1683 | "Failed to set channel\n"); | ||
1684 | return false; | ||
1685 | } | ||
1686 | } | ||
1687 | |||
1688 | if (ah->eep_ops->set_txpower(ah, chan, | ||
1689 | ath9k_regd_get_ctl(&ah->regulatory, chan), | ||
1690 | channel->max_antenna_gain * 2, | ||
1691 | channel->max_power * 2, | ||
1692 | min((u32) MAX_RATE_POWER, | ||
1693 | (u32) ah->regulatory.power_limit)) != 0) { | ||
1694 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
1695 | "Error initializing transmit power\n"); | ||
1696 | return false; | ||
1697 | } | ||
1698 | |||
1699 | synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; | ||
1700 | if (IS_CHAN_B(chan)) | ||
1701 | synthDelay = (4 * synthDelay) / 22; | ||
1702 | else | ||
1703 | synthDelay /= 10; | ||
1704 | |||
1705 | udelay(synthDelay + BASE_ACTIVATE_DELAY); | ||
1706 | |||
1707 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); | ||
1708 | |||
1709 | if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) | ||
1710 | ath9k_hw_set_delta_slope(ah, chan); | ||
1711 | |||
1712 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
1713 | ath9k_hw_9280_spur_mitigate(ah, chan); | ||
1714 | else | ||
1715 | ath9k_hw_spur_mitigate(ah, chan); | ||
1716 | |||
1717 | if (!chan->oneTimeCalsDone) | ||
1718 | chan->oneTimeCalsDone = true; | ||
1719 | |||
1720 | return true; | ||
1721 | } | ||
1722 | |||
1723 | static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan) | ||
1724 | { | ||
1725 | int bb_spur = AR_NO_SPUR; | ||
1726 | int freq; | ||
1727 | int bin, cur_bin; | ||
1728 | int bb_spur_off, spur_subchannel_sd; | ||
1729 | int spur_freq_sd; | ||
1730 | int spur_delta_phase; | ||
1731 | int denominator; | ||
1732 | int upper, lower, cur_vit_mask; | ||
1733 | int tmp, newVal; | ||
1734 | int i; | ||
1735 | int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, | ||
1736 | AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 | ||
1737 | }; | ||
1738 | int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, | ||
1739 | AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 | ||
1740 | }; | ||
1741 | int inc[4] = { 0, 100, 0, 0 }; | ||
1742 | struct chan_centers centers; | ||
1743 | |||
1744 | int8_t mask_m[123]; | ||
1745 | int8_t mask_p[123]; | ||
1746 | int8_t mask_amt; | ||
1747 | int tmp_mask; | ||
1748 | int cur_bb_spur; | ||
1749 | bool is2GHz = IS_CHAN_2GHZ(chan); | ||
1750 | |||
1751 | memset(&mask_m, 0, sizeof(int8_t) * 123); | ||
1752 | memset(&mask_p, 0, sizeof(int8_t) * 123); | ||
1753 | |||
1754 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
1755 | freq = centers.synth_center; | ||
1756 | |||
1757 | ah->config.spurmode = SPUR_ENABLE_EEPROM; | ||
1758 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | ||
1759 | cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); | ||
1760 | |||
1761 | if (is2GHz) | ||
1762 | cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ; | ||
1763 | else | ||
1764 | cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ; | ||
1765 | |||
1766 | if (AR_NO_SPUR == cur_bb_spur) | ||
1767 | break; | ||
1768 | cur_bb_spur = cur_bb_spur - freq; | ||
1769 | |||
1770 | if (IS_CHAN_HT40(chan)) { | ||
1771 | if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) && | ||
1772 | (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) { | ||
1773 | bb_spur = cur_bb_spur; | ||
1774 | break; | ||
1775 | } | ||
1776 | } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) && | ||
1777 | (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) { | ||
1778 | bb_spur = cur_bb_spur; | ||
1779 | break; | ||
1780 | } | ||
1781 | } | ||
1782 | |||
1783 | if (AR_NO_SPUR == bb_spur) { | ||
1784 | REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, | ||
1785 | AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); | ||
1786 | return; | ||
1787 | } else { | ||
1788 | REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, | ||
1789 | AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); | ||
1790 | } | ||
1791 | |||
1792 | bin = bb_spur * 320; | ||
1793 | |||
1794 | tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0)); | ||
1795 | |||
1796 | newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | | ||
1797 | AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | | ||
1798 | AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | | ||
1799 | AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); | ||
1800 | REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal); | ||
1801 | |||
1802 | newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | | ||
1803 | AR_PHY_SPUR_REG_ENABLE_MASK_PPM | | ||
1804 | AR_PHY_SPUR_REG_MASK_RATE_SELECT | | ||
1805 | AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | | ||
1806 | SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); | ||
1807 | REG_WRITE(ah, AR_PHY_SPUR_REG, newVal); | ||
1808 | |||
1809 | if (IS_CHAN_HT40(chan)) { | ||
1810 | if (bb_spur < 0) { | ||
1811 | spur_subchannel_sd = 1; | ||
1812 | bb_spur_off = bb_spur + 10; | ||
1813 | } else { | ||
1814 | spur_subchannel_sd = 0; | ||
1815 | bb_spur_off = bb_spur - 10; | ||
1816 | } | ||
1817 | } else { | ||
1818 | spur_subchannel_sd = 0; | ||
1819 | bb_spur_off = bb_spur; | ||
1820 | } | ||
1821 | |||
1822 | if (IS_CHAN_HT40(chan)) | ||
1823 | spur_delta_phase = | ||
1824 | ((bb_spur * 262144) / | ||
1825 | 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
1826 | else | ||
1827 | spur_delta_phase = | ||
1828 | ((bb_spur * 524288) / | ||
1829 | 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
1830 | |||
1831 | denominator = IS_CHAN_2GHZ(chan) ? 44 : 40; | ||
1832 | spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff; | ||
1833 | |||
1834 | newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | | ||
1835 | SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | | ||
1836 | SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); | ||
1837 | REG_WRITE(ah, AR_PHY_TIMING11, newVal); | ||
1838 | |||
1839 | newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S; | ||
1840 | REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal); | ||
1841 | |||
1842 | cur_bin = -6000; | ||
1843 | upper = bin + 100; | ||
1844 | lower = bin - 100; | ||
1845 | |||
1846 | for (i = 0; i < 4; i++) { | ||
1847 | int pilot_mask = 0; | ||
1848 | int chan_mask = 0; | ||
1849 | int bp = 0; | ||
1850 | for (bp = 0; bp < 30; bp++) { | ||
1851 | if ((cur_bin > lower) && (cur_bin < upper)) { | ||
1852 | pilot_mask = pilot_mask | 0x1 << bp; | ||
1853 | chan_mask = chan_mask | 0x1 << bp; | ||
1854 | } | ||
1855 | cur_bin += 100; | ||
1856 | } | ||
1857 | cur_bin += inc[i]; | ||
1858 | REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); | ||
1859 | REG_WRITE(ah, chan_mask_reg[i], chan_mask); | ||
1860 | } | ||
1861 | |||
1862 | cur_vit_mask = 6100; | ||
1863 | upper = bin + 120; | ||
1864 | lower = bin - 120; | ||
1865 | |||
1866 | for (i = 0; i < 123; i++) { | ||
1867 | if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { | ||
1868 | |||
1869 | /* workaround for gcc bug #37014 */ | ||
1870 | volatile int tmp_v = abs(cur_vit_mask - bin); | ||
1871 | |||
1872 | if (tmp_v < 75) | ||
1873 | mask_amt = 1; | ||
1874 | else | ||
1875 | mask_amt = 0; | ||
1876 | if (cur_vit_mask < 0) | ||
1877 | mask_m[abs(cur_vit_mask / 100)] = mask_amt; | ||
1878 | else | ||
1879 | mask_p[cur_vit_mask / 100] = mask_amt; | ||
1880 | } | ||
1881 | cur_vit_mask -= 100; | ||
1882 | } | ||
1883 | |||
1884 | tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) | ||
1885 | | (mask_m[48] << 26) | (mask_m[49] << 24) | ||
1886 | | (mask_m[50] << 22) | (mask_m[51] << 20) | ||
1887 | | (mask_m[52] << 18) | (mask_m[53] << 16) | ||
1888 | | (mask_m[54] << 14) | (mask_m[55] << 12) | ||
1889 | | (mask_m[56] << 10) | (mask_m[57] << 8) | ||
1890 | | (mask_m[58] << 6) | (mask_m[59] << 4) | ||
1891 | | (mask_m[60] << 2) | (mask_m[61] << 0); | ||
1892 | REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); | ||
1893 | REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); | ||
1894 | |||
1895 | tmp_mask = (mask_m[31] << 28) | ||
1896 | | (mask_m[32] << 26) | (mask_m[33] << 24) | ||
1897 | | (mask_m[34] << 22) | (mask_m[35] << 20) | ||
1898 | | (mask_m[36] << 18) | (mask_m[37] << 16) | ||
1899 | | (mask_m[48] << 14) | (mask_m[39] << 12) | ||
1900 | | (mask_m[40] << 10) | (mask_m[41] << 8) | ||
1901 | | (mask_m[42] << 6) | (mask_m[43] << 4) | ||
1902 | | (mask_m[44] << 2) | (mask_m[45] << 0); | ||
1903 | REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); | ||
1904 | REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); | ||
1905 | |||
1906 | tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) | ||
1907 | | (mask_m[18] << 26) | (mask_m[18] << 24) | ||
1908 | | (mask_m[20] << 22) | (mask_m[20] << 20) | ||
1909 | | (mask_m[22] << 18) | (mask_m[22] << 16) | ||
1910 | | (mask_m[24] << 14) | (mask_m[24] << 12) | ||
1911 | | (mask_m[25] << 10) | (mask_m[26] << 8) | ||
1912 | | (mask_m[27] << 6) | (mask_m[28] << 4) | ||
1913 | | (mask_m[29] << 2) | (mask_m[30] << 0); | ||
1914 | REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); | ||
1915 | REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); | ||
1916 | |||
1917 | tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28) | ||
1918 | | (mask_m[2] << 26) | (mask_m[3] << 24) | ||
1919 | | (mask_m[4] << 22) | (mask_m[5] << 20) | ||
1920 | | (mask_m[6] << 18) | (mask_m[7] << 16) | ||
1921 | | (mask_m[8] << 14) | (mask_m[9] << 12) | ||
1922 | | (mask_m[10] << 10) | (mask_m[11] << 8) | ||
1923 | | (mask_m[12] << 6) | (mask_m[13] << 4) | ||
1924 | | (mask_m[14] << 2) | (mask_m[15] << 0); | ||
1925 | REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); | ||
1926 | REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); | ||
1927 | |||
1928 | tmp_mask = (mask_p[15] << 28) | ||
1929 | | (mask_p[14] << 26) | (mask_p[13] << 24) | ||
1930 | | (mask_p[12] << 22) | (mask_p[11] << 20) | ||
1931 | | (mask_p[10] << 18) | (mask_p[9] << 16) | ||
1932 | | (mask_p[8] << 14) | (mask_p[7] << 12) | ||
1933 | | (mask_p[6] << 10) | (mask_p[5] << 8) | ||
1934 | | (mask_p[4] << 6) | (mask_p[3] << 4) | ||
1935 | | (mask_p[2] << 2) | (mask_p[1] << 0); | ||
1936 | REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); | ||
1937 | REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); | ||
1938 | |||
1939 | tmp_mask = (mask_p[30] << 28) | ||
1940 | | (mask_p[29] << 26) | (mask_p[28] << 24) | ||
1941 | | (mask_p[27] << 22) | (mask_p[26] << 20) | ||
1942 | | (mask_p[25] << 18) | (mask_p[24] << 16) | ||
1943 | | (mask_p[23] << 14) | (mask_p[22] << 12) | ||
1944 | | (mask_p[21] << 10) | (mask_p[20] << 8) | ||
1945 | | (mask_p[19] << 6) | (mask_p[18] << 4) | ||
1946 | | (mask_p[17] << 2) | (mask_p[16] << 0); | ||
1947 | REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); | ||
1948 | REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); | ||
1949 | |||
1950 | tmp_mask = (mask_p[45] << 28) | ||
1951 | | (mask_p[44] << 26) | (mask_p[43] << 24) | ||
1952 | | (mask_p[42] << 22) | (mask_p[41] << 20) | ||
1953 | | (mask_p[40] << 18) | (mask_p[39] << 16) | ||
1954 | | (mask_p[38] << 14) | (mask_p[37] << 12) | ||
1955 | | (mask_p[36] << 10) | (mask_p[35] << 8) | ||
1956 | | (mask_p[34] << 6) | (mask_p[33] << 4) | ||
1957 | | (mask_p[32] << 2) | (mask_p[31] << 0); | ||
1958 | REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); | ||
1959 | REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); | ||
1960 | |||
1961 | tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) | ||
1962 | | (mask_p[59] << 26) | (mask_p[58] << 24) | ||
1963 | | (mask_p[57] << 22) | (mask_p[56] << 20) | ||
1964 | | (mask_p[55] << 18) | (mask_p[54] << 16) | ||
1965 | | (mask_p[53] << 14) | (mask_p[52] << 12) | ||
1966 | | (mask_p[51] << 10) | (mask_p[50] << 8) | ||
1967 | | (mask_p[49] << 6) | (mask_p[48] << 4) | ||
1968 | | (mask_p[47] << 2) | (mask_p[46] << 0); | ||
1969 | REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); | ||
1970 | REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); | ||
1971 | } | ||
1972 | |||
1973 | static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan) | ||
1974 | { | ||
1975 | int bb_spur = AR_NO_SPUR; | ||
1976 | int bin, cur_bin; | ||
1977 | int spur_freq_sd; | ||
1978 | int spur_delta_phase; | ||
1979 | int denominator; | ||
1980 | int upper, lower, cur_vit_mask; | ||
1981 | int tmp, new; | ||
1982 | int i; | ||
1983 | int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, | ||
1984 | AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 | ||
1985 | }; | ||
1986 | int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, | ||
1987 | AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 | ||
1988 | }; | ||
1989 | int inc[4] = { 0, 100, 0, 0 }; | ||
1990 | |||
1991 | int8_t mask_m[123]; | ||
1992 | int8_t mask_p[123]; | ||
1993 | int8_t mask_amt; | ||
1994 | int tmp_mask; | ||
1995 | int cur_bb_spur; | ||
1996 | bool is2GHz = IS_CHAN_2GHZ(chan); | ||
1997 | |||
1998 | memset(&mask_m, 0, sizeof(int8_t) * 123); | ||
1999 | memset(&mask_p, 0, sizeof(int8_t) * 123); | ||
2000 | |||
2001 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | ||
2002 | cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); | ||
2003 | if (AR_NO_SPUR == cur_bb_spur) | ||
2004 | break; | ||
2005 | cur_bb_spur = cur_bb_spur - (chan->channel * 10); | ||
2006 | if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) { | ||
2007 | bb_spur = cur_bb_spur; | ||
2008 | break; | ||
2009 | } | ||
2010 | } | ||
2011 | |||
2012 | if (AR_NO_SPUR == bb_spur) | ||
2013 | return; | ||
2014 | |||
2015 | bin = bb_spur * 32; | ||
2016 | |||
2017 | tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0)); | ||
2018 | new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | | ||
2019 | AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | | ||
2020 | AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | | ||
2021 | AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); | ||
2022 | |||
2023 | REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new); | ||
2024 | |||
2025 | new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | | ||
2026 | AR_PHY_SPUR_REG_ENABLE_MASK_PPM | | ||
2027 | AR_PHY_SPUR_REG_MASK_RATE_SELECT | | ||
2028 | AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | | ||
2029 | SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); | ||
2030 | REG_WRITE(ah, AR_PHY_SPUR_REG, new); | ||
2031 | |||
2032 | spur_delta_phase = ((bb_spur * 524288) / 100) & | ||
2033 | AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
2034 | |||
2035 | denominator = IS_CHAN_2GHZ(chan) ? 440 : 400; | ||
2036 | spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff; | ||
2037 | |||
2038 | new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | | ||
2039 | SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | | ||
2040 | SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); | ||
2041 | REG_WRITE(ah, AR_PHY_TIMING11, new); | ||
2042 | |||
2043 | cur_bin = -6000; | ||
2044 | upper = bin + 100; | ||
2045 | lower = bin - 100; | ||
2046 | |||
2047 | for (i = 0; i < 4; i++) { | ||
2048 | int pilot_mask = 0; | ||
2049 | int chan_mask = 0; | ||
2050 | int bp = 0; | ||
2051 | for (bp = 0; bp < 30; bp++) { | ||
2052 | if ((cur_bin > lower) && (cur_bin < upper)) { | ||
2053 | pilot_mask = pilot_mask | 0x1 << bp; | ||
2054 | chan_mask = chan_mask | 0x1 << bp; | ||
2055 | } | ||
2056 | cur_bin += 100; | ||
2057 | } | ||
2058 | cur_bin += inc[i]; | ||
2059 | REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); | ||
2060 | REG_WRITE(ah, chan_mask_reg[i], chan_mask); | ||
2061 | } | ||
2062 | |||
2063 | cur_vit_mask = 6100; | ||
2064 | upper = bin + 120; | ||
2065 | lower = bin - 120; | ||
2066 | |||
2067 | for (i = 0; i < 123; i++) { | ||
2068 | if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { | ||
2069 | |||
2070 | /* workaround for gcc bug #37014 */ | ||
2071 | volatile int tmp_v = abs(cur_vit_mask - bin); | ||
2072 | |||
2073 | if (tmp_v < 75) | ||
2074 | mask_amt = 1; | ||
2075 | else | ||
2076 | mask_amt = 0; | ||
2077 | if (cur_vit_mask < 0) | ||
2078 | mask_m[abs(cur_vit_mask / 100)] = mask_amt; | ||
2079 | else | ||
2080 | mask_p[cur_vit_mask / 100] = mask_amt; | ||
2081 | } | ||
2082 | cur_vit_mask -= 100; | ||
2083 | } | ||
2084 | |||
2085 | tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) | ||
2086 | | (mask_m[48] << 26) | (mask_m[49] << 24) | ||
2087 | | (mask_m[50] << 22) | (mask_m[51] << 20) | ||
2088 | | (mask_m[52] << 18) | (mask_m[53] << 16) | ||
2089 | | (mask_m[54] << 14) | (mask_m[55] << 12) | ||
2090 | | (mask_m[56] << 10) | (mask_m[57] << 8) | ||
2091 | | (mask_m[58] << 6) | (mask_m[59] << 4) | ||
2092 | | (mask_m[60] << 2) | (mask_m[61] << 0); | ||
2093 | REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); | ||
2094 | REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); | ||
2095 | |||
2096 | tmp_mask = (mask_m[31] << 28) | ||
2097 | | (mask_m[32] << 26) | (mask_m[33] << 24) | ||
2098 | | (mask_m[34] << 22) | (mask_m[35] << 20) | ||
2099 | | (mask_m[36] << 18) | (mask_m[37] << 16) | ||
2100 | | (mask_m[48] << 14) | (mask_m[39] << 12) | ||
2101 | | (mask_m[40] << 10) | (mask_m[41] << 8) | ||
2102 | | (mask_m[42] << 6) | (mask_m[43] << 4) | ||
2103 | | (mask_m[44] << 2) | (mask_m[45] << 0); | ||
2104 | REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); | ||
2105 | REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); | ||
2106 | |||
2107 | tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) | ||
2108 | | (mask_m[18] << 26) | (mask_m[18] << 24) | ||
2109 | | (mask_m[20] << 22) | (mask_m[20] << 20) | ||
2110 | | (mask_m[22] << 18) | (mask_m[22] << 16) | ||
2111 | | (mask_m[24] << 14) | (mask_m[24] << 12) | ||
2112 | | (mask_m[25] << 10) | (mask_m[26] << 8) | ||
2113 | | (mask_m[27] << 6) | (mask_m[28] << 4) | ||
2114 | | (mask_m[29] << 2) | (mask_m[30] << 0); | ||
2115 | REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); | ||
2116 | REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); | ||
2117 | |||
2118 | tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28) | ||
2119 | | (mask_m[2] << 26) | (mask_m[3] << 24) | ||
2120 | | (mask_m[4] << 22) | (mask_m[5] << 20) | ||
2121 | | (mask_m[6] << 18) | (mask_m[7] << 16) | ||
2122 | | (mask_m[8] << 14) | (mask_m[9] << 12) | ||
2123 | | (mask_m[10] << 10) | (mask_m[11] << 8) | ||
2124 | | (mask_m[12] << 6) | (mask_m[13] << 4) | ||
2125 | | (mask_m[14] << 2) | (mask_m[15] << 0); | ||
2126 | REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); | ||
2127 | REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); | ||
2128 | |||
2129 | tmp_mask = (mask_p[15] << 28) | ||
2130 | | (mask_p[14] << 26) | (mask_p[13] << 24) | ||
2131 | | (mask_p[12] << 22) | (mask_p[11] << 20) | ||
2132 | | (mask_p[10] << 18) | (mask_p[9] << 16) | ||
2133 | | (mask_p[8] << 14) | (mask_p[7] << 12) | ||
2134 | | (mask_p[6] << 10) | (mask_p[5] << 8) | ||
2135 | | (mask_p[4] << 6) | (mask_p[3] << 4) | ||
2136 | | (mask_p[2] << 2) | (mask_p[1] << 0); | ||
2137 | REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); | ||
2138 | REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); | ||
2139 | |||
2140 | tmp_mask = (mask_p[30] << 28) | ||
2141 | | (mask_p[29] << 26) | (mask_p[28] << 24) | ||
2142 | | (mask_p[27] << 22) | (mask_p[26] << 20) | ||
2143 | | (mask_p[25] << 18) | (mask_p[24] << 16) | ||
2144 | | (mask_p[23] << 14) | (mask_p[22] << 12) | ||
2145 | | (mask_p[21] << 10) | (mask_p[20] << 8) | ||
2146 | | (mask_p[19] << 6) | (mask_p[18] << 4) | ||
2147 | | (mask_p[17] << 2) | (mask_p[16] << 0); | ||
2148 | REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); | ||
2149 | REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); | ||
2150 | |||
2151 | tmp_mask = (mask_p[45] << 28) | ||
2152 | | (mask_p[44] << 26) | (mask_p[43] << 24) | ||
2153 | | (mask_p[42] << 22) | (mask_p[41] << 20) | ||
2154 | | (mask_p[40] << 18) | (mask_p[39] << 16) | ||
2155 | | (mask_p[38] << 14) | (mask_p[37] << 12) | ||
2156 | | (mask_p[36] << 10) | (mask_p[35] << 8) | ||
2157 | | (mask_p[34] << 6) | (mask_p[33] << 4) | ||
2158 | | (mask_p[32] << 2) | (mask_p[31] << 0); | ||
2159 | REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); | ||
2160 | REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); | ||
2161 | |||
2162 | tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) | ||
2163 | | (mask_p[59] << 26) | (mask_p[58] << 24) | ||
2164 | | (mask_p[57] << 22) | (mask_p[56] << 20) | ||
2165 | | (mask_p[55] << 18) | (mask_p[54] << 16) | ||
2166 | | (mask_p[53] << 14) | (mask_p[52] << 12) | ||
2167 | | (mask_p[51] << 10) | (mask_p[50] << 8) | ||
2168 | | (mask_p[49] << 6) | (mask_p[48] << 4) | ||
2169 | | (mask_p[47] << 2) | (mask_p[46] << 0); | ||
2170 | REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); | ||
2171 | REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); | ||
2172 | } | ||
2173 | |||
2174 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | ||
2175 | bool bChannelChange) | ||
2176 | { | ||
2177 | u32 saveLedState; | ||
2178 | struct ath_softc *sc = ah->ah_sc; | ||
2179 | struct ath9k_channel *curchan = ah->curchan; | ||
2180 | u32 saveDefAntenna; | ||
2181 | u32 macStaId1; | ||
2182 | int i, rx_chainmask, r; | ||
2183 | |||
2184 | ah->extprotspacing = sc->ht_extprotspacing; | ||
2185 | ah->txchainmask = sc->tx_chainmask; | ||
2186 | ah->rxchainmask = sc->rx_chainmask; | ||
2187 | |||
2188 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) | ||
2189 | return -EIO; | ||
2190 | |||
2191 | if (curchan) | ||
2192 | ath9k_hw_getnf(ah, curchan); | ||
2193 | |||
2194 | if (bChannelChange && | ||
2195 | (ah->chip_fullsleep != true) && | ||
2196 | (ah->curchan != NULL) && | ||
2197 | (chan->channel != ah->curchan->channel) && | ||
2198 | ((chan->channelFlags & CHANNEL_ALL) == | ||
2199 | (ah->curchan->channelFlags & CHANNEL_ALL)) && | ||
2200 | (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) && | ||
2201 | !IS_CHAN_A_5MHZ_SPACED(ah->curchan)))) { | ||
2202 | |||
2203 | if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) { | ||
2204 | ath9k_hw_loadnf(ah, ah->curchan); | ||
2205 | ath9k_hw_start_nfcal(ah); | ||
2206 | return 0; | ||
2207 | } | ||
2208 | } | ||
2209 | |||
2210 | saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA); | ||
2211 | if (saveDefAntenna == 0) | ||
2212 | saveDefAntenna = 1; | ||
2213 | |||
2214 | macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; | ||
2215 | |||
2216 | saveLedState = REG_READ(ah, AR_CFG_LED) & | ||
2217 | (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | | ||
2218 | AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW); | ||
2219 | |||
2220 | ath9k_hw_mark_phy_inactive(ah); | ||
2221 | |||
2222 | if (!ath9k_hw_chip_reset(ah, chan)) { | ||
2223 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Chip reset failed\n"); | ||
2224 | return -EINVAL; | ||
2225 | } | ||
2226 | |||
2227 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
2228 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); | ||
2229 | |||
2230 | r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width); | ||
2231 | if (r) | ||
2232 | return r; | ||
2233 | |||
2234 | /* Setup MFP options for CCMP */ | ||
2235 | if (AR_SREV_9280_20_OR_LATER(ah)) { | ||
2236 | /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt | ||
2237 | * frames when constructing CCMP AAD. */ | ||
2238 | REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT, | ||
2239 | 0xc7ff); | ||
2240 | ah->sw_mgmt_crypto = false; | ||
2241 | } else if (AR_SREV_9160_10_OR_LATER(ah)) { | ||
2242 | /* Disable hardware crypto for management frames */ | ||
2243 | REG_CLR_BIT(ah, AR_PCU_MISC_MODE2, | ||
2244 | AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE); | ||
2245 | REG_SET_BIT(ah, AR_PCU_MISC_MODE2, | ||
2246 | AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT); | ||
2247 | ah->sw_mgmt_crypto = true; | ||
2248 | } else | ||
2249 | ah->sw_mgmt_crypto = true; | ||
2250 | |||
2251 | if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) | ||
2252 | ath9k_hw_set_delta_slope(ah, chan); | ||
2253 | |||
2254 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
2255 | ath9k_hw_9280_spur_mitigate(ah, chan); | ||
2256 | else | ||
2257 | ath9k_hw_spur_mitigate(ah, chan); | ||
2258 | |||
2259 | ah->eep_ops->set_board_values(ah, chan); | ||
2260 | |||
2261 | ath9k_hw_decrease_chain_power(ah, chan); | ||
2262 | |||
2263 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ah->macaddr)); | ||
2264 | REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ah->macaddr + 4) | ||
2265 | | macStaId1 | ||
2266 | | AR_STA_ID1_RTS_USE_DEF | ||
2267 | | (ah->config. | ||
2268 | ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) | ||
2269 | | ah->sta_id1_defaults); | ||
2270 | ath9k_hw_set_operating_mode(ah, ah->opmode); | ||
2271 | |||
2272 | REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask)); | ||
2273 | REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4)); | ||
2274 | |||
2275 | REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); | ||
2276 | |||
2277 | REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid)); | ||
2278 | REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) | | ||
2279 | ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S)); | ||
2280 | |||
2281 | REG_WRITE(ah, AR_ISR, ~0); | ||
2282 | |||
2283 | REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); | ||
2284 | |||
2285 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
2286 | if (!(ath9k_hw_ar9280_set_channel(ah, chan))) | ||
2287 | return -EIO; | ||
2288 | } else { | ||
2289 | if (!(ath9k_hw_set_channel(ah, chan))) | ||
2290 | return -EIO; | ||
2291 | } | ||
2292 | |||
2293 | for (i = 0; i < AR_NUM_DCU; i++) | ||
2294 | REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); | ||
2295 | |||
2296 | ah->intr_txqs = 0; | ||
2297 | for (i = 0; i < ah->caps.total_queues; i++) | ||
2298 | ath9k_hw_resettxqueue(ah, i); | ||
2299 | |||
2300 | ath9k_hw_init_interrupt_masks(ah, ah->opmode); | ||
2301 | ath9k_hw_init_qos(ah); | ||
2302 | |||
2303 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
2304 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
2305 | ath9k_enable_rfkill(ah); | ||
2306 | #endif | ||
2307 | ath9k_hw_init_user_settings(ah); | ||
2308 | |||
2309 | REG_WRITE(ah, AR_STA_ID1, | ||
2310 | REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); | ||
2311 | |||
2312 | ath9k_hw_set_dma(ah); | ||
2313 | |||
2314 | REG_WRITE(ah, AR_OBS, 8); | ||
2315 | |||
2316 | if (ah->config.intr_mitigation) { | ||
2317 | REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); | ||
2318 | REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); | ||
2319 | } | ||
2320 | |||
2321 | ath9k_hw_init_bb(ah, chan); | ||
2322 | |||
2323 | if (!ath9k_hw_init_cal(ah, chan)) | ||
2324 | return -EIO;; | ||
2325 | |||
2326 | rx_chainmask = ah->rxchainmask; | ||
2327 | if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) { | ||
2328 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); | ||
2329 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); | ||
2330 | } | ||
2331 | |||
2332 | REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ); | ||
2333 | |||
2334 | if (AR_SREV_9100(ah)) { | ||
2335 | u32 mask; | ||
2336 | mask = REG_READ(ah, AR_CFG); | ||
2337 | if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) { | ||
2338 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | ||
2339 | "CFG Byte Swap Set 0x%x\n", mask); | ||
2340 | } else { | ||
2341 | mask = | ||
2342 | INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB; | ||
2343 | REG_WRITE(ah, AR_CFG, mask); | ||
2344 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | ||
2345 | "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG)); | ||
2346 | } | ||
2347 | } else { | ||
2348 | #ifdef __BIG_ENDIAN | ||
2349 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); | ||
2350 | #endif | ||
2351 | } | ||
2352 | |||
2353 | return 0; | ||
2354 | } | ||
2355 | |||
2356 | /************************/ | ||
2357 | /* Key Cache Management */ | ||
2358 | /************************/ | ||
2359 | |||
2360 | bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry) | ||
2361 | { | ||
2362 | u32 keyType; | ||
2363 | |||
2364 | if (entry >= ah->caps.keycache_size) { | ||
2365 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
2366 | "keychache entry %u out of range\n", entry); | ||
2367 | return false; | ||
2368 | } | ||
2369 | |||
2370 | keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry)); | ||
2371 | |||
2372 | REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); | ||
2373 | REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); | ||
2374 | REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); | ||
2375 | REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); | ||
2376 | REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); | ||
2377 | REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); | ||
2378 | REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); | ||
2379 | REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); | ||
2380 | |||
2381 | if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) { | ||
2382 | u16 micentry = entry + 64; | ||
2383 | |||
2384 | REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0); | ||
2385 | REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); | ||
2386 | REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); | ||
2387 | REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); | ||
2388 | |||
2389 | } | ||
2390 | |||
2391 | if (ah->curchan == NULL) | ||
2392 | return true; | ||
2393 | |||
2394 | return true; | ||
2395 | } | ||
2396 | |||
2397 | bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) | ||
2398 | { | ||
2399 | u32 macHi, macLo; | ||
2400 | |||
2401 | if (entry >= ah->caps.keycache_size) { | ||
2402 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
2403 | "keychache entry %u out of range\n", entry); | ||
2404 | return false; | ||
2405 | } | ||
2406 | |||
2407 | if (mac != NULL) { | ||
2408 | macHi = (mac[5] << 8) | mac[4]; | ||
2409 | macLo = (mac[3] << 24) | | ||
2410 | (mac[2] << 16) | | ||
2411 | (mac[1] << 8) | | ||
2412 | mac[0]; | ||
2413 | macLo >>= 1; | ||
2414 | macLo |= (macHi & 1) << 31; | ||
2415 | macHi >>= 1; | ||
2416 | } else { | ||
2417 | macLo = macHi = 0; | ||
2418 | } | ||
2419 | REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); | ||
2420 | REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID); | ||
2421 | |||
2422 | return true; | ||
2423 | } | ||
2424 | |||
2425 | bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, | ||
2426 | const struct ath9k_keyval *k, | ||
2427 | const u8 *mac) | ||
2428 | { | ||
2429 | const struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
2430 | u32 key0, key1, key2, key3, key4; | ||
2431 | u32 keyType; | ||
2432 | |||
2433 | if (entry >= pCap->keycache_size) { | ||
2434 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
2435 | "keycache entry %u out of range\n", entry); | ||
2436 | return false; | ||
2437 | } | ||
2438 | |||
2439 | switch (k->kv_type) { | ||
2440 | case ATH9K_CIPHER_AES_OCB: | ||
2441 | keyType = AR_KEYTABLE_TYPE_AES; | ||
2442 | break; | ||
2443 | case ATH9K_CIPHER_AES_CCM: | ||
2444 | if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) { | ||
2445 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | ||
2446 | "AES-CCM not supported by mac rev 0x%x\n", | ||
2447 | ah->hw_version.macRev); | ||
2448 | return false; | ||
2449 | } | ||
2450 | keyType = AR_KEYTABLE_TYPE_CCM; | ||
2451 | break; | ||
2452 | case ATH9K_CIPHER_TKIP: | ||
2453 | keyType = AR_KEYTABLE_TYPE_TKIP; | ||
2454 | if (ATH9K_IS_MIC_ENABLED(ah) | ||
2455 | && entry + 64 >= pCap->keycache_size) { | ||
2456 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | ||
2457 | "entry %u inappropriate for TKIP\n", entry); | ||
2458 | return false; | ||
2459 | } | ||
2460 | break; | ||
2461 | case ATH9K_CIPHER_WEP: | ||
2462 | if (k->kv_len < LEN_WEP40) { | ||
2463 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | ||
2464 | "WEP key length %u too small\n", k->kv_len); | ||
2465 | return false; | ||
2466 | } | ||
2467 | if (k->kv_len <= LEN_WEP40) | ||
2468 | keyType = AR_KEYTABLE_TYPE_40; | ||
2469 | else if (k->kv_len <= LEN_WEP104) | ||
2470 | keyType = AR_KEYTABLE_TYPE_104; | ||
2471 | else | ||
2472 | keyType = AR_KEYTABLE_TYPE_128; | ||
2473 | break; | ||
2474 | case ATH9K_CIPHER_CLR: | ||
2475 | keyType = AR_KEYTABLE_TYPE_CLR; | ||
2476 | break; | ||
2477 | default: | ||
2478 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
2479 | "cipher %u not supported\n", k->kv_type); | ||
2480 | return false; | ||
2481 | } | ||
2482 | |||
2483 | key0 = get_unaligned_le32(k->kv_val + 0); | ||
2484 | key1 = get_unaligned_le16(k->kv_val + 4); | ||
2485 | key2 = get_unaligned_le32(k->kv_val + 6); | ||
2486 | key3 = get_unaligned_le16(k->kv_val + 10); | ||
2487 | key4 = get_unaligned_le32(k->kv_val + 12); | ||
2488 | if (k->kv_len <= LEN_WEP104) | ||
2489 | key4 &= 0xff; | ||
2490 | |||
2491 | /* | ||
2492 | * Note: Key cache registers access special memory area that requires | ||
2493 | * two 32-bit writes to actually update the values in the internal | ||
2494 | * memory. Consequently, the exact order and pairs used here must be | ||
2495 | * maintained. | ||
2496 | */ | ||
2497 | |||
2498 | if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) { | ||
2499 | u16 micentry = entry + 64; | ||
2500 | |||
2501 | /* | ||
2502 | * Write inverted key[47:0] first to avoid Michael MIC errors | ||
2503 | * on frames that could be sent or received at the same time. | ||
2504 | * The correct key will be written in the end once everything | ||
2505 | * else is ready. | ||
2506 | */ | ||
2507 | REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0); | ||
2508 | REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1); | ||
2509 | |||
2510 | /* Write key[95:48] */ | ||
2511 | REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); | ||
2512 | REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); | ||
2513 | |||
2514 | /* Write key[127:96] and key type */ | ||
2515 | REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); | ||
2516 | REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); | ||
2517 | |||
2518 | /* Write MAC address for the entry */ | ||
2519 | (void) ath9k_hw_keysetmac(ah, entry, mac); | ||
2520 | |||
2521 | if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) { | ||
2522 | /* | ||
2523 | * TKIP uses two key cache entries: | ||
2524 | * Michael MIC TX/RX keys in the same key cache entry | ||
2525 | * (idx = main index + 64): | ||
2526 | * key0 [31:0] = RX key [31:0] | ||
2527 | * key1 [15:0] = TX key [31:16] | ||
2528 | * key1 [31:16] = reserved | ||
2529 | * key2 [31:0] = RX key [63:32] | ||
2530 | * key3 [15:0] = TX key [15:0] | ||
2531 | * key3 [31:16] = reserved | ||
2532 | * key4 [31:0] = TX key [63:32] | ||
2533 | */ | ||
2534 | u32 mic0, mic1, mic2, mic3, mic4; | ||
2535 | |||
2536 | mic0 = get_unaligned_le32(k->kv_mic + 0); | ||
2537 | mic2 = get_unaligned_le32(k->kv_mic + 4); | ||
2538 | mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff; | ||
2539 | mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff; | ||
2540 | mic4 = get_unaligned_le32(k->kv_txmic + 4); | ||
2541 | |||
2542 | /* Write RX[31:0] and TX[31:16] */ | ||
2543 | REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); | ||
2544 | REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1); | ||
2545 | |||
2546 | /* Write RX[63:32] and TX[15:0] */ | ||
2547 | REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); | ||
2548 | REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3); | ||
2549 | |||
2550 | /* Write TX[63:32] and keyType(reserved) */ | ||
2551 | REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4); | ||
2552 | REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), | ||
2553 | AR_KEYTABLE_TYPE_CLR); | ||
2554 | |||
2555 | } else { | ||
2556 | /* | ||
2557 | * TKIP uses four key cache entries (two for group | ||
2558 | * keys): | ||
2559 | * Michael MIC TX/RX keys are in different key cache | ||
2560 | * entries (idx = main index + 64 for TX and | ||
2561 | * main index + 32 + 96 for RX): | ||
2562 | * key0 [31:0] = TX/RX MIC key [31:0] | ||
2563 | * key1 [31:0] = reserved | ||
2564 | * key2 [31:0] = TX/RX MIC key [63:32] | ||
2565 | * key3 [31:0] = reserved | ||
2566 | * key4 [31:0] = reserved | ||
2567 | * | ||
2568 | * Upper layer code will call this function separately | ||
2569 | * for TX and RX keys when these registers offsets are | ||
2570 | * used. | ||
2571 | */ | ||
2572 | u32 mic0, mic2; | ||
2573 | |||
2574 | mic0 = get_unaligned_le32(k->kv_mic + 0); | ||
2575 | mic2 = get_unaligned_le32(k->kv_mic + 4); | ||
2576 | |||
2577 | /* Write MIC key[31:0] */ | ||
2578 | REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); | ||
2579 | REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); | ||
2580 | |||
2581 | /* Write MIC key[63:32] */ | ||
2582 | REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); | ||
2583 | REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); | ||
2584 | |||
2585 | /* Write TX[63:32] and keyType(reserved) */ | ||
2586 | REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); | ||
2587 | REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), | ||
2588 | AR_KEYTABLE_TYPE_CLR); | ||
2589 | } | ||
2590 | |||
2591 | /* MAC address registers are reserved for the MIC entry */ | ||
2592 | REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0); | ||
2593 | REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0); | ||
2594 | |||
2595 | /* | ||
2596 | * Write the correct (un-inverted) key[47:0] last to enable | ||
2597 | * TKIP now that all other registers are set with correct | ||
2598 | * values. | ||
2599 | */ | ||
2600 | REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); | ||
2601 | REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); | ||
2602 | } else { | ||
2603 | /* Write key[47:0] */ | ||
2604 | REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); | ||
2605 | REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); | ||
2606 | |||
2607 | /* Write key[95:48] */ | ||
2608 | REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); | ||
2609 | REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); | ||
2610 | |||
2611 | /* Write key[127:96] and key type */ | ||
2612 | REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); | ||
2613 | REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); | ||
2614 | |||
2615 | /* Write MAC address for the entry */ | ||
2616 | (void) ath9k_hw_keysetmac(ah, entry, mac); | ||
2617 | } | ||
2618 | |||
2619 | return true; | ||
2620 | } | ||
2621 | |||
2622 | bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry) | ||
2623 | { | ||
2624 | if (entry < ah->caps.keycache_size) { | ||
2625 | u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry)); | ||
2626 | if (val & AR_KEYTABLE_VALID) | ||
2627 | return true; | ||
2628 | } | ||
2629 | return false; | ||
2630 | } | ||
2631 | |||
2632 | /******************************/ | ||
2633 | /* Power Management (Chipset) */ | ||
2634 | /******************************/ | ||
2635 | |||
2636 | static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) | ||
2637 | { | ||
2638 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); | ||
2639 | if (setChip) { | ||
2640 | REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, | ||
2641 | AR_RTC_FORCE_WAKE_EN); | ||
2642 | if (!AR_SREV_9100(ah)) | ||
2643 | REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); | ||
2644 | |||
2645 | REG_CLR_BIT(ah, (AR_RTC_RESET), | ||
2646 | AR_RTC_RESET_EN); | ||
2647 | } | ||
2648 | } | ||
2649 | |||
2650 | static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) | ||
2651 | { | ||
2652 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); | ||
2653 | if (setChip) { | ||
2654 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
2655 | |||
2656 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | ||
2657 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, | ||
2658 | AR_RTC_FORCE_WAKE_ON_INT); | ||
2659 | } else { | ||
2660 | REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, | ||
2661 | AR_RTC_FORCE_WAKE_EN); | ||
2662 | } | ||
2663 | } | ||
2664 | } | ||
2665 | |||
2666 | static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) | ||
2667 | { | ||
2668 | u32 val; | ||
2669 | int i; | ||
2670 | |||
2671 | if (setChip) { | ||
2672 | if ((REG_READ(ah, AR_RTC_STATUS) & | ||
2673 | AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { | ||
2674 | if (ath9k_hw_set_reset_reg(ah, | ||
2675 | ATH9K_RESET_POWER_ON) != true) { | ||
2676 | return false; | ||
2677 | } | ||
2678 | } | ||
2679 | if (AR_SREV_9100(ah)) | ||
2680 | REG_SET_BIT(ah, AR_RTC_RESET, | ||
2681 | AR_RTC_RESET_EN); | ||
2682 | |||
2683 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, | ||
2684 | AR_RTC_FORCE_WAKE_EN); | ||
2685 | udelay(50); | ||
2686 | |||
2687 | for (i = POWER_UP_TIME / 50; i > 0; i--) { | ||
2688 | val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; | ||
2689 | if (val == AR_RTC_STATUS_ON) | ||
2690 | break; | ||
2691 | udelay(50); | ||
2692 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, | ||
2693 | AR_RTC_FORCE_WAKE_EN); | ||
2694 | } | ||
2695 | if (i == 0) { | ||
2696 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
2697 | "Failed to wakeup in %uus\n", POWER_UP_TIME / 20); | ||
2698 | return false; | ||
2699 | } | ||
2700 | } | ||
2701 | |||
2702 | REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); | ||
2703 | |||
2704 | return true; | ||
2705 | } | ||
2706 | |||
2707 | bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) | ||
2708 | { | ||
2709 | int status = true, setChip = true; | ||
2710 | static const char *modes[] = { | ||
2711 | "AWAKE", | ||
2712 | "FULL-SLEEP", | ||
2713 | "NETWORK SLEEP", | ||
2714 | "UNDEFINED" | ||
2715 | }; | ||
2716 | |||
2717 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s -> %s\n", | ||
2718 | modes[ah->power_mode], modes[mode]); | ||
2719 | |||
2720 | switch (mode) { | ||
2721 | case ATH9K_PM_AWAKE: | ||
2722 | status = ath9k_hw_set_power_awake(ah, setChip); | ||
2723 | break; | ||
2724 | case ATH9K_PM_FULL_SLEEP: | ||
2725 | ath9k_set_power_sleep(ah, setChip); | ||
2726 | ah->chip_fullsleep = true; | ||
2727 | break; | ||
2728 | case ATH9K_PM_NETWORK_SLEEP: | ||
2729 | ath9k_set_power_network_sleep(ah, setChip); | ||
2730 | break; | ||
2731 | default: | ||
2732 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
2733 | "Unknown power mode %u\n", mode); | ||
2734 | return false; | ||
2735 | } | ||
2736 | ah->power_mode = mode; | ||
2737 | |||
2738 | return status; | ||
2739 | } | ||
2740 | |||
2741 | /* | ||
2742 | * Helper for ASPM support. | ||
2743 | * | ||
2744 | * Disable PLL when in L0s as well as receiver clock when in L1. | ||
2745 | * This power saving option must be enabled through the SerDes. | ||
2746 | * | ||
2747 | * Programming the SerDes must go through the same 288 bit serial shift | ||
2748 | * register as the other analog registers. Hence the 9 writes. | ||
2749 | */ | ||
2750 | void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore) | ||
2751 | { | ||
2752 | u8 i; | ||
2753 | |||
2754 | if (ah->is_pciexpress != true) | ||
2755 | return; | ||
2756 | |||
2757 | /* Do not touch SerDes registers */ | ||
2758 | if (ah->config.pcie_powersave_enable == 2) | ||
2759 | return; | ||
2760 | |||
2761 | /* Nothing to do on restore for 11N */ | ||
2762 | if (restore) | ||
2763 | return; | ||
2764 | |||
2765 | if (AR_SREV_9280_20_OR_LATER(ah)) { | ||
2766 | /* | ||
2767 | * AR9280 2.0 or later chips use SerDes values from the | ||
2768 | * initvals.h initialized depending on chipset during | ||
2769 | * ath9k_hw_do_attach() | ||
2770 | */ | ||
2771 | for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) { | ||
2772 | REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0), | ||
2773 | INI_RA(&ah->iniPcieSerdes, i, 1)); | ||
2774 | } | ||
2775 | } else if (AR_SREV_9280(ah) && | ||
2776 | (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) { | ||
2777 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00); | ||
2778 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); | ||
2779 | |||
2780 | /* RX shut off when elecidle is asserted */ | ||
2781 | REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019); | ||
2782 | REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820); | ||
2783 | REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560); | ||
2784 | |||
2785 | /* Shut off CLKREQ active in L1 */ | ||
2786 | if (ah->config.pcie_clock_req) | ||
2787 | REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc); | ||
2788 | else | ||
2789 | REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd); | ||
2790 | |||
2791 | REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); | ||
2792 | REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); | ||
2793 | REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007); | ||
2794 | |||
2795 | /* Load the new settings */ | ||
2796 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); | ||
2797 | |||
2798 | } else { | ||
2799 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); | ||
2800 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); | ||
2801 | |||
2802 | /* RX shut off when elecidle is asserted */ | ||
2803 | REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039); | ||
2804 | REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824); | ||
2805 | REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579); | ||
2806 | |||
2807 | /* | ||
2808 | * Ignore ah->ah_config.pcie_clock_req setting for | ||
2809 | * pre-AR9280 11n | ||
2810 | */ | ||
2811 | REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff); | ||
2812 | |||
2813 | REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); | ||
2814 | REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); | ||
2815 | REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007); | ||
2816 | |||
2817 | /* Load the new settings */ | ||
2818 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); | ||
2819 | } | ||
2820 | |||
2821 | udelay(1000); | ||
2822 | |||
2823 | /* set bit 19 to allow forcing of pcie core into L1 state */ | ||
2824 | REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); | ||
2825 | |||
2826 | /* Several PCIe massages to ensure proper behaviour */ | ||
2827 | if (ah->config.pcie_waen) { | ||
2828 | REG_WRITE(ah, AR_WA, ah->config.pcie_waen); | ||
2829 | } else { | ||
2830 | if (AR_SREV_9285(ah)) | ||
2831 | REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT); | ||
2832 | /* | ||
2833 | * On AR9280 chips bit 22 of 0x4004 needs to be set to | ||
2834 | * otherwise card may disappear. | ||
2835 | */ | ||
2836 | else if (AR_SREV_9280(ah)) | ||
2837 | REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT); | ||
2838 | else | ||
2839 | REG_WRITE(ah, AR_WA, AR_WA_DEFAULT); | ||
2840 | } | ||
2841 | } | ||
2842 | |||
2843 | /**********************/ | ||
2844 | /* Interrupt Handling */ | ||
2845 | /**********************/ | ||
2846 | |||
2847 | bool ath9k_hw_intrpend(struct ath_hw *ah) | ||
2848 | { | ||
2849 | u32 host_isr; | ||
2850 | |||
2851 | if (AR_SREV_9100(ah)) | ||
2852 | return true; | ||
2853 | |||
2854 | host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE); | ||
2855 | if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS)) | ||
2856 | return true; | ||
2857 | |||
2858 | host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE); | ||
2859 | if ((host_isr & AR_INTR_SYNC_DEFAULT) | ||
2860 | && (host_isr != AR_INTR_SPURIOUS)) | ||
2861 | return true; | ||
2862 | |||
2863 | return false; | ||
2864 | } | ||
2865 | |||
2866 | bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) | ||
2867 | { | ||
2868 | u32 isr = 0; | ||
2869 | u32 mask2 = 0; | ||
2870 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
2871 | u32 sync_cause = 0; | ||
2872 | bool fatal_int = false; | ||
2873 | |||
2874 | if (!AR_SREV_9100(ah)) { | ||
2875 | if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) { | ||
2876 | if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) | ||
2877 | == AR_RTC_STATUS_ON) { | ||
2878 | isr = REG_READ(ah, AR_ISR); | ||
2879 | } | ||
2880 | } | ||
2881 | |||
2882 | sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) & | ||
2883 | AR_INTR_SYNC_DEFAULT; | ||
2884 | |||
2885 | *masked = 0; | ||
2886 | |||
2887 | if (!isr && !sync_cause) | ||
2888 | return false; | ||
2889 | } else { | ||
2890 | *masked = 0; | ||
2891 | isr = REG_READ(ah, AR_ISR); | ||
2892 | } | ||
2893 | |||
2894 | if (isr) { | ||
2895 | if (isr & AR_ISR_BCNMISC) { | ||
2896 | u32 isr2; | ||
2897 | isr2 = REG_READ(ah, AR_ISR_S2); | ||
2898 | if (isr2 & AR_ISR_S2_TIM) | ||
2899 | mask2 |= ATH9K_INT_TIM; | ||
2900 | if (isr2 & AR_ISR_S2_DTIM) | ||
2901 | mask2 |= ATH9K_INT_DTIM; | ||
2902 | if (isr2 & AR_ISR_S2_DTIMSYNC) | ||
2903 | mask2 |= ATH9K_INT_DTIMSYNC; | ||
2904 | if (isr2 & (AR_ISR_S2_CABEND)) | ||
2905 | mask2 |= ATH9K_INT_CABEND; | ||
2906 | if (isr2 & AR_ISR_S2_GTT) | ||
2907 | mask2 |= ATH9K_INT_GTT; | ||
2908 | if (isr2 & AR_ISR_S2_CST) | ||
2909 | mask2 |= ATH9K_INT_CST; | ||
2910 | if (isr2 & AR_ISR_S2_TSFOOR) | ||
2911 | mask2 |= ATH9K_INT_TSFOOR; | ||
2912 | } | ||
2913 | |||
2914 | isr = REG_READ(ah, AR_ISR_RAC); | ||
2915 | if (isr == 0xffffffff) { | ||
2916 | *masked = 0; | ||
2917 | return false; | ||
2918 | } | ||
2919 | |||
2920 | *masked = isr & ATH9K_INT_COMMON; | ||
2921 | |||
2922 | if (ah->config.intr_mitigation) { | ||
2923 | if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) | ||
2924 | *masked |= ATH9K_INT_RX; | ||
2925 | } | ||
2926 | |||
2927 | if (isr & (AR_ISR_RXOK | AR_ISR_RXERR)) | ||
2928 | *masked |= ATH9K_INT_RX; | ||
2929 | if (isr & | ||
2930 | (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR | | ||
2931 | AR_ISR_TXEOL)) { | ||
2932 | u32 s0_s, s1_s; | ||
2933 | |||
2934 | *masked |= ATH9K_INT_TX; | ||
2935 | |||
2936 | s0_s = REG_READ(ah, AR_ISR_S0_S); | ||
2937 | ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK); | ||
2938 | ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC); | ||
2939 | |||
2940 | s1_s = REG_READ(ah, AR_ISR_S1_S); | ||
2941 | ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR); | ||
2942 | ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL); | ||
2943 | } | ||
2944 | |||
2945 | if (isr & AR_ISR_RXORN) { | ||
2946 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, | ||
2947 | "receive FIFO overrun interrupt\n"); | ||
2948 | } | ||
2949 | |||
2950 | if (!AR_SREV_9100(ah)) { | ||
2951 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | ||
2952 | u32 isr5 = REG_READ(ah, AR_ISR_S5_S); | ||
2953 | if (isr5 & AR_ISR_S5_TIM_TIMER) | ||
2954 | *masked |= ATH9K_INT_TIM_TIMER; | ||
2955 | } | ||
2956 | } | ||
2957 | |||
2958 | *masked |= mask2; | ||
2959 | } | ||
2960 | |||
2961 | if (AR_SREV_9100(ah)) | ||
2962 | return true; | ||
2963 | |||
2964 | if (sync_cause) { | ||
2965 | fatal_int = | ||
2966 | (sync_cause & | ||
2967 | (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) | ||
2968 | ? true : false; | ||
2969 | |||
2970 | if (fatal_int) { | ||
2971 | if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) { | ||
2972 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | ||
2973 | "received PCI FATAL interrupt\n"); | ||
2974 | } | ||
2975 | if (sync_cause & AR_INTR_SYNC_HOST1_PERR) { | ||
2976 | DPRINTF(ah->ah_sc, ATH_DBG_ANY, | ||
2977 | "received PCI PERR interrupt\n"); | ||
2978 | } | ||
2979 | } | ||
2980 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { | ||
2981 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, | ||
2982 | "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n"); | ||
2983 | REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); | ||
2984 | REG_WRITE(ah, AR_RC, 0); | ||
2985 | *masked |= ATH9K_INT_FATAL; | ||
2986 | } | ||
2987 | if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) { | ||
2988 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, | ||
2989 | "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); | ||
2990 | } | ||
2991 | |||
2992 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); | ||
2993 | (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR); | ||
2994 | } | ||
2995 | |||
2996 | return true; | ||
2997 | } | ||
2998 | |||
2999 | enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah) | ||
3000 | { | ||
3001 | return ah->mask_reg; | ||
3002 | } | ||
3003 | |||
3004 | enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | ||
3005 | { | ||
3006 | u32 omask = ah->mask_reg; | ||
3007 | u32 mask, mask2; | ||
3008 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
3009 | |||
3010 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); | ||
3011 | |||
3012 | if (omask & ATH9K_INT_GLOBAL) { | ||
3013 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "disable IER\n"); | ||
3014 | REG_WRITE(ah, AR_IER, AR_IER_DISABLE); | ||
3015 | (void) REG_READ(ah, AR_IER); | ||
3016 | if (!AR_SREV_9100(ah)) { | ||
3017 | REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0); | ||
3018 | (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE); | ||
3019 | |||
3020 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); | ||
3021 | (void) REG_READ(ah, AR_INTR_SYNC_ENABLE); | ||
3022 | } | ||
3023 | } | ||
3024 | |||
3025 | mask = ints & ATH9K_INT_COMMON; | ||
3026 | mask2 = 0; | ||
3027 | |||
3028 | if (ints & ATH9K_INT_TX) { | ||
3029 | if (ah->txok_interrupt_mask) | ||
3030 | mask |= AR_IMR_TXOK; | ||
3031 | if (ah->txdesc_interrupt_mask) | ||
3032 | mask |= AR_IMR_TXDESC; | ||
3033 | if (ah->txerr_interrupt_mask) | ||
3034 | mask |= AR_IMR_TXERR; | ||
3035 | if (ah->txeol_interrupt_mask) | ||
3036 | mask |= AR_IMR_TXEOL; | ||
3037 | } | ||
3038 | if (ints & ATH9K_INT_RX) { | ||
3039 | mask |= AR_IMR_RXERR; | ||
3040 | if (ah->config.intr_mitigation) | ||
3041 | mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; | ||
3042 | else | ||
3043 | mask |= AR_IMR_RXOK | AR_IMR_RXDESC; | ||
3044 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) | ||
3045 | mask |= AR_IMR_GENTMR; | ||
3046 | } | ||
3047 | |||
3048 | if (ints & (ATH9K_INT_BMISC)) { | ||
3049 | mask |= AR_IMR_BCNMISC; | ||
3050 | if (ints & ATH9K_INT_TIM) | ||
3051 | mask2 |= AR_IMR_S2_TIM; | ||
3052 | if (ints & ATH9K_INT_DTIM) | ||
3053 | mask2 |= AR_IMR_S2_DTIM; | ||
3054 | if (ints & ATH9K_INT_DTIMSYNC) | ||
3055 | mask2 |= AR_IMR_S2_DTIMSYNC; | ||
3056 | if (ints & ATH9K_INT_CABEND) | ||
3057 | mask2 |= AR_IMR_S2_CABEND; | ||
3058 | if (ints & ATH9K_INT_TSFOOR) | ||
3059 | mask2 |= AR_IMR_S2_TSFOOR; | ||
3060 | } | ||
3061 | |||
3062 | if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) { | ||
3063 | mask |= AR_IMR_BCNMISC; | ||
3064 | if (ints & ATH9K_INT_GTT) | ||
3065 | mask2 |= AR_IMR_S2_GTT; | ||
3066 | if (ints & ATH9K_INT_CST) | ||
3067 | mask2 |= AR_IMR_S2_CST; | ||
3068 | } | ||
3069 | |||
3070 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); | ||
3071 | REG_WRITE(ah, AR_IMR, mask); | ||
3072 | mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM | | ||
3073 | AR_IMR_S2_DTIM | | ||
3074 | AR_IMR_S2_DTIMSYNC | | ||
3075 | AR_IMR_S2_CABEND | | ||
3076 | AR_IMR_S2_CABTO | | ||
3077 | AR_IMR_S2_TSFOOR | | ||
3078 | AR_IMR_S2_GTT | AR_IMR_S2_CST); | ||
3079 | REG_WRITE(ah, AR_IMR_S2, mask | mask2); | ||
3080 | ah->mask_reg = ints; | ||
3081 | |||
3082 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | ||
3083 | if (ints & ATH9K_INT_TIM_TIMER) | ||
3084 | REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); | ||
3085 | else | ||
3086 | REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); | ||
3087 | } | ||
3088 | |||
3089 | if (ints & ATH9K_INT_GLOBAL) { | ||
3090 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "enable IER\n"); | ||
3091 | REG_WRITE(ah, AR_IER, AR_IER_ENABLE); | ||
3092 | if (!AR_SREV_9100(ah)) { | ||
3093 | REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, | ||
3094 | AR_INTR_MAC_IRQ); | ||
3095 | REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ); | ||
3096 | |||
3097 | |||
3098 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, | ||
3099 | AR_INTR_SYNC_DEFAULT); | ||
3100 | REG_WRITE(ah, AR_INTR_SYNC_MASK, | ||
3101 | AR_INTR_SYNC_DEFAULT); | ||
3102 | } | ||
3103 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", | ||
3104 | REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); | ||
3105 | } | ||
3106 | |||
3107 | return omask; | ||
3108 | } | ||
3109 | |||
3110 | /*******************/ | ||
3111 | /* Beacon Handling */ | ||
3112 | /*******************/ | ||
3113 | |||
3114 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) | ||
3115 | { | ||
3116 | int flags = 0; | ||
3117 | |||
3118 | ah->beacon_interval = beacon_period; | ||
3119 | |||
3120 | switch (ah->opmode) { | ||
3121 | case NL80211_IFTYPE_STATION: | ||
3122 | case NL80211_IFTYPE_MONITOR: | ||
3123 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); | ||
3124 | REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff); | ||
3125 | REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff); | ||
3126 | flags |= AR_TBTT_TIMER_EN; | ||
3127 | break; | ||
3128 | case NL80211_IFTYPE_ADHOC: | ||
3129 | case NL80211_IFTYPE_MESH_POINT: | ||
3130 | REG_SET_BIT(ah, AR_TXCFG, | ||
3131 | AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); | ||
3132 | REG_WRITE(ah, AR_NEXT_NDP_TIMER, | ||
3133 | TU_TO_USEC(next_beacon + | ||
3134 | (ah->atim_window ? ah-> | ||
3135 | atim_window : 1))); | ||
3136 | flags |= AR_NDP_TIMER_EN; | ||
3137 | case NL80211_IFTYPE_AP: | ||
3138 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); | ||
3139 | REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, | ||
3140 | TU_TO_USEC(next_beacon - | ||
3141 | ah->config. | ||
3142 | dma_beacon_response_time)); | ||
3143 | REG_WRITE(ah, AR_NEXT_SWBA, | ||
3144 | TU_TO_USEC(next_beacon - | ||
3145 | ah->config. | ||
3146 | sw_beacon_response_time)); | ||
3147 | flags |= | ||
3148 | AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; | ||
3149 | break; | ||
3150 | default: | ||
3151 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, | ||
3152 | "%s: unsupported opmode: %d\n", | ||
3153 | __func__, ah->opmode); | ||
3154 | return; | ||
3155 | break; | ||
3156 | } | ||
3157 | |||
3158 | REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period)); | ||
3159 | REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period)); | ||
3160 | REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period)); | ||
3161 | REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period)); | ||
3162 | |||
3163 | beacon_period &= ~ATH9K_BEACON_ENA; | ||
3164 | if (beacon_period & ATH9K_BEACON_RESET_TSF) { | ||
3165 | beacon_period &= ~ATH9K_BEACON_RESET_TSF; | ||
3166 | ath9k_hw_reset_tsf(ah); | ||
3167 | } | ||
3168 | |||
3169 | REG_SET_BIT(ah, AR_TIMER_MODE, flags); | ||
3170 | } | ||
3171 | |||
3172 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | ||
3173 | const struct ath9k_beacon_state *bs) | ||
3174 | { | ||
3175 | u32 nextTbtt, beaconintval, dtimperiod, beacontimeout; | ||
3176 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
3177 | |||
3178 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt)); | ||
3179 | |||
3180 | REG_WRITE(ah, AR_BEACON_PERIOD, | ||
3181 | TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD)); | ||
3182 | REG_WRITE(ah, AR_DMA_BEACON_PERIOD, | ||
3183 | TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD)); | ||
3184 | |||
3185 | REG_RMW_FIELD(ah, AR_RSSI_THR, | ||
3186 | AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold); | ||
3187 | |||
3188 | beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD; | ||
3189 | |||
3190 | if (bs->bs_sleepduration > beaconintval) | ||
3191 | beaconintval = bs->bs_sleepduration; | ||
3192 | |||
3193 | dtimperiod = bs->bs_dtimperiod; | ||
3194 | if (bs->bs_sleepduration > dtimperiod) | ||
3195 | dtimperiod = bs->bs_sleepduration; | ||
3196 | |||
3197 | if (beaconintval == dtimperiod) | ||
3198 | nextTbtt = bs->bs_nextdtim; | ||
3199 | else | ||
3200 | nextTbtt = bs->bs_nexttbtt; | ||
3201 | |||
3202 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim); | ||
3203 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt); | ||
3204 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "beacon period %d\n", beaconintval); | ||
3205 | DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod); | ||
3206 | |||
3207 | REG_WRITE(ah, AR_NEXT_DTIM, | ||
3208 | TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP)); | ||
3209 | REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP)); | ||
3210 | |||
3211 | REG_WRITE(ah, AR_SLEEP1, | ||
3212 | SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT) | ||
3213 | | AR_SLEEP1_ASSUME_DTIM); | ||
3214 | |||
3215 | if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP) | ||
3216 | beacontimeout = (BEACON_TIMEOUT_VAL << 3); | ||
3217 | else | ||
3218 | beacontimeout = MIN_BEACON_TIMEOUT_VAL; | ||
3219 | |||
3220 | REG_WRITE(ah, AR_SLEEP2, | ||
3221 | SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT)); | ||
3222 | |||
3223 | REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval)); | ||
3224 | REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod)); | ||
3225 | |||
3226 | REG_SET_BIT(ah, AR_TIMER_MODE, | ||
3227 | AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN | | ||
3228 | AR_DTIM_TIMER_EN); | ||
3229 | |||
3230 | /* TSF Out of Range Threshold */ | ||
3231 | REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold); | ||
3232 | } | ||
3233 | |||
3234 | /*******************/ | ||
3235 | /* HW Capabilities */ | ||
3236 | /*******************/ | ||
3237 | |||
3238 | void ath9k_hw_fill_cap_info(struct ath_hw *ah) | ||
3239 | { | ||
3240 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
3241 | u16 capField = 0, eeval; | ||
3242 | |||
3243 | eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); | ||
3244 | ah->regulatory.current_rd = eeval; | ||
3245 | |||
3246 | eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1); | ||
3247 | if (AR_SREV_9285_10_OR_LATER(ah)) | ||
3248 | eeval |= AR9285_RDEXT_DEFAULT; | ||
3249 | ah->regulatory.current_rd_ext = eeval; | ||
3250 | |||
3251 | capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP); | ||
3252 | |||
3253 | if (ah->opmode != NL80211_IFTYPE_AP && | ||
3254 | ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) { | ||
3255 | if (ah->regulatory.current_rd == 0x64 || | ||
3256 | ah->regulatory.current_rd == 0x65) | ||
3257 | ah->regulatory.current_rd += 5; | ||
3258 | else if (ah->regulatory.current_rd == 0x41) | ||
3259 | ah->regulatory.current_rd = 0x43; | ||
3260 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
3261 | "regdomain mapped to 0x%x\n", ah->regulatory.current_rd); | ||
3262 | } | ||
3263 | |||
3264 | eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE); | ||
3265 | bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX); | ||
3266 | |||
3267 | if (eeval & AR5416_OPFLAGS_11A) { | ||
3268 | set_bit(ATH9K_MODE_11A, pCap->wireless_modes); | ||
3269 | if (ah->config.ht_enable) { | ||
3270 | if (!(eeval & AR5416_OPFLAGS_N_5G_HT20)) | ||
3271 | set_bit(ATH9K_MODE_11NA_HT20, | ||
3272 | pCap->wireless_modes); | ||
3273 | if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) { | ||
3274 | set_bit(ATH9K_MODE_11NA_HT40PLUS, | ||
3275 | pCap->wireless_modes); | ||
3276 | set_bit(ATH9K_MODE_11NA_HT40MINUS, | ||
3277 | pCap->wireless_modes); | ||
3278 | } | ||
3279 | } | ||
3280 | } | ||
3281 | |||
3282 | if (eeval & AR5416_OPFLAGS_11G) { | ||
3283 | set_bit(ATH9K_MODE_11B, pCap->wireless_modes); | ||
3284 | set_bit(ATH9K_MODE_11G, pCap->wireless_modes); | ||
3285 | if (ah->config.ht_enable) { | ||
3286 | if (!(eeval & AR5416_OPFLAGS_N_2G_HT20)) | ||
3287 | set_bit(ATH9K_MODE_11NG_HT20, | ||
3288 | pCap->wireless_modes); | ||
3289 | if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) { | ||
3290 | set_bit(ATH9K_MODE_11NG_HT40PLUS, | ||
3291 | pCap->wireless_modes); | ||
3292 | set_bit(ATH9K_MODE_11NG_HT40MINUS, | ||
3293 | pCap->wireless_modes); | ||
3294 | } | ||
3295 | } | ||
3296 | } | ||
3297 | |||
3298 | pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK); | ||
3299 | if ((ah->hw_version.devid == AR5416_DEVID_PCI) && | ||
3300 | !(eeval & AR5416_OPFLAGS_11A)) | ||
3301 | pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7; | ||
3302 | else | ||
3303 | pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK); | ||
3304 | |||
3305 | if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0))) | ||
3306 | ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA; | ||
3307 | |||
3308 | pCap->low_2ghz_chan = 2312; | ||
3309 | pCap->high_2ghz_chan = 2732; | ||
3310 | |||
3311 | pCap->low_5ghz_chan = 4920; | ||
3312 | pCap->high_5ghz_chan = 6100; | ||
3313 | |||
3314 | pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP; | ||
3315 | pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP; | ||
3316 | pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM; | ||
3317 | |||
3318 | pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP; | ||
3319 | pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP; | ||
3320 | pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM; | ||
3321 | |||
3322 | if (ah->config.ht_enable) | ||
3323 | pCap->hw_caps |= ATH9K_HW_CAP_HT; | ||
3324 | else | ||
3325 | pCap->hw_caps &= ~ATH9K_HW_CAP_HT; | ||
3326 | |||
3327 | pCap->hw_caps |= ATH9K_HW_CAP_GTT; | ||
3328 | pCap->hw_caps |= ATH9K_HW_CAP_VEOL; | ||
3329 | pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK; | ||
3330 | pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH; | ||
3331 | |||
3332 | if (capField & AR_EEPROM_EEPCAP_MAXQCU) | ||
3333 | pCap->total_queues = | ||
3334 | MS(capField, AR_EEPROM_EEPCAP_MAXQCU); | ||
3335 | else | ||
3336 | pCap->total_queues = ATH9K_NUM_TX_QUEUES; | ||
3337 | |||
3338 | if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES) | ||
3339 | pCap->keycache_size = | ||
3340 | 1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES); | ||
3341 | else | ||
3342 | pCap->keycache_size = AR_KEYTABLE_SIZE; | ||
3343 | |||
3344 | pCap->hw_caps |= ATH9K_HW_CAP_FASTCC; | ||
3345 | pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; | ||
3346 | |||
3347 | if (AR_SREV_9285_10_OR_LATER(ah)) | ||
3348 | pCap->num_gpio_pins = AR9285_NUM_GPIO; | ||
3349 | else if (AR_SREV_9280_10_OR_LATER(ah)) | ||
3350 | pCap->num_gpio_pins = AR928X_NUM_GPIO; | ||
3351 | else | ||
3352 | pCap->num_gpio_pins = AR_NUM_GPIO; | ||
3353 | |||
3354 | if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) { | ||
3355 | pCap->hw_caps |= ATH9K_HW_CAP_CST; | ||
3356 | pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX; | ||
3357 | } else { | ||
3358 | pCap->rts_aggr_limit = (8 * 1024); | ||
3359 | } | ||
3360 | |||
3361 | pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM; | ||
3362 | |||
3363 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
3364 | ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT); | ||
3365 | if (ah->rfsilent & EEP_RFSILENT_ENABLED) { | ||
3366 | ah->rfkill_gpio = | ||
3367 | MS(ah->rfsilent, EEP_RFSILENT_GPIO_SEL); | ||
3368 | ah->rfkill_polarity = | ||
3369 | MS(ah->rfsilent, EEP_RFSILENT_POLARITY); | ||
3370 | |||
3371 | pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT; | ||
3372 | } | ||
3373 | #endif | ||
3374 | |||
3375 | if ((ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || | ||
3376 | (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) || | ||
3377 | (ah->hw_version.macVersion == AR_SREV_VERSION_9160) || | ||
3378 | (ah->hw_version.macVersion == AR_SREV_VERSION_9100) || | ||
3379 | (ah->hw_version.macVersion == AR_SREV_VERSION_9280)) | ||
3380 | pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP; | ||
3381 | else | ||
3382 | pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP; | ||
3383 | |||
3384 | if (AR_SREV_9280(ah) || AR_SREV_9285(ah)) | ||
3385 | pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS; | ||
3386 | else | ||
3387 | pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; | ||
3388 | |||
3389 | if (ah->regulatory.current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) { | ||
3390 | pCap->reg_cap = | ||
3391 | AR_EEPROM_EEREGCAP_EN_KK_NEW_11A | | ||
3392 | AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN | | ||
3393 | AR_EEPROM_EEREGCAP_EN_KK_U2 | | ||
3394 | AR_EEPROM_EEREGCAP_EN_KK_MIDBAND; | ||
3395 | } else { | ||
3396 | pCap->reg_cap = | ||
3397 | AR_EEPROM_EEREGCAP_EN_KK_NEW_11A | | ||
3398 | AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN; | ||
3399 | } | ||
3400 | |||
3401 | pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND; | ||
3402 | |||
3403 | pCap->num_antcfg_5ghz = | ||
3404 | ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ); | ||
3405 | pCap->num_antcfg_2ghz = | ||
3406 | ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ); | ||
3407 | |||
3408 | if (AR_SREV_9280_10_OR_LATER(ah) && btcoex_enable) { | ||
3409 | pCap->hw_caps |= ATH9K_HW_CAP_BT_COEX; | ||
3410 | ah->btactive_gpio = 6; | ||
3411 | ah->wlanactive_gpio = 5; | ||
3412 | } | ||
3413 | } | ||
3414 | |||
3415 | bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, | ||
3416 | u32 capability, u32 *result) | ||
3417 | { | ||
3418 | switch (type) { | ||
3419 | case ATH9K_CAP_CIPHER: | ||
3420 | switch (capability) { | ||
3421 | case ATH9K_CIPHER_AES_CCM: | ||
3422 | case ATH9K_CIPHER_AES_OCB: | ||
3423 | case ATH9K_CIPHER_TKIP: | ||
3424 | case ATH9K_CIPHER_WEP: | ||
3425 | case ATH9K_CIPHER_MIC: | ||
3426 | case ATH9K_CIPHER_CLR: | ||
3427 | return true; | ||
3428 | default: | ||
3429 | return false; | ||
3430 | } | ||
3431 | case ATH9K_CAP_TKIP_MIC: | ||
3432 | switch (capability) { | ||
3433 | case 0: | ||
3434 | return true; | ||
3435 | case 1: | ||
3436 | return (ah->sta_id1_defaults & | ||
3437 | AR_STA_ID1_CRPT_MIC_ENABLE) ? true : | ||
3438 | false; | ||
3439 | } | ||
3440 | case ATH9K_CAP_TKIP_SPLIT: | ||
3441 | return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ? | ||
3442 | false : true; | ||
3443 | case ATH9K_CAP_DIVERSITY: | ||
3444 | return (REG_READ(ah, AR_PHY_CCK_DETECT) & | ||
3445 | AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ? | ||
3446 | true : false; | ||
3447 | case ATH9K_CAP_MCAST_KEYSRCH: | ||
3448 | switch (capability) { | ||
3449 | case 0: | ||
3450 | return true; | ||
3451 | case 1: | ||
3452 | if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) { | ||
3453 | return false; | ||
3454 | } else { | ||
3455 | return (ah->sta_id1_defaults & | ||
3456 | AR_STA_ID1_MCAST_KSRCH) ? true : | ||
3457 | false; | ||
3458 | } | ||
3459 | } | ||
3460 | return false; | ||
3461 | case ATH9K_CAP_TXPOW: | ||
3462 | switch (capability) { | ||
3463 | case 0: | ||
3464 | return 0; | ||
3465 | case 1: | ||
3466 | *result = ah->regulatory.power_limit; | ||
3467 | return 0; | ||
3468 | case 2: | ||
3469 | *result = ah->regulatory.max_power_level; | ||
3470 | return 0; | ||
3471 | case 3: | ||
3472 | *result = ah->regulatory.tp_scale; | ||
3473 | return 0; | ||
3474 | } | ||
3475 | return false; | ||
3476 | case ATH9K_CAP_DS: | ||
3477 | return (AR_SREV_9280_20_OR_LATER(ah) && | ||
3478 | (ah->eep_ops->get_eeprom(ah, EEP_RC_CHAIN_MASK) == 1)) | ||
3479 | ? false : true; | ||
3480 | default: | ||
3481 | return false; | ||
3482 | } | ||
3483 | } | ||
3484 | |||
3485 | bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, | ||
3486 | u32 capability, u32 setting, int *status) | ||
3487 | { | ||
3488 | u32 v; | ||
3489 | |||
3490 | switch (type) { | ||
3491 | case ATH9K_CAP_TKIP_MIC: | ||
3492 | if (setting) | ||
3493 | ah->sta_id1_defaults |= | ||
3494 | AR_STA_ID1_CRPT_MIC_ENABLE; | ||
3495 | else | ||
3496 | ah->sta_id1_defaults &= | ||
3497 | ~AR_STA_ID1_CRPT_MIC_ENABLE; | ||
3498 | return true; | ||
3499 | case ATH9K_CAP_DIVERSITY: | ||
3500 | v = REG_READ(ah, AR_PHY_CCK_DETECT); | ||
3501 | if (setting) | ||
3502 | v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; | ||
3503 | else | ||
3504 | v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; | ||
3505 | REG_WRITE(ah, AR_PHY_CCK_DETECT, v); | ||
3506 | return true; | ||
3507 | case ATH9K_CAP_MCAST_KEYSRCH: | ||
3508 | if (setting) | ||
3509 | ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH; | ||
3510 | else | ||
3511 | ah->sta_id1_defaults &= ~AR_STA_ID1_MCAST_KSRCH; | ||
3512 | return true; | ||
3513 | default: | ||
3514 | return false; | ||
3515 | } | ||
3516 | } | ||
3517 | |||
3518 | /****************************/ | ||
3519 | /* GPIO / RFKILL / Antennae */ | ||
3520 | /****************************/ | ||
3521 | |||
3522 | static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah, | ||
3523 | u32 gpio, u32 type) | ||
3524 | { | ||
3525 | int addr; | ||
3526 | u32 gpio_shift, tmp; | ||
3527 | |||
3528 | if (gpio > 11) | ||
3529 | addr = AR_GPIO_OUTPUT_MUX3; | ||
3530 | else if (gpio > 5) | ||
3531 | addr = AR_GPIO_OUTPUT_MUX2; | ||
3532 | else | ||
3533 | addr = AR_GPIO_OUTPUT_MUX1; | ||
3534 | |||
3535 | gpio_shift = (gpio % 6) * 5; | ||
3536 | |||
3537 | if (AR_SREV_9280_20_OR_LATER(ah) | ||
3538 | || (addr != AR_GPIO_OUTPUT_MUX1)) { | ||
3539 | REG_RMW(ah, addr, (type << gpio_shift), | ||
3540 | (0x1f << gpio_shift)); | ||
3541 | } else { | ||
3542 | tmp = REG_READ(ah, addr); | ||
3543 | tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0); | ||
3544 | tmp &= ~(0x1f << gpio_shift); | ||
3545 | tmp |= (type << gpio_shift); | ||
3546 | REG_WRITE(ah, addr, tmp); | ||
3547 | } | ||
3548 | } | ||
3549 | |||
3550 | void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio) | ||
3551 | { | ||
3552 | u32 gpio_shift; | ||
3553 | |||
3554 | ASSERT(gpio < ah->caps.num_gpio_pins); | ||
3555 | |||
3556 | gpio_shift = gpio << 1; | ||
3557 | |||
3558 | REG_RMW(ah, | ||
3559 | AR_GPIO_OE_OUT, | ||
3560 | (AR_GPIO_OE_OUT_DRV_NO << gpio_shift), | ||
3561 | (AR_GPIO_OE_OUT_DRV << gpio_shift)); | ||
3562 | } | ||
3563 | |||
3564 | u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) | ||
3565 | { | ||
3566 | #define MS_REG_READ(x, y) \ | ||
3567 | (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y))) | ||
3568 | |||
3569 | if (gpio >= ah->caps.num_gpio_pins) | ||
3570 | return 0xffffffff; | ||
3571 | |||
3572 | if (AR_SREV_9285_10_OR_LATER(ah)) | ||
3573 | return MS_REG_READ(AR9285, gpio) != 0; | ||
3574 | else if (AR_SREV_9280_10_OR_LATER(ah)) | ||
3575 | return MS_REG_READ(AR928X, gpio) != 0; | ||
3576 | else | ||
3577 | return MS_REG_READ(AR, gpio) != 0; | ||
3578 | } | ||
3579 | |||
3580 | void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, | ||
3581 | u32 ah_signal_type) | ||
3582 | { | ||
3583 | u32 gpio_shift; | ||
3584 | |||
3585 | ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type); | ||
3586 | |||
3587 | gpio_shift = 2 * gpio; | ||
3588 | |||
3589 | REG_RMW(ah, | ||
3590 | AR_GPIO_OE_OUT, | ||
3591 | (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift), | ||
3592 | (AR_GPIO_OE_OUT_DRV << gpio_shift)); | ||
3593 | } | ||
3594 | |||
3595 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) | ||
3596 | { | ||
3597 | REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), | ||
3598 | AR_GPIO_BIT(gpio)); | ||
3599 | } | ||
3600 | |||
3601 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
3602 | void ath9k_enable_rfkill(struct ath_hw *ah) | ||
3603 | { | ||
3604 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, | ||
3605 | AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); | ||
3606 | |||
3607 | REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2, | ||
3608 | AR_GPIO_INPUT_MUX2_RFSILENT); | ||
3609 | |||
3610 | ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio); | ||
3611 | REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB); | ||
3612 | } | ||
3613 | #endif | ||
3614 | |||
3615 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah) | ||
3616 | { | ||
3617 | return REG_READ(ah, AR_DEF_ANTENNA) & 0x7; | ||
3618 | } | ||
3619 | |||
3620 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) | ||
3621 | { | ||
3622 | REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); | ||
3623 | } | ||
3624 | |||
3625 | bool ath9k_hw_setantennaswitch(struct ath_hw *ah, | ||
3626 | enum ath9k_ant_setting settings, | ||
3627 | struct ath9k_channel *chan, | ||
3628 | u8 *tx_chainmask, | ||
3629 | u8 *rx_chainmask, | ||
3630 | u8 *antenna_cfgd) | ||
3631 | { | ||
3632 | static u8 tx_chainmask_cfg, rx_chainmask_cfg; | ||
3633 | |||
3634 | if (AR_SREV_9280(ah)) { | ||
3635 | if (!tx_chainmask_cfg) { | ||
3636 | |||
3637 | tx_chainmask_cfg = *tx_chainmask; | ||
3638 | rx_chainmask_cfg = *rx_chainmask; | ||
3639 | } | ||
3640 | |||
3641 | switch (settings) { | ||
3642 | case ATH9K_ANT_FIXED_A: | ||
3643 | *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK; | ||
3644 | *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK; | ||
3645 | *antenna_cfgd = true; | ||
3646 | break; | ||
3647 | case ATH9K_ANT_FIXED_B: | ||
3648 | if (ah->caps.tx_chainmask > | ||
3649 | ATH9K_ANTENNA1_CHAINMASK) { | ||
3650 | *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK; | ||
3651 | } | ||
3652 | *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK; | ||
3653 | *antenna_cfgd = true; | ||
3654 | break; | ||
3655 | case ATH9K_ANT_VARIABLE: | ||
3656 | *tx_chainmask = tx_chainmask_cfg; | ||
3657 | *rx_chainmask = rx_chainmask_cfg; | ||
3658 | *antenna_cfgd = true; | ||
3659 | break; | ||
3660 | default: | ||
3661 | break; | ||
3662 | } | ||
3663 | } else { | ||
3664 | ah->diversity_control = settings; | ||
3665 | } | ||
3666 | |||
3667 | return true; | ||
3668 | } | ||
3669 | |||
3670 | /*********************/ | ||
3671 | /* General Operation */ | ||
3672 | /*********************/ | ||
3673 | |||
3674 | u32 ath9k_hw_getrxfilter(struct ath_hw *ah) | ||
3675 | { | ||
3676 | u32 bits = REG_READ(ah, AR_RX_FILTER); | ||
3677 | u32 phybits = REG_READ(ah, AR_PHY_ERR); | ||
3678 | |||
3679 | if (phybits & AR_PHY_ERR_RADAR) | ||
3680 | bits |= ATH9K_RX_FILTER_PHYRADAR; | ||
3681 | if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING)) | ||
3682 | bits |= ATH9K_RX_FILTER_PHYERR; | ||
3683 | |||
3684 | return bits; | ||
3685 | } | ||
3686 | |||
3687 | void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) | ||
3688 | { | ||
3689 | u32 phybits; | ||
3690 | |||
3691 | REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff) | AR_RX_COMPR_BAR); | ||
3692 | phybits = 0; | ||
3693 | if (bits & ATH9K_RX_FILTER_PHYRADAR) | ||
3694 | phybits |= AR_PHY_ERR_RADAR; | ||
3695 | if (bits & ATH9K_RX_FILTER_PHYERR) | ||
3696 | phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING; | ||
3697 | REG_WRITE(ah, AR_PHY_ERR, phybits); | ||
3698 | |||
3699 | if (phybits) | ||
3700 | REG_WRITE(ah, AR_RXCFG, | ||
3701 | REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA); | ||
3702 | else | ||
3703 | REG_WRITE(ah, AR_RXCFG, | ||
3704 | REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA); | ||
3705 | } | ||
3706 | |||
3707 | bool ath9k_hw_phy_disable(struct ath_hw *ah) | ||
3708 | { | ||
3709 | return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM); | ||
3710 | } | ||
3711 | |||
3712 | bool ath9k_hw_disable(struct ath_hw *ah) | ||
3713 | { | ||
3714 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) | ||
3715 | return false; | ||
3716 | |||
3717 | return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD); | ||
3718 | } | ||
3719 | |||
3720 | bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit) | ||
3721 | { | ||
3722 | struct ath9k_channel *chan = ah->curchan; | ||
3723 | struct ieee80211_channel *channel = chan->chan; | ||
3724 | |||
3725 | ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER); | ||
3726 | |||
3727 | if (ah->eep_ops->set_txpower(ah, chan, | ||
3728 | ath9k_regd_get_ctl(&ah->regulatory, chan), | ||
3729 | channel->max_antenna_gain * 2, | ||
3730 | channel->max_power * 2, | ||
3731 | min((u32) MAX_RATE_POWER, | ||
3732 | (u32) ah->regulatory.power_limit)) != 0) | ||
3733 | return false; | ||
3734 | |||
3735 | return true; | ||
3736 | } | ||
3737 | |||
3738 | void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac) | ||
3739 | { | ||
3740 | memcpy(ah->macaddr, mac, ETH_ALEN); | ||
3741 | } | ||
3742 | |||
3743 | void ath9k_hw_setopmode(struct ath_hw *ah) | ||
3744 | { | ||
3745 | ath9k_hw_set_operating_mode(ah, ah->opmode); | ||
3746 | } | ||
3747 | |||
3748 | void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1) | ||
3749 | { | ||
3750 | REG_WRITE(ah, AR_MCAST_FIL0, filter0); | ||
3751 | REG_WRITE(ah, AR_MCAST_FIL1, filter1); | ||
3752 | } | ||
3753 | |||
3754 | void ath9k_hw_setbssidmask(struct ath_softc *sc) | ||
3755 | { | ||
3756 | REG_WRITE(sc->sc_ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask)); | ||
3757 | REG_WRITE(sc->sc_ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4)); | ||
3758 | } | ||
3759 | |||
3760 | void ath9k_hw_write_associd(struct ath_softc *sc) | ||
3761 | { | ||
3762 | REG_WRITE(sc->sc_ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid)); | ||
3763 | REG_WRITE(sc->sc_ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) | | ||
3764 | ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S)); | ||
3765 | } | ||
3766 | |||
3767 | u64 ath9k_hw_gettsf64(struct ath_hw *ah) | ||
3768 | { | ||
3769 | u64 tsf; | ||
3770 | |||
3771 | tsf = REG_READ(ah, AR_TSF_U32); | ||
3772 | tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32); | ||
3773 | |||
3774 | return tsf; | ||
3775 | } | ||
3776 | |||
3777 | void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64) | ||
3778 | { | ||
3779 | REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff); | ||
3780 | REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff); | ||
3781 | } | ||
3782 | |||
3783 | void ath9k_hw_reset_tsf(struct ath_hw *ah) | ||
3784 | { | ||
3785 | int count; | ||
3786 | |||
3787 | count = 0; | ||
3788 | while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) { | ||
3789 | count++; | ||
3790 | if (count > 10) { | ||
3791 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | ||
3792 | "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n"); | ||
3793 | break; | ||
3794 | } | ||
3795 | udelay(10); | ||
3796 | } | ||
3797 | REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE); | ||
3798 | } | ||
3799 | |||
3800 | bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting) | ||
3801 | { | ||
3802 | if (setting) | ||
3803 | ah->misc_mode |= AR_PCU_TX_ADD_TSF; | ||
3804 | else | ||
3805 | ah->misc_mode &= ~AR_PCU_TX_ADD_TSF; | ||
3806 | |||
3807 | return true; | ||
3808 | } | ||
3809 | |||
3810 | bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us) | ||
3811 | { | ||
3812 | if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) { | ||
3813 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad slot time %u\n", us); | ||
3814 | ah->slottime = (u32) -1; | ||
3815 | return false; | ||
3816 | } else { | ||
3817 | REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us)); | ||
3818 | ah->slottime = us; | ||
3819 | return true; | ||
3820 | } | ||
3821 | } | ||
3822 | |||
3823 | void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode) | ||
3824 | { | ||
3825 | u32 macmode; | ||
3826 | |||
3827 | if (mode == ATH9K_HT_MACMODE_2040 && | ||
3828 | !ah->config.cwm_ignore_extcca) | ||
3829 | macmode = AR_2040_JOINED_RX_CLEAR; | ||
3830 | else | ||
3831 | macmode = 0; | ||
3832 | |||
3833 | REG_WRITE(ah, AR_2040_MODE, macmode); | ||
3834 | } | ||
3835 | |||
3836 | /***************************/ | ||
3837 | /* Bluetooth Coexistence */ | ||
3838 | /***************************/ | ||
3839 | |||
3840 | void ath9k_hw_btcoex_enable(struct ath_hw *ah) | ||
3841 | { | ||
3842 | /* connect bt_active to baseband */ | ||
3843 | REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL, | ||
3844 | (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF | | ||
3845 | AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF)); | ||
3846 | |||
3847 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, | ||
3848 | AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB); | ||
3849 | |||
3850 | /* Set input mux for bt_active to gpio pin */ | ||
3851 | REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1, | ||
3852 | AR_GPIO_INPUT_MUX1_BT_ACTIVE, | ||
3853 | ah->btactive_gpio); | ||
3854 | |||
3855 | /* Configure the desired gpio port for input */ | ||
3856 | ath9k_hw_cfg_gpio_input(ah, ah->btactive_gpio); | ||
3857 | |||
3858 | /* Configure the desired GPIO port for TX_FRAME output */ | ||
3859 | ath9k_hw_cfg_output(ah, ah->wlanactive_gpio, | ||
3860 | AR_GPIO_OUTPUT_MUX_AS_TX_FRAME); | ||
3861 | } | ||
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h deleted file mode 100644 index 984ac7da09d6..000000000000 --- a/drivers/net/wireless/ath9k/hw.h +++ /dev/null | |||
@@ -1,631 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 HW_H | ||
18 | #define HW_H | ||
19 | |||
20 | #include <linux/if_ether.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/io.h> | ||
23 | |||
24 | #include "mac.h" | ||
25 | #include "ani.h" | ||
26 | #include "eeprom.h" | ||
27 | #include "calib.h" | ||
28 | #include "reg.h" | ||
29 | #include "phy.h" | ||
30 | |||
31 | #include "../ath/regd.h" | ||
32 | |||
33 | #define ATHEROS_VENDOR_ID 0x168c | ||
34 | #define AR5416_DEVID_PCI 0x0023 | ||
35 | #define AR5416_DEVID_PCIE 0x0024 | ||
36 | #define AR9160_DEVID_PCI 0x0027 | ||
37 | #define AR9280_DEVID_PCI 0x0029 | ||
38 | #define AR9280_DEVID_PCIE 0x002a | ||
39 | #define AR9285_DEVID_PCIE 0x002b | ||
40 | #define AR5416_AR9100_DEVID 0x000b | ||
41 | #define AR_SUBVENDOR_ID_NOG 0x0e11 | ||
42 | #define AR_SUBVENDOR_ID_NEW_A 0x7065 | ||
43 | #define AR5416_MAGIC 0x19641014 | ||
44 | |||
45 | /* Register read/write primitives */ | ||
46 | #define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val)) | ||
47 | #define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg)) | ||
48 | |||
49 | #define SM(_v, _f) (((_v) << _f##_S) & _f) | ||
50 | #define MS(_v, _f) (((_v) & _f) >> _f##_S) | ||
51 | #define REG_RMW(_a, _r, _set, _clr) \ | ||
52 | REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set)) | ||
53 | #define REG_RMW_FIELD(_a, _r, _f, _v) \ | ||
54 | REG_WRITE(_a, _r, \ | ||
55 | (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f)) | ||
56 | #define REG_SET_BIT(_a, _r, _f) \ | ||
57 | REG_WRITE(_a, _r, REG_READ(_a, _r) | _f) | ||
58 | #define REG_CLR_BIT(_a, _r, _f) \ | ||
59 | REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f) | ||
60 | |||
61 | #define DO_DELAY(x) do { \ | ||
62 | if ((++(x) % 64) == 0) \ | ||
63 | udelay(1); \ | ||
64 | } while (0) | ||
65 | |||
66 | #define REG_WRITE_ARRAY(iniarray, column, regWr) do { \ | ||
67 | int r; \ | ||
68 | for (r = 0; r < ((iniarray)->ia_rows); r++) { \ | ||
69 | REG_WRITE(ah, INI_RA((iniarray), (r), 0), \ | ||
70 | INI_RA((iniarray), r, (column))); \ | ||
71 | DO_DELAY(regWr); \ | ||
72 | } \ | ||
73 | } while (0) | ||
74 | |||
75 | #define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0 | ||
76 | #define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1 | ||
77 | #define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2 | ||
78 | #define AR_GPIO_OUTPUT_MUX_AS_TX_FRAME 3 | ||
79 | #define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5 | ||
80 | #define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6 | ||
81 | |||
82 | #define AR_GPIOD_MASK 0x00001FFF | ||
83 | #define AR_GPIO_BIT(_gpio) (1 << (_gpio)) | ||
84 | |||
85 | #define BASE_ACTIVATE_DELAY 100 | ||
86 | #define RTC_PLL_SETTLE_DELAY 1000 | ||
87 | #define COEF_SCALE_S 24 | ||
88 | #define HT40_CHANNEL_CENTER_SHIFT 10 | ||
89 | |||
90 | #define ATH9K_ANTENNA0_CHAINMASK 0x1 | ||
91 | #define ATH9K_ANTENNA1_CHAINMASK 0x2 | ||
92 | |||
93 | #define ATH9K_NUM_DMA_DEBUG_REGS 8 | ||
94 | #define ATH9K_NUM_QUEUES 10 | ||
95 | |||
96 | #define MAX_RATE_POWER 63 | ||
97 | #define AH_WAIT_TIMEOUT 100000 /* (us) */ | ||
98 | #define AH_TIME_QUANTUM 10 | ||
99 | #define AR_KEYTABLE_SIZE 128 | ||
100 | #define POWER_UP_TIME 200000 | ||
101 | #define SPUR_RSSI_THRESH 40 | ||
102 | |||
103 | #define CAB_TIMEOUT_VAL 10 | ||
104 | #define BEACON_TIMEOUT_VAL 10 | ||
105 | #define MIN_BEACON_TIMEOUT_VAL 1 | ||
106 | #define SLEEP_SLOP 3 | ||
107 | |||
108 | #define INIT_CONFIG_STATUS 0x00000000 | ||
109 | #define INIT_RSSI_THR 0x00000700 | ||
110 | #define INIT_BCON_CNTRL_REG 0x00000000 | ||
111 | |||
112 | #define TU_TO_USEC(_tu) ((_tu) << 10) | ||
113 | |||
114 | enum wireless_mode { | ||
115 | ATH9K_MODE_11A = 0, | ||
116 | ATH9K_MODE_11B = 2, | ||
117 | ATH9K_MODE_11G = 3, | ||
118 | ATH9K_MODE_11NA_HT20 = 6, | ||
119 | ATH9K_MODE_11NG_HT20 = 7, | ||
120 | ATH9K_MODE_11NA_HT40PLUS = 8, | ||
121 | ATH9K_MODE_11NA_HT40MINUS = 9, | ||
122 | ATH9K_MODE_11NG_HT40PLUS = 10, | ||
123 | ATH9K_MODE_11NG_HT40MINUS = 11, | ||
124 | ATH9K_MODE_MAX | ||
125 | }; | ||
126 | |||
127 | enum ath9k_hw_caps { | ||
128 | ATH9K_HW_CAP_MIC_AESCCM = BIT(0), | ||
129 | ATH9K_HW_CAP_MIC_CKIP = BIT(1), | ||
130 | ATH9K_HW_CAP_MIC_TKIP = BIT(2), | ||
131 | ATH9K_HW_CAP_CIPHER_AESCCM = BIT(3), | ||
132 | ATH9K_HW_CAP_CIPHER_CKIP = BIT(4), | ||
133 | ATH9K_HW_CAP_CIPHER_TKIP = BIT(5), | ||
134 | ATH9K_HW_CAP_VEOL = BIT(6), | ||
135 | ATH9K_HW_CAP_BSSIDMASK = BIT(7), | ||
136 | ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(8), | ||
137 | ATH9K_HW_CAP_HT = BIT(9), | ||
138 | ATH9K_HW_CAP_GTT = BIT(10), | ||
139 | ATH9K_HW_CAP_FASTCC = BIT(11), | ||
140 | ATH9K_HW_CAP_RFSILENT = BIT(12), | ||
141 | ATH9K_HW_CAP_CST = BIT(13), | ||
142 | ATH9K_HW_CAP_ENHANCEDPM = BIT(14), | ||
143 | ATH9K_HW_CAP_AUTOSLEEP = BIT(15), | ||
144 | ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(16), | ||
145 | ATH9K_HW_CAP_BT_COEX = BIT(17) | ||
146 | }; | ||
147 | |||
148 | enum ath9k_capability_type { | ||
149 | ATH9K_CAP_CIPHER = 0, | ||
150 | ATH9K_CAP_TKIP_MIC, | ||
151 | ATH9K_CAP_TKIP_SPLIT, | ||
152 | ATH9K_CAP_DIVERSITY, | ||
153 | ATH9K_CAP_TXPOW, | ||
154 | ATH9K_CAP_MCAST_KEYSRCH, | ||
155 | ATH9K_CAP_DS | ||
156 | }; | ||
157 | |||
158 | struct ath9k_hw_capabilities { | ||
159 | u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ | ||
160 | DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */ | ||
161 | u16 total_queues; | ||
162 | u16 keycache_size; | ||
163 | u16 low_5ghz_chan, high_5ghz_chan; | ||
164 | u16 low_2ghz_chan, high_2ghz_chan; | ||
165 | u16 rts_aggr_limit; | ||
166 | u8 tx_chainmask; | ||
167 | u8 rx_chainmask; | ||
168 | u16 tx_triglevel_max; | ||
169 | u16 reg_cap; | ||
170 | u8 num_gpio_pins; | ||
171 | u8 num_antcfg_2ghz; | ||
172 | u8 num_antcfg_5ghz; | ||
173 | }; | ||
174 | |||
175 | struct ath9k_ops_config { | ||
176 | int dma_beacon_response_time; | ||
177 | int sw_beacon_response_time; | ||
178 | int additional_swba_backoff; | ||
179 | int ack_6mb; | ||
180 | int cwm_ignore_extcca; | ||
181 | u8 pcie_powersave_enable; | ||
182 | u8 pcie_clock_req; | ||
183 | u32 pcie_waen; | ||
184 | u8 analog_shiftreg; | ||
185 | u8 ht_enable; | ||
186 | u32 ofdm_trig_low; | ||
187 | u32 ofdm_trig_high; | ||
188 | u32 cck_trig_high; | ||
189 | u32 cck_trig_low; | ||
190 | u32 enable_ani; | ||
191 | u16 diversity_control; | ||
192 | u16 antenna_switch_swap; | ||
193 | int serialize_regmode; | ||
194 | bool intr_mitigation; | ||
195 | #define SPUR_DISABLE 0 | ||
196 | #define SPUR_ENABLE_IOCTL 1 | ||
197 | #define SPUR_ENABLE_EEPROM 2 | ||
198 | #define AR_EEPROM_MODAL_SPURS 5 | ||
199 | #define AR_SPUR_5413_1 1640 | ||
200 | #define AR_SPUR_5413_2 1200 | ||
201 | #define AR_NO_SPUR 0x8000 | ||
202 | #define AR_BASE_FREQ_2GHZ 2300 | ||
203 | #define AR_BASE_FREQ_5GHZ 4900 | ||
204 | #define AR_SPUR_FEEQ_BOUND_HT40 19 | ||
205 | #define AR_SPUR_FEEQ_BOUND_HT20 10 | ||
206 | int spurmode; | ||
207 | u16 spurchans[AR_EEPROM_MODAL_SPURS][2]; | ||
208 | }; | ||
209 | |||
210 | enum ath9k_int { | ||
211 | ATH9K_INT_RX = 0x00000001, | ||
212 | ATH9K_INT_RXDESC = 0x00000002, | ||
213 | ATH9K_INT_RXNOFRM = 0x00000008, | ||
214 | ATH9K_INT_RXEOL = 0x00000010, | ||
215 | ATH9K_INT_RXORN = 0x00000020, | ||
216 | ATH9K_INT_TX = 0x00000040, | ||
217 | ATH9K_INT_TXDESC = 0x00000080, | ||
218 | ATH9K_INT_TIM_TIMER = 0x00000100, | ||
219 | ATH9K_INT_TXURN = 0x00000800, | ||
220 | ATH9K_INT_MIB = 0x00001000, | ||
221 | ATH9K_INT_RXPHY = 0x00004000, | ||
222 | ATH9K_INT_RXKCM = 0x00008000, | ||
223 | ATH9K_INT_SWBA = 0x00010000, | ||
224 | ATH9K_INT_BMISS = 0x00040000, | ||
225 | ATH9K_INT_BNR = 0x00100000, | ||
226 | ATH9K_INT_TIM = 0x00200000, | ||
227 | ATH9K_INT_DTIM = 0x00400000, | ||
228 | ATH9K_INT_DTIMSYNC = 0x00800000, | ||
229 | ATH9K_INT_GPIO = 0x01000000, | ||
230 | ATH9K_INT_CABEND = 0x02000000, | ||
231 | ATH9K_INT_TSFOOR = 0x04000000, | ||
232 | ATH9K_INT_CST = 0x10000000, | ||
233 | ATH9K_INT_GTT = 0x20000000, | ||
234 | ATH9K_INT_FATAL = 0x40000000, | ||
235 | ATH9K_INT_GLOBAL = 0x80000000, | ||
236 | ATH9K_INT_BMISC = ATH9K_INT_TIM | | ||
237 | ATH9K_INT_DTIM | | ||
238 | ATH9K_INT_DTIMSYNC | | ||
239 | ATH9K_INT_TSFOOR | | ||
240 | ATH9K_INT_CABEND, | ||
241 | ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM | | ||
242 | ATH9K_INT_RXDESC | | ||
243 | ATH9K_INT_RXEOL | | ||
244 | ATH9K_INT_RXORN | | ||
245 | ATH9K_INT_TXURN | | ||
246 | ATH9K_INT_TXDESC | | ||
247 | ATH9K_INT_MIB | | ||
248 | ATH9K_INT_RXPHY | | ||
249 | ATH9K_INT_RXKCM | | ||
250 | ATH9K_INT_SWBA | | ||
251 | ATH9K_INT_BMISS | | ||
252 | ATH9K_INT_GPIO, | ||
253 | ATH9K_INT_NOCARD = 0xffffffff | ||
254 | }; | ||
255 | |||
256 | #define CHANNEL_CW_INT 0x00002 | ||
257 | #define CHANNEL_CCK 0x00020 | ||
258 | #define CHANNEL_OFDM 0x00040 | ||
259 | #define CHANNEL_2GHZ 0x00080 | ||
260 | #define CHANNEL_5GHZ 0x00100 | ||
261 | #define CHANNEL_PASSIVE 0x00200 | ||
262 | #define CHANNEL_DYN 0x00400 | ||
263 | #define CHANNEL_HALF 0x04000 | ||
264 | #define CHANNEL_QUARTER 0x08000 | ||
265 | #define CHANNEL_HT20 0x10000 | ||
266 | #define CHANNEL_HT40PLUS 0x20000 | ||
267 | #define CHANNEL_HT40MINUS 0x40000 | ||
268 | |||
269 | #define CHANNEL_INTERFERENCE 0x01 | ||
270 | #define CHANNEL_DFS 0x02 | ||
271 | #define CHANNEL_4MS_LIMIT 0x04 | ||
272 | #define CHANNEL_DFS_CLEAR 0x08 | ||
273 | #define CHANNEL_DISALLOW_ADHOC 0x10 | ||
274 | #define CHANNEL_PER_11D_ADHOC 0x20 | ||
275 | |||
276 | #define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM) | ||
277 | #define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK) | ||
278 | #define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM) | ||
279 | #define CHANNEL_G_HT20 (CHANNEL_2GHZ|CHANNEL_HT20) | ||
280 | #define CHANNEL_A_HT20 (CHANNEL_5GHZ|CHANNEL_HT20) | ||
281 | #define CHANNEL_G_HT40PLUS (CHANNEL_2GHZ|CHANNEL_HT40PLUS) | ||
282 | #define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS) | ||
283 | #define CHANNEL_A_HT40PLUS (CHANNEL_5GHZ|CHANNEL_HT40PLUS) | ||
284 | #define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS) | ||
285 | #define CHANNEL_ALL \ | ||
286 | (CHANNEL_OFDM| \ | ||
287 | CHANNEL_CCK| \ | ||
288 | CHANNEL_2GHZ | \ | ||
289 | CHANNEL_5GHZ | \ | ||
290 | CHANNEL_HT20 | \ | ||
291 | CHANNEL_HT40PLUS | \ | ||
292 | CHANNEL_HT40MINUS) | ||
293 | |||
294 | struct ath9k_channel { | ||
295 | struct ieee80211_channel *chan; | ||
296 | u16 channel; | ||
297 | u32 channelFlags; | ||
298 | u32 chanmode; | ||
299 | int32_t CalValid; | ||
300 | bool oneTimeCalsDone; | ||
301 | int8_t iCoff; | ||
302 | int8_t qCoff; | ||
303 | int16_t rawNoiseFloor; | ||
304 | }; | ||
305 | |||
306 | #define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \ | ||
307 | (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \ | ||
308 | (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \ | ||
309 | (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS)) | ||
310 | #define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \ | ||
311 | (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \ | ||
312 | (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \ | ||
313 | (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS)) | ||
314 | #define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0) | ||
315 | #define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0) | ||
316 | #define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0) | ||
317 | #define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0) | ||
318 | #define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0) | ||
319 | #define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0) | ||
320 | #define IS_CHAN_A_5MHZ_SPACED(_c) \ | ||
321 | ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \ | ||
322 | (((_c)->channel % 20) != 0) && \ | ||
323 | (((_c)->channel % 10) != 0)) | ||
324 | |||
325 | /* These macros check chanmode and not channelFlags */ | ||
326 | #define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B) | ||
327 | #define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) || \ | ||
328 | ((_c)->chanmode == CHANNEL_G_HT20)) | ||
329 | #define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) || \ | ||
330 | ((_c)->chanmode == CHANNEL_A_HT40MINUS) || \ | ||
331 | ((_c)->chanmode == CHANNEL_G_HT40PLUS) || \ | ||
332 | ((_c)->chanmode == CHANNEL_G_HT40MINUS)) | ||
333 | #define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c))) | ||
334 | |||
335 | enum ath9k_power_mode { | ||
336 | ATH9K_PM_AWAKE = 0, | ||
337 | ATH9K_PM_FULL_SLEEP, | ||
338 | ATH9K_PM_NETWORK_SLEEP, | ||
339 | ATH9K_PM_UNDEFINED | ||
340 | }; | ||
341 | |||
342 | enum ath9k_ant_setting { | ||
343 | ATH9K_ANT_VARIABLE = 0, | ||
344 | ATH9K_ANT_FIXED_A, | ||
345 | ATH9K_ANT_FIXED_B | ||
346 | }; | ||
347 | |||
348 | enum ath9k_tp_scale { | ||
349 | ATH9K_TP_SCALE_MAX = 0, | ||
350 | ATH9K_TP_SCALE_50, | ||
351 | ATH9K_TP_SCALE_25, | ||
352 | ATH9K_TP_SCALE_12, | ||
353 | ATH9K_TP_SCALE_MIN | ||
354 | }; | ||
355 | |||
356 | enum ser_reg_mode { | ||
357 | SER_REG_MODE_OFF = 0, | ||
358 | SER_REG_MODE_ON = 1, | ||
359 | SER_REG_MODE_AUTO = 2, | ||
360 | }; | ||
361 | |||
362 | struct ath9k_beacon_state { | ||
363 | u32 bs_nexttbtt; | ||
364 | u32 bs_nextdtim; | ||
365 | u32 bs_intval; | ||
366 | #define ATH9K_BEACON_PERIOD 0x0000ffff | ||
367 | #define ATH9K_BEACON_ENA 0x00800000 | ||
368 | #define ATH9K_BEACON_RESET_TSF 0x01000000 | ||
369 | #define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */ | ||
370 | u32 bs_dtimperiod; | ||
371 | u16 bs_cfpperiod; | ||
372 | u16 bs_cfpmaxduration; | ||
373 | u32 bs_cfpnext; | ||
374 | u16 bs_timoffset; | ||
375 | u16 bs_bmissthreshold; | ||
376 | u32 bs_sleepduration; | ||
377 | u32 bs_tsfoor_threshold; | ||
378 | }; | ||
379 | |||
380 | struct chan_centers { | ||
381 | u16 synth_center; | ||
382 | u16 ctl_center; | ||
383 | u16 ext_center; | ||
384 | }; | ||
385 | |||
386 | enum { | ||
387 | ATH9K_RESET_POWER_ON, | ||
388 | ATH9K_RESET_WARM, | ||
389 | ATH9K_RESET_COLD, | ||
390 | }; | ||
391 | |||
392 | struct ath9k_hw_version { | ||
393 | u32 magic; | ||
394 | u16 devid; | ||
395 | u16 subvendorid; | ||
396 | u32 macVersion; | ||
397 | u16 macRev; | ||
398 | u16 phyRev; | ||
399 | u16 analog5GhzRev; | ||
400 | u16 analog2GhzRev; | ||
401 | }; | ||
402 | |||
403 | struct ath_hw { | ||
404 | struct ath_softc *ah_sc; | ||
405 | struct ath9k_hw_version hw_version; | ||
406 | struct ath9k_ops_config config; | ||
407 | struct ath9k_hw_capabilities caps; | ||
408 | struct ath_regulatory regulatory; | ||
409 | struct ath9k_channel channels[38]; | ||
410 | struct ath9k_channel *curchan; | ||
411 | |||
412 | union { | ||
413 | struct ar5416_eeprom_def def; | ||
414 | struct ar5416_eeprom_4k map4k; | ||
415 | } eeprom; | ||
416 | const struct eeprom_ops *eep_ops; | ||
417 | enum ath9k_eep_map eep_map; | ||
418 | |||
419 | bool sw_mgmt_crypto; | ||
420 | bool is_pciexpress; | ||
421 | u8 macaddr[ETH_ALEN]; | ||
422 | u16 tx_trig_level; | ||
423 | u16 rfsilent; | ||
424 | u32 rfkill_gpio; | ||
425 | u32 rfkill_polarity; | ||
426 | u32 btactive_gpio; | ||
427 | u32 wlanactive_gpio; | ||
428 | u32 ah_flags; | ||
429 | |||
430 | enum nl80211_iftype opmode; | ||
431 | enum ath9k_power_mode power_mode; | ||
432 | enum ath9k_power_mode restore_mode; | ||
433 | |||
434 | struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; | ||
435 | struct ar5416Stats stats; | ||
436 | struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; | ||
437 | |||
438 | int16_t curchan_rad_index; | ||
439 | u32 mask_reg; | ||
440 | u32 txok_interrupt_mask; | ||
441 | u32 txerr_interrupt_mask; | ||
442 | u32 txdesc_interrupt_mask; | ||
443 | u32 txeol_interrupt_mask; | ||
444 | u32 txurn_interrupt_mask; | ||
445 | bool chip_fullsleep; | ||
446 | u32 atim_window; | ||
447 | u16 antenna_switch_swap; | ||
448 | enum ath9k_ant_setting diversity_control; | ||
449 | |||
450 | /* Calibration */ | ||
451 | enum hal_cal_types supp_cals; | ||
452 | struct hal_cal_list iq_caldata; | ||
453 | struct hal_cal_list adcgain_caldata; | ||
454 | struct hal_cal_list adcdc_calinitdata; | ||
455 | struct hal_cal_list adcdc_caldata; | ||
456 | struct hal_cal_list *cal_list; | ||
457 | struct hal_cal_list *cal_list_last; | ||
458 | struct hal_cal_list *cal_list_curr; | ||
459 | #define totalPowerMeasI meas0.unsign | ||
460 | #define totalPowerMeasQ meas1.unsign | ||
461 | #define totalIqCorrMeas meas2.sign | ||
462 | #define totalAdcIOddPhase meas0.unsign | ||
463 | #define totalAdcIEvenPhase meas1.unsign | ||
464 | #define totalAdcQOddPhase meas2.unsign | ||
465 | #define totalAdcQEvenPhase meas3.unsign | ||
466 | #define totalAdcDcOffsetIOddPhase meas0.sign | ||
467 | #define totalAdcDcOffsetIEvenPhase meas1.sign | ||
468 | #define totalAdcDcOffsetQOddPhase meas2.sign | ||
469 | #define totalAdcDcOffsetQEvenPhase meas3.sign | ||
470 | union { | ||
471 | u32 unsign[AR5416_MAX_CHAINS]; | ||
472 | int32_t sign[AR5416_MAX_CHAINS]; | ||
473 | } meas0; | ||
474 | union { | ||
475 | u32 unsign[AR5416_MAX_CHAINS]; | ||
476 | int32_t sign[AR5416_MAX_CHAINS]; | ||
477 | } meas1; | ||
478 | union { | ||
479 | u32 unsign[AR5416_MAX_CHAINS]; | ||
480 | int32_t sign[AR5416_MAX_CHAINS]; | ||
481 | } meas2; | ||
482 | union { | ||
483 | u32 unsign[AR5416_MAX_CHAINS]; | ||
484 | int32_t sign[AR5416_MAX_CHAINS]; | ||
485 | } meas3; | ||
486 | u16 cal_samples; | ||
487 | |||
488 | u32 sta_id1_defaults; | ||
489 | u32 misc_mode; | ||
490 | enum { | ||
491 | AUTO_32KHZ, | ||
492 | USE_32KHZ, | ||
493 | DONT_USE_32KHZ, | ||
494 | } enable_32kHz_clock; | ||
495 | |||
496 | /* RF */ | ||
497 | u32 *analogBank0Data; | ||
498 | u32 *analogBank1Data; | ||
499 | u32 *analogBank2Data; | ||
500 | u32 *analogBank3Data; | ||
501 | u32 *analogBank6Data; | ||
502 | u32 *analogBank6TPCData; | ||
503 | u32 *analogBank7Data; | ||
504 | u32 *addac5416_21; | ||
505 | u32 *bank6Temp; | ||
506 | |||
507 | int16_t txpower_indexoffset; | ||
508 | u32 beacon_interval; | ||
509 | u32 slottime; | ||
510 | u32 acktimeout; | ||
511 | u32 ctstimeout; | ||
512 | u32 globaltxtimeout; | ||
513 | u8 gbeacon_rate; | ||
514 | |||
515 | /* ANI */ | ||
516 | u32 proc_phyerr; | ||
517 | bool has_hw_phycounters; | ||
518 | u32 aniperiod; | ||
519 | struct ar5416AniState *curani; | ||
520 | struct ar5416AniState ani[255]; | ||
521 | int totalSizeDesired[5]; | ||
522 | int coarse_high[5]; | ||
523 | int coarse_low[5]; | ||
524 | int firpwr[5]; | ||
525 | enum ath9k_ani_cmd ani_function; | ||
526 | |||
527 | u32 intr_txqs; | ||
528 | enum ath9k_ht_extprotspacing extprotspacing; | ||
529 | u8 txchainmask; | ||
530 | u8 rxchainmask; | ||
531 | |||
532 | u32 originalGain[22]; | ||
533 | int initPDADC; | ||
534 | int PDADCdelta; | ||
535 | |||
536 | struct ar5416IniArray iniModes; | ||
537 | struct ar5416IniArray iniCommon; | ||
538 | struct ar5416IniArray iniBank0; | ||
539 | struct ar5416IniArray iniBB_RfGain; | ||
540 | struct ar5416IniArray iniBank1; | ||
541 | struct ar5416IniArray iniBank2; | ||
542 | struct ar5416IniArray iniBank3; | ||
543 | struct ar5416IniArray iniBank6; | ||
544 | struct ar5416IniArray iniBank6TPC; | ||
545 | struct ar5416IniArray iniBank7; | ||
546 | struct ar5416IniArray iniAddac; | ||
547 | struct ar5416IniArray iniPcieSerdes; | ||
548 | struct ar5416IniArray iniModesAdditional; | ||
549 | struct ar5416IniArray iniModesRxGain; | ||
550 | struct ar5416IniArray iniModesTxGain; | ||
551 | }; | ||
552 | |||
553 | /* Attach, Detach, Reset */ | ||
554 | const char *ath9k_hw_probe(u16 vendorid, u16 devid); | ||
555 | void ath9k_hw_detach(struct ath_hw *ah); | ||
556 | struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error); | ||
557 | void ath9k_hw_rfdetach(struct ath_hw *ah); | ||
558 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | ||
559 | bool bChannelChange); | ||
560 | void ath9k_hw_fill_cap_info(struct ath_hw *ah); | ||
561 | bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, | ||
562 | u32 capability, u32 *result); | ||
563 | bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, | ||
564 | u32 capability, u32 setting, int *status); | ||
565 | |||
566 | /* Key Cache Management */ | ||
567 | bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry); | ||
568 | bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac); | ||
569 | bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, | ||
570 | const struct ath9k_keyval *k, | ||
571 | const u8 *mac); | ||
572 | bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry); | ||
573 | |||
574 | /* GPIO / RFKILL / Antennae */ | ||
575 | void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio); | ||
576 | u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio); | ||
577 | void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, | ||
578 | u32 ah_signal_type); | ||
579 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); | ||
580 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
581 | void ath9k_enable_rfkill(struct ath_hw *ah); | ||
582 | #endif | ||
583 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah); | ||
584 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); | ||
585 | bool ath9k_hw_setantennaswitch(struct ath_hw *ah, | ||
586 | enum ath9k_ant_setting settings, | ||
587 | struct ath9k_channel *chan, | ||
588 | u8 *tx_chainmask, u8 *rx_chainmask, | ||
589 | u8 *antenna_cfgd); | ||
590 | |||
591 | /* General Operation */ | ||
592 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); | ||
593 | u32 ath9k_hw_reverse_bits(u32 val, u32 n); | ||
594 | bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high); | ||
595 | u16 ath9k_hw_computetxtime(struct ath_hw *ah, struct ath_rate_table *rates, | ||
596 | u32 frameLen, u16 rateix, bool shortPreamble); | ||
597 | void ath9k_hw_get_channel_centers(struct ath_hw *ah, | ||
598 | struct ath9k_channel *chan, | ||
599 | struct chan_centers *centers); | ||
600 | u32 ath9k_hw_getrxfilter(struct ath_hw *ah); | ||
601 | void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits); | ||
602 | bool ath9k_hw_phy_disable(struct ath_hw *ah); | ||
603 | bool ath9k_hw_disable(struct ath_hw *ah); | ||
604 | bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit); | ||
605 | void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac); | ||
606 | void ath9k_hw_setopmode(struct ath_hw *ah); | ||
607 | void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1); | ||
608 | void ath9k_hw_setbssidmask(struct ath_softc *sc); | ||
609 | void ath9k_hw_write_associd(struct ath_softc *sc); | ||
610 | u64 ath9k_hw_gettsf64(struct ath_hw *ah); | ||
611 | void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); | ||
612 | void ath9k_hw_reset_tsf(struct ath_hw *ah); | ||
613 | bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); | ||
614 | bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us); | ||
615 | void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode); | ||
616 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); | ||
617 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | ||
618 | const struct ath9k_beacon_state *bs); | ||
619 | bool ath9k_hw_setpower(struct ath_hw *ah, | ||
620 | enum ath9k_power_mode mode); | ||
621 | void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore); | ||
622 | |||
623 | /* Interrupt Handling */ | ||
624 | bool ath9k_hw_intrpend(struct ath_hw *ah); | ||
625 | bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked); | ||
626 | enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah); | ||
627 | enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints); | ||
628 | |||
629 | void ath9k_hw_btcoex_enable(struct ath_hw *ah); | ||
630 | |||
631 | #endif | ||
diff --git a/drivers/net/wireless/ath9k/initvals.h b/drivers/net/wireless/ath9k/initvals.h deleted file mode 100644 index e2f0a34b79a1..000000000000 --- a/drivers/net/wireless/ath9k/initvals.h +++ /dev/null | |||
@@ -1,4848 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 | static const u32 ar5416Modes[][6] = { | ||
18 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | ||
19 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | ||
20 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | ||
21 | { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, | ||
22 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, | ||
23 | { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf }, | ||
24 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, | ||
25 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, | ||
26 | { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
27 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, | ||
28 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
29 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, | ||
30 | { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 }, | ||
31 | { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
32 | { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
33 | { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
34 | { 0x00009850, 0x6c48b4e0, 0x6c48b4e0, 0x6c48b0de, 0x6c48b0de, 0x6c48b0de }, | ||
35 | { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e }, | ||
36 | { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e }, | ||
37 | { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 }, | ||
38 | { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, | ||
39 | { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 }, | ||
40 | { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 }, | ||
41 | { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, | ||
42 | { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 }, | ||
43 | { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b }, | ||
44 | { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 }, | ||
45 | { 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 }, | ||
46 | { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 }, | ||
47 | { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 }, | ||
48 | { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 }, | ||
49 | { 0x0000c9bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 }, | ||
50 | { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be }, | ||
51 | { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, | ||
52 | { 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c }, | ||
53 | { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, | ||
54 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, | ||
55 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
56 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
57 | { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 }, | ||
58 | { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 }, | ||
59 | { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
60 | { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
61 | { 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
62 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | ||
63 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | ||
64 | { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa }, | ||
65 | { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 }, | ||
66 | { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 }, | ||
67 | { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 }, | ||
68 | { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b }, | ||
69 | { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b }, | ||
70 | { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a }, | ||
71 | { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf }, | ||
72 | { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f }, | ||
73 | { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f }, | ||
74 | { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f }, | ||
75 | { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 }, | ||
76 | { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
77 | { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
78 | { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
79 | }; | ||
80 | |||
81 | static const u32 ar5416Common[][2] = { | ||
82 | { 0x0000000c, 0x00000000 }, | ||
83 | { 0x00000030, 0x00020015 }, | ||
84 | { 0x00000034, 0x00000005 }, | ||
85 | { 0x00000040, 0x00000000 }, | ||
86 | { 0x00000044, 0x00000008 }, | ||
87 | { 0x00000048, 0x00000008 }, | ||
88 | { 0x0000004c, 0x00000010 }, | ||
89 | { 0x00000050, 0x00000000 }, | ||
90 | { 0x00000054, 0x0000001f }, | ||
91 | { 0x00000800, 0x00000000 }, | ||
92 | { 0x00000804, 0x00000000 }, | ||
93 | { 0x00000808, 0x00000000 }, | ||
94 | { 0x0000080c, 0x00000000 }, | ||
95 | { 0x00000810, 0x00000000 }, | ||
96 | { 0x00000814, 0x00000000 }, | ||
97 | { 0x00000818, 0x00000000 }, | ||
98 | { 0x0000081c, 0x00000000 }, | ||
99 | { 0x00000820, 0x00000000 }, | ||
100 | { 0x00000824, 0x00000000 }, | ||
101 | { 0x00001040, 0x002ffc0f }, | ||
102 | { 0x00001044, 0x002ffc0f }, | ||
103 | { 0x00001048, 0x002ffc0f }, | ||
104 | { 0x0000104c, 0x002ffc0f }, | ||
105 | { 0x00001050, 0x002ffc0f }, | ||
106 | { 0x00001054, 0x002ffc0f }, | ||
107 | { 0x00001058, 0x002ffc0f }, | ||
108 | { 0x0000105c, 0x002ffc0f }, | ||
109 | { 0x00001060, 0x002ffc0f }, | ||
110 | { 0x00001064, 0x002ffc0f }, | ||
111 | { 0x00001230, 0x00000000 }, | ||
112 | { 0x00001270, 0x00000000 }, | ||
113 | { 0x00001038, 0x00000000 }, | ||
114 | { 0x00001078, 0x00000000 }, | ||
115 | { 0x000010b8, 0x00000000 }, | ||
116 | { 0x000010f8, 0x00000000 }, | ||
117 | { 0x00001138, 0x00000000 }, | ||
118 | { 0x00001178, 0x00000000 }, | ||
119 | { 0x000011b8, 0x00000000 }, | ||
120 | { 0x000011f8, 0x00000000 }, | ||
121 | { 0x00001238, 0x00000000 }, | ||
122 | { 0x00001278, 0x00000000 }, | ||
123 | { 0x000012b8, 0x00000000 }, | ||
124 | { 0x000012f8, 0x00000000 }, | ||
125 | { 0x00001338, 0x00000000 }, | ||
126 | { 0x00001378, 0x00000000 }, | ||
127 | { 0x000013b8, 0x00000000 }, | ||
128 | { 0x000013f8, 0x00000000 }, | ||
129 | { 0x00001438, 0x00000000 }, | ||
130 | { 0x00001478, 0x00000000 }, | ||
131 | { 0x000014b8, 0x00000000 }, | ||
132 | { 0x000014f8, 0x00000000 }, | ||
133 | { 0x00001538, 0x00000000 }, | ||
134 | { 0x00001578, 0x00000000 }, | ||
135 | { 0x000015b8, 0x00000000 }, | ||
136 | { 0x000015f8, 0x00000000 }, | ||
137 | { 0x00001638, 0x00000000 }, | ||
138 | { 0x00001678, 0x00000000 }, | ||
139 | { 0x000016b8, 0x00000000 }, | ||
140 | { 0x000016f8, 0x00000000 }, | ||
141 | { 0x00001738, 0x00000000 }, | ||
142 | { 0x00001778, 0x00000000 }, | ||
143 | { 0x000017b8, 0x00000000 }, | ||
144 | { 0x000017f8, 0x00000000 }, | ||
145 | { 0x0000103c, 0x00000000 }, | ||
146 | { 0x0000107c, 0x00000000 }, | ||
147 | { 0x000010bc, 0x00000000 }, | ||
148 | { 0x000010fc, 0x00000000 }, | ||
149 | { 0x0000113c, 0x00000000 }, | ||
150 | { 0x0000117c, 0x00000000 }, | ||
151 | { 0x000011bc, 0x00000000 }, | ||
152 | { 0x000011fc, 0x00000000 }, | ||
153 | { 0x0000123c, 0x00000000 }, | ||
154 | { 0x0000127c, 0x00000000 }, | ||
155 | { 0x000012bc, 0x00000000 }, | ||
156 | { 0x000012fc, 0x00000000 }, | ||
157 | { 0x0000133c, 0x00000000 }, | ||
158 | { 0x0000137c, 0x00000000 }, | ||
159 | { 0x000013bc, 0x00000000 }, | ||
160 | { 0x000013fc, 0x00000000 }, | ||
161 | { 0x0000143c, 0x00000000 }, | ||
162 | { 0x0000147c, 0x00000000 }, | ||
163 | { 0x00004030, 0x00000002 }, | ||
164 | { 0x0000403c, 0x00000002 }, | ||
165 | { 0x00007010, 0x00000000 }, | ||
166 | { 0x00007038, 0x000004c2 }, | ||
167 | { 0x00008004, 0x00000000 }, | ||
168 | { 0x00008008, 0x00000000 }, | ||
169 | { 0x0000800c, 0x00000000 }, | ||
170 | { 0x00008018, 0x00000700 }, | ||
171 | { 0x00008020, 0x00000000 }, | ||
172 | { 0x00008038, 0x00000000 }, | ||
173 | { 0x0000803c, 0x00000000 }, | ||
174 | { 0x00008048, 0x40000000 }, | ||
175 | { 0x00008054, 0x00000000 }, | ||
176 | { 0x00008058, 0x00000000 }, | ||
177 | { 0x0000805c, 0x000fc78f }, | ||
178 | { 0x00008060, 0x0000000f }, | ||
179 | { 0x00008064, 0x00000000 }, | ||
180 | { 0x000080c0, 0x2a82301a }, | ||
181 | { 0x000080c4, 0x05dc01e0 }, | ||
182 | { 0x000080c8, 0x1f402710 }, | ||
183 | { 0x000080cc, 0x01f40000 }, | ||
184 | { 0x000080d0, 0x00001e00 }, | ||
185 | { 0x000080d4, 0x00000000 }, | ||
186 | { 0x000080d8, 0x00400000 }, | ||
187 | { 0x000080e0, 0xffffffff }, | ||
188 | { 0x000080e4, 0x0000ffff }, | ||
189 | { 0x000080e8, 0x003f3f3f }, | ||
190 | { 0x000080ec, 0x00000000 }, | ||
191 | { 0x000080f0, 0x00000000 }, | ||
192 | { 0x000080f4, 0x00000000 }, | ||
193 | { 0x000080f8, 0x00000000 }, | ||
194 | { 0x000080fc, 0x00020000 }, | ||
195 | { 0x00008100, 0x00020000 }, | ||
196 | { 0x00008104, 0x00000001 }, | ||
197 | { 0x00008108, 0x00000052 }, | ||
198 | { 0x0000810c, 0x00000000 }, | ||
199 | { 0x00008110, 0x00000168 }, | ||
200 | { 0x00008118, 0x000100aa }, | ||
201 | { 0x0000811c, 0x00003210 }, | ||
202 | { 0x00008120, 0x08f04800 }, | ||
203 | { 0x00008124, 0x00000000 }, | ||
204 | { 0x00008128, 0x00000000 }, | ||
205 | { 0x0000812c, 0x00000000 }, | ||
206 | { 0x00008130, 0x00000000 }, | ||
207 | { 0x00008134, 0x00000000 }, | ||
208 | { 0x00008138, 0x00000000 }, | ||
209 | { 0x0000813c, 0x00000000 }, | ||
210 | { 0x00008144, 0xffffffff }, | ||
211 | { 0x00008168, 0x00000000 }, | ||
212 | { 0x0000816c, 0x00000000 }, | ||
213 | { 0x00008170, 0x32143320 }, | ||
214 | { 0x00008174, 0xfaa4fa50 }, | ||
215 | { 0x00008178, 0x00000100 }, | ||
216 | { 0x0000817c, 0x00000000 }, | ||
217 | { 0x000081c4, 0x00000000 }, | ||
218 | { 0x000081d0, 0x00003210 }, | ||
219 | { 0x000081ec, 0x00000000 }, | ||
220 | { 0x000081f0, 0x00000000 }, | ||
221 | { 0x000081f4, 0x00000000 }, | ||
222 | { 0x000081f8, 0x00000000 }, | ||
223 | { 0x000081fc, 0x00000000 }, | ||
224 | { 0x00008200, 0x00000000 }, | ||
225 | { 0x00008204, 0x00000000 }, | ||
226 | { 0x00008208, 0x00000000 }, | ||
227 | { 0x0000820c, 0x00000000 }, | ||
228 | { 0x00008210, 0x00000000 }, | ||
229 | { 0x00008214, 0x00000000 }, | ||
230 | { 0x00008218, 0x00000000 }, | ||
231 | { 0x0000821c, 0x00000000 }, | ||
232 | { 0x00008220, 0x00000000 }, | ||
233 | { 0x00008224, 0x00000000 }, | ||
234 | { 0x00008228, 0x00000000 }, | ||
235 | { 0x0000822c, 0x00000000 }, | ||
236 | { 0x00008230, 0x00000000 }, | ||
237 | { 0x00008234, 0x00000000 }, | ||
238 | { 0x00008238, 0x00000000 }, | ||
239 | { 0x0000823c, 0x00000000 }, | ||
240 | { 0x00008240, 0x00100000 }, | ||
241 | { 0x00008244, 0x0010f400 }, | ||
242 | { 0x00008248, 0x00000100 }, | ||
243 | { 0x0000824c, 0x0001e800 }, | ||
244 | { 0x00008250, 0x00000000 }, | ||
245 | { 0x00008254, 0x00000000 }, | ||
246 | { 0x00008258, 0x00000000 }, | ||
247 | { 0x0000825c, 0x400000ff }, | ||
248 | { 0x00008260, 0x00080922 }, | ||
249 | { 0x00008270, 0x00000000 }, | ||
250 | { 0x00008274, 0x40000000 }, | ||
251 | { 0x00008278, 0x003e4180 }, | ||
252 | { 0x0000827c, 0x00000000 }, | ||
253 | { 0x00008284, 0x0000002c }, | ||
254 | { 0x00008288, 0x0000002c }, | ||
255 | { 0x0000828c, 0x00000000 }, | ||
256 | { 0x00008294, 0x00000000 }, | ||
257 | { 0x00008298, 0x00000000 }, | ||
258 | { 0x00008300, 0x00000000 }, | ||
259 | { 0x00008304, 0x00000000 }, | ||
260 | { 0x00008308, 0x00000000 }, | ||
261 | { 0x0000830c, 0x00000000 }, | ||
262 | { 0x00008310, 0x00000000 }, | ||
263 | { 0x00008314, 0x00000000 }, | ||
264 | { 0x00008318, 0x00000000 }, | ||
265 | { 0x00008328, 0x00000000 }, | ||
266 | { 0x0000832c, 0x00000007 }, | ||
267 | { 0x00008330, 0x00000302 }, | ||
268 | { 0x00008334, 0x00000e00 }, | ||
269 | { 0x00008338, 0x00070000 }, | ||
270 | { 0x0000833c, 0x00000000 }, | ||
271 | { 0x00008340, 0x000107ff }, | ||
272 | { 0x00009808, 0x00000000 }, | ||
273 | { 0x0000980c, 0xad848e19 }, | ||
274 | { 0x00009810, 0x7d14e000 }, | ||
275 | { 0x00009814, 0x9c0a9f6b }, | ||
276 | { 0x0000981c, 0x00000000 }, | ||
277 | { 0x0000982c, 0x0000a000 }, | ||
278 | { 0x00009830, 0x00000000 }, | ||
279 | { 0x0000983c, 0x00200400 }, | ||
280 | { 0x00009840, 0x206a002e }, | ||
281 | { 0x0000984c, 0x1284233c }, | ||
282 | { 0x00009854, 0x00000859 }, | ||
283 | { 0x00009900, 0x00000000 }, | ||
284 | { 0x00009904, 0x00000000 }, | ||
285 | { 0x00009908, 0x00000000 }, | ||
286 | { 0x0000990c, 0x00000000 }, | ||
287 | { 0x0000991c, 0x10000fff }, | ||
288 | { 0x00009920, 0x05100000 }, | ||
289 | { 0x0000a920, 0x05100000 }, | ||
290 | { 0x0000b920, 0x05100000 }, | ||
291 | { 0x00009928, 0x00000001 }, | ||
292 | { 0x0000992c, 0x00000004 }, | ||
293 | { 0x00009934, 0x1e1f2022 }, | ||
294 | { 0x00009938, 0x0a0b0c0d }, | ||
295 | { 0x0000993c, 0x00000000 }, | ||
296 | { 0x00009948, 0x9280b212 }, | ||
297 | { 0x0000994c, 0x00020028 }, | ||
298 | { 0x00009954, 0x5d50e188 }, | ||
299 | { 0x00009958, 0x00081fff }, | ||
300 | { 0x0000c95c, 0x004b6a8e }, | ||
301 | { 0x0000c968, 0x000003ce }, | ||
302 | { 0x00009970, 0x190fb515 }, | ||
303 | { 0x00009974, 0x00000000 }, | ||
304 | { 0x00009978, 0x00000001 }, | ||
305 | { 0x0000997c, 0x00000000 }, | ||
306 | { 0x00009980, 0x00000000 }, | ||
307 | { 0x00009984, 0x00000000 }, | ||
308 | { 0x00009988, 0x00000000 }, | ||
309 | { 0x0000998c, 0x00000000 }, | ||
310 | { 0x00009990, 0x00000000 }, | ||
311 | { 0x00009994, 0x00000000 }, | ||
312 | { 0x00009998, 0x00000000 }, | ||
313 | { 0x0000999c, 0x00000000 }, | ||
314 | { 0x000099a0, 0x00000000 }, | ||
315 | { 0x000099a4, 0x00000001 }, | ||
316 | { 0x000099a8, 0x001fff00 }, | ||
317 | { 0x000099ac, 0x00000000 }, | ||
318 | { 0x000099b0, 0x03051000 }, | ||
319 | { 0x000099dc, 0x00000000 }, | ||
320 | { 0x000099e0, 0x00000200 }, | ||
321 | { 0x000099e4, 0xaaaaaaaa }, | ||
322 | { 0x000099e8, 0x3c466478 }, | ||
323 | { 0x000099ec, 0x000000aa }, | ||
324 | { 0x000099fc, 0x00001042 }, | ||
325 | { 0x00009b00, 0x00000000 }, | ||
326 | { 0x00009b04, 0x00000001 }, | ||
327 | { 0x00009b08, 0x00000002 }, | ||
328 | { 0x00009b0c, 0x00000003 }, | ||
329 | { 0x00009b10, 0x00000004 }, | ||
330 | { 0x00009b14, 0x00000005 }, | ||
331 | { 0x00009b18, 0x00000008 }, | ||
332 | { 0x00009b1c, 0x00000009 }, | ||
333 | { 0x00009b20, 0x0000000a }, | ||
334 | { 0x00009b24, 0x0000000b }, | ||
335 | { 0x00009b28, 0x0000000c }, | ||
336 | { 0x00009b2c, 0x0000000d }, | ||
337 | { 0x00009b30, 0x00000010 }, | ||
338 | { 0x00009b34, 0x00000011 }, | ||
339 | { 0x00009b38, 0x00000012 }, | ||
340 | { 0x00009b3c, 0x00000013 }, | ||
341 | { 0x00009b40, 0x00000014 }, | ||
342 | { 0x00009b44, 0x00000015 }, | ||
343 | { 0x00009b48, 0x00000018 }, | ||
344 | { 0x00009b4c, 0x00000019 }, | ||
345 | { 0x00009b50, 0x0000001a }, | ||
346 | { 0x00009b54, 0x0000001b }, | ||
347 | { 0x00009b58, 0x0000001c }, | ||
348 | { 0x00009b5c, 0x0000001d }, | ||
349 | { 0x00009b60, 0x00000020 }, | ||
350 | { 0x00009b64, 0x00000021 }, | ||
351 | { 0x00009b68, 0x00000022 }, | ||
352 | { 0x00009b6c, 0x00000023 }, | ||
353 | { 0x00009b70, 0x00000024 }, | ||
354 | { 0x00009b74, 0x00000025 }, | ||
355 | { 0x00009b78, 0x00000028 }, | ||
356 | { 0x00009b7c, 0x00000029 }, | ||
357 | { 0x00009b80, 0x0000002a }, | ||
358 | { 0x00009b84, 0x0000002b }, | ||
359 | { 0x00009b88, 0x0000002c }, | ||
360 | { 0x00009b8c, 0x0000002d }, | ||
361 | { 0x00009b90, 0x00000030 }, | ||
362 | { 0x00009b94, 0x00000031 }, | ||
363 | { 0x00009b98, 0x00000032 }, | ||
364 | { 0x00009b9c, 0x00000033 }, | ||
365 | { 0x00009ba0, 0x00000034 }, | ||
366 | { 0x00009ba4, 0x00000035 }, | ||
367 | { 0x00009ba8, 0x00000035 }, | ||
368 | { 0x00009bac, 0x00000035 }, | ||
369 | { 0x00009bb0, 0x00000035 }, | ||
370 | { 0x00009bb4, 0x00000035 }, | ||
371 | { 0x00009bb8, 0x00000035 }, | ||
372 | { 0x00009bbc, 0x00000035 }, | ||
373 | { 0x00009bc0, 0x00000035 }, | ||
374 | { 0x00009bc4, 0x00000035 }, | ||
375 | { 0x00009bc8, 0x00000035 }, | ||
376 | { 0x00009bcc, 0x00000035 }, | ||
377 | { 0x00009bd0, 0x00000035 }, | ||
378 | { 0x00009bd4, 0x00000035 }, | ||
379 | { 0x00009bd8, 0x00000035 }, | ||
380 | { 0x00009bdc, 0x00000035 }, | ||
381 | { 0x00009be0, 0x00000035 }, | ||
382 | { 0x00009be4, 0x00000035 }, | ||
383 | { 0x00009be8, 0x00000035 }, | ||
384 | { 0x00009bec, 0x00000035 }, | ||
385 | { 0x00009bf0, 0x00000035 }, | ||
386 | { 0x00009bf4, 0x00000035 }, | ||
387 | { 0x00009bf8, 0x00000010 }, | ||
388 | { 0x00009bfc, 0x0000001a }, | ||
389 | { 0x0000a210, 0x40806333 }, | ||
390 | { 0x0000a214, 0x00106c10 }, | ||
391 | { 0x0000a218, 0x009c4060 }, | ||
392 | { 0x0000a220, 0x018830c6 }, | ||
393 | { 0x0000a224, 0x00000400 }, | ||
394 | { 0x0000a228, 0x00000bb5 }, | ||
395 | { 0x0000a22c, 0x00000011 }, | ||
396 | { 0x0000a234, 0x20202020 }, | ||
397 | { 0x0000a238, 0x20202020 }, | ||
398 | { 0x0000a23c, 0x13c889af }, | ||
399 | { 0x0000a240, 0x38490a20 }, | ||
400 | { 0x0000a244, 0x00007bb6 }, | ||
401 | { 0x0000a248, 0x0fff3ffc }, | ||
402 | { 0x0000a24c, 0x00000001 }, | ||
403 | { 0x0000a250, 0x0000a000 }, | ||
404 | { 0x0000a254, 0x00000000 }, | ||
405 | { 0x0000a258, 0x0cc75380 }, | ||
406 | { 0x0000a25c, 0x0f0f0f01 }, | ||
407 | { 0x0000a260, 0xdfa91f01 }, | ||
408 | { 0x0000a268, 0x00000000 }, | ||
409 | { 0x0000a26c, 0x0ebae9c6 }, | ||
410 | { 0x0000b26c, 0x0ebae9c6 }, | ||
411 | { 0x0000c26c, 0x0ebae9c6 }, | ||
412 | { 0x0000d270, 0x00820820 }, | ||
413 | { 0x0000a278, 0x1ce739ce }, | ||
414 | { 0x0000a27c, 0x051701ce }, | ||
415 | { 0x0000a338, 0x00000000 }, | ||
416 | { 0x0000a33c, 0x00000000 }, | ||
417 | { 0x0000a340, 0x00000000 }, | ||
418 | { 0x0000a344, 0x00000000 }, | ||
419 | { 0x0000a348, 0x3fffffff }, | ||
420 | { 0x0000a34c, 0x3fffffff }, | ||
421 | { 0x0000a350, 0x3fffffff }, | ||
422 | { 0x0000a354, 0x0003ffff }, | ||
423 | { 0x0000a358, 0x79a8aa1f }, | ||
424 | { 0x0000d35c, 0x07ffffef }, | ||
425 | { 0x0000d360, 0x0fffffe7 }, | ||
426 | { 0x0000d364, 0x17ffffe5 }, | ||
427 | { 0x0000d368, 0x1fffffe4 }, | ||
428 | { 0x0000d36c, 0x37ffffe3 }, | ||
429 | { 0x0000d370, 0x3fffffe3 }, | ||
430 | { 0x0000d374, 0x57ffffe3 }, | ||
431 | { 0x0000d378, 0x5fffffe2 }, | ||
432 | { 0x0000d37c, 0x7fffffe2 }, | ||
433 | { 0x0000d380, 0x7f3c7bba }, | ||
434 | { 0x0000d384, 0xf3307ff0 }, | ||
435 | { 0x0000a388, 0x08000000 }, | ||
436 | { 0x0000a38c, 0x20202020 }, | ||
437 | { 0x0000a390, 0x20202020 }, | ||
438 | { 0x0000a394, 0x1ce739ce }, | ||
439 | { 0x0000a398, 0x000001ce }, | ||
440 | { 0x0000a39c, 0x00000001 }, | ||
441 | { 0x0000a3a0, 0x00000000 }, | ||
442 | { 0x0000a3a4, 0x00000000 }, | ||
443 | { 0x0000a3a8, 0x00000000 }, | ||
444 | { 0x0000a3ac, 0x00000000 }, | ||
445 | { 0x0000a3b0, 0x00000000 }, | ||
446 | { 0x0000a3b4, 0x00000000 }, | ||
447 | { 0x0000a3b8, 0x00000000 }, | ||
448 | { 0x0000a3bc, 0x00000000 }, | ||
449 | { 0x0000a3c0, 0x00000000 }, | ||
450 | { 0x0000a3c4, 0x00000000 }, | ||
451 | { 0x0000a3c8, 0x00000246 }, | ||
452 | { 0x0000a3cc, 0x20202020 }, | ||
453 | { 0x0000a3d0, 0x20202020 }, | ||
454 | { 0x0000a3d4, 0x20202020 }, | ||
455 | { 0x0000a3dc, 0x1ce739ce }, | ||
456 | { 0x0000a3e0, 0x000001ce }, | ||
457 | }; | ||
458 | |||
459 | static const u32 ar5416Bank0[][2] = { | ||
460 | { 0x000098b0, 0x1e5795e5 }, | ||
461 | { 0x000098e0, 0x02008020 }, | ||
462 | }; | ||
463 | |||
464 | static const u32 ar5416BB_RfGain[][3] = { | ||
465 | { 0x00009a00, 0x00000000, 0x00000000 }, | ||
466 | { 0x00009a04, 0x00000040, 0x00000040 }, | ||
467 | { 0x00009a08, 0x00000080, 0x00000080 }, | ||
468 | { 0x00009a0c, 0x000001a1, 0x00000141 }, | ||
469 | { 0x00009a10, 0x000001e1, 0x00000181 }, | ||
470 | { 0x00009a14, 0x00000021, 0x000001c1 }, | ||
471 | { 0x00009a18, 0x00000061, 0x00000001 }, | ||
472 | { 0x00009a1c, 0x00000168, 0x00000041 }, | ||
473 | { 0x00009a20, 0x000001a8, 0x000001a8 }, | ||
474 | { 0x00009a24, 0x000001e8, 0x000001e8 }, | ||
475 | { 0x00009a28, 0x00000028, 0x00000028 }, | ||
476 | { 0x00009a2c, 0x00000068, 0x00000068 }, | ||
477 | { 0x00009a30, 0x00000189, 0x000000a8 }, | ||
478 | { 0x00009a34, 0x000001c9, 0x00000169 }, | ||
479 | { 0x00009a38, 0x00000009, 0x000001a9 }, | ||
480 | { 0x00009a3c, 0x00000049, 0x000001e9 }, | ||
481 | { 0x00009a40, 0x00000089, 0x00000029 }, | ||
482 | { 0x00009a44, 0x00000170, 0x00000069 }, | ||
483 | { 0x00009a48, 0x000001b0, 0x00000190 }, | ||
484 | { 0x00009a4c, 0x000001f0, 0x000001d0 }, | ||
485 | { 0x00009a50, 0x00000030, 0x00000010 }, | ||
486 | { 0x00009a54, 0x00000070, 0x00000050 }, | ||
487 | { 0x00009a58, 0x00000191, 0x00000090 }, | ||
488 | { 0x00009a5c, 0x000001d1, 0x00000151 }, | ||
489 | { 0x00009a60, 0x00000011, 0x00000191 }, | ||
490 | { 0x00009a64, 0x00000051, 0x000001d1 }, | ||
491 | { 0x00009a68, 0x00000091, 0x00000011 }, | ||
492 | { 0x00009a6c, 0x000001b8, 0x00000051 }, | ||
493 | { 0x00009a70, 0x000001f8, 0x00000198 }, | ||
494 | { 0x00009a74, 0x00000038, 0x000001d8 }, | ||
495 | { 0x00009a78, 0x00000078, 0x00000018 }, | ||
496 | { 0x00009a7c, 0x00000199, 0x00000058 }, | ||
497 | { 0x00009a80, 0x000001d9, 0x00000098 }, | ||
498 | { 0x00009a84, 0x00000019, 0x00000159 }, | ||
499 | { 0x00009a88, 0x00000059, 0x00000199 }, | ||
500 | { 0x00009a8c, 0x00000099, 0x000001d9 }, | ||
501 | { 0x00009a90, 0x000000d9, 0x00000019 }, | ||
502 | { 0x00009a94, 0x000000f9, 0x00000059 }, | ||
503 | { 0x00009a98, 0x000000f9, 0x00000099 }, | ||
504 | { 0x00009a9c, 0x000000f9, 0x000000d9 }, | ||
505 | { 0x00009aa0, 0x000000f9, 0x000000f9 }, | ||
506 | { 0x00009aa4, 0x000000f9, 0x000000f9 }, | ||
507 | { 0x00009aa8, 0x000000f9, 0x000000f9 }, | ||
508 | { 0x00009aac, 0x000000f9, 0x000000f9 }, | ||
509 | { 0x00009ab0, 0x000000f9, 0x000000f9 }, | ||
510 | { 0x00009ab4, 0x000000f9, 0x000000f9 }, | ||
511 | { 0x00009ab8, 0x000000f9, 0x000000f9 }, | ||
512 | { 0x00009abc, 0x000000f9, 0x000000f9 }, | ||
513 | { 0x00009ac0, 0x000000f9, 0x000000f9 }, | ||
514 | { 0x00009ac4, 0x000000f9, 0x000000f9 }, | ||
515 | { 0x00009ac8, 0x000000f9, 0x000000f9 }, | ||
516 | { 0x00009acc, 0x000000f9, 0x000000f9 }, | ||
517 | { 0x00009ad0, 0x000000f9, 0x000000f9 }, | ||
518 | { 0x00009ad4, 0x000000f9, 0x000000f9 }, | ||
519 | { 0x00009ad8, 0x000000f9, 0x000000f9 }, | ||
520 | { 0x00009adc, 0x000000f9, 0x000000f9 }, | ||
521 | { 0x00009ae0, 0x000000f9, 0x000000f9 }, | ||
522 | { 0x00009ae4, 0x000000f9, 0x000000f9 }, | ||
523 | { 0x00009ae8, 0x000000f9, 0x000000f9 }, | ||
524 | { 0x00009aec, 0x000000f9, 0x000000f9 }, | ||
525 | { 0x00009af0, 0x000000f9, 0x000000f9 }, | ||
526 | { 0x00009af4, 0x000000f9, 0x000000f9 }, | ||
527 | { 0x00009af8, 0x000000f9, 0x000000f9 }, | ||
528 | { 0x00009afc, 0x000000f9, 0x000000f9 }, | ||
529 | }; | ||
530 | |||
531 | static const u32 ar5416Bank1[][2] = { | ||
532 | { 0x000098b0, 0x02108421 }, | ||
533 | { 0x000098ec, 0x00000008 }, | ||
534 | }; | ||
535 | |||
536 | static const u32 ar5416Bank2[][2] = { | ||
537 | { 0x000098b0, 0x0e73ff17 }, | ||
538 | { 0x000098e0, 0x00000420 }, | ||
539 | }; | ||
540 | |||
541 | static const u32 ar5416Bank3[][3] = { | ||
542 | { 0x000098f0, 0x01400018, 0x01c00018 }, | ||
543 | }; | ||
544 | |||
545 | static const u32 ar5416Bank6[][3] = { | ||
546 | |||
547 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
548 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
549 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
550 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
551 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
552 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
553 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
554 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
555 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
556 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
557 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
558 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
559 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
560 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
561 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
562 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
563 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
564 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
565 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
566 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
567 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
568 | { 0x0000989c, 0x004210a2, 0x004210a2 }, | ||
569 | { 0x0000989c, 0x0014008f, 0x0014008f }, | ||
570 | { 0x0000989c, 0x00c40003, 0x00c40003 }, | ||
571 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
572 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
573 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
574 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
575 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
576 | { 0x0000989c, 0x000000f1, 0x000000f1 }, | ||
577 | { 0x0000989c, 0x00002081, 0x00002081 }, | ||
578 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
579 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
580 | }; | ||
581 | |||
582 | static const u32 ar5416Bank6TPC[][3] = { | ||
583 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
584 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
585 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
586 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
587 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
588 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
589 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
590 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
591 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
592 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
593 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
594 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
595 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
596 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
597 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
598 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
599 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
600 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
601 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
602 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
603 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
604 | { 0x0000989c, 0x00423022, 0x00423022 }, | ||
605 | { 0x0000989c, 0x201400df, 0x201400df }, | ||
606 | { 0x0000989c, 0x00c40002, 0x00c40002 }, | ||
607 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
608 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
609 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
610 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
611 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
612 | { 0x0000989c, 0x000000e1, 0x000000e1 }, | ||
613 | { 0x0000989c, 0x00007081, 0x00007081 }, | ||
614 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
615 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
616 | }; | ||
617 | |||
618 | static const u32 ar5416Bank7[][2] = { | ||
619 | { 0x0000989c, 0x00000500 }, | ||
620 | { 0x0000989c, 0x00000800 }, | ||
621 | { 0x000098cc, 0x0000000e }, | ||
622 | }; | ||
623 | |||
624 | static const u32 ar5416Addac[][2] = { | ||
625 | {0x0000989c, 0x00000000 }, | ||
626 | {0x0000989c, 0x00000003 }, | ||
627 | {0x0000989c, 0x00000000 }, | ||
628 | {0x0000989c, 0x0000000c }, | ||
629 | {0x0000989c, 0x00000000 }, | ||
630 | {0x0000989c, 0x00000030 }, | ||
631 | {0x0000989c, 0x00000000 }, | ||
632 | {0x0000989c, 0x00000000 }, | ||
633 | {0x0000989c, 0x00000000 }, | ||
634 | {0x0000989c, 0x00000000 }, | ||
635 | {0x0000989c, 0x00000000 }, | ||
636 | {0x0000989c, 0x00000000 }, | ||
637 | {0x0000989c, 0x00000000 }, | ||
638 | {0x0000989c, 0x00000000 }, | ||
639 | {0x0000989c, 0x00000000 }, | ||
640 | {0x0000989c, 0x00000000 }, | ||
641 | {0x0000989c, 0x00000000 }, | ||
642 | {0x0000989c, 0x00000000 }, | ||
643 | {0x0000989c, 0x00000060 }, | ||
644 | {0x0000989c, 0x00000000 }, | ||
645 | {0x0000989c, 0x00000000 }, | ||
646 | {0x0000989c, 0x00000000 }, | ||
647 | {0x0000989c, 0x00000000 }, | ||
648 | {0x0000989c, 0x00000000 }, | ||
649 | {0x0000989c, 0x00000000 }, | ||
650 | {0x0000989c, 0x00000000 }, | ||
651 | {0x0000989c, 0x00000000 }, | ||
652 | {0x0000989c, 0x00000000 }, | ||
653 | {0x0000989c, 0x00000000 }, | ||
654 | {0x0000989c, 0x00000000 }, | ||
655 | {0x0000989c, 0x00000000 }, | ||
656 | {0x0000989c, 0x00000058 }, | ||
657 | {0x0000989c, 0x00000000 }, | ||
658 | {0x0000989c, 0x00000000 }, | ||
659 | {0x0000989c, 0x00000000 }, | ||
660 | {0x0000989c, 0x00000000 }, | ||
661 | {0x000098cc, 0x00000000 }, | ||
662 | }; | ||
663 | |||
664 | static const u32 ar5416Modes_9100[][6] = { | ||
665 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | ||
666 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | ||
667 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | ||
668 | { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, | ||
669 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, | ||
670 | { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf }, | ||
671 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, | ||
672 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, | ||
673 | { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
674 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, | ||
675 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
676 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, | ||
677 | { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 }, | ||
678 | { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
679 | { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
680 | { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
681 | { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 }, | ||
682 | { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e }, | ||
683 | { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e }, | ||
684 | { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 }, | ||
685 | { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, | ||
686 | { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 }, | ||
687 | { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 }, | ||
688 | { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 }, | ||
689 | { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, | ||
690 | { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d }, | ||
691 | { 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 }, | ||
692 | { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 }, | ||
693 | { 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e }, | ||
694 | { 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff }, | ||
695 | #ifdef TB243 | ||
696 | { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 }, | ||
697 | { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 }, | ||
698 | { 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 }, | ||
699 | { 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 }, | ||
700 | #else | ||
701 | { 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 }, | ||
702 | { 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 }, | ||
703 | { 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 }, | ||
704 | { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 }, | ||
705 | #endif | ||
706 | { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 }, | ||
707 | { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be }, | ||
708 | { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, | ||
709 | { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 }, | ||
710 | { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, | ||
711 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, | ||
712 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
713 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
714 | { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 }, | ||
715 | { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 }, | ||
716 | { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
717 | { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
718 | { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
719 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | ||
720 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | ||
721 | { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa }, | ||
722 | { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 }, | ||
723 | { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 }, | ||
724 | { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 }, | ||
725 | { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b }, | ||
726 | { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b }, | ||
727 | { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a }, | ||
728 | { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf }, | ||
729 | { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f }, | ||
730 | { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f }, | ||
731 | { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f }, | ||
732 | { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 }, | ||
733 | { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
734 | { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
735 | { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
736 | }; | ||
737 | |||
738 | static const u32 ar5416Common_9100[][2] = { | ||
739 | { 0x0000000c, 0x00000000 }, | ||
740 | { 0x00000030, 0x00020015 }, | ||
741 | { 0x00000034, 0x00000005 }, | ||
742 | { 0x00000040, 0x00000000 }, | ||
743 | { 0x00000044, 0x00000008 }, | ||
744 | { 0x00000048, 0x00000008 }, | ||
745 | { 0x0000004c, 0x00000010 }, | ||
746 | { 0x00000050, 0x00000000 }, | ||
747 | { 0x00000054, 0x0000001f }, | ||
748 | { 0x00000800, 0x00000000 }, | ||
749 | { 0x00000804, 0x00000000 }, | ||
750 | { 0x00000808, 0x00000000 }, | ||
751 | { 0x0000080c, 0x00000000 }, | ||
752 | { 0x00000810, 0x00000000 }, | ||
753 | { 0x00000814, 0x00000000 }, | ||
754 | { 0x00000818, 0x00000000 }, | ||
755 | { 0x0000081c, 0x00000000 }, | ||
756 | { 0x00000820, 0x00000000 }, | ||
757 | { 0x00000824, 0x00000000 }, | ||
758 | { 0x00001040, 0x002ffc0f }, | ||
759 | { 0x00001044, 0x002ffc0f }, | ||
760 | { 0x00001048, 0x002ffc0f }, | ||
761 | { 0x0000104c, 0x002ffc0f }, | ||
762 | { 0x00001050, 0x002ffc0f }, | ||
763 | { 0x00001054, 0x002ffc0f }, | ||
764 | { 0x00001058, 0x002ffc0f }, | ||
765 | { 0x0000105c, 0x002ffc0f }, | ||
766 | { 0x00001060, 0x002ffc0f }, | ||
767 | { 0x00001064, 0x002ffc0f }, | ||
768 | { 0x00001230, 0x00000000 }, | ||
769 | { 0x00001270, 0x00000000 }, | ||
770 | { 0x00001038, 0x00000000 }, | ||
771 | { 0x00001078, 0x00000000 }, | ||
772 | { 0x000010b8, 0x00000000 }, | ||
773 | { 0x000010f8, 0x00000000 }, | ||
774 | { 0x00001138, 0x00000000 }, | ||
775 | { 0x00001178, 0x00000000 }, | ||
776 | { 0x000011b8, 0x00000000 }, | ||
777 | { 0x000011f8, 0x00000000 }, | ||
778 | { 0x00001238, 0x00000000 }, | ||
779 | { 0x00001278, 0x00000000 }, | ||
780 | { 0x000012b8, 0x00000000 }, | ||
781 | { 0x000012f8, 0x00000000 }, | ||
782 | { 0x00001338, 0x00000000 }, | ||
783 | { 0x00001378, 0x00000000 }, | ||
784 | { 0x000013b8, 0x00000000 }, | ||
785 | { 0x000013f8, 0x00000000 }, | ||
786 | { 0x00001438, 0x00000000 }, | ||
787 | { 0x00001478, 0x00000000 }, | ||
788 | { 0x000014b8, 0x00000000 }, | ||
789 | { 0x000014f8, 0x00000000 }, | ||
790 | { 0x00001538, 0x00000000 }, | ||
791 | { 0x00001578, 0x00000000 }, | ||
792 | { 0x000015b8, 0x00000000 }, | ||
793 | { 0x000015f8, 0x00000000 }, | ||
794 | { 0x00001638, 0x00000000 }, | ||
795 | { 0x00001678, 0x00000000 }, | ||
796 | { 0x000016b8, 0x00000000 }, | ||
797 | { 0x000016f8, 0x00000000 }, | ||
798 | { 0x00001738, 0x00000000 }, | ||
799 | { 0x00001778, 0x00000000 }, | ||
800 | { 0x000017b8, 0x00000000 }, | ||
801 | { 0x000017f8, 0x00000000 }, | ||
802 | { 0x0000103c, 0x00000000 }, | ||
803 | { 0x0000107c, 0x00000000 }, | ||
804 | { 0x000010bc, 0x00000000 }, | ||
805 | { 0x000010fc, 0x00000000 }, | ||
806 | { 0x0000113c, 0x00000000 }, | ||
807 | { 0x0000117c, 0x00000000 }, | ||
808 | { 0x000011bc, 0x00000000 }, | ||
809 | { 0x000011fc, 0x00000000 }, | ||
810 | { 0x0000123c, 0x00000000 }, | ||
811 | { 0x0000127c, 0x00000000 }, | ||
812 | { 0x000012bc, 0x00000000 }, | ||
813 | { 0x000012fc, 0x00000000 }, | ||
814 | { 0x0000133c, 0x00000000 }, | ||
815 | { 0x0000137c, 0x00000000 }, | ||
816 | { 0x000013bc, 0x00000000 }, | ||
817 | { 0x000013fc, 0x00000000 }, | ||
818 | { 0x0000143c, 0x00000000 }, | ||
819 | { 0x0000147c, 0x00000000 }, | ||
820 | { 0x00020010, 0x00000003 }, | ||
821 | { 0x00020038, 0x000004c2 }, | ||
822 | { 0x00008004, 0x00000000 }, | ||
823 | { 0x00008008, 0x00000000 }, | ||
824 | { 0x0000800c, 0x00000000 }, | ||
825 | { 0x00008018, 0x00000700 }, | ||
826 | { 0x00008020, 0x00000000 }, | ||
827 | { 0x00008038, 0x00000000 }, | ||
828 | { 0x0000803c, 0x00000000 }, | ||
829 | { 0x00008048, 0x40000000 }, | ||
830 | { 0x00008054, 0x00004000 }, | ||
831 | { 0x00008058, 0x00000000 }, | ||
832 | { 0x0000805c, 0x000fc78f }, | ||
833 | { 0x00008060, 0x0000000f }, | ||
834 | { 0x00008064, 0x00000000 }, | ||
835 | { 0x000080c0, 0x2a82301a }, | ||
836 | { 0x000080c4, 0x05dc01e0 }, | ||
837 | { 0x000080c8, 0x1f402710 }, | ||
838 | { 0x000080cc, 0x01f40000 }, | ||
839 | { 0x000080d0, 0x00001e00 }, | ||
840 | { 0x000080d4, 0x00000000 }, | ||
841 | { 0x000080d8, 0x00400000 }, | ||
842 | { 0x000080e0, 0xffffffff }, | ||
843 | { 0x000080e4, 0x0000ffff }, | ||
844 | { 0x000080e8, 0x003f3f3f }, | ||
845 | { 0x000080ec, 0x00000000 }, | ||
846 | { 0x000080f0, 0x00000000 }, | ||
847 | { 0x000080f4, 0x00000000 }, | ||
848 | { 0x000080f8, 0x00000000 }, | ||
849 | { 0x000080fc, 0x00020000 }, | ||
850 | { 0x00008100, 0x00020000 }, | ||
851 | { 0x00008104, 0x00000001 }, | ||
852 | { 0x00008108, 0x00000052 }, | ||
853 | { 0x0000810c, 0x00000000 }, | ||
854 | { 0x00008110, 0x00000168 }, | ||
855 | { 0x00008118, 0x000100aa }, | ||
856 | { 0x0000811c, 0x00003210 }, | ||
857 | { 0x00008120, 0x08f04800 }, | ||
858 | { 0x00008124, 0x00000000 }, | ||
859 | { 0x00008128, 0x00000000 }, | ||
860 | { 0x0000812c, 0x00000000 }, | ||
861 | { 0x00008130, 0x00000000 }, | ||
862 | { 0x00008134, 0x00000000 }, | ||
863 | { 0x00008138, 0x00000000 }, | ||
864 | { 0x0000813c, 0x00000000 }, | ||
865 | { 0x00008144, 0x00000000 }, | ||
866 | { 0x00008168, 0x00000000 }, | ||
867 | { 0x0000816c, 0x00000000 }, | ||
868 | { 0x00008170, 0x32143320 }, | ||
869 | { 0x00008174, 0xfaa4fa50 }, | ||
870 | { 0x00008178, 0x00000100 }, | ||
871 | { 0x0000817c, 0x00000000 }, | ||
872 | { 0x000081c4, 0x00000000 }, | ||
873 | { 0x000081d0, 0x00003210 }, | ||
874 | { 0x000081ec, 0x00000000 }, | ||
875 | { 0x000081f0, 0x00000000 }, | ||
876 | { 0x000081f4, 0x00000000 }, | ||
877 | { 0x000081f8, 0x00000000 }, | ||
878 | { 0x000081fc, 0x00000000 }, | ||
879 | { 0x00008200, 0x00000000 }, | ||
880 | { 0x00008204, 0x00000000 }, | ||
881 | { 0x00008208, 0x00000000 }, | ||
882 | { 0x0000820c, 0x00000000 }, | ||
883 | { 0x00008210, 0x00000000 }, | ||
884 | { 0x00008214, 0x00000000 }, | ||
885 | { 0x00008218, 0x00000000 }, | ||
886 | { 0x0000821c, 0x00000000 }, | ||
887 | { 0x00008220, 0x00000000 }, | ||
888 | { 0x00008224, 0x00000000 }, | ||
889 | { 0x00008228, 0x00000000 }, | ||
890 | { 0x0000822c, 0x00000000 }, | ||
891 | { 0x00008230, 0x00000000 }, | ||
892 | { 0x00008234, 0x00000000 }, | ||
893 | { 0x00008238, 0x00000000 }, | ||
894 | { 0x0000823c, 0x00000000 }, | ||
895 | { 0x00008240, 0x00100000 }, | ||
896 | { 0x00008244, 0x0010f400 }, | ||
897 | { 0x00008248, 0x00000100 }, | ||
898 | { 0x0000824c, 0x0001e800 }, | ||
899 | { 0x00008250, 0x00000000 }, | ||
900 | { 0x00008254, 0x00000000 }, | ||
901 | { 0x00008258, 0x00000000 }, | ||
902 | { 0x0000825c, 0x400000ff }, | ||
903 | { 0x00008260, 0x00080922 }, | ||
904 | { 0x00008270, 0x00000000 }, | ||
905 | { 0x00008274, 0x40000000 }, | ||
906 | { 0x00008278, 0x003e4180 }, | ||
907 | { 0x0000827c, 0x00000000 }, | ||
908 | { 0x00008284, 0x0000002c }, | ||
909 | { 0x00008288, 0x0000002c }, | ||
910 | { 0x0000828c, 0x00000000 }, | ||
911 | { 0x00008294, 0x00000000 }, | ||
912 | { 0x00008298, 0x00000000 }, | ||
913 | { 0x00008300, 0x00000000 }, | ||
914 | { 0x00008304, 0x00000000 }, | ||
915 | { 0x00008308, 0x00000000 }, | ||
916 | { 0x0000830c, 0x00000000 }, | ||
917 | { 0x00008310, 0x00000000 }, | ||
918 | { 0x00008314, 0x00000000 }, | ||
919 | { 0x00008318, 0x00000000 }, | ||
920 | { 0x00008328, 0x00000000 }, | ||
921 | { 0x0000832c, 0x00000007 }, | ||
922 | { 0x00008330, 0x00000302 }, | ||
923 | { 0x00008334, 0x00000e00 }, | ||
924 | { 0x00008338, 0x00000000 }, | ||
925 | { 0x0000833c, 0x00000000 }, | ||
926 | { 0x00008340, 0x000107ff }, | ||
927 | { 0x00009808, 0x00000000 }, | ||
928 | { 0x0000980c, 0xad848e19 }, | ||
929 | { 0x00009810, 0x7d14e000 }, | ||
930 | { 0x00009814, 0x9c0a9f6b }, | ||
931 | { 0x0000981c, 0x00000000 }, | ||
932 | { 0x0000982c, 0x0000a000 }, | ||
933 | { 0x00009830, 0x00000000 }, | ||
934 | { 0x0000983c, 0x00200400 }, | ||
935 | { 0x00009840, 0x206a01ae }, | ||
936 | { 0x0000984c, 0x1284233c }, | ||
937 | { 0x00009854, 0x00000859 }, | ||
938 | { 0x00009900, 0x00000000 }, | ||
939 | { 0x00009904, 0x00000000 }, | ||
940 | { 0x00009908, 0x00000000 }, | ||
941 | { 0x0000990c, 0x00000000 }, | ||
942 | { 0x0000991c, 0x10000fff }, | ||
943 | { 0x00009920, 0x05100000 }, | ||
944 | { 0x0000a920, 0x05100000 }, | ||
945 | { 0x0000b920, 0x05100000 }, | ||
946 | { 0x00009928, 0x00000001 }, | ||
947 | { 0x0000992c, 0x00000004 }, | ||
948 | { 0x00009934, 0x1e1f2022 }, | ||
949 | { 0x00009938, 0x0a0b0c0d }, | ||
950 | { 0x0000993c, 0x00000000 }, | ||
951 | { 0x00009948, 0x9280b212 }, | ||
952 | { 0x0000994c, 0x00020028 }, | ||
953 | { 0x0000c95c, 0x004b6a8e }, | ||
954 | { 0x0000c968, 0x000003ce }, | ||
955 | { 0x00009970, 0x190fb515 }, | ||
956 | { 0x00009974, 0x00000000 }, | ||
957 | { 0x00009978, 0x00000001 }, | ||
958 | { 0x0000997c, 0x00000000 }, | ||
959 | { 0x00009980, 0x00000000 }, | ||
960 | { 0x00009984, 0x00000000 }, | ||
961 | { 0x00009988, 0x00000000 }, | ||
962 | { 0x0000998c, 0x00000000 }, | ||
963 | { 0x00009990, 0x00000000 }, | ||
964 | { 0x00009994, 0x00000000 }, | ||
965 | { 0x00009998, 0x00000000 }, | ||
966 | { 0x0000999c, 0x00000000 }, | ||
967 | { 0x000099a0, 0x00000000 }, | ||
968 | { 0x000099a4, 0x00000001 }, | ||
969 | { 0x000099a8, 0x201fff00 }, | ||
970 | { 0x000099ac, 0x006f0000 }, | ||
971 | { 0x000099b0, 0x03051000 }, | ||
972 | { 0x000099dc, 0x00000000 }, | ||
973 | { 0x000099e0, 0x00000200 }, | ||
974 | { 0x000099e4, 0xaaaaaaaa }, | ||
975 | { 0x000099e8, 0x3c466478 }, | ||
976 | { 0x000099ec, 0x0cc80caa }, | ||
977 | { 0x000099fc, 0x00001042 }, | ||
978 | { 0x00009b00, 0x00000000 }, | ||
979 | { 0x00009b04, 0x00000001 }, | ||
980 | { 0x00009b08, 0x00000002 }, | ||
981 | { 0x00009b0c, 0x00000003 }, | ||
982 | { 0x00009b10, 0x00000004 }, | ||
983 | { 0x00009b14, 0x00000005 }, | ||
984 | { 0x00009b18, 0x00000008 }, | ||
985 | { 0x00009b1c, 0x00000009 }, | ||
986 | { 0x00009b20, 0x0000000a }, | ||
987 | { 0x00009b24, 0x0000000b }, | ||
988 | { 0x00009b28, 0x0000000c }, | ||
989 | { 0x00009b2c, 0x0000000d }, | ||
990 | { 0x00009b30, 0x00000010 }, | ||
991 | { 0x00009b34, 0x00000011 }, | ||
992 | { 0x00009b38, 0x00000012 }, | ||
993 | { 0x00009b3c, 0x00000013 }, | ||
994 | { 0x00009b40, 0x00000014 }, | ||
995 | { 0x00009b44, 0x00000015 }, | ||
996 | { 0x00009b48, 0x00000018 }, | ||
997 | { 0x00009b4c, 0x00000019 }, | ||
998 | { 0x00009b50, 0x0000001a }, | ||
999 | { 0x00009b54, 0x0000001b }, | ||
1000 | { 0x00009b58, 0x0000001c }, | ||
1001 | { 0x00009b5c, 0x0000001d }, | ||
1002 | { 0x00009b60, 0x00000020 }, | ||
1003 | { 0x00009b64, 0x00000021 }, | ||
1004 | { 0x00009b68, 0x00000022 }, | ||
1005 | { 0x00009b6c, 0x00000023 }, | ||
1006 | { 0x00009b70, 0x00000024 }, | ||
1007 | { 0x00009b74, 0x00000025 }, | ||
1008 | { 0x00009b78, 0x00000028 }, | ||
1009 | { 0x00009b7c, 0x00000029 }, | ||
1010 | { 0x00009b80, 0x0000002a }, | ||
1011 | { 0x00009b84, 0x0000002b }, | ||
1012 | { 0x00009b88, 0x0000002c }, | ||
1013 | { 0x00009b8c, 0x0000002d }, | ||
1014 | { 0x00009b90, 0x00000030 }, | ||
1015 | { 0x00009b94, 0x00000031 }, | ||
1016 | { 0x00009b98, 0x00000032 }, | ||
1017 | { 0x00009b9c, 0x00000033 }, | ||
1018 | { 0x00009ba0, 0x00000034 }, | ||
1019 | { 0x00009ba4, 0x00000035 }, | ||
1020 | { 0x00009ba8, 0x00000035 }, | ||
1021 | { 0x00009bac, 0x00000035 }, | ||
1022 | { 0x00009bb0, 0x00000035 }, | ||
1023 | { 0x00009bb4, 0x00000035 }, | ||
1024 | { 0x00009bb8, 0x00000035 }, | ||
1025 | { 0x00009bbc, 0x00000035 }, | ||
1026 | { 0x00009bc0, 0x00000035 }, | ||
1027 | { 0x00009bc4, 0x00000035 }, | ||
1028 | { 0x00009bc8, 0x00000035 }, | ||
1029 | { 0x00009bcc, 0x00000035 }, | ||
1030 | { 0x00009bd0, 0x00000035 }, | ||
1031 | { 0x00009bd4, 0x00000035 }, | ||
1032 | { 0x00009bd8, 0x00000035 }, | ||
1033 | { 0x00009bdc, 0x00000035 }, | ||
1034 | { 0x00009be0, 0x00000035 }, | ||
1035 | { 0x00009be4, 0x00000035 }, | ||
1036 | { 0x00009be8, 0x00000035 }, | ||
1037 | { 0x00009bec, 0x00000035 }, | ||
1038 | { 0x00009bf0, 0x00000035 }, | ||
1039 | { 0x00009bf4, 0x00000035 }, | ||
1040 | { 0x00009bf8, 0x00000010 }, | ||
1041 | { 0x00009bfc, 0x0000001a }, | ||
1042 | { 0x0000a210, 0x40806333 }, | ||
1043 | { 0x0000a214, 0x00106c10 }, | ||
1044 | { 0x0000a218, 0x009c4060 }, | ||
1045 | { 0x0000a220, 0x018830c6 }, | ||
1046 | { 0x0000a224, 0x00000400 }, | ||
1047 | { 0x0000a228, 0x001a0bb5 }, | ||
1048 | { 0x0000a22c, 0x00000000 }, | ||
1049 | { 0x0000a234, 0x20202020 }, | ||
1050 | { 0x0000a238, 0x20202020 }, | ||
1051 | { 0x0000a23c, 0x13c889ae }, | ||
1052 | { 0x0000a240, 0x38490a20 }, | ||
1053 | { 0x0000a244, 0x00007bb6 }, | ||
1054 | { 0x0000a248, 0x0fff3ffc }, | ||
1055 | { 0x0000a24c, 0x00000001 }, | ||
1056 | { 0x0000a250, 0x0000a000 }, | ||
1057 | { 0x0000a254, 0x00000000 }, | ||
1058 | { 0x0000a258, 0x0cc75380 }, | ||
1059 | { 0x0000a25c, 0x0f0f0f01 }, | ||
1060 | { 0x0000a260, 0xdfa91f01 }, | ||
1061 | { 0x0000a268, 0x00000001 }, | ||
1062 | { 0x0000a26c, 0x0ebae9c6 }, | ||
1063 | { 0x0000b26c, 0x0ebae9c6 }, | ||
1064 | { 0x0000c26c, 0x0ebae9c6 }, | ||
1065 | { 0x0000d270, 0x00820820 }, | ||
1066 | { 0x0000a278, 0x1ce739ce }, | ||
1067 | { 0x0000a27c, 0x050701ce }, | ||
1068 | { 0x0000a338, 0x00000000 }, | ||
1069 | { 0x0000a33c, 0x00000000 }, | ||
1070 | { 0x0000a340, 0x00000000 }, | ||
1071 | { 0x0000a344, 0x00000000 }, | ||
1072 | { 0x0000a348, 0x3fffffff }, | ||
1073 | { 0x0000a34c, 0x3fffffff }, | ||
1074 | { 0x0000a350, 0x3fffffff }, | ||
1075 | { 0x0000a354, 0x0003ffff }, | ||
1076 | { 0x0000a358, 0x79a8aa33 }, | ||
1077 | { 0x0000d35c, 0x07ffffef }, | ||
1078 | { 0x0000d360, 0x0fffffe7 }, | ||
1079 | { 0x0000d364, 0x17ffffe5 }, | ||
1080 | { 0x0000d368, 0x1fffffe4 }, | ||
1081 | { 0x0000d36c, 0x37ffffe3 }, | ||
1082 | { 0x0000d370, 0x3fffffe3 }, | ||
1083 | { 0x0000d374, 0x57ffffe3 }, | ||
1084 | { 0x0000d378, 0x5fffffe2 }, | ||
1085 | { 0x0000d37c, 0x7fffffe2 }, | ||
1086 | { 0x0000d380, 0x7f3c7bba }, | ||
1087 | { 0x0000d384, 0xf3307ff0 }, | ||
1088 | { 0x0000a388, 0x0c000000 }, | ||
1089 | { 0x0000a38c, 0x20202020 }, | ||
1090 | { 0x0000a390, 0x20202020 }, | ||
1091 | { 0x0000a394, 0x1ce739ce }, | ||
1092 | { 0x0000a398, 0x000001ce }, | ||
1093 | { 0x0000a39c, 0x00000001 }, | ||
1094 | { 0x0000a3a0, 0x00000000 }, | ||
1095 | { 0x0000a3a4, 0x00000000 }, | ||
1096 | { 0x0000a3a8, 0x00000000 }, | ||
1097 | { 0x0000a3ac, 0x00000000 }, | ||
1098 | { 0x0000a3b0, 0x00000000 }, | ||
1099 | { 0x0000a3b4, 0x00000000 }, | ||
1100 | { 0x0000a3b8, 0x00000000 }, | ||
1101 | { 0x0000a3bc, 0x00000000 }, | ||
1102 | { 0x0000a3c0, 0x00000000 }, | ||
1103 | { 0x0000a3c4, 0x00000000 }, | ||
1104 | { 0x0000a3c8, 0x00000246 }, | ||
1105 | { 0x0000a3cc, 0x20202020 }, | ||
1106 | { 0x0000a3d0, 0x20202020 }, | ||
1107 | { 0x0000a3d4, 0x20202020 }, | ||
1108 | { 0x0000a3dc, 0x1ce739ce }, | ||
1109 | { 0x0000a3e0, 0x000001ce }, | ||
1110 | }; | ||
1111 | |||
1112 | static const u32 ar5416Bank0_9100[][2] = { | ||
1113 | { 0x000098b0, 0x1e5795e5 }, | ||
1114 | { 0x000098e0, 0x02008020 }, | ||
1115 | }; | ||
1116 | |||
1117 | static const u32 ar5416BB_RfGain_9100[][3] = { | ||
1118 | { 0x00009a00, 0x00000000, 0x00000000 }, | ||
1119 | { 0x00009a04, 0x00000040, 0x00000040 }, | ||
1120 | { 0x00009a08, 0x00000080, 0x00000080 }, | ||
1121 | { 0x00009a0c, 0x000001a1, 0x00000141 }, | ||
1122 | { 0x00009a10, 0x000001e1, 0x00000181 }, | ||
1123 | { 0x00009a14, 0x00000021, 0x000001c1 }, | ||
1124 | { 0x00009a18, 0x00000061, 0x00000001 }, | ||
1125 | { 0x00009a1c, 0x00000168, 0x00000041 }, | ||
1126 | { 0x00009a20, 0x000001a8, 0x000001a8 }, | ||
1127 | { 0x00009a24, 0x000001e8, 0x000001e8 }, | ||
1128 | { 0x00009a28, 0x00000028, 0x00000028 }, | ||
1129 | { 0x00009a2c, 0x00000068, 0x00000068 }, | ||
1130 | { 0x00009a30, 0x00000189, 0x000000a8 }, | ||
1131 | { 0x00009a34, 0x000001c9, 0x00000169 }, | ||
1132 | { 0x00009a38, 0x00000009, 0x000001a9 }, | ||
1133 | { 0x00009a3c, 0x00000049, 0x000001e9 }, | ||
1134 | { 0x00009a40, 0x00000089, 0x00000029 }, | ||
1135 | { 0x00009a44, 0x00000170, 0x00000069 }, | ||
1136 | { 0x00009a48, 0x000001b0, 0x00000190 }, | ||
1137 | { 0x00009a4c, 0x000001f0, 0x000001d0 }, | ||
1138 | { 0x00009a50, 0x00000030, 0x00000010 }, | ||
1139 | { 0x00009a54, 0x00000070, 0x00000050 }, | ||
1140 | { 0x00009a58, 0x00000191, 0x00000090 }, | ||
1141 | { 0x00009a5c, 0x000001d1, 0x00000151 }, | ||
1142 | { 0x00009a60, 0x00000011, 0x00000191 }, | ||
1143 | { 0x00009a64, 0x00000051, 0x000001d1 }, | ||
1144 | { 0x00009a68, 0x00000091, 0x00000011 }, | ||
1145 | { 0x00009a6c, 0x000001b8, 0x00000051 }, | ||
1146 | { 0x00009a70, 0x000001f8, 0x00000198 }, | ||
1147 | { 0x00009a74, 0x00000038, 0x000001d8 }, | ||
1148 | { 0x00009a78, 0x00000078, 0x00000018 }, | ||
1149 | { 0x00009a7c, 0x00000199, 0x00000058 }, | ||
1150 | { 0x00009a80, 0x000001d9, 0x00000098 }, | ||
1151 | { 0x00009a84, 0x00000019, 0x00000159 }, | ||
1152 | { 0x00009a88, 0x00000059, 0x00000199 }, | ||
1153 | { 0x00009a8c, 0x00000099, 0x000001d9 }, | ||
1154 | { 0x00009a90, 0x000000d9, 0x00000019 }, | ||
1155 | { 0x00009a94, 0x000000f9, 0x00000059 }, | ||
1156 | { 0x00009a98, 0x000000f9, 0x00000099 }, | ||
1157 | { 0x00009a9c, 0x000000f9, 0x000000d9 }, | ||
1158 | { 0x00009aa0, 0x000000f9, 0x000000f9 }, | ||
1159 | { 0x00009aa4, 0x000000f9, 0x000000f9 }, | ||
1160 | { 0x00009aa8, 0x000000f9, 0x000000f9 }, | ||
1161 | { 0x00009aac, 0x000000f9, 0x000000f9 }, | ||
1162 | { 0x00009ab0, 0x000000f9, 0x000000f9 }, | ||
1163 | { 0x00009ab4, 0x000000f9, 0x000000f9 }, | ||
1164 | { 0x00009ab8, 0x000000f9, 0x000000f9 }, | ||
1165 | { 0x00009abc, 0x000000f9, 0x000000f9 }, | ||
1166 | { 0x00009ac0, 0x000000f9, 0x000000f9 }, | ||
1167 | { 0x00009ac4, 0x000000f9, 0x000000f9 }, | ||
1168 | { 0x00009ac8, 0x000000f9, 0x000000f9 }, | ||
1169 | { 0x00009acc, 0x000000f9, 0x000000f9 }, | ||
1170 | { 0x00009ad0, 0x000000f9, 0x000000f9 }, | ||
1171 | { 0x00009ad4, 0x000000f9, 0x000000f9 }, | ||
1172 | { 0x00009ad8, 0x000000f9, 0x000000f9 }, | ||
1173 | { 0x00009adc, 0x000000f9, 0x000000f9 }, | ||
1174 | { 0x00009ae0, 0x000000f9, 0x000000f9 }, | ||
1175 | { 0x00009ae4, 0x000000f9, 0x000000f9 }, | ||
1176 | { 0x00009ae8, 0x000000f9, 0x000000f9 }, | ||
1177 | { 0x00009aec, 0x000000f9, 0x000000f9 }, | ||
1178 | { 0x00009af0, 0x000000f9, 0x000000f9 }, | ||
1179 | { 0x00009af4, 0x000000f9, 0x000000f9 }, | ||
1180 | { 0x00009af8, 0x000000f9, 0x000000f9 }, | ||
1181 | { 0x00009afc, 0x000000f9, 0x000000f9 }, | ||
1182 | }; | ||
1183 | |||
1184 | static const u32 ar5416Bank1_9100[][2] = { | ||
1185 | { 0x000098b0, 0x02108421}, | ||
1186 | { 0x000098ec, 0x00000008}, | ||
1187 | }; | ||
1188 | |||
1189 | static const u32 ar5416Bank2_9100[][2] = { | ||
1190 | { 0x000098b0, 0x0e73ff17}, | ||
1191 | { 0x000098e0, 0x00000420}, | ||
1192 | }; | ||
1193 | |||
1194 | static const u32 ar5416Bank3_9100[][3] = { | ||
1195 | { 0x000098f0, 0x01400018, 0x01c00018 }, | ||
1196 | }; | ||
1197 | |||
1198 | static const u32 ar5416Bank6_9100[][3] = { | ||
1199 | |||
1200 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1201 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1202 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1203 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
1204 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
1205 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
1206 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
1207 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
1208 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1209 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1210 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1211 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1212 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
1213 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
1214 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
1215 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
1216 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1217 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
1218 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
1219 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
1220 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
1221 | { 0x0000989c, 0x004210a2, 0x004210a2 }, | ||
1222 | { 0x0000989c, 0x0014000f, 0x0014000f }, | ||
1223 | { 0x0000989c, 0x00c40002, 0x00c40002 }, | ||
1224 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
1225 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
1226 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
1227 | { 0x0000989c, 0x000180d6, 0x000180d6 }, | ||
1228 | { 0x0000989c, 0x0000c0aa, 0x0000c0aa }, | ||
1229 | { 0x0000989c, 0x000000b1, 0x000000b1 }, | ||
1230 | { 0x0000989c, 0x00002000, 0x00002000 }, | ||
1231 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
1232 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
1233 | }; | ||
1234 | |||
1235 | |||
1236 | static const u32 ar5416Bank6TPC_9100[][3] = { | ||
1237 | |||
1238 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1239 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1240 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1241 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
1242 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
1243 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
1244 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
1245 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
1246 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1247 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1248 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1249 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
1250 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
1251 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
1252 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
1253 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
1254 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1255 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
1256 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
1257 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
1258 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
1259 | { 0x0000989c, 0x00423022, 0x00423022 }, | ||
1260 | { 0x0000989c, 0x2014008f, 0x2014008f }, | ||
1261 | { 0x0000989c, 0x00c40002, 0x00c40002 }, | ||
1262 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
1263 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
1264 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
1265 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
1266 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
1267 | { 0x0000989c, 0x000000e1, 0x000000e1 }, | ||
1268 | { 0x0000989c, 0x00007080, 0x00007080 }, | ||
1269 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
1270 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
1271 | }; | ||
1272 | |||
1273 | static const u32 ar5416Bank7_9100[][2] = { | ||
1274 | { 0x0000989c, 0x00000500 }, | ||
1275 | { 0x0000989c, 0x00000800 }, | ||
1276 | { 0x000098cc, 0x0000000e }, | ||
1277 | }; | ||
1278 | |||
1279 | static const u32 ar5416Addac_9100[][2] = { | ||
1280 | {0x0000989c, 0x00000000 }, | ||
1281 | {0x0000989c, 0x00000000 }, | ||
1282 | {0x0000989c, 0x00000000 }, | ||
1283 | {0x0000989c, 0x00000000 }, | ||
1284 | {0x0000989c, 0x00000000 }, | ||
1285 | {0x0000989c, 0x00000000 }, | ||
1286 | {0x0000989c, 0x00000000 }, | ||
1287 | {0x0000989c, 0x00000010 }, | ||
1288 | {0x0000989c, 0x00000000 }, | ||
1289 | {0x0000989c, 0x00000000 }, | ||
1290 | {0x0000989c, 0x00000000 }, | ||
1291 | {0x0000989c, 0x00000000 }, | ||
1292 | {0x0000989c, 0x00000000 }, | ||
1293 | {0x0000989c, 0x00000000 }, | ||
1294 | {0x0000989c, 0x00000000 }, | ||
1295 | {0x0000989c, 0x00000000 }, | ||
1296 | {0x0000989c, 0x00000000 }, | ||
1297 | {0x0000989c, 0x00000000 }, | ||
1298 | {0x0000989c, 0x00000000 }, | ||
1299 | {0x0000989c, 0x00000000 }, | ||
1300 | {0x0000989c, 0x00000000 }, | ||
1301 | {0x0000989c, 0x000000c0 }, | ||
1302 | {0x0000989c, 0x00000015 }, | ||
1303 | {0x0000989c, 0x00000000 }, | ||
1304 | {0x0000989c, 0x00000000 }, | ||
1305 | {0x0000989c, 0x00000000 }, | ||
1306 | {0x0000989c, 0x00000000 }, | ||
1307 | {0x0000989c, 0x00000000 }, | ||
1308 | {0x0000989c, 0x00000000 }, | ||
1309 | {0x0000989c, 0x00000000 }, | ||
1310 | {0x0000989c, 0x00000000 }, | ||
1311 | {0x000098cc, 0x00000000 }, | ||
1312 | }; | ||
1313 | |||
1314 | static const u32 ar5416Modes_9160[][6] = { | ||
1315 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | ||
1316 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | ||
1317 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | ||
1318 | { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, | ||
1319 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, | ||
1320 | { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf }, | ||
1321 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, | ||
1322 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, | ||
1323 | { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
1324 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, | ||
1325 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
1326 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, | ||
1327 | { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 }, | ||
1328 | { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
1329 | { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
1330 | { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
1331 | { 0x00009850, 0x6c48b4e2, 0x6c48b4e2, 0x6c48b0e2, 0x6c48b0e2, 0x6c48b0e2 }, | ||
1332 | { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e }, | ||
1333 | { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e }, | ||
1334 | { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 }, | ||
1335 | { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, | ||
1336 | { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 }, | ||
1337 | { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 }, | ||
1338 | { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, | ||
1339 | { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, | ||
1340 | { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d }, | ||
1341 | { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 }, | ||
1342 | { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 }, | ||
1343 | { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 }, | ||
1344 | { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 }, | ||
1345 | { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 }, | ||
1346 | { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce }, | ||
1347 | { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 }, | ||
1348 | { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be }, | ||
1349 | { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, | ||
1350 | { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 }, | ||
1351 | { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, | ||
1352 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, | ||
1353 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
1354 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
1355 | { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 }, | ||
1356 | { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 }, | ||
1357 | { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
1358 | { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
1359 | { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
1360 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | ||
1361 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | ||
1362 | { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa }, | ||
1363 | { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 }, | ||
1364 | { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 }, | ||
1365 | { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 }, | ||
1366 | { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b }, | ||
1367 | { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b }, | ||
1368 | { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a }, | ||
1369 | { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf }, | ||
1370 | { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f }, | ||
1371 | { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f }, | ||
1372 | { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f }, | ||
1373 | { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 }, | ||
1374 | { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
1375 | { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
1376 | { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
1377 | }; | ||
1378 | |||
1379 | static const u32 ar5416Common_9160[][2] = { | ||
1380 | { 0x0000000c, 0x00000000 }, | ||
1381 | { 0x00000030, 0x00020015 }, | ||
1382 | { 0x00000034, 0x00000005 }, | ||
1383 | { 0x00000040, 0x00000000 }, | ||
1384 | { 0x00000044, 0x00000008 }, | ||
1385 | { 0x00000048, 0x00000008 }, | ||
1386 | { 0x0000004c, 0x00000010 }, | ||
1387 | { 0x00000050, 0x00000000 }, | ||
1388 | { 0x00000054, 0x0000001f }, | ||
1389 | { 0x00000800, 0x00000000 }, | ||
1390 | { 0x00000804, 0x00000000 }, | ||
1391 | { 0x00000808, 0x00000000 }, | ||
1392 | { 0x0000080c, 0x00000000 }, | ||
1393 | { 0x00000810, 0x00000000 }, | ||
1394 | { 0x00000814, 0x00000000 }, | ||
1395 | { 0x00000818, 0x00000000 }, | ||
1396 | { 0x0000081c, 0x00000000 }, | ||
1397 | { 0x00000820, 0x00000000 }, | ||
1398 | { 0x00000824, 0x00000000 }, | ||
1399 | { 0x00001040, 0x002ffc0f }, | ||
1400 | { 0x00001044, 0x002ffc0f }, | ||
1401 | { 0x00001048, 0x002ffc0f }, | ||
1402 | { 0x0000104c, 0x002ffc0f }, | ||
1403 | { 0x00001050, 0x002ffc0f }, | ||
1404 | { 0x00001054, 0x002ffc0f }, | ||
1405 | { 0x00001058, 0x002ffc0f }, | ||
1406 | { 0x0000105c, 0x002ffc0f }, | ||
1407 | { 0x00001060, 0x002ffc0f }, | ||
1408 | { 0x00001064, 0x002ffc0f }, | ||
1409 | { 0x00001230, 0x00000000 }, | ||
1410 | { 0x00001270, 0x00000000 }, | ||
1411 | { 0x00001038, 0x00000000 }, | ||
1412 | { 0x00001078, 0x00000000 }, | ||
1413 | { 0x000010b8, 0x00000000 }, | ||
1414 | { 0x000010f8, 0x00000000 }, | ||
1415 | { 0x00001138, 0x00000000 }, | ||
1416 | { 0x00001178, 0x00000000 }, | ||
1417 | { 0x000011b8, 0x00000000 }, | ||
1418 | { 0x000011f8, 0x00000000 }, | ||
1419 | { 0x00001238, 0x00000000 }, | ||
1420 | { 0x00001278, 0x00000000 }, | ||
1421 | { 0x000012b8, 0x00000000 }, | ||
1422 | { 0x000012f8, 0x00000000 }, | ||
1423 | { 0x00001338, 0x00000000 }, | ||
1424 | { 0x00001378, 0x00000000 }, | ||
1425 | { 0x000013b8, 0x00000000 }, | ||
1426 | { 0x000013f8, 0x00000000 }, | ||
1427 | { 0x00001438, 0x00000000 }, | ||
1428 | { 0x00001478, 0x00000000 }, | ||
1429 | { 0x000014b8, 0x00000000 }, | ||
1430 | { 0x000014f8, 0x00000000 }, | ||
1431 | { 0x00001538, 0x00000000 }, | ||
1432 | { 0x00001578, 0x00000000 }, | ||
1433 | { 0x000015b8, 0x00000000 }, | ||
1434 | { 0x000015f8, 0x00000000 }, | ||
1435 | { 0x00001638, 0x00000000 }, | ||
1436 | { 0x00001678, 0x00000000 }, | ||
1437 | { 0x000016b8, 0x00000000 }, | ||
1438 | { 0x000016f8, 0x00000000 }, | ||
1439 | { 0x00001738, 0x00000000 }, | ||
1440 | { 0x00001778, 0x00000000 }, | ||
1441 | { 0x000017b8, 0x00000000 }, | ||
1442 | { 0x000017f8, 0x00000000 }, | ||
1443 | { 0x0000103c, 0x00000000 }, | ||
1444 | { 0x0000107c, 0x00000000 }, | ||
1445 | { 0x000010bc, 0x00000000 }, | ||
1446 | { 0x000010fc, 0x00000000 }, | ||
1447 | { 0x0000113c, 0x00000000 }, | ||
1448 | { 0x0000117c, 0x00000000 }, | ||
1449 | { 0x000011bc, 0x00000000 }, | ||
1450 | { 0x000011fc, 0x00000000 }, | ||
1451 | { 0x0000123c, 0x00000000 }, | ||
1452 | { 0x0000127c, 0x00000000 }, | ||
1453 | { 0x000012bc, 0x00000000 }, | ||
1454 | { 0x000012fc, 0x00000000 }, | ||
1455 | { 0x0000133c, 0x00000000 }, | ||
1456 | { 0x0000137c, 0x00000000 }, | ||
1457 | { 0x000013bc, 0x00000000 }, | ||
1458 | { 0x000013fc, 0x00000000 }, | ||
1459 | { 0x0000143c, 0x00000000 }, | ||
1460 | { 0x0000147c, 0x00000000 }, | ||
1461 | { 0x00004030, 0x00000002 }, | ||
1462 | { 0x0000403c, 0x00000002 }, | ||
1463 | { 0x00007010, 0x00000020 }, | ||
1464 | { 0x00007038, 0x000004c2 }, | ||
1465 | { 0x00008004, 0x00000000 }, | ||
1466 | { 0x00008008, 0x00000000 }, | ||
1467 | { 0x0000800c, 0x00000000 }, | ||
1468 | { 0x00008018, 0x00000700 }, | ||
1469 | { 0x00008020, 0x00000000 }, | ||
1470 | { 0x00008038, 0x00000000 }, | ||
1471 | { 0x0000803c, 0x00000000 }, | ||
1472 | { 0x00008048, 0x40000000 }, | ||
1473 | { 0x00008054, 0x00000000 }, | ||
1474 | { 0x00008058, 0x00000000 }, | ||
1475 | { 0x0000805c, 0x000fc78f }, | ||
1476 | { 0x00008060, 0x0000000f }, | ||
1477 | { 0x00008064, 0x00000000 }, | ||
1478 | { 0x000080c0, 0x2a82301a }, | ||
1479 | { 0x000080c4, 0x05dc01e0 }, | ||
1480 | { 0x000080c8, 0x1f402710 }, | ||
1481 | { 0x000080cc, 0x01f40000 }, | ||
1482 | { 0x000080d0, 0x00001e00 }, | ||
1483 | { 0x000080d4, 0x00000000 }, | ||
1484 | { 0x000080d8, 0x00400000 }, | ||
1485 | { 0x000080e0, 0xffffffff }, | ||
1486 | { 0x000080e4, 0x0000ffff }, | ||
1487 | { 0x000080e8, 0x003f3f3f }, | ||
1488 | { 0x000080ec, 0x00000000 }, | ||
1489 | { 0x000080f0, 0x00000000 }, | ||
1490 | { 0x000080f4, 0x00000000 }, | ||
1491 | { 0x000080f8, 0x00000000 }, | ||
1492 | { 0x000080fc, 0x00020000 }, | ||
1493 | { 0x00008100, 0x00020000 }, | ||
1494 | { 0x00008104, 0x00000001 }, | ||
1495 | { 0x00008108, 0x00000052 }, | ||
1496 | { 0x0000810c, 0x00000000 }, | ||
1497 | { 0x00008110, 0x00000168 }, | ||
1498 | { 0x00008118, 0x000100aa }, | ||
1499 | { 0x0000811c, 0x00003210 }, | ||
1500 | { 0x00008120, 0x08f04800 }, | ||
1501 | { 0x00008124, 0x00000000 }, | ||
1502 | { 0x00008128, 0x00000000 }, | ||
1503 | { 0x0000812c, 0x00000000 }, | ||
1504 | { 0x00008130, 0x00000000 }, | ||
1505 | { 0x00008134, 0x00000000 }, | ||
1506 | { 0x00008138, 0x00000000 }, | ||
1507 | { 0x0000813c, 0x00000000 }, | ||
1508 | { 0x00008144, 0xffffffff }, | ||
1509 | { 0x00008168, 0x00000000 }, | ||
1510 | { 0x0000816c, 0x00000000 }, | ||
1511 | { 0x00008170, 0x32143320 }, | ||
1512 | { 0x00008174, 0xfaa4fa50 }, | ||
1513 | { 0x00008178, 0x00000100 }, | ||
1514 | { 0x0000817c, 0x00000000 }, | ||
1515 | { 0x000081c4, 0x00000000 }, | ||
1516 | { 0x000081d0, 0x00003210 }, | ||
1517 | { 0x000081ec, 0x00000000 }, | ||
1518 | { 0x000081f0, 0x00000000 }, | ||
1519 | { 0x000081f4, 0x00000000 }, | ||
1520 | { 0x000081f8, 0x00000000 }, | ||
1521 | { 0x000081fc, 0x00000000 }, | ||
1522 | { 0x00008200, 0x00000000 }, | ||
1523 | { 0x00008204, 0x00000000 }, | ||
1524 | { 0x00008208, 0x00000000 }, | ||
1525 | { 0x0000820c, 0x00000000 }, | ||
1526 | { 0x00008210, 0x00000000 }, | ||
1527 | { 0x00008214, 0x00000000 }, | ||
1528 | { 0x00008218, 0x00000000 }, | ||
1529 | { 0x0000821c, 0x00000000 }, | ||
1530 | { 0x00008220, 0x00000000 }, | ||
1531 | { 0x00008224, 0x00000000 }, | ||
1532 | { 0x00008228, 0x00000000 }, | ||
1533 | { 0x0000822c, 0x00000000 }, | ||
1534 | { 0x00008230, 0x00000000 }, | ||
1535 | { 0x00008234, 0x00000000 }, | ||
1536 | { 0x00008238, 0x00000000 }, | ||
1537 | { 0x0000823c, 0x00000000 }, | ||
1538 | { 0x00008240, 0x00100000 }, | ||
1539 | { 0x00008244, 0x0010f400 }, | ||
1540 | { 0x00008248, 0x00000100 }, | ||
1541 | { 0x0000824c, 0x0001e800 }, | ||
1542 | { 0x00008250, 0x00000000 }, | ||
1543 | { 0x00008254, 0x00000000 }, | ||
1544 | { 0x00008258, 0x00000000 }, | ||
1545 | { 0x0000825c, 0x400000ff }, | ||
1546 | { 0x00008260, 0x00080922 }, | ||
1547 | { 0x00008270, 0x00000000 }, | ||
1548 | { 0x00008274, 0x40000000 }, | ||
1549 | { 0x00008278, 0x003e4180 }, | ||
1550 | { 0x0000827c, 0x00000000 }, | ||
1551 | { 0x00008284, 0x0000002c }, | ||
1552 | { 0x00008288, 0x0000002c }, | ||
1553 | { 0x0000828c, 0x00000000 }, | ||
1554 | { 0x00008294, 0x00000000 }, | ||
1555 | { 0x00008298, 0x00000000 }, | ||
1556 | { 0x00008300, 0x00000000 }, | ||
1557 | { 0x00008304, 0x00000000 }, | ||
1558 | { 0x00008308, 0x00000000 }, | ||
1559 | { 0x0000830c, 0x00000000 }, | ||
1560 | { 0x00008310, 0x00000000 }, | ||
1561 | { 0x00008314, 0x00000000 }, | ||
1562 | { 0x00008318, 0x00000000 }, | ||
1563 | { 0x00008328, 0x00000000 }, | ||
1564 | { 0x0000832c, 0x00000007 }, | ||
1565 | { 0x00008330, 0x00000302 }, | ||
1566 | { 0x00008334, 0x00000e00 }, | ||
1567 | { 0x00008338, 0x00ff0000 }, | ||
1568 | { 0x0000833c, 0x00000000 }, | ||
1569 | { 0x00008340, 0x000107ff }, | ||
1570 | { 0x00009808, 0x00000000 }, | ||
1571 | { 0x0000980c, 0xad848e19 }, | ||
1572 | { 0x00009810, 0x7d14e000 }, | ||
1573 | { 0x00009814, 0x9c0a9f6b }, | ||
1574 | { 0x0000981c, 0x00000000 }, | ||
1575 | { 0x0000982c, 0x0000a000 }, | ||
1576 | { 0x00009830, 0x00000000 }, | ||
1577 | { 0x0000983c, 0x00200400 }, | ||
1578 | { 0x00009840, 0x206a01ae }, | ||
1579 | { 0x0000984c, 0x1284233c }, | ||
1580 | { 0x00009854, 0x00000859 }, | ||
1581 | { 0x00009900, 0x00000000 }, | ||
1582 | { 0x00009904, 0x00000000 }, | ||
1583 | { 0x00009908, 0x00000000 }, | ||
1584 | { 0x0000990c, 0x00000000 }, | ||
1585 | { 0x0000991c, 0x10000fff }, | ||
1586 | { 0x00009920, 0x05100000 }, | ||
1587 | { 0x0000a920, 0x05100000 }, | ||
1588 | { 0x0000b920, 0x05100000 }, | ||
1589 | { 0x00009928, 0x00000001 }, | ||
1590 | { 0x0000992c, 0x00000004 }, | ||
1591 | { 0x00009934, 0x1e1f2022 }, | ||
1592 | { 0x00009938, 0x0a0b0c0d }, | ||
1593 | { 0x0000993c, 0x00000000 }, | ||
1594 | { 0x00009948, 0x9280b212 }, | ||
1595 | { 0x0000994c, 0x00020028 }, | ||
1596 | { 0x00009954, 0x5f3ca3de }, | ||
1597 | { 0x00009958, 0x2108ecff }, | ||
1598 | { 0x00009940, 0x00750604 }, | ||
1599 | { 0x0000c95c, 0x004b6a8e }, | ||
1600 | { 0x00009970, 0x190fb515 }, | ||
1601 | { 0x00009974, 0x00000000 }, | ||
1602 | { 0x00009978, 0x00000001 }, | ||
1603 | { 0x0000997c, 0x00000000 }, | ||
1604 | { 0x00009980, 0x00000000 }, | ||
1605 | { 0x00009984, 0x00000000 }, | ||
1606 | { 0x00009988, 0x00000000 }, | ||
1607 | { 0x0000998c, 0x00000000 }, | ||
1608 | { 0x00009990, 0x00000000 }, | ||
1609 | { 0x00009994, 0x00000000 }, | ||
1610 | { 0x00009998, 0x00000000 }, | ||
1611 | { 0x0000999c, 0x00000000 }, | ||
1612 | { 0x000099a0, 0x00000000 }, | ||
1613 | { 0x000099a4, 0x00000001 }, | ||
1614 | { 0x000099a8, 0x201fff00 }, | ||
1615 | { 0x000099ac, 0x006f0000 }, | ||
1616 | { 0x000099b0, 0x03051000 }, | ||
1617 | { 0x000099dc, 0x00000000 }, | ||
1618 | { 0x000099e0, 0x00000200 }, | ||
1619 | { 0x000099e4, 0xaaaaaaaa }, | ||
1620 | { 0x000099e8, 0x3c466478 }, | ||
1621 | { 0x000099ec, 0x0cc80caa }, | ||
1622 | { 0x000099fc, 0x00001042 }, | ||
1623 | { 0x00009b00, 0x00000000 }, | ||
1624 | { 0x00009b04, 0x00000001 }, | ||
1625 | { 0x00009b08, 0x00000002 }, | ||
1626 | { 0x00009b0c, 0x00000003 }, | ||
1627 | { 0x00009b10, 0x00000004 }, | ||
1628 | { 0x00009b14, 0x00000005 }, | ||
1629 | { 0x00009b18, 0x00000008 }, | ||
1630 | { 0x00009b1c, 0x00000009 }, | ||
1631 | { 0x00009b20, 0x0000000a }, | ||
1632 | { 0x00009b24, 0x0000000b }, | ||
1633 | { 0x00009b28, 0x0000000c }, | ||
1634 | { 0x00009b2c, 0x0000000d }, | ||
1635 | { 0x00009b30, 0x00000010 }, | ||
1636 | { 0x00009b34, 0x00000011 }, | ||
1637 | { 0x00009b38, 0x00000012 }, | ||
1638 | { 0x00009b3c, 0x00000013 }, | ||
1639 | { 0x00009b40, 0x00000014 }, | ||
1640 | { 0x00009b44, 0x00000015 }, | ||
1641 | { 0x00009b48, 0x00000018 }, | ||
1642 | { 0x00009b4c, 0x00000019 }, | ||
1643 | { 0x00009b50, 0x0000001a }, | ||
1644 | { 0x00009b54, 0x0000001b }, | ||
1645 | { 0x00009b58, 0x0000001c }, | ||
1646 | { 0x00009b5c, 0x0000001d }, | ||
1647 | { 0x00009b60, 0x00000020 }, | ||
1648 | { 0x00009b64, 0x00000021 }, | ||
1649 | { 0x00009b68, 0x00000022 }, | ||
1650 | { 0x00009b6c, 0x00000023 }, | ||
1651 | { 0x00009b70, 0x00000024 }, | ||
1652 | { 0x00009b74, 0x00000025 }, | ||
1653 | { 0x00009b78, 0x00000028 }, | ||
1654 | { 0x00009b7c, 0x00000029 }, | ||
1655 | { 0x00009b80, 0x0000002a }, | ||
1656 | { 0x00009b84, 0x0000002b }, | ||
1657 | { 0x00009b88, 0x0000002c }, | ||
1658 | { 0x00009b8c, 0x0000002d }, | ||
1659 | { 0x00009b90, 0x00000030 }, | ||
1660 | { 0x00009b94, 0x00000031 }, | ||
1661 | { 0x00009b98, 0x00000032 }, | ||
1662 | { 0x00009b9c, 0x00000033 }, | ||
1663 | { 0x00009ba0, 0x00000034 }, | ||
1664 | { 0x00009ba4, 0x00000035 }, | ||
1665 | { 0x00009ba8, 0x00000035 }, | ||
1666 | { 0x00009bac, 0x00000035 }, | ||
1667 | { 0x00009bb0, 0x00000035 }, | ||
1668 | { 0x00009bb4, 0x00000035 }, | ||
1669 | { 0x00009bb8, 0x00000035 }, | ||
1670 | { 0x00009bbc, 0x00000035 }, | ||
1671 | { 0x00009bc0, 0x00000035 }, | ||
1672 | { 0x00009bc4, 0x00000035 }, | ||
1673 | { 0x00009bc8, 0x00000035 }, | ||
1674 | { 0x00009bcc, 0x00000035 }, | ||
1675 | { 0x00009bd0, 0x00000035 }, | ||
1676 | { 0x00009bd4, 0x00000035 }, | ||
1677 | { 0x00009bd8, 0x00000035 }, | ||
1678 | { 0x00009bdc, 0x00000035 }, | ||
1679 | { 0x00009be0, 0x00000035 }, | ||
1680 | { 0x00009be4, 0x00000035 }, | ||
1681 | { 0x00009be8, 0x00000035 }, | ||
1682 | { 0x00009bec, 0x00000035 }, | ||
1683 | { 0x00009bf0, 0x00000035 }, | ||
1684 | { 0x00009bf4, 0x00000035 }, | ||
1685 | { 0x00009bf8, 0x00000010 }, | ||
1686 | { 0x00009bfc, 0x0000001a }, | ||
1687 | { 0x0000a210, 0x40806333 }, | ||
1688 | { 0x0000a214, 0x00106c10 }, | ||
1689 | { 0x0000a218, 0x009c4060 }, | ||
1690 | { 0x0000a220, 0x018830c6 }, | ||
1691 | { 0x0000a224, 0x00000400 }, | ||
1692 | { 0x0000a228, 0x001a0bb5 }, | ||
1693 | { 0x0000a22c, 0x00000000 }, | ||
1694 | { 0x0000a234, 0x20202020 }, | ||
1695 | { 0x0000a238, 0x20202020 }, | ||
1696 | { 0x0000a23c, 0x13c889af }, | ||
1697 | { 0x0000a240, 0x38490a20 }, | ||
1698 | { 0x0000a244, 0x00007bb6 }, | ||
1699 | { 0x0000a248, 0x0fff3ffc }, | ||
1700 | { 0x0000a24c, 0x00000001 }, | ||
1701 | { 0x0000a250, 0x0000e000 }, | ||
1702 | { 0x0000a254, 0x00000000 }, | ||
1703 | { 0x0000a258, 0x0cc75380 }, | ||
1704 | { 0x0000a25c, 0x0f0f0f01 }, | ||
1705 | { 0x0000a260, 0xdfa91f01 }, | ||
1706 | { 0x0000a268, 0x00000001 }, | ||
1707 | { 0x0000a26c, 0x0ebae9c6 }, | ||
1708 | { 0x0000b26c, 0x0ebae9c6 }, | ||
1709 | { 0x0000c26c, 0x0ebae9c6 }, | ||
1710 | { 0x0000d270, 0x00820820 }, | ||
1711 | { 0x0000a278, 0x1ce739ce }, | ||
1712 | { 0x0000a27c, 0x050701ce }, | ||
1713 | { 0x0000a338, 0x00000000 }, | ||
1714 | { 0x0000a33c, 0x00000000 }, | ||
1715 | { 0x0000a340, 0x00000000 }, | ||
1716 | { 0x0000a344, 0x00000000 }, | ||
1717 | { 0x0000a348, 0x3fffffff }, | ||
1718 | { 0x0000a34c, 0x3fffffff }, | ||
1719 | { 0x0000a350, 0x3fffffff }, | ||
1720 | { 0x0000a354, 0x0003ffff }, | ||
1721 | { 0x0000a358, 0x79bfaa03 }, | ||
1722 | { 0x0000d35c, 0x07ffffef }, | ||
1723 | { 0x0000d360, 0x0fffffe7 }, | ||
1724 | { 0x0000d364, 0x17ffffe5 }, | ||
1725 | { 0x0000d368, 0x1fffffe4 }, | ||
1726 | { 0x0000d36c, 0x37ffffe3 }, | ||
1727 | { 0x0000d370, 0x3fffffe3 }, | ||
1728 | { 0x0000d374, 0x57ffffe3 }, | ||
1729 | { 0x0000d378, 0x5fffffe2 }, | ||
1730 | { 0x0000d37c, 0x7fffffe2 }, | ||
1731 | { 0x0000d380, 0x7f3c7bba }, | ||
1732 | { 0x0000d384, 0xf3307ff0 }, | ||
1733 | { 0x0000a388, 0x0c000000 }, | ||
1734 | { 0x0000a38c, 0x20202020 }, | ||
1735 | { 0x0000a390, 0x20202020 }, | ||
1736 | { 0x0000a394, 0x1ce739ce }, | ||
1737 | { 0x0000a398, 0x000001ce }, | ||
1738 | { 0x0000a39c, 0x00000001 }, | ||
1739 | { 0x0000a3a0, 0x00000000 }, | ||
1740 | { 0x0000a3a4, 0x00000000 }, | ||
1741 | { 0x0000a3a8, 0x00000000 }, | ||
1742 | { 0x0000a3ac, 0x00000000 }, | ||
1743 | { 0x0000a3b0, 0x00000000 }, | ||
1744 | { 0x0000a3b4, 0x00000000 }, | ||
1745 | { 0x0000a3b8, 0x00000000 }, | ||
1746 | { 0x0000a3bc, 0x00000000 }, | ||
1747 | { 0x0000a3c0, 0x00000000 }, | ||
1748 | { 0x0000a3c4, 0x00000000 }, | ||
1749 | { 0x0000a3c8, 0x00000246 }, | ||
1750 | { 0x0000a3cc, 0x20202020 }, | ||
1751 | { 0x0000a3d0, 0x20202020 }, | ||
1752 | { 0x0000a3d4, 0x20202020 }, | ||
1753 | { 0x0000a3dc, 0x1ce739ce }, | ||
1754 | { 0x0000a3e0, 0x000001ce }, | ||
1755 | }; | ||
1756 | |||
1757 | static const u32 ar5416Bank0_9160[][2] = { | ||
1758 | { 0x000098b0, 0x1e5795e5 }, | ||
1759 | { 0x000098e0, 0x02008020 }, | ||
1760 | }; | ||
1761 | |||
1762 | static const u32 ar5416BB_RfGain_9160[][3] = { | ||
1763 | { 0x00009a00, 0x00000000, 0x00000000 }, | ||
1764 | { 0x00009a04, 0x00000040, 0x00000040 }, | ||
1765 | { 0x00009a08, 0x00000080, 0x00000080 }, | ||
1766 | { 0x00009a0c, 0x000001a1, 0x00000141 }, | ||
1767 | { 0x00009a10, 0x000001e1, 0x00000181 }, | ||
1768 | { 0x00009a14, 0x00000021, 0x000001c1 }, | ||
1769 | { 0x00009a18, 0x00000061, 0x00000001 }, | ||
1770 | { 0x00009a1c, 0x00000168, 0x00000041 }, | ||
1771 | { 0x00009a20, 0x000001a8, 0x000001a8 }, | ||
1772 | { 0x00009a24, 0x000001e8, 0x000001e8 }, | ||
1773 | { 0x00009a28, 0x00000028, 0x00000028 }, | ||
1774 | { 0x00009a2c, 0x00000068, 0x00000068 }, | ||
1775 | { 0x00009a30, 0x00000189, 0x000000a8 }, | ||
1776 | { 0x00009a34, 0x000001c9, 0x00000169 }, | ||
1777 | { 0x00009a38, 0x00000009, 0x000001a9 }, | ||
1778 | { 0x00009a3c, 0x00000049, 0x000001e9 }, | ||
1779 | { 0x00009a40, 0x00000089, 0x00000029 }, | ||
1780 | { 0x00009a44, 0x00000170, 0x00000069 }, | ||
1781 | { 0x00009a48, 0x000001b0, 0x00000190 }, | ||
1782 | { 0x00009a4c, 0x000001f0, 0x000001d0 }, | ||
1783 | { 0x00009a50, 0x00000030, 0x00000010 }, | ||
1784 | { 0x00009a54, 0x00000070, 0x00000050 }, | ||
1785 | { 0x00009a58, 0x00000191, 0x00000090 }, | ||
1786 | { 0x00009a5c, 0x000001d1, 0x00000151 }, | ||
1787 | { 0x00009a60, 0x00000011, 0x00000191 }, | ||
1788 | { 0x00009a64, 0x00000051, 0x000001d1 }, | ||
1789 | { 0x00009a68, 0x00000091, 0x00000011 }, | ||
1790 | { 0x00009a6c, 0x000001b8, 0x00000051 }, | ||
1791 | { 0x00009a70, 0x000001f8, 0x00000198 }, | ||
1792 | { 0x00009a74, 0x00000038, 0x000001d8 }, | ||
1793 | { 0x00009a78, 0x00000078, 0x00000018 }, | ||
1794 | { 0x00009a7c, 0x00000199, 0x00000058 }, | ||
1795 | { 0x00009a80, 0x000001d9, 0x00000098 }, | ||
1796 | { 0x00009a84, 0x00000019, 0x00000159 }, | ||
1797 | { 0x00009a88, 0x00000059, 0x00000199 }, | ||
1798 | { 0x00009a8c, 0x00000099, 0x000001d9 }, | ||
1799 | { 0x00009a90, 0x000000d9, 0x00000019 }, | ||
1800 | { 0x00009a94, 0x000000f9, 0x00000059 }, | ||
1801 | { 0x00009a98, 0x000000f9, 0x00000099 }, | ||
1802 | { 0x00009a9c, 0x000000f9, 0x000000d9 }, | ||
1803 | { 0x00009aa0, 0x000000f9, 0x000000f9 }, | ||
1804 | { 0x00009aa4, 0x000000f9, 0x000000f9 }, | ||
1805 | { 0x00009aa8, 0x000000f9, 0x000000f9 }, | ||
1806 | { 0x00009aac, 0x000000f9, 0x000000f9 }, | ||
1807 | { 0x00009ab0, 0x000000f9, 0x000000f9 }, | ||
1808 | { 0x00009ab4, 0x000000f9, 0x000000f9 }, | ||
1809 | { 0x00009ab8, 0x000000f9, 0x000000f9 }, | ||
1810 | { 0x00009abc, 0x000000f9, 0x000000f9 }, | ||
1811 | { 0x00009ac0, 0x000000f9, 0x000000f9 }, | ||
1812 | { 0x00009ac4, 0x000000f9, 0x000000f9 }, | ||
1813 | { 0x00009ac8, 0x000000f9, 0x000000f9 }, | ||
1814 | { 0x00009acc, 0x000000f9, 0x000000f9 }, | ||
1815 | { 0x00009ad0, 0x000000f9, 0x000000f9 }, | ||
1816 | { 0x00009ad4, 0x000000f9, 0x000000f9 }, | ||
1817 | { 0x00009ad8, 0x000000f9, 0x000000f9 }, | ||
1818 | { 0x00009adc, 0x000000f9, 0x000000f9 }, | ||
1819 | { 0x00009ae0, 0x000000f9, 0x000000f9 }, | ||
1820 | { 0x00009ae4, 0x000000f9, 0x000000f9 }, | ||
1821 | { 0x00009ae8, 0x000000f9, 0x000000f9 }, | ||
1822 | { 0x00009aec, 0x000000f9, 0x000000f9 }, | ||
1823 | { 0x00009af0, 0x000000f9, 0x000000f9 }, | ||
1824 | { 0x00009af4, 0x000000f9, 0x000000f9 }, | ||
1825 | { 0x00009af8, 0x000000f9, 0x000000f9 }, | ||
1826 | { 0x00009afc, 0x000000f9, 0x000000f9 }, | ||
1827 | }; | ||
1828 | |||
1829 | static const u32 ar5416Bank1_9160[][2] = { | ||
1830 | { 0x000098b0, 0x02108421 }, | ||
1831 | { 0x000098ec, 0x00000008 }, | ||
1832 | }; | ||
1833 | |||
1834 | static const u32 ar5416Bank2_9160[][2] = { | ||
1835 | { 0x000098b0, 0x0e73ff17 }, | ||
1836 | { 0x000098e0, 0x00000420 }, | ||
1837 | }; | ||
1838 | |||
1839 | static const u32 ar5416Bank3_9160[][3] = { | ||
1840 | { 0x000098f0, 0x01400018, 0x01c00018 }, | ||
1841 | }; | ||
1842 | |||
1843 | static const u32 ar5416Bank6_9160[][3] = { | ||
1844 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1845 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1846 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1847 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
1848 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
1849 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
1850 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
1851 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
1852 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1853 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1854 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1855 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
1856 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
1857 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
1858 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
1859 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
1860 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1861 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
1862 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
1863 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
1864 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
1865 | { 0x0000989c, 0x004210a2, 0x004210a2 }, | ||
1866 | { 0x0000989c, 0x0014008f, 0x0014008f }, | ||
1867 | { 0x0000989c, 0x00c40003, 0x00c40003 }, | ||
1868 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
1869 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
1870 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
1871 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
1872 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
1873 | { 0x0000989c, 0x000000f1, 0x000000f1 }, | ||
1874 | { 0x0000989c, 0x00002081, 0x00002081 }, | ||
1875 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
1876 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
1877 | }; | ||
1878 | |||
1879 | static const u32 ar5416Bank6TPC_9160[][3] = { | ||
1880 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1881 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1882 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1883 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
1884 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
1885 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
1886 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
1887 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
1888 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1889 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1890 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1891 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
1892 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
1893 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
1894 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
1895 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
1896 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1897 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
1898 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
1899 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
1900 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
1901 | { 0x0000989c, 0x00423022, 0x00423022 }, | ||
1902 | { 0x0000989c, 0x2014008f, 0x2014008f }, | ||
1903 | { 0x0000989c, 0x00c40002, 0x00c40002 }, | ||
1904 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
1905 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
1906 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
1907 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
1908 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
1909 | { 0x0000989c, 0x000000e1, 0x000000e1 }, | ||
1910 | { 0x0000989c, 0x00007080, 0x00007080 }, | ||
1911 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
1912 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
1913 | }; | ||
1914 | |||
1915 | static const u32 ar5416Bank7_9160[][2] = { | ||
1916 | { 0x0000989c, 0x00000500 }, | ||
1917 | { 0x0000989c, 0x00000800 }, | ||
1918 | { 0x000098cc, 0x0000000e }, | ||
1919 | }; | ||
1920 | |||
1921 | static u32 ar5416Addac_9160[][2] = { | ||
1922 | {0x0000989c, 0x00000000 }, | ||
1923 | {0x0000989c, 0x00000000 }, | ||
1924 | {0x0000989c, 0x00000000 }, | ||
1925 | {0x0000989c, 0x00000000 }, | ||
1926 | {0x0000989c, 0x00000000 }, | ||
1927 | {0x0000989c, 0x00000000 }, | ||
1928 | {0x0000989c, 0x000000c0 }, | ||
1929 | {0x0000989c, 0x00000018 }, | ||
1930 | {0x0000989c, 0x00000004 }, | ||
1931 | {0x0000989c, 0x00000000 }, | ||
1932 | {0x0000989c, 0x00000000 }, | ||
1933 | {0x0000989c, 0x00000000 }, | ||
1934 | {0x0000989c, 0x00000000 }, | ||
1935 | {0x0000989c, 0x00000000 }, | ||
1936 | {0x0000989c, 0x00000000 }, | ||
1937 | {0x0000989c, 0x00000000 }, | ||
1938 | {0x0000989c, 0x00000000 }, | ||
1939 | {0x0000989c, 0x00000000 }, | ||
1940 | {0x0000989c, 0x00000000 }, | ||
1941 | {0x0000989c, 0x00000000 }, | ||
1942 | {0x0000989c, 0x00000000 }, | ||
1943 | {0x0000989c, 0x000000c0 }, | ||
1944 | {0x0000989c, 0x00000019 }, | ||
1945 | {0x0000989c, 0x00000004 }, | ||
1946 | {0x0000989c, 0x00000000 }, | ||
1947 | {0x0000989c, 0x00000000 }, | ||
1948 | {0x0000989c, 0x00000000 }, | ||
1949 | {0x0000989c, 0x00000004 }, | ||
1950 | {0x0000989c, 0x00000003 }, | ||
1951 | {0x0000989c, 0x00000008 }, | ||
1952 | {0x0000989c, 0x00000000 }, | ||
1953 | {0x000098cc, 0x00000000 }, | ||
1954 | }; | ||
1955 | |||
1956 | static u32 ar5416Addac_91601_1[][2] = { | ||
1957 | {0x0000989c, 0x00000000 }, | ||
1958 | {0x0000989c, 0x00000000 }, | ||
1959 | {0x0000989c, 0x00000000 }, | ||
1960 | {0x0000989c, 0x00000000 }, | ||
1961 | {0x0000989c, 0x00000000 }, | ||
1962 | {0x0000989c, 0x00000000 }, | ||
1963 | {0x0000989c, 0x000000c0 }, | ||
1964 | {0x0000989c, 0x00000018 }, | ||
1965 | {0x0000989c, 0x00000004 }, | ||
1966 | {0x0000989c, 0x00000000 }, | ||
1967 | {0x0000989c, 0x00000000 }, | ||
1968 | {0x0000989c, 0x00000000 }, | ||
1969 | {0x0000989c, 0x00000000 }, | ||
1970 | {0x0000989c, 0x00000000 }, | ||
1971 | {0x0000989c, 0x00000000 }, | ||
1972 | {0x0000989c, 0x00000000 }, | ||
1973 | {0x0000989c, 0x00000000 }, | ||
1974 | {0x0000989c, 0x00000000 }, | ||
1975 | {0x0000989c, 0x00000000 }, | ||
1976 | {0x0000989c, 0x00000000 }, | ||
1977 | {0x0000989c, 0x00000000 }, | ||
1978 | {0x0000989c, 0x000000c0 }, | ||
1979 | {0x0000989c, 0x00000019 }, | ||
1980 | {0x0000989c, 0x00000004 }, | ||
1981 | {0x0000989c, 0x00000000 }, | ||
1982 | {0x0000989c, 0x00000000 }, | ||
1983 | {0x0000989c, 0x00000000 }, | ||
1984 | {0x0000989c, 0x00000000 }, | ||
1985 | {0x0000989c, 0x00000000 }, | ||
1986 | {0x0000989c, 0x00000000 }, | ||
1987 | {0x0000989c, 0x00000000 }, | ||
1988 | {0x000098cc, 0x00000000 }, | ||
1989 | }; | ||
1990 | |||
1991 | /* XXX 9280 1 */ | ||
1992 | static const u32 ar9280Modes_9280[][6] = { | ||
1993 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | ||
1994 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | ||
1995 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | ||
1996 | { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, | ||
1997 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801080, 0x08400840, 0x06e006e0 }, | ||
1998 | { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f }, | ||
1999 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, | ||
2000 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, | ||
2001 | { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
2002 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, | ||
2003 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
2004 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, | ||
2005 | { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 }, | ||
2006 | { 0x00009848, 0x00028566, 0x00028566, 0x00028563, 0x00028563, 0x00028563 }, | ||
2007 | { 0x0000a848, 0x00028566, 0x00028566, 0x00028563, 0x00028563, 0x00028563 }, | ||
2008 | { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 }, | ||
2009 | { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e }, | ||
2010 | { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e }, | ||
2011 | { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d20, 0x00049d20, 0x00049d18 }, | ||
2012 | { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, | ||
2013 | { 0x00009868, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190 }, | ||
2014 | { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 }, | ||
2015 | { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 }, | ||
2016 | { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, | ||
2017 | { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d }, | ||
2018 | { 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010 }, | ||
2019 | { 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 }, | ||
2020 | { 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 }, | ||
2021 | { 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210 }, | ||
2022 | { 0x0000c9b8, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a }, | ||
2023 | { 0x0000c9bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 }, | ||
2024 | { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 }, | ||
2025 | { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, | ||
2026 | { 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c }, | ||
2027 | { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, | ||
2028 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, | ||
2029 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
2030 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
2031 | { 0x00009a00, 0x00008184, 0x00008184, 0x00000214, 0x00000214, 0x00000214 }, | ||
2032 | { 0x00009a04, 0x00008188, 0x00008188, 0x00000218, 0x00000218, 0x00000218 }, | ||
2033 | { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000224, 0x00000224, 0x00000224 }, | ||
2034 | { 0x00009a0c, 0x00008190, 0x00008190, 0x00000228, 0x00000228, 0x00000228 }, | ||
2035 | { 0x00009a10, 0x00008194, 0x00008194, 0x0000022c, 0x0000022c, 0x0000022c }, | ||
2036 | { 0x00009a14, 0x00008200, 0x00008200, 0x00000230, 0x00000230, 0x00000230 }, | ||
2037 | { 0x00009a18, 0x00008204, 0x00008204, 0x000002a4, 0x000002a4, 0x000002a4 }, | ||
2038 | { 0x00009a1c, 0x00008208, 0x00008208, 0x000002a8, 0x000002a8, 0x000002a8 }, | ||
2039 | { 0x00009a20, 0x0000820c, 0x0000820c, 0x000002ac, 0x000002ac, 0x000002ac }, | ||
2040 | { 0x00009a24, 0x00008210, 0x00008210, 0x000002b0, 0x000002b0, 0x000002b0 }, | ||
2041 | { 0x00009a28, 0x00008214, 0x00008214, 0x000002b4, 0x000002b4, 0x000002b4 }, | ||
2042 | { 0x00009a2c, 0x00008280, 0x00008280, 0x000002b8, 0x000002b8, 0x000002b8 }, | ||
2043 | { 0x00009a30, 0x00008284, 0x00008284, 0x00000390, 0x00000390, 0x00000390 }, | ||
2044 | { 0x00009a34, 0x00008288, 0x00008288, 0x00000394, 0x00000394, 0x00000394 }, | ||
2045 | { 0x00009a38, 0x0000828c, 0x0000828c, 0x00000398, 0x00000398, 0x00000398 }, | ||
2046 | { 0x00009a3c, 0x00008290, 0x00008290, 0x00000334, 0x00000334, 0x00000334 }, | ||
2047 | { 0x00009a40, 0x00008300, 0x00008300, 0x00000338, 0x00000338, 0x00000338 }, | ||
2048 | { 0x00009a44, 0x00008304, 0x00008304, 0x000003ac, 0x000003ac, 0x000003ac }, | ||
2049 | { 0x00009a48, 0x00008308, 0x00008308, 0x000003b0, 0x000003b0, 0x000003b0 }, | ||
2050 | { 0x00009a4c, 0x0000830c, 0x0000830c, 0x000003b4, 0x000003b4, 0x000003b4 }, | ||
2051 | { 0x00009a50, 0x00008310, 0x00008310, 0x000003b8, 0x000003b8, 0x000003b8 }, | ||
2052 | { 0x00009a54, 0x00008314, 0x00008314, 0x000003a5, 0x000003a5, 0x000003a5 }, | ||
2053 | { 0x00009a58, 0x00008380, 0x00008380, 0x000003a9, 0x000003a9, 0x000003a9 }, | ||
2054 | { 0x00009a5c, 0x00008384, 0x00008384, 0x000003ad, 0x000003ad, 0x000003ad }, | ||
2055 | { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 }, | ||
2056 | { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 }, | ||
2057 | { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c }, | ||
2058 | { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 }, | ||
2059 | { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 }, | ||
2060 | { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 }, | ||
2061 | { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 }, | ||
2062 | { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 }, | ||
2063 | { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 }, | ||
2064 | { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 }, | ||
2065 | { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 }, | ||
2066 | { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c }, | ||
2067 | { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 }, | ||
2068 | { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 }, | ||
2069 | { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 }, | ||
2070 | { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 }, | ||
2071 | { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 }, | ||
2072 | { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c }, | ||
2073 | { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 }, | ||
2074 | { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 }, | ||
2075 | { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 }, | ||
2076 | { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 }, | ||
2077 | { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 }, | ||
2078 | { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c }, | ||
2079 | { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 }, | ||
2080 | { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 }, | ||
2081 | { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 }, | ||
2082 | { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c }, | ||
2083 | { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 }, | ||
2084 | { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 }, | ||
2085 | { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 }, | ||
2086 | { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 }, | ||
2087 | { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c }, | ||
2088 | { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 }, | ||
2089 | { 0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c }, | ||
2090 | { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310 }, | ||
2091 | { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384 }, | ||
2092 | { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388 }, | ||
2093 | { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324 }, | ||
2094 | { 0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704 }, | ||
2095 | { 0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4 }, | ||
2096 | { 0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8 }, | ||
2097 | { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710 }, | ||
2098 | { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714 }, | ||
2099 | { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720 }, | ||
2100 | { 0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724 }, | ||
2101 | { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728 }, | ||
2102 | { 0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c }, | ||
2103 | { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0 }, | ||
2104 | { 0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4 }, | ||
2105 | { 0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8 }, | ||
2106 | { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0 }, | ||
2107 | { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4 }, | ||
2108 | { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8 }, | ||
2109 | { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5 }, | ||
2110 | { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9 }, | ||
2111 | { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad }, | ||
2112 | { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1 }, | ||
2113 | { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5 }, | ||
2114 | { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9 }, | ||
2115 | { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5 }, | ||
2116 | { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9 }, | ||
2117 | { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1 }, | ||
2118 | { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5 }, | ||
2119 | { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9 }, | ||
2120 | { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6 }, | ||
2121 | { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca }, | ||
2122 | { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce }, | ||
2123 | { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2 }, | ||
2124 | { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6 }, | ||
2125 | { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3 }, | ||
2126 | { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7 }, | ||
2127 | { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb }, | ||
2128 | { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf }, | ||
2129 | { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7 }, | ||
2130 | { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db }, | ||
2131 | { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db }, | ||
2132 | { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db }, | ||
2133 | { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2134 | { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2135 | { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2136 | { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2137 | { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2138 | { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2139 | { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2140 | { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2141 | { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2142 | { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2143 | { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2144 | { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2145 | { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2146 | { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2147 | { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2148 | { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2149 | { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2150 | { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2151 | { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2152 | { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2153 | { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2154 | { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2155 | { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2156 | { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2157 | { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2158 | { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
2159 | { 0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444 }, | ||
2160 | { 0x0000a208, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788 }, | ||
2161 | { 0x0000a20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019 }, | ||
2162 | { 0x0000b20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019 }, | ||
2163 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | ||
2164 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | ||
2165 | { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 }, | ||
2166 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
2167 | { 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002 }, | ||
2168 | { 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009 }, | ||
2169 | { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b }, | ||
2170 | { 0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012 }, | ||
2171 | { 0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048 }, | ||
2172 | { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a }, | ||
2173 | { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211 }, | ||
2174 | { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 }, | ||
2175 | { 0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b }, | ||
2176 | { 0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412 }, | ||
2177 | { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414 }, | ||
2178 | { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a }, | ||
2179 | { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649 }, | ||
2180 | { 0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b }, | ||
2181 | { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49 }, | ||
2182 | { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48 }, | ||
2183 | { 0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a }, | ||
2184 | { 0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88 }, | ||
2185 | { 0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a }, | ||
2186 | { 0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9 }, | ||
2187 | { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 }, | ||
2188 | { 0x0000784c, 0x0e4f048c, 0x0e4f048c, 0x0e4d048c, 0x0e4d048c, 0x0e4d048c }, | ||
2189 | { 0x00007854, 0x12031828, 0x12031828, 0x12035828, 0x12035828, 0x12035828 }, | ||
2190 | { 0x00007870, 0x807ec400, 0x807ec400, 0x807ec000, 0x807ec000, 0x807ec000 }, | ||
2191 | { 0x0000788c, 0x00010000, 0x00010000, 0x00110000, 0x00110000, 0x00110000 }, | ||
2192 | }; | ||
2193 | |||
2194 | static const u32 ar9280Common_9280[][2] = { | ||
2195 | { 0x0000000c, 0x00000000 }, | ||
2196 | { 0x00000030, 0x00020015 }, | ||
2197 | { 0x00000034, 0x00000005 }, | ||
2198 | { 0x00000040, 0x00000000 }, | ||
2199 | { 0x00000044, 0x00000008 }, | ||
2200 | { 0x00000048, 0x00000008 }, | ||
2201 | { 0x0000004c, 0x00000010 }, | ||
2202 | { 0x00000050, 0x00000000 }, | ||
2203 | { 0x00000054, 0x0000001f }, | ||
2204 | { 0x00000800, 0x00000000 }, | ||
2205 | { 0x00000804, 0x00000000 }, | ||
2206 | { 0x00000808, 0x00000000 }, | ||
2207 | { 0x0000080c, 0x00000000 }, | ||
2208 | { 0x00000810, 0x00000000 }, | ||
2209 | { 0x00000814, 0x00000000 }, | ||
2210 | { 0x00000818, 0x00000000 }, | ||
2211 | { 0x0000081c, 0x00000000 }, | ||
2212 | { 0x00000820, 0x00000000 }, | ||
2213 | { 0x00000824, 0x00000000 }, | ||
2214 | { 0x00001040, 0x002ffc0f }, | ||
2215 | { 0x00001044, 0x002ffc0f }, | ||
2216 | { 0x00001048, 0x002ffc0f }, | ||
2217 | { 0x0000104c, 0x002ffc0f }, | ||
2218 | { 0x00001050, 0x002ffc0f }, | ||
2219 | { 0x00001054, 0x002ffc0f }, | ||
2220 | { 0x00001058, 0x002ffc0f }, | ||
2221 | { 0x0000105c, 0x002ffc0f }, | ||
2222 | { 0x00001060, 0x002ffc0f }, | ||
2223 | { 0x00001064, 0x002ffc0f }, | ||
2224 | { 0x00001230, 0x00000000 }, | ||
2225 | { 0x00001270, 0x00000000 }, | ||
2226 | { 0x00001038, 0x00000000 }, | ||
2227 | { 0x00001078, 0x00000000 }, | ||
2228 | { 0x000010b8, 0x00000000 }, | ||
2229 | { 0x000010f8, 0x00000000 }, | ||
2230 | { 0x00001138, 0x00000000 }, | ||
2231 | { 0x00001178, 0x00000000 }, | ||
2232 | { 0x000011b8, 0x00000000 }, | ||
2233 | { 0x000011f8, 0x00000000 }, | ||
2234 | { 0x00001238, 0x00000000 }, | ||
2235 | { 0x00001278, 0x00000000 }, | ||
2236 | { 0x000012b8, 0x00000000 }, | ||
2237 | { 0x000012f8, 0x00000000 }, | ||
2238 | { 0x00001338, 0x00000000 }, | ||
2239 | { 0x00001378, 0x00000000 }, | ||
2240 | { 0x000013b8, 0x00000000 }, | ||
2241 | { 0x000013f8, 0x00000000 }, | ||
2242 | { 0x00001438, 0x00000000 }, | ||
2243 | { 0x00001478, 0x00000000 }, | ||
2244 | { 0x000014b8, 0x00000000 }, | ||
2245 | { 0x000014f8, 0x00000000 }, | ||
2246 | { 0x00001538, 0x00000000 }, | ||
2247 | { 0x00001578, 0x00000000 }, | ||
2248 | { 0x000015b8, 0x00000000 }, | ||
2249 | { 0x000015f8, 0x00000000 }, | ||
2250 | { 0x00001638, 0x00000000 }, | ||
2251 | { 0x00001678, 0x00000000 }, | ||
2252 | { 0x000016b8, 0x00000000 }, | ||
2253 | { 0x000016f8, 0x00000000 }, | ||
2254 | { 0x00001738, 0x00000000 }, | ||
2255 | { 0x00001778, 0x00000000 }, | ||
2256 | { 0x000017b8, 0x00000000 }, | ||
2257 | { 0x000017f8, 0x00000000 }, | ||
2258 | { 0x0000103c, 0x00000000 }, | ||
2259 | { 0x0000107c, 0x00000000 }, | ||
2260 | { 0x000010bc, 0x00000000 }, | ||
2261 | { 0x000010fc, 0x00000000 }, | ||
2262 | { 0x0000113c, 0x00000000 }, | ||
2263 | { 0x0000117c, 0x00000000 }, | ||
2264 | { 0x000011bc, 0x00000000 }, | ||
2265 | { 0x000011fc, 0x00000000 }, | ||
2266 | { 0x0000123c, 0x00000000 }, | ||
2267 | { 0x0000127c, 0x00000000 }, | ||
2268 | { 0x000012bc, 0x00000000 }, | ||
2269 | { 0x000012fc, 0x00000000 }, | ||
2270 | { 0x0000133c, 0x00000000 }, | ||
2271 | { 0x0000137c, 0x00000000 }, | ||
2272 | { 0x000013bc, 0x00000000 }, | ||
2273 | { 0x000013fc, 0x00000000 }, | ||
2274 | { 0x0000143c, 0x00000000 }, | ||
2275 | { 0x0000147c, 0x00000000 }, | ||
2276 | { 0x00004030, 0x00000002 }, | ||
2277 | { 0x0000403c, 0x00000002 }, | ||
2278 | { 0x00004024, 0x0000001f }, | ||
2279 | { 0x00007010, 0x00000033 }, | ||
2280 | { 0x00007038, 0x000004c2 }, | ||
2281 | { 0x00008004, 0x00000000 }, | ||
2282 | { 0x00008008, 0x00000000 }, | ||
2283 | { 0x0000800c, 0x00000000 }, | ||
2284 | { 0x00008018, 0x00000700 }, | ||
2285 | { 0x00008020, 0x00000000 }, | ||
2286 | { 0x00008038, 0x00000000 }, | ||
2287 | { 0x0000803c, 0x00000000 }, | ||
2288 | { 0x00008048, 0x40000000 }, | ||
2289 | { 0x00008054, 0x00000000 }, | ||
2290 | { 0x00008058, 0x00000000 }, | ||
2291 | { 0x0000805c, 0x000fc78f }, | ||
2292 | { 0x00008060, 0x0000000f }, | ||
2293 | { 0x00008064, 0x00000000 }, | ||
2294 | { 0x00008070, 0x00000000 }, | ||
2295 | { 0x000080c0, 0x2a82301a }, | ||
2296 | { 0x000080c4, 0x05dc01e0 }, | ||
2297 | { 0x000080c8, 0x1f402710 }, | ||
2298 | { 0x000080cc, 0x01f40000 }, | ||
2299 | { 0x000080d0, 0x00001e00 }, | ||
2300 | { 0x000080d4, 0x00000000 }, | ||
2301 | { 0x000080d8, 0x00400000 }, | ||
2302 | { 0x000080e0, 0xffffffff }, | ||
2303 | { 0x000080e4, 0x0000ffff }, | ||
2304 | { 0x000080e8, 0x003f3f3f }, | ||
2305 | { 0x000080ec, 0x00000000 }, | ||
2306 | { 0x000080f0, 0x00000000 }, | ||
2307 | { 0x000080f4, 0x00000000 }, | ||
2308 | { 0x000080f8, 0x00000000 }, | ||
2309 | { 0x000080fc, 0x00020000 }, | ||
2310 | { 0x00008100, 0x00020000 }, | ||
2311 | { 0x00008104, 0x00000001 }, | ||
2312 | { 0x00008108, 0x00000052 }, | ||
2313 | { 0x0000810c, 0x00000000 }, | ||
2314 | { 0x00008110, 0x00000168 }, | ||
2315 | { 0x00008118, 0x000100aa }, | ||
2316 | { 0x0000811c, 0x00003210 }, | ||
2317 | { 0x00008120, 0x08f04800 }, | ||
2318 | { 0x00008124, 0x00000000 }, | ||
2319 | { 0x00008128, 0x00000000 }, | ||
2320 | { 0x0000812c, 0x00000000 }, | ||
2321 | { 0x00008130, 0x00000000 }, | ||
2322 | { 0x00008134, 0x00000000 }, | ||
2323 | { 0x00008138, 0x00000000 }, | ||
2324 | { 0x0000813c, 0x00000000 }, | ||
2325 | { 0x00008144, 0x00000000 }, | ||
2326 | { 0x00008168, 0x00000000 }, | ||
2327 | { 0x0000816c, 0x00000000 }, | ||
2328 | { 0x00008170, 0x32143320 }, | ||
2329 | { 0x00008174, 0xfaa4fa50 }, | ||
2330 | { 0x00008178, 0x00000100 }, | ||
2331 | { 0x0000817c, 0x00000000 }, | ||
2332 | { 0x000081c4, 0x00000000 }, | ||
2333 | { 0x000081d0, 0x00003210 }, | ||
2334 | { 0x000081ec, 0x00000000 }, | ||
2335 | { 0x000081f0, 0x00000000 }, | ||
2336 | { 0x000081f4, 0x00000000 }, | ||
2337 | { 0x000081f8, 0x00000000 }, | ||
2338 | { 0x000081fc, 0x00000000 }, | ||
2339 | { 0x00008200, 0x00000000 }, | ||
2340 | { 0x00008204, 0x00000000 }, | ||
2341 | { 0x00008208, 0x00000000 }, | ||
2342 | { 0x0000820c, 0x00000000 }, | ||
2343 | { 0x00008210, 0x00000000 }, | ||
2344 | { 0x00008214, 0x00000000 }, | ||
2345 | { 0x00008218, 0x00000000 }, | ||
2346 | { 0x0000821c, 0x00000000 }, | ||
2347 | { 0x00008220, 0x00000000 }, | ||
2348 | { 0x00008224, 0x00000000 }, | ||
2349 | { 0x00008228, 0x00000000 }, | ||
2350 | { 0x0000822c, 0x00000000 }, | ||
2351 | { 0x00008230, 0x00000000 }, | ||
2352 | { 0x00008234, 0x00000000 }, | ||
2353 | { 0x00008238, 0x00000000 }, | ||
2354 | { 0x0000823c, 0x00000000 }, | ||
2355 | { 0x00008240, 0x00100000 }, | ||
2356 | { 0x00008244, 0x0010f400 }, | ||
2357 | { 0x00008248, 0x00000100 }, | ||
2358 | { 0x0000824c, 0x0001e800 }, | ||
2359 | { 0x00008250, 0x00000000 }, | ||
2360 | { 0x00008254, 0x00000000 }, | ||
2361 | { 0x00008258, 0x00000000 }, | ||
2362 | { 0x0000825c, 0x400000ff }, | ||
2363 | { 0x00008260, 0x00080922 }, | ||
2364 | { 0x00008270, 0x00000000 }, | ||
2365 | { 0x00008274, 0x40000000 }, | ||
2366 | { 0x00008278, 0x003e4180 }, | ||
2367 | { 0x0000827c, 0x00000000 }, | ||
2368 | { 0x00008284, 0x0000002c }, | ||
2369 | { 0x00008288, 0x0000002c }, | ||
2370 | { 0x0000828c, 0x00000000 }, | ||
2371 | { 0x00008294, 0x00000000 }, | ||
2372 | { 0x00008298, 0x00000000 }, | ||
2373 | { 0x00008300, 0x00000000 }, | ||
2374 | { 0x00008304, 0x00000000 }, | ||
2375 | { 0x00008308, 0x00000000 }, | ||
2376 | { 0x0000830c, 0x00000000 }, | ||
2377 | { 0x00008310, 0x00000000 }, | ||
2378 | { 0x00008314, 0x00000000 }, | ||
2379 | { 0x00008318, 0x00000000 }, | ||
2380 | { 0x00008328, 0x00000000 }, | ||
2381 | { 0x0000832c, 0x00000007 }, | ||
2382 | { 0x00008330, 0x00000302 }, | ||
2383 | { 0x00008334, 0x00000e00 }, | ||
2384 | { 0x00008338, 0x00000000 }, | ||
2385 | { 0x0000833c, 0x00000000 }, | ||
2386 | { 0x00008340, 0x000107ff }, | ||
2387 | { 0x00008344, 0x00000000 }, | ||
2388 | { 0x00009808, 0x00000000 }, | ||
2389 | { 0x0000980c, 0xaf268e30 }, | ||
2390 | { 0x00009810, 0xfd14e000 }, | ||
2391 | { 0x00009814, 0x9c0a9f6b }, | ||
2392 | { 0x0000981c, 0x00000000 }, | ||
2393 | { 0x0000982c, 0x0000a000 }, | ||
2394 | { 0x00009830, 0x00000000 }, | ||
2395 | { 0x0000983c, 0x00200400 }, | ||
2396 | { 0x00009840, 0x206a01ae }, | ||
2397 | { 0x0000984c, 0x0040233c }, | ||
2398 | { 0x0000a84c, 0x0040233c }, | ||
2399 | { 0x00009854, 0x00000044 }, | ||
2400 | { 0x00009900, 0x00000000 }, | ||
2401 | { 0x00009904, 0x00000000 }, | ||
2402 | { 0x00009908, 0x00000000 }, | ||
2403 | { 0x0000990c, 0x00000000 }, | ||
2404 | { 0x0000991c, 0x10000fff }, | ||
2405 | { 0x00009920, 0x04900000 }, | ||
2406 | { 0x0000a920, 0x04900000 }, | ||
2407 | { 0x00009928, 0x00000001 }, | ||
2408 | { 0x0000992c, 0x00000004 }, | ||
2409 | { 0x00009934, 0x1e1f2022 }, | ||
2410 | { 0x00009938, 0x0a0b0c0d }, | ||
2411 | { 0x0000993c, 0x00000000 }, | ||
2412 | { 0x00009948, 0x9280c00a }, | ||
2413 | { 0x0000994c, 0x00020028 }, | ||
2414 | { 0x00009954, 0xe250a51e }, | ||
2415 | { 0x00009958, 0x3388ffff }, | ||
2416 | { 0x00009940, 0x00781204 }, | ||
2417 | { 0x0000c95c, 0x004b6a8e }, | ||
2418 | { 0x0000c968, 0x000003ce }, | ||
2419 | { 0x00009970, 0x190fb514 }, | ||
2420 | { 0x00009974, 0x00000000 }, | ||
2421 | { 0x00009978, 0x00000001 }, | ||
2422 | { 0x0000997c, 0x00000000 }, | ||
2423 | { 0x00009980, 0x00000000 }, | ||
2424 | { 0x00009984, 0x00000000 }, | ||
2425 | { 0x00009988, 0x00000000 }, | ||
2426 | { 0x0000998c, 0x00000000 }, | ||
2427 | { 0x00009990, 0x00000000 }, | ||
2428 | { 0x00009994, 0x00000000 }, | ||
2429 | { 0x00009998, 0x00000000 }, | ||
2430 | { 0x0000999c, 0x00000000 }, | ||
2431 | { 0x000099a0, 0x00000000 }, | ||
2432 | { 0x000099a4, 0x00000001 }, | ||
2433 | { 0x000099a8, 0x201fff00 }, | ||
2434 | { 0x000099ac, 0x006f00c4 }, | ||
2435 | { 0x000099b0, 0x03051000 }, | ||
2436 | { 0x000099b4, 0x00000820 }, | ||
2437 | { 0x000099dc, 0x00000000 }, | ||
2438 | { 0x000099e0, 0x00000000 }, | ||
2439 | { 0x000099e4, 0xaaaaaaaa }, | ||
2440 | { 0x000099e8, 0x3c466478 }, | ||
2441 | { 0x000099ec, 0x0cc80caa }, | ||
2442 | { 0x000099fc, 0x00001042 }, | ||
2443 | { 0x0000a210, 0x4080a333 }, | ||
2444 | { 0x0000a214, 0x40206c10 }, | ||
2445 | { 0x0000a218, 0x009c4060 }, | ||
2446 | { 0x0000a220, 0x01834061 }, | ||
2447 | { 0x0000a224, 0x00000400 }, | ||
2448 | { 0x0000a228, 0x000003b5 }, | ||
2449 | { 0x0000a22c, 0x23277200 }, | ||
2450 | { 0x0000a234, 0x20202020 }, | ||
2451 | { 0x0000a238, 0x20202020 }, | ||
2452 | { 0x0000a23c, 0x13c889af }, | ||
2453 | { 0x0000a240, 0x38490a20 }, | ||
2454 | { 0x0000a244, 0x00007bb6 }, | ||
2455 | { 0x0000a248, 0x0fff3ffc }, | ||
2456 | { 0x0000a24c, 0x00000001 }, | ||
2457 | { 0x0000a250, 0x001da000 }, | ||
2458 | { 0x0000a254, 0x00000000 }, | ||
2459 | { 0x0000a258, 0x0cdbd380 }, | ||
2460 | { 0x0000a25c, 0x0f0f0f01 }, | ||
2461 | { 0x0000a260, 0xdfa91f01 }, | ||
2462 | { 0x0000a268, 0x00000000 }, | ||
2463 | { 0x0000a26c, 0x0ebae9c6 }, | ||
2464 | { 0x0000b26c, 0x0ebae9c6 }, | ||
2465 | { 0x0000d270, 0x00820820 }, | ||
2466 | { 0x0000a278, 0x1ce739ce }, | ||
2467 | { 0x0000a27c, 0x050701ce }, | ||
2468 | { 0x0000a358, 0x7999aa0f }, | ||
2469 | { 0x0000d35c, 0x07ffffef }, | ||
2470 | { 0x0000d360, 0x0fffffe7 }, | ||
2471 | { 0x0000d364, 0x17ffffe5 }, | ||
2472 | { 0x0000d368, 0x1fffffe4 }, | ||
2473 | { 0x0000d36c, 0x37ffffe3 }, | ||
2474 | { 0x0000d370, 0x3fffffe3 }, | ||
2475 | { 0x0000d374, 0x57ffffe3 }, | ||
2476 | { 0x0000d378, 0x5fffffe2 }, | ||
2477 | { 0x0000d37c, 0x7fffffe2 }, | ||
2478 | { 0x0000d380, 0x7f3c7bba }, | ||
2479 | { 0x0000d384, 0xf3307ff0 }, | ||
2480 | { 0x0000a388, 0x0c000000 }, | ||
2481 | { 0x0000a38c, 0x20202020 }, | ||
2482 | { 0x0000a390, 0x20202020 }, | ||
2483 | { 0x0000a394, 0x1ce739ce }, | ||
2484 | { 0x0000a398, 0x000001ce }, | ||
2485 | { 0x0000a39c, 0x00000001 }, | ||
2486 | { 0x0000a3a0, 0x00000000 }, | ||
2487 | { 0x0000a3a4, 0x00000000 }, | ||
2488 | { 0x0000a3a8, 0x00000000 }, | ||
2489 | { 0x0000a3ac, 0x00000000 }, | ||
2490 | { 0x0000a3b0, 0x00000000 }, | ||
2491 | { 0x0000a3b4, 0x00000000 }, | ||
2492 | { 0x0000a3b8, 0x00000000 }, | ||
2493 | { 0x0000a3bc, 0x00000000 }, | ||
2494 | { 0x0000a3c0, 0x00000000 }, | ||
2495 | { 0x0000a3c4, 0x00000000 }, | ||
2496 | { 0x0000a3c8, 0x00000246 }, | ||
2497 | { 0x0000a3cc, 0x20202020 }, | ||
2498 | { 0x0000a3d0, 0x20202020 }, | ||
2499 | { 0x0000a3d4, 0x20202020 }, | ||
2500 | { 0x0000a3dc, 0x1ce739ce }, | ||
2501 | { 0x0000a3e0, 0x000001ce }, | ||
2502 | { 0x0000a3e4, 0x00000000 }, | ||
2503 | { 0x0000a3e8, 0x18c43433 }, | ||
2504 | { 0x0000a3ec, 0x00f38081 }, | ||
2505 | { 0x00007800, 0x00040000 }, | ||
2506 | { 0x00007804, 0xdb005012 }, | ||
2507 | { 0x00007808, 0x04924914 }, | ||
2508 | { 0x0000780c, 0x21084210 }, | ||
2509 | { 0x00007810, 0x6d801300 }, | ||
2510 | { 0x00007814, 0x0019beff }, | ||
2511 | { 0x00007818, 0x07e40000 }, | ||
2512 | { 0x0000781c, 0x00492000 }, | ||
2513 | { 0x00007820, 0x92492480 }, | ||
2514 | { 0x00007824, 0x00040000 }, | ||
2515 | { 0x00007828, 0xdb005012 }, | ||
2516 | { 0x0000782c, 0x04924914 }, | ||
2517 | { 0x00007830, 0x21084210 }, | ||
2518 | { 0x00007834, 0x6d801300 }, | ||
2519 | { 0x00007838, 0x0019beff }, | ||
2520 | { 0x0000783c, 0x07e40000 }, | ||
2521 | { 0x00007840, 0x00492000 }, | ||
2522 | { 0x00007844, 0x92492480 }, | ||
2523 | { 0x00007848, 0x00120000 }, | ||
2524 | { 0x00007850, 0x54214514 }, | ||
2525 | { 0x00007858, 0x92592692 }, | ||
2526 | { 0x00007860, 0x52802000 }, | ||
2527 | { 0x00007864, 0x0a8e370e }, | ||
2528 | { 0x00007868, 0xc0102850 }, | ||
2529 | { 0x0000786c, 0x812d4000 }, | ||
2530 | { 0x00007874, 0x001b6db0 }, | ||
2531 | { 0x00007878, 0x00376b63 }, | ||
2532 | { 0x0000787c, 0x06db6db6 }, | ||
2533 | { 0x00007880, 0x006d8000 }, | ||
2534 | { 0x00007884, 0xffeffffe }, | ||
2535 | { 0x00007888, 0xffeffffe }, | ||
2536 | { 0x00007890, 0x00060aeb }, | ||
2537 | { 0x00007894, 0x5a108000 }, | ||
2538 | { 0x00007898, 0x2a850160 }, | ||
2539 | }; | ||
2540 | |||
2541 | /* XXX 9280 2 */ | ||
2542 | static const u32 ar9280Modes_9280_2[][6] = { | ||
2543 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | ||
2544 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | ||
2545 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | ||
2546 | { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 }, | ||
2547 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, | ||
2548 | { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f }, | ||
2549 | { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 }, | ||
2550 | { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a }, | ||
2551 | { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 }, | ||
2552 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, | ||
2553 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, | ||
2554 | { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
2555 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, | ||
2556 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
2557 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, | ||
2558 | { 0x00009840, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e, 0x206a012e }, | ||
2559 | { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 }, | ||
2560 | { 0x00009850, 0x6c4000e2, 0x6c4000e2, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2 }, | ||
2561 | { 0x00009858, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e }, | ||
2562 | { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x3139605e, 0x31395d5e, 0x31395d5e }, | ||
2563 | { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 }, | ||
2564 | { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, | ||
2565 | { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 }, | ||
2566 | { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 }, | ||
2567 | { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, | ||
2568 | { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, | ||
2569 | { 0x00009924, 0xd00a8a0b, 0xd00a8a0b, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d }, | ||
2570 | { 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010 }, | ||
2571 | { 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 }, | ||
2572 | { 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 }, | ||
2573 | { 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210 }, | ||
2574 | { 0x000099b8, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c }, | ||
2575 | { 0x000099bc, 0x00000a00, 0x00000a00, 0x00000c00, 0x00000c00, 0x00000c00 }, | ||
2576 | { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 }, | ||
2577 | { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, | ||
2578 | { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 }, | ||
2579 | { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, | ||
2580 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, | ||
2581 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
2582 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
2583 | { 0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444 }, | ||
2584 | { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019 }, | ||
2585 | { 0x0000b20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019 }, | ||
2586 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | ||
2587 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | ||
2588 | { 0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000 }, | ||
2589 | { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, | ||
2590 | { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
2591 | { 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000 }, | ||
2592 | }; | ||
2593 | |||
2594 | static const u32 ar9280Common_9280_2[][2] = { | ||
2595 | { 0x0000000c, 0x00000000 }, | ||
2596 | { 0x00000030, 0x00020015 }, | ||
2597 | { 0x00000034, 0x00000005 }, | ||
2598 | { 0x00000040, 0x00000000 }, | ||
2599 | { 0x00000044, 0x00000008 }, | ||
2600 | { 0x00000048, 0x00000008 }, | ||
2601 | { 0x0000004c, 0x00000010 }, | ||
2602 | { 0x00000050, 0x00000000 }, | ||
2603 | { 0x00000054, 0x0000001f }, | ||
2604 | { 0x00000800, 0x00000000 }, | ||
2605 | { 0x00000804, 0x00000000 }, | ||
2606 | { 0x00000808, 0x00000000 }, | ||
2607 | { 0x0000080c, 0x00000000 }, | ||
2608 | { 0x00000810, 0x00000000 }, | ||
2609 | { 0x00000814, 0x00000000 }, | ||
2610 | { 0x00000818, 0x00000000 }, | ||
2611 | { 0x0000081c, 0x00000000 }, | ||
2612 | { 0x00000820, 0x00000000 }, | ||
2613 | { 0x00000824, 0x00000000 }, | ||
2614 | { 0x00001040, 0x002ffc0f }, | ||
2615 | { 0x00001044, 0x002ffc0f }, | ||
2616 | { 0x00001048, 0x002ffc0f }, | ||
2617 | { 0x0000104c, 0x002ffc0f }, | ||
2618 | { 0x00001050, 0x002ffc0f }, | ||
2619 | { 0x00001054, 0x002ffc0f }, | ||
2620 | { 0x00001058, 0x002ffc0f }, | ||
2621 | { 0x0000105c, 0x002ffc0f }, | ||
2622 | { 0x00001060, 0x002ffc0f }, | ||
2623 | { 0x00001064, 0x002ffc0f }, | ||
2624 | { 0x00001230, 0x00000000 }, | ||
2625 | { 0x00001270, 0x00000000 }, | ||
2626 | { 0x00001038, 0x00000000 }, | ||
2627 | { 0x00001078, 0x00000000 }, | ||
2628 | { 0x000010b8, 0x00000000 }, | ||
2629 | { 0x000010f8, 0x00000000 }, | ||
2630 | { 0x00001138, 0x00000000 }, | ||
2631 | { 0x00001178, 0x00000000 }, | ||
2632 | { 0x000011b8, 0x00000000 }, | ||
2633 | { 0x000011f8, 0x00000000 }, | ||
2634 | { 0x00001238, 0x00000000 }, | ||
2635 | { 0x00001278, 0x00000000 }, | ||
2636 | { 0x000012b8, 0x00000000 }, | ||
2637 | { 0x000012f8, 0x00000000 }, | ||
2638 | { 0x00001338, 0x00000000 }, | ||
2639 | { 0x00001378, 0x00000000 }, | ||
2640 | { 0x000013b8, 0x00000000 }, | ||
2641 | { 0x000013f8, 0x00000000 }, | ||
2642 | { 0x00001438, 0x00000000 }, | ||
2643 | { 0x00001478, 0x00000000 }, | ||
2644 | { 0x000014b8, 0x00000000 }, | ||
2645 | { 0x000014f8, 0x00000000 }, | ||
2646 | { 0x00001538, 0x00000000 }, | ||
2647 | { 0x00001578, 0x00000000 }, | ||
2648 | { 0x000015b8, 0x00000000 }, | ||
2649 | { 0x000015f8, 0x00000000 }, | ||
2650 | { 0x00001638, 0x00000000 }, | ||
2651 | { 0x00001678, 0x00000000 }, | ||
2652 | { 0x000016b8, 0x00000000 }, | ||
2653 | { 0x000016f8, 0x00000000 }, | ||
2654 | { 0x00001738, 0x00000000 }, | ||
2655 | { 0x00001778, 0x00000000 }, | ||
2656 | { 0x000017b8, 0x00000000 }, | ||
2657 | { 0x000017f8, 0x00000000 }, | ||
2658 | { 0x0000103c, 0x00000000 }, | ||
2659 | { 0x0000107c, 0x00000000 }, | ||
2660 | { 0x000010bc, 0x00000000 }, | ||
2661 | { 0x000010fc, 0x00000000 }, | ||
2662 | { 0x0000113c, 0x00000000 }, | ||
2663 | { 0x0000117c, 0x00000000 }, | ||
2664 | { 0x000011bc, 0x00000000 }, | ||
2665 | { 0x000011fc, 0x00000000 }, | ||
2666 | { 0x0000123c, 0x00000000 }, | ||
2667 | { 0x0000127c, 0x00000000 }, | ||
2668 | { 0x000012bc, 0x00000000 }, | ||
2669 | { 0x000012fc, 0x00000000 }, | ||
2670 | { 0x0000133c, 0x00000000 }, | ||
2671 | { 0x0000137c, 0x00000000 }, | ||
2672 | { 0x000013bc, 0x00000000 }, | ||
2673 | { 0x000013fc, 0x00000000 }, | ||
2674 | { 0x0000143c, 0x00000000 }, | ||
2675 | { 0x0000147c, 0x00000000 }, | ||
2676 | { 0x00004030, 0x00000002 }, | ||
2677 | { 0x0000403c, 0x00000002 }, | ||
2678 | { 0x00004024, 0x0000001f }, | ||
2679 | { 0x00004060, 0x00000000 }, | ||
2680 | { 0x00004064, 0x00000000 }, | ||
2681 | { 0x00007010, 0x00000033 }, | ||
2682 | { 0x00007034, 0x00000002 }, | ||
2683 | { 0x00007038, 0x000004c2 }, | ||
2684 | { 0x00008004, 0x00000000 }, | ||
2685 | { 0x00008008, 0x00000000 }, | ||
2686 | { 0x0000800c, 0x00000000 }, | ||
2687 | { 0x00008018, 0x00000700 }, | ||
2688 | { 0x00008020, 0x00000000 }, | ||
2689 | { 0x00008038, 0x00000000 }, | ||
2690 | { 0x0000803c, 0x00000000 }, | ||
2691 | { 0x00008048, 0x40000000 }, | ||
2692 | { 0x00008054, 0x00000000 }, | ||
2693 | { 0x00008058, 0x00000000 }, | ||
2694 | { 0x0000805c, 0x000fc78f }, | ||
2695 | { 0x00008060, 0x0000000f }, | ||
2696 | { 0x00008064, 0x00000000 }, | ||
2697 | { 0x00008070, 0x00000000 }, | ||
2698 | { 0x000080c0, 0x2a80001a }, | ||
2699 | { 0x000080c4, 0x05dc01e0 }, | ||
2700 | { 0x000080c8, 0x1f402710 }, | ||
2701 | { 0x000080cc, 0x01f40000 }, | ||
2702 | { 0x000080d0, 0x00001e00 }, | ||
2703 | { 0x000080d4, 0x00000000 }, | ||
2704 | { 0x000080d8, 0x00400000 }, | ||
2705 | { 0x000080e0, 0xffffffff }, | ||
2706 | { 0x000080e4, 0x0000ffff }, | ||
2707 | { 0x000080e8, 0x003f3f3f }, | ||
2708 | { 0x000080ec, 0x00000000 }, | ||
2709 | { 0x000080f0, 0x00000000 }, | ||
2710 | { 0x000080f4, 0x00000000 }, | ||
2711 | { 0x000080f8, 0x00000000 }, | ||
2712 | { 0x000080fc, 0x00020000 }, | ||
2713 | { 0x00008100, 0x00020000 }, | ||
2714 | { 0x00008104, 0x00000001 }, | ||
2715 | { 0x00008108, 0x00000052 }, | ||
2716 | { 0x0000810c, 0x00000000 }, | ||
2717 | { 0x00008110, 0x00000168 }, | ||
2718 | { 0x00008118, 0x000100aa }, | ||
2719 | { 0x0000811c, 0x00003210 }, | ||
2720 | { 0x00008124, 0x00000000 }, | ||
2721 | { 0x00008128, 0x00000000 }, | ||
2722 | { 0x0000812c, 0x00000000 }, | ||
2723 | { 0x00008130, 0x00000000 }, | ||
2724 | { 0x00008134, 0x00000000 }, | ||
2725 | { 0x00008138, 0x00000000 }, | ||
2726 | { 0x0000813c, 0x00000000 }, | ||
2727 | { 0x00008144, 0xffffffff }, | ||
2728 | { 0x00008168, 0x00000000 }, | ||
2729 | { 0x0000816c, 0x00000000 }, | ||
2730 | { 0x00008170, 0x32143320 }, | ||
2731 | { 0x00008174, 0xfaa4fa50 }, | ||
2732 | { 0x00008178, 0x00000100 }, | ||
2733 | { 0x0000817c, 0x00000000 }, | ||
2734 | { 0x000081c0, 0x00000000 }, | ||
2735 | { 0x000081ec, 0x00000000 }, | ||
2736 | { 0x000081f0, 0x00000000 }, | ||
2737 | { 0x000081f4, 0x00000000 }, | ||
2738 | { 0x000081f8, 0x00000000 }, | ||
2739 | { 0x000081fc, 0x00000000 }, | ||
2740 | { 0x00008200, 0x00000000 }, | ||
2741 | { 0x00008204, 0x00000000 }, | ||
2742 | { 0x00008208, 0x00000000 }, | ||
2743 | { 0x0000820c, 0x00000000 }, | ||
2744 | { 0x00008210, 0x00000000 }, | ||
2745 | { 0x00008214, 0x00000000 }, | ||
2746 | { 0x00008218, 0x00000000 }, | ||
2747 | { 0x0000821c, 0x00000000 }, | ||
2748 | { 0x00008220, 0x00000000 }, | ||
2749 | { 0x00008224, 0x00000000 }, | ||
2750 | { 0x00008228, 0x00000000 }, | ||
2751 | { 0x0000822c, 0x00000000 }, | ||
2752 | { 0x00008230, 0x00000000 }, | ||
2753 | { 0x00008234, 0x00000000 }, | ||
2754 | { 0x00008238, 0x00000000 }, | ||
2755 | { 0x0000823c, 0x00000000 }, | ||
2756 | { 0x00008240, 0x00100000 }, | ||
2757 | { 0x00008244, 0x0010f400 }, | ||
2758 | { 0x00008248, 0x00000100 }, | ||
2759 | { 0x0000824c, 0x0001e800 }, | ||
2760 | { 0x00008250, 0x00000000 }, | ||
2761 | { 0x00008254, 0x00000000 }, | ||
2762 | { 0x00008258, 0x00000000 }, | ||
2763 | { 0x0000825c, 0x400000ff }, | ||
2764 | { 0x00008260, 0x00080922 }, | ||
2765 | { 0x00008264, 0xa8a00010 }, | ||
2766 | { 0x00008270, 0x00000000 }, | ||
2767 | { 0x00008274, 0x40000000 }, | ||
2768 | { 0x00008278, 0x003e4180 }, | ||
2769 | { 0x0000827c, 0x00000000 }, | ||
2770 | { 0x00008284, 0x0000002c }, | ||
2771 | { 0x00008288, 0x0000002c }, | ||
2772 | { 0x0000828c, 0x00000000 }, | ||
2773 | { 0x00008294, 0x00000000 }, | ||
2774 | { 0x00008298, 0x00000000 }, | ||
2775 | { 0x0000829c, 0x00000000 }, | ||
2776 | { 0x00008300, 0x00000040 }, | ||
2777 | { 0x00008314, 0x00000000 }, | ||
2778 | { 0x00008328, 0x00000000 }, | ||
2779 | { 0x0000832c, 0x00000007 }, | ||
2780 | { 0x00008330, 0x00000302 }, | ||
2781 | { 0x00008334, 0x00000e00 }, | ||
2782 | { 0x00008338, 0x00ff0000 }, | ||
2783 | { 0x0000833c, 0x00000000 }, | ||
2784 | { 0x00008340, 0x000107ff }, | ||
2785 | { 0x00008344, 0x00581043 }, | ||
2786 | { 0x00009808, 0x00000000 }, | ||
2787 | { 0x0000980c, 0xafa68e30 }, | ||
2788 | { 0x00009810, 0xfd14e000 }, | ||
2789 | { 0x00009814, 0x9c0a9f6b }, | ||
2790 | { 0x0000981c, 0x00000000 }, | ||
2791 | { 0x0000982c, 0x0000a000 }, | ||
2792 | { 0x00009830, 0x00000000 }, | ||
2793 | { 0x0000983c, 0x00200400 }, | ||
2794 | { 0x0000984c, 0x0040233c }, | ||
2795 | { 0x0000a84c, 0x0040233c }, | ||
2796 | { 0x00009854, 0x00000044 }, | ||
2797 | { 0x00009900, 0x00000000 }, | ||
2798 | { 0x00009904, 0x00000000 }, | ||
2799 | { 0x00009908, 0x00000000 }, | ||
2800 | { 0x0000990c, 0x00000000 }, | ||
2801 | { 0x00009910, 0x01002310 }, | ||
2802 | { 0x0000991c, 0x10000fff }, | ||
2803 | { 0x00009920, 0x04900000 }, | ||
2804 | { 0x0000a920, 0x04900000 }, | ||
2805 | { 0x00009928, 0x00000001 }, | ||
2806 | { 0x0000992c, 0x00000004 }, | ||
2807 | { 0x00009934, 0x1e1f2022 }, | ||
2808 | { 0x00009938, 0x0a0b0c0d }, | ||
2809 | { 0x0000993c, 0x00000000 }, | ||
2810 | { 0x00009948, 0x9280c00a }, | ||
2811 | { 0x0000994c, 0x00020028 }, | ||
2812 | { 0x00009954, 0x5f3ca3de }, | ||
2813 | { 0x00009958, 0x2108ecff }, | ||
2814 | { 0x00009940, 0x14750604 }, | ||
2815 | { 0x0000c95c, 0x004b6a8e }, | ||
2816 | { 0x0000c968, 0x000003ce }, | ||
2817 | { 0x00009970, 0x190fb515 }, | ||
2818 | { 0x00009974, 0x00000000 }, | ||
2819 | { 0x00009978, 0x00000001 }, | ||
2820 | { 0x0000997c, 0x00000000 }, | ||
2821 | { 0x00009980, 0x00000000 }, | ||
2822 | { 0x00009984, 0x00000000 }, | ||
2823 | { 0x00009988, 0x00000000 }, | ||
2824 | { 0x0000998c, 0x00000000 }, | ||
2825 | { 0x00009990, 0x00000000 }, | ||
2826 | { 0x00009994, 0x00000000 }, | ||
2827 | { 0x00009998, 0x00000000 }, | ||
2828 | { 0x0000999c, 0x00000000 }, | ||
2829 | { 0x000099a0, 0x00000000 }, | ||
2830 | { 0x000099a4, 0x00000001 }, | ||
2831 | { 0x000099a8, 0x201fff00 }, | ||
2832 | { 0x000099ac, 0x006f0000 }, | ||
2833 | { 0x000099b0, 0x03051000 }, | ||
2834 | { 0x000099b4, 0x00000820 }, | ||
2835 | { 0x000099dc, 0x00000000 }, | ||
2836 | { 0x000099e0, 0x00000000 }, | ||
2837 | { 0x000099e4, 0xaaaaaaaa }, | ||
2838 | { 0x000099e8, 0x3c466478 }, | ||
2839 | { 0x000099ec, 0x0cc80caa }, | ||
2840 | { 0x000099f0, 0x00000000 }, | ||
2841 | { 0x000099fc, 0x00001042 }, | ||
2842 | { 0x0000a208, 0x803e4788 }, | ||
2843 | { 0x0000a210, 0x4080a333 }, | ||
2844 | { 0x0000a214, 0x40206c10 }, | ||
2845 | { 0x0000a218, 0x009c4060 }, | ||
2846 | { 0x0000a220, 0x01834061 }, | ||
2847 | { 0x0000a224, 0x00000400 }, | ||
2848 | { 0x0000a228, 0x000003b5 }, | ||
2849 | { 0x0000a22c, 0x233f7180 }, | ||
2850 | { 0x0000a234, 0x20202020 }, | ||
2851 | { 0x0000a238, 0x20202020 }, | ||
2852 | { 0x0000a23c, 0x13c88000 }, | ||
2853 | { 0x0000a240, 0x38490a20 }, | ||
2854 | { 0x0000a244, 0x00007bb6 }, | ||
2855 | { 0x0000a248, 0x0fff3ffc }, | ||
2856 | { 0x0000a24c, 0x00000000 }, | ||
2857 | { 0x0000a254, 0x00000000 }, | ||
2858 | { 0x0000a258, 0x0cdbd380 }, | ||
2859 | { 0x0000a25c, 0x0f0f0f01 }, | ||
2860 | { 0x0000a260, 0xdfa91f01 }, | ||
2861 | { 0x0000a268, 0x00000000 }, | ||
2862 | { 0x0000a26c, 0x0ebae9c6 }, | ||
2863 | { 0x0000b26c, 0x0ebae9c6 }, | ||
2864 | { 0x0000d270, 0x00820820 }, | ||
2865 | { 0x0000a278, 0x1ce739ce }, | ||
2866 | { 0x0000d35c, 0x07ffffef }, | ||
2867 | { 0x0000d360, 0x0fffffe7 }, | ||
2868 | { 0x0000d364, 0x17ffffe5 }, | ||
2869 | { 0x0000d368, 0x1fffffe4 }, | ||
2870 | { 0x0000d36c, 0x37ffffe3 }, | ||
2871 | { 0x0000d370, 0x3fffffe3 }, | ||
2872 | { 0x0000d374, 0x57ffffe3 }, | ||
2873 | { 0x0000d378, 0x5fffffe2 }, | ||
2874 | { 0x0000d37c, 0x7fffffe2 }, | ||
2875 | { 0x0000d380, 0x7f3c7bba }, | ||
2876 | { 0x0000d384, 0xf3307ff0 }, | ||
2877 | { 0x0000a388, 0x0c000000 }, | ||
2878 | { 0x0000a38c, 0x20202020 }, | ||
2879 | { 0x0000a390, 0x20202020 }, | ||
2880 | { 0x0000a394, 0x1ce739ce }, | ||
2881 | { 0x0000a398, 0x000001ce }, | ||
2882 | { 0x0000a39c, 0x00000001 }, | ||
2883 | { 0x0000a3a0, 0x00000000 }, | ||
2884 | { 0x0000a3a4, 0x00000000 }, | ||
2885 | { 0x0000a3a8, 0x00000000 }, | ||
2886 | { 0x0000a3ac, 0x00000000 }, | ||
2887 | { 0x0000a3b0, 0x00000000 }, | ||
2888 | { 0x0000a3b4, 0x00000000 }, | ||
2889 | { 0x0000a3b8, 0x00000000 }, | ||
2890 | { 0x0000a3bc, 0x00000000 }, | ||
2891 | { 0x0000a3c0, 0x00000000 }, | ||
2892 | { 0x0000a3c4, 0x00000000 }, | ||
2893 | { 0x0000a3c8, 0x00000246 }, | ||
2894 | { 0x0000a3cc, 0x20202020 }, | ||
2895 | { 0x0000a3d0, 0x20202020 }, | ||
2896 | { 0x0000a3d4, 0x20202020 }, | ||
2897 | { 0x0000a3dc, 0x1ce739ce }, | ||
2898 | { 0x0000a3e0, 0x000001ce }, | ||
2899 | { 0x0000a3e4, 0x00000000 }, | ||
2900 | { 0x0000a3e8, 0x18c43433 }, | ||
2901 | { 0x0000a3ec, 0x00f70081 }, | ||
2902 | { 0x00007800, 0x00040000 }, | ||
2903 | { 0x00007804, 0xdb005012 }, | ||
2904 | { 0x00007808, 0x04924914 }, | ||
2905 | { 0x0000780c, 0x21084210 }, | ||
2906 | { 0x00007810, 0x6d801300 }, | ||
2907 | { 0x00007818, 0x07e41000 }, | ||
2908 | { 0x00007824, 0x00040000 }, | ||
2909 | { 0x00007828, 0xdb005012 }, | ||
2910 | { 0x0000782c, 0x04924914 }, | ||
2911 | { 0x00007830, 0x21084210 }, | ||
2912 | { 0x00007834, 0x6d801300 }, | ||
2913 | { 0x0000783c, 0x07e40000 }, | ||
2914 | { 0x00007848, 0x00100000 }, | ||
2915 | { 0x0000784c, 0x773f0567 }, | ||
2916 | { 0x00007850, 0x54214514 }, | ||
2917 | { 0x00007854, 0x12035828 }, | ||
2918 | { 0x00007858, 0x9259269a }, | ||
2919 | { 0x00007860, 0x52802000 }, | ||
2920 | { 0x00007864, 0x0a8e370e }, | ||
2921 | { 0x00007868, 0xc0102850 }, | ||
2922 | { 0x0000786c, 0x812d4000 }, | ||
2923 | { 0x00007870, 0x807ec400 }, | ||
2924 | { 0x00007874, 0x001b6db0 }, | ||
2925 | { 0x00007878, 0x00376b63 }, | ||
2926 | { 0x0000787c, 0x06db6db6 }, | ||
2927 | { 0x00007880, 0x006d8000 }, | ||
2928 | { 0x00007884, 0xffeffffe }, | ||
2929 | { 0x00007888, 0xffeffffe }, | ||
2930 | { 0x0000788c, 0x00010000 }, | ||
2931 | { 0x00007890, 0x02060aeb }, | ||
2932 | { 0x00007898, 0x2a850160 }, | ||
2933 | }; | ||
2934 | |||
2935 | static const u32 ar9280Modes_fast_clock_9280_2[][3] = { | ||
2936 | { 0x00001030, 0x00000268, 0x000004d0 }, | ||
2937 | { 0x00001070, 0x0000018c, 0x00000318 }, | ||
2938 | { 0x000010b0, 0x00000fd0, 0x00001fa0 }, | ||
2939 | { 0x00008014, 0x044c044c, 0x08980898 }, | ||
2940 | { 0x0000801c, 0x148ec02b, 0x148ec057 }, | ||
2941 | { 0x00008318, 0x000044c0, 0x00008980 }, | ||
2942 | { 0x00009820, 0x02020200, 0x02020200 }, | ||
2943 | { 0x00009824, 0x00000f0f, 0x00000f0f }, | ||
2944 | { 0x00009828, 0x0b020001, 0x0b020001 }, | ||
2945 | { 0x00009834, 0x00000f0f, 0x00000f0f }, | ||
2946 | { 0x00009844, 0x03721821, 0x03721821 }, | ||
2947 | { 0x00009914, 0x00000898, 0x00001130 }, | ||
2948 | { 0x00009918, 0x0000000b, 0x00000016 }, | ||
2949 | }; | ||
2950 | |||
2951 | static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = { | ||
2952 | { 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290 }, | ||
2953 | { 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300 }, | ||
2954 | { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304 }, | ||
2955 | { 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308 }, | ||
2956 | { 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c }, | ||
2957 | { 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000 }, | ||
2958 | { 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004 }, | ||
2959 | { 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008 }, | ||
2960 | { 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c }, | ||
2961 | { 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080 }, | ||
2962 | { 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084 }, | ||
2963 | { 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088 }, | ||
2964 | { 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c }, | ||
2965 | { 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100 }, | ||
2966 | { 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104 }, | ||
2967 | { 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108 }, | ||
2968 | { 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c }, | ||
2969 | { 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110 }, | ||
2970 | { 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114 }, | ||
2971 | { 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180 }, | ||
2972 | { 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184 }, | ||
2973 | { 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188 }, | ||
2974 | { 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c }, | ||
2975 | { 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190 }, | ||
2976 | { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 }, | ||
2977 | { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 }, | ||
2978 | { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c }, | ||
2979 | { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 }, | ||
2980 | { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 }, | ||
2981 | { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 }, | ||
2982 | { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 }, | ||
2983 | { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 }, | ||
2984 | { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 }, | ||
2985 | { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 }, | ||
2986 | { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 }, | ||
2987 | { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c }, | ||
2988 | { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 }, | ||
2989 | { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 }, | ||
2990 | { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 }, | ||
2991 | { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 }, | ||
2992 | { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 }, | ||
2993 | { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c }, | ||
2994 | { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 }, | ||
2995 | { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 }, | ||
2996 | { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 }, | ||
2997 | { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 }, | ||
2998 | { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 }, | ||
2999 | { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c }, | ||
3000 | { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b10, 0x00008b10, 0x00008b10 }, | ||
3001 | { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b14, 0x00008b14, 0x00008b14 }, | ||
3002 | { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b01, 0x00008b01, 0x00008b01 }, | ||
3003 | { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b05, 0x00008b05, 0x00008b05 }, | ||
3004 | { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b09, 0x00008b09, 0x00008b09 }, | ||
3005 | { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008b0d, 0x00008b0d, 0x00008b0d }, | ||
3006 | { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008b11, 0x00008b11, 0x00008b11 }, | ||
3007 | { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008b15, 0x00008b15, 0x00008b15 }, | ||
3008 | { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008b02, 0x00008b02, 0x00008b02 }, | ||
3009 | { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008b06, 0x00008b06, 0x00008b06 }, | ||
3010 | { 0x00009ae8, 0x0000b780, 0x0000b780, 0x00008b0a, 0x00008b0a, 0x00008b0a }, | ||
3011 | { 0x00009aec, 0x0000b784, 0x0000b784, 0x00008b0e, 0x00008b0e, 0x00008b0e }, | ||
3012 | { 0x00009af0, 0x0000b788, 0x0000b788, 0x00008b12, 0x00008b12, 0x00008b12 }, | ||
3013 | { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00008b16, 0x00008b16, 0x00008b16 }, | ||
3014 | { 0x00009af8, 0x0000b790, 0x0000b790, 0x00008b03, 0x00008b03, 0x00008b03 }, | ||
3015 | { 0x00009afc, 0x0000b794, 0x0000b794, 0x00008b07, 0x00008b07, 0x00008b07 }, | ||
3016 | { 0x00009b00, 0x0000b798, 0x0000b798, 0x00008b0b, 0x00008b0b, 0x00008b0b }, | ||
3017 | { 0x00009b04, 0x0000d784, 0x0000d784, 0x00008b0f, 0x00008b0f, 0x00008b0f }, | ||
3018 | { 0x00009b08, 0x0000d788, 0x0000d788, 0x00008b13, 0x00008b13, 0x00008b13 }, | ||
3019 | { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00008b17, 0x00008b17, 0x00008b17 }, | ||
3020 | { 0x00009b10, 0x0000d790, 0x0000d790, 0x00008b23, 0x00008b23, 0x00008b23 }, | ||
3021 | { 0x00009b14, 0x0000f780, 0x0000f780, 0x00008b27, 0x00008b27, 0x00008b27 }, | ||
3022 | { 0x00009b18, 0x0000f784, 0x0000f784, 0x00008b2b, 0x00008b2b, 0x00008b2b }, | ||
3023 | { 0x00009b1c, 0x0000f788, 0x0000f788, 0x00008b2f, 0x00008b2f, 0x00008b2f }, | ||
3024 | { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x00008b33, 0x00008b33, 0x00008b33 }, | ||
3025 | { 0x00009b24, 0x0000f790, 0x0000f790, 0x00008b37, 0x00008b37, 0x00008b37 }, | ||
3026 | { 0x00009b28, 0x0000f794, 0x0000f794, 0x00008b43, 0x00008b43, 0x00008b43 }, | ||
3027 | { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x00008b47, 0x00008b47, 0x00008b47 }, | ||
3028 | { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00008b4b, 0x00008b4b, 0x00008b4b }, | ||
3029 | { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00008b4f, 0x00008b4f, 0x00008b4f }, | ||
3030 | { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00008b53, 0x00008b53, 0x00008b53 }, | ||
3031 | { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00008b57, 0x00008b57, 0x00008b57 }, | ||
3032 | { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3033 | { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3034 | { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3035 | { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3036 | { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3037 | { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3038 | { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3039 | { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3040 | { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3041 | { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3042 | { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3043 | { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3044 | { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3045 | { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3046 | { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3047 | { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3048 | { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3049 | { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3050 | { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3051 | { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3052 | { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3053 | { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3054 | { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3055 | { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3056 | { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3057 | { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3058 | { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3059 | { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3060 | { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3061 | { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3062 | { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3063 | { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3064 | { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3065 | { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3066 | { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3067 | { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3068 | { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3069 | { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3070 | { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3071 | { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3072 | { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3073 | { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3074 | { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3075 | { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3076 | { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3077 | { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3078 | { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3079 | { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, | ||
3080 | { 0x00009848, 0x00001066, 0x00001066, 0x00001050, 0x00001050, 0x00001050 }, | ||
3081 | { 0x0000a848, 0x00001066, 0x00001066, 0x00001050, 0x00001050, 0x00001050 }, | ||
3082 | }; | ||
3083 | |||
3084 | static const u32 ar9280Modes_original_rxgain_9280_2[][6] = { | ||
3085 | { 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290 }, | ||
3086 | { 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300 }, | ||
3087 | { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304 }, | ||
3088 | { 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308 }, | ||
3089 | { 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c }, | ||
3090 | { 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000 }, | ||
3091 | { 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004 }, | ||
3092 | { 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008 }, | ||
3093 | { 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c }, | ||
3094 | { 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080 }, | ||
3095 | { 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084 }, | ||
3096 | { 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088 }, | ||
3097 | { 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c }, | ||
3098 | { 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100 }, | ||
3099 | { 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104 }, | ||
3100 | { 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108 }, | ||
3101 | { 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c }, | ||
3102 | { 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110 }, | ||
3103 | { 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114 }, | ||
3104 | { 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180 }, | ||
3105 | { 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184 }, | ||
3106 | { 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188 }, | ||
3107 | { 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c }, | ||
3108 | { 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190 }, | ||
3109 | { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 }, | ||
3110 | { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 }, | ||
3111 | { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c }, | ||
3112 | { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 }, | ||
3113 | { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 }, | ||
3114 | { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 }, | ||
3115 | { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 }, | ||
3116 | { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 }, | ||
3117 | { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 }, | ||
3118 | { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 }, | ||
3119 | { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 }, | ||
3120 | { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c }, | ||
3121 | { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 }, | ||
3122 | { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 }, | ||
3123 | { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 }, | ||
3124 | { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 }, | ||
3125 | { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 }, | ||
3126 | { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c }, | ||
3127 | { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 }, | ||
3128 | { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 }, | ||
3129 | { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 }, | ||
3130 | { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 }, | ||
3131 | { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 }, | ||
3132 | { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c }, | ||
3133 | { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 }, | ||
3134 | { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 }, | ||
3135 | { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 }, | ||
3136 | { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c }, | ||
3137 | { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 }, | ||
3138 | { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 }, | ||
3139 | { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 }, | ||
3140 | { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 }, | ||
3141 | { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c }, | ||
3142 | { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 }, | ||
3143 | { 0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c }, | ||
3144 | { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310 }, | ||
3145 | { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384 }, | ||
3146 | { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388 }, | ||
3147 | { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324 }, | ||
3148 | { 0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704 }, | ||
3149 | { 0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4 }, | ||
3150 | { 0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8 }, | ||
3151 | { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710 }, | ||
3152 | { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714 }, | ||
3153 | { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720 }, | ||
3154 | { 0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724 }, | ||
3155 | { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728 }, | ||
3156 | { 0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c }, | ||
3157 | { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0 }, | ||
3158 | { 0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4 }, | ||
3159 | { 0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8 }, | ||
3160 | { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0 }, | ||
3161 | { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4 }, | ||
3162 | { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8 }, | ||
3163 | { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5 }, | ||
3164 | { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9 }, | ||
3165 | { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad }, | ||
3166 | { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1 }, | ||
3167 | { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5 }, | ||
3168 | { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9 }, | ||
3169 | { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5 }, | ||
3170 | { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9 }, | ||
3171 | { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1 }, | ||
3172 | { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5 }, | ||
3173 | { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9 }, | ||
3174 | { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6 }, | ||
3175 | { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca }, | ||
3176 | { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce }, | ||
3177 | { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2 }, | ||
3178 | { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6 }, | ||
3179 | { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3 }, | ||
3180 | { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7 }, | ||
3181 | { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb }, | ||
3182 | { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf }, | ||
3183 | { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7 }, | ||
3184 | { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db }, | ||
3185 | { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db }, | ||
3186 | { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db }, | ||
3187 | { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3188 | { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3189 | { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3190 | { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3191 | { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3192 | { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3193 | { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3194 | { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3195 | { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3196 | { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3197 | { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3198 | { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3199 | { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3200 | { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3201 | { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3202 | { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3203 | { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3204 | { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3205 | { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3206 | { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3207 | { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3208 | { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3209 | { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3210 | { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3211 | { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3212 | { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, | ||
3213 | { 0x00009848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063 }, | ||
3214 | { 0x0000a848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063 }, | ||
3215 | }; | ||
3216 | |||
3217 | static const u32 ar9280Modes_backoff_13db_rxgain_9280_2[][6] = { | ||
3218 | { 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290 }, | ||
3219 | { 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300 }, | ||
3220 | { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304 }, | ||
3221 | { 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308 }, | ||
3222 | { 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c }, | ||
3223 | { 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000 }, | ||
3224 | { 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004 }, | ||
3225 | { 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008 }, | ||
3226 | { 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c }, | ||
3227 | { 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080 }, | ||
3228 | { 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084 }, | ||
3229 | { 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088 }, | ||
3230 | { 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c }, | ||
3231 | { 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100 }, | ||
3232 | { 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104 }, | ||
3233 | { 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108 }, | ||
3234 | { 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c }, | ||
3235 | { 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110 }, | ||
3236 | { 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114 }, | ||
3237 | { 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180 }, | ||
3238 | { 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184 }, | ||
3239 | { 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188 }, | ||
3240 | { 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c }, | ||
3241 | { 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190 }, | ||
3242 | { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 }, | ||
3243 | { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 }, | ||
3244 | { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c }, | ||
3245 | { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 }, | ||
3246 | { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 }, | ||
3247 | { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 }, | ||
3248 | { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 }, | ||
3249 | { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 }, | ||
3250 | { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 }, | ||
3251 | { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 }, | ||
3252 | { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 }, | ||
3253 | { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c }, | ||
3254 | { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 }, | ||
3255 | { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 }, | ||
3256 | { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 }, | ||
3257 | { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 }, | ||
3258 | { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 }, | ||
3259 | { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c }, | ||
3260 | { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 }, | ||
3261 | { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 }, | ||
3262 | { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 }, | ||
3263 | { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 }, | ||
3264 | { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 }, | ||
3265 | { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c }, | ||
3266 | { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 }, | ||
3267 | { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 }, | ||
3268 | { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 }, | ||
3269 | { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c }, | ||
3270 | { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 }, | ||
3271 | { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 }, | ||
3272 | { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 }, | ||
3273 | { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 }, | ||
3274 | { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c }, | ||
3275 | { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 }, | ||
3276 | { 0x00009ae8, 0x0000b780, 0x0000b780, 0x00009310, 0x00009310, 0x00009310 }, | ||
3277 | { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009314, 0x00009314, 0x00009314 }, | ||
3278 | { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009320, 0x00009320, 0x00009320 }, | ||
3279 | { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009324, 0x00009324, 0x00009324 }, | ||
3280 | { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009328, 0x00009328, 0x00009328 }, | ||
3281 | { 0x00009afc, 0x0000b794, 0x0000b794, 0x0000932c, 0x0000932c, 0x0000932c }, | ||
3282 | { 0x00009b00, 0x0000b798, 0x0000b798, 0x00009330, 0x00009330, 0x00009330 }, | ||
3283 | { 0x00009b04, 0x0000d784, 0x0000d784, 0x00009334, 0x00009334, 0x00009334 }, | ||
3284 | { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009321, 0x00009321, 0x00009321 }, | ||
3285 | { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009325, 0x00009325, 0x00009325 }, | ||
3286 | { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009329, 0x00009329, 0x00009329 }, | ||
3287 | { 0x00009b14, 0x0000f780, 0x0000f780, 0x0000932d, 0x0000932d, 0x0000932d }, | ||
3288 | { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009331, 0x00009331, 0x00009331 }, | ||
3289 | { 0x00009b1c, 0x0000f788, 0x0000f788, 0x00009335, 0x00009335, 0x00009335 }, | ||
3290 | { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x00009322, 0x00009322, 0x00009322 }, | ||
3291 | { 0x00009b24, 0x0000f790, 0x0000f790, 0x00009326, 0x00009326, 0x00009326 }, | ||
3292 | { 0x00009b28, 0x0000f794, 0x0000f794, 0x0000932a, 0x0000932a, 0x0000932a }, | ||
3293 | { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x0000932e, 0x0000932e, 0x0000932e }, | ||
3294 | { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00009332, 0x00009332, 0x00009332 }, | ||
3295 | { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00009336, 0x00009336, 0x00009336 }, | ||
3296 | { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00009323, 0x00009323, 0x00009323 }, | ||
3297 | { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00009327, 0x00009327, 0x00009327 }, | ||
3298 | { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x0000932b, 0x0000932b, 0x0000932b }, | ||
3299 | { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x0000932f, 0x0000932f, 0x0000932f }, | ||
3300 | { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00009333, 0x00009333, 0x00009333 }, | ||
3301 | { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00009337, 0x00009337, 0x00009337 }, | ||
3302 | { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00009343, 0x00009343, 0x00009343 }, | ||
3303 | { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00009347, 0x00009347, 0x00009347 }, | ||
3304 | { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x0000934b, 0x0000934b, 0x0000934b }, | ||
3305 | { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x0000934f, 0x0000934f, 0x0000934f }, | ||
3306 | { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00009353, 0x00009353, 0x00009353 }, | ||
3307 | { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00009357, 0x00009357, 0x00009357 }, | ||
3308 | { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3309 | { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3310 | { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3311 | { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3312 | { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3313 | { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3314 | { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3315 | { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3316 | { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3317 | { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3318 | { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3319 | { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3320 | { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3321 | { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3322 | { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3323 | { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3324 | { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3325 | { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3326 | { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3327 | { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3328 | { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3329 | { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3330 | { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3331 | { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3332 | { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3333 | { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3334 | { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3335 | { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3336 | { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3337 | { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3338 | { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3339 | { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3340 | { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3341 | { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3342 | { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3343 | { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3344 | { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3345 | { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, | ||
3346 | { 0x00009848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a }, | ||
3347 | { 0x0000a848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a }, | ||
3348 | }; | ||
3349 | |||
3350 | static const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = { | ||
3351 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
3352 | { 0x0000a304, 0x00003002, 0x00003002, 0x00004002, 0x00004002, 0x00004002 }, | ||
3353 | { 0x0000a308, 0x00006004, 0x00006004, 0x00007008, 0x00007008, 0x00007008 }, | ||
3354 | { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000c010, 0x0000c010, 0x0000c010 }, | ||
3355 | { 0x0000a310, 0x0000e012, 0x0000e012, 0x00010012, 0x00010012, 0x00010012 }, | ||
3356 | { 0x0000a314, 0x00011014, 0x00011014, 0x00013014, 0x00013014, 0x00013014 }, | ||
3357 | { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a, 0x0001820a }, | ||
3358 | { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211, 0x0001b211 }, | ||
3359 | { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 }, | ||
3360 | { 0x0000a324, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411 }, | ||
3361 | { 0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413 }, | ||
3362 | { 0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811 }, | ||
3363 | { 0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813 }, | ||
3364 | { 0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14 }, | ||
3365 | { 0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50 }, | ||
3366 | { 0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c }, | ||
3367 | { 0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a }, | ||
3368 | { 0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92 }, | ||
3369 | { 0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2 }, | ||
3370 | { 0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5 }, | ||
3371 | { 0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54 }, | ||
3372 | { 0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5 }, | ||
3373 | { 0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff }, | ||
3374 | { 0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff }, | ||
3375 | { 0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 }, | ||
3376 | { 0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 }, | ||
3377 | { 0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 }, | ||
3378 | { 0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 }, | ||
3379 | { 0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 }, | ||
3380 | { 0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce }, | ||
3381 | }; | ||
3382 | |||
3383 | static const u32 ar9280Modes_original_tx_gain_9280_2[][6] = { | ||
3384 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
3385 | { 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002 }, | ||
3386 | { 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009 }, | ||
3387 | { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b }, | ||
3388 | { 0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012 }, | ||
3389 | { 0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048 }, | ||
3390 | { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a }, | ||
3391 | { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211 }, | ||
3392 | { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 }, | ||
3393 | { 0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b }, | ||
3394 | { 0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412 }, | ||
3395 | { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414 }, | ||
3396 | { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a }, | ||
3397 | { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649 }, | ||
3398 | { 0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b }, | ||
3399 | { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49 }, | ||
3400 | { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48 }, | ||
3401 | { 0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a }, | ||
3402 | { 0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88 }, | ||
3403 | { 0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a }, | ||
3404 | { 0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9 }, | ||
3405 | { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 }, | ||
3406 | { 0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff }, | ||
3407 | { 0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff }, | ||
3408 | { 0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 }, | ||
3409 | { 0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 }, | ||
3410 | { 0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 }, | ||
3411 | { 0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 }, | ||
3412 | { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 }, | ||
3413 | { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce }, | ||
3414 | }; | ||
3415 | |||
3416 | static const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = { | ||
3417 | {0x00004040, 0x9248fd00 }, | ||
3418 | {0x00004040, 0x24924924 }, | ||
3419 | {0x00004040, 0xa8000019 }, | ||
3420 | {0x00004040, 0x13160820 }, | ||
3421 | {0x00004040, 0xe5980560 }, | ||
3422 | {0x00004040, 0xc01dcffc }, | ||
3423 | {0x00004040, 0x1aaabe41 }, | ||
3424 | {0x00004040, 0xbe105554 }, | ||
3425 | {0x00004040, 0x00043007 }, | ||
3426 | {0x00004044, 0x00000000 }, | ||
3427 | }; | ||
3428 | |||
3429 | static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = { | ||
3430 | {0x00004040, 0x9248fd00 }, | ||
3431 | {0x00004040, 0x24924924 }, | ||
3432 | {0x00004040, 0xa8000019 }, | ||
3433 | {0x00004040, 0x13160820 }, | ||
3434 | {0x00004040, 0xe5980560 }, | ||
3435 | {0x00004040, 0xc01dcffd }, | ||
3436 | {0x00004040, 0x1aaabe41 }, | ||
3437 | {0x00004040, 0xbe105554 }, | ||
3438 | {0x00004040, 0x00043007 }, | ||
3439 | {0x00004044, 0x00000000 }, | ||
3440 | }; | ||
3441 | |||
3442 | /* AR9285 */ | ||
3443 | static const u_int32_t ar9285Modes_9285[][6] = { | ||
3444 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | ||
3445 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | ||
3446 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | ||
3447 | { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 }, | ||
3448 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, | ||
3449 | { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f }, | ||
3450 | { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 }, | ||
3451 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, | ||
3452 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, | ||
3453 | { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
3454 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, | ||
3455 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
3456 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, | ||
3457 | { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e }, | ||
3458 | { 0x00009844, 0x0372161e, 0x0372161e, 0x03720020, 0x03720020, 0x037216a0 }, | ||
3459 | { 0x00009848, 0x00001066, 0x00001066, 0x0000004e, 0x0000004e, 0x00001059 }, | ||
3460 | { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 }, | ||
3461 | { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e }, | ||
3462 | { 0x0000985c, 0x3139605e, 0x3139605e, 0x3136605e, 0x3136605e, 0x3139605e }, | ||
3463 | { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 }, | ||
3464 | { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, | ||
3465 | { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 }, | ||
3466 | { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 }, | ||
3467 | { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, | ||
3468 | { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, | ||
3469 | { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d }, | ||
3470 | { 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1020, 0xdfbc1020, 0xdfbc1010 }, | ||
3471 | { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
3472 | { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
3473 | { 0x000099b8, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c }, | ||
3474 | { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 }, | ||
3475 | { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 }, | ||
3476 | { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, | ||
3477 | { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 }, | ||
3478 | { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, | ||
3479 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, | ||
3480 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
3481 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
3482 | { 0x00009a00, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 }, | ||
3483 | { 0x00009a04, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 }, | ||
3484 | { 0x00009a08, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 }, | ||
3485 | { 0x00009a0c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 }, | ||
3486 | { 0x00009a10, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 }, | ||
3487 | { 0x00009a14, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 }, | ||
3488 | { 0x00009a18, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 }, | ||
3489 | { 0x00009a1c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 }, | ||
3490 | { 0x00009a20, 0x00000000, 0x00000000, 0x00068114, 0x00068114, 0x00000000 }, | ||
3491 | { 0x00009a24, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 }, | ||
3492 | { 0x00009a28, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 }, | ||
3493 | { 0x00009a2c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 }, | ||
3494 | { 0x00009a30, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 }, | ||
3495 | { 0x00009a34, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 }, | ||
3496 | { 0x00009a38, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 }, | ||
3497 | { 0x00009a3c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 }, | ||
3498 | { 0x00009a40, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 }, | ||
3499 | { 0x00009a44, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 }, | ||
3500 | { 0x00009a48, 0x00000000, 0x00000000, 0x00068284, 0x00068284, 0x00000000 }, | ||
3501 | { 0x00009a4c, 0x00000000, 0x00000000, 0x00068288, 0x00068288, 0x00000000 }, | ||
3502 | { 0x00009a50, 0x00000000, 0x00000000, 0x00068220, 0x00068220, 0x00000000 }, | ||
3503 | { 0x00009a54, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 }, | ||
3504 | { 0x00009a58, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 }, | ||
3505 | { 0x00009a5c, 0x00000000, 0x00000000, 0x00068304, 0x00068304, 0x00000000 }, | ||
3506 | { 0x00009a60, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 }, | ||
3507 | { 0x00009a64, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 }, | ||
3508 | { 0x00009a68, 0x00000000, 0x00000000, 0x00068380, 0x00068380, 0x00000000 }, | ||
3509 | { 0x00009a6c, 0x00000000, 0x00000000, 0x00068384, 0x00068384, 0x00000000 }, | ||
3510 | { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 }, | ||
3511 | { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 }, | ||
3512 | { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 }, | ||
3513 | { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, | ||
3514 | { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, | ||
3515 | { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, | ||
3516 | { 0x00009a88, 0x00000000, 0x00000000, 0x00068b04, 0x00068b04, 0x00000000 }, | ||
3517 | { 0x00009a8c, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 }, | ||
3518 | { 0x00009a90, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 }, | ||
3519 | { 0x00009a94, 0x00000000, 0x00000000, 0x00068b0c, 0x00068b0c, 0x00000000 }, | ||
3520 | { 0x00009a98, 0x00000000, 0x00000000, 0x00068b80, 0x00068b80, 0x00000000 }, | ||
3521 | { 0x00009a9c, 0x00000000, 0x00000000, 0x00068b84, 0x00068b84, 0x00000000 }, | ||
3522 | { 0x00009aa0, 0x00000000, 0x00000000, 0x00068b88, 0x00068b88, 0x00000000 }, | ||
3523 | { 0x00009aa4, 0x00000000, 0x00000000, 0x00068b8c, 0x00068b8c, 0x00000000 }, | ||
3524 | { 0x00009aa8, 0x00000000, 0x00000000, 0x000b8b90, 0x000b8b90, 0x00000000 }, | ||
3525 | { 0x00009aac, 0x00000000, 0x00000000, 0x000b8f80, 0x000b8f80, 0x00000000 }, | ||
3526 | { 0x00009ab0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 }, | ||
3527 | { 0x00009ab4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 }, | ||
3528 | { 0x00009ab8, 0x00000000, 0x00000000, 0x000b8f8c, 0x000b8f8c, 0x00000000 }, | ||
3529 | { 0x00009abc, 0x00000000, 0x00000000, 0x000b8f90, 0x000b8f90, 0x00000000 }, | ||
3530 | { 0x00009ac0, 0x00000000, 0x00000000, 0x000bb30c, 0x000bb30c, 0x00000000 }, | ||
3531 | { 0x00009ac4, 0x00000000, 0x00000000, 0x000bb310, 0x000bb310, 0x00000000 }, | ||
3532 | { 0x00009ac8, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 }, | ||
3533 | { 0x00009acc, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 }, | ||
3534 | { 0x00009ad0, 0x00000000, 0x00000000, 0x000bb324, 0x000bb324, 0x00000000 }, | ||
3535 | { 0x00009ad4, 0x00000000, 0x00000000, 0x000bb704, 0x000bb704, 0x00000000 }, | ||
3536 | { 0x00009ad8, 0x00000000, 0x00000000, 0x000f96a4, 0x000f96a4, 0x00000000 }, | ||
3537 | { 0x00009adc, 0x00000000, 0x00000000, 0x000f96a8, 0x000f96a8, 0x00000000 }, | ||
3538 | { 0x00009ae0, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 }, | ||
3539 | { 0x00009ae4, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 }, | ||
3540 | { 0x00009ae8, 0x00000000, 0x00000000, 0x000f9720, 0x000f9720, 0x00000000 }, | ||
3541 | { 0x00009aec, 0x00000000, 0x00000000, 0x000f9724, 0x000f9724, 0x00000000 }, | ||
3542 | { 0x00009af0, 0x00000000, 0x00000000, 0x000f9728, 0x000f9728, 0x00000000 }, | ||
3543 | { 0x00009af4, 0x00000000, 0x00000000, 0x000f972c, 0x000f972c, 0x00000000 }, | ||
3544 | { 0x00009af8, 0x00000000, 0x00000000, 0x000f97a0, 0x000f97a0, 0x00000000 }, | ||
3545 | { 0x00009afc, 0x00000000, 0x00000000, 0x000f97a4, 0x000f97a4, 0x00000000 }, | ||
3546 | { 0x00009b00, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 }, | ||
3547 | { 0x00009b04, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 }, | ||
3548 | { 0x00009b08, 0x00000000, 0x00000000, 0x000fb7b4, 0x000fb7b4, 0x00000000 }, | ||
3549 | { 0x00009b0c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 }, | ||
3550 | { 0x00009b10, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 }, | ||
3551 | { 0x00009b14, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 }, | ||
3552 | { 0x00009b18, 0x00000000, 0x00000000, 0x000fb7ad, 0x000fb7ad, 0x00000000 }, | ||
3553 | { 0x00009b1c, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 }, | ||
3554 | { 0x00009b20, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 }, | ||
3555 | { 0x00009b24, 0x00000000, 0x00000000, 0x000fb7b9, 0x000fb7b9, 0x00000000 }, | ||
3556 | { 0x00009b28, 0x00000000, 0x00000000, 0x000fb7c5, 0x000fb7c5, 0x00000000 }, | ||
3557 | { 0x00009b2c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 }, | ||
3558 | { 0x00009b30, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 }, | ||
3559 | { 0x00009b34, 0x00000000, 0x00000000, 0x000fb7d5, 0x000fb7d5, 0x00000000 }, | ||
3560 | { 0x00009b38, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 }, | ||
3561 | { 0x00009b3c, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 }, | ||
3562 | { 0x00009b40, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 }, | ||
3563 | { 0x00009b44, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 }, | ||
3564 | { 0x00009b48, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 }, | ||
3565 | { 0x00009b4c, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 }, | ||
3566 | { 0x00009b50, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 }, | ||
3567 | { 0x00009b54, 0x00000000, 0x00000000, 0x000fb7c7, 0x000fb7c7, 0x00000000 }, | ||
3568 | { 0x00009b58, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 }, | ||
3569 | { 0x00009b5c, 0x00000000, 0x00000000, 0x000fb7cf, 0x000fb7cf, 0x00000000 }, | ||
3570 | { 0x00009b60, 0x00000000, 0x00000000, 0x000fb7d7, 0x000fb7d7, 0x00000000 }, | ||
3571 | { 0x00009b64, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3572 | { 0x00009b68, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3573 | { 0x00009b6c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3574 | { 0x00009b70, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3575 | { 0x00009b74, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3576 | { 0x00009b78, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3577 | { 0x00009b7c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3578 | { 0x00009b80, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3579 | { 0x00009b84, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3580 | { 0x00009b88, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3581 | { 0x00009b8c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3582 | { 0x00009b90, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3583 | { 0x00009b94, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3584 | { 0x00009b98, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3585 | { 0x00009b9c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3586 | { 0x00009ba0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3587 | { 0x00009ba4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3588 | { 0x00009ba8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3589 | { 0x00009bac, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3590 | { 0x00009bb0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3591 | { 0x00009bb4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3592 | { 0x00009bb8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3593 | { 0x00009bbc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3594 | { 0x00009bc0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3595 | { 0x00009bc4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3596 | { 0x00009bc8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3597 | { 0x00009bcc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3598 | { 0x00009bd0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3599 | { 0x00009bd4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3600 | { 0x00009bd8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3601 | { 0x00009bdc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3602 | { 0x00009be0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3603 | { 0x00009be4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3604 | { 0x00009be8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3605 | { 0x00009bec, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3606 | { 0x00009bf0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3607 | { 0x00009bf4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3608 | { 0x00009bf8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3609 | { 0x00009bfc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | ||
3610 | { 0x0000aa00, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 }, | ||
3611 | { 0x0000aa04, 0x00000000, 0x00000000, 0x00068080, 0x00068080, 0x00000000 }, | ||
3612 | { 0x0000aa08, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 }, | ||
3613 | { 0x0000aa0c, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 }, | ||
3614 | { 0x0000aa10, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 }, | ||
3615 | { 0x0000aa14, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 }, | ||
3616 | { 0x0000aa18, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 }, | ||
3617 | { 0x0000aa1c, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 }, | ||
3618 | { 0x0000aa20, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 }, | ||
3619 | { 0x0000aa24, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 }, | ||
3620 | { 0x0000aa28, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 }, | ||
3621 | { 0x0000aa2c, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 }, | ||
3622 | { 0x0000aa30, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 }, | ||
3623 | { 0x0000aa34, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 }, | ||
3624 | { 0x0000aa38, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 }, | ||
3625 | { 0x0000aa3c, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 }, | ||
3626 | { 0x0000aa40, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 }, | ||
3627 | { 0x0000aa44, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 }, | ||
3628 | { 0x0000aa48, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 }, | ||
3629 | { 0x0000aa4c, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 }, | ||
3630 | { 0x0000aa50, 0x00000000, 0x00000000, 0x000681ac, 0x000681ac, 0x00000000 }, | ||
3631 | { 0x0000aa54, 0x00000000, 0x00000000, 0x0006821c, 0x0006821c, 0x00000000 }, | ||
3632 | { 0x0000aa58, 0x00000000, 0x00000000, 0x00068224, 0x00068224, 0x00000000 }, | ||
3633 | { 0x0000aa5c, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 }, | ||
3634 | { 0x0000aa60, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 }, | ||
3635 | { 0x0000aa64, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 }, | ||
3636 | { 0x0000aa68, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 }, | ||
3637 | { 0x0000aa6c, 0x00000000, 0x00000000, 0x00068310, 0x00068310, 0x00000000 }, | ||
3638 | { 0x0000aa70, 0x00000000, 0x00000000, 0x00068788, 0x00068788, 0x00000000 }, | ||
3639 | { 0x0000aa74, 0x00000000, 0x00000000, 0x0006878c, 0x0006878c, 0x00000000 }, | ||
3640 | { 0x0000aa78, 0x00000000, 0x00000000, 0x00068790, 0x00068790, 0x00000000 }, | ||
3641 | { 0x0000aa7c, 0x00000000, 0x00000000, 0x00068794, 0x00068794, 0x00000000 }, | ||
3642 | { 0x0000aa80, 0x00000000, 0x00000000, 0x00068798, 0x00068798, 0x00000000 }, | ||
3643 | { 0x0000aa84, 0x00000000, 0x00000000, 0x0006879c, 0x0006879c, 0x00000000 }, | ||
3644 | { 0x0000aa88, 0x00000000, 0x00000000, 0x00068b89, 0x00068b89, 0x00000000 }, | ||
3645 | { 0x0000aa8c, 0x00000000, 0x00000000, 0x00068b8d, 0x00068b8d, 0x00000000 }, | ||
3646 | { 0x0000aa90, 0x00000000, 0x00000000, 0x00068b91, 0x00068b91, 0x00000000 }, | ||
3647 | { 0x0000aa94, 0x00000000, 0x00000000, 0x00068b95, 0x00068b95, 0x00000000 }, | ||
3648 | { 0x0000aa98, 0x00000000, 0x00000000, 0x00068b99, 0x00068b99, 0x00000000 }, | ||
3649 | { 0x0000aa9c, 0x00000000, 0x00000000, 0x00068ba5, 0x00068ba5, 0x00000000 }, | ||
3650 | { 0x0000aaa0, 0x00000000, 0x00000000, 0x00068ba9, 0x00068ba9, 0x00000000 }, | ||
3651 | { 0x0000aaa4, 0x00000000, 0x00000000, 0x00068bad, 0x00068bad, 0x00000000 }, | ||
3652 | { 0x0000aaa8, 0x00000000, 0x00000000, 0x000b8b0c, 0x000b8b0c, 0x00000000 }, | ||
3653 | { 0x0000aaac, 0x00000000, 0x00000000, 0x000b8f10, 0x000b8f10, 0x00000000 }, | ||
3654 | { 0x0000aab0, 0x00000000, 0x00000000, 0x000b8f14, 0x000b8f14, 0x00000000 }, | ||
3655 | { 0x0000aab4, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 }, | ||
3656 | { 0x0000aab8, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 }, | ||
3657 | { 0x0000aabc, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 }, | ||
3658 | { 0x0000aac0, 0x00000000, 0x00000000, 0x000bb380, 0x000bb380, 0x00000000 }, | ||
3659 | { 0x0000aac4, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 }, | ||
3660 | { 0x0000aac8, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 }, | ||
3661 | { 0x0000aacc, 0x00000000, 0x00000000, 0x000bb38c, 0x000bb38c, 0x00000000 }, | ||
3662 | { 0x0000aad0, 0x00000000, 0x00000000, 0x000bb394, 0x000bb394, 0x00000000 }, | ||
3663 | { 0x0000aad4, 0x00000000, 0x00000000, 0x000bb798, 0x000bb798, 0x00000000 }, | ||
3664 | { 0x0000aad8, 0x00000000, 0x00000000, 0x000f970c, 0x000f970c, 0x00000000 }, | ||
3665 | { 0x0000aadc, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 }, | ||
3666 | { 0x0000aae0, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 }, | ||
3667 | { 0x0000aae4, 0x00000000, 0x00000000, 0x000f9718, 0x000f9718, 0x00000000 }, | ||
3668 | { 0x0000aae8, 0x00000000, 0x00000000, 0x000f9705, 0x000f9705, 0x00000000 }, | ||
3669 | { 0x0000aaec, 0x00000000, 0x00000000, 0x000f9709, 0x000f9709, 0x00000000 }, | ||
3670 | { 0x0000aaf0, 0x00000000, 0x00000000, 0x000f970d, 0x000f970d, 0x00000000 }, | ||
3671 | { 0x0000aaf4, 0x00000000, 0x00000000, 0x000f9711, 0x000f9711, 0x00000000 }, | ||
3672 | { 0x0000aaf8, 0x00000000, 0x00000000, 0x000f9715, 0x000f9715, 0x00000000 }, | ||
3673 | { 0x0000aafc, 0x00000000, 0x00000000, 0x000f9719, 0x000f9719, 0x00000000 }, | ||
3674 | { 0x0000ab00, 0x00000000, 0x00000000, 0x000fb7a4, 0x000fb7a4, 0x00000000 }, | ||
3675 | { 0x0000ab04, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 }, | ||
3676 | { 0x0000ab08, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 }, | ||
3677 | { 0x0000ab0c, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 }, | ||
3678 | { 0x0000ab10, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 }, | ||
3679 | { 0x0000ab14, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 }, | ||
3680 | { 0x0000ab18, 0x00000000, 0x00000000, 0x000fb7bc, 0x000fb7bc, 0x00000000 }, | ||
3681 | { 0x0000ab1c, 0x00000000, 0x00000000, 0x000fb7a1, 0x000fb7a1, 0x00000000 }, | ||
3682 | { 0x0000ab20, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 }, | ||
3683 | { 0x0000ab24, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 }, | ||
3684 | { 0x0000ab28, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 }, | ||
3685 | { 0x0000ab2c, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 }, | ||
3686 | { 0x0000ab30, 0x00000000, 0x00000000, 0x000fb7bd, 0x000fb7bd, 0x00000000 }, | ||
3687 | { 0x0000ab34, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 }, | ||
3688 | { 0x0000ab38, 0x00000000, 0x00000000, 0x000fb7cd, 0x000fb7cd, 0x00000000 }, | ||
3689 | { 0x0000ab3c, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 }, | ||
3690 | { 0x0000ab40, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 }, | ||
3691 | { 0x0000ab44, 0x00000000, 0x00000000, 0x000fb7c2, 0x000fb7c2, 0x00000000 }, | ||
3692 | { 0x0000ab48, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 }, | ||
3693 | { 0x0000ab4c, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 }, | ||
3694 | { 0x0000ab50, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 }, | ||
3695 | { 0x0000ab54, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 }, | ||
3696 | { 0x0000ab58, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 }, | ||
3697 | { 0x0000ab5c, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 }, | ||
3698 | { 0x0000ab60, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 }, | ||
3699 | { 0x0000ab64, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3700 | { 0x0000ab68, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3701 | { 0x0000ab6c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3702 | { 0x0000ab70, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3703 | { 0x0000ab74, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3704 | { 0x0000ab78, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3705 | { 0x0000ab7c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3706 | { 0x0000ab80, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3707 | { 0x0000ab84, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3708 | { 0x0000ab88, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3709 | { 0x0000ab8c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3710 | { 0x0000ab90, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3711 | { 0x0000ab94, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3712 | { 0x0000ab98, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3713 | { 0x0000ab9c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3714 | { 0x0000aba0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3715 | { 0x0000aba4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3716 | { 0x0000aba8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3717 | { 0x0000abac, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3718 | { 0x0000abb0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3719 | { 0x0000abb4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3720 | { 0x0000abb8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3721 | { 0x0000abbc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3722 | { 0x0000abc0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3723 | { 0x0000abc4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3724 | { 0x0000abc8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3725 | { 0x0000abcc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3726 | { 0x0000abd0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3727 | { 0x0000abd4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3728 | { 0x0000abd8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3729 | { 0x0000abdc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3730 | { 0x0000abe0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3731 | { 0x0000abe4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3732 | { 0x0000abe8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3733 | { 0x0000abec, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3734 | { 0x0000abf0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3735 | { 0x0000abf4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3736 | { 0x0000abf8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3737 | { 0x0000abfc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | ||
3738 | { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 }, | ||
3739 | { 0x0000a20c, 0x00000014, 0x00000014, 0x00000000, 0x00000000, 0x0001f000 }, | ||
3740 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | ||
3741 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | ||
3742 | { 0x0000a250, 0x001ff000, 0x001ff000, 0x001ca000, 0x001ca000, 0x001da000 }, | ||
3743 | { 0x0000a274, 0x0a81c652, 0x0a81c652, 0x0a820652, 0x0a820652, 0x0a82a652 }, | ||
3744 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
3745 | { 0x0000a304, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 }, | ||
3746 | { 0x0000a308, 0x00000000, 0x00000000, 0x00010408, 0x00010408, 0x00000000 }, | ||
3747 | { 0x0000a30c, 0x00000000, 0x00000000, 0x0001860a, 0x0001860a, 0x00000000 }, | ||
3748 | { 0x0000a310, 0x00000000, 0x00000000, 0x00020818, 0x00020818, 0x00000000 }, | ||
3749 | { 0x0000a314, 0x00000000, 0x00000000, 0x00024858, 0x00024858, 0x00000000 }, | ||
3750 | { 0x0000a318, 0x00000000, 0x00000000, 0x00026859, 0x00026859, 0x00000000 }, | ||
3751 | { 0x0000a31c, 0x00000000, 0x00000000, 0x0002985b, 0x0002985b, 0x00000000 }, | ||
3752 | { 0x0000a320, 0x00000000, 0x00000000, 0x0002c89a, 0x0002c89a, 0x00000000 }, | ||
3753 | { 0x0000a324, 0x00000000, 0x00000000, 0x0002e89b, 0x0002e89b, 0x00000000 }, | ||
3754 | { 0x0000a328, 0x00000000, 0x00000000, 0x0003089c, 0x0003089c, 0x00000000 }, | ||
3755 | { 0x0000a32c, 0x00000000, 0x00000000, 0x0003289d, 0x0003289d, 0x00000000 }, | ||
3756 | { 0x0000a330, 0x00000000, 0x00000000, 0x0003489e, 0x0003489e, 0x00000000 }, | ||
3757 | { 0x0000a334, 0x00000000, 0x00000000, 0x000388de, 0x000388de, 0x00000000 }, | ||
3758 | { 0x0000a338, 0x00000000, 0x00000000, 0x0003b91e, 0x0003b91e, 0x00000000 }, | ||
3759 | { 0x0000a33c, 0x00000000, 0x00000000, 0x0003d95e, 0x0003d95e, 0x00000000 }, | ||
3760 | { 0x0000a340, 0x00000000, 0x00000000, 0x000419df, 0x000419df, 0x00000000 }, | ||
3761 | { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
3762 | { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, | ||
3763 | }; | ||
3764 | |||
3765 | static const u_int32_t ar9285Common_9285[][2] = { | ||
3766 | { 0x0000000c, 0x00000000 }, | ||
3767 | { 0x00000030, 0x00020045 }, | ||
3768 | { 0x00000034, 0x00000005 }, | ||
3769 | { 0x00000040, 0x00000000 }, | ||
3770 | { 0x00000044, 0x00000008 }, | ||
3771 | { 0x00000048, 0x00000008 }, | ||
3772 | { 0x0000004c, 0x00000010 }, | ||
3773 | { 0x00000050, 0x00000000 }, | ||
3774 | { 0x00000054, 0x0000001f }, | ||
3775 | { 0x00000800, 0x00000000 }, | ||
3776 | { 0x00000804, 0x00000000 }, | ||
3777 | { 0x00000808, 0x00000000 }, | ||
3778 | { 0x0000080c, 0x00000000 }, | ||
3779 | { 0x00000810, 0x00000000 }, | ||
3780 | { 0x00000814, 0x00000000 }, | ||
3781 | { 0x00000818, 0x00000000 }, | ||
3782 | { 0x0000081c, 0x00000000 }, | ||
3783 | { 0x00000820, 0x00000000 }, | ||
3784 | { 0x00000824, 0x00000000 }, | ||
3785 | { 0x00001040, 0x002ffc0f }, | ||
3786 | { 0x00001044, 0x002ffc0f }, | ||
3787 | { 0x00001048, 0x002ffc0f }, | ||
3788 | { 0x0000104c, 0x002ffc0f }, | ||
3789 | { 0x00001050, 0x002ffc0f }, | ||
3790 | { 0x00001054, 0x002ffc0f }, | ||
3791 | { 0x00001058, 0x002ffc0f }, | ||
3792 | { 0x0000105c, 0x002ffc0f }, | ||
3793 | { 0x00001060, 0x002ffc0f }, | ||
3794 | { 0x00001064, 0x002ffc0f }, | ||
3795 | { 0x00001230, 0x00000000 }, | ||
3796 | { 0x00001270, 0x00000000 }, | ||
3797 | { 0x00001038, 0x00000000 }, | ||
3798 | { 0x00001078, 0x00000000 }, | ||
3799 | { 0x000010b8, 0x00000000 }, | ||
3800 | { 0x000010f8, 0x00000000 }, | ||
3801 | { 0x00001138, 0x00000000 }, | ||
3802 | { 0x00001178, 0x00000000 }, | ||
3803 | { 0x000011b8, 0x00000000 }, | ||
3804 | { 0x000011f8, 0x00000000 }, | ||
3805 | { 0x00001238, 0x00000000 }, | ||
3806 | { 0x00001278, 0x00000000 }, | ||
3807 | { 0x000012b8, 0x00000000 }, | ||
3808 | { 0x000012f8, 0x00000000 }, | ||
3809 | { 0x00001338, 0x00000000 }, | ||
3810 | { 0x00001378, 0x00000000 }, | ||
3811 | { 0x000013b8, 0x00000000 }, | ||
3812 | { 0x000013f8, 0x00000000 }, | ||
3813 | { 0x00001438, 0x00000000 }, | ||
3814 | { 0x00001478, 0x00000000 }, | ||
3815 | { 0x000014b8, 0x00000000 }, | ||
3816 | { 0x000014f8, 0x00000000 }, | ||
3817 | { 0x00001538, 0x00000000 }, | ||
3818 | { 0x00001578, 0x00000000 }, | ||
3819 | { 0x000015b8, 0x00000000 }, | ||
3820 | { 0x000015f8, 0x00000000 }, | ||
3821 | { 0x00001638, 0x00000000 }, | ||
3822 | { 0x00001678, 0x00000000 }, | ||
3823 | { 0x000016b8, 0x00000000 }, | ||
3824 | { 0x000016f8, 0x00000000 }, | ||
3825 | { 0x00001738, 0x00000000 }, | ||
3826 | { 0x00001778, 0x00000000 }, | ||
3827 | { 0x000017b8, 0x00000000 }, | ||
3828 | { 0x000017f8, 0x00000000 }, | ||
3829 | { 0x0000103c, 0x00000000 }, | ||
3830 | { 0x0000107c, 0x00000000 }, | ||
3831 | { 0x000010bc, 0x00000000 }, | ||
3832 | { 0x000010fc, 0x00000000 }, | ||
3833 | { 0x0000113c, 0x00000000 }, | ||
3834 | { 0x0000117c, 0x00000000 }, | ||
3835 | { 0x000011bc, 0x00000000 }, | ||
3836 | { 0x000011fc, 0x00000000 }, | ||
3837 | { 0x0000123c, 0x00000000 }, | ||
3838 | { 0x0000127c, 0x00000000 }, | ||
3839 | { 0x000012bc, 0x00000000 }, | ||
3840 | { 0x000012fc, 0x00000000 }, | ||
3841 | { 0x0000133c, 0x00000000 }, | ||
3842 | { 0x0000137c, 0x00000000 }, | ||
3843 | { 0x000013bc, 0x00000000 }, | ||
3844 | { 0x000013fc, 0x00000000 }, | ||
3845 | { 0x0000143c, 0x00000000 }, | ||
3846 | { 0x0000147c, 0x00000000 }, | ||
3847 | { 0x00004030, 0x00000002 }, | ||
3848 | { 0x0000403c, 0x00000002 }, | ||
3849 | { 0x00004024, 0x0000001f }, | ||
3850 | { 0x00004060, 0x00000000 }, | ||
3851 | { 0x00004064, 0x00000000 }, | ||
3852 | { 0x00007010, 0x00000031 }, | ||
3853 | { 0x00007034, 0x00000002 }, | ||
3854 | { 0x00007038, 0x000004c2 }, | ||
3855 | { 0x00008004, 0x00000000 }, | ||
3856 | { 0x00008008, 0x00000000 }, | ||
3857 | { 0x0000800c, 0x00000000 }, | ||
3858 | { 0x00008018, 0x00000700 }, | ||
3859 | { 0x00008020, 0x00000000 }, | ||
3860 | { 0x00008038, 0x00000000 }, | ||
3861 | { 0x0000803c, 0x00000000 }, | ||
3862 | { 0x00008048, 0x00000000 }, | ||
3863 | { 0x00008054, 0x00000000 }, | ||
3864 | { 0x00008058, 0x00000000 }, | ||
3865 | { 0x0000805c, 0x000fc78f }, | ||
3866 | { 0x00008060, 0x0000000f }, | ||
3867 | { 0x00008064, 0x00000000 }, | ||
3868 | { 0x00008070, 0x00000000 }, | ||
3869 | { 0x000080c0, 0x2a80001a }, | ||
3870 | { 0x000080c4, 0x05dc01e0 }, | ||
3871 | { 0x000080c8, 0x1f402710 }, | ||
3872 | { 0x000080cc, 0x01f40000 }, | ||
3873 | { 0x000080d0, 0x00001e00 }, | ||
3874 | { 0x000080d4, 0x00000000 }, | ||
3875 | { 0x000080d8, 0x00400000 }, | ||
3876 | { 0x000080e0, 0xffffffff }, | ||
3877 | { 0x000080e4, 0x0000ffff }, | ||
3878 | { 0x000080e8, 0x003f3f3f }, | ||
3879 | { 0x000080ec, 0x00000000 }, | ||
3880 | { 0x000080f0, 0x00000000 }, | ||
3881 | { 0x000080f4, 0x00000000 }, | ||
3882 | { 0x000080f8, 0x00000000 }, | ||
3883 | { 0x000080fc, 0x00020000 }, | ||
3884 | { 0x00008100, 0x00020000 }, | ||
3885 | { 0x00008104, 0x00000001 }, | ||
3886 | { 0x00008108, 0x00000052 }, | ||
3887 | { 0x0000810c, 0x00000000 }, | ||
3888 | { 0x00008110, 0x00000168 }, | ||
3889 | { 0x00008118, 0x000100aa }, | ||
3890 | { 0x0000811c, 0x00003210 }, | ||
3891 | { 0x00008120, 0x08f04800 }, | ||
3892 | { 0x00008124, 0x00000000 }, | ||
3893 | { 0x00008128, 0x00000000 }, | ||
3894 | { 0x0000812c, 0x00000000 }, | ||
3895 | { 0x00008130, 0x00000000 }, | ||
3896 | { 0x00008134, 0x00000000 }, | ||
3897 | { 0x00008138, 0x00000000 }, | ||
3898 | { 0x0000813c, 0x00000000 }, | ||
3899 | { 0x00008144, 0x00000000 }, | ||
3900 | { 0x00008168, 0x00000000 }, | ||
3901 | { 0x0000816c, 0x00000000 }, | ||
3902 | { 0x00008170, 0x32143320 }, | ||
3903 | { 0x00008174, 0xfaa4fa50 }, | ||
3904 | { 0x00008178, 0x00000100 }, | ||
3905 | { 0x0000817c, 0x00000000 }, | ||
3906 | { 0x000081c0, 0x00000000 }, | ||
3907 | { 0x000081d0, 0x00003210 }, | ||
3908 | { 0x000081ec, 0x00000000 }, | ||
3909 | { 0x000081f0, 0x00000000 }, | ||
3910 | { 0x000081f4, 0x00000000 }, | ||
3911 | { 0x000081f8, 0x00000000 }, | ||
3912 | { 0x000081fc, 0x00000000 }, | ||
3913 | { 0x00008200, 0x00000000 }, | ||
3914 | { 0x00008204, 0x00000000 }, | ||
3915 | { 0x00008208, 0x00000000 }, | ||
3916 | { 0x0000820c, 0x00000000 }, | ||
3917 | { 0x00008210, 0x00000000 }, | ||
3918 | { 0x00008214, 0x00000000 }, | ||
3919 | { 0x00008218, 0x00000000 }, | ||
3920 | { 0x0000821c, 0x00000000 }, | ||
3921 | { 0x00008220, 0x00000000 }, | ||
3922 | { 0x00008224, 0x00000000 }, | ||
3923 | { 0x00008228, 0x00000000 }, | ||
3924 | { 0x0000822c, 0x00000000 }, | ||
3925 | { 0x00008230, 0x00000000 }, | ||
3926 | { 0x00008234, 0x00000000 }, | ||
3927 | { 0x00008238, 0x00000000 }, | ||
3928 | { 0x0000823c, 0x00000000 }, | ||
3929 | { 0x00008240, 0x00100000 }, | ||
3930 | { 0x00008244, 0x0010f400 }, | ||
3931 | { 0x00008248, 0x00000100 }, | ||
3932 | { 0x0000824c, 0x0001e800 }, | ||
3933 | { 0x00008250, 0x00000000 }, | ||
3934 | { 0x00008254, 0x00000000 }, | ||
3935 | { 0x00008258, 0x00000000 }, | ||
3936 | { 0x0000825c, 0x400000ff }, | ||
3937 | { 0x00008260, 0x00080922 }, | ||
3938 | { 0x00008264, 0xa8a00010 }, | ||
3939 | { 0x00008270, 0x00000000 }, | ||
3940 | { 0x00008274, 0x40000000 }, | ||
3941 | { 0x00008278, 0x003e4180 }, | ||
3942 | { 0x0000827c, 0x00000000 }, | ||
3943 | { 0x00008284, 0x0000002c }, | ||
3944 | { 0x00008288, 0x0000002c }, | ||
3945 | { 0x0000828c, 0x00000000 }, | ||
3946 | { 0x00008294, 0x00000000 }, | ||
3947 | { 0x00008298, 0x00000000 }, | ||
3948 | { 0x0000829c, 0x00000000 }, | ||
3949 | { 0x00008300, 0x00000040 }, | ||
3950 | { 0x00008314, 0x00000000 }, | ||
3951 | { 0x00008328, 0x00000000 }, | ||
3952 | { 0x0000832c, 0x00000001 }, | ||
3953 | { 0x00008330, 0x00000302 }, | ||
3954 | { 0x00008334, 0x00000e00 }, | ||
3955 | { 0x00008338, 0x00000000 }, | ||
3956 | { 0x0000833c, 0x00000000 }, | ||
3957 | { 0x00008340, 0x00010380 }, | ||
3958 | { 0x00008344, 0x00581043 }, | ||
3959 | { 0x00009808, 0x00000000 }, | ||
3960 | { 0x0000980c, 0xafe68e30 }, | ||
3961 | { 0x00009810, 0xfd14e000 }, | ||
3962 | { 0x00009814, 0x9c0a9f6b }, | ||
3963 | { 0x0000981c, 0x00000000 }, | ||
3964 | { 0x0000982c, 0x0000a000 }, | ||
3965 | { 0x00009830, 0x00000000 }, | ||
3966 | { 0x0000983c, 0x00200400 }, | ||
3967 | { 0x0000984c, 0x0040233c }, | ||
3968 | { 0x00009854, 0x00000044 }, | ||
3969 | { 0x00009900, 0x00000000 }, | ||
3970 | { 0x00009904, 0x00000000 }, | ||
3971 | { 0x00009908, 0x00000000 }, | ||
3972 | { 0x0000990c, 0x00000000 }, | ||
3973 | { 0x00009910, 0x01002310 }, | ||
3974 | { 0x0000991c, 0x10000fff }, | ||
3975 | { 0x00009920, 0x04900000 }, | ||
3976 | { 0x00009928, 0x00000001 }, | ||
3977 | { 0x0000992c, 0x00000004 }, | ||
3978 | { 0x00009934, 0x1e1f2022 }, | ||
3979 | { 0x00009938, 0x0a0b0c0d }, | ||
3980 | { 0x0000993c, 0x00000000 }, | ||
3981 | { 0x00009940, 0x14750604 }, | ||
3982 | { 0x00009948, 0x9280c00a }, | ||
3983 | { 0x0000994c, 0x00020028 }, | ||
3984 | { 0x00009954, 0x5f3ca3de }, | ||
3985 | { 0x00009958, 0x2108ecff }, | ||
3986 | { 0x00009968, 0x000003ce }, | ||
3987 | { 0x00009970, 0x1927b515 }, | ||
3988 | { 0x00009974, 0x00000000 }, | ||
3989 | { 0x00009978, 0x00000001 }, | ||
3990 | { 0x0000997c, 0x00000000 }, | ||
3991 | { 0x00009980, 0x00000000 }, | ||
3992 | { 0x00009984, 0x00000000 }, | ||
3993 | { 0x00009988, 0x00000000 }, | ||
3994 | { 0x0000998c, 0x00000000 }, | ||
3995 | { 0x00009990, 0x00000000 }, | ||
3996 | { 0x00009994, 0x00000000 }, | ||
3997 | { 0x00009998, 0x00000000 }, | ||
3998 | { 0x0000999c, 0x00000000 }, | ||
3999 | { 0x000099a0, 0x00000000 }, | ||
4000 | { 0x000099a4, 0x00000001 }, | ||
4001 | { 0x000099a8, 0x201fff00 }, | ||
4002 | { 0x000099ac, 0x2def0a00 }, | ||
4003 | { 0x000099b0, 0x03051000 }, | ||
4004 | { 0x000099b4, 0x00000820 }, | ||
4005 | { 0x000099dc, 0x00000000 }, | ||
4006 | { 0x000099e0, 0x00000000 }, | ||
4007 | { 0x000099e4, 0xaaaaaaaa }, | ||
4008 | { 0x000099e8, 0x3c466478 }, | ||
4009 | { 0x000099ec, 0x0cc80caa }, | ||
4010 | { 0x000099f0, 0x00000000 }, | ||
4011 | { 0x0000a208, 0x803e6788 }, | ||
4012 | { 0x0000a210, 0x4080a333 }, | ||
4013 | { 0x0000a214, 0x00206c10 }, | ||
4014 | { 0x0000a218, 0x009c4060 }, | ||
4015 | { 0x0000a220, 0x01834061 }, | ||
4016 | { 0x0000a224, 0x00000400 }, | ||
4017 | { 0x0000a228, 0x000003b5 }, | ||
4018 | { 0x0000a22c, 0x00000000 }, | ||
4019 | { 0x0000a234, 0x20202020 }, | ||
4020 | { 0x0000a238, 0x20202020 }, | ||
4021 | { 0x0000a244, 0x00000000 }, | ||
4022 | { 0x0000a248, 0xfffffffc }, | ||
4023 | { 0x0000a24c, 0x00000000 }, | ||
4024 | { 0x0000a254, 0x00000000 }, | ||
4025 | { 0x0000a258, 0x0ccb5380 }, | ||
4026 | { 0x0000a25c, 0x15151501 }, | ||
4027 | { 0x0000a260, 0xdfa90f01 }, | ||
4028 | { 0x0000a268, 0x00000000 }, | ||
4029 | { 0x0000a26c, 0x0ebae9e6 }, | ||
4030 | { 0x0000d270, 0x0d820820 }, | ||
4031 | { 0x0000a278, 0x39ce739c }, | ||
4032 | { 0x0000a27c, 0x050e039c }, | ||
4033 | { 0x0000d35c, 0x07ffffef }, | ||
4034 | { 0x0000d360, 0x0fffffe7 }, | ||
4035 | { 0x0000d364, 0x17ffffe5 }, | ||
4036 | { 0x0000d368, 0x1fffffe4 }, | ||
4037 | { 0x0000d36c, 0x37ffffe3 }, | ||
4038 | { 0x0000d370, 0x3fffffe3 }, | ||
4039 | { 0x0000d374, 0x57ffffe3 }, | ||
4040 | { 0x0000d378, 0x5fffffe2 }, | ||
4041 | { 0x0000d37c, 0x7fffffe2 }, | ||
4042 | { 0x0000d380, 0x7f3c7bba }, | ||
4043 | { 0x0000d384, 0xf3307ff0 }, | ||
4044 | { 0x0000a388, 0x0c000000 }, | ||
4045 | { 0x0000a38c, 0x20202020 }, | ||
4046 | { 0x0000a390, 0x20202020 }, | ||
4047 | { 0x0000a394, 0x39ce739c }, | ||
4048 | { 0x0000a398, 0x0000039c }, | ||
4049 | { 0x0000a39c, 0x00000001 }, | ||
4050 | { 0x0000a3a0, 0x00000000 }, | ||
4051 | { 0x0000a3a4, 0x00000000 }, | ||
4052 | { 0x0000a3a8, 0x00000000 }, | ||
4053 | { 0x0000a3ac, 0x00000000 }, | ||
4054 | { 0x0000a3b0, 0x00000000 }, | ||
4055 | { 0x0000a3b4, 0x00000000 }, | ||
4056 | { 0x0000a3b8, 0x00000000 }, | ||
4057 | { 0x0000a3bc, 0x00000000 }, | ||
4058 | { 0x0000a3c0, 0x00000000 }, | ||
4059 | { 0x0000a3c4, 0x00000000 }, | ||
4060 | { 0x0000a3cc, 0x20202020 }, | ||
4061 | { 0x0000a3d0, 0x20202020 }, | ||
4062 | { 0x0000a3d4, 0x20202020 }, | ||
4063 | { 0x0000a3dc, 0x39ce739c }, | ||
4064 | { 0x0000a3e0, 0x0000039c }, | ||
4065 | { 0x0000a3e4, 0x00000000 }, | ||
4066 | { 0x0000a3e8, 0x18c43433 }, | ||
4067 | { 0x0000a3ec, 0x00f70081 }, | ||
4068 | { 0x00007800, 0x00140000 }, | ||
4069 | { 0x00007804, 0x0e4548d8 }, | ||
4070 | { 0x00007808, 0x54214514 }, | ||
4071 | { 0x0000780c, 0x02025820 }, | ||
4072 | { 0x00007810, 0x71c0d388 }, | ||
4073 | { 0x00007814, 0x924934a8 }, | ||
4074 | { 0x0000781c, 0x00000000 }, | ||
4075 | { 0x00007820, 0x00000c04 }, | ||
4076 | { 0x00007824, 0x00d86fff }, | ||
4077 | { 0x00007828, 0x26d2491b }, | ||
4078 | { 0x0000782c, 0x6e36d97b }, | ||
4079 | { 0x00007830, 0xedb6d96c }, | ||
4080 | { 0x00007834, 0x71400086 }, | ||
4081 | { 0x00007838, 0xfac68800 }, | ||
4082 | { 0x0000783c, 0x0001fffe }, | ||
4083 | { 0x00007840, 0xffeb1a20 }, | ||
4084 | { 0x00007844, 0x000c0db6 }, | ||
4085 | { 0x00007848, 0x6db61b6f }, | ||
4086 | { 0x0000784c, 0x6d9b66db }, | ||
4087 | { 0x00007850, 0x6d8c6dba }, | ||
4088 | { 0x00007854, 0x00040000 }, | ||
4089 | { 0x00007858, 0xdb003012 }, | ||
4090 | { 0x0000785c, 0x04924914 }, | ||
4091 | { 0x00007860, 0x21084210 }, | ||
4092 | { 0x00007864, 0xf7d7ffde }, | ||
4093 | { 0x00007868, 0xc2034080 }, | ||
4094 | { 0x0000786c, 0x48609eb4 }, | ||
4095 | { 0x00007870, 0x10142c00 }, | ||
4096 | }; | ||
4097 | |||
4098 | static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285[][2] = { | ||
4099 | {0x00004040, 0x9248fd00 }, | ||
4100 | {0x00004040, 0x24924924 }, | ||
4101 | {0x00004040, 0xa8000019 }, | ||
4102 | {0x00004040, 0x13160820 }, | ||
4103 | {0x00004040, 0xe5980560 }, | ||
4104 | {0x00004040, 0xc01dcffd }, | ||
4105 | {0x00004040, 0x1aaabe41 }, | ||
4106 | {0x00004040, 0xbe105554 }, | ||
4107 | {0x00004040, 0x00043007 }, | ||
4108 | {0x00004044, 0x00000000 }, | ||
4109 | }; | ||
4110 | |||
4111 | static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = { | ||
4112 | {0x00004040, 0x9248fd00 }, | ||
4113 | {0x00004040, 0x24924924 }, | ||
4114 | {0x00004040, 0xa8000019 }, | ||
4115 | {0x00004040, 0x13160820 }, | ||
4116 | {0x00004040, 0xe5980560 }, | ||
4117 | {0x00004040, 0xc01dcffc }, | ||
4118 | {0x00004040, 0x1aaabe41 }, | ||
4119 | {0x00004040, 0xbe105554 }, | ||
4120 | {0x00004040, 0x00043007 }, | ||
4121 | {0x00004044, 0x00000000 }, | ||
4122 | }; | ||
4123 | |||
4124 | /* AR9285 v1_2 PCI Register Writes. Created: 03/04/09 */ | ||
4125 | static const u_int32_t ar9285Modes_9285_1_2[][6] = { | ||
4126 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | ||
4127 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | ||
4128 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | ||
4129 | { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 }, | ||
4130 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, | ||
4131 | { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f }, | ||
4132 | { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 }, | ||
4133 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, | ||
4134 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, | ||
4135 | { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
4136 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, | ||
4137 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
4138 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, | ||
4139 | { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e }, | ||
4140 | { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 }, | ||
4141 | { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 }, | ||
4142 | { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 }, | ||
4143 | { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e }, | ||
4144 | { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e }, | ||
4145 | { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 }, | ||
4146 | { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, | ||
4147 | { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 }, | ||
4148 | { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 }, | ||
4149 | { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, | ||
4150 | { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, | ||
4151 | { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d }, | ||
4152 | { 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010 }, | ||
4153 | { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
4154 | { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
4155 | { 0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c }, | ||
4156 | { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 }, | ||
4157 | { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 }, | ||
4158 | { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, | ||
4159 | { 0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 }, | ||
4160 | { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, | ||
4161 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, | ||
4162 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
4163 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
4164 | { 0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 }, | ||
4165 | { 0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 }, | ||
4166 | { 0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 }, | ||
4167 | { 0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 }, | ||
4168 | { 0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 }, | ||
4169 | { 0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 }, | ||
4170 | { 0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 }, | ||
4171 | { 0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 }, | ||
4172 | { 0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 }, | ||
4173 | { 0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 }, | ||
4174 | { 0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 }, | ||
4175 | { 0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 }, | ||
4176 | { 0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 }, | ||
4177 | { 0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 }, | ||
4178 | { 0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 }, | ||
4179 | { 0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 }, | ||
4180 | { 0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 }, | ||
4181 | { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, | ||
4182 | { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, | ||
4183 | { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, | ||
4184 | { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, | ||
4185 | { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, | ||
4186 | { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, | ||
4187 | { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, | ||
4188 | { 0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 }, | ||
4189 | { 0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 }, | ||
4190 | { 0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 }, | ||
4191 | { 0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 }, | ||
4192 | { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 }, | ||
4193 | { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 }, | ||
4194 | { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 }, | ||
4195 | { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, | ||
4196 | { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, | ||
4197 | { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, | ||
4198 | { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, | ||
4199 | { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, | ||
4200 | { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, | ||
4201 | { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, | ||
4202 | { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, | ||
4203 | { 0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 }, | ||
4204 | { 0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 }, | ||
4205 | { 0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 }, | ||
4206 | { 0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 }, | ||
4207 | { 0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 }, | ||
4208 | { 0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 }, | ||
4209 | { 0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 }, | ||
4210 | { 0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 }, | ||
4211 | { 0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 }, | ||
4212 | { 0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 }, | ||
4213 | { 0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 }, | ||
4214 | { 0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 }, | ||
4215 | { 0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 }, | ||
4216 | { 0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 }, | ||
4217 | { 0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 }, | ||
4218 | { 0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 }, | ||
4219 | { 0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 }, | ||
4220 | { 0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 }, | ||
4221 | { 0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 }, | ||
4222 | { 0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 }, | ||
4223 | { 0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 }, | ||
4224 | { 0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 }, | ||
4225 | { 0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 }, | ||
4226 | { 0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 }, | ||
4227 | { 0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 }, | ||
4228 | { 0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 }, | ||
4229 | { 0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 }, | ||
4230 | { 0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 }, | ||
4231 | { 0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 }, | ||
4232 | { 0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 }, | ||
4233 | { 0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 }, | ||
4234 | { 0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 }, | ||
4235 | { 0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 }, | ||
4236 | { 0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 }, | ||
4237 | { 0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 }, | ||
4238 | { 0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 }, | ||
4239 | { 0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 }, | ||
4240 | { 0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 }, | ||
4241 | { 0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 }, | ||
4242 | { 0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 }, | ||
4243 | { 0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 }, | ||
4244 | { 0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 }, | ||
4245 | { 0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 }, | ||
4246 | { 0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 }, | ||
4247 | { 0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 }, | ||
4248 | { 0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 }, | ||
4249 | { 0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 }, | ||
4250 | { 0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 }, | ||
4251 | { 0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 }, | ||
4252 | { 0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 }, | ||
4253 | { 0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4254 | { 0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4255 | { 0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4256 | { 0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4257 | { 0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4258 | { 0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4259 | { 0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4260 | { 0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4261 | { 0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4262 | { 0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4263 | { 0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4264 | { 0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4265 | { 0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4266 | { 0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4267 | { 0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4268 | { 0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4269 | { 0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4270 | { 0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4271 | { 0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4272 | { 0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4273 | { 0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4274 | { 0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4275 | { 0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4276 | { 0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4277 | { 0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4278 | { 0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4279 | { 0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4280 | { 0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4281 | { 0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4282 | { 0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4283 | { 0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4284 | { 0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4285 | { 0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4286 | { 0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4287 | { 0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4288 | { 0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4289 | { 0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4290 | { 0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4291 | { 0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4292 | { 0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 }, | ||
4293 | { 0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 }, | ||
4294 | { 0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 }, | ||
4295 | { 0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 }, | ||
4296 | { 0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 }, | ||
4297 | { 0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 }, | ||
4298 | { 0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 }, | ||
4299 | { 0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 }, | ||
4300 | { 0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 }, | ||
4301 | { 0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 }, | ||
4302 | { 0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 }, | ||
4303 | { 0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 }, | ||
4304 | { 0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 }, | ||
4305 | { 0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 }, | ||
4306 | { 0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 }, | ||
4307 | { 0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 }, | ||
4308 | { 0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 }, | ||
4309 | { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, | ||
4310 | { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, | ||
4311 | { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, | ||
4312 | { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, | ||
4313 | { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, | ||
4314 | { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, | ||
4315 | { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, | ||
4316 | { 0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 }, | ||
4317 | { 0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 }, | ||
4318 | { 0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 }, | ||
4319 | { 0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 }, | ||
4320 | { 0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 }, | ||
4321 | { 0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 }, | ||
4322 | { 0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 }, | ||
4323 | { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, | ||
4324 | { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, | ||
4325 | { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, | ||
4326 | { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, | ||
4327 | { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, | ||
4328 | { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, | ||
4329 | { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, | ||
4330 | { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, | ||
4331 | { 0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 }, | ||
4332 | { 0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 }, | ||
4333 | { 0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 }, | ||
4334 | { 0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 }, | ||
4335 | { 0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 }, | ||
4336 | { 0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 }, | ||
4337 | { 0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 }, | ||
4338 | { 0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 }, | ||
4339 | { 0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 }, | ||
4340 | { 0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 }, | ||
4341 | { 0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 }, | ||
4342 | { 0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 }, | ||
4343 | { 0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 }, | ||
4344 | { 0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 }, | ||
4345 | { 0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 }, | ||
4346 | { 0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 }, | ||
4347 | { 0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 }, | ||
4348 | { 0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 }, | ||
4349 | { 0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 }, | ||
4350 | { 0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 }, | ||
4351 | { 0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 }, | ||
4352 | { 0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 }, | ||
4353 | { 0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 }, | ||
4354 | { 0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 }, | ||
4355 | { 0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 }, | ||
4356 | { 0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 }, | ||
4357 | { 0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 }, | ||
4358 | { 0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 }, | ||
4359 | { 0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 }, | ||
4360 | { 0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 }, | ||
4361 | { 0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 }, | ||
4362 | { 0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 }, | ||
4363 | { 0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 }, | ||
4364 | { 0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 }, | ||
4365 | { 0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 }, | ||
4366 | { 0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 }, | ||
4367 | { 0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 }, | ||
4368 | { 0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 }, | ||
4369 | { 0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 }, | ||
4370 | { 0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 }, | ||
4371 | { 0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 }, | ||
4372 | { 0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 }, | ||
4373 | { 0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 }, | ||
4374 | { 0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 }, | ||
4375 | { 0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 }, | ||
4376 | { 0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 }, | ||
4377 | { 0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 }, | ||
4378 | { 0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 }, | ||
4379 | { 0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 }, | ||
4380 | { 0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 }, | ||
4381 | { 0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4382 | { 0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4383 | { 0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4384 | { 0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4385 | { 0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4386 | { 0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4387 | { 0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4388 | { 0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4389 | { 0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4390 | { 0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4391 | { 0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4392 | { 0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4393 | { 0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4394 | { 0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4395 | { 0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4396 | { 0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4397 | { 0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4398 | { 0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4399 | { 0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4400 | { 0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4401 | { 0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4402 | { 0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4403 | { 0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4404 | { 0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4405 | { 0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4406 | { 0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4407 | { 0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4408 | { 0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4409 | { 0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4410 | { 0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4411 | { 0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4412 | { 0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4413 | { 0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4414 | { 0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4415 | { 0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4416 | { 0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4417 | { 0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4418 | { 0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4419 | { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, | ||
4420 | { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 }, | ||
4421 | { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 }, | ||
4422 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | ||
4423 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | ||
4424 | { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 }, | ||
4425 | { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, | ||
4426 | }; | ||
4427 | |||
4428 | static const u_int32_t ar9285Common_9285_1_2[][2] = { | ||
4429 | { 0x0000000c, 0x00000000 }, | ||
4430 | { 0x00000030, 0x00020045 }, | ||
4431 | { 0x00000034, 0x00000005 }, | ||
4432 | { 0x00000040, 0x00000000 }, | ||
4433 | { 0x00000044, 0x00000008 }, | ||
4434 | { 0x00000048, 0x00000008 }, | ||
4435 | { 0x0000004c, 0x00000010 }, | ||
4436 | { 0x00000050, 0x00000000 }, | ||
4437 | { 0x00000054, 0x0000001f }, | ||
4438 | { 0x00000800, 0x00000000 }, | ||
4439 | { 0x00000804, 0x00000000 }, | ||
4440 | { 0x00000808, 0x00000000 }, | ||
4441 | { 0x0000080c, 0x00000000 }, | ||
4442 | { 0x00000810, 0x00000000 }, | ||
4443 | { 0x00000814, 0x00000000 }, | ||
4444 | { 0x00000818, 0x00000000 }, | ||
4445 | { 0x0000081c, 0x00000000 }, | ||
4446 | { 0x00000820, 0x00000000 }, | ||
4447 | { 0x00000824, 0x00000000 }, | ||
4448 | { 0x00001040, 0x002ffc0f }, | ||
4449 | { 0x00001044, 0x002ffc0f }, | ||
4450 | { 0x00001048, 0x002ffc0f }, | ||
4451 | { 0x0000104c, 0x002ffc0f }, | ||
4452 | { 0x00001050, 0x002ffc0f }, | ||
4453 | { 0x00001054, 0x002ffc0f }, | ||
4454 | { 0x00001058, 0x002ffc0f }, | ||
4455 | { 0x0000105c, 0x002ffc0f }, | ||
4456 | { 0x00001060, 0x002ffc0f }, | ||
4457 | { 0x00001064, 0x002ffc0f }, | ||
4458 | { 0x00001230, 0x00000000 }, | ||
4459 | { 0x00001270, 0x00000000 }, | ||
4460 | { 0x00001038, 0x00000000 }, | ||
4461 | { 0x00001078, 0x00000000 }, | ||
4462 | { 0x000010b8, 0x00000000 }, | ||
4463 | { 0x000010f8, 0x00000000 }, | ||
4464 | { 0x00001138, 0x00000000 }, | ||
4465 | { 0x00001178, 0x00000000 }, | ||
4466 | { 0x000011b8, 0x00000000 }, | ||
4467 | { 0x000011f8, 0x00000000 }, | ||
4468 | { 0x00001238, 0x00000000 }, | ||
4469 | { 0x00001278, 0x00000000 }, | ||
4470 | { 0x000012b8, 0x00000000 }, | ||
4471 | { 0x000012f8, 0x00000000 }, | ||
4472 | { 0x00001338, 0x00000000 }, | ||
4473 | { 0x00001378, 0x00000000 }, | ||
4474 | { 0x000013b8, 0x00000000 }, | ||
4475 | { 0x000013f8, 0x00000000 }, | ||
4476 | { 0x00001438, 0x00000000 }, | ||
4477 | { 0x00001478, 0x00000000 }, | ||
4478 | { 0x000014b8, 0x00000000 }, | ||
4479 | { 0x000014f8, 0x00000000 }, | ||
4480 | { 0x00001538, 0x00000000 }, | ||
4481 | { 0x00001578, 0x00000000 }, | ||
4482 | { 0x000015b8, 0x00000000 }, | ||
4483 | { 0x000015f8, 0x00000000 }, | ||
4484 | { 0x00001638, 0x00000000 }, | ||
4485 | { 0x00001678, 0x00000000 }, | ||
4486 | { 0x000016b8, 0x00000000 }, | ||
4487 | { 0x000016f8, 0x00000000 }, | ||
4488 | { 0x00001738, 0x00000000 }, | ||
4489 | { 0x00001778, 0x00000000 }, | ||
4490 | { 0x000017b8, 0x00000000 }, | ||
4491 | { 0x000017f8, 0x00000000 }, | ||
4492 | { 0x0000103c, 0x00000000 }, | ||
4493 | { 0x0000107c, 0x00000000 }, | ||
4494 | { 0x000010bc, 0x00000000 }, | ||
4495 | { 0x000010fc, 0x00000000 }, | ||
4496 | { 0x0000113c, 0x00000000 }, | ||
4497 | { 0x0000117c, 0x00000000 }, | ||
4498 | { 0x000011bc, 0x00000000 }, | ||
4499 | { 0x000011fc, 0x00000000 }, | ||
4500 | { 0x0000123c, 0x00000000 }, | ||
4501 | { 0x0000127c, 0x00000000 }, | ||
4502 | { 0x000012bc, 0x00000000 }, | ||
4503 | { 0x000012fc, 0x00000000 }, | ||
4504 | { 0x0000133c, 0x00000000 }, | ||
4505 | { 0x0000137c, 0x00000000 }, | ||
4506 | { 0x000013bc, 0x00000000 }, | ||
4507 | { 0x000013fc, 0x00000000 }, | ||
4508 | { 0x0000143c, 0x00000000 }, | ||
4509 | { 0x0000147c, 0x00000000 }, | ||
4510 | { 0x00004030, 0x00000002 }, | ||
4511 | { 0x0000403c, 0x00000002 }, | ||
4512 | { 0x00004024, 0x0000001f }, | ||
4513 | { 0x00004060, 0x00000000 }, | ||
4514 | { 0x00004064, 0x00000000 }, | ||
4515 | { 0x00007010, 0x00000031 }, | ||
4516 | { 0x00007034, 0x00000002 }, | ||
4517 | { 0x00007038, 0x000004c2 }, | ||
4518 | { 0x00008004, 0x00000000 }, | ||
4519 | { 0x00008008, 0x00000000 }, | ||
4520 | { 0x0000800c, 0x00000000 }, | ||
4521 | { 0x00008018, 0x00000700 }, | ||
4522 | { 0x00008020, 0x00000000 }, | ||
4523 | { 0x00008038, 0x00000000 }, | ||
4524 | { 0x0000803c, 0x00000000 }, | ||
4525 | { 0x00008048, 0x00000000 }, | ||
4526 | { 0x00008054, 0x00000000 }, | ||
4527 | { 0x00008058, 0x00000000 }, | ||
4528 | { 0x0000805c, 0x000fc78f }, | ||
4529 | { 0x00008060, 0x0000000f }, | ||
4530 | { 0x00008064, 0x00000000 }, | ||
4531 | { 0x00008070, 0x00000000 }, | ||
4532 | { 0x000080c0, 0x2a80001a }, | ||
4533 | { 0x000080c4, 0x05dc01e0 }, | ||
4534 | { 0x000080c8, 0x1f402710 }, | ||
4535 | { 0x000080cc, 0x01f40000 }, | ||
4536 | { 0x000080d0, 0x00001e00 }, | ||
4537 | { 0x000080d4, 0x00000000 }, | ||
4538 | { 0x000080d8, 0x00400000 }, | ||
4539 | { 0x000080e0, 0xffffffff }, | ||
4540 | { 0x000080e4, 0x0000ffff }, | ||
4541 | { 0x000080e8, 0x003f3f3f }, | ||
4542 | { 0x000080ec, 0x00000000 }, | ||
4543 | { 0x000080f0, 0x00000000 }, | ||
4544 | { 0x000080f4, 0x00000000 }, | ||
4545 | { 0x000080f8, 0x00000000 }, | ||
4546 | { 0x000080fc, 0x00020000 }, | ||
4547 | { 0x00008100, 0x00020000 }, | ||
4548 | { 0x00008104, 0x00000001 }, | ||
4549 | { 0x00008108, 0x00000052 }, | ||
4550 | { 0x0000810c, 0x00000000 }, | ||
4551 | { 0x00008110, 0x00000168 }, | ||
4552 | { 0x00008118, 0x000100aa }, | ||
4553 | { 0x0000811c, 0x00003210 }, | ||
4554 | { 0x00008120, 0x08f04810 }, | ||
4555 | { 0x00008124, 0x00000000 }, | ||
4556 | { 0x00008128, 0x00000000 }, | ||
4557 | { 0x0000812c, 0x00000000 }, | ||
4558 | { 0x00008130, 0x00000000 }, | ||
4559 | { 0x00008134, 0x00000000 }, | ||
4560 | { 0x00008138, 0x00000000 }, | ||
4561 | { 0x0000813c, 0x00000000 }, | ||
4562 | { 0x00008144, 0xffffffff }, | ||
4563 | { 0x00008168, 0x00000000 }, | ||
4564 | { 0x0000816c, 0x00000000 }, | ||
4565 | { 0x00008170, 0x32143320 }, | ||
4566 | { 0x00008174, 0xfaa4fa50 }, | ||
4567 | { 0x00008178, 0x00000100 }, | ||
4568 | { 0x0000817c, 0x00000000 }, | ||
4569 | { 0x000081c0, 0x00000000 }, | ||
4570 | { 0x000081d0, 0x0000320a }, | ||
4571 | { 0x000081ec, 0x00000000 }, | ||
4572 | { 0x000081f0, 0x00000000 }, | ||
4573 | { 0x000081f4, 0x00000000 }, | ||
4574 | { 0x000081f8, 0x00000000 }, | ||
4575 | { 0x000081fc, 0x00000000 }, | ||
4576 | { 0x00008200, 0x00000000 }, | ||
4577 | { 0x00008204, 0x00000000 }, | ||
4578 | { 0x00008208, 0x00000000 }, | ||
4579 | { 0x0000820c, 0x00000000 }, | ||
4580 | { 0x00008210, 0x00000000 }, | ||
4581 | { 0x00008214, 0x00000000 }, | ||
4582 | { 0x00008218, 0x00000000 }, | ||
4583 | { 0x0000821c, 0x00000000 }, | ||
4584 | { 0x00008220, 0x00000000 }, | ||
4585 | { 0x00008224, 0x00000000 }, | ||
4586 | { 0x00008228, 0x00000000 }, | ||
4587 | { 0x0000822c, 0x00000000 }, | ||
4588 | { 0x00008230, 0x00000000 }, | ||
4589 | { 0x00008234, 0x00000000 }, | ||
4590 | { 0x00008238, 0x00000000 }, | ||
4591 | { 0x0000823c, 0x00000000 }, | ||
4592 | { 0x00008240, 0x00100000 }, | ||
4593 | { 0x00008244, 0x0010f400 }, | ||
4594 | { 0x00008248, 0x00000100 }, | ||
4595 | { 0x0000824c, 0x0001e800 }, | ||
4596 | { 0x00008250, 0x00000000 }, | ||
4597 | { 0x00008254, 0x00000000 }, | ||
4598 | { 0x00008258, 0x00000000 }, | ||
4599 | { 0x0000825c, 0x400000ff }, | ||
4600 | { 0x00008260, 0x00080922 }, | ||
4601 | { 0x00008264, 0xa8a00010 }, | ||
4602 | { 0x00008270, 0x00000000 }, | ||
4603 | { 0x00008274, 0x40000000 }, | ||
4604 | { 0x00008278, 0x003e4180 }, | ||
4605 | { 0x0000827c, 0x00000000 }, | ||
4606 | { 0x00008284, 0x0000002c }, | ||
4607 | { 0x00008288, 0x0000002c }, | ||
4608 | { 0x0000828c, 0x00000000 }, | ||
4609 | { 0x00008294, 0x00000000 }, | ||
4610 | { 0x00008298, 0x00000000 }, | ||
4611 | { 0x0000829c, 0x00000000 }, | ||
4612 | { 0x00008300, 0x00000040 }, | ||
4613 | { 0x00008314, 0x00000000 }, | ||
4614 | { 0x00008328, 0x00000000 }, | ||
4615 | { 0x0000832c, 0x00000001 }, | ||
4616 | { 0x00008330, 0x00000302 }, | ||
4617 | { 0x00008334, 0x00000e00 }, | ||
4618 | { 0x00008338, 0x00ff0000 }, | ||
4619 | { 0x0000833c, 0x00000000 }, | ||
4620 | { 0x00008340, 0x00010380 }, | ||
4621 | { 0x00008344, 0x00581043 }, | ||
4622 | { 0x00009808, 0x00000000 }, | ||
4623 | { 0x0000980c, 0xafe68e30 }, | ||
4624 | { 0x00009810, 0xfd14e000 }, | ||
4625 | { 0x00009814, 0x9c0a9f6b }, | ||
4626 | { 0x0000981c, 0x00000000 }, | ||
4627 | { 0x0000982c, 0x0000a000 }, | ||
4628 | { 0x00009830, 0x00000000 }, | ||
4629 | { 0x0000983c, 0x00200400 }, | ||
4630 | { 0x0000984c, 0x0040233c }, | ||
4631 | { 0x00009854, 0x00000044 }, | ||
4632 | { 0x00009900, 0x00000000 }, | ||
4633 | { 0x00009904, 0x00000000 }, | ||
4634 | { 0x00009908, 0x00000000 }, | ||
4635 | { 0x0000990c, 0x00000000 }, | ||
4636 | { 0x00009910, 0x01002310 }, | ||
4637 | { 0x0000991c, 0x10000fff }, | ||
4638 | { 0x00009920, 0x04900000 }, | ||
4639 | { 0x00009928, 0x00000001 }, | ||
4640 | { 0x0000992c, 0x00000004 }, | ||
4641 | { 0x00009934, 0x1e1f2022 }, | ||
4642 | { 0x00009938, 0x0a0b0c0d }, | ||
4643 | { 0x0000993c, 0x00000000 }, | ||
4644 | { 0x00009940, 0x14750604 }, | ||
4645 | { 0x00009948, 0x9280c00a }, | ||
4646 | { 0x0000994c, 0x00020028 }, | ||
4647 | { 0x00009954, 0x5f3ca3de }, | ||
4648 | { 0x00009958, 0x2108ecff }, | ||
4649 | { 0x00009968, 0x000003ce }, | ||
4650 | { 0x00009970, 0x192bb515 }, | ||
4651 | { 0x00009974, 0x00000000 }, | ||
4652 | { 0x00009978, 0x00000001 }, | ||
4653 | { 0x0000997c, 0x00000000 }, | ||
4654 | { 0x00009980, 0x00000000 }, | ||
4655 | { 0x00009984, 0x00000000 }, | ||
4656 | { 0x00009988, 0x00000000 }, | ||
4657 | { 0x0000998c, 0x00000000 }, | ||
4658 | { 0x00009990, 0x00000000 }, | ||
4659 | { 0x00009994, 0x00000000 }, | ||
4660 | { 0x00009998, 0x00000000 }, | ||
4661 | { 0x0000999c, 0x00000000 }, | ||
4662 | { 0x000099a0, 0x00000000 }, | ||
4663 | { 0x000099a4, 0x00000001 }, | ||
4664 | { 0x000099a8, 0x201fff00 }, | ||
4665 | { 0x000099ac, 0x2def0400 }, | ||
4666 | { 0x000099b0, 0x03051000 }, | ||
4667 | { 0x000099b4, 0x00000820 }, | ||
4668 | { 0x000099dc, 0x00000000 }, | ||
4669 | { 0x000099e0, 0x00000000 }, | ||
4670 | { 0x000099e4, 0xaaaaaaaa }, | ||
4671 | { 0x000099e8, 0x3c466478 }, | ||
4672 | { 0x000099ec, 0x0cc80caa }, | ||
4673 | { 0x000099f0, 0x00000000 }, | ||
4674 | { 0x0000a208, 0x803e68c8 }, | ||
4675 | { 0x0000a210, 0x4080a333 }, | ||
4676 | { 0x0000a214, 0x00206c10 }, | ||
4677 | { 0x0000a218, 0x009c4060 }, | ||
4678 | { 0x0000a220, 0x01834061 }, | ||
4679 | { 0x0000a224, 0x00000400 }, | ||
4680 | { 0x0000a228, 0x000003b5 }, | ||
4681 | { 0x0000a22c, 0x00000000 }, | ||
4682 | { 0x0000a234, 0x20202020 }, | ||
4683 | { 0x0000a238, 0x20202020 }, | ||
4684 | { 0x0000a244, 0x00000000 }, | ||
4685 | { 0x0000a248, 0xfffffffc }, | ||
4686 | { 0x0000a24c, 0x00000000 }, | ||
4687 | { 0x0000a254, 0x00000000 }, | ||
4688 | { 0x0000a258, 0x0ccb5380 }, | ||
4689 | { 0x0000a25c, 0x15151501 }, | ||
4690 | { 0x0000a260, 0xdfa90f01 }, | ||
4691 | { 0x0000a268, 0x00000000 }, | ||
4692 | { 0x0000a26c, 0x0ebae9e6 }, | ||
4693 | { 0x0000d270, 0x0d820820 }, | ||
4694 | { 0x0000d35c, 0x07ffffef }, | ||
4695 | { 0x0000d360, 0x0fffffe7 }, | ||
4696 | { 0x0000d364, 0x17ffffe5 }, | ||
4697 | { 0x0000d368, 0x1fffffe4 }, | ||
4698 | { 0x0000d36c, 0x37ffffe3 }, | ||
4699 | { 0x0000d370, 0x3fffffe3 }, | ||
4700 | { 0x0000d374, 0x57ffffe3 }, | ||
4701 | { 0x0000d378, 0x5fffffe2 }, | ||
4702 | { 0x0000d37c, 0x7fffffe2 }, | ||
4703 | { 0x0000d380, 0x7f3c7bba }, | ||
4704 | { 0x0000d384, 0xf3307ff0 }, | ||
4705 | { 0x0000a388, 0x0c000000 }, | ||
4706 | { 0x0000a38c, 0x20202020 }, | ||
4707 | { 0x0000a390, 0x20202020 }, | ||
4708 | { 0x0000a39c, 0x00000001 }, | ||
4709 | { 0x0000a3a0, 0x00000000 }, | ||
4710 | { 0x0000a3a4, 0x00000000 }, | ||
4711 | { 0x0000a3a8, 0x00000000 }, | ||
4712 | { 0x0000a3ac, 0x00000000 }, | ||
4713 | { 0x0000a3b0, 0x00000000 }, | ||
4714 | { 0x0000a3b4, 0x00000000 }, | ||
4715 | { 0x0000a3b8, 0x00000000 }, | ||
4716 | { 0x0000a3bc, 0x00000000 }, | ||
4717 | { 0x0000a3c0, 0x00000000 }, | ||
4718 | { 0x0000a3c4, 0x00000000 }, | ||
4719 | { 0x0000a3cc, 0x20202020 }, | ||
4720 | { 0x0000a3d0, 0x20202020 }, | ||
4721 | { 0x0000a3d4, 0x20202020 }, | ||
4722 | { 0x0000a3e4, 0x00000000 }, | ||
4723 | { 0x0000a3e8, 0x18c43433 }, | ||
4724 | { 0x0000a3ec, 0x00f70081 }, | ||
4725 | { 0x00007800, 0x00140000 }, | ||
4726 | { 0x00007804, 0x0e4548d8 }, | ||
4727 | { 0x00007808, 0x54214514 }, | ||
4728 | { 0x0000780c, 0x02025820 }, | ||
4729 | { 0x00007810, 0x71c0d388 }, | ||
4730 | { 0x00007814, 0x924934a8 }, | ||
4731 | { 0x0000781c, 0x00000000 }, | ||
4732 | { 0x00007824, 0x00d86fff }, | ||
4733 | { 0x00007828, 0x26d2491b }, | ||
4734 | { 0x0000782c, 0x6e36d97b }, | ||
4735 | { 0x00007830, 0xedb6d96e }, | ||
4736 | { 0x00007834, 0x71400087 }, | ||
4737 | { 0x0000783c, 0x0001fffe }, | ||
4738 | { 0x00007840, 0xffeb1a20 }, | ||
4739 | { 0x00007844, 0x000c0db6 }, | ||
4740 | { 0x00007848, 0x6db61b6f }, | ||
4741 | { 0x0000784c, 0x6d9b66db }, | ||
4742 | { 0x00007850, 0x6d8c6dba }, | ||
4743 | { 0x00007854, 0x00040000 }, | ||
4744 | { 0x00007858, 0xdb003012 }, | ||
4745 | { 0x0000785c, 0x04924914 }, | ||
4746 | { 0x00007860, 0x21084210 }, | ||
4747 | { 0x00007864, 0xf7d7ffde }, | ||
4748 | { 0x00007868, 0xc2034080 }, | ||
4749 | { 0x00007870, 0x10142c00 }, | ||
4750 | }; | ||
4751 | |||
4752 | static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = { | ||
4753 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ | ||
4754 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
4755 | { 0x0000a304, 0x00000000, 0x00000000, 0x00005200, 0x00005200, 0x00000000 }, | ||
4756 | { 0x0000a308, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 }, | ||
4757 | { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 }, | ||
4758 | { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 }, | ||
4759 | { 0x0000a314, 0x00000000, 0x00000000, 0x0000f440, 0x0000f440, 0x00000000 }, | ||
4760 | { 0x0000a318, 0x00000000, 0x00000000, 0x00014640, 0x00014640, 0x00000000 }, | ||
4761 | { 0x0000a31c, 0x00000000, 0x00000000, 0x00018680, 0x00018680, 0x00000000 }, | ||
4762 | { 0x0000a320, 0x00000000, 0x00000000, 0x00019841, 0x00019841, 0x00000000 }, | ||
4763 | { 0x0000a324, 0x00000000, 0x00000000, 0x0001ca40, 0x0001ca40, 0x00000000 }, | ||
4764 | { 0x0000a328, 0x00000000, 0x00000000, 0x0001fa80, 0x0001fa80, 0x00000000 }, | ||
4765 | { 0x0000a32c, 0x00000000, 0x00000000, 0x00023ac0, 0x00023ac0, 0x00000000 }, | ||
4766 | { 0x0000a330, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 }, | ||
4767 | { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 }, | ||
4768 | { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 }, | ||
4769 | { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 }, | ||
4770 | { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
4771 | { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
4772 | { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
4773 | { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
4774 | { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
4775 | { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
4776 | { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 }, | ||
4777 | { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe }, | ||
4778 | { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 }, | ||
4779 | { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a21a652, 0x0a21a652, 0x0a22a652 }, | ||
4780 | { 0x0000a278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce }, | ||
4781 | { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce }, | ||
4782 | { 0x0000a394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce }, | ||
4783 | { 0x0000a398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce }, | ||
4784 | { 0x0000a3dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce }, | ||
4785 | { 0x0000a3e0, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce }, | ||
4786 | }; | ||
4787 | |||
4788 | static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = { | ||
4789 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ | ||
4790 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
4791 | { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 }, | ||
4792 | { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 }, | ||
4793 | { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 }, | ||
4794 | { 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 }, | ||
4795 | { 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 }, | ||
4796 | { 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 }, | ||
4797 | { 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 }, | ||
4798 | { 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 }, | ||
4799 | { 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 }, | ||
4800 | { 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 }, | ||
4801 | { 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 }, | ||
4802 | { 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 }, | ||
4803 | { 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 }, | ||
4804 | { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 }, | ||
4805 | { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 }, | ||
4806 | { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
4807 | { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
4808 | { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
4809 | { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
4810 | { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
4811 | { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
4812 | { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 }, | ||
4813 | { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 }, | ||
4814 | { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 }, | ||
4815 | { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 }, | ||
4816 | { 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c }, | ||
4817 | { 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c }, | ||
4818 | { 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c }, | ||
4819 | { 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c }, | ||
4820 | { 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c }, | ||
4821 | { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c }, | ||
4822 | }; | ||
4823 | |||
4824 | static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = { | ||
4825 | {0x00004040, 0x9248fd00 }, | ||
4826 | {0x00004040, 0x24924924 }, | ||
4827 | {0x00004040, 0xa8000019 }, | ||
4828 | {0x00004040, 0x13160820 }, | ||
4829 | {0x00004040, 0xe5980560 }, | ||
4830 | {0x00004040, 0xc01dcffd }, | ||
4831 | {0x00004040, 0x1aaabe41 }, | ||
4832 | {0x00004040, 0xbe105554 }, | ||
4833 | {0x00004040, 0x00043007 }, | ||
4834 | {0x00004044, 0x00000000 }, | ||
4835 | }; | ||
4836 | |||
4837 | static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = { | ||
4838 | {0x00004040, 0x9248fd00 }, | ||
4839 | {0x00004040, 0x24924924 }, | ||
4840 | {0x00004040, 0xa8000019 }, | ||
4841 | {0x00004040, 0x13160820 }, | ||
4842 | {0x00004040, 0xe5980560 }, | ||
4843 | {0x00004040, 0xc01dcffc }, | ||
4844 | {0x00004040, 0x1aaabe41 }, | ||
4845 | {0x00004040, 0xbe105554 }, | ||
4846 | {0x00004040, 0x00043007 }, | ||
4847 | {0x00004044, 0x00000000 }, | ||
4848 | }; | ||
diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath9k/mac.c deleted file mode 100644 index 8ae4ec21667b..000000000000 --- a/drivers/net/wireless/ath9k/mac.c +++ /dev/null | |||
@@ -1,976 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 "ath9k.h" | ||
18 | |||
19 | static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, | ||
20 | struct ath9k_tx_queue_info *qi) | ||
21 | { | ||
22 | DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, | ||
23 | "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", | ||
24 | ah->txok_interrupt_mask, ah->txerr_interrupt_mask, | ||
25 | ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask, | ||
26 | ah->txurn_interrupt_mask); | ||
27 | |||
28 | REG_WRITE(ah, AR_IMR_S0, | ||
29 | SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK) | ||
30 | | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC)); | ||
31 | REG_WRITE(ah, AR_IMR_S1, | ||
32 | SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR) | ||
33 | | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL)); | ||
34 | REG_RMW_FIELD(ah, AR_IMR_S2, | ||
35 | AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask); | ||
36 | } | ||
37 | |||
38 | u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) | ||
39 | { | ||
40 | return REG_READ(ah, AR_QTXDP(q)); | ||
41 | } | ||
42 | |||
43 | bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp) | ||
44 | { | ||
45 | REG_WRITE(ah, AR_QTXDP(q), txdp); | ||
46 | |||
47 | return true; | ||
48 | } | ||
49 | |||
50 | bool ath9k_hw_txstart(struct ath_hw *ah, u32 q) | ||
51 | { | ||
52 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q); | ||
53 | |||
54 | REG_WRITE(ah, AR_Q_TXE, 1 << q); | ||
55 | |||
56 | return true; | ||
57 | } | ||
58 | |||
59 | u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q) | ||
60 | { | ||
61 | u32 npend; | ||
62 | |||
63 | npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT; | ||
64 | if (npend == 0) { | ||
65 | |||
66 | if (REG_READ(ah, AR_Q_TXE) & (1 << q)) | ||
67 | npend = 1; | ||
68 | } | ||
69 | |||
70 | return npend; | ||
71 | } | ||
72 | |||
73 | bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel) | ||
74 | { | ||
75 | u32 txcfg, curLevel, newLevel; | ||
76 | enum ath9k_int omask; | ||
77 | |||
78 | if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD) | ||
79 | return false; | ||
80 | |||
81 | omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL); | ||
82 | |||
83 | txcfg = REG_READ(ah, AR_TXCFG); | ||
84 | curLevel = MS(txcfg, AR_FTRIG); | ||
85 | newLevel = curLevel; | ||
86 | if (bIncTrigLevel) { | ||
87 | if (curLevel < MAX_TX_FIFO_THRESHOLD) | ||
88 | newLevel++; | ||
89 | } else if (curLevel > MIN_TX_FIFO_THRESHOLD) | ||
90 | newLevel--; | ||
91 | if (newLevel != curLevel) | ||
92 | REG_WRITE(ah, AR_TXCFG, | ||
93 | (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG)); | ||
94 | |||
95 | ath9k_hw_set_interrupts(ah, omask); | ||
96 | |||
97 | ah->tx_trig_level = newLevel; | ||
98 | |||
99 | return newLevel != curLevel; | ||
100 | } | ||
101 | |||
102 | bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) | ||
103 | { | ||
104 | #define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */ | ||
105 | #define ATH9K_TIME_QUANTUM 100 /* usec */ | ||
106 | |||
107 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
108 | struct ath9k_tx_queue_info *qi; | ||
109 | u32 tsfLow, j, wait; | ||
110 | u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM; | ||
111 | |||
112 | if (q >= pCap->total_queues) { | ||
113 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, " | ||
114 | "invalid queue: %u\n", q); | ||
115 | return false; | ||
116 | } | ||
117 | |||
118 | qi = &ah->txq[q]; | ||
119 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | ||
120 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, " | ||
121 | "inactive queue: %u\n", q); | ||
122 | return false; | ||
123 | } | ||
124 | |||
125 | REG_WRITE(ah, AR_Q_TXD, 1 << q); | ||
126 | |||
127 | for (wait = wait_time; wait != 0; wait--) { | ||
128 | if (ath9k_hw_numtxpending(ah, q) == 0) | ||
129 | break; | ||
130 | udelay(ATH9K_TIME_QUANTUM); | ||
131 | } | ||
132 | |||
133 | if (ath9k_hw_numtxpending(ah, q)) { | ||
134 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, | ||
135 | "%s: Num of pending TX Frames %d on Q %d\n", | ||
136 | __func__, ath9k_hw_numtxpending(ah, q), q); | ||
137 | |||
138 | for (j = 0; j < 2; j++) { | ||
139 | tsfLow = REG_READ(ah, AR_TSF_L32); | ||
140 | REG_WRITE(ah, AR_QUIET2, | ||
141 | SM(10, AR_QUIET2_QUIET_DUR)); | ||
142 | REG_WRITE(ah, AR_QUIET_PERIOD, 100); | ||
143 | REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10); | ||
144 | REG_SET_BIT(ah, AR_TIMER_MODE, | ||
145 | AR_QUIET_TIMER_EN); | ||
146 | |||
147 | if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10)) | ||
148 | break; | ||
149 | |||
150 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, | ||
151 | "TSF has moved while trying to set " | ||
152 | "quiet time TSF: 0x%08x\n", tsfLow); | ||
153 | } | ||
154 | |||
155 | REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); | ||
156 | |||
157 | udelay(200); | ||
158 | REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN); | ||
159 | |||
160 | wait = wait_time; | ||
161 | while (ath9k_hw_numtxpending(ah, q)) { | ||
162 | if ((--wait) == 0) { | ||
163 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, | ||
164 | "Failed to stop TX DMA in 100 " | ||
165 | "msec after killing last frame\n"); | ||
166 | break; | ||
167 | } | ||
168 | udelay(ATH9K_TIME_QUANTUM); | ||
169 | } | ||
170 | |||
171 | REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); | ||
172 | } | ||
173 | |||
174 | REG_WRITE(ah, AR_Q_TXD, 0); | ||
175 | return wait != 0; | ||
176 | |||
177 | #undef ATH9K_TX_STOP_DMA_TIMEOUT | ||
178 | #undef ATH9K_TIME_QUANTUM | ||
179 | } | ||
180 | |||
181 | bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds, | ||
182 | u32 segLen, bool firstSeg, | ||
183 | bool lastSeg, const struct ath_desc *ds0) | ||
184 | { | ||
185 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
186 | |||
187 | if (firstSeg) { | ||
188 | ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore); | ||
189 | } else if (lastSeg) { | ||
190 | ads->ds_ctl0 = 0; | ||
191 | ads->ds_ctl1 = segLen; | ||
192 | ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2; | ||
193 | ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3; | ||
194 | } else { | ||
195 | ads->ds_ctl0 = 0; | ||
196 | ads->ds_ctl1 = segLen | AR_TxMore; | ||
197 | ads->ds_ctl2 = 0; | ||
198 | ads->ds_ctl3 = 0; | ||
199 | } | ||
200 | ads->ds_txstatus0 = ads->ds_txstatus1 = 0; | ||
201 | ads->ds_txstatus2 = ads->ds_txstatus3 = 0; | ||
202 | ads->ds_txstatus4 = ads->ds_txstatus5 = 0; | ||
203 | ads->ds_txstatus6 = ads->ds_txstatus7 = 0; | ||
204 | ads->ds_txstatus8 = ads->ds_txstatus9 = 0; | ||
205 | |||
206 | return true; | ||
207 | } | ||
208 | |||
209 | void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds) | ||
210 | { | ||
211 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
212 | |||
213 | ads->ds_txstatus0 = ads->ds_txstatus1 = 0; | ||
214 | ads->ds_txstatus2 = ads->ds_txstatus3 = 0; | ||
215 | ads->ds_txstatus4 = ads->ds_txstatus5 = 0; | ||
216 | ads->ds_txstatus6 = ads->ds_txstatus7 = 0; | ||
217 | ads->ds_txstatus8 = ads->ds_txstatus9 = 0; | ||
218 | } | ||
219 | |||
220 | int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds) | ||
221 | { | ||
222 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
223 | |||
224 | if ((ads->ds_txstatus9 & AR_TxDone) == 0) | ||
225 | return -EINPROGRESS; | ||
226 | |||
227 | ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum); | ||
228 | ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp; | ||
229 | ds->ds_txstat.ts_status = 0; | ||
230 | ds->ds_txstat.ts_flags = 0; | ||
231 | |||
232 | if (ads->ds_txstatus1 & AR_ExcessiveRetries) | ||
233 | ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY; | ||
234 | if (ads->ds_txstatus1 & AR_Filtered) | ||
235 | ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT; | ||
236 | if (ads->ds_txstatus1 & AR_FIFOUnderrun) { | ||
237 | ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO; | ||
238 | ath9k_hw_updatetxtriglevel(ah, true); | ||
239 | } | ||
240 | if (ads->ds_txstatus9 & AR_TxOpExceeded) | ||
241 | ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP; | ||
242 | if (ads->ds_txstatus1 & AR_TxTimerExpired) | ||
243 | ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED; | ||
244 | |||
245 | if (ads->ds_txstatus1 & AR_DescCfgErr) | ||
246 | ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR; | ||
247 | if (ads->ds_txstatus1 & AR_TxDataUnderrun) { | ||
248 | ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN; | ||
249 | ath9k_hw_updatetxtriglevel(ah, true); | ||
250 | } | ||
251 | if (ads->ds_txstatus1 & AR_TxDelimUnderrun) { | ||
252 | ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN; | ||
253 | ath9k_hw_updatetxtriglevel(ah, true); | ||
254 | } | ||
255 | if (ads->ds_txstatus0 & AR_TxBaStatus) { | ||
256 | ds->ds_txstat.ts_flags |= ATH9K_TX_BA; | ||
257 | ds->ds_txstat.ba_low = ads->AR_BaBitmapLow; | ||
258 | ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh; | ||
259 | } | ||
260 | |||
261 | ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx); | ||
262 | switch (ds->ds_txstat.ts_rateindex) { | ||
263 | case 0: | ||
264 | ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0); | ||
265 | break; | ||
266 | case 1: | ||
267 | ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1); | ||
268 | break; | ||
269 | case 2: | ||
270 | ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2); | ||
271 | break; | ||
272 | case 3: | ||
273 | ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3); | ||
274 | break; | ||
275 | } | ||
276 | |||
277 | ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined); | ||
278 | ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00); | ||
279 | ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01); | ||
280 | ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02); | ||
281 | ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10); | ||
282 | ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11); | ||
283 | ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12); | ||
284 | ds->ds_txstat.evm0 = ads->AR_TxEVM0; | ||
285 | ds->ds_txstat.evm1 = ads->AR_TxEVM1; | ||
286 | ds->ds_txstat.evm2 = ads->AR_TxEVM2; | ||
287 | ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt); | ||
288 | ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt); | ||
289 | ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt); | ||
290 | ds->ds_txstat.ts_antenna = 0; | ||
291 | |||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds, | ||
296 | u32 pktLen, enum ath9k_pkt_type type, u32 txPower, | ||
297 | u32 keyIx, enum ath9k_key_type keyType, u32 flags) | ||
298 | { | ||
299 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
300 | |||
301 | txPower += ah->txpower_indexoffset; | ||
302 | if (txPower > 63) | ||
303 | txPower = 63; | ||
304 | |||
305 | ads->ds_ctl0 = (pktLen & AR_FrameLen) | ||
306 | | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) | ||
307 | | SM(txPower, AR_XmitPower) | ||
308 | | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) | ||
309 | | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) | ||
310 | | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) | ||
311 | | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0); | ||
312 | |||
313 | ads->ds_ctl1 = | ||
314 | (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0) | ||
315 | | SM(type, AR_FrameType) | ||
316 | | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0) | ||
317 | | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) | ||
318 | | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0); | ||
319 | |||
320 | ads->ds_ctl6 = SM(keyType, AR_EncrType); | ||
321 | |||
322 | if (AR_SREV_9285(ah)) { | ||
323 | ads->ds_ctl8 = 0; | ||
324 | ads->ds_ctl9 = 0; | ||
325 | ads->ds_ctl10 = 0; | ||
326 | ads->ds_ctl11 = 0; | ||
327 | } | ||
328 | } | ||
329 | |||
330 | void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds, | ||
331 | struct ath_desc *lastds, | ||
332 | u32 durUpdateEn, u32 rtsctsRate, | ||
333 | u32 rtsctsDuration, | ||
334 | struct ath9k_11n_rate_series series[], | ||
335 | u32 nseries, u32 flags) | ||
336 | { | ||
337 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
338 | struct ar5416_desc *last_ads = AR5416DESC(lastds); | ||
339 | u32 ds_ctl0; | ||
340 | |||
341 | if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) { | ||
342 | ds_ctl0 = ads->ds_ctl0; | ||
343 | |||
344 | if (flags & ATH9K_TXDESC_RTSENA) { | ||
345 | ds_ctl0 &= ~AR_CTSEnable; | ||
346 | ds_ctl0 |= AR_RTSEnable; | ||
347 | } else { | ||
348 | ds_ctl0 &= ~AR_RTSEnable; | ||
349 | ds_ctl0 |= AR_CTSEnable; | ||
350 | } | ||
351 | |||
352 | ads->ds_ctl0 = ds_ctl0; | ||
353 | } else { | ||
354 | ads->ds_ctl0 = | ||
355 | (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable)); | ||
356 | } | ||
357 | |||
358 | ads->ds_ctl2 = set11nTries(series, 0) | ||
359 | | set11nTries(series, 1) | ||
360 | | set11nTries(series, 2) | ||
361 | | set11nTries(series, 3) | ||
362 | | (durUpdateEn ? AR_DurUpdateEna : 0) | ||
363 | | SM(0, AR_BurstDur); | ||
364 | |||
365 | ads->ds_ctl3 = set11nRate(series, 0) | ||
366 | | set11nRate(series, 1) | ||
367 | | set11nRate(series, 2) | ||
368 | | set11nRate(series, 3); | ||
369 | |||
370 | ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0) | ||
371 | | set11nPktDurRTSCTS(series, 1); | ||
372 | |||
373 | ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2) | ||
374 | | set11nPktDurRTSCTS(series, 3); | ||
375 | |||
376 | ads->ds_ctl7 = set11nRateFlags(series, 0) | ||
377 | | set11nRateFlags(series, 1) | ||
378 | | set11nRateFlags(series, 2) | ||
379 | | set11nRateFlags(series, 3) | ||
380 | | SM(rtsctsRate, AR_RTSCTSRate); | ||
381 | last_ads->ds_ctl2 = ads->ds_ctl2; | ||
382 | last_ads->ds_ctl3 = ads->ds_ctl3; | ||
383 | } | ||
384 | |||
385 | void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds, | ||
386 | u32 aggrLen) | ||
387 | { | ||
388 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
389 | |||
390 | ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); | ||
391 | ads->ds_ctl6 &= ~AR_AggrLen; | ||
392 | ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen); | ||
393 | } | ||
394 | |||
395 | void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds, | ||
396 | u32 numDelims) | ||
397 | { | ||
398 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
399 | unsigned int ctl6; | ||
400 | |||
401 | ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); | ||
402 | |||
403 | ctl6 = ads->ds_ctl6; | ||
404 | ctl6 &= ~AR_PadDelim; | ||
405 | ctl6 |= SM(numDelims, AR_PadDelim); | ||
406 | ads->ds_ctl6 = ctl6; | ||
407 | } | ||
408 | |||
409 | void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds) | ||
410 | { | ||
411 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
412 | |||
413 | ads->ds_ctl1 |= AR_IsAggr; | ||
414 | ads->ds_ctl1 &= ~AR_MoreAggr; | ||
415 | ads->ds_ctl6 &= ~AR_PadDelim; | ||
416 | } | ||
417 | |||
418 | void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds) | ||
419 | { | ||
420 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
421 | |||
422 | ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr); | ||
423 | } | ||
424 | |||
425 | void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds, | ||
426 | u32 burstDuration) | ||
427 | { | ||
428 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
429 | |||
430 | ads->ds_ctl2 &= ~AR_BurstDur; | ||
431 | ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur); | ||
432 | } | ||
433 | |||
434 | void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds, | ||
435 | u32 vmf) | ||
436 | { | ||
437 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
438 | |||
439 | if (vmf) | ||
440 | ads->ds_ctl0 |= AR_VirtMoreFrag; | ||
441 | else | ||
442 | ads->ds_ctl0 &= ~AR_VirtMoreFrag; | ||
443 | } | ||
444 | |||
445 | void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs) | ||
446 | { | ||
447 | *txqs &= ah->intr_txqs; | ||
448 | ah->intr_txqs &= ~(*txqs); | ||
449 | } | ||
450 | |||
451 | bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, | ||
452 | const struct ath9k_tx_queue_info *qinfo) | ||
453 | { | ||
454 | u32 cw; | ||
455 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
456 | struct ath9k_tx_queue_info *qi; | ||
457 | |||
458 | if (q >= pCap->total_queues) { | ||
459 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, " | ||
460 | "invalid queue: %u\n", q); | ||
461 | return false; | ||
462 | } | ||
463 | |||
464 | qi = &ah->txq[q]; | ||
465 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | ||
466 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, " | ||
467 | "inactive queue: %u\n", q); | ||
468 | return false; | ||
469 | } | ||
470 | |||
471 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q); | ||
472 | |||
473 | qi->tqi_ver = qinfo->tqi_ver; | ||
474 | qi->tqi_subtype = qinfo->tqi_subtype; | ||
475 | qi->tqi_qflags = qinfo->tqi_qflags; | ||
476 | qi->tqi_priority = qinfo->tqi_priority; | ||
477 | if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT) | ||
478 | qi->tqi_aifs = min(qinfo->tqi_aifs, 255U); | ||
479 | else | ||
480 | qi->tqi_aifs = INIT_AIFS; | ||
481 | if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) { | ||
482 | cw = min(qinfo->tqi_cwmin, 1024U); | ||
483 | qi->tqi_cwmin = 1; | ||
484 | while (qi->tqi_cwmin < cw) | ||
485 | qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1; | ||
486 | } else | ||
487 | qi->tqi_cwmin = qinfo->tqi_cwmin; | ||
488 | if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) { | ||
489 | cw = min(qinfo->tqi_cwmax, 1024U); | ||
490 | qi->tqi_cwmax = 1; | ||
491 | while (qi->tqi_cwmax < cw) | ||
492 | qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1; | ||
493 | } else | ||
494 | qi->tqi_cwmax = INIT_CWMAX; | ||
495 | |||
496 | if (qinfo->tqi_shretry != 0) | ||
497 | qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U); | ||
498 | else | ||
499 | qi->tqi_shretry = INIT_SH_RETRY; | ||
500 | if (qinfo->tqi_lgretry != 0) | ||
501 | qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U); | ||
502 | else | ||
503 | qi->tqi_lgretry = INIT_LG_RETRY; | ||
504 | qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod; | ||
505 | qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit; | ||
506 | qi->tqi_burstTime = qinfo->tqi_burstTime; | ||
507 | qi->tqi_readyTime = qinfo->tqi_readyTime; | ||
508 | |||
509 | switch (qinfo->tqi_subtype) { | ||
510 | case ATH9K_WME_UPSD: | ||
511 | if (qi->tqi_type == ATH9K_TX_QUEUE_DATA) | ||
512 | qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS; | ||
513 | break; | ||
514 | default: | ||
515 | break; | ||
516 | } | ||
517 | |||
518 | return true; | ||
519 | } | ||
520 | |||
521 | bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q, | ||
522 | struct ath9k_tx_queue_info *qinfo) | ||
523 | { | ||
524 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
525 | struct ath9k_tx_queue_info *qi; | ||
526 | |||
527 | if (q >= pCap->total_queues) { | ||
528 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, " | ||
529 | "invalid queue: %u\n", q); | ||
530 | return false; | ||
531 | } | ||
532 | |||
533 | qi = &ah->txq[q]; | ||
534 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | ||
535 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, " | ||
536 | "inactive queue: %u\n", q); | ||
537 | return false; | ||
538 | } | ||
539 | |||
540 | qinfo->tqi_qflags = qi->tqi_qflags; | ||
541 | qinfo->tqi_ver = qi->tqi_ver; | ||
542 | qinfo->tqi_subtype = qi->tqi_subtype; | ||
543 | qinfo->tqi_qflags = qi->tqi_qflags; | ||
544 | qinfo->tqi_priority = qi->tqi_priority; | ||
545 | qinfo->tqi_aifs = qi->tqi_aifs; | ||
546 | qinfo->tqi_cwmin = qi->tqi_cwmin; | ||
547 | qinfo->tqi_cwmax = qi->tqi_cwmax; | ||
548 | qinfo->tqi_shretry = qi->tqi_shretry; | ||
549 | qinfo->tqi_lgretry = qi->tqi_lgretry; | ||
550 | qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod; | ||
551 | qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit; | ||
552 | qinfo->tqi_burstTime = qi->tqi_burstTime; | ||
553 | qinfo->tqi_readyTime = qi->tqi_readyTime; | ||
554 | |||
555 | return true; | ||
556 | } | ||
557 | |||
558 | int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, | ||
559 | const struct ath9k_tx_queue_info *qinfo) | ||
560 | { | ||
561 | struct ath9k_tx_queue_info *qi; | ||
562 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
563 | int q; | ||
564 | |||
565 | switch (type) { | ||
566 | case ATH9K_TX_QUEUE_BEACON: | ||
567 | q = pCap->total_queues - 1; | ||
568 | break; | ||
569 | case ATH9K_TX_QUEUE_CAB: | ||
570 | q = pCap->total_queues - 2; | ||
571 | break; | ||
572 | case ATH9K_TX_QUEUE_PSPOLL: | ||
573 | q = 1; | ||
574 | break; | ||
575 | case ATH9K_TX_QUEUE_UAPSD: | ||
576 | q = pCap->total_queues - 3; | ||
577 | break; | ||
578 | case ATH9K_TX_QUEUE_DATA: | ||
579 | for (q = 0; q < pCap->total_queues; q++) | ||
580 | if (ah->txq[q].tqi_type == | ||
581 | ATH9K_TX_QUEUE_INACTIVE) | ||
582 | break; | ||
583 | if (q == pCap->total_queues) { | ||
584 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
585 | "No available TX queue\n"); | ||
586 | return -1; | ||
587 | } | ||
588 | break; | ||
589 | default: | ||
590 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Invalid TX queue type: %u\n", | ||
591 | type); | ||
592 | return -1; | ||
593 | } | ||
594 | |||
595 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q); | ||
596 | |||
597 | qi = &ah->txq[q]; | ||
598 | if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) { | ||
599 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
600 | "TX queue: %u already active\n", q); | ||
601 | return -1; | ||
602 | } | ||
603 | memset(qi, 0, sizeof(struct ath9k_tx_queue_info)); | ||
604 | qi->tqi_type = type; | ||
605 | if (qinfo == NULL) { | ||
606 | qi->tqi_qflags = | ||
607 | TXQ_FLAG_TXOKINT_ENABLE | ||
608 | | TXQ_FLAG_TXERRINT_ENABLE | ||
609 | | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE; | ||
610 | qi->tqi_aifs = INIT_AIFS; | ||
611 | qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT; | ||
612 | qi->tqi_cwmax = INIT_CWMAX; | ||
613 | qi->tqi_shretry = INIT_SH_RETRY; | ||
614 | qi->tqi_lgretry = INIT_LG_RETRY; | ||
615 | qi->tqi_physCompBuf = 0; | ||
616 | } else { | ||
617 | qi->tqi_physCompBuf = qinfo->tqi_physCompBuf; | ||
618 | (void) ath9k_hw_set_txq_props(ah, q, qinfo); | ||
619 | } | ||
620 | |||
621 | return q; | ||
622 | } | ||
623 | |||
624 | bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) | ||
625 | { | ||
626 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
627 | struct ath9k_tx_queue_info *qi; | ||
628 | |||
629 | if (q >= pCap->total_queues) { | ||
630 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, " | ||
631 | "invalid queue: %u\n", q); | ||
632 | return false; | ||
633 | } | ||
634 | qi = &ah->txq[q]; | ||
635 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | ||
636 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, " | ||
637 | "inactive queue: %u\n", q); | ||
638 | return false; | ||
639 | } | ||
640 | |||
641 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TX queue: %u\n", q); | ||
642 | |||
643 | qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; | ||
644 | ah->txok_interrupt_mask &= ~(1 << q); | ||
645 | ah->txerr_interrupt_mask &= ~(1 << q); | ||
646 | ah->txdesc_interrupt_mask &= ~(1 << q); | ||
647 | ah->txeol_interrupt_mask &= ~(1 << q); | ||
648 | ah->txurn_interrupt_mask &= ~(1 << q); | ||
649 | ath9k_hw_set_txq_interrupts(ah, qi); | ||
650 | |||
651 | return true; | ||
652 | } | ||
653 | |||
654 | bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | ||
655 | { | ||
656 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
657 | struct ath9k_channel *chan = ah->curchan; | ||
658 | struct ath9k_tx_queue_info *qi; | ||
659 | u32 cwMin, chanCwMin, value; | ||
660 | |||
661 | if (q >= pCap->total_queues) { | ||
662 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, " | ||
663 | "invalid queue: %u\n", q); | ||
664 | return false; | ||
665 | } | ||
666 | |||
667 | qi = &ah->txq[q]; | ||
668 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | ||
669 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, " | ||
670 | "inactive queue: %u\n", q); | ||
671 | return true; | ||
672 | } | ||
673 | |||
674 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q); | ||
675 | |||
676 | if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) { | ||
677 | if (chan && IS_CHAN_B(chan)) | ||
678 | chanCwMin = INIT_CWMIN_11B; | ||
679 | else | ||
680 | chanCwMin = INIT_CWMIN; | ||
681 | |||
682 | for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1); | ||
683 | } else | ||
684 | cwMin = qi->tqi_cwmin; | ||
685 | |||
686 | REG_WRITE(ah, AR_DLCL_IFS(q), | ||
687 | SM(cwMin, AR_D_LCL_IFS_CWMIN) | | ||
688 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) | | ||
689 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS)); | ||
690 | |||
691 | REG_WRITE(ah, AR_DRETRY_LIMIT(q), | ||
692 | SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) | | ||
693 | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) | | ||
694 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)); | ||
695 | |||
696 | REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ); | ||
697 | REG_WRITE(ah, AR_DMISC(q), | ||
698 | AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2); | ||
699 | |||
700 | if (qi->tqi_cbrPeriod) { | ||
701 | REG_WRITE(ah, AR_QCBRCFG(q), | ||
702 | SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) | | ||
703 | SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH)); | ||
704 | REG_WRITE(ah, AR_QMISC(q), | ||
705 | REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | | ||
706 | (qi->tqi_cbrOverflowLimit ? | ||
707 | AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0)); | ||
708 | } | ||
709 | if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) { | ||
710 | REG_WRITE(ah, AR_QRDYTIMECFG(q), | ||
711 | SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) | | ||
712 | AR_Q_RDYTIMECFG_EN); | ||
713 | } | ||
714 | |||
715 | REG_WRITE(ah, AR_DCHNTIME(q), | ||
716 | SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) | | ||
717 | (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0)); | ||
718 | |||
719 | if (qi->tqi_burstTime | ||
720 | && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) { | ||
721 | REG_WRITE(ah, AR_QMISC(q), | ||
722 | REG_READ(ah, AR_QMISC(q)) | | ||
723 | AR_Q_MISC_RDYTIME_EXP_POLICY); | ||
724 | |||
725 | } | ||
726 | |||
727 | if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) { | ||
728 | REG_WRITE(ah, AR_DMISC(q), | ||
729 | REG_READ(ah, AR_DMISC(q)) | | ||
730 | AR_D_MISC_POST_FR_BKOFF_DIS); | ||
731 | } | ||
732 | if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) { | ||
733 | REG_WRITE(ah, AR_DMISC(q), | ||
734 | REG_READ(ah, AR_DMISC(q)) | | ||
735 | AR_D_MISC_FRAG_BKOFF_EN); | ||
736 | } | ||
737 | switch (qi->tqi_type) { | ||
738 | case ATH9K_TX_QUEUE_BEACON: | ||
739 | REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) | ||
740 | | AR_Q_MISC_FSP_DBA_GATED | ||
741 | | AR_Q_MISC_BEACON_USE | ||
742 | | AR_Q_MISC_CBR_INCR_DIS1); | ||
743 | |||
744 | REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) | ||
745 | | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << | ||
746 | AR_D_MISC_ARB_LOCKOUT_CNTRL_S) | ||
747 | | AR_D_MISC_BEACON_USE | ||
748 | | AR_D_MISC_POST_FR_BKOFF_DIS); | ||
749 | break; | ||
750 | case ATH9K_TX_QUEUE_CAB: | ||
751 | REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) | ||
752 | | AR_Q_MISC_FSP_DBA_GATED | ||
753 | | AR_Q_MISC_CBR_INCR_DIS1 | ||
754 | | AR_Q_MISC_CBR_INCR_DIS0); | ||
755 | value = (qi->tqi_readyTime - | ||
756 | (ah->config.sw_beacon_response_time - | ||
757 | ah->config.dma_beacon_response_time) - | ||
758 | ah->config.additional_swba_backoff) * 1024; | ||
759 | REG_WRITE(ah, AR_QRDYTIMECFG(q), | ||
760 | value | AR_Q_RDYTIMECFG_EN); | ||
761 | REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) | ||
762 | | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << | ||
763 | AR_D_MISC_ARB_LOCKOUT_CNTRL_S)); | ||
764 | break; | ||
765 | case ATH9K_TX_QUEUE_PSPOLL: | ||
766 | REG_WRITE(ah, AR_QMISC(q), | ||
767 | REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1); | ||
768 | break; | ||
769 | case ATH9K_TX_QUEUE_UAPSD: | ||
770 | REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) | | ||
771 | AR_D_MISC_POST_FR_BKOFF_DIS); | ||
772 | break; | ||
773 | default: | ||
774 | break; | ||
775 | } | ||
776 | |||
777 | if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) { | ||
778 | REG_WRITE(ah, AR_DMISC(q), | ||
779 | REG_READ(ah, AR_DMISC(q)) | | ||
780 | SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, | ||
781 | AR_D_MISC_ARB_LOCKOUT_CNTRL) | | ||
782 | AR_D_MISC_POST_FR_BKOFF_DIS); | ||
783 | } | ||
784 | |||
785 | if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE) | ||
786 | ah->txok_interrupt_mask |= 1 << q; | ||
787 | else | ||
788 | ah->txok_interrupt_mask &= ~(1 << q); | ||
789 | if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE) | ||
790 | ah->txerr_interrupt_mask |= 1 << q; | ||
791 | else | ||
792 | ah->txerr_interrupt_mask &= ~(1 << q); | ||
793 | if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE) | ||
794 | ah->txdesc_interrupt_mask |= 1 << q; | ||
795 | else | ||
796 | ah->txdesc_interrupt_mask &= ~(1 << q); | ||
797 | if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE) | ||
798 | ah->txeol_interrupt_mask |= 1 << q; | ||
799 | else | ||
800 | ah->txeol_interrupt_mask &= ~(1 << q); | ||
801 | if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE) | ||
802 | ah->txurn_interrupt_mask |= 1 << q; | ||
803 | else | ||
804 | ah->txurn_interrupt_mask &= ~(1 << q); | ||
805 | ath9k_hw_set_txq_interrupts(ah, qi); | ||
806 | |||
807 | return true; | ||
808 | } | ||
809 | |||
810 | int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, | ||
811 | u32 pa, struct ath_desc *nds, u64 tsf) | ||
812 | { | ||
813 | struct ar5416_desc ads; | ||
814 | struct ar5416_desc *adsp = AR5416DESC(ds); | ||
815 | u32 phyerr; | ||
816 | |||
817 | if ((adsp->ds_rxstatus8 & AR_RxDone) == 0) | ||
818 | return -EINPROGRESS; | ||
819 | |||
820 | ads.u.rx = adsp->u.rx; | ||
821 | |||
822 | ds->ds_rxstat.rs_status = 0; | ||
823 | ds->ds_rxstat.rs_flags = 0; | ||
824 | |||
825 | ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen; | ||
826 | ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp; | ||
827 | |||
828 | ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined); | ||
829 | ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00); | ||
830 | ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01); | ||
831 | ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02); | ||
832 | ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10); | ||
833 | ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11); | ||
834 | ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12); | ||
835 | if (ads.ds_rxstatus8 & AR_RxKeyIdxValid) | ||
836 | ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx); | ||
837 | else | ||
838 | ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID; | ||
839 | |||
840 | ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads)); | ||
841 | ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0; | ||
842 | |||
843 | ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0; | ||
844 | ds->ds_rxstat.rs_moreaggr = | ||
845 | (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0; | ||
846 | ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna); | ||
847 | ds->ds_rxstat.rs_flags = | ||
848 | (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0; | ||
849 | ds->ds_rxstat.rs_flags |= | ||
850 | (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0; | ||
851 | |||
852 | if (ads.ds_rxstatus8 & AR_PreDelimCRCErr) | ||
853 | ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE; | ||
854 | if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) | ||
855 | ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST; | ||
856 | if (ads.ds_rxstatus8 & AR_DecryptBusyErr) | ||
857 | ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY; | ||
858 | |||
859 | if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) { | ||
860 | if (ads.ds_rxstatus8 & AR_CRCErr) | ||
861 | ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC; | ||
862 | else if (ads.ds_rxstatus8 & AR_PHYErr) { | ||
863 | ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY; | ||
864 | phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode); | ||
865 | ds->ds_rxstat.rs_phyerr = phyerr; | ||
866 | } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) | ||
867 | ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT; | ||
868 | else if (ads.ds_rxstatus8 & AR_MichaelErr) | ||
869 | ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC; | ||
870 | } | ||
871 | |||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, | ||
876 | u32 size, u32 flags) | ||
877 | { | ||
878 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
879 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
880 | |||
881 | ads->ds_ctl1 = size & AR_BufLen; | ||
882 | if (flags & ATH9K_RXDESC_INTREQ) | ||
883 | ads->ds_ctl1 |= AR_RxIntrReq; | ||
884 | |||
885 | ads->ds_rxstatus8 &= ~AR_RxDone; | ||
886 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) | ||
887 | memset(&(ads->u), 0, sizeof(ads->u)); | ||
888 | |||
889 | return true; | ||
890 | } | ||
891 | |||
892 | bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set) | ||
893 | { | ||
894 | u32 reg; | ||
895 | |||
896 | if (set) { | ||
897 | REG_SET_BIT(ah, AR_DIAG_SW, | ||
898 | (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); | ||
899 | |||
900 | if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, | ||
901 | 0, AH_WAIT_TIMEOUT)) { | ||
902 | REG_CLR_BIT(ah, AR_DIAG_SW, | ||
903 | (AR_DIAG_RX_DIS | | ||
904 | AR_DIAG_RX_ABORT)); | ||
905 | |||
906 | reg = REG_READ(ah, AR_OBS_BUS_1); | ||
907 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
908 | "RX failed to go idle in 10 ms RXSM=0x%x\n", reg); | ||
909 | |||
910 | return false; | ||
911 | } | ||
912 | } else { | ||
913 | REG_CLR_BIT(ah, AR_DIAG_SW, | ||
914 | (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); | ||
915 | } | ||
916 | |||
917 | return true; | ||
918 | } | ||
919 | |||
920 | void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp) | ||
921 | { | ||
922 | REG_WRITE(ah, AR_RXDP, rxdp); | ||
923 | } | ||
924 | |||
925 | void ath9k_hw_rxena(struct ath_hw *ah) | ||
926 | { | ||
927 | REG_WRITE(ah, AR_CR, AR_CR_RXE); | ||
928 | } | ||
929 | |||
930 | void ath9k_hw_startpcureceive(struct ath_hw *ah) | ||
931 | { | ||
932 | ath9k_enable_mib_counters(ah); | ||
933 | |||
934 | ath9k_ani_reset(ah); | ||
935 | |||
936 | REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); | ||
937 | } | ||
938 | |||
939 | void ath9k_hw_stoppcurecv(struct ath_hw *ah) | ||
940 | { | ||
941 | REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); | ||
942 | |||
943 | ath9k_hw_disable_mib_counters(ah); | ||
944 | } | ||
945 | |||
946 | bool ath9k_hw_stopdmarecv(struct ath_hw *ah) | ||
947 | { | ||
948 | #define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ | ||
949 | #define AH_RX_TIME_QUANTUM 100 /* usec */ | ||
950 | |||
951 | int i; | ||
952 | |||
953 | REG_WRITE(ah, AR_CR, AR_CR_RXD); | ||
954 | |||
955 | /* Wait for rx enable bit to go low */ | ||
956 | for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) { | ||
957 | if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0) | ||
958 | break; | ||
959 | udelay(AH_TIME_QUANTUM); | ||
960 | } | ||
961 | |||
962 | if (i == 0) { | ||
963 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
964 | "DMA failed to stop in %d ms " | ||
965 | "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n", | ||
966 | AH_RX_STOP_DMA_TIMEOUT / 1000, | ||
967 | REG_READ(ah, AR_CR), | ||
968 | REG_READ(ah, AR_DIAG_SW)); | ||
969 | return false; | ||
970 | } else { | ||
971 | return true; | ||
972 | } | ||
973 | |||
974 | #undef AH_RX_TIME_QUANTUM | ||
975 | #undef AH_RX_STOP_DMA_TIMEOUT | ||
976 | } | ||
diff --git a/drivers/net/wireless/ath9k/mac.h b/drivers/net/wireless/ath9k/mac.h deleted file mode 100644 index 1176bce8b76c..000000000000 --- a/drivers/net/wireless/ath9k/mac.h +++ /dev/null | |||
@@ -1,680 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 MAC_H | ||
18 | #define MAC_H | ||
19 | |||
20 | #define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_20_OR_LATER(ah) ? \ | ||
21 | MS(ads->ds_rxstatus0, AR_RxRate) : \ | ||
22 | (ads->ds_rxstatus3 >> 2) & 0xFF) | ||
23 | |||
24 | #define set11nTries(_series, _index) \ | ||
25 | (SM((_series)[_index].Tries, AR_XmitDataTries##_index)) | ||
26 | |||
27 | #define set11nRate(_series, _index) \ | ||
28 | (SM((_series)[_index].Rate, AR_XmitRate##_index)) | ||
29 | |||
30 | #define set11nPktDurRTSCTS(_series, _index) \ | ||
31 | (SM((_series)[_index].PktDuration, AR_PacketDur##_index) | \ | ||
32 | ((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS ? \ | ||
33 | AR_RTSCTSQual##_index : 0)) | ||
34 | |||
35 | #define set11nRateFlags(_series, _index) \ | ||
36 | (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \ | ||
37 | AR_2040_##_index : 0) \ | ||
38 | |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \ | ||
39 | AR_GI##_index : 0) \ | ||
40 | |SM((_series)[_index].ChSel, AR_ChainSel##_index)) | ||
41 | |||
42 | #define CCK_SIFS_TIME 10 | ||
43 | #define CCK_PREAMBLE_BITS 144 | ||
44 | #define CCK_PLCP_BITS 48 | ||
45 | |||
46 | #define OFDM_SIFS_TIME 16 | ||
47 | #define OFDM_PREAMBLE_TIME 20 | ||
48 | #define OFDM_PLCP_BITS 22 | ||
49 | #define OFDM_SYMBOL_TIME 4 | ||
50 | |||
51 | #define OFDM_SIFS_TIME_HALF 32 | ||
52 | #define OFDM_PREAMBLE_TIME_HALF 40 | ||
53 | #define OFDM_PLCP_BITS_HALF 22 | ||
54 | #define OFDM_SYMBOL_TIME_HALF 8 | ||
55 | |||
56 | #define OFDM_SIFS_TIME_QUARTER 64 | ||
57 | #define OFDM_PREAMBLE_TIME_QUARTER 80 | ||
58 | #define OFDM_PLCP_BITS_QUARTER 22 | ||
59 | #define OFDM_SYMBOL_TIME_QUARTER 16 | ||
60 | |||
61 | #define INIT_AIFS 2 | ||
62 | #define INIT_CWMIN 15 | ||
63 | #define INIT_CWMIN_11B 31 | ||
64 | #define INIT_CWMAX 1023 | ||
65 | #define INIT_SH_RETRY 10 | ||
66 | #define INIT_LG_RETRY 10 | ||
67 | #define INIT_SSH_RETRY 32 | ||
68 | #define INIT_SLG_RETRY 32 | ||
69 | |||
70 | #define ATH9K_SLOT_TIME_6 6 | ||
71 | #define ATH9K_SLOT_TIME_9 9 | ||
72 | #define ATH9K_SLOT_TIME_20 20 | ||
73 | |||
74 | #define ATH9K_TXERR_XRETRY 0x01 | ||
75 | #define ATH9K_TXERR_FILT 0x02 | ||
76 | #define ATH9K_TXERR_FIFO 0x04 | ||
77 | #define ATH9K_TXERR_XTXOP 0x08 | ||
78 | #define ATH9K_TXERR_TIMER_EXPIRED 0x10 | ||
79 | |||
80 | #define ATH9K_TX_BA 0x01 | ||
81 | #define ATH9K_TX_PWRMGMT 0x02 | ||
82 | #define ATH9K_TX_DESC_CFG_ERR 0x04 | ||
83 | #define ATH9K_TX_DATA_UNDERRUN 0x08 | ||
84 | #define ATH9K_TX_DELIM_UNDERRUN 0x10 | ||
85 | #define ATH9K_TX_SW_ABORTED 0x40 | ||
86 | #define ATH9K_TX_SW_FILTERED 0x80 | ||
87 | |||
88 | #define MIN_TX_FIFO_THRESHOLD 0x1 | ||
89 | #define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1) | ||
90 | #define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD | ||
91 | |||
92 | struct ath_tx_status { | ||
93 | u32 ts_tstamp; | ||
94 | u16 ts_seqnum; | ||
95 | u8 ts_status; | ||
96 | u8 ts_ratecode; | ||
97 | u8 ts_rateindex; | ||
98 | int8_t ts_rssi; | ||
99 | u8 ts_shortretry; | ||
100 | u8 ts_longretry; | ||
101 | u8 ts_virtcol; | ||
102 | u8 ts_antenna; | ||
103 | u8 ts_flags; | ||
104 | int8_t ts_rssi_ctl0; | ||
105 | int8_t ts_rssi_ctl1; | ||
106 | int8_t ts_rssi_ctl2; | ||
107 | int8_t ts_rssi_ext0; | ||
108 | int8_t ts_rssi_ext1; | ||
109 | int8_t ts_rssi_ext2; | ||
110 | u8 pad[3]; | ||
111 | u32 ba_low; | ||
112 | u32 ba_high; | ||
113 | u32 evm0; | ||
114 | u32 evm1; | ||
115 | u32 evm2; | ||
116 | }; | ||
117 | |||
118 | struct ath_rx_status { | ||
119 | u32 rs_tstamp; | ||
120 | u16 rs_datalen; | ||
121 | u8 rs_status; | ||
122 | u8 rs_phyerr; | ||
123 | int8_t rs_rssi; | ||
124 | u8 rs_keyix; | ||
125 | u8 rs_rate; | ||
126 | u8 rs_antenna; | ||
127 | u8 rs_more; | ||
128 | int8_t rs_rssi_ctl0; | ||
129 | int8_t rs_rssi_ctl1; | ||
130 | int8_t rs_rssi_ctl2; | ||
131 | int8_t rs_rssi_ext0; | ||
132 | int8_t rs_rssi_ext1; | ||
133 | int8_t rs_rssi_ext2; | ||
134 | u8 rs_isaggr; | ||
135 | u8 rs_moreaggr; | ||
136 | u8 rs_num_delims; | ||
137 | u8 rs_flags; | ||
138 | u32 evm0; | ||
139 | u32 evm1; | ||
140 | u32 evm2; | ||
141 | }; | ||
142 | |||
143 | #define ATH9K_RXERR_CRC 0x01 | ||
144 | #define ATH9K_RXERR_PHY 0x02 | ||
145 | #define ATH9K_RXERR_FIFO 0x04 | ||
146 | #define ATH9K_RXERR_DECRYPT 0x08 | ||
147 | #define ATH9K_RXERR_MIC 0x10 | ||
148 | |||
149 | #define ATH9K_RX_MORE 0x01 | ||
150 | #define ATH9K_RX_MORE_AGGR 0x02 | ||
151 | #define ATH9K_RX_GI 0x04 | ||
152 | #define ATH9K_RX_2040 0x08 | ||
153 | #define ATH9K_RX_DELIM_CRC_PRE 0x10 | ||
154 | #define ATH9K_RX_DELIM_CRC_POST 0x20 | ||
155 | #define ATH9K_RX_DECRYPT_BUSY 0x40 | ||
156 | |||
157 | #define ATH9K_RXKEYIX_INVALID ((u8)-1) | ||
158 | #define ATH9K_TXKEYIX_INVALID ((u32)-1) | ||
159 | |||
160 | struct ath_desc { | ||
161 | u32 ds_link; | ||
162 | u32 ds_data; | ||
163 | u32 ds_ctl0; | ||
164 | u32 ds_ctl1; | ||
165 | u32 ds_hw[20]; | ||
166 | union { | ||
167 | struct ath_tx_status tx; | ||
168 | struct ath_rx_status rx; | ||
169 | void *stats; | ||
170 | } ds_us; | ||
171 | void *ds_vdata; | ||
172 | } __packed; | ||
173 | |||
174 | #define ds_txstat ds_us.tx | ||
175 | #define ds_rxstat ds_us.rx | ||
176 | #define ds_stat ds_us.stats | ||
177 | |||
178 | #define ATH9K_TXDESC_CLRDMASK 0x0001 | ||
179 | #define ATH9K_TXDESC_NOACK 0x0002 | ||
180 | #define ATH9K_TXDESC_RTSENA 0x0004 | ||
181 | #define ATH9K_TXDESC_CTSENA 0x0008 | ||
182 | /* ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for | ||
183 | * the descriptor its marked on. We take a tx interrupt to reap | ||
184 | * descriptors when the h/w hits an EOL condition or | ||
185 | * when the descriptor is specifically marked to generate | ||
186 | * an interrupt with this flag. Descriptors should be | ||
187 | * marked periodically to insure timely replenishing of the | ||
188 | * supply needed for sending frames. Defering interrupts | ||
189 | * reduces system load and potentially allows more concurrent | ||
190 | * work to be done but if done to aggressively can cause | ||
191 | * senders to backup. When the hardware queue is left too | ||
192 | * large rate control information may also be too out of | ||
193 | * date. An Alternative for this is TX interrupt mitigation | ||
194 | * but this needs more testing. */ | ||
195 | #define ATH9K_TXDESC_INTREQ 0x0010 | ||
196 | #define ATH9K_TXDESC_VEOL 0x0020 | ||
197 | #define ATH9K_TXDESC_EXT_ONLY 0x0040 | ||
198 | #define ATH9K_TXDESC_EXT_AND_CTL 0x0080 | ||
199 | #define ATH9K_TXDESC_VMF 0x0100 | ||
200 | #define ATH9K_TXDESC_FRAG_IS_ON 0x0200 | ||
201 | #define ATH9K_TXDESC_CAB 0x0400 | ||
202 | |||
203 | #define ATH9K_RXDESC_INTREQ 0x0020 | ||
204 | |||
205 | struct ar5416_desc { | ||
206 | u32 ds_link; | ||
207 | u32 ds_data; | ||
208 | u32 ds_ctl0; | ||
209 | u32 ds_ctl1; | ||
210 | union { | ||
211 | struct { | ||
212 | u32 ctl2; | ||
213 | u32 ctl3; | ||
214 | u32 ctl4; | ||
215 | u32 ctl5; | ||
216 | u32 ctl6; | ||
217 | u32 ctl7; | ||
218 | u32 ctl8; | ||
219 | u32 ctl9; | ||
220 | u32 ctl10; | ||
221 | u32 ctl11; | ||
222 | u32 status0; | ||
223 | u32 status1; | ||
224 | u32 status2; | ||
225 | u32 status3; | ||
226 | u32 status4; | ||
227 | u32 status5; | ||
228 | u32 status6; | ||
229 | u32 status7; | ||
230 | u32 status8; | ||
231 | u32 status9; | ||
232 | } tx; | ||
233 | struct { | ||
234 | u32 status0; | ||
235 | u32 status1; | ||
236 | u32 status2; | ||
237 | u32 status3; | ||
238 | u32 status4; | ||
239 | u32 status5; | ||
240 | u32 status6; | ||
241 | u32 status7; | ||
242 | u32 status8; | ||
243 | } rx; | ||
244 | } u; | ||
245 | } __packed; | ||
246 | |||
247 | #define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds)) | ||
248 | #define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds)) | ||
249 | |||
250 | #define ds_ctl2 u.tx.ctl2 | ||
251 | #define ds_ctl3 u.tx.ctl3 | ||
252 | #define ds_ctl4 u.tx.ctl4 | ||
253 | #define ds_ctl5 u.tx.ctl5 | ||
254 | #define ds_ctl6 u.tx.ctl6 | ||
255 | #define ds_ctl7 u.tx.ctl7 | ||
256 | #define ds_ctl8 u.tx.ctl8 | ||
257 | #define ds_ctl9 u.tx.ctl9 | ||
258 | #define ds_ctl10 u.tx.ctl10 | ||
259 | #define ds_ctl11 u.tx.ctl11 | ||
260 | |||
261 | #define ds_txstatus0 u.tx.status0 | ||
262 | #define ds_txstatus1 u.tx.status1 | ||
263 | #define ds_txstatus2 u.tx.status2 | ||
264 | #define ds_txstatus3 u.tx.status3 | ||
265 | #define ds_txstatus4 u.tx.status4 | ||
266 | #define ds_txstatus5 u.tx.status5 | ||
267 | #define ds_txstatus6 u.tx.status6 | ||
268 | #define ds_txstatus7 u.tx.status7 | ||
269 | #define ds_txstatus8 u.tx.status8 | ||
270 | #define ds_txstatus9 u.tx.status9 | ||
271 | |||
272 | #define ds_rxstatus0 u.rx.status0 | ||
273 | #define ds_rxstatus1 u.rx.status1 | ||
274 | #define ds_rxstatus2 u.rx.status2 | ||
275 | #define ds_rxstatus3 u.rx.status3 | ||
276 | #define ds_rxstatus4 u.rx.status4 | ||
277 | #define ds_rxstatus5 u.rx.status5 | ||
278 | #define ds_rxstatus6 u.rx.status6 | ||
279 | #define ds_rxstatus7 u.rx.status7 | ||
280 | #define ds_rxstatus8 u.rx.status8 | ||
281 | |||
282 | #define AR_FrameLen 0x00000fff | ||
283 | #define AR_VirtMoreFrag 0x00001000 | ||
284 | #define AR_TxCtlRsvd00 0x0000e000 | ||
285 | #define AR_XmitPower 0x003f0000 | ||
286 | #define AR_XmitPower_S 16 | ||
287 | #define AR_RTSEnable 0x00400000 | ||
288 | #define AR_VEOL 0x00800000 | ||
289 | #define AR_ClrDestMask 0x01000000 | ||
290 | #define AR_TxCtlRsvd01 0x1e000000 | ||
291 | #define AR_TxIntrReq 0x20000000 | ||
292 | #define AR_DestIdxValid 0x40000000 | ||
293 | #define AR_CTSEnable 0x80000000 | ||
294 | |||
295 | #define AR_BufLen 0x00000fff | ||
296 | #define AR_TxMore 0x00001000 | ||
297 | #define AR_DestIdx 0x000fe000 | ||
298 | #define AR_DestIdx_S 13 | ||
299 | #define AR_FrameType 0x00f00000 | ||
300 | #define AR_FrameType_S 20 | ||
301 | #define AR_NoAck 0x01000000 | ||
302 | #define AR_InsertTS 0x02000000 | ||
303 | #define AR_CorruptFCS 0x04000000 | ||
304 | #define AR_ExtOnly 0x08000000 | ||
305 | #define AR_ExtAndCtl 0x10000000 | ||
306 | #define AR_MoreAggr 0x20000000 | ||
307 | #define AR_IsAggr 0x40000000 | ||
308 | |||
309 | #define AR_BurstDur 0x00007fff | ||
310 | #define AR_BurstDur_S 0 | ||
311 | #define AR_DurUpdateEna 0x00008000 | ||
312 | #define AR_XmitDataTries0 0x000f0000 | ||
313 | #define AR_XmitDataTries0_S 16 | ||
314 | #define AR_XmitDataTries1 0x00f00000 | ||
315 | #define AR_XmitDataTries1_S 20 | ||
316 | #define AR_XmitDataTries2 0x0f000000 | ||
317 | #define AR_XmitDataTries2_S 24 | ||
318 | #define AR_XmitDataTries3 0xf0000000 | ||
319 | #define AR_XmitDataTries3_S 28 | ||
320 | |||
321 | #define AR_XmitRate0 0x000000ff | ||
322 | #define AR_XmitRate0_S 0 | ||
323 | #define AR_XmitRate1 0x0000ff00 | ||
324 | #define AR_XmitRate1_S 8 | ||
325 | #define AR_XmitRate2 0x00ff0000 | ||
326 | #define AR_XmitRate2_S 16 | ||
327 | #define AR_XmitRate3 0xff000000 | ||
328 | #define AR_XmitRate3_S 24 | ||
329 | |||
330 | #define AR_PacketDur0 0x00007fff | ||
331 | #define AR_PacketDur0_S 0 | ||
332 | #define AR_RTSCTSQual0 0x00008000 | ||
333 | #define AR_PacketDur1 0x7fff0000 | ||
334 | #define AR_PacketDur1_S 16 | ||
335 | #define AR_RTSCTSQual1 0x80000000 | ||
336 | |||
337 | #define AR_PacketDur2 0x00007fff | ||
338 | #define AR_PacketDur2_S 0 | ||
339 | #define AR_RTSCTSQual2 0x00008000 | ||
340 | #define AR_PacketDur3 0x7fff0000 | ||
341 | #define AR_PacketDur3_S 16 | ||
342 | #define AR_RTSCTSQual3 0x80000000 | ||
343 | |||
344 | #define AR_AggrLen 0x0000ffff | ||
345 | #define AR_AggrLen_S 0 | ||
346 | #define AR_TxCtlRsvd60 0x00030000 | ||
347 | #define AR_PadDelim 0x03fc0000 | ||
348 | #define AR_PadDelim_S 18 | ||
349 | #define AR_EncrType 0x0c000000 | ||
350 | #define AR_EncrType_S 26 | ||
351 | #define AR_TxCtlRsvd61 0xf0000000 | ||
352 | |||
353 | #define AR_2040_0 0x00000001 | ||
354 | #define AR_GI0 0x00000002 | ||
355 | #define AR_ChainSel0 0x0000001c | ||
356 | #define AR_ChainSel0_S 2 | ||
357 | #define AR_2040_1 0x00000020 | ||
358 | #define AR_GI1 0x00000040 | ||
359 | #define AR_ChainSel1 0x00000380 | ||
360 | #define AR_ChainSel1_S 7 | ||
361 | #define AR_2040_2 0x00000400 | ||
362 | #define AR_GI2 0x00000800 | ||
363 | #define AR_ChainSel2 0x00007000 | ||
364 | #define AR_ChainSel2_S 12 | ||
365 | #define AR_2040_3 0x00008000 | ||
366 | #define AR_GI3 0x00010000 | ||
367 | #define AR_ChainSel3 0x000e0000 | ||
368 | #define AR_ChainSel3_S 17 | ||
369 | #define AR_RTSCTSRate 0x0ff00000 | ||
370 | #define AR_RTSCTSRate_S 20 | ||
371 | #define AR_TxCtlRsvd70 0xf0000000 | ||
372 | |||
373 | #define AR_TxRSSIAnt00 0x000000ff | ||
374 | #define AR_TxRSSIAnt00_S 0 | ||
375 | #define AR_TxRSSIAnt01 0x0000ff00 | ||
376 | #define AR_TxRSSIAnt01_S 8 | ||
377 | #define AR_TxRSSIAnt02 0x00ff0000 | ||
378 | #define AR_TxRSSIAnt02_S 16 | ||
379 | #define AR_TxStatusRsvd00 0x3f000000 | ||
380 | #define AR_TxBaStatus 0x40000000 | ||
381 | #define AR_TxStatusRsvd01 0x80000000 | ||
382 | |||
383 | #define AR_FrmXmitOK 0x00000001 | ||
384 | #define AR_ExcessiveRetries 0x00000002 | ||
385 | #define AR_FIFOUnderrun 0x00000004 | ||
386 | #define AR_Filtered 0x00000008 | ||
387 | #define AR_RTSFailCnt 0x000000f0 | ||
388 | #define AR_RTSFailCnt_S 4 | ||
389 | #define AR_DataFailCnt 0x00000f00 | ||
390 | #define AR_DataFailCnt_S 8 | ||
391 | #define AR_VirtRetryCnt 0x0000f000 | ||
392 | #define AR_VirtRetryCnt_S 12 | ||
393 | #define AR_TxDelimUnderrun 0x00010000 | ||
394 | #define AR_TxDataUnderrun 0x00020000 | ||
395 | #define AR_DescCfgErr 0x00040000 | ||
396 | #define AR_TxTimerExpired 0x00080000 | ||
397 | #define AR_TxStatusRsvd10 0xfff00000 | ||
398 | |||
399 | #define AR_SendTimestamp ds_txstatus2 | ||
400 | #define AR_BaBitmapLow ds_txstatus3 | ||
401 | #define AR_BaBitmapHigh ds_txstatus4 | ||
402 | |||
403 | #define AR_TxRSSIAnt10 0x000000ff | ||
404 | #define AR_TxRSSIAnt10_S 0 | ||
405 | #define AR_TxRSSIAnt11 0x0000ff00 | ||
406 | #define AR_TxRSSIAnt11_S 8 | ||
407 | #define AR_TxRSSIAnt12 0x00ff0000 | ||
408 | #define AR_TxRSSIAnt12_S 16 | ||
409 | #define AR_TxRSSICombined 0xff000000 | ||
410 | #define AR_TxRSSICombined_S 24 | ||
411 | |||
412 | #define AR_TxEVM0 ds_txstatus5 | ||
413 | #define AR_TxEVM1 ds_txstatus6 | ||
414 | #define AR_TxEVM2 ds_txstatus7 | ||
415 | |||
416 | #define AR_TxDone 0x00000001 | ||
417 | #define AR_SeqNum 0x00001ffe | ||
418 | #define AR_SeqNum_S 1 | ||
419 | #define AR_TxStatusRsvd80 0x0001e000 | ||
420 | #define AR_TxOpExceeded 0x00020000 | ||
421 | #define AR_TxStatusRsvd81 0x001c0000 | ||
422 | #define AR_FinalTxIdx 0x00600000 | ||
423 | #define AR_FinalTxIdx_S 21 | ||
424 | #define AR_TxStatusRsvd82 0x01800000 | ||
425 | #define AR_PowerMgmt 0x02000000 | ||
426 | #define AR_TxStatusRsvd83 0xfc000000 | ||
427 | |||
428 | #define AR_RxCTLRsvd00 0xffffffff | ||
429 | |||
430 | #define AR_BufLen 0x00000fff | ||
431 | #define AR_RxCtlRsvd00 0x00001000 | ||
432 | #define AR_RxIntrReq 0x00002000 | ||
433 | #define AR_RxCtlRsvd01 0xffffc000 | ||
434 | |||
435 | #define AR_RxRSSIAnt00 0x000000ff | ||
436 | #define AR_RxRSSIAnt00_S 0 | ||
437 | #define AR_RxRSSIAnt01 0x0000ff00 | ||
438 | #define AR_RxRSSIAnt01_S 8 | ||
439 | #define AR_RxRSSIAnt02 0x00ff0000 | ||
440 | #define AR_RxRSSIAnt02_S 16 | ||
441 | #define AR_RxRate 0xff000000 | ||
442 | #define AR_RxRate_S 24 | ||
443 | #define AR_RxStatusRsvd00 0xff000000 | ||
444 | |||
445 | #define AR_DataLen 0x00000fff | ||
446 | #define AR_RxMore 0x00001000 | ||
447 | #define AR_NumDelim 0x003fc000 | ||
448 | #define AR_NumDelim_S 14 | ||
449 | #define AR_RxStatusRsvd10 0xff800000 | ||
450 | |||
451 | #define AR_RcvTimestamp ds_rxstatus2 | ||
452 | |||
453 | #define AR_GI 0x00000001 | ||
454 | #define AR_2040 0x00000002 | ||
455 | #define AR_Parallel40 0x00000004 | ||
456 | #define AR_Parallel40_S 2 | ||
457 | #define AR_RxStatusRsvd30 0x000000f8 | ||
458 | #define AR_RxAntenna 0xffffff00 | ||
459 | #define AR_RxAntenna_S 8 | ||
460 | |||
461 | #define AR_RxRSSIAnt10 0x000000ff | ||
462 | #define AR_RxRSSIAnt10_S 0 | ||
463 | #define AR_RxRSSIAnt11 0x0000ff00 | ||
464 | #define AR_RxRSSIAnt11_S 8 | ||
465 | #define AR_RxRSSIAnt12 0x00ff0000 | ||
466 | #define AR_RxRSSIAnt12_S 16 | ||
467 | #define AR_RxRSSICombined 0xff000000 | ||
468 | #define AR_RxRSSICombined_S 24 | ||
469 | |||
470 | #define AR_RxEVM0 ds_rxstatus4 | ||
471 | #define AR_RxEVM1 ds_rxstatus5 | ||
472 | #define AR_RxEVM2 ds_rxstatus6 | ||
473 | |||
474 | #define AR_RxDone 0x00000001 | ||
475 | #define AR_RxFrameOK 0x00000002 | ||
476 | #define AR_CRCErr 0x00000004 | ||
477 | #define AR_DecryptCRCErr 0x00000008 | ||
478 | #define AR_PHYErr 0x00000010 | ||
479 | #define AR_MichaelErr 0x00000020 | ||
480 | #define AR_PreDelimCRCErr 0x00000040 | ||
481 | #define AR_RxStatusRsvd70 0x00000080 | ||
482 | #define AR_RxKeyIdxValid 0x00000100 | ||
483 | #define AR_KeyIdx 0x0000fe00 | ||
484 | #define AR_KeyIdx_S 9 | ||
485 | #define AR_PHYErrCode 0x0000ff00 | ||
486 | #define AR_PHYErrCode_S 8 | ||
487 | #define AR_RxMoreAggr 0x00010000 | ||
488 | #define AR_RxAggr 0x00020000 | ||
489 | #define AR_PostDelimCRCErr 0x00040000 | ||
490 | #define AR_RxStatusRsvd71 0x3ff80000 | ||
491 | #define AR_DecryptBusyErr 0x40000000 | ||
492 | #define AR_KeyMiss 0x80000000 | ||
493 | |||
494 | enum ath9k_tx_queue { | ||
495 | ATH9K_TX_QUEUE_INACTIVE = 0, | ||
496 | ATH9K_TX_QUEUE_DATA, | ||
497 | ATH9K_TX_QUEUE_BEACON, | ||
498 | ATH9K_TX_QUEUE_CAB, | ||
499 | ATH9K_TX_QUEUE_UAPSD, | ||
500 | ATH9K_TX_QUEUE_PSPOLL | ||
501 | }; | ||
502 | |||
503 | #define ATH9K_NUM_TX_QUEUES 10 | ||
504 | |||
505 | enum ath9k_tx_queue_subtype { | ||
506 | ATH9K_WME_AC_BK = 0, | ||
507 | ATH9K_WME_AC_BE, | ||
508 | ATH9K_WME_AC_VI, | ||
509 | ATH9K_WME_AC_VO, | ||
510 | ATH9K_WME_UPSD | ||
511 | }; | ||
512 | |||
513 | enum ath9k_tx_queue_flags { | ||
514 | TXQ_FLAG_TXOKINT_ENABLE = 0x0001, | ||
515 | TXQ_FLAG_TXERRINT_ENABLE = 0x0001, | ||
516 | TXQ_FLAG_TXDESCINT_ENABLE = 0x0002, | ||
517 | TXQ_FLAG_TXEOLINT_ENABLE = 0x0004, | ||
518 | TXQ_FLAG_TXURNINT_ENABLE = 0x0008, | ||
519 | TXQ_FLAG_BACKOFF_DISABLE = 0x0010, | ||
520 | TXQ_FLAG_COMPRESSION_ENABLE = 0x0020, | ||
521 | TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040, | ||
522 | TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080, | ||
523 | }; | ||
524 | |||
525 | #define ATH9K_TXQ_USEDEFAULT ((u32) -1) | ||
526 | #define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001 | ||
527 | |||
528 | #define ATH9K_DECOMP_MASK_SIZE 128 | ||
529 | #define ATH9K_READY_TIME_LO_BOUND 50 | ||
530 | #define ATH9K_READY_TIME_HI_BOUND 96 | ||
531 | |||
532 | enum ath9k_pkt_type { | ||
533 | ATH9K_PKT_TYPE_NORMAL = 0, | ||
534 | ATH9K_PKT_TYPE_ATIM, | ||
535 | ATH9K_PKT_TYPE_PSPOLL, | ||
536 | ATH9K_PKT_TYPE_BEACON, | ||
537 | ATH9K_PKT_TYPE_PROBE_RESP, | ||
538 | ATH9K_PKT_TYPE_CHIRP, | ||
539 | ATH9K_PKT_TYPE_GRP_POLL, | ||
540 | }; | ||
541 | |||
542 | struct ath9k_tx_queue_info { | ||
543 | u32 tqi_ver; | ||
544 | enum ath9k_tx_queue tqi_type; | ||
545 | enum ath9k_tx_queue_subtype tqi_subtype; | ||
546 | enum ath9k_tx_queue_flags tqi_qflags; | ||
547 | u32 tqi_priority; | ||
548 | u32 tqi_aifs; | ||
549 | u32 tqi_cwmin; | ||
550 | u32 tqi_cwmax; | ||
551 | u16 tqi_shretry; | ||
552 | u16 tqi_lgretry; | ||
553 | u32 tqi_cbrPeriod; | ||
554 | u32 tqi_cbrOverflowLimit; | ||
555 | u32 tqi_burstTime; | ||
556 | u32 tqi_readyTime; | ||
557 | u32 tqi_physCompBuf; | ||
558 | u32 tqi_intFlags; | ||
559 | }; | ||
560 | |||
561 | enum ath9k_rx_filter { | ||
562 | ATH9K_RX_FILTER_UCAST = 0x00000001, | ||
563 | ATH9K_RX_FILTER_MCAST = 0x00000002, | ||
564 | ATH9K_RX_FILTER_BCAST = 0x00000004, | ||
565 | ATH9K_RX_FILTER_CONTROL = 0x00000008, | ||
566 | ATH9K_RX_FILTER_BEACON = 0x00000010, | ||
567 | ATH9K_RX_FILTER_PROM = 0x00000020, | ||
568 | ATH9K_RX_FILTER_PROBEREQ = 0x00000080, | ||
569 | ATH9K_RX_FILTER_PHYERR = 0x00000100, | ||
570 | ATH9K_RX_FILTER_MYBEACON = 0x00000200, | ||
571 | ATH9K_RX_FILTER_PSPOLL = 0x00004000, | ||
572 | ATH9K_RX_FILTER_PHYRADAR = 0x00002000, | ||
573 | ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000, | ||
574 | }; | ||
575 | |||
576 | #define ATH9K_RATESERIES_RTS_CTS 0x0001 | ||
577 | #define ATH9K_RATESERIES_2040 0x0002 | ||
578 | #define ATH9K_RATESERIES_HALFGI 0x0004 | ||
579 | |||
580 | struct ath9k_11n_rate_series { | ||
581 | u32 Tries; | ||
582 | u32 Rate; | ||
583 | u32 PktDuration; | ||
584 | u32 ChSel; | ||
585 | u32 RateFlags; | ||
586 | }; | ||
587 | |||
588 | struct ath9k_keyval { | ||
589 | u8 kv_type; | ||
590 | u8 kv_pad; | ||
591 | u16 kv_len; | ||
592 | u8 kv_val[16]; /* TK */ | ||
593 | u8 kv_mic[8]; /* Michael MIC key */ | ||
594 | u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware | ||
595 | * supports both MIC keys in the same key cache entry; | ||
596 | * in that case, kv_mic is the RX key) */ | ||
597 | }; | ||
598 | |||
599 | enum ath9k_key_type { | ||
600 | ATH9K_KEY_TYPE_CLEAR, | ||
601 | ATH9K_KEY_TYPE_WEP, | ||
602 | ATH9K_KEY_TYPE_AES, | ||
603 | ATH9K_KEY_TYPE_TKIP, | ||
604 | }; | ||
605 | |||
606 | enum ath9k_cipher { | ||
607 | ATH9K_CIPHER_WEP = 0, | ||
608 | ATH9K_CIPHER_AES_OCB = 1, | ||
609 | ATH9K_CIPHER_AES_CCM = 2, | ||
610 | ATH9K_CIPHER_CKIP = 3, | ||
611 | ATH9K_CIPHER_TKIP = 4, | ||
612 | ATH9K_CIPHER_CLR = 5, | ||
613 | ATH9K_CIPHER_MIC = 127 | ||
614 | }; | ||
615 | |||
616 | enum ath9k_ht_macmode { | ||
617 | ATH9K_HT_MACMODE_20 = 0, | ||
618 | ATH9K_HT_MACMODE_2040 = 1, | ||
619 | }; | ||
620 | |||
621 | enum ath9k_ht_extprotspacing { | ||
622 | ATH9K_HT_EXTPROTSPACING_20 = 0, | ||
623 | ATH9K_HT_EXTPROTSPACING_25 = 1, | ||
624 | }; | ||
625 | |||
626 | struct ath_hw; | ||
627 | struct ath9k_channel; | ||
628 | struct ath_rate_table; | ||
629 | |||
630 | u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q); | ||
631 | bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp); | ||
632 | bool ath9k_hw_txstart(struct ath_hw *ah, u32 q); | ||
633 | u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q); | ||
634 | bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); | ||
635 | bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q); | ||
636 | bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds, | ||
637 | u32 segLen, bool firstSeg, | ||
638 | bool lastSeg, const struct ath_desc *ds0); | ||
639 | void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds); | ||
640 | int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds); | ||
641 | void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds, | ||
642 | u32 pktLen, enum ath9k_pkt_type type, u32 txPower, | ||
643 | u32 keyIx, enum ath9k_key_type keyType, u32 flags); | ||
644 | void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds, | ||
645 | struct ath_desc *lastds, | ||
646 | u32 durUpdateEn, u32 rtsctsRate, | ||
647 | u32 rtsctsDuration, | ||
648 | struct ath9k_11n_rate_series series[], | ||
649 | u32 nseries, u32 flags); | ||
650 | void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds, | ||
651 | u32 aggrLen); | ||
652 | void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds, | ||
653 | u32 numDelims); | ||
654 | void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds); | ||
655 | void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds); | ||
656 | void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds, | ||
657 | u32 burstDuration); | ||
658 | void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds, | ||
659 | u32 vmf); | ||
660 | void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs); | ||
661 | bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, | ||
662 | const struct ath9k_tx_queue_info *qinfo); | ||
663 | bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q, | ||
664 | struct ath9k_tx_queue_info *qinfo); | ||
665 | int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, | ||
666 | const struct ath9k_tx_queue_info *qinfo); | ||
667 | bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q); | ||
668 | bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q); | ||
669 | int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, | ||
670 | u32 pa, struct ath_desc *nds, u64 tsf); | ||
671 | bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, | ||
672 | u32 size, u32 flags); | ||
673 | bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set); | ||
674 | void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp); | ||
675 | void ath9k_hw_rxena(struct ath_hw *ah); | ||
676 | void ath9k_hw_startpcureceive(struct ath_hw *ah); | ||
677 | void ath9k_hw_stoppcurecv(struct ath_hw *ah); | ||
678 | bool ath9k_hw_stopdmarecv(struct ath_hw *ah); | ||
679 | |||
680 | #endif /* MAC_H */ | ||
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c deleted file mode 100644 index 8b6a7ea4e59b..000000000000 --- a/drivers/net/wireless/ath9k/main.c +++ /dev/null | |||
@@ -1,2890 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 <linux/nl80211.h> | ||
18 | #include "ath9k.h" | ||
19 | |||
20 | #define ATH_PCI_VERSION "0.1" | ||
21 | |||
22 | static char *dev_info = "ath9k"; | ||
23 | |||
24 | MODULE_AUTHOR("Atheros Communications"); | ||
25 | MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); | ||
26 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); | ||
27 | MODULE_LICENSE("Dual BSD/GPL"); | ||
28 | |||
29 | static int modparam_nohwcrypt; | ||
30 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); | ||
31 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); | ||
32 | |||
33 | /* We use the hw_value as an index into our private channel structure */ | ||
34 | |||
35 | #define CHAN2G(_freq, _idx) { \ | ||
36 | .center_freq = (_freq), \ | ||
37 | .hw_value = (_idx), \ | ||
38 | .max_power = 30, \ | ||
39 | } | ||
40 | |||
41 | #define CHAN5G(_freq, _idx) { \ | ||
42 | .band = IEEE80211_BAND_5GHZ, \ | ||
43 | .center_freq = (_freq), \ | ||
44 | .hw_value = (_idx), \ | ||
45 | .max_power = 30, \ | ||
46 | } | ||
47 | |||
48 | /* Some 2 GHz radios are actually tunable on 2312-2732 | ||
49 | * on 5 MHz steps, we support the channels which we know | ||
50 | * we have calibration data for all cards though to make | ||
51 | * this static */ | ||
52 | static struct ieee80211_channel ath9k_2ghz_chantable[] = { | ||
53 | CHAN2G(2412, 0), /* Channel 1 */ | ||
54 | CHAN2G(2417, 1), /* Channel 2 */ | ||
55 | CHAN2G(2422, 2), /* Channel 3 */ | ||
56 | CHAN2G(2427, 3), /* Channel 4 */ | ||
57 | CHAN2G(2432, 4), /* Channel 5 */ | ||
58 | CHAN2G(2437, 5), /* Channel 6 */ | ||
59 | CHAN2G(2442, 6), /* Channel 7 */ | ||
60 | CHAN2G(2447, 7), /* Channel 8 */ | ||
61 | CHAN2G(2452, 8), /* Channel 9 */ | ||
62 | CHAN2G(2457, 9), /* Channel 10 */ | ||
63 | CHAN2G(2462, 10), /* Channel 11 */ | ||
64 | CHAN2G(2467, 11), /* Channel 12 */ | ||
65 | CHAN2G(2472, 12), /* Channel 13 */ | ||
66 | CHAN2G(2484, 13), /* Channel 14 */ | ||
67 | }; | ||
68 | |||
69 | /* Some 5 GHz radios are actually tunable on XXXX-YYYY | ||
70 | * on 5 MHz steps, we support the channels which we know | ||
71 | * we have calibration data for all cards though to make | ||
72 | * this static */ | ||
73 | static struct ieee80211_channel ath9k_5ghz_chantable[] = { | ||
74 | /* _We_ call this UNII 1 */ | ||
75 | CHAN5G(5180, 14), /* Channel 36 */ | ||
76 | CHAN5G(5200, 15), /* Channel 40 */ | ||
77 | CHAN5G(5220, 16), /* Channel 44 */ | ||
78 | CHAN5G(5240, 17), /* Channel 48 */ | ||
79 | /* _We_ call this UNII 2 */ | ||
80 | CHAN5G(5260, 18), /* Channel 52 */ | ||
81 | CHAN5G(5280, 19), /* Channel 56 */ | ||
82 | CHAN5G(5300, 20), /* Channel 60 */ | ||
83 | CHAN5G(5320, 21), /* Channel 64 */ | ||
84 | /* _We_ call this "Middle band" */ | ||
85 | CHAN5G(5500, 22), /* Channel 100 */ | ||
86 | CHAN5G(5520, 23), /* Channel 104 */ | ||
87 | CHAN5G(5540, 24), /* Channel 108 */ | ||
88 | CHAN5G(5560, 25), /* Channel 112 */ | ||
89 | CHAN5G(5580, 26), /* Channel 116 */ | ||
90 | CHAN5G(5600, 27), /* Channel 120 */ | ||
91 | CHAN5G(5620, 28), /* Channel 124 */ | ||
92 | CHAN5G(5640, 29), /* Channel 128 */ | ||
93 | CHAN5G(5660, 30), /* Channel 132 */ | ||
94 | CHAN5G(5680, 31), /* Channel 136 */ | ||
95 | CHAN5G(5700, 32), /* Channel 140 */ | ||
96 | /* _We_ call this UNII 3 */ | ||
97 | CHAN5G(5745, 33), /* Channel 149 */ | ||
98 | CHAN5G(5765, 34), /* Channel 153 */ | ||
99 | CHAN5G(5785, 35), /* Channel 157 */ | ||
100 | CHAN5G(5805, 36), /* Channel 161 */ | ||
101 | CHAN5G(5825, 37), /* Channel 165 */ | ||
102 | }; | ||
103 | |||
104 | static void ath_cache_conf_rate(struct ath_softc *sc, | ||
105 | struct ieee80211_conf *conf) | ||
106 | { | ||
107 | switch (conf->channel->band) { | ||
108 | case IEEE80211_BAND_2GHZ: | ||
109 | if (conf_is_ht20(conf)) | ||
110 | sc->cur_rate_table = | ||
111 | sc->hw_rate_table[ATH9K_MODE_11NG_HT20]; | ||
112 | else if (conf_is_ht40_minus(conf)) | ||
113 | sc->cur_rate_table = | ||
114 | sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS]; | ||
115 | else if (conf_is_ht40_plus(conf)) | ||
116 | sc->cur_rate_table = | ||
117 | sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS]; | ||
118 | else | ||
119 | sc->cur_rate_table = | ||
120 | sc->hw_rate_table[ATH9K_MODE_11G]; | ||
121 | break; | ||
122 | case IEEE80211_BAND_5GHZ: | ||
123 | if (conf_is_ht20(conf)) | ||
124 | sc->cur_rate_table = | ||
125 | sc->hw_rate_table[ATH9K_MODE_11NA_HT20]; | ||
126 | else if (conf_is_ht40_minus(conf)) | ||
127 | sc->cur_rate_table = | ||
128 | sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS]; | ||
129 | else if (conf_is_ht40_plus(conf)) | ||
130 | sc->cur_rate_table = | ||
131 | sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS]; | ||
132 | else | ||
133 | sc->cur_rate_table = | ||
134 | sc->hw_rate_table[ATH9K_MODE_11A]; | ||
135 | break; | ||
136 | default: | ||
137 | BUG_ON(1); | ||
138 | break; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | static void ath_update_txpow(struct ath_softc *sc) | ||
143 | { | ||
144 | struct ath_hw *ah = sc->sc_ah; | ||
145 | u32 txpow; | ||
146 | |||
147 | if (sc->curtxpow != sc->config.txpowlimit) { | ||
148 | ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit); | ||
149 | /* read back in case value is clamped */ | ||
150 | ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow); | ||
151 | sc->curtxpow = txpow; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | static u8 parse_mpdudensity(u8 mpdudensity) | ||
156 | { | ||
157 | /* | ||
158 | * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing": | ||
159 | * 0 for no restriction | ||
160 | * 1 for 1/4 us | ||
161 | * 2 for 1/2 us | ||
162 | * 3 for 1 us | ||
163 | * 4 for 2 us | ||
164 | * 5 for 4 us | ||
165 | * 6 for 8 us | ||
166 | * 7 for 16 us | ||
167 | */ | ||
168 | switch (mpdudensity) { | ||
169 | case 0: | ||
170 | return 0; | ||
171 | case 1: | ||
172 | case 2: | ||
173 | case 3: | ||
174 | /* Our lower layer calculations limit our precision to | ||
175 | 1 microsecond */ | ||
176 | return 1; | ||
177 | case 4: | ||
178 | return 2; | ||
179 | case 5: | ||
180 | return 4; | ||
181 | case 6: | ||
182 | return 8; | ||
183 | case 7: | ||
184 | return 16; | ||
185 | default: | ||
186 | return 0; | ||
187 | } | ||
188 | } | ||
189 | |||
190 | static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) | ||
191 | { | ||
192 | struct ath_rate_table *rate_table = NULL; | ||
193 | struct ieee80211_supported_band *sband; | ||
194 | struct ieee80211_rate *rate; | ||
195 | int i, maxrates; | ||
196 | |||
197 | switch (band) { | ||
198 | case IEEE80211_BAND_2GHZ: | ||
199 | rate_table = sc->hw_rate_table[ATH9K_MODE_11G]; | ||
200 | break; | ||
201 | case IEEE80211_BAND_5GHZ: | ||
202 | rate_table = sc->hw_rate_table[ATH9K_MODE_11A]; | ||
203 | break; | ||
204 | default: | ||
205 | break; | ||
206 | } | ||
207 | |||
208 | if (rate_table == NULL) | ||
209 | return; | ||
210 | |||
211 | sband = &sc->sbands[band]; | ||
212 | rate = sc->rates[band]; | ||
213 | |||
214 | if (rate_table->rate_cnt > ATH_RATE_MAX) | ||
215 | maxrates = ATH_RATE_MAX; | ||
216 | else | ||
217 | maxrates = rate_table->rate_cnt; | ||
218 | |||
219 | for (i = 0; i < maxrates; i++) { | ||
220 | rate[i].bitrate = rate_table->info[i].ratekbps / 100; | ||
221 | rate[i].hw_value = rate_table->info[i].ratecode; | ||
222 | if (rate_table->info[i].short_preamble) { | ||
223 | rate[i].hw_value_short = rate_table->info[i].ratecode | | ||
224 | rate_table->info[i].short_preamble; | ||
225 | rate[i].flags = IEEE80211_RATE_SHORT_PREAMBLE; | ||
226 | } | ||
227 | sband->n_bitrates++; | ||
228 | |||
229 | DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n", | ||
230 | rate[i].bitrate / 10, rate[i].hw_value); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | /* | ||
235 | * Set/change channels. If the channel is really being changed, it's done | ||
236 | * by reseting the chip. To accomplish this we must first cleanup any pending | ||
237 | * DMA, then restart stuff. | ||
238 | */ | ||
239 | int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | ||
240 | struct ath9k_channel *hchan) | ||
241 | { | ||
242 | struct ath_hw *ah = sc->sc_ah; | ||
243 | bool fastcc = true, stopped; | ||
244 | struct ieee80211_channel *channel = hw->conf.channel; | ||
245 | int r; | ||
246 | |||
247 | if (sc->sc_flags & SC_OP_INVALID) | ||
248 | return -EIO; | ||
249 | |||
250 | ath9k_ps_wakeup(sc); | ||
251 | |||
252 | /* | ||
253 | * This is only performed if the channel settings have | ||
254 | * actually changed. | ||
255 | * | ||
256 | * To switch channels clear any pending DMA operations; | ||
257 | * wait long enough for the RX fifo to drain, reset the | ||
258 | * hardware at the new frequency, and then re-enable | ||
259 | * the relevant bits of the h/w. | ||
260 | */ | ||
261 | ath9k_hw_set_interrupts(ah, 0); | ||
262 | ath_drain_all_txq(sc, false); | ||
263 | stopped = ath_stoprecv(sc); | ||
264 | |||
265 | /* XXX: do not flush receive queue here. We don't want | ||
266 | * to flush data frames already in queue because of | ||
267 | * changing channel. */ | ||
268 | |||
269 | if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET)) | ||
270 | fastcc = false; | ||
271 | |||
272 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
273 | "(%u MHz) -> (%u MHz), chanwidth: %d\n", | ||
274 | sc->sc_ah->curchan->channel, | ||
275 | channel->center_freq, sc->tx_chan_width); | ||
276 | |||
277 | spin_lock_bh(&sc->sc_resetlock); | ||
278 | |||
279 | r = ath9k_hw_reset(ah, hchan, fastcc); | ||
280 | if (r) { | ||
281 | DPRINTF(sc, ATH_DBG_FATAL, | ||
282 | "Unable to reset channel (%u Mhz) " | ||
283 | "reset status %u\n", | ||
284 | channel->center_freq, r); | ||
285 | spin_unlock_bh(&sc->sc_resetlock); | ||
286 | return r; | ||
287 | } | ||
288 | spin_unlock_bh(&sc->sc_resetlock); | ||
289 | |||
290 | sc->sc_flags &= ~SC_OP_FULL_RESET; | ||
291 | |||
292 | if (ath_startrecv(sc) != 0) { | ||
293 | DPRINTF(sc, ATH_DBG_FATAL, | ||
294 | "Unable to restart recv logic\n"); | ||
295 | return -EIO; | ||
296 | } | ||
297 | |||
298 | ath_cache_conf_rate(sc, &hw->conf); | ||
299 | ath_update_txpow(sc); | ||
300 | ath9k_hw_set_interrupts(ah, sc->imask); | ||
301 | ath9k_ps_restore(sc); | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | /* | ||
306 | * This routine performs the periodic noise floor calibration function | ||
307 | * that is used to adjust and optimize the chip performance. This | ||
308 | * takes environmental changes (location, temperature) into account. | ||
309 | * When the task is complete, it reschedules itself depending on the | ||
310 | * appropriate interval that was calculated. | ||
311 | */ | ||
312 | static void ath_ani_calibrate(unsigned long data) | ||
313 | { | ||
314 | struct ath_softc *sc = (struct ath_softc *)data; | ||
315 | struct ath_hw *ah = sc->sc_ah; | ||
316 | bool longcal = false; | ||
317 | bool shortcal = false; | ||
318 | bool aniflag = false; | ||
319 | unsigned int timestamp = jiffies_to_msecs(jiffies); | ||
320 | u32 cal_interval, short_cal_interval; | ||
321 | |||
322 | short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? | ||
323 | ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; | ||
324 | |||
325 | /* | ||
326 | * don't calibrate when we're scanning. | ||
327 | * we are most likely not on our home channel. | ||
328 | */ | ||
329 | if (sc->sc_flags & SC_OP_SCANNING) | ||
330 | goto set_timer; | ||
331 | |||
332 | /* Long calibration runs independently of short calibration. */ | ||
333 | if ((timestamp - sc->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { | ||
334 | longcal = true; | ||
335 | DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies); | ||
336 | sc->ani.longcal_timer = timestamp; | ||
337 | } | ||
338 | |||
339 | /* Short calibration applies only while caldone is false */ | ||
340 | if (!sc->ani.caldone) { | ||
341 | if ((timestamp - sc->ani.shortcal_timer) >= short_cal_interval) { | ||
342 | shortcal = true; | ||
343 | DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies); | ||
344 | sc->ani.shortcal_timer = timestamp; | ||
345 | sc->ani.resetcal_timer = timestamp; | ||
346 | } | ||
347 | } else { | ||
348 | if ((timestamp - sc->ani.resetcal_timer) >= | ||
349 | ATH_RESTART_CALINTERVAL) { | ||
350 | sc->ani.caldone = ath9k_hw_reset_calvalid(ah); | ||
351 | if (sc->ani.caldone) | ||
352 | sc->ani.resetcal_timer = timestamp; | ||
353 | } | ||
354 | } | ||
355 | |||
356 | /* Verify whether we must check ANI */ | ||
357 | if ((timestamp - sc->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { | ||
358 | aniflag = true; | ||
359 | sc->ani.checkani_timer = timestamp; | ||
360 | } | ||
361 | |||
362 | /* Skip all processing if there's nothing to do. */ | ||
363 | if (longcal || shortcal || aniflag) { | ||
364 | /* Call ANI routine if necessary */ | ||
365 | if (aniflag) | ||
366 | ath9k_hw_ani_monitor(ah, &sc->nodestats, ah->curchan); | ||
367 | |||
368 | /* Perform calibration if necessary */ | ||
369 | if (longcal || shortcal) { | ||
370 | bool iscaldone = false; | ||
371 | |||
372 | if (ath9k_hw_calibrate(ah, ah->curchan, | ||
373 | sc->rx_chainmask, longcal, | ||
374 | &iscaldone)) { | ||
375 | if (longcal) | ||
376 | sc->ani.noise_floor = | ||
377 | ath9k_hw_getchan_noise(ah, | ||
378 | ah->curchan); | ||
379 | |||
380 | DPRINTF(sc, ATH_DBG_ANI, | ||
381 | "calibrate chan %u/%x nf: %d\n", | ||
382 | ah->curchan->channel, | ||
383 | ah->curchan->channelFlags, | ||
384 | sc->ani.noise_floor); | ||
385 | } else { | ||
386 | DPRINTF(sc, ATH_DBG_ANY, | ||
387 | "calibrate chan %u/%x failed\n", | ||
388 | ah->curchan->channel, | ||
389 | ah->curchan->channelFlags); | ||
390 | } | ||
391 | sc->ani.caldone = iscaldone; | ||
392 | } | ||
393 | } | ||
394 | |||
395 | set_timer: | ||
396 | /* | ||
397 | * Set timer interval based on previous results. | ||
398 | * The interval must be the shortest necessary to satisfy ANI, | ||
399 | * short calibration and long calibration. | ||
400 | */ | ||
401 | cal_interval = ATH_LONG_CALINTERVAL; | ||
402 | if (sc->sc_ah->config.enable_ani) | ||
403 | cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); | ||
404 | if (!sc->ani.caldone) | ||
405 | cal_interval = min(cal_interval, (u32)short_cal_interval); | ||
406 | |||
407 | mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); | ||
408 | } | ||
409 | |||
410 | /* | ||
411 | * Update tx/rx chainmask. For legacy association, | ||
412 | * hard code chainmask to 1x1, for 11n association, use | ||
413 | * the chainmask configuration, for bt coexistence, use | ||
414 | * the chainmask configuration even in legacy mode. | ||
415 | */ | ||
416 | void ath_update_chainmask(struct ath_softc *sc, int is_ht) | ||
417 | { | ||
418 | if (is_ht || | ||
419 | (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) { | ||
420 | sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask; | ||
421 | sc->rx_chainmask = sc->sc_ah->caps.rx_chainmask; | ||
422 | } else { | ||
423 | sc->tx_chainmask = 1; | ||
424 | sc->rx_chainmask = 1; | ||
425 | } | ||
426 | |||
427 | DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n", | ||
428 | sc->tx_chainmask, sc->rx_chainmask); | ||
429 | } | ||
430 | |||
431 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) | ||
432 | { | ||
433 | struct ath_node *an; | ||
434 | |||
435 | an = (struct ath_node *)sta->drv_priv; | ||
436 | |||
437 | if (sc->sc_flags & SC_OP_TXAGGR) { | ||
438 | ath_tx_node_init(sc, an); | ||
439 | an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + | ||
440 | sta->ht_cap.ampdu_factor); | ||
441 | an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); | ||
442 | } | ||
443 | } | ||
444 | |||
445 | static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) | ||
446 | { | ||
447 | struct ath_node *an = (struct ath_node *)sta->drv_priv; | ||
448 | |||
449 | if (sc->sc_flags & SC_OP_TXAGGR) | ||
450 | ath_tx_node_cleanup(sc, an); | ||
451 | } | ||
452 | |||
453 | static void ath9k_tasklet(unsigned long data) | ||
454 | { | ||
455 | struct ath_softc *sc = (struct ath_softc *)data; | ||
456 | u32 status = sc->intrstatus; | ||
457 | |||
458 | if (status & ATH9K_INT_FATAL) { | ||
459 | ath_reset(sc, false); | ||
460 | return; | ||
461 | } | ||
462 | |||
463 | if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) { | ||
464 | spin_lock_bh(&sc->rx.rxflushlock); | ||
465 | ath_rx_tasklet(sc, 0); | ||
466 | spin_unlock_bh(&sc->rx.rxflushlock); | ||
467 | } | ||
468 | |||
469 | if (status & ATH9K_INT_TX) | ||
470 | ath_tx_tasklet(sc); | ||
471 | |||
472 | /* re-enable hardware interrupt */ | ||
473 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | ||
474 | } | ||
475 | |||
476 | irqreturn_t ath_isr(int irq, void *dev) | ||
477 | { | ||
478 | #define SCHED_INTR ( \ | ||
479 | ATH9K_INT_FATAL | \ | ||
480 | ATH9K_INT_RXORN | \ | ||
481 | ATH9K_INT_RXEOL | \ | ||
482 | ATH9K_INT_RX | \ | ||
483 | ATH9K_INT_TX | \ | ||
484 | ATH9K_INT_BMISS | \ | ||
485 | ATH9K_INT_CST | \ | ||
486 | ATH9K_INT_TSFOOR) | ||
487 | |||
488 | struct ath_softc *sc = dev; | ||
489 | struct ath_hw *ah = sc->sc_ah; | ||
490 | enum ath9k_int status; | ||
491 | bool sched = false; | ||
492 | |||
493 | /* | ||
494 | * The hardware is not ready/present, don't | ||
495 | * touch anything. Note this can happen early | ||
496 | * on if the IRQ is shared. | ||
497 | */ | ||
498 | if (sc->sc_flags & SC_OP_INVALID) | ||
499 | return IRQ_NONE; | ||
500 | |||
501 | ath9k_ps_wakeup(sc); | ||
502 | |||
503 | /* shared irq, not for us */ | ||
504 | |||
505 | if (!ath9k_hw_intrpend(ah)) { | ||
506 | ath9k_ps_restore(sc); | ||
507 | return IRQ_NONE; | ||
508 | } | ||
509 | |||
510 | /* | ||
511 | * Figure out the reason(s) for the interrupt. Note | ||
512 | * that the hal returns a pseudo-ISR that may include | ||
513 | * bits we haven't explicitly enabled so we mask the | ||
514 | * value to insure we only process bits we requested. | ||
515 | */ | ||
516 | ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */ | ||
517 | status &= sc->imask; /* discard unasked-for bits */ | ||
518 | |||
519 | /* | ||
520 | * If there are no status bits set, then this interrupt was not | ||
521 | * for me (should have been caught above). | ||
522 | */ | ||
523 | if (!status) { | ||
524 | ath9k_ps_restore(sc); | ||
525 | return IRQ_NONE; | ||
526 | } | ||
527 | |||
528 | /* Cache the status */ | ||
529 | sc->intrstatus = status; | ||
530 | |||
531 | if (status & SCHED_INTR) | ||
532 | sched = true; | ||
533 | |||
534 | /* | ||
535 | * If a FATAL or RXORN interrupt is received, we have to reset the | ||
536 | * chip immediately. | ||
537 | */ | ||
538 | if (status & (ATH9K_INT_FATAL | ATH9K_INT_RXORN)) | ||
539 | goto chip_reset; | ||
540 | |||
541 | if (status & ATH9K_INT_SWBA) | ||
542 | tasklet_schedule(&sc->bcon_tasklet); | ||
543 | |||
544 | if (status & ATH9K_INT_TXURN) | ||
545 | ath9k_hw_updatetxtriglevel(ah, true); | ||
546 | |||
547 | if (status & ATH9K_INT_MIB) { | ||
548 | /* | ||
549 | * Disable interrupts until we service the MIB | ||
550 | * interrupt; otherwise it will continue to | ||
551 | * fire. | ||
552 | */ | ||
553 | ath9k_hw_set_interrupts(ah, 0); | ||
554 | /* | ||
555 | * Let the hal handle the event. We assume | ||
556 | * it will clear whatever condition caused | ||
557 | * the interrupt. | ||
558 | */ | ||
559 | ath9k_hw_procmibevent(ah, &sc->nodestats); | ||
560 | ath9k_hw_set_interrupts(ah, sc->imask); | ||
561 | } | ||
562 | |||
563 | if (status & ATH9K_INT_TIM_TIMER) { | ||
564 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | ||
565 | /* Clear RxAbort bit so that we can | ||
566 | * receive frames */ | ||
567 | ath9k_hw_setpower(ah, ATH9K_PM_AWAKE); | ||
568 | ath9k_hw_setrxabort(ah, 0); | ||
569 | sched = true; | ||
570 | sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; | ||
571 | } | ||
572 | } | ||
573 | |||
574 | chip_reset: | ||
575 | |||
576 | ath9k_ps_restore(sc); | ||
577 | ath_debug_stat_interrupt(sc, status); | ||
578 | |||
579 | if (sched) { | ||
580 | /* turn off every interrupt except SWBA */ | ||
581 | ath9k_hw_set_interrupts(ah, (sc->imask & ATH9K_INT_SWBA)); | ||
582 | tasklet_schedule(&sc->intr_tq); | ||
583 | } | ||
584 | |||
585 | return IRQ_HANDLED; | ||
586 | |||
587 | #undef SCHED_INTR | ||
588 | } | ||
589 | |||
590 | static u32 ath_get_extchanmode(struct ath_softc *sc, | ||
591 | struct ieee80211_channel *chan, | ||
592 | enum nl80211_channel_type channel_type) | ||
593 | { | ||
594 | u32 chanmode = 0; | ||
595 | |||
596 | switch (chan->band) { | ||
597 | case IEEE80211_BAND_2GHZ: | ||
598 | switch(channel_type) { | ||
599 | case NL80211_CHAN_NO_HT: | ||
600 | case NL80211_CHAN_HT20: | ||
601 | chanmode = CHANNEL_G_HT20; | ||
602 | break; | ||
603 | case NL80211_CHAN_HT40PLUS: | ||
604 | chanmode = CHANNEL_G_HT40PLUS; | ||
605 | break; | ||
606 | case NL80211_CHAN_HT40MINUS: | ||
607 | chanmode = CHANNEL_G_HT40MINUS; | ||
608 | break; | ||
609 | } | ||
610 | break; | ||
611 | case IEEE80211_BAND_5GHZ: | ||
612 | switch(channel_type) { | ||
613 | case NL80211_CHAN_NO_HT: | ||
614 | case NL80211_CHAN_HT20: | ||
615 | chanmode = CHANNEL_A_HT20; | ||
616 | break; | ||
617 | case NL80211_CHAN_HT40PLUS: | ||
618 | chanmode = CHANNEL_A_HT40PLUS; | ||
619 | break; | ||
620 | case NL80211_CHAN_HT40MINUS: | ||
621 | chanmode = CHANNEL_A_HT40MINUS; | ||
622 | break; | ||
623 | } | ||
624 | break; | ||
625 | default: | ||
626 | break; | ||
627 | } | ||
628 | |||
629 | return chanmode; | ||
630 | } | ||
631 | |||
632 | static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key, | ||
633 | struct ath9k_keyval *hk, const u8 *addr, | ||
634 | bool authenticator) | ||
635 | { | ||
636 | const u8 *key_rxmic; | ||
637 | const u8 *key_txmic; | ||
638 | |||
639 | key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; | ||
640 | key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; | ||
641 | |||
642 | if (addr == NULL) { | ||
643 | /* | ||
644 | * Group key installation - only two key cache entries are used | ||
645 | * regardless of splitmic capability since group key is only | ||
646 | * used either for TX or RX. | ||
647 | */ | ||
648 | if (authenticator) { | ||
649 | memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); | ||
650 | memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic)); | ||
651 | } else { | ||
652 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | ||
653 | memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); | ||
654 | } | ||
655 | return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr); | ||
656 | } | ||
657 | if (!sc->splitmic) { | ||
658 | /* TX and RX keys share the same key cache entry. */ | ||
659 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | ||
660 | memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); | ||
661 | return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr); | ||
662 | } | ||
663 | |||
664 | /* Separate key cache entries for TX and RX */ | ||
665 | |||
666 | /* TX key goes at first index, RX key at +32. */ | ||
667 | memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); | ||
668 | if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) { | ||
669 | /* TX MIC entry failed. No need to proceed further */ | ||
670 | DPRINTF(sc, ATH_DBG_FATAL, | ||
671 | "Setting TX MIC Key Failed\n"); | ||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | ||
676 | /* XXX delete tx key on failure? */ | ||
677 | return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix + 32, hk, addr); | ||
678 | } | ||
679 | |||
680 | static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc) | ||
681 | { | ||
682 | int i; | ||
683 | |||
684 | for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) { | ||
685 | if (test_bit(i, sc->keymap) || | ||
686 | test_bit(i + 64, sc->keymap)) | ||
687 | continue; /* At least one part of TKIP key allocated */ | ||
688 | if (sc->splitmic && | ||
689 | (test_bit(i + 32, sc->keymap) || | ||
690 | test_bit(i + 64 + 32, sc->keymap))) | ||
691 | continue; /* At least one part of TKIP key allocated */ | ||
692 | |||
693 | /* Found a free slot for a TKIP key */ | ||
694 | return i; | ||
695 | } | ||
696 | return -1; | ||
697 | } | ||
698 | |||
699 | static int ath_reserve_key_cache_slot(struct ath_softc *sc) | ||
700 | { | ||
701 | int i; | ||
702 | |||
703 | /* First, try to find slots that would not be available for TKIP. */ | ||
704 | if (sc->splitmic) { | ||
705 | for (i = IEEE80211_WEP_NKID; i < sc->keymax / 4; i++) { | ||
706 | if (!test_bit(i, sc->keymap) && | ||
707 | (test_bit(i + 32, sc->keymap) || | ||
708 | test_bit(i + 64, sc->keymap) || | ||
709 | test_bit(i + 64 + 32, sc->keymap))) | ||
710 | return i; | ||
711 | if (!test_bit(i + 32, sc->keymap) && | ||
712 | (test_bit(i, sc->keymap) || | ||
713 | test_bit(i + 64, sc->keymap) || | ||
714 | test_bit(i + 64 + 32, sc->keymap))) | ||
715 | return i + 32; | ||
716 | if (!test_bit(i + 64, sc->keymap) && | ||
717 | (test_bit(i , sc->keymap) || | ||
718 | test_bit(i + 32, sc->keymap) || | ||
719 | test_bit(i + 64 + 32, sc->keymap))) | ||
720 | return i + 64; | ||
721 | if (!test_bit(i + 64 + 32, sc->keymap) && | ||
722 | (test_bit(i, sc->keymap) || | ||
723 | test_bit(i + 32, sc->keymap) || | ||
724 | test_bit(i + 64, sc->keymap))) | ||
725 | return i + 64 + 32; | ||
726 | } | ||
727 | } else { | ||
728 | for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) { | ||
729 | if (!test_bit(i, sc->keymap) && | ||
730 | test_bit(i + 64, sc->keymap)) | ||
731 | return i; | ||
732 | if (test_bit(i, sc->keymap) && | ||
733 | !test_bit(i + 64, sc->keymap)) | ||
734 | return i + 64; | ||
735 | } | ||
736 | } | ||
737 | |||
738 | /* No partially used TKIP slots, pick any available slot */ | ||
739 | for (i = IEEE80211_WEP_NKID; i < sc->keymax; i++) { | ||
740 | /* Do not allow slots that could be needed for TKIP group keys | ||
741 | * to be used. This limitation could be removed if we know that | ||
742 | * TKIP will not be used. */ | ||
743 | if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) | ||
744 | continue; | ||
745 | if (sc->splitmic) { | ||
746 | if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) | ||
747 | continue; | ||
748 | if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) | ||
749 | continue; | ||
750 | } | ||
751 | |||
752 | if (!test_bit(i, sc->keymap)) | ||
753 | return i; /* Found a free slot for a key */ | ||
754 | } | ||
755 | |||
756 | /* No free slot found */ | ||
757 | return -1; | ||
758 | } | ||
759 | |||
760 | static int ath_key_config(struct ath_softc *sc, | ||
761 | struct ieee80211_vif *vif, | ||
762 | struct ieee80211_sta *sta, | ||
763 | struct ieee80211_key_conf *key) | ||
764 | { | ||
765 | struct ath9k_keyval hk; | ||
766 | const u8 *mac = NULL; | ||
767 | int ret = 0; | ||
768 | int idx; | ||
769 | |||
770 | memset(&hk, 0, sizeof(hk)); | ||
771 | |||
772 | switch (key->alg) { | ||
773 | case ALG_WEP: | ||
774 | hk.kv_type = ATH9K_CIPHER_WEP; | ||
775 | break; | ||
776 | case ALG_TKIP: | ||
777 | hk.kv_type = ATH9K_CIPHER_TKIP; | ||
778 | break; | ||
779 | case ALG_CCMP: | ||
780 | hk.kv_type = ATH9K_CIPHER_AES_CCM; | ||
781 | break; | ||
782 | default: | ||
783 | return -EOPNOTSUPP; | ||
784 | } | ||
785 | |||
786 | hk.kv_len = key->keylen; | ||
787 | memcpy(hk.kv_val, key->key, key->keylen); | ||
788 | |||
789 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | ||
790 | /* For now, use the default keys for broadcast keys. This may | ||
791 | * need to change with virtual interfaces. */ | ||
792 | idx = key->keyidx; | ||
793 | } else if (key->keyidx) { | ||
794 | if (WARN_ON(!sta)) | ||
795 | return -EOPNOTSUPP; | ||
796 | mac = sta->addr; | ||
797 | |||
798 | if (vif->type != NL80211_IFTYPE_AP) { | ||
799 | /* Only keyidx 0 should be used with unicast key, but | ||
800 | * allow this for client mode for now. */ | ||
801 | idx = key->keyidx; | ||
802 | } else | ||
803 | return -EIO; | ||
804 | } else { | ||
805 | if (WARN_ON(!sta)) | ||
806 | return -EOPNOTSUPP; | ||
807 | mac = sta->addr; | ||
808 | |||
809 | if (key->alg == ALG_TKIP) | ||
810 | idx = ath_reserve_key_cache_slot_tkip(sc); | ||
811 | else | ||
812 | idx = ath_reserve_key_cache_slot(sc); | ||
813 | if (idx < 0) | ||
814 | return -ENOSPC; /* no free key cache entries */ | ||
815 | } | ||
816 | |||
817 | if (key->alg == ALG_TKIP) | ||
818 | ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac, | ||
819 | vif->type == NL80211_IFTYPE_AP); | ||
820 | else | ||
821 | ret = ath9k_hw_set_keycache_entry(sc->sc_ah, idx, &hk, mac); | ||
822 | |||
823 | if (!ret) | ||
824 | return -EIO; | ||
825 | |||
826 | set_bit(idx, sc->keymap); | ||
827 | if (key->alg == ALG_TKIP) { | ||
828 | set_bit(idx + 64, sc->keymap); | ||
829 | if (sc->splitmic) { | ||
830 | set_bit(idx + 32, sc->keymap); | ||
831 | set_bit(idx + 64 + 32, sc->keymap); | ||
832 | } | ||
833 | } | ||
834 | |||
835 | return idx; | ||
836 | } | ||
837 | |||
838 | static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key) | ||
839 | { | ||
840 | ath9k_hw_keyreset(sc->sc_ah, key->hw_key_idx); | ||
841 | if (key->hw_key_idx < IEEE80211_WEP_NKID) | ||
842 | return; | ||
843 | |||
844 | clear_bit(key->hw_key_idx, sc->keymap); | ||
845 | if (key->alg != ALG_TKIP) | ||
846 | return; | ||
847 | |||
848 | clear_bit(key->hw_key_idx + 64, sc->keymap); | ||
849 | if (sc->splitmic) { | ||
850 | clear_bit(key->hw_key_idx + 32, sc->keymap); | ||
851 | clear_bit(key->hw_key_idx + 64 + 32, sc->keymap); | ||
852 | } | ||
853 | } | ||
854 | |||
855 | static void setup_ht_cap(struct ath_softc *sc, | ||
856 | struct ieee80211_sta_ht_cap *ht_info) | ||
857 | { | ||
858 | #define ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */ | ||
859 | #define ATH9K_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */ | ||
860 | |||
861 | ht_info->ht_supported = true; | ||
862 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
863 | IEEE80211_HT_CAP_SM_PS | | ||
864 | IEEE80211_HT_CAP_SGI_40 | | ||
865 | IEEE80211_HT_CAP_DSSSCCK40; | ||
866 | |||
867 | ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536; | ||
868 | ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8; | ||
869 | |||
870 | /* set up supported mcs set */ | ||
871 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | ||
872 | |||
873 | switch(sc->rx_chainmask) { | ||
874 | case 1: | ||
875 | ht_info->mcs.rx_mask[0] = 0xff; | ||
876 | break; | ||
877 | case 3: | ||
878 | case 5: | ||
879 | case 7: | ||
880 | default: | ||
881 | ht_info->mcs.rx_mask[0] = 0xff; | ||
882 | ht_info->mcs.rx_mask[1] = 0xff; | ||
883 | break; | ||
884 | } | ||
885 | |||
886 | ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; | ||
887 | } | ||
888 | |||
889 | static void ath9k_bss_assoc_info(struct ath_softc *sc, | ||
890 | struct ieee80211_vif *vif, | ||
891 | struct ieee80211_bss_conf *bss_conf) | ||
892 | { | ||
893 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
894 | |||
895 | if (bss_conf->assoc) { | ||
896 | DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n", | ||
897 | bss_conf->aid, sc->curbssid); | ||
898 | |||
899 | /* New association, store aid */ | ||
900 | if (avp->av_opmode == NL80211_IFTYPE_STATION) { | ||
901 | sc->curaid = bss_conf->aid; | ||
902 | ath9k_hw_write_associd(sc); | ||
903 | } | ||
904 | |||
905 | /* Configure the beacon */ | ||
906 | ath_beacon_config(sc, vif); | ||
907 | |||
908 | /* Reset rssi stats */ | ||
909 | sc->nodestats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER; | ||
910 | sc->nodestats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER; | ||
911 | sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER; | ||
912 | sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER; | ||
913 | |||
914 | /* Start ANI */ | ||
915 | mod_timer(&sc->ani.timer, | ||
916 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); | ||
917 | } else { | ||
918 | DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); | ||
919 | sc->curaid = 0; | ||
920 | } | ||
921 | } | ||
922 | |||
923 | /********************************/ | ||
924 | /* LED functions */ | ||
925 | /********************************/ | ||
926 | |||
927 | static void ath_led_blink_work(struct work_struct *work) | ||
928 | { | ||
929 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
930 | ath_led_blink_work.work); | ||
931 | |||
932 | if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED)) | ||
933 | return; | ||
934 | |||
935 | if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) || | ||
936 | (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) | ||
937 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0); | ||
938 | else | ||
939 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, | ||
940 | (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0); | ||
941 | |||
942 | queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work, | ||
943 | (sc->sc_flags & SC_OP_LED_ON) ? | ||
944 | msecs_to_jiffies(sc->led_off_duration) : | ||
945 | msecs_to_jiffies(sc->led_on_duration)); | ||
946 | |||
947 | sc->led_on_duration = sc->led_on_cnt ? | ||
948 | max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) : | ||
949 | ATH_LED_ON_DURATION_IDLE; | ||
950 | sc->led_off_duration = sc->led_off_cnt ? | ||
951 | max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) : | ||
952 | ATH_LED_OFF_DURATION_IDLE; | ||
953 | sc->led_on_cnt = sc->led_off_cnt = 0; | ||
954 | if (sc->sc_flags & SC_OP_LED_ON) | ||
955 | sc->sc_flags &= ~SC_OP_LED_ON; | ||
956 | else | ||
957 | sc->sc_flags |= SC_OP_LED_ON; | ||
958 | } | ||
959 | |||
960 | static void ath_led_brightness(struct led_classdev *led_cdev, | ||
961 | enum led_brightness brightness) | ||
962 | { | ||
963 | struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); | ||
964 | struct ath_softc *sc = led->sc; | ||
965 | |||
966 | switch (brightness) { | ||
967 | case LED_OFF: | ||
968 | if (led->led_type == ATH_LED_ASSOC || | ||
969 | led->led_type == ATH_LED_RADIO) { | ||
970 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, | ||
971 | (led->led_type == ATH_LED_RADIO)); | ||
972 | sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; | ||
973 | if (led->led_type == ATH_LED_RADIO) | ||
974 | sc->sc_flags &= ~SC_OP_LED_ON; | ||
975 | } else { | ||
976 | sc->led_off_cnt++; | ||
977 | } | ||
978 | break; | ||
979 | case LED_FULL: | ||
980 | if (led->led_type == ATH_LED_ASSOC) { | ||
981 | sc->sc_flags |= SC_OP_LED_ASSOCIATED; | ||
982 | queue_delayed_work(sc->hw->workqueue, | ||
983 | &sc->ath_led_blink_work, 0); | ||
984 | } else if (led->led_type == ATH_LED_RADIO) { | ||
985 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0); | ||
986 | sc->sc_flags |= SC_OP_LED_ON; | ||
987 | } else { | ||
988 | sc->led_on_cnt++; | ||
989 | } | ||
990 | break; | ||
991 | default: | ||
992 | break; | ||
993 | } | ||
994 | } | ||
995 | |||
996 | static int ath_register_led(struct ath_softc *sc, struct ath_led *led, | ||
997 | char *trigger) | ||
998 | { | ||
999 | int ret; | ||
1000 | |||
1001 | led->sc = sc; | ||
1002 | led->led_cdev.name = led->name; | ||
1003 | led->led_cdev.default_trigger = trigger; | ||
1004 | led->led_cdev.brightness_set = ath_led_brightness; | ||
1005 | |||
1006 | ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev); | ||
1007 | if (ret) | ||
1008 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1009 | "Failed to register led:%s", led->name); | ||
1010 | else | ||
1011 | led->registered = 1; | ||
1012 | return ret; | ||
1013 | } | ||
1014 | |||
1015 | static void ath_unregister_led(struct ath_led *led) | ||
1016 | { | ||
1017 | if (led->registered) { | ||
1018 | led_classdev_unregister(&led->led_cdev); | ||
1019 | led->registered = 0; | ||
1020 | } | ||
1021 | } | ||
1022 | |||
1023 | static void ath_deinit_leds(struct ath_softc *sc) | ||
1024 | { | ||
1025 | cancel_delayed_work_sync(&sc->ath_led_blink_work); | ||
1026 | ath_unregister_led(&sc->assoc_led); | ||
1027 | sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; | ||
1028 | ath_unregister_led(&sc->tx_led); | ||
1029 | ath_unregister_led(&sc->rx_led); | ||
1030 | ath_unregister_led(&sc->radio_led); | ||
1031 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); | ||
1032 | } | ||
1033 | |||
1034 | static void ath_init_leds(struct ath_softc *sc) | ||
1035 | { | ||
1036 | char *trigger; | ||
1037 | int ret; | ||
1038 | |||
1039 | /* Configure gpio 1 for output */ | ||
1040 | ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN, | ||
1041 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
1042 | /* LED off, active low */ | ||
1043 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); | ||
1044 | |||
1045 | INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); | ||
1046 | |||
1047 | trigger = ieee80211_get_radio_led_name(sc->hw); | ||
1048 | snprintf(sc->radio_led.name, sizeof(sc->radio_led.name), | ||
1049 | "ath9k-%s::radio", wiphy_name(sc->hw->wiphy)); | ||
1050 | ret = ath_register_led(sc, &sc->radio_led, trigger); | ||
1051 | sc->radio_led.led_type = ATH_LED_RADIO; | ||
1052 | if (ret) | ||
1053 | goto fail; | ||
1054 | |||
1055 | trigger = ieee80211_get_assoc_led_name(sc->hw); | ||
1056 | snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name), | ||
1057 | "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy)); | ||
1058 | ret = ath_register_led(sc, &sc->assoc_led, trigger); | ||
1059 | sc->assoc_led.led_type = ATH_LED_ASSOC; | ||
1060 | if (ret) | ||
1061 | goto fail; | ||
1062 | |||
1063 | trigger = ieee80211_get_tx_led_name(sc->hw); | ||
1064 | snprintf(sc->tx_led.name, sizeof(sc->tx_led.name), | ||
1065 | "ath9k-%s::tx", wiphy_name(sc->hw->wiphy)); | ||
1066 | ret = ath_register_led(sc, &sc->tx_led, trigger); | ||
1067 | sc->tx_led.led_type = ATH_LED_TX; | ||
1068 | if (ret) | ||
1069 | goto fail; | ||
1070 | |||
1071 | trigger = ieee80211_get_rx_led_name(sc->hw); | ||
1072 | snprintf(sc->rx_led.name, sizeof(sc->rx_led.name), | ||
1073 | "ath9k-%s::rx", wiphy_name(sc->hw->wiphy)); | ||
1074 | ret = ath_register_led(sc, &sc->rx_led, trigger); | ||
1075 | sc->rx_led.led_type = ATH_LED_RX; | ||
1076 | if (ret) | ||
1077 | goto fail; | ||
1078 | |||
1079 | return; | ||
1080 | |||
1081 | fail: | ||
1082 | ath_deinit_leds(sc); | ||
1083 | } | ||
1084 | |||
1085 | void ath_radio_enable(struct ath_softc *sc) | ||
1086 | { | ||
1087 | struct ath_hw *ah = sc->sc_ah; | ||
1088 | struct ieee80211_channel *channel = sc->hw->conf.channel; | ||
1089 | int r; | ||
1090 | |||
1091 | ath9k_ps_wakeup(sc); | ||
1092 | spin_lock_bh(&sc->sc_resetlock); | ||
1093 | |||
1094 | r = ath9k_hw_reset(ah, ah->curchan, false); | ||
1095 | |||
1096 | if (r) { | ||
1097 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1098 | "Unable to reset channel %u (%uMhz) ", | ||
1099 | "reset status %u\n", | ||
1100 | channel->center_freq, r); | ||
1101 | } | ||
1102 | spin_unlock_bh(&sc->sc_resetlock); | ||
1103 | |||
1104 | ath_update_txpow(sc); | ||
1105 | if (ath_startrecv(sc) != 0) { | ||
1106 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1107 | "Unable to restart recv logic\n"); | ||
1108 | return; | ||
1109 | } | ||
1110 | |||
1111 | if (sc->sc_flags & SC_OP_BEACONS) | ||
1112 | ath_beacon_config(sc, NULL); /* restart beacons */ | ||
1113 | |||
1114 | /* Re-Enable interrupts */ | ||
1115 | ath9k_hw_set_interrupts(ah, sc->imask); | ||
1116 | |||
1117 | /* Enable LED */ | ||
1118 | ath9k_hw_cfg_output(ah, ATH_LED_PIN, | ||
1119 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
1120 | ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0); | ||
1121 | |||
1122 | ieee80211_wake_queues(sc->hw); | ||
1123 | ath9k_ps_restore(sc); | ||
1124 | } | ||
1125 | |||
1126 | void ath_radio_disable(struct ath_softc *sc) | ||
1127 | { | ||
1128 | struct ath_hw *ah = sc->sc_ah; | ||
1129 | struct ieee80211_channel *channel = sc->hw->conf.channel; | ||
1130 | int r; | ||
1131 | |||
1132 | ath9k_ps_wakeup(sc); | ||
1133 | ieee80211_stop_queues(sc->hw); | ||
1134 | |||
1135 | /* Disable LED */ | ||
1136 | ath9k_hw_set_gpio(ah, ATH_LED_PIN, 1); | ||
1137 | ath9k_hw_cfg_gpio_input(ah, ATH_LED_PIN); | ||
1138 | |||
1139 | /* Disable interrupts */ | ||
1140 | ath9k_hw_set_interrupts(ah, 0); | ||
1141 | |||
1142 | ath_drain_all_txq(sc, false); /* clear pending tx frames */ | ||
1143 | ath_stoprecv(sc); /* turn off frame recv */ | ||
1144 | ath_flushrecv(sc); /* flush recv queue */ | ||
1145 | |||
1146 | spin_lock_bh(&sc->sc_resetlock); | ||
1147 | r = ath9k_hw_reset(ah, ah->curchan, false); | ||
1148 | if (r) { | ||
1149 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1150 | "Unable to reset channel %u (%uMhz) " | ||
1151 | "reset status %u\n", | ||
1152 | channel->center_freq, r); | ||
1153 | } | ||
1154 | spin_unlock_bh(&sc->sc_resetlock); | ||
1155 | |||
1156 | ath9k_hw_phy_disable(ah); | ||
1157 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); | ||
1158 | ath9k_ps_restore(sc); | ||
1159 | } | ||
1160 | |||
1161 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
1162 | |||
1163 | /*******************/ | ||
1164 | /* Rfkill */ | ||
1165 | /*******************/ | ||
1166 | |||
1167 | static bool ath_is_rfkill_set(struct ath_softc *sc) | ||
1168 | { | ||
1169 | struct ath_hw *ah = sc->sc_ah; | ||
1170 | |||
1171 | return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) == | ||
1172 | ah->rfkill_polarity; | ||
1173 | } | ||
1174 | |||
1175 | /* h/w rfkill poll function */ | ||
1176 | static void ath_rfkill_poll(struct work_struct *work) | ||
1177 | { | ||
1178 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
1179 | rf_kill.rfkill_poll.work); | ||
1180 | bool radio_on; | ||
1181 | |||
1182 | if (sc->sc_flags & SC_OP_INVALID) | ||
1183 | return; | ||
1184 | |||
1185 | radio_on = !ath_is_rfkill_set(sc); | ||
1186 | |||
1187 | /* | ||
1188 | * enable/disable radio only when there is a | ||
1189 | * state change in RF switch | ||
1190 | */ | ||
1191 | if (radio_on == !!(sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED)) { | ||
1192 | enum rfkill_state state; | ||
1193 | |||
1194 | if (sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED) { | ||
1195 | state = radio_on ? RFKILL_STATE_SOFT_BLOCKED | ||
1196 | : RFKILL_STATE_HARD_BLOCKED; | ||
1197 | } else if (radio_on) { | ||
1198 | ath_radio_enable(sc); | ||
1199 | state = RFKILL_STATE_UNBLOCKED; | ||
1200 | } else { | ||
1201 | ath_radio_disable(sc); | ||
1202 | state = RFKILL_STATE_HARD_BLOCKED; | ||
1203 | } | ||
1204 | |||
1205 | if (state == RFKILL_STATE_HARD_BLOCKED) | ||
1206 | sc->sc_flags |= SC_OP_RFKILL_HW_BLOCKED; | ||
1207 | else | ||
1208 | sc->sc_flags &= ~SC_OP_RFKILL_HW_BLOCKED; | ||
1209 | |||
1210 | rfkill_force_state(sc->rf_kill.rfkill, state); | ||
1211 | } | ||
1212 | |||
1213 | queue_delayed_work(sc->hw->workqueue, &sc->rf_kill.rfkill_poll, | ||
1214 | msecs_to_jiffies(ATH_RFKILL_POLL_INTERVAL)); | ||
1215 | } | ||
1216 | |||
1217 | /* s/w rfkill handler */ | ||
1218 | static int ath_sw_toggle_radio(void *data, enum rfkill_state state) | ||
1219 | { | ||
1220 | struct ath_softc *sc = data; | ||
1221 | |||
1222 | switch (state) { | ||
1223 | case RFKILL_STATE_SOFT_BLOCKED: | ||
1224 | if (!(sc->sc_flags & (SC_OP_RFKILL_HW_BLOCKED | | ||
1225 | SC_OP_RFKILL_SW_BLOCKED))) | ||
1226 | ath_radio_disable(sc); | ||
1227 | sc->sc_flags |= SC_OP_RFKILL_SW_BLOCKED; | ||
1228 | return 0; | ||
1229 | case RFKILL_STATE_UNBLOCKED: | ||
1230 | if ((sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED)) { | ||
1231 | sc->sc_flags &= ~SC_OP_RFKILL_SW_BLOCKED; | ||
1232 | if (sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED) { | ||
1233 | DPRINTF(sc, ATH_DBG_FATAL, "Can't turn on the" | ||
1234 | "radio as it is disabled by h/w\n"); | ||
1235 | return -EPERM; | ||
1236 | } | ||
1237 | ath_radio_enable(sc); | ||
1238 | } | ||
1239 | return 0; | ||
1240 | default: | ||
1241 | return -EINVAL; | ||
1242 | } | ||
1243 | } | ||
1244 | |||
1245 | /* Init s/w rfkill */ | ||
1246 | static int ath_init_sw_rfkill(struct ath_softc *sc) | ||
1247 | { | ||
1248 | sc->rf_kill.rfkill = rfkill_allocate(wiphy_dev(sc->hw->wiphy), | ||
1249 | RFKILL_TYPE_WLAN); | ||
1250 | if (!sc->rf_kill.rfkill) { | ||
1251 | DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n"); | ||
1252 | return -ENOMEM; | ||
1253 | } | ||
1254 | |||
1255 | snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name), | ||
1256 | "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy)); | ||
1257 | sc->rf_kill.rfkill->name = sc->rf_kill.rfkill_name; | ||
1258 | sc->rf_kill.rfkill->data = sc; | ||
1259 | sc->rf_kill.rfkill->toggle_radio = ath_sw_toggle_radio; | ||
1260 | sc->rf_kill.rfkill->state = RFKILL_STATE_UNBLOCKED; | ||
1261 | |||
1262 | return 0; | ||
1263 | } | ||
1264 | |||
1265 | /* Deinitialize rfkill */ | ||
1266 | static void ath_deinit_rfkill(struct ath_softc *sc) | ||
1267 | { | ||
1268 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
1269 | cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); | ||
1270 | |||
1271 | if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) { | ||
1272 | rfkill_unregister(sc->rf_kill.rfkill); | ||
1273 | sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED; | ||
1274 | sc->rf_kill.rfkill = NULL; | ||
1275 | } | ||
1276 | } | ||
1277 | |||
1278 | static int ath_start_rfkill_poll(struct ath_softc *sc) | ||
1279 | { | ||
1280 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
1281 | queue_delayed_work(sc->hw->workqueue, | ||
1282 | &sc->rf_kill.rfkill_poll, 0); | ||
1283 | |||
1284 | if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) { | ||
1285 | if (rfkill_register(sc->rf_kill.rfkill)) { | ||
1286 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1287 | "Unable to register rfkill\n"); | ||
1288 | rfkill_free(sc->rf_kill.rfkill); | ||
1289 | |||
1290 | /* Deinitialize the device */ | ||
1291 | ath_cleanup(sc); | ||
1292 | return -EIO; | ||
1293 | } else { | ||
1294 | sc->sc_flags |= SC_OP_RFKILL_REGISTERED; | ||
1295 | } | ||
1296 | } | ||
1297 | |||
1298 | return 0; | ||
1299 | } | ||
1300 | #endif /* CONFIG_RFKILL */ | ||
1301 | |||
1302 | void ath_cleanup(struct ath_softc *sc) | ||
1303 | { | ||
1304 | ath_detach(sc); | ||
1305 | free_irq(sc->irq, sc); | ||
1306 | ath_bus_cleanup(sc); | ||
1307 | kfree(sc->sec_wiphy); | ||
1308 | ieee80211_free_hw(sc->hw); | ||
1309 | } | ||
1310 | |||
1311 | void ath_detach(struct ath_softc *sc) | ||
1312 | { | ||
1313 | struct ieee80211_hw *hw = sc->hw; | ||
1314 | int i = 0; | ||
1315 | |||
1316 | ath9k_ps_wakeup(sc); | ||
1317 | |||
1318 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); | ||
1319 | |||
1320 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
1321 | ath_deinit_rfkill(sc); | ||
1322 | #endif | ||
1323 | ath_deinit_leds(sc); | ||
1324 | cancel_work_sync(&sc->chan_work); | ||
1325 | cancel_delayed_work_sync(&sc->wiphy_work); | ||
1326 | |||
1327 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
1328 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
1329 | if (aphy == NULL) | ||
1330 | continue; | ||
1331 | sc->sec_wiphy[i] = NULL; | ||
1332 | ieee80211_unregister_hw(aphy->hw); | ||
1333 | ieee80211_free_hw(aphy->hw); | ||
1334 | } | ||
1335 | ieee80211_unregister_hw(hw); | ||
1336 | ath_rx_cleanup(sc); | ||
1337 | ath_tx_cleanup(sc); | ||
1338 | |||
1339 | tasklet_kill(&sc->intr_tq); | ||
1340 | tasklet_kill(&sc->bcon_tasklet); | ||
1341 | |||
1342 | if (!(sc->sc_flags & SC_OP_INVALID)) | ||
1343 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); | ||
1344 | |||
1345 | /* cleanup tx queues */ | ||
1346 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
1347 | if (ATH_TXQ_SETUP(sc, i)) | ||
1348 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
1349 | |||
1350 | ath9k_hw_detach(sc->sc_ah); | ||
1351 | ath9k_exit_debug(sc); | ||
1352 | ath9k_ps_restore(sc); | ||
1353 | } | ||
1354 | |||
1355 | static int ath9k_reg_notifier(struct wiphy *wiphy, | ||
1356 | struct regulatory_request *request) | ||
1357 | { | ||
1358 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | ||
1359 | struct ath_wiphy *aphy = hw->priv; | ||
1360 | struct ath_softc *sc = aphy->sc; | ||
1361 | struct ath_regulatory *reg = &sc->sc_ah->regulatory; | ||
1362 | |||
1363 | return ath_reg_notifier_apply(wiphy, request, reg); | ||
1364 | } | ||
1365 | |||
1366 | static int ath_init(u16 devid, struct ath_softc *sc) | ||
1367 | { | ||
1368 | struct ath_hw *ah = NULL; | ||
1369 | int status; | ||
1370 | int error = 0, i; | ||
1371 | int csz = 0; | ||
1372 | |||
1373 | /* XXX: hardware will not be ready until ath_open() being called */ | ||
1374 | sc->sc_flags |= SC_OP_INVALID; | ||
1375 | |||
1376 | if (ath9k_init_debug(sc) < 0) | ||
1377 | printk(KERN_ERR "Unable to create debugfs files\n"); | ||
1378 | |||
1379 | spin_lock_init(&sc->wiphy_lock); | ||
1380 | spin_lock_init(&sc->sc_resetlock); | ||
1381 | spin_lock_init(&sc->sc_serial_rw); | ||
1382 | mutex_init(&sc->mutex); | ||
1383 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | ||
1384 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | ||
1385 | (unsigned long)sc); | ||
1386 | |||
1387 | /* | ||
1388 | * Cache line size is used to size and align various | ||
1389 | * structures used to communicate with the hardware. | ||
1390 | */ | ||
1391 | ath_read_cachesize(sc, &csz); | ||
1392 | /* XXX assert csz is non-zero */ | ||
1393 | sc->cachelsz = csz << 2; /* convert to bytes */ | ||
1394 | |||
1395 | ah = ath9k_hw_attach(devid, sc, &status); | ||
1396 | if (ah == NULL) { | ||
1397 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1398 | "Unable to attach hardware; HAL status %d\n", status); | ||
1399 | error = -ENXIO; | ||
1400 | goto bad; | ||
1401 | } | ||
1402 | sc->sc_ah = ah; | ||
1403 | |||
1404 | /* Get the hardware key cache size. */ | ||
1405 | sc->keymax = ah->caps.keycache_size; | ||
1406 | if (sc->keymax > ATH_KEYMAX) { | ||
1407 | DPRINTF(sc, ATH_DBG_ANY, | ||
1408 | "Warning, using only %u entries in %u key cache\n", | ||
1409 | ATH_KEYMAX, sc->keymax); | ||
1410 | sc->keymax = ATH_KEYMAX; | ||
1411 | } | ||
1412 | |||
1413 | /* | ||
1414 | * Reset the key cache since some parts do not | ||
1415 | * reset the contents on initial power up. | ||
1416 | */ | ||
1417 | for (i = 0; i < sc->keymax; i++) | ||
1418 | ath9k_hw_keyreset(ah, (u16) i); | ||
1419 | |||
1420 | if (ath_regd_init(&sc->sc_ah->regulatory, sc->hw->wiphy, | ||
1421 | ath9k_reg_notifier)) | ||
1422 | goto bad; | ||
1423 | |||
1424 | /* default to MONITOR mode */ | ||
1425 | sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; | ||
1426 | |||
1427 | /* Setup rate tables */ | ||
1428 | |||
1429 | ath_rate_attach(sc); | ||
1430 | ath_setup_rates(sc, IEEE80211_BAND_2GHZ); | ||
1431 | ath_setup_rates(sc, IEEE80211_BAND_5GHZ); | ||
1432 | |||
1433 | /* | ||
1434 | * Allocate hardware transmit queues: one queue for | ||
1435 | * beacon frames and one data queue for each QoS | ||
1436 | * priority. Note that the hal handles reseting | ||
1437 | * these queues at the needed time. | ||
1438 | */ | ||
1439 | sc->beacon.beaconq = ath_beaconq_setup(ah); | ||
1440 | if (sc->beacon.beaconq == -1) { | ||
1441 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1442 | "Unable to setup a beacon xmit queue\n"); | ||
1443 | error = -EIO; | ||
1444 | goto bad2; | ||
1445 | } | ||
1446 | sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); | ||
1447 | if (sc->beacon.cabq == NULL) { | ||
1448 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1449 | "Unable to setup CAB xmit queue\n"); | ||
1450 | error = -EIO; | ||
1451 | goto bad2; | ||
1452 | } | ||
1453 | |||
1454 | sc->config.cabqReadytime = ATH_CABQ_READY_TIME; | ||
1455 | ath_cabq_update(sc); | ||
1456 | |||
1457 | for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++) | ||
1458 | sc->tx.hwq_map[i] = -1; | ||
1459 | |||
1460 | /* Setup data queues */ | ||
1461 | /* NB: ensure BK queue is the lowest priority h/w queue */ | ||
1462 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { | ||
1463 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1464 | "Unable to setup xmit queue for BK traffic\n"); | ||
1465 | error = -EIO; | ||
1466 | goto bad2; | ||
1467 | } | ||
1468 | |||
1469 | if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { | ||
1470 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1471 | "Unable to setup xmit queue for BE traffic\n"); | ||
1472 | error = -EIO; | ||
1473 | goto bad2; | ||
1474 | } | ||
1475 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { | ||
1476 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1477 | "Unable to setup xmit queue for VI traffic\n"); | ||
1478 | error = -EIO; | ||
1479 | goto bad2; | ||
1480 | } | ||
1481 | if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { | ||
1482 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1483 | "Unable to setup xmit queue for VO traffic\n"); | ||
1484 | error = -EIO; | ||
1485 | goto bad2; | ||
1486 | } | ||
1487 | |||
1488 | /* Initializes the noise floor to a reasonable default value. | ||
1489 | * Later on this will be updated during ANI processing. */ | ||
1490 | |||
1491 | sc->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; | ||
1492 | setup_timer(&sc->ani.timer, ath_ani_calibrate, (unsigned long)sc); | ||
1493 | |||
1494 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | ||
1495 | ATH9K_CIPHER_TKIP, NULL)) { | ||
1496 | /* | ||
1497 | * Whether we should enable h/w TKIP MIC. | ||
1498 | * XXX: if we don't support WME TKIP MIC, then we wouldn't | ||
1499 | * report WMM capable, so it's always safe to turn on | ||
1500 | * TKIP MIC in this case. | ||
1501 | */ | ||
1502 | ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, | ||
1503 | 0, 1, NULL); | ||
1504 | } | ||
1505 | |||
1506 | /* | ||
1507 | * Check whether the separate key cache entries | ||
1508 | * are required to handle both tx+rx MIC keys. | ||
1509 | * With split mic keys the number of stations is limited | ||
1510 | * to 27 otherwise 59. | ||
1511 | */ | ||
1512 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | ||
1513 | ATH9K_CIPHER_TKIP, NULL) | ||
1514 | && ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | ||
1515 | ATH9K_CIPHER_MIC, NULL) | ||
1516 | && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT, | ||
1517 | 0, NULL)) | ||
1518 | sc->splitmic = 1; | ||
1519 | |||
1520 | /* turn on mcast key search if possible */ | ||
1521 | if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) | ||
1522 | (void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1, | ||
1523 | 1, NULL); | ||
1524 | |||
1525 | sc->config.txpowlimit = ATH_TXPOWER_MAX; | ||
1526 | |||
1527 | /* 11n Capabilities */ | ||
1528 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
1529 | sc->sc_flags |= SC_OP_TXAGGR; | ||
1530 | sc->sc_flags |= SC_OP_RXAGGR; | ||
1531 | } | ||
1532 | |||
1533 | sc->tx_chainmask = ah->caps.tx_chainmask; | ||
1534 | sc->rx_chainmask = ah->caps.rx_chainmask; | ||
1535 | |||
1536 | ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); | ||
1537 | sc->rx.defant = ath9k_hw_getdefantenna(ah); | ||
1538 | |||
1539 | if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | ||
1540 | memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN); | ||
1541 | |||
1542 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */ | ||
1543 | |||
1544 | /* initialize beacon slots */ | ||
1545 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | ||
1546 | sc->beacon.bslot[i] = NULL; | ||
1547 | sc->beacon.bslot_aphy[i] = NULL; | ||
1548 | } | ||
1549 | |||
1550 | /* setup channels and rates */ | ||
1551 | |||
1552 | sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; | ||
1553 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = | ||
1554 | sc->rates[IEEE80211_BAND_2GHZ]; | ||
1555 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | ||
1556 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = | ||
1557 | ARRAY_SIZE(ath9k_2ghz_chantable); | ||
1558 | |||
1559 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { | ||
1560 | sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; | ||
1561 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = | ||
1562 | sc->rates[IEEE80211_BAND_5GHZ]; | ||
1563 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | ||
1564 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = | ||
1565 | ARRAY_SIZE(ath9k_5ghz_chantable); | ||
1566 | } | ||
1567 | |||
1568 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX) | ||
1569 | ath9k_hw_btcoex_enable(sc->sc_ah); | ||
1570 | |||
1571 | return 0; | ||
1572 | bad2: | ||
1573 | /* cleanup tx queues */ | ||
1574 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
1575 | if (ATH_TXQ_SETUP(sc, i)) | ||
1576 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
1577 | bad: | ||
1578 | if (ah) | ||
1579 | ath9k_hw_detach(ah); | ||
1580 | ath9k_exit_debug(sc); | ||
1581 | |||
1582 | return error; | ||
1583 | } | ||
1584 | |||
1585 | void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | ||
1586 | { | ||
1587 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
1588 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
1589 | IEEE80211_HW_SIGNAL_DBM | | ||
1590 | IEEE80211_HW_AMPDU_AGGREGATION | | ||
1591 | IEEE80211_HW_SUPPORTS_PS | | ||
1592 | IEEE80211_HW_PS_NULLFUNC_STACK | | ||
1593 | IEEE80211_HW_SPECTRUM_MGMT; | ||
1594 | |||
1595 | if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt) | ||
1596 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | ||
1597 | |||
1598 | hw->wiphy->interface_modes = | ||
1599 | BIT(NL80211_IFTYPE_AP) | | ||
1600 | BIT(NL80211_IFTYPE_STATION) | | ||
1601 | BIT(NL80211_IFTYPE_ADHOC) | | ||
1602 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
1603 | |||
1604 | hw->queues = 4; | ||
1605 | hw->max_rates = 4; | ||
1606 | hw->channel_change_time = 5000; | ||
1607 | hw->max_listen_interval = 10; | ||
1608 | hw->max_rate_tries = ATH_11N_TXMAXTRY; | ||
1609 | hw->sta_data_size = sizeof(struct ath_node); | ||
1610 | hw->vif_data_size = sizeof(struct ath_vif); | ||
1611 | |||
1612 | hw->rate_control_algorithm = "ath9k_rate_control"; | ||
1613 | |||
1614 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
1615 | &sc->sbands[IEEE80211_BAND_2GHZ]; | ||
1616 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | ||
1617 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
1618 | &sc->sbands[IEEE80211_BAND_5GHZ]; | ||
1619 | } | ||
1620 | |||
1621 | int ath_attach(u16 devid, struct ath_softc *sc) | ||
1622 | { | ||
1623 | struct ieee80211_hw *hw = sc->hw; | ||
1624 | int error = 0, i; | ||
1625 | struct ath_regulatory *reg; | ||
1626 | |||
1627 | DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n"); | ||
1628 | |||
1629 | error = ath_init(devid, sc); | ||
1630 | if (error != 0) | ||
1631 | return error; | ||
1632 | |||
1633 | reg = &sc->sc_ah->regulatory; | ||
1634 | |||
1635 | /* get mac address from hardware and set in mac80211 */ | ||
1636 | |||
1637 | SET_IEEE80211_PERM_ADDR(hw, sc->sc_ah->macaddr); | ||
1638 | |||
1639 | ath_set_hw_capab(sc, hw); | ||
1640 | |||
1641 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
1642 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); | ||
1643 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) | ||
1644 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); | ||
1645 | } | ||
1646 | |||
1647 | /* initialize tx/rx engine */ | ||
1648 | error = ath_tx_init(sc, ATH_TXBUF); | ||
1649 | if (error != 0) | ||
1650 | goto error_attach; | ||
1651 | |||
1652 | error = ath_rx_init(sc, ATH_RXBUF); | ||
1653 | if (error != 0) | ||
1654 | goto error_attach; | ||
1655 | |||
1656 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
1657 | /* Initialze h/w Rfkill */ | ||
1658 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
1659 | INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll); | ||
1660 | |||
1661 | /* Initialize s/w rfkill */ | ||
1662 | error = ath_init_sw_rfkill(sc); | ||
1663 | if (error) | ||
1664 | goto error_attach; | ||
1665 | #endif | ||
1666 | |||
1667 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); | ||
1668 | INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); | ||
1669 | sc->wiphy_scheduler_int = msecs_to_jiffies(500); | ||
1670 | |||
1671 | error = ieee80211_register_hw(hw); | ||
1672 | |||
1673 | if (!ath_is_world_regd(reg)) { | ||
1674 | error = regulatory_hint(hw->wiphy, reg->alpha2); | ||
1675 | if (error) | ||
1676 | goto error_attach; | ||
1677 | } | ||
1678 | |||
1679 | /* Initialize LED control */ | ||
1680 | ath_init_leds(sc); | ||
1681 | |||
1682 | |||
1683 | return 0; | ||
1684 | |||
1685 | error_attach: | ||
1686 | /* cleanup tx queues */ | ||
1687 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
1688 | if (ATH_TXQ_SETUP(sc, i)) | ||
1689 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | ||
1690 | |||
1691 | ath9k_hw_detach(sc->sc_ah); | ||
1692 | ath9k_exit_debug(sc); | ||
1693 | |||
1694 | return error; | ||
1695 | } | ||
1696 | |||
1697 | int ath_reset(struct ath_softc *sc, bool retry_tx) | ||
1698 | { | ||
1699 | struct ath_hw *ah = sc->sc_ah; | ||
1700 | struct ieee80211_hw *hw = sc->hw; | ||
1701 | int r; | ||
1702 | |||
1703 | ath9k_hw_set_interrupts(ah, 0); | ||
1704 | ath_drain_all_txq(sc, retry_tx); | ||
1705 | ath_stoprecv(sc); | ||
1706 | ath_flushrecv(sc); | ||
1707 | |||
1708 | spin_lock_bh(&sc->sc_resetlock); | ||
1709 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); | ||
1710 | if (r) | ||
1711 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1712 | "Unable to reset hardware; reset status %u\n", r); | ||
1713 | spin_unlock_bh(&sc->sc_resetlock); | ||
1714 | |||
1715 | if (ath_startrecv(sc) != 0) | ||
1716 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n"); | ||
1717 | |||
1718 | /* | ||
1719 | * We may be doing a reset in response to a request | ||
1720 | * that changes the channel so update any state that | ||
1721 | * might change as a result. | ||
1722 | */ | ||
1723 | ath_cache_conf_rate(sc, &hw->conf); | ||
1724 | |||
1725 | ath_update_txpow(sc); | ||
1726 | |||
1727 | if (sc->sc_flags & SC_OP_BEACONS) | ||
1728 | ath_beacon_config(sc, NULL); /* restart beacons */ | ||
1729 | |||
1730 | ath9k_hw_set_interrupts(ah, sc->imask); | ||
1731 | |||
1732 | if (retry_tx) { | ||
1733 | int i; | ||
1734 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
1735 | if (ATH_TXQ_SETUP(sc, i)) { | ||
1736 | spin_lock_bh(&sc->tx.txq[i].axq_lock); | ||
1737 | ath_txq_schedule(sc, &sc->tx.txq[i]); | ||
1738 | spin_unlock_bh(&sc->tx.txq[i].axq_lock); | ||
1739 | } | ||
1740 | } | ||
1741 | } | ||
1742 | |||
1743 | return r; | ||
1744 | } | ||
1745 | |||
1746 | /* | ||
1747 | * This function will allocate both the DMA descriptor structure, and the | ||
1748 | * buffers it contains. These are used to contain the descriptors used | ||
1749 | * by the system. | ||
1750 | */ | ||
1751 | int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | ||
1752 | struct list_head *head, const char *name, | ||
1753 | int nbuf, int ndesc) | ||
1754 | { | ||
1755 | #define DS2PHYS(_dd, _ds) \ | ||
1756 | ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) | ||
1757 | #define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) | ||
1758 | #define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) | ||
1759 | |||
1760 | struct ath_desc *ds; | ||
1761 | struct ath_buf *bf; | ||
1762 | int i, bsize, error; | ||
1763 | |||
1764 | DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", | ||
1765 | name, nbuf, ndesc); | ||
1766 | |||
1767 | INIT_LIST_HEAD(head); | ||
1768 | /* ath_desc must be a multiple of DWORDs */ | ||
1769 | if ((sizeof(struct ath_desc) % 4) != 0) { | ||
1770 | DPRINTF(sc, ATH_DBG_FATAL, "ath_desc not DWORD aligned\n"); | ||
1771 | ASSERT((sizeof(struct ath_desc) % 4) == 0); | ||
1772 | error = -ENOMEM; | ||
1773 | goto fail; | ||
1774 | } | ||
1775 | |||
1776 | dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc; | ||
1777 | |||
1778 | /* | ||
1779 | * Need additional DMA memory because we can't use | ||
1780 | * descriptors that cross the 4K page boundary. Assume | ||
1781 | * one skipped descriptor per 4K page. | ||
1782 | */ | ||
1783 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) { | ||
1784 | u32 ndesc_skipped = | ||
1785 | ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len); | ||
1786 | u32 dma_len; | ||
1787 | |||
1788 | while (ndesc_skipped) { | ||
1789 | dma_len = ndesc_skipped * sizeof(struct ath_desc); | ||
1790 | dd->dd_desc_len += dma_len; | ||
1791 | |||
1792 | ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len); | ||
1793 | }; | ||
1794 | } | ||
1795 | |||
1796 | /* allocate descriptors */ | ||
1797 | dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len, | ||
1798 | &dd->dd_desc_paddr, GFP_KERNEL); | ||
1799 | if (dd->dd_desc == NULL) { | ||
1800 | error = -ENOMEM; | ||
1801 | goto fail; | ||
1802 | } | ||
1803 | ds = dd->dd_desc; | ||
1804 | DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", | ||
1805 | name, ds, (u32) dd->dd_desc_len, | ||
1806 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); | ||
1807 | |||
1808 | /* allocate buffers */ | ||
1809 | bsize = sizeof(struct ath_buf) * nbuf; | ||
1810 | bf = kzalloc(bsize, GFP_KERNEL); | ||
1811 | if (bf == NULL) { | ||
1812 | error = -ENOMEM; | ||
1813 | goto fail2; | ||
1814 | } | ||
1815 | dd->dd_bufptr = bf; | ||
1816 | |||
1817 | for (i = 0; i < nbuf; i++, bf++, ds += ndesc) { | ||
1818 | bf->bf_desc = ds; | ||
1819 | bf->bf_daddr = DS2PHYS(dd, ds); | ||
1820 | |||
1821 | if (!(sc->sc_ah->caps.hw_caps & | ||
1822 | ATH9K_HW_CAP_4KB_SPLITTRANS)) { | ||
1823 | /* | ||
1824 | * Skip descriptor addresses which can cause 4KB | ||
1825 | * boundary crossing (addr + length) with a 32 dword | ||
1826 | * descriptor fetch. | ||
1827 | */ | ||
1828 | while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { | ||
1829 | ASSERT((caddr_t) bf->bf_desc < | ||
1830 | ((caddr_t) dd->dd_desc + | ||
1831 | dd->dd_desc_len)); | ||
1832 | |||
1833 | ds += ndesc; | ||
1834 | bf->bf_desc = ds; | ||
1835 | bf->bf_daddr = DS2PHYS(dd, ds); | ||
1836 | } | ||
1837 | } | ||
1838 | list_add_tail(&bf->list, head); | ||
1839 | } | ||
1840 | return 0; | ||
1841 | fail2: | ||
1842 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
1843 | dd->dd_desc_paddr); | ||
1844 | fail: | ||
1845 | memset(dd, 0, sizeof(*dd)); | ||
1846 | return error; | ||
1847 | #undef ATH_DESC_4KB_BOUND_CHECK | ||
1848 | #undef ATH_DESC_4KB_BOUND_NUM_SKIPPED | ||
1849 | #undef DS2PHYS | ||
1850 | } | ||
1851 | |||
1852 | void ath_descdma_cleanup(struct ath_softc *sc, | ||
1853 | struct ath_descdma *dd, | ||
1854 | struct list_head *head) | ||
1855 | { | ||
1856 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
1857 | dd->dd_desc_paddr); | ||
1858 | |||
1859 | INIT_LIST_HEAD(head); | ||
1860 | kfree(dd->dd_bufptr); | ||
1861 | memset(dd, 0, sizeof(*dd)); | ||
1862 | } | ||
1863 | |||
1864 | int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) | ||
1865 | { | ||
1866 | int qnum; | ||
1867 | |||
1868 | switch (queue) { | ||
1869 | case 0: | ||
1870 | qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO]; | ||
1871 | break; | ||
1872 | case 1: | ||
1873 | qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI]; | ||
1874 | break; | ||
1875 | case 2: | ||
1876 | qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE]; | ||
1877 | break; | ||
1878 | case 3: | ||
1879 | qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK]; | ||
1880 | break; | ||
1881 | default: | ||
1882 | qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE]; | ||
1883 | break; | ||
1884 | } | ||
1885 | |||
1886 | return qnum; | ||
1887 | } | ||
1888 | |||
1889 | int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc) | ||
1890 | { | ||
1891 | int qnum; | ||
1892 | |||
1893 | switch (queue) { | ||
1894 | case ATH9K_WME_AC_VO: | ||
1895 | qnum = 0; | ||
1896 | break; | ||
1897 | case ATH9K_WME_AC_VI: | ||
1898 | qnum = 1; | ||
1899 | break; | ||
1900 | case ATH9K_WME_AC_BE: | ||
1901 | qnum = 2; | ||
1902 | break; | ||
1903 | case ATH9K_WME_AC_BK: | ||
1904 | qnum = 3; | ||
1905 | break; | ||
1906 | default: | ||
1907 | qnum = -1; | ||
1908 | break; | ||
1909 | } | ||
1910 | |||
1911 | return qnum; | ||
1912 | } | ||
1913 | |||
1914 | /* XXX: Remove me once we don't depend on ath9k_channel for all | ||
1915 | * this redundant data */ | ||
1916 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, | ||
1917 | struct ath9k_channel *ichan) | ||
1918 | { | ||
1919 | struct ieee80211_channel *chan = hw->conf.channel; | ||
1920 | struct ieee80211_conf *conf = &hw->conf; | ||
1921 | |||
1922 | ichan->channel = chan->center_freq; | ||
1923 | ichan->chan = chan; | ||
1924 | |||
1925 | if (chan->band == IEEE80211_BAND_2GHZ) { | ||
1926 | ichan->chanmode = CHANNEL_G; | ||
1927 | ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM; | ||
1928 | } else { | ||
1929 | ichan->chanmode = CHANNEL_A; | ||
1930 | ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; | ||
1931 | } | ||
1932 | |||
1933 | sc->tx_chan_width = ATH9K_HT_MACMODE_20; | ||
1934 | |||
1935 | if (conf_is_ht(conf)) { | ||
1936 | if (conf_is_ht40(conf)) | ||
1937 | sc->tx_chan_width = ATH9K_HT_MACMODE_2040; | ||
1938 | |||
1939 | ichan->chanmode = ath_get_extchanmode(sc, chan, | ||
1940 | conf->channel_type); | ||
1941 | } | ||
1942 | } | ||
1943 | |||
1944 | /**********************/ | ||
1945 | /* mac80211 callbacks */ | ||
1946 | /**********************/ | ||
1947 | |||
1948 | static int ath9k_start(struct ieee80211_hw *hw) | ||
1949 | { | ||
1950 | struct ath_wiphy *aphy = hw->priv; | ||
1951 | struct ath_softc *sc = aphy->sc; | ||
1952 | struct ieee80211_channel *curchan = hw->conf.channel; | ||
1953 | struct ath9k_channel *init_channel; | ||
1954 | int r, pos; | ||
1955 | |||
1956 | DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " | ||
1957 | "initial channel: %d MHz\n", curchan->center_freq); | ||
1958 | |||
1959 | mutex_lock(&sc->mutex); | ||
1960 | |||
1961 | if (ath9k_wiphy_started(sc)) { | ||
1962 | if (sc->chan_idx == curchan->hw_value) { | ||
1963 | /* | ||
1964 | * Already on the operational channel, the new wiphy | ||
1965 | * can be marked active. | ||
1966 | */ | ||
1967 | aphy->state = ATH_WIPHY_ACTIVE; | ||
1968 | ieee80211_wake_queues(hw); | ||
1969 | } else { | ||
1970 | /* | ||
1971 | * Another wiphy is on another channel, start the new | ||
1972 | * wiphy in paused state. | ||
1973 | */ | ||
1974 | aphy->state = ATH_WIPHY_PAUSED; | ||
1975 | ieee80211_stop_queues(hw); | ||
1976 | } | ||
1977 | mutex_unlock(&sc->mutex); | ||
1978 | return 0; | ||
1979 | } | ||
1980 | aphy->state = ATH_WIPHY_ACTIVE; | ||
1981 | |||
1982 | /* setup initial channel */ | ||
1983 | |||
1984 | pos = curchan->hw_value; | ||
1985 | |||
1986 | sc->chan_idx = pos; | ||
1987 | init_channel = &sc->sc_ah->channels[pos]; | ||
1988 | ath9k_update_ichannel(sc, hw, init_channel); | ||
1989 | |||
1990 | /* Reset SERDES registers */ | ||
1991 | ath9k_hw_configpcipowersave(sc->sc_ah, 0); | ||
1992 | |||
1993 | /* | ||
1994 | * The basic interface to setting the hardware in a good | ||
1995 | * state is ``reset''. On return the hardware is known to | ||
1996 | * be powered up and with interrupts disabled. This must | ||
1997 | * be followed by initialization of the appropriate bits | ||
1998 | * and then setup of the interrupt mask. | ||
1999 | */ | ||
2000 | spin_lock_bh(&sc->sc_resetlock); | ||
2001 | r = ath9k_hw_reset(sc->sc_ah, init_channel, false); | ||
2002 | if (r) { | ||
2003 | DPRINTF(sc, ATH_DBG_FATAL, | ||
2004 | "Unable to reset hardware; reset status %u " | ||
2005 | "(freq %u MHz)\n", r, | ||
2006 | curchan->center_freq); | ||
2007 | spin_unlock_bh(&sc->sc_resetlock); | ||
2008 | goto mutex_unlock; | ||
2009 | } | ||
2010 | spin_unlock_bh(&sc->sc_resetlock); | ||
2011 | |||
2012 | /* | ||
2013 | * This is needed only to setup initial state | ||
2014 | * but it's best done after a reset. | ||
2015 | */ | ||
2016 | ath_update_txpow(sc); | ||
2017 | |||
2018 | /* | ||
2019 | * Setup the hardware after reset: | ||
2020 | * The receive engine is set going. | ||
2021 | * Frame transmit is handled entirely | ||
2022 | * in the frame output path; there's nothing to do | ||
2023 | * here except setup the interrupt mask. | ||
2024 | */ | ||
2025 | if (ath_startrecv(sc) != 0) { | ||
2026 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n"); | ||
2027 | r = -EIO; | ||
2028 | goto mutex_unlock; | ||
2029 | } | ||
2030 | |||
2031 | /* Setup our intr mask. */ | ||
2032 | sc->imask = ATH9K_INT_RX | ATH9K_INT_TX | ||
2033 | | ATH9K_INT_RXEOL | ATH9K_INT_RXORN | ||
2034 | | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL; | ||
2035 | |||
2036 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_GTT) | ||
2037 | sc->imask |= ATH9K_INT_GTT; | ||
2038 | |||
2039 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) | ||
2040 | sc->imask |= ATH9K_INT_CST; | ||
2041 | |||
2042 | ath_cache_conf_rate(sc, &hw->conf); | ||
2043 | |||
2044 | sc->sc_flags &= ~SC_OP_INVALID; | ||
2045 | |||
2046 | /* Disable BMISS interrupt when we're not associated */ | ||
2047 | sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); | ||
2048 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | ||
2049 | |||
2050 | ieee80211_wake_queues(hw); | ||
2051 | |||
2052 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
2053 | r = ath_start_rfkill_poll(sc); | ||
2054 | #endif | ||
2055 | |||
2056 | mutex_unlock: | ||
2057 | mutex_unlock(&sc->mutex); | ||
2058 | |||
2059 | return r; | ||
2060 | } | ||
2061 | |||
2062 | static int ath9k_tx(struct ieee80211_hw *hw, | ||
2063 | struct sk_buff *skb) | ||
2064 | { | ||
2065 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
2066 | struct ath_wiphy *aphy = hw->priv; | ||
2067 | struct ath_softc *sc = aphy->sc; | ||
2068 | struct ath_tx_control txctl; | ||
2069 | int hdrlen, padsize; | ||
2070 | |||
2071 | if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { | ||
2072 | printk(KERN_DEBUG "ath9k: %s: TX in unexpected wiphy state " | ||
2073 | "%d\n", wiphy_name(hw->wiphy), aphy->state); | ||
2074 | goto exit; | ||
2075 | } | ||
2076 | |||
2077 | memset(&txctl, 0, sizeof(struct ath_tx_control)); | ||
2078 | |||
2079 | /* | ||
2080 | * As a temporary workaround, assign seq# here; this will likely need | ||
2081 | * to be cleaned up to work better with Beacon transmission and virtual | ||
2082 | * BSSes. | ||
2083 | */ | ||
2084 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
2085 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
2086 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | ||
2087 | sc->tx.seq_no += 0x10; | ||
2088 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
2089 | hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); | ||
2090 | } | ||
2091 | |||
2092 | /* Add the padding after the header if this is not already done */ | ||
2093 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
2094 | if (hdrlen & 3) { | ||
2095 | padsize = hdrlen % 4; | ||
2096 | if (skb_headroom(skb) < padsize) | ||
2097 | return -1; | ||
2098 | skb_push(skb, padsize); | ||
2099 | memmove(skb->data, skb->data + padsize, hdrlen); | ||
2100 | } | ||
2101 | |||
2102 | /* Check if a tx queue is available */ | ||
2103 | |||
2104 | txctl.txq = ath_test_get_txq(sc, skb); | ||
2105 | if (!txctl.txq) | ||
2106 | goto exit; | ||
2107 | |||
2108 | DPRINTF(sc, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); | ||
2109 | |||
2110 | if (ath_tx_start(hw, skb, &txctl) != 0) { | ||
2111 | DPRINTF(sc, ATH_DBG_XMIT, "TX failed\n"); | ||
2112 | goto exit; | ||
2113 | } | ||
2114 | |||
2115 | return 0; | ||
2116 | exit: | ||
2117 | dev_kfree_skb_any(skb); | ||
2118 | return 0; | ||
2119 | } | ||
2120 | |||
2121 | static void ath9k_stop(struct ieee80211_hw *hw) | ||
2122 | { | ||
2123 | struct ath_wiphy *aphy = hw->priv; | ||
2124 | struct ath_softc *sc = aphy->sc; | ||
2125 | |||
2126 | aphy->state = ATH_WIPHY_INACTIVE; | ||
2127 | |||
2128 | if (sc->sc_flags & SC_OP_INVALID) { | ||
2129 | DPRINTF(sc, ATH_DBG_ANY, "Device not present\n"); | ||
2130 | return; | ||
2131 | } | ||
2132 | |||
2133 | mutex_lock(&sc->mutex); | ||
2134 | |||
2135 | ieee80211_stop_queues(hw); | ||
2136 | |||
2137 | if (ath9k_wiphy_started(sc)) { | ||
2138 | mutex_unlock(&sc->mutex); | ||
2139 | return; /* another wiphy still in use */ | ||
2140 | } | ||
2141 | |||
2142 | /* make sure h/w will not generate any interrupt | ||
2143 | * before setting the invalid flag. */ | ||
2144 | ath9k_hw_set_interrupts(sc->sc_ah, 0); | ||
2145 | |||
2146 | if (!(sc->sc_flags & SC_OP_INVALID)) { | ||
2147 | ath_drain_all_txq(sc, false); | ||
2148 | ath_stoprecv(sc); | ||
2149 | ath9k_hw_phy_disable(sc->sc_ah); | ||
2150 | } else | ||
2151 | sc->rx.rxlink = NULL; | ||
2152 | |||
2153 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
2154 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
2155 | cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); | ||
2156 | #endif | ||
2157 | /* disable HAL and put h/w to sleep */ | ||
2158 | ath9k_hw_disable(sc->sc_ah); | ||
2159 | ath9k_hw_configpcipowersave(sc->sc_ah, 1); | ||
2160 | |||
2161 | sc->sc_flags |= SC_OP_INVALID; | ||
2162 | |||
2163 | mutex_unlock(&sc->mutex); | ||
2164 | |||
2165 | DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n"); | ||
2166 | } | ||
2167 | |||
2168 | static int ath9k_add_interface(struct ieee80211_hw *hw, | ||
2169 | struct ieee80211_if_init_conf *conf) | ||
2170 | { | ||
2171 | struct ath_wiphy *aphy = hw->priv; | ||
2172 | struct ath_softc *sc = aphy->sc; | ||
2173 | struct ath_vif *avp = (void *)conf->vif->drv_priv; | ||
2174 | enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; | ||
2175 | int ret = 0; | ||
2176 | |||
2177 | mutex_lock(&sc->mutex); | ||
2178 | |||
2179 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) && | ||
2180 | sc->nvifs > 0) { | ||
2181 | ret = -ENOBUFS; | ||
2182 | goto out; | ||
2183 | } | ||
2184 | |||
2185 | switch (conf->type) { | ||
2186 | case NL80211_IFTYPE_STATION: | ||
2187 | ic_opmode = NL80211_IFTYPE_STATION; | ||
2188 | break; | ||
2189 | case NL80211_IFTYPE_ADHOC: | ||
2190 | case NL80211_IFTYPE_AP: | ||
2191 | case NL80211_IFTYPE_MESH_POINT: | ||
2192 | if (sc->nbcnvifs >= ATH_BCBUF) { | ||
2193 | ret = -ENOBUFS; | ||
2194 | goto out; | ||
2195 | } | ||
2196 | ic_opmode = conf->type; | ||
2197 | break; | ||
2198 | default: | ||
2199 | DPRINTF(sc, ATH_DBG_FATAL, | ||
2200 | "Interface type %d not yet supported\n", conf->type); | ||
2201 | ret = -EOPNOTSUPP; | ||
2202 | goto out; | ||
2203 | } | ||
2204 | |||
2205 | DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VIF of type: %d\n", ic_opmode); | ||
2206 | |||
2207 | /* Set the VIF opmode */ | ||
2208 | avp->av_opmode = ic_opmode; | ||
2209 | avp->av_bslot = -1; | ||
2210 | |||
2211 | sc->nvifs++; | ||
2212 | |||
2213 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | ||
2214 | ath9k_set_bssid_mask(hw); | ||
2215 | |||
2216 | if (sc->nvifs > 1) | ||
2217 | goto out; /* skip global settings for secondary vif */ | ||
2218 | |||
2219 | if (ic_opmode == NL80211_IFTYPE_AP) { | ||
2220 | ath9k_hw_set_tsfadjust(sc->sc_ah, 1); | ||
2221 | sc->sc_flags |= SC_OP_TSF_RESET; | ||
2222 | } | ||
2223 | |||
2224 | /* Set the device opmode */ | ||
2225 | sc->sc_ah->opmode = ic_opmode; | ||
2226 | |||
2227 | /* | ||
2228 | * Enable MIB interrupts when there are hardware phy counters. | ||
2229 | * Note we only do this (at the moment) for station mode. | ||
2230 | */ | ||
2231 | if ((conf->type == NL80211_IFTYPE_STATION) || | ||
2232 | (conf->type == NL80211_IFTYPE_ADHOC) || | ||
2233 | (conf->type == NL80211_IFTYPE_MESH_POINT)) { | ||
2234 | if (ath9k_hw_phycounters(sc->sc_ah)) | ||
2235 | sc->imask |= ATH9K_INT_MIB; | ||
2236 | sc->imask |= ATH9K_INT_TSFOOR; | ||
2237 | } | ||
2238 | |||
2239 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | ||
2240 | |||
2241 | if (conf->type == NL80211_IFTYPE_AP) { | ||
2242 | /* TODO: is this a suitable place to start ANI for AP mode? */ | ||
2243 | /* Start ANI */ | ||
2244 | mod_timer(&sc->ani.timer, | ||
2245 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); | ||
2246 | } | ||
2247 | |||
2248 | out: | ||
2249 | mutex_unlock(&sc->mutex); | ||
2250 | return ret; | ||
2251 | } | ||
2252 | |||
2253 | static void ath9k_remove_interface(struct ieee80211_hw *hw, | ||
2254 | struct ieee80211_if_init_conf *conf) | ||
2255 | { | ||
2256 | struct ath_wiphy *aphy = hw->priv; | ||
2257 | struct ath_softc *sc = aphy->sc; | ||
2258 | struct ath_vif *avp = (void *)conf->vif->drv_priv; | ||
2259 | int i; | ||
2260 | |||
2261 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n"); | ||
2262 | |||
2263 | mutex_lock(&sc->mutex); | ||
2264 | |||
2265 | /* Stop ANI */ | ||
2266 | del_timer_sync(&sc->ani.timer); | ||
2267 | |||
2268 | /* Reclaim beacon resources */ | ||
2269 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || | ||
2270 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || | ||
2271 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { | ||
2272 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
2273 | ath_beacon_return(sc, avp); | ||
2274 | } | ||
2275 | |||
2276 | sc->sc_flags &= ~SC_OP_BEACONS; | ||
2277 | |||
2278 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | ||
2279 | if (sc->beacon.bslot[i] == conf->vif) { | ||
2280 | printk(KERN_DEBUG "%s: vif had allocated beacon " | ||
2281 | "slot\n", __func__); | ||
2282 | sc->beacon.bslot[i] = NULL; | ||
2283 | sc->beacon.bslot_aphy[i] = NULL; | ||
2284 | } | ||
2285 | } | ||
2286 | |||
2287 | sc->nvifs--; | ||
2288 | |||
2289 | mutex_unlock(&sc->mutex); | ||
2290 | } | ||
2291 | |||
2292 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | ||
2293 | { | ||
2294 | struct ath_wiphy *aphy = hw->priv; | ||
2295 | struct ath_softc *sc = aphy->sc; | ||
2296 | struct ieee80211_conf *conf = &hw->conf; | ||
2297 | struct ath_hw *ah = sc->sc_ah; | ||
2298 | |||
2299 | mutex_lock(&sc->mutex); | ||
2300 | |||
2301 | if (changed & IEEE80211_CONF_CHANGE_PS) { | ||
2302 | if (conf->flags & IEEE80211_CONF_PS) { | ||
2303 | if (!(ah->caps.hw_caps & | ||
2304 | ATH9K_HW_CAP_AUTOSLEEP)) { | ||
2305 | if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { | ||
2306 | sc->imask |= ATH9K_INT_TIM_TIMER; | ||
2307 | ath9k_hw_set_interrupts(sc->sc_ah, | ||
2308 | sc->imask); | ||
2309 | } | ||
2310 | ath9k_hw_setrxabort(sc->sc_ah, 1); | ||
2311 | } | ||
2312 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); | ||
2313 | } else { | ||
2314 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); | ||
2315 | if (!(ah->caps.hw_caps & | ||
2316 | ATH9K_HW_CAP_AUTOSLEEP)) { | ||
2317 | ath9k_hw_setrxabort(sc->sc_ah, 0); | ||
2318 | sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; | ||
2319 | if (sc->imask & ATH9K_INT_TIM_TIMER) { | ||
2320 | sc->imask &= ~ATH9K_INT_TIM_TIMER; | ||
2321 | ath9k_hw_set_interrupts(sc->sc_ah, | ||
2322 | sc->imask); | ||
2323 | } | ||
2324 | } | ||
2325 | } | ||
2326 | } | ||
2327 | |||
2328 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | ||
2329 | struct ieee80211_channel *curchan = hw->conf.channel; | ||
2330 | int pos = curchan->hw_value; | ||
2331 | |||
2332 | aphy->chan_idx = pos; | ||
2333 | aphy->chan_is_ht = conf_is_ht(conf); | ||
2334 | |||
2335 | if (aphy->state == ATH_WIPHY_SCAN || | ||
2336 | aphy->state == ATH_WIPHY_ACTIVE) | ||
2337 | ath9k_wiphy_pause_all_forced(sc, aphy); | ||
2338 | else { | ||
2339 | /* | ||
2340 | * Do not change operational channel based on a paused | ||
2341 | * wiphy changes. | ||
2342 | */ | ||
2343 | goto skip_chan_change; | ||
2344 | } | ||
2345 | |||
2346 | DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n", | ||
2347 | curchan->center_freq); | ||
2348 | |||
2349 | /* XXX: remove me eventualy */ | ||
2350 | ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]); | ||
2351 | |||
2352 | ath_update_chainmask(sc, conf_is_ht(conf)); | ||
2353 | |||
2354 | if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { | ||
2355 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); | ||
2356 | mutex_unlock(&sc->mutex); | ||
2357 | return -EINVAL; | ||
2358 | } | ||
2359 | } | ||
2360 | |||
2361 | skip_chan_change: | ||
2362 | if (changed & IEEE80211_CONF_CHANGE_POWER) | ||
2363 | sc->config.txpowlimit = 2 * conf->power_level; | ||
2364 | |||
2365 | /* | ||
2366 | * The HW TSF has to be reset when the beacon interval changes. | ||
2367 | * We set the flag here, and ath_beacon_config_ap() would take this | ||
2368 | * into account when it gets called through the subsequent | ||
2369 | * config_interface() call - with IFCC_BEACON in the changed field. | ||
2370 | */ | ||
2371 | |||
2372 | if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) | ||
2373 | sc->sc_flags |= SC_OP_TSF_RESET; | ||
2374 | |||
2375 | mutex_unlock(&sc->mutex); | ||
2376 | |||
2377 | return 0; | ||
2378 | } | ||
2379 | |||
2380 | static int ath9k_config_interface(struct ieee80211_hw *hw, | ||
2381 | struct ieee80211_vif *vif, | ||
2382 | struct ieee80211_if_conf *conf) | ||
2383 | { | ||
2384 | struct ath_wiphy *aphy = hw->priv; | ||
2385 | struct ath_softc *sc = aphy->sc; | ||
2386 | struct ath_hw *ah = sc->sc_ah; | ||
2387 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
2388 | u32 rfilt = 0; | ||
2389 | int error, i; | ||
2390 | |||
2391 | mutex_lock(&sc->mutex); | ||
2392 | |||
2393 | /* TODO: Need to decide which hw opmode to use for multi-interface | ||
2394 | * cases */ | ||
2395 | if (vif->type == NL80211_IFTYPE_AP && | ||
2396 | ah->opmode != NL80211_IFTYPE_AP) { | ||
2397 | ah->opmode = NL80211_IFTYPE_STATION; | ||
2398 | ath9k_hw_setopmode(ah); | ||
2399 | memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN); | ||
2400 | sc->curaid = 0; | ||
2401 | ath9k_hw_write_associd(sc); | ||
2402 | /* Request full reset to get hw opmode changed properly */ | ||
2403 | sc->sc_flags |= SC_OP_FULL_RESET; | ||
2404 | } | ||
2405 | |||
2406 | if ((conf->changed & IEEE80211_IFCC_BSSID) && | ||
2407 | !is_zero_ether_addr(conf->bssid)) { | ||
2408 | switch (vif->type) { | ||
2409 | case NL80211_IFTYPE_STATION: | ||
2410 | case NL80211_IFTYPE_ADHOC: | ||
2411 | case NL80211_IFTYPE_MESH_POINT: | ||
2412 | /* Set BSSID */ | ||
2413 | memcpy(sc->curbssid, conf->bssid, ETH_ALEN); | ||
2414 | memcpy(avp->bssid, conf->bssid, ETH_ALEN); | ||
2415 | sc->curaid = 0; | ||
2416 | ath9k_hw_write_associd(sc); | ||
2417 | |||
2418 | /* Set aggregation protection mode parameters */ | ||
2419 | sc->config.ath_aggr_prot = 0; | ||
2420 | |||
2421 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
2422 | "RX filter 0x%x bssid %pM aid 0x%x\n", | ||
2423 | rfilt, sc->curbssid, sc->curaid); | ||
2424 | |||
2425 | /* need to reconfigure the beacon */ | ||
2426 | sc->sc_flags &= ~SC_OP_BEACONS ; | ||
2427 | |||
2428 | break; | ||
2429 | default: | ||
2430 | break; | ||
2431 | } | ||
2432 | } | ||
2433 | |||
2434 | if ((vif->type == NL80211_IFTYPE_ADHOC) || | ||
2435 | (vif->type == NL80211_IFTYPE_AP) || | ||
2436 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { | ||
2437 | if ((conf->changed & IEEE80211_IFCC_BEACON) || | ||
2438 | (conf->changed & IEEE80211_IFCC_BEACON_ENABLED && | ||
2439 | conf->enable_beacon)) { | ||
2440 | /* | ||
2441 | * Allocate and setup the beacon frame. | ||
2442 | * | ||
2443 | * Stop any previous beacon DMA. This may be | ||
2444 | * necessary, for example, when an ibss merge | ||
2445 | * causes reconfiguration; we may be called | ||
2446 | * with beacon transmission active. | ||
2447 | */ | ||
2448 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
2449 | |||
2450 | error = ath_beacon_alloc(aphy, vif); | ||
2451 | if (error != 0) { | ||
2452 | mutex_unlock(&sc->mutex); | ||
2453 | return error; | ||
2454 | } | ||
2455 | |||
2456 | ath_beacon_config(sc, vif); | ||
2457 | } | ||
2458 | } | ||
2459 | |||
2460 | /* Check for WLAN_CAPABILITY_PRIVACY ? */ | ||
2461 | if ((avp->av_opmode != NL80211_IFTYPE_STATION)) { | ||
2462 | for (i = 0; i < IEEE80211_WEP_NKID; i++) | ||
2463 | if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i)) | ||
2464 | ath9k_hw_keysetmac(sc->sc_ah, | ||
2465 | (u16)i, | ||
2466 | sc->curbssid); | ||
2467 | } | ||
2468 | |||
2469 | /* Only legacy IBSS for now */ | ||
2470 | if (vif->type == NL80211_IFTYPE_ADHOC) | ||
2471 | ath_update_chainmask(sc, 0); | ||
2472 | |||
2473 | mutex_unlock(&sc->mutex); | ||
2474 | |||
2475 | return 0; | ||
2476 | } | ||
2477 | |||
2478 | #define SUPPORTED_FILTERS \ | ||
2479 | (FIF_PROMISC_IN_BSS | \ | ||
2480 | FIF_ALLMULTI | \ | ||
2481 | FIF_CONTROL | \ | ||
2482 | FIF_OTHER_BSS | \ | ||
2483 | FIF_BCN_PRBRESP_PROMISC | \ | ||
2484 | FIF_FCSFAIL) | ||
2485 | |||
2486 | /* FIXME: sc->sc_full_reset ? */ | ||
2487 | static void ath9k_configure_filter(struct ieee80211_hw *hw, | ||
2488 | unsigned int changed_flags, | ||
2489 | unsigned int *total_flags, | ||
2490 | int mc_count, | ||
2491 | struct dev_mc_list *mclist) | ||
2492 | { | ||
2493 | struct ath_wiphy *aphy = hw->priv; | ||
2494 | struct ath_softc *sc = aphy->sc; | ||
2495 | u32 rfilt; | ||
2496 | |||
2497 | changed_flags &= SUPPORTED_FILTERS; | ||
2498 | *total_flags &= SUPPORTED_FILTERS; | ||
2499 | |||
2500 | sc->rx.rxfilter = *total_flags; | ||
2501 | rfilt = ath_calcrxfilter(sc); | ||
2502 | ath9k_hw_setrxfilter(sc->sc_ah, rfilt); | ||
2503 | |||
2504 | DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter); | ||
2505 | } | ||
2506 | |||
2507 | static void ath9k_sta_notify(struct ieee80211_hw *hw, | ||
2508 | struct ieee80211_vif *vif, | ||
2509 | enum sta_notify_cmd cmd, | ||
2510 | struct ieee80211_sta *sta) | ||
2511 | { | ||
2512 | struct ath_wiphy *aphy = hw->priv; | ||
2513 | struct ath_softc *sc = aphy->sc; | ||
2514 | |||
2515 | switch (cmd) { | ||
2516 | case STA_NOTIFY_ADD: | ||
2517 | ath_node_attach(sc, sta); | ||
2518 | break; | ||
2519 | case STA_NOTIFY_REMOVE: | ||
2520 | ath_node_detach(sc, sta); | ||
2521 | break; | ||
2522 | default: | ||
2523 | break; | ||
2524 | } | ||
2525 | } | ||
2526 | |||
2527 | static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, | ||
2528 | const struct ieee80211_tx_queue_params *params) | ||
2529 | { | ||
2530 | struct ath_wiphy *aphy = hw->priv; | ||
2531 | struct ath_softc *sc = aphy->sc; | ||
2532 | struct ath9k_tx_queue_info qi; | ||
2533 | int ret = 0, qnum; | ||
2534 | |||
2535 | if (queue >= WME_NUM_AC) | ||
2536 | return 0; | ||
2537 | |||
2538 | mutex_lock(&sc->mutex); | ||
2539 | |||
2540 | memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); | ||
2541 | |||
2542 | qi.tqi_aifs = params->aifs; | ||
2543 | qi.tqi_cwmin = params->cw_min; | ||
2544 | qi.tqi_cwmax = params->cw_max; | ||
2545 | qi.tqi_burstTime = params->txop; | ||
2546 | qnum = ath_get_hal_qnum(queue, sc); | ||
2547 | |||
2548 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
2549 | "Configure tx [queue/halq] [%d/%d], " | ||
2550 | "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", | ||
2551 | queue, qnum, params->aifs, params->cw_min, | ||
2552 | params->cw_max, params->txop); | ||
2553 | |||
2554 | ret = ath_txq_update(sc, qnum, &qi); | ||
2555 | if (ret) | ||
2556 | DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n"); | ||
2557 | |||
2558 | mutex_unlock(&sc->mutex); | ||
2559 | |||
2560 | return ret; | ||
2561 | } | ||
2562 | |||
2563 | static int ath9k_set_key(struct ieee80211_hw *hw, | ||
2564 | enum set_key_cmd cmd, | ||
2565 | struct ieee80211_vif *vif, | ||
2566 | struct ieee80211_sta *sta, | ||
2567 | struct ieee80211_key_conf *key) | ||
2568 | { | ||
2569 | struct ath_wiphy *aphy = hw->priv; | ||
2570 | struct ath_softc *sc = aphy->sc; | ||
2571 | int ret = 0; | ||
2572 | |||
2573 | if (modparam_nohwcrypt) | ||
2574 | return -ENOSPC; | ||
2575 | |||
2576 | mutex_lock(&sc->mutex); | ||
2577 | ath9k_ps_wakeup(sc); | ||
2578 | DPRINTF(sc, ATH_DBG_CONFIG, "Set HW Key\n"); | ||
2579 | |||
2580 | switch (cmd) { | ||
2581 | case SET_KEY: | ||
2582 | ret = ath_key_config(sc, vif, sta, key); | ||
2583 | if (ret >= 0) { | ||
2584 | key->hw_key_idx = ret; | ||
2585 | /* push IV and Michael MIC generation to stack */ | ||
2586 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
2587 | if (key->alg == ALG_TKIP) | ||
2588 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
2589 | if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP) | ||
2590 | key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; | ||
2591 | ret = 0; | ||
2592 | } | ||
2593 | break; | ||
2594 | case DISABLE_KEY: | ||
2595 | ath_key_delete(sc, key); | ||
2596 | break; | ||
2597 | default: | ||
2598 | ret = -EINVAL; | ||
2599 | } | ||
2600 | |||
2601 | ath9k_ps_restore(sc); | ||
2602 | mutex_unlock(&sc->mutex); | ||
2603 | |||
2604 | return ret; | ||
2605 | } | ||
2606 | |||
2607 | static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | ||
2608 | struct ieee80211_vif *vif, | ||
2609 | struct ieee80211_bss_conf *bss_conf, | ||
2610 | u32 changed) | ||
2611 | { | ||
2612 | struct ath_wiphy *aphy = hw->priv; | ||
2613 | struct ath_softc *sc = aphy->sc; | ||
2614 | |||
2615 | mutex_lock(&sc->mutex); | ||
2616 | |||
2617 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | ||
2618 | DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", | ||
2619 | bss_conf->use_short_preamble); | ||
2620 | if (bss_conf->use_short_preamble) | ||
2621 | sc->sc_flags |= SC_OP_PREAMBLE_SHORT; | ||
2622 | else | ||
2623 | sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT; | ||
2624 | } | ||
2625 | |||
2626 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { | ||
2627 | DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", | ||
2628 | bss_conf->use_cts_prot); | ||
2629 | if (bss_conf->use_cts_prot && | ||
2630 | hw->conf.channel->band != IEEE80211_BAND_5GHZ) | ||
2631 | sc->sc_flags |= SC_OP_PROTECT_ENABLE; | ||
2632 | else | ||
2633 | sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; | ||
2634 | } | ||
2635 | |||
2636 | if (changed & BSS_CHANGED_ASSOC) { | ||
2637 | DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", | ||
2638 | bss_conf->assoc); | ||
2639 | ath9k_bss_assoc_info(sc, vif, bss_conf); | ||
2640 | } | ||
2641 | |||
2642 | mutex_unlock(&sc->mutex); | ||
2643 | } | ||
2644 | |||
2645 | static u64 ath9k_get_tsf(struct ieee80211_hw *hw) | ||
2646 | { | ||
2647 | u64 tsf; | ||
2648 | struct ath_wiphy *aphy = hw->priv; | ||
2649 | struct ath_softc *sc = aphy->sc; | ||
2650 | |||
2651 | mutex_lock(&sc->mutex); | ||
2652 | tsf = ath9k_hw_gettsf64(sc->sc_ah); | ||
2653 | mutex_unlock(&sc->mutex); | ||
2654 | |||
2655 | return tsf; | ||
2656 | } | ||
2657 | |||
2658 | static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf) | ||
2659 | { | ||
2660 | struct ath_wiphy *aphy = hw->priv; | ||
2661 | struct ath_softc *sc = aphy->sc; | ||
2662 | |||
2663 | mutex_lock(&sc->mutex); | ||
2664 | ath9k_hw_settsf64(sc->sc_ah, tsf); | ||
2665 | mutex_unlock(&sc->mutex); | ||
2666 | } | ||
2667 | |||
2668 | static void ath9k_reset_tsf(struct ieee80211_hw *hw) | ||
2669 | { | ||
2670 | struct ath_wiphy *aphy = hw->priv; | ||
2671 | struct ath_softc *sc = aphy->sc; | ||
2672 | |||
2673 | mutex_lock(&sc->mutex); | ||
2674 | ath9k_hw_reset_tsf(sc->sc_ah); | ||
2675 | mutex_unlock(&sc->mutex); | ||
2676 | } | ||
2677 | |||
2678 | static int ath9k_ampdu_action(struct ieee80211_hw *hw, | ||
2679 | enum ieee80211_ampdu_mlme_action action, | ||
2680 | struct ieee80211_sta *sta, | ||
2681 | u16 tid, u16 *ssn) | ||
2682 | { | ||
2683 | struct ath_wiphy *aphy = hw->priv; | ||
2684 | struct ath_softc *sc = aphy->sc; | ||
2685 | int ret = 0; | ||
2686 | |||
2687 | switch (action) { | ||
2688 | case IEEE80211_AMPDU_RX_START: | ||
2689 | if (!(sc->sc_flags & SC_OP_RXAGGR)) | ||
2690 | ret = -ENOTSUPP; | ||
2691 | break; | ||
2692 | case IEEE80211_AMPDU_RX_STOP: | ||
2693 | break; | ||
2694 | case IEEE80211_AMPDU_TX_START: | ||
2695 | ret = ath_tx_aggr_start(sc, sta, tid, ssn); | ||
2696 | if (ret < 0) | ||
2697 | DPRINTF(sc, ATH_DBG_FATAL, | ||
2698 | "Unable to start TX aggregation\n"); | ||
2699 | else | ||
2700 | ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); | ||
2701 | break; | ||
2702 | case IEEE80211_AMPDU_TX_STOP: | ||
2703 | ret = ath_tx_aggr_stop(sc, sta, tid); | ||
2704 | if (ret < 0) | ||
2705 | DPRINTF(sc, ATH_DBG_FATAL, | ||
2706 | "Unable to stop TX aggregation\n"); | ||
2707 | |||
2708 | ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); | ||
2709 | break; | ||
2710 | case IEEE80211_AMPDU_TX_OPERATIONAL: | ||
2711 | ath_tx_aggr_resume(sc, sta, tid); | ||
2712 | break; | ||
2713 | default: | ||
2714 | DPRINTF(sc, ATH_DBG_FATAL, "Unknown AMPDU action\n"); | ||
2715 | } | ||
2716 | |||
2717 | return ret; | ||
2718 | } | ||
2719 | |||
2720 | static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | ||
2721 | { | ||
2722 | struct ath_wiphy *aphy = hw->priv; | ||
2723 | struct ath_softc *sc = aphy->sc; | ||
2724 | |||
2725 | if (ath9k_wiphy_scanning(sc)) { | ||
2726 | printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the " | ||
2727 | "same time\n"); | ||
2728 | /* | ||
2729 | * Do not allow the concurrent scanning state for now. This | ||
2730 | * could be improved with scanning control moved into ath9k. | ||
2731 | */ | ||
2732 | return; | ||
2733 | } | ||
2734 | |||
2735 | aphy->state = ATH_WIPHY_SCAN; | ||
2736 | ath9k_wiphy_pause_all_forced(sc, aphy); | ||
2737 | |||
2738 | mutex_lock(&sc->mutex); | ||
2739 | sc->sc_flags |= SC_OP_SCANNING; | ||
2740 | mutex_unlock(&sc->mutex); | ||
2741 | } | ||
2742 | |||
2743 | static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) | ||
2744 | { | ||
2745 | struct ath_wiphy *aphy = hw->priv; | ||
2746 | struct ath_softc *sc = aphy->sc; | ||
2747 | |||
2748 | mutex_lock(&sc->mutex); | ||
2749 | aphy->state = ATH_WIPHY_ACTIVE; | ||
2750 | sc->sc_flags &= ~SC_OP_SCANNING; | ||
2751 | mutex_unlock(&sc->mutex); | ||
2752 | } | ||
2753 | |||
2754 | struct ieee80211_ops ath9k_ops = { | ||
2755 | .tx = ath9k_tx, | ||
2756 | .start = ath9k_start, | ||
2757 | .stop = ath9k_stop, | ||
2758 | .add_interface = ath9k_add_interface, | ||
2759 | .remove_interface = ath9k_remove_interface, | ||
2760 | .config = ath9k_config, | ||
2761 | .config_interface = ath9k_config_interface, | ||
2762 | .configure_filter = ath9k_configure_filter, | ||
2763 | .sta_notify = ath9k_sta_notify, | ||
2764 | .conf_tx = ath9k_conf_tx, | ||
2765 | .bss_info_changed = ath9k_bss_info_changed, | ||
2766 | .set_key = ath9k_set_key, | ||
2767 | .get_tsf = ath9k_get_tsf, | ||
2768 | .set_tsf = ath9k_set_tsf, | ||
2769 | .reset_tsf = ath9k_reset_tsf, | ||
2770 | .ampdu_action = ath9k_ampdu_action, | ||
2771 | .sw_scan_start = ath9k_sw_scan_start, | ||
2772 | .sw_scan_complete = ath9k_sw_scan_complete, | ||
2773 | }; | ||
2774 | |||
2775 | static struct { | ||
2776 | u32 version; | ||
2777 | const char * name; | ||
2778 | } ath_mac_bb_names[] = { | ||
2779 | { AR_SREV_VERSION_5416_PCI, "5416" }, | ||
2780 | { AR_SREV_VERSION_5416_PCIE, "5418" }, | ||
2781 | { AR_SREV_VERSION_9100, "9100" }, | ||
2782 | { AR_SREV_VERSION_9160, "9160" }, | ||
2783 | { AR_SREV_VERSION_9280, "9280" }, | ||
2784 | { AR_SREV_VERSION_9285, "9285" } | ||
2785 | }; | ||
2786 | |||
2787 | static struct { | ||
2788 | u16 version; | ||
2789 | const char * name; | ||
2790 | } ath_rf_names[] = { | ||
2791 | { 0, "5133" }, | ||
2792 | { AR_RAD5133_SREV_MAJOR, "5133" }, | ||
2793 | { AR_RAD5122_SREV_MAJOR, "5122" }, | ||
2794 | { AR_RAD2133_SREV_MAJOR, "2133" }, | ||
2795 | { AR_RAD2122_SREV_MAJOR, "2122" } | ||
2796 | }; | ||
2797 | |||
2798 | /* | ||
2799 | * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown. | ||
2800 | */ | ||
2801 | const char * | ||
2802 | ath_mac_bb_name(u32 mac_bb_version) | ||
2803 | { | ||
2804 | int i; | ||
2805 | |||
2806 | for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) { | ||
2807 | if (ath_mac_bb_names[i].version == mac_bb_version) { | ||
2808 | return ath_mac_bb_names[i].name; | ||
2809 | } | ||
2810 | } | ||
2811 | |||
2812 | return "????"; | ||
2813 | } | ||
2814 | |||
2815 | /* | ||
2816 | * Return the RF name. "????" is returned if the RF is unknown. | ||
2817 | */ | ||
2818 | const char * | ||
2819 | ath_rf_name(u16 rf_version) | ||
2820 | { | ||
2821 | int i; | ||
2822 | |||
2823 | for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) { | ||
2824 | if (ath_rf_names[i].version == rf_version) { | ||
2825 | return ath_rf_names[i].name; | ||
2826 | } | ||
2827 | } | ||
2828 | |||
2829 | return "????"; | ||
2830 | } | ||
2831 | |||
2832 | static int __init ath9k_init(void) | ||
2833 | { | ||
2834 | int error; | ||
2835 | |||
2836 | /* Register rate control algorithm */ | ||
2837 | error = ath_rate_control_register(); | ||
2838 | if (error != 0) { | ||
2839 | printk(KERN_ERR | ||
2840 | "ath9k: Unable to register rate control " | ||
2841 | "algorithm: %d\n", | ||
2842 | error); | ||
2843 | goto err_out; | ||
2844 | } | ||
2845 | |||
2846 | error = ath9k_debug_create_root(); | ||
2847 | if (error) { | ||
2848 | printk(KERN_ERR | ||
2849 | "ath9k: Unable to create debugfs root: %d\n", | ||
2850 | error); | ||
2851 | goto err_rate_unregister; | ||
2852 | } | ||
2853 | |||
2854 | error = ath_pci_init(); | ||
2855 | if (error < 0) { | ||
2856 | printk(KERN_ERR | ||
2857 | "ath9k: No PCI devices found, driver not installed.\n"); | ||
2858 | error = -ENODEV; | ||
2859 | goto err_remove_root; | ||
2860 | } | ||
2861 | |||
2862 | error = ath_ahb_init(); | ||
2863 | if (error < 0) { | ||
2864 | error = -ENODEV; | ||
2865 | goto err_pci_exit; | ||
2866 | } | ||
2867 | |||
2868 | return 0; | ||
2869 | |||
2870 | err_pci_exit: | ||
2871 | ath_pci_exit(); | ||
2872 | |||
2873 | err_remove_root: | ||
2874 | ath9k_debug_remove_root(); | ||
2875 | err_rate_unregister: | ||
2876 | ath_rate_control_unregister(); | ||
2877 | err_out: | ||
2878 | return error; | ||
2879 | } | ||
2880 | module_init(ath9k_init); | ||
2881 | |||
2882 | static void __exit ath9k_exit(void) | ||
2883 | { | ||
2884 | ath_ahb_exit(); | ||
2885 | ath_pci_exit(); | ||
2886 | ath9k_debug_remove_root(); | ||
2887 | ath_rate_control_unregister(); | ||
2888 | printk(KERN_INFO "%s: Driver unloaded\n", dev_info); | ||
2889 | } | ||
2890 | module_exit(ath9k_exit); | ||
diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath9k/pci.c deleted file mode 100644 index 6dbc58580abb..000000000000 --- a/drivers/net/wireless/ath9k/pci.c +++ /dev/null | |||
@@ -1,295 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 <linux/nl80211.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include "ath9k.h" | ||
20 | |||
21 | static struct pci_device_id ath_pci_id_table[] __devinitdata = { | ||
22 | { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */ | ||
23 | { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */ | ||
24 | { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */ | ||
25 | { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ | ||
26 | { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ | ||
27 | { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ | ||
28 | { 0 } | ||
29 | }; | ||
30 | |||
31 | /* return bus cachesize in 4B word units */ | ||
32 | static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz) | ||
33 | { | ||
34 | u8 u8tmp; | ||
35 | |||
36 | pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE, | ||
37 | (u8 *)&u8tmp); | ||
38 | *csz = (int)u8tmp; | ||
39 | |||
40 | /* | ||
41 | * This check was put in to avoid "unplesant" consequences if | ||
42 | * the bootrom has not fully initialized all PCI devices. | ||
43 | * Sometimes the cache line size register is not set | ||
44 | */ | ||
45 | |||
46 | if (*csz == 0) | ||
47 | *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ | ||
48 | } | ||
49 | |||
50 | static void ath_pci_cleanup(struct ath_softc *sc) | ||
51 | { | ||
52 | struct pci_dev *pdev = to_pci_dev(sc->dev); | ||
53 | |||
54 | pci_iounmap(pdev, sc->mem); | ||
55 | pci_disable_device(pdev); | ||
56 | pci_release_region(pdev, 0); | ||
57 | } | ||
58 | |||
59 | static bool ath_pci_eeprom_read(struct ath_hw *ah, u32 off, u16 *data) | ||
60 | { | ||
61 | (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S)); | ||
62 | |||
63 | if (!ath9k_hw_wait(ah, | ||
64 | AR_EEPROM_STATUS_DATA, | ||
65 | AR_EEPROM_STATUS_DATA_BUSY | | ||
66 | AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0, | ||
67 | AH_WAIT_TIMEOUT)) { | ||
68 | return false; | ||
69 | } | ||
70 | |||
71 | *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA), | ||
72 | AR_EEPROM_STATUS_DATA_VAL); | ||
73 | |||
74 | return true; | ||
75 | } | ||
76 | |||
77 | static struct ath_bus_ops ath_pci_bus_ops = { | ||
78 | .read_cachesize = ath_pci_read_cachesize, | ||
79 | .cleanup = ath_pci_cleanup, | ||
80 | .eeprom_read = ath_pci_eeprom_read, | ||
81 | }; | ||
82 | |||
83 | static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | ||
84 | { | ||
85 | void __iomem *mem; | ||
86 | struct ath_wiphy *aphy; | ||
87 | struct ath_softc *sc; | ||
88 | struct ieee80211_hw *hw; | ||
89 | u8 csz; | ||
90 | int ret = 0; | ||
91 | struct ath_hw *ah; | ||
92 | |||
93 | if (pci_enable_device(pdev)) | ||
94 | return -EIO; | ||
95 | |||
96 | ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
97 | |||
98 | if (ret) { | ||
99 | printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); | ||
100 | goto bad; | ||
101 | } | ||
102 | |||
103 | ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
104 | |||
105 | if (ret) { | ||
106 | printk(KERN_ERR "ath9k: 32-bit DMA consistent " | ||
107 | "DMA enable failed\n"); | ||
108 | goto bad; | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * Cache line size is used to size and align various | ||
113 | * structures used to communicate with the hardware. | ||
114 | */ | ||
115 | pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); | ||
116 | if (csz == 0) { | ||
117 | /* | ||
118 | * Linux 2.4.18 (at least) writes the cache line size | ||
119 | * register as a 16-bit wide register which is wrong. | ||
120 | * We must have this setup properly for rx buffer | ||
121 | * DMA to work so force a reasonable value here if it | ||
122 | * comes up zero. | ||
123 | */ | ||
124 | csz = L1_CACHE_BYTES / sizeof(u32); | ||
125 | pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); | ||
126 | } | ||
127 | /* | ||
128 | * The default setting of latency timer yields poor results, | ||
129 | * set it to the value used by other systems. It may be worth | ||
130 | * tweaking this setting more. | ||
131 | */ | ||
132 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); | ||
133 | |||
134 | pci_set_master(pdev); | ||
135 | |||
136 | ret = pci_request_region(pdev, 0, "ath9k"); | ||
137 | if (ret) { | ||
138 | dev_err(&pdev->dev, "PCI memory region reserve error\n"); | ||
139 | ret = -ENODEV; | ||
140 | goto bad; | ||
141 | } | ||
142 | |||
143 | mem = pci_iomap(pdev, 0, 0); | ||
144 | if (!mem) { | ||
145 | printk(KERN_ERR "PCI memory map error\n") ; | ||
146 | ret = -EIO; | ||
147 | goto bad1; | ||
148 | } | ||
149 | |||
150 | hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + | ||
151 | sizeof(struct ath_softc), &ath9k_ops); | ||
152 | if (hw == NULL) { | ||
153 | printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n"); | ||
154 | goto bad2; | ||
155 | } | ||
156 | |||
157 | SET_IEEE80211_DEV(hw, &pdev->dev); | ||
158 | pci_set_drvdata(pdev, hw); | ||
159 | |||
160 | aphy = hw->priv; | ||
161 | sc = (struct ath_softc *) (aphy + 1); | ||
162 | aphy->sc = sc; | ||
163 | aphy->hw = hw; | ||
164 | sc->pri_wiphy = aphy; | ||
165 | sc->hw = hw; | ||
166 | sc->dev = &pdev->dev; | ||
167 | sc->mem = mem; | ||
168 | sc->bus_ops = &ath_pci_bus_ops; | ||
169 | |||
170 | if (ath_attach(id->device, sc) != 0) { | ||
171 | ret = -ENODEV; | ||
172 | goto bad3; | ||
173 | } | ||
174 | |||
175 | /* setup interrupt service routine */ | ||
176 | |||
177 | if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) { | ||
178 | printk(KERN_ERR "%s: request_irq failed\n", | ||
179 | wiphy_name(hw->wiphy)); | ||
180 | ret = -EIO; | ||
181 | goto bad4; | ||
182 | } | ||
183 | |||
184 | sc->irq = pdev->irq; | ||
185 | |||
186 | ah = sc->sc_ah; | ||
187 | printk(KERN_INFO | ||
188 | "%s: Atheros AR%s MAC/BB Rev:%x " | ||
189 | "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n", | ||
190 | wiphy_name(hw->wiphy), | ||
191 | ath_mac_bb_name(ah->hw_version.macVersion), | ||
192 | ah->hw_version.macRev, | ||
193 | ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)), | ||
194 | ah->hw_version.phyRev, | ||
195 | (unsigned long)mem, pdev->irq); | ||
196 | |||
197 | return 0; | ||
198 | bad4: | ||
199 | ath_detach(sc); | ||
200 | bad3: | ||
201 | ieee80211_free_hw(hw); | ||
202 | bad2: | ||
203 | pci_iounmap(pdev, mem); | ||
204 | bad1: | ||
205 | pci_release_region(pdev, 0); | ||
206 | bad: | ||
207 | pci_disable_device(pdev); | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | static void ath_pci_remove(struct pci_dev *pdev) | ||
212 | { | ||
213 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
214 | struct ath_wiphy *aphy = hw->priv; | ||
215 | struct ath_softc *sc = aphy->sc; | ||
216 | |||
217 | ath_cleanup(sc); | ||
218 | } | ||
219 | |||
220 | #ifdef CONFIG_PM | ||
221 | |||
222 | static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
223 | { | ||
224 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
225 | struct ath_wiphy *aphy = hw->priv; | ||
226 | struct ath_softc *sc = aphy->sc; | ||
227 | |||
228 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); | ||
229 | |||
230 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
231 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
232 | cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); | ||
233 | #endif | ||
234 | |||
235 | pci_save_state(pdev); | ||
236 | pci_disable_device(pdev); | ||
237 | pci_set_power_state(pdev, PCI_D3hot); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static int ath_pci_resume(struct pci_dev *pdev) | ||
243 | { | ||
244 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
245 | struct ath_wiphy *aphy = hw->priv; | ||
246 | struct ath_softc *sc = aphy->sc; | ||
247 | int err; | ||
248 | |||
249 | err = pci_enable_device(pdev); | ||
250 | if (err) | ||
251 | return err; | ||
252 | pci_restore_state(pdev); | ||
253 | |||
254 | /* Enable LED */ | ||
255 | ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN, | ||
256 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
257 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); | ||
258 | |||
259 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
260 | /* | ||
261 | * check the h/w rfkill state on resume | ||
262 | * and start the rfkill poll timer | ||
263 | */ | ||
264 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
265 | queue_delayed_work(sc->hw->workqueue, | ||
266 | &sc->rf_kill.rfkill_poll, 0); | ||
267 | #endif | ||
268 | |||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | #endif /* CONFIG_PM */ | ||
273 | |||
274 | MODULE_DEVICE_TABLE(pci, ath_pci_id_table); | ||
275 | |||
276 | static struct pci_driver ath_pci_driver = { | ||
277 | .name = "ath9k", | ||
278 | .id_table = ath_pci_id_table, | ||
279 | .probe = ath_pci_probe, | ||
280 | .remove = ath_pci_remove, | ||
281 | #ifdef CONFIG_PM | ||
282 | .suspend = ath_pci_suspend, | ||
283 | .resume = ath_pci_resume, | ||
284 | #endif /* CONFIG_PM */ | ||
285 | }; | ||
286 | |||
287 | int ath_pci_init(void) | ||
288 | { | ||
289 | return pci_register_driver(&ath_pci_driver); | ||
290 | } | ||
291 | |||
292 | void ath_pci_exit(void) | ||
293 | { | ||
294 | pci_unregister_driver(&ath_pci_driver); | ||
295 | } | ||
diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath9k/phy.c deleted file mode 100644 index 5ec9ce91d979..000000000000 --- a/drivers/net/wireless/ath9k/phy.c +++ /dev/null | |||
@@ -1,424 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 "ath9k.h" | ||
18 | |||
19 | void | ||
20 | ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex, | ||
21 | int regWrites) | ||
22 | { | ||
23 | REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); | ||
24 | } | ||
25 | |||
26 | bool | ||
27 | ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | ||
28 | { | ||
29 | u32 channelSel = 0; | ||
30 | u32 bModeSynth = 0; | ||
31 | u32 aModeRefSel = 0; | ||
32 | u32 reg32 = 0; | ||
33 | u16 freq; | ||
34 | struct chan_centers centers; | ||
35 | |||
36 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
37 | freq = centers.synth_center; | ||
38 | |||
39 | if (freq < 4800) { | ||
40 | u32 txctl; | ||
41 | |||
42 | if (((freq - 2192) % 5) == 0) { | ||
43 | channelSel = ((freq - 672) * 2 - 3040) / 10; | ||
44 | bModeSynth = 0; | ||
45 | } else if (((freq - 2224) % 5) == 0) { | ||
46 | channelSel = ((freq - 704) * 2 - 3040) / 10; | ||
47 | bModeSynth = 1; | ||
48 | } else { | ||
49 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
50 | "Invalid channel %u MHz\n", freq); | ||
51 | return false; | ||
52 | } | ||
53 | |||
54 | channelSel = (channelSel << 2) & 0xff; | ||
55 | channelSel = ath9k_hw_reverse_bits(channelSel, 8); | ||
56 | |||
57 | txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL); | ||
58 | if (freq == 2484) { | ||
59 | |||
60 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
61 | txctl | AR_PHY_CCK_TX_CTRL_JAPAN); | ||
62 | } else { | ||
63 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
64 | txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN); | ||
65 | } | ||
66 | |||
67 | } else if ((freq % 20) == 0 && freq >= 5120) { | ||
68 | channelSel = | ||
69 | ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8); | ||
70 | aModeRefSel = ath9k_hw_reverse_bits(1, 2); | ||
71 | } else if ((freq % 10) == 0) { | ||
72 | channelSel = | ||
73 | ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8); | ||
74 | if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) | ||
75 | aModeRefSel = ath9k_hw_reverse_bits(2, 2); | ||
76 | else | ||
77 | aModeRefSel = ath9k_hw_reverse_bits(1, 2); | ||
78 | } else if ((freq % 5) == 0) { | ||
79 | channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8); | ||
80 | aModeRefSel = ath9k_hw_reverse_bits(1, 2); | ||
81 | } else { | ||
82 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
83 | "Invalid channel %u MHz\n", freq); | ||
84 | return false; | ||
85 | } | ||
86 | |||
87 | reg32 = | ||
88 | (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) | | ||
89 | (1 << 5) | 0x1; | ||
90 | |||
91 | REG_WRITE(ah, AR_PHY(0x37), reg32); | ||
92 | |||
93 | ah->curchan = chan; | ||
94 | ah->curchan_rad_index = -1; | ||
95 | |||
96 | return true; | ||
97 | } | ||
98 | |||
99 | bool | ||
100 | ath9k_hw_ar9280_set_channel(struct ath_hw *ah, | ||
101 | struct ath9k_channel *chan) | ||
102 | { | ||
103 | u16 bMode, fracMode, aModeRefSel = 0; | ||
104 | u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0; | ||
105 | struct chan_centers centers; | ||
106 | u32 refDivA = 24; | ||
107 | |||
108 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
109 | freq = centers.synth_center; | ||
110 | |||
111 | reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL); | ||
112 | reg32 &= 0xc0000000; | ||
113 | |||
114 | if (freq < 4800) { | ||
115 | u32 txctl; | ||
116 | |||
117 | bMode = 1; | ||
118 | fracMode = 1; | ||
119 | aModeRefSel = 0; | ||
120 | channelSel = (freq * 0x10000) / 15; | ||
121 | |||
122 | txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL); | ||
123 | if (freq == 2484) { | ||
124 | |||
125 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
126 | txctl | AR_PHY_CCK_TX_CTRL_JAPAN); | ||
127 | } else { | ||
128 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
129 | txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN); | ||
130 | } | ||
131 | } else { | ||
132 | bMode = 0; | ||
133 | fracMode = 0; | ||
134 | |||
135 | switch(ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) { | ||
136 | case 0: | ||
137 | if ((freq % 20) == 0) { | ||
138 | aModeRefSel = 3; | ||
139 | } else if ((freq % 10) == 0) { | ||
140 | aModeRefSel = 2; | ||
141 | } | ||
142 | if (aModeRefSel) | ||
143 | break; | ||
144 | case 1: | ||
145 | default: | ||
146 | aModeRefSel = 0; | ||
147 | fracMode = 1; | ||
148 | refDivA = 1; | ||
149 | channelSel = (freq * 0x8000) / 15; | ||
150 | |||
151 | REG_RMW_FIELD(ah, AR_AN_SYNTH9, | ||
152 | AR_AN_SYNTH9_REFDIVA, refDivA); | ||
153 | |||
154 | } | ||
155 | |||
156 | if (!fracMode) { | ||
157 | ndiv = (freq * (refDivA >> aModeRefSel)) / 60; | ||
158 | channelSel = ndiv & 0x1ff; | ||
159 | channelFrac = (ndiv & 0xfffffe00) * 2; | ||
160 | channelSel = (channelSel << 17) | channelFrac; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | reg32 = reg32 | | ||
165 | (bMode << 29) | | ||
166 | (fracMode << 28) | (aModeRefSel << 26) | (channelSel); | ||
167 | |||
168 | REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32); | ||
169 | |||
170 | ah->curchan = chan; | ||
171 | ah->curchan_rad_index = -1; | ||
172 | |||
173 | return true; | ||
174 | } | ||
175 | |||
176 | static void | ||
177 | ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32, | ||
178 | u32 numBits, u32 firstBit, | ||
179 | u32 column) | ||
180 | { | ||
181 | u32 tmp32, mask, arrayEntry, lastBit; | ||
182 | int32_t bitPosition, bitsLeft; | ||
183 | |||
184 | tmp32 = ath9k_hw_reverse_bits(reg32, numBits); | ||
185 | arrayEntry = (firstBit - 1) / 8; | ||
186 | bitPosition = (firstBit - 1) % 8; | ||
187 | bitsLeft = numBits; | ||
188 | while (bitsLeft > 0) { | ||
189 | lastBit = (bitPosition + bitsLeft > 8) ? | ||
190 | 8 : bitPosition + bitsLeft; | ||
191 | mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) << | ||
192 | (column * 8); | ||
193 | rfBuf[arrayEntry] &= ~mask; | ||
194 | rfBuf[arrayEntry] |= ((tmp32 << bitPosition) << | ||
195 | (column * 8)) & mask; | ||
196 | bitsLeft -= 8 - bitPosition; | ||
197 | tmp32 = tmp32 >> (8 - bitPosition); | ||
198 | bitPosition = 0; | ||
199 | arrayEntry++; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | bool | ||
204 | ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan, | ||
205 | u16 modesIndex) | ||
206 | { | ||
207 | u32 eepMinorRev; | ||
208 | u32 ob5GHz = 0, db5GHz = 0; | ||
209 | u32 ob2GHz = 0, db2GHz = 0; | ||
210 | int regWrites = 0; | ||
211 | |||
212 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
213 | return true; | ||
214 | |||
215 | eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); | ||
216 | |||
217 | RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1); | ||
218 | |||
219 | RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1); | ||
220 | |||
221 | RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1); | ||
222 | |||
223 | RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3, | ||
224 | modesIndex); | ||
225 | { | ||
226 | int i; | ||
227 | for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) { | ||
228 | ah->analogBank6Data[i] = | ||
229 | INI_RA(&ah->iniBank6TPC, i, modesIndex); | ||
230 | } | ||
231 | } | ||
232 | |||
233 | if (eepMinorRev >= 2) { | ||
234 | if (IS_CHAN_2GHZ(chan)) { | ||
235 | ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2); | ||
236 | db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2); | ||
237 | ath9k_phy_modify_rx_buffer(ah->analogBank6Data, | ||
238 | ob2GHz, 3, 197, 0); | ||
239 | ath9k_phy_modify_rx_buffer(ah->analogBank6Data, | ||
240 | db2GHz, 3, 194, 0); | ||
241 | } else { | ||
242 | ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5); | ||
243 | db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5); | ||
244 | ath9k_phy_modify_rx_buffer(ah->analogBank6Data, | ||
245 | ob5GHz, 3, 203, 0); | ||
246 | ath9k_phy_modify_rx_buffer(ah->analogBank6Data, | ||
247 | db5GHz, 3, 200, 0); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1); | ||
252 | |||
253 | REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data, | ||
254 | regWrites); | ||
255 | REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data, | ||
256 | regWrites); | ||
257 | REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data, | ||
258 | regWrites); | ||
259 | REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data, | ||
260 | regWrites); | ||
261 | REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data, | ||
262 | regWrites); | ||
263 | REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data, | ||
264 | regWrites); | ||
265 | |||
266 | return true; | ||
267 | } | ||
268 | |||
269 | void | ||
270 | ath9k_hw_rfdetach(struct ath_hw *ah) | ||
271 | { | ||
272 | if (ah->analogBank0Data != NULL) { | ||
273 | kfree(ah->analogBank0Data); | ||
274 | ah->analogBank0Data = NULL; | ||
275 | } | ||
276 | if (ah->analogBank1Data != NULL) { | ||
277 | kfree(ah->analogBank1Data); | ||
278 | ah->analogBank1Data = NULL; | ||
279 | } | ||
280 | if (ah->analogBank2Data != NULL) { | ||
281 | kfree(ah->analogBank2Data); | ||
282 | ah->analogBank2Data = NULL; | ||
283 | } | ||
284 | if (ah->analogBank3Data != NULL) { | ||
285 | kfree(ah->analogBank3Data); | ||
286 | ah->analogBank3Data = NULL; | ||
287 | } | ||
288 | if (ah->analogBank6Data != NULL) { | ||
289 | kfree(ah->analogBank6Data); | ||
290 | ah->analogBank6Data = NULL; | ||
291 | } | ||
292 | if (ah->analogBank6TPCData != NULL) { | ||
293 | kfree(ah->analogBank6TPCData); | ||
294 | ah->analogBank6TPCData = NULL; | ||
295 | } | ||
296 | if (ah->analogBank7Data != NULL) { | ||
297 | kfree(ah->analogBank7Data); | ||
298 | ah->analogBank7Data = NULL; | ||
299 | } | ||
300 | if (ah->addac5416_21 != NULL) { | ||
301 | kfree(ah->addac5416_21); | ||
302 | ah->addac5416_21 = NULL; | ||
303 | } | ||
304 | if (ah->bank6Temp != NULL) { | ||
305 | kfree(ah->bank6Temp); | ||
306 | ah->bank6Temp = NULL; | ||
307 | } | ||
308 | } | ||
309 | |||
310 | bool ath9k_hw_init_rf(struct ath_hw *ah, int *status) | ||
311 | { | ||
312 | if (!AR_SREV_9280_10_OR_LATER(ah)) { | ||
313 | ah->analogBank0Data = | ||
314 | kzalloc((sizeof(u32) * | ||
315 | ah->iniBank0.ia_rows), GFP_KERNEL); | ||
316 | ah->analogBank1Data = | ||
317 | kzalloc((sizeof(u32) * | ||
318 | ah->iniBank1.ia_rows), GFP_KERNEL); | ||
319 | ah->analogBank2Data = | ||
320 | kzalloc((sizeof(u32) * | ||
321 | ah->iniBank2.ia_rows), GFP_KERNEL); | ||
322 | ah->analogBank3Data = | ||
323 | kzalloc((sizeof(u32) * | ||
324 | ah->iniBank3.ia_rows), GFP_KERNEL); | ||
325 | ah->analogBank6Data = | ||
326 | kzalloc((sizeof(u32) * | ||
327 | ah->iniBank6.ia_rows), GFP_KERNEL); | ||
328 | ah->analogBank6TPCData = | ||
329 | kzalloc((sizeof(u32) * | ||
330 | ah->iniBank6TPC.ia_rows), GFP_KERNEL); | ||
331 | ah->analogBank7Data = | ||
332 | kzalloc((sizeof(u32) * | ||
333 | ah->iniBank7.ia_rows), GFP_KERNEL); | ||
334 | |||
335 | if (ah->analogBank0Data == NULL | ||
336 | || ah->analogBank1Data == NULL | ||
337 | || ah->analogBank2Data == NULL | ||
338 | || ah->analogBank3Data == NULL | ||
339 | || ah->analogBank6Data == NULL | ||
340 | || ah->analogBank6TPCData == NULL | ||
341 | || ah->analogBank7Data == NULL) { | ||
342 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
343 | "Cannot allocate RF banks\n"); | ||
344 | *status = -ENOMEM; | ||
345 | return false; | ||
346 | } | ||
347 | |||
348 | ah->addac5416_21 = | ||
349 | kzalloc((sizeof(u32) * | ||
350 | ah->iniAddac.ia_rows * | ||
351 | ah->iniAddac.ia_columns), GFP_KERNEL); | ||
352 | if (ah->addac5416_21 == NULL) { | ||
353 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
354 | "Cannot allocate addac5416_21\n"); | ||
355 | *status = -ENOMEM; | ||
356 | return false; | ||
357 | } | ||
358 | |||
359 | ah->bank6Temp = | ||
360 | kzalloc((sizeof(u32) * | ||
361 | ah->iniBank6.ia_rows), GFP_KERNEL); | ||
362 | if (ah->bank6Temp == NULL) { | ||
363 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
364 | "Cannot allocate bank6Temp\n"); | ||
365 | *status = -ENOMEM; | ||
366 | return false; | ||
367 | } | ||
368 | } | ||
369 | |||
370 | return true; | ||
371 | } | ||
372 | |||
373 | void | ||
374 | ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan) | ||
375 | { | ||
376 | int i, regWrites = 0; | ||
377 | u32 bank6SelMask; | ||
378 | u32 *bank6Temp = ah->bank6Temp; | ||
379 | |||
380 | switch (ah->diversity_control) { | ||
381 | case ATH9K_ANT_FIXED_A: | ||
382 | bank6SelMask = | ||
383 | (ah-> | ||
384 | antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_0 : | ||
385 | REDUCE_CHAIN_1; | ||
386 | break; | ||
387 | case ATH9K_ANT_FIXED_B: | ||
388 | bank6SelMask = | ||
389 | (ah-> | ||
390 | antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_1 : | ||
391 | REDUCE_CHAIN_0; | ||
392 | break; | ||
393 | case ATH9K_ANT_VARIABLE: | ||
394 | return; | ||
395 | break; | ||
396 | default: | ||
397 | return; | ||
398 | break; | ||
399 | } | ||
400 | |||
401 | for (i = 0; i < ah->iniBank6.ia_rows; i++) | ||
402 | bank6Temp[i] = ah->analogBank6Data[i]; | ||
403 | |||
404 | REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask); | ||
405 | |||
406 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0); | ||
407 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0); | ||
408 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0); | ||
409 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 192, 0); | ||
410 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 193, 0); | ||
411 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 222, 0); | ||
412 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 245, 0); | ||
413 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0); | ||
414 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0); | ||
415 | |||
416 | REG_WRITE_RF_ARRAY(&ah->iniBank6, bank6Temp, regWrites); | ||
417 | |||
418 | REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053); | ||
419 | #ifdef ALTER_SWITCH | ||
420 | REG_WRITE(ah, PHY_SWITCH_CHAIN_0, | ||
421 | (REG_READ(ah, PHY_SWITCH_CHAIN_0) & ~0x38) | ||
422 | | ((REG_READ(ah, PHY_SWITCH_CHAIN_0) >> 3) & 0x38)); | ||
423 | #endif | ||
424 | } | ||
diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath9k/phy.h deleted file mode 100644 index 296d0e985f25..000000000000 --- a/drivers/net/wireless/ath9k/phy.h +++ /dev/null | |||
@@ -1,576 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 PHY_H | ||
18 | #define PHY_H | ||
19 | |||
20 | bool ath9k_hw_ar9280_set_channel(struct ath_hw *ah, | ||
21 | struct ath9k_channel | ||
22 | *chan); | ||
23 | bool ath9k_hw_set_channel(struct ath_hw *ah, | ||
24 | struct ath9k_channel *chan); | ||
25 | void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, | ||
26 | u32 freqIndex, int regWrites); | ||
27 | bool ath9k_hw_set_rf_regs(struct ath_hw *ah, | ||
28 | struct ath9k_channel *chan, | ||
29 | u16 modesIndex); | ||
30 | void ath9k_hw_decrease_chain_power(struct ath_hw *ah, | ||
31 | struct ath9k_channel *chan); | ||
32 | bool ath9k_hw_init_rf(struct ath_hw *ah, | ||
33 | int *status); | ||
34 | |||
35 | #define AR_PHY_BASE 0x9800 | ||
36 | #define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2)) | ||
37 | |||
38 | #define AR_PHY_TEST 0x9800 | ||
39 | #define PHY_AGC_CLR 0x10000000 | ||
40 | #define RFSILENT_BB 0x00002000 | ||
41 | |||
42 | #define AR_PHY_TURBO 0x9804 | ||
43 | #define AR_PHY_FC_TURBO_MODE 0x00000001 | ||
44 | #define AR_PHY_FC_TURBO_SHORT 0x00000002 | ||
45 | #define AR_PHY_FC_DYN2040_EN 0x00000004 | ||
46 | #define AR_PHY_FC_DYN2040_PRI_ONLY 0x00000008 | ||
47 | #define AR_PHY_FC_DYN2040_PRI_CH 0x00000010 | ||
48 | #define AR_PHY_FC_DYN2040_EXT_CH 0x00000020 | ||
49 | #define AR_PHY_FC_HT_EN 0x00000040 | ||
50 | #define AR_PHY_FC_SHORT_GI_40 0x00000080 | ||
51 | #define AR_PHY_FC_WALSH 0x00000100 | ||
52 | #define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200 | ||
53 | #define AR_PHY_FC_ENABLE_DAC_FIFO 0x00000800 | ||
54 | |||
55 | #define AR_PHY_TEST2 0x9808 | ||
56 | |||
57 | #define AR_PHY_TIMING2 0x9810 | ||
58 | #define AR_PHY_TIMING3 0x9814 | ||
59 | #define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000 | ||
60 | #define AR_PHY_TIMING3_DSC_MAN_S 17 | ||
61 | #define AR_PHY_TIMING3_DSC_EXP 0x0001E000 | ||
62 | #define AR_PHY_TIMING3_DSC_EXP_S 13 | ||
63 | |||
64 | #define AR_PHY_CHIP_ID 0x9818 | ||
65 | #define AR_PHY_CHIP_ID_REV_0 0x80 | ||
66 | #define AR_PHY_CHIP_ID_REV_1 0x81 | ||
67 | #define AR_PHY_CHIP_ID_9160_REV_0 0xb0 | ||
68 | |||
69 | #define AR_PHY_ACTIVE 0x981C | ||
70 | #define AR_PHY_ACTIVE_EN 0x00000001 | ||
71 | #define AR_PHY_ACTIVE_DIS 0x00000000 | ||
72 | |||
73 | #define AR_PHY_RF_CTL2 0x9824 | ||
74 | #define AR_PHY_TX_END_DATA_START 0x000000FF | ||
75 | #define AR_PHY_TX_END_DATA_START_S 0 | ||
76 | #define AR_PHY_TX_END_PA_ON 0x0000FF00 | ||
77 | #define AR_PHY_TX_END_PA_ON_S 8 | ||
78 | |||
79 | #define AR_PHY_RF_CTL3 0x9828 | ||
80 | #define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000 | ||
81 | #define AR_PHY_TX_END_TO_A2_RX_ON_S 16 | ||
82 | |||
83 | #define AR_PHY_ADC_CTL 0x982C | ||
84 | #define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003 | ||
85 | #define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S 0 | ||
86 | #define AR_PHY_ADC_CTL_OFF_PWDDAC 0x00002000 | ||
87 | #define AR_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000 | ||
88 | #define AR_PHY_ADC_CTL_OFF_PWDADC 0x00008000 | ||
89 | #define AR_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000 | ||
90 | #define AR_PHY_ADC_CTL_ON_INBUFGAIN_S 16 | ||
91 | |||
92 | #define AR_PHY_ADC_SERIAL_CTL 0x9830 | ||
93 | #define AR_PHY_SEL_INTERNAL_ADDAC 0x00000000 | ||
94 | #define AR_PHY_SEL_EXTERNAL_RADIO 0x00000001 | ||
95 | |||
96 | #define AR_PHY_RF_CTL4 0x9834 | ||
97 | #define AR_PHY_RF_CTL4_TX_END_XPAB_OFF 0xFF000000 | ||
98 | #define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24 | ||
99 | #define AR_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00FF0000 | ||
100 | #define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16 | ||
101 | #define AR_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000FF00 | ||
102 | #define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S 8 | ||
103 | #define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF | ||
104 | #define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0 | ||
105 | |||
106 | #define AR_PHY_TSTDAC_CONST 0x983c | ||
107 | |||
108 | #define AR_PHY_SETTLING 0x9844 | ||
109 | #define AR_PHY_SETTLING_SWITCH 0x00003F80 | ||
110 | #define AR_PHY_SETTLING_SWITCH_S 7 | ||
111 | |||
112 | #define AR_PHY_RXGAIN 0x9848 | ||
113 | #define AR_PHY_RXGAIN_TXRX_ATTEN 0x0003F000 | ||
114 | #define AR_PHY_RXGAIN_TXRX_ATTEN_S 12 | ||
115 | #define AR_PHY_RXGAIN_TXRX_RF_MAX 0x007C0000 | ||
116 | #define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18 | ||
117 | #define AR9280_PHY_RXGAIN_TXRX_ATTEN 0x00003F80 | ||
118 | #define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7 | ||
119 | #define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000 | ||
120 | #define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14 | ||
121 | |||
122 | #define AR_PHY_DESIRED_SZ 0x9850 | ||
123 | #define AR_PHY_DESIRED_SZ_ADC 0x000000FF | ||
124 | #define AR_PHY_DESIRED_SZ_ADC_S 0 | ||
125 | #define AR_PHY_DESIRED_SZ_PGA 0x0000FF00 | ||
126 | #define AR_PHY_DESIRED_SZ_PGA_S 8 | ||
127 | #define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000 | ||
128 | #define AR_PHY_DESIRED_SZ_TOT_DES_S 20 | ||
129 | |||
130 | #define AR_PHY_FIND_SIG 0x9858 | ||
131 | #define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000 | ||
132 | #define AR_PHY_FIND_SIG_FIRSTEP_S 12 | ||
133 | #define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000 | ||
134 | #define AR_PHY_FIND_SIG_FIRPWR_S 18 | ||
135 | |||
136 | #define AR_PHY_AGC_CTL1 0x985C | ||
137 | #define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80 | ||
138 | #define AR_PHY_AGC_CTL1_COARSE_LOW_S 7 | ||
139 | #define AR_PHY_AGC_CTL1_COARSE_HIGH 0x003F8000 | ||
140 | #define AR_PHY_AGC_CTL1_COARSE_HIGH_S 15 | ||
141 | |||
142 | #define AR_PHY_AGC_CONTROL 0x9860 | ||
143 | #define AR_PHY_AGC_CONTROL_CAL 0x00000001 | ||
144 | #define AR_PHY_AGC_CONTROL_NF 0x00000002 | ||
145 | #define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000 | ||
146 | #define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000 | ||
147 | #define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 | ||
148 | |||
149 | #define AR_PHY_CCA 0x9864 | ||
150 | #define AR_PHY_MINCCA_PWR 0x0FF80000 | ||
151 | #define AR_PHY_MINCCA_PWR_S 19 | ||
152 | #define AR_PHY_CCA_THRESH62 0x0007F000 | ||
153 | #define AR_PHY_CCA_THRESH62_S 12 | ||
154 | #define AR9280_PHY_MINCCA_PWR 0x1FF00000 | ||
155 | #define AR9280_PHY_MINCCA_PWR_S 20 | ||
156 | #define AR9280_PHY_CCA_THRESH62 0x000FF000 | ||
157 | #define AR9280_PHY_CCA_THRESH62_S 12 | ||
158 | |||
159 | #define AR_PHY_SFCORR_LOW 0x986C | ||
160 | #define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001 | ||
161 | #define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00 | ||
162 | #define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8 | ||
163 | #define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000 | ||
164 | #define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14 | ||
165 | #define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000 | ||
166 | #define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21 | ||
167 | |||
168 | #define AR_PHY_SFCORR 0x9868 | ||
169 | #define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F | ||
170 | #define AR_PHY_SFCORR_M2COUNT_THR_S 0 | ||
171 | #define AR_PHY_SFCORR_M1_THRESH 0x00FE0000 | ||
172 | #define AR_PHY_SFCORR_M1_THRESH_S 17 | ||
173 | #define AR_PHY_SFCORR_M2_THRESH 0x7F000000 | ||
174 | #define AR_PHY_SFCORR_M2_THRESH_S 24 | ||
175 | |||
176 | #define AR_PHY_SLEEP_CTR_CONTROL 0x9870 | ||
177 | #define AR_PHY_SLEEP_CTR_LIMIT 0x9874 | ||
178 | #define AR_PHY_SYNTH_CONTROL 0x9874 | ||
179 | #define AR_PHY_SLEEP_SCAL 0x9878 | ||
180 | |||
181 | #define AR_PHY_PLL_CTL 0x987c | ||
182 | #define AR_PHY_PLL_CTL_40 0xaa | ||
183 | #define AR_PHY_PLL_CTL_40_5413 0x04 | ||
184 | #define AR_PHY_PLL_CTL_44 0xab | ||
185 | #define AR_PHY_PLL_CTL_44_2133 0xeb | ||
186 | #define AR_PHY_PLL_CTL_40_2133 0xea | ||
187 | |||
188 | #define AR_PHY_RX_DELAY 0x9914 | ||
189 | #define AR_PHY_SEARCH_START_DELAY 0x9918 | ||
190 | #define AR_PHY_RX_DELAY_DELAY 0x00003FFF | ||
191 | |||
192 | #define AR_PHY_TIMING_CTRL4(_i) (0x9920 + ((_i) << 12)) | ||
193 | #define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F | ||
194 | #define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0 | ||
195 | #define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0 | ||
196 | #define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5 | ||
197 | #define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800 | ||
198 | #define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000 | ||
199 | #define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12 | ||
200 | #define AR_PHY_TIMING_CTRL4_DO_CAL 0x10000 | ||
201 | |||
202 | #define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000 | ||
203 | #define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000 | ||
204 | #define AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000 | ||
205 | #define AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000 | ||
206 | |||
207 | #define AR_PHY_TIMING5 0x9924 | ||
208 | #define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE | ||
209 | #define AR_PHY_TIMING5_CYCPWR_THR1_S 1 | ||
210 | |||
211 | #define AR_PHY_POWER_TX_RATE1 0x9934 | ||
212 | #define AR_PHY_POWER_TX_RATE2 0x9938 | ||
213 | #define AR_PHY_POWER_TX_RATE_MAX 0x993c | ||
214 | #define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040 | ||
215 | |||
216 | #define AR_PHY_FRAME_CTL 0x9944 | ||
217 | #define AR_PHY_FRAME_CTL_TX_CLIP 0x00000038 | ||
218 | #define AR_PHY_FRAME_CTL_TX_CLIP_S 3 | ||
219 | |||
220 | #define AR_PHY_TXPWRADJ 0x994C | ||
221 | #define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA 0x00000FC0 | ||
222 | #define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S 6 | ||
223 | #define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX 0x00FC0000 | ||
224 | #define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18 | ||
225 | |||
226 | #define AR_PHY_RADAR_EXT 0x9940 | ||
227 | #define AR_PHY_RADAR_EXT_ENA 0x00004000 | ||
228 | |||
229 | #define AR_PHY_RADAR_0 0x9954 | ||
230 | #define AR_PHY_RADAR_0_ENA 0x00000001 | ||
231 | #define AR_PHY_RADAR_0_FFT_ENA 0x80000000 | ||
232 | #define AR_PHY_RADAR_0_INBAND 0x0000003e | ||
233 | #define AR_PHY_RADAR_0_INBAND_S 1 | ||
234 | #define AR_PHY_RADAR_0_PRSSI 0x00000FC0 | ||
235 | #define AR_PHY_RADAR_0_PRSSI_S 6 | ||
236 | #define AR_PHY_RADAR_0_HEIGHT 0x0003F000 | ||
237 | #define AR_PHY_RADAR_0_HEIGHT_S 12 | ||
238 | #define AR_PHY_RADAR_0_RRSSI 0x00FC0000 | ||
239 | #define AR_PHY_RADAR_0_RRSSI_S 18 | ||
240 | #define AR_PHY_RADAR_0_FIRPWR 0x7F000000 | ||
241 | #define AR_PHY_RADAR_0_FIRPWR_S 24 | ||
242 | |||
243 | #define AR_PHY_RADAR_1 0x9958 | ||
244 | #define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000 | ||
245 | #define AR_PHY_RADAR_1_USE_FIR128 0x00400000 | ||
246 | #define AR_PHY_RADAR_1_RELPWR_THRESH 0x003F0000 | ||
247 | #define AR_PHY_RADAR_1_RELPWR_THRESH_S 16 | ||
248 | #define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000 | ||
249 | #define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000 | ||
250 | #define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000 | ||
251 | #define AR_PHY_RADAR_1_RELSTEP_THRESH 0x00001F00 | ||
252 | #define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8 | ||
253 | #define AR_PHY_RADAR_1_MAXLEN 0x000000FF | ||
254 | #define AR_PHY_RADAR_1_MAXLEN_S 0 | ||
255 | |||
256 | #define AR_PHY_SWITCH_CHAIN_0 0x9960 | ||
257 | #define AR_PHY_SWITCH_COM 0x9964 | ||
258 | |||
259 | #define AR_PHY_SIGMA_DELTA 0x996C | ||
260 | #define AR_PHY_SIGMA_DELTA_ADC_SEL 0x00000003 | ||
261 | #define AR_PHY_SIGMA_DELTA_ADC_SEL_S 0 | ||
262 | #define AR_PHY_SIGMA_DELTA_FILT2 0x000000F8 | ||
263 | #define AR_PHY_SIGMA_DELTA_FILT2_S 3 | ||
264 | #define AR_PHY_SIGMA_DELTA_FILT1 0x00001F00 | ||
265 | #define AR_PHY_SIGMA_DELTA_FILT1_S 8 | ||
266 | #define AR_PHY_SIGMA_DELTA_ADC_CLIP 0x01FFE000 | ||
267 | #define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13 | ||
268 | |||
269 | #define AR_PHY_RESTART 0x9970 | ||
270 | #define AR_PHY_RESTART_DIV_GC 0x001C0000 | ||
271 | #define AR_PHY_RESTART_DIV_GC_S 18 | ||
272 | |||
273 | #define AR_PHY_RFBUS_REQ 0x997C | ||
274 | #define AR_PHY_RFBUS_REQ_EN 0x00000001 | ||
275 | |||
276 | #define AR_PHY_TIMING7 0x9980 | ||
277 | #define AR_PHY_TIMING8 0x9984 | ||
278 | #define AR_PHY_TIMING8_PILOT_MASK_2 0x000FFFFF | ||
279 | #define AR_PHY_TIMING8_PILOT_MASK_2_S 0 | ||
280 | |||
281 | #define AR_PHY_BIN_MASK2_1 0x9988 | ||
282 | #define AR_PHY_BIN_MASK2_2 0x998c | ||
283 | #define AR_PHY_BIN_MASK2_3 0x9990 | ||
284 | #define AR_PHY_BIN_MASK2_4 0x9994 | ||
285 | |||
286 | #define AR_PHY_BIN_MASK_1 0x9900 | ||
287 | #define AR_PHY_BIN_MASK_2 0x9904 | ||
288 | #define AR_PHY_BIN_MASK_3 0x9908 | ||
289 | |||
290 | #define AR_PHY_MASK_CTL 0x990c | ||
291 | |||
292 | #define AR_PHY_BIN_MASK2_4_MASK_4 0x00003FFF | ||
293 | #define AR_PHY_BIN_MASK2_4_MASK_4_S 0 | ||
294 | |||
295 | #define AR_PHY_TIMING9 0x9998 | ||
296 | #define AR_PHY_TIMING10 0x999c | ||
297 | #define AR_PHY_TIMING10_PILOT_MASK_2 0x000FFFFF | ||
298 | #define AR_PHY_TIMING10_PILOT_MASK_2_S 0 | ||
299 | |||
300 | #define AR_PHY_TIMING11 0x99a0 | ||
301 | #define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF | ||
302 | #define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0 | ||
303 | #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 | ||
304 | #define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 | ||
305 | #define AR_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000 | ||
306 | #define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000 | ||
307 | |||
308 | #define AR_PHY_RX_CHAINMASK 0x99a4 | ||
309 | #define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12)) | ||
310 | #define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000 | ||
311 | #define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000 | ||
312 | #define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac | ||
313 | |||
314 | #define AR_PHY_EXT_CCA0 0x99b8 | ||
315 | #define AR_PHY_EXT_CCA0_THRESH62 0x000000FF | ||
316 | #define AR_PHY_EXT_CCA0_THRESH62_S 0 | ||
317 | |||
318 | #define AR_PHY_EXT_CCA 0x99bc | ||
319 | #define AR_PHY_EXT_CCA_CYCPWR_THR1 0x0000FE00 | ||
320 | #define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9 | ||
321 | #define AR_PHY_EXT_CCA_THRESH62 0x007F0000 | ||
322 | #define AR_PHY_EXT_CCA_THRESH62_S 16 | ||
323 | #define AR_PHY_EXT_MINCCA_PWR 0xFF800000 | ||
324 | #define AR_PHY_EXT_MINCCA_PWR_S 23 | ||
325 | #define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000 | ||
326 | #define AR9280_PHY_EXT_MINCCA_PWR_S 16 | ||
327 | |||
328 | #define AR_PHY_SFCORR_EXT 0x99c0 | ||
329 | #define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F | ||
330 | #define AR_PHY_SFCORR_EXT_M1_THRESH_S 0 | ||
331 | #define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80 | ||
332 | #define AR_PHY_SFCORR_EXT_M2_THRESH_S 7 | ||
333 | #define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000 | ||
334 | #define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14 | ||
335 | #define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000 | ||
336 | #define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21 | ||
337 | #define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28 | ||
338 | |||
339 | #define AR_PHY_HALFGI 0x99D0 | ||
340 | #define AR_PHY_HALFGI_DSC_MAN 0x0007FFF0 | ||
341 | #define AR_PHY_HALFGI_DSC_MAN_S 4 | ||
342 | #define AR_PHY_HALFGI_DSC_EXP 0x0000000F | ||
343 | #define AR_PHY_HALFGI_DSC_EXP_S 0 | ||
344 | |||
345 | #define AR_PHY_CHAN_INFO_MEMORY 0x99DC | ||
346 | #define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001 | ||
347 | |||
348 | #define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0 | ||
349 | |||
350 | #define AR_PHY_M_SLEEP 0x99f0 | ||
351 | #define AR_PHY_REFCLKDLY 0x99f4 | ||
352 | #define AR_PHY_REFCLKPD 0x99f8 | ||
353 | |||
354 | #define AR_PHY_CALMODE 0x99f0 | ||
355 | |||
356 | #define AR_PHY_CALMODE_IQ 0x00000000 | ||
357 | #define AR_PHY_CALMODE_ADC_GAIN 0x00000001 | ||
358 | #define AR_PHY_CALMODE_ADC_DC_PER 0x00000002 | ||
359 | #define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003 | ||
360 | |||
361 | #define AR_PHY_CAL_MEAS_0(_i) (0x9c10 + ((_i) << 12)) | ||
362 | #define AR_PHY_CAL_MEAS_1(_i) (0x9c14 + ((_i) << 12)) | ||
363 | #define AR_PHY_CAL_MEAS_2(_i) (0x9c18 + ((_i) << 12)) | ||
364 | #define AR_PHY_CAL_MEAS_3(_i) (0x9c1c + ((_i) << 12)) | ||
365 | |||
366 | #define AR_PHY_CURRENT_RSSI 0x9c1c | ||
367 | #define AR9280_PHY_CURRENT_RSSI 0x9c3c | ||
368 | |||
369 | #define AR_PHY_RFBUS_GRANT 0x9C20 | ||
370 | #define AR_PHY_RFBUS_GRANT_EN 0x00000001 | ||
371 | |||
372 | #define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4 | ||
373 | #define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320 | ||
374 | |||
375 | #define AR_PHY_CHAN_INFO_GAIN 0x9CFC | ||
376 | |||
377 | #define AR_PHY_MODE 0xA200 | ||
378 | #define AR_PHY_MODE_AR2133 0x08 | ||
379 | #define AR_PHY_MODE_AR5111 0x00 | ||
380 | #define AR_PHY_MODE_AR5112 0x08 | ||
381 | #define AR_PHY_MODE_DYNAMIC 0x04 | ||
382 | #define AR_PHY_MODE_RF2GHZ 0x02 | ||
383 | #define AR_PHY_MODE_RF5GHZ 0x00 | ||
384 | #define AR_PHY_MODE_CCK 0x01 | ||
385 | #define AR_PHY_MODE_OFDM 0x00 | ||
386 | #define AR_PHY_MODE_DYN_CCK_DISABLE 0x100 | ||
387 | |||
388 | #define AR_PHY_CCK_TX_CTRL 0xA204 | ||
389 | #define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010 | ||
390 | #define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000C | ||
391 | #define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2 | ||
392 | |||
393 | #define AR_PHY_CCK_DETECT 0xA208 | ||
394 | #define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F | ||
395 | #define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0 | ||
396 | /* [12:6] settling time for antenna switch */ | ||
397 | #define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0 | ||
398 | #define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6 | ||
399 | #define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 | ||
400 | |||
401 | #define AR_PHY_GAIN_2GHZ 0xA20C | ||
402 | #define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000 | ||
403 | #define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18 | ||
404 | #define AR_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003C00 | ||
405 | #define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S 10 | ||
406 | #define AR_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001F | ||
407 | #define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S 0 | ||
408 | |||
409 | #define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003E0000 | ||
410 | #define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17 | ||
411 | #define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001F000 | ||
412 | #define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12 | ||
413 | #define AR_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000FC0 | ||
414 | #define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S 6 | ||
415 | #define AR_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003F | ||
416 | #define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S 0 | ||
417 | |||
418 | #define AR_PHY_CCK_RXCTRL4 0xA21C | ||
419 | #define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01F80000 | ||
420 | #define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19 | ||
421 | |||
422 | #define AR_PHY_DAG_CTRLCCK 0xA228 | ||
423 | #define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200 | ||
424 | #define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00 | ||
425 | #define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10 | ||
426 | |||
427 | #define AR_PHY_FORCE_CLKEN_CCK 0xA22C | ||
428 | #define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX 0x00000040 | ||
429 | |||
430 | #define AR_PHY_POWER_TX_RATE3 0xA234 | ||
431 | #define AR_PHY_POWER_TX_RATE4 0xA238 | ||
432 | |||
433 | #define AR_PHY_SCRM_SEQ_XR 0xA23C | ||
434 | #define AR_PHY_HEADER_DETECT_XR 0xA240 | ||
435 | #define AR_PHY_CHIRP_DETECTED_XR 0xA244 | ||
436 | #define AR_PHY_BLUETOOTH 0xA254 | ||
437 | |||
438 | #define AR_PHY_TPCRG1 0xA258 | ||
439 | #define AR_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000 | ||
440 | #define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14 | ||
441 | |||
442 | #define AR_PHY_TPCRG1_PD_GAIN_1 0x00030000 | ||
443 | #define AR_PHY_TPCRG1_PD_GAIN_1_S 16 | ||
444 | #define AR_PHY_TPCRG1_PD_GAIN_2 0x000C0000 | ||
445 | #define AR_PHY_TPCRG1_PD_GAIN_2_S 18 | ||
446 | #define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000 | ||
447 | #define AR_PHY_TPCRG1_PD_GAIN_3_S 20 | ||
448 | |||
449 | #define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000 | ||
450 | #define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22 | ||
451 | |||
452 | #define AR_PHY_TX_PWRCTRL4 0xa264 | ||
453 | #define AR_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001 | ||
454 | #define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0 | ||
455 | #define AR_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001FE | ||
456 | #define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1 | ||
457 | |||
458 | #define AR_PHY_TX_PWRCTRL6_0 0xa270 | ||
459 | #define AR_PHY_TX_PWRCTRL6_1 0xb270 | ||
460 | #define AR_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000 | ||
461 | #define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24 | ||
462 | |||
463 | #define AR_PHY_TX_PWRCTRL7 0xa274 | ||
464 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000 | ||
465 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 | ||
466 | |||
467 | #define AR_PHY_TX_PWRCTRL9 0xa27C | ||
468 | #define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00 | ||
469 | #define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 | ||
470 | |||
471 | #define AR_PHY_TX_GAIN_TBL1 0xa300 | ||
472 | #define AR_PHY_TX_GAIN 0x0007F000 | ||
473 | #define AR_PHY_TX_GAIN_S 12 | ||
474 | |||
475 | #define AR_PHY_VIT_MASK2_M_46_61 0xa3a0 | ||
476 | #define AR_PHY_MASK2_M_31_45 0xa3a4 | ||
477 | #define AR_PHY_MASK2_M_16_30 0xa3a8 | ||
478 | #define AR_PHY_MASK2_M_00_15 0xa3ac | ||
479 | #define AR_PHY_MASK2_P_15_01 0xa3b8 | ||
480 | #define AR_PHY_MASK2_P_30_16 0xa3bc | ||
481 | #define AR_PHY_MASK2_P_45_31 0xa3c0 | ||
482 | #define AR_PHY_MASK2_P_61_45 0xa3c4 | ||
483 | #define AR_PHY_SPUR_REG 0x994c | ||
484 | |||
485 | #define AR_PHY_SPUR_REG_MASK_RATE_CNTL (0xFF << 18) | ||
486 | #define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18 | ||
487 | |||
488 | #define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000 | ||
489 | #define AR_PHY_SPUR_REG_MASK_RATE_SELECT (0xFF << 9) | ||
490 | #define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S 9 | ||
491 | #define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100 | ||
492 | #define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7F | ||
493 | #define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0 | ||
494 | |||
495 | #define AR_PHY_PILOT_MASK_01_30 0xa3b0 | ||
496 | #define AR_PHY_PILOT_MASK_31_60 0xa3b4 | ||
497 | |||
498 | #define AR_PHY_CHANNEL_MASK_01_30 0x99d4 | ||
499 | #define AR_PHY_CHANNEL_MASK_31_60 0x99d8 | ||
500 | |||
501 | #define AR_PHY_ANALOG_SWAP 0xa268 | ||
502 | #define AR_PHY_SWAP_ALT_CHAIN 0x00000040 | ||
503 | |||
504 | #define AR_PHY_TPCRG5 0xA26C | ||
505 | #define AR_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000F | ||
506 | #define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0 | ||
507 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003F0 | ||
508 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4 | ||
509 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000FC00 | ||
510 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10 | ||
511 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003F0000 | ||
512 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16 | ||
513 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000 | ||
514 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22 | ||
515 | |||
516 | /* Carrier leak calibration control, do it after AGC calibration */ | ||
517 | #define AR_PHY_CL_CAL_CTL 0xA358 | ||
518 | #define AR_PHY_CL_CAL_ENABLE 0x00000002 | ||
519 | #define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001 | ||
520 | |||
521 | #define AR_PHY_POWER_TX_RATE5 0xA38C | ||
522 | #define AR_PHY_POWER_TX_RATE6 0xA390 | ||
523 | |||
524 | #define AR_PHY_CAL_CHAINMASK 0xA39C | ||
525 | |||
526 | #define AR_PHY_POWER_TX_SUB 0xA3C8 | ||
527 | #define AR_PHY_POWER_TX_RATE7 0xA3CC | ||
528 | #define AR_PHY_POWER_TX_RATE8 0xA3D0 | ||
529 | #define AR_PHY_POWER_TX_RATE9 0xA3D4 | ||
530 | |||
531 | #define AR_PHY_XPA_CFG 0xA3D8 | ||
532 | #define AR_PHY_FORCE_XPA_CFG 0x000000001 | ||
533 | #define AR_PHY_FORCE_XPA_CFG_S 0 | ||
534 | |||
535 | #define AR_PHY_CH1_CCA 0xa864 | ||
536 | #define AR_PHY_CH1_MINCCA_PWR 0x0FF80000 | ||
537 | #define AR_PHY_CH1_MINCCA_PWR_S 19 | ||
538 | #define AR9280_PHY_CH1_MINCCA_PWR 0x1FF00000 | ||
539 | #define AR9280_PHY_CH1_MINCCA_PWR_S 20 | ||
540 | |||
541 | #define AR_PHY_CH2_CCA 0xb864 | ||
542 | #define AR_PHY_CH2_MINCCA_PWR 0x0FF80000 | ||
543 | #define AR_PHY_CH2_MINCCA_PWR_S 19 | ||
544 | |||
545 | #define AR_PHY_CH1_EXT_CCA 0xa9bc | ||
546 | #define AR_PHY_CH1_EXT_MINCCA_PWR 0xFF800000 | ||
547 | #define AR_PHY_CH1_EXT_MINCCA_PWR_S 23 | ||
548 | #define AR9280_PHY_CH1_EXT_MINCCA_PWR 0x01FF0000 | ||
549 | #define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16 | ||
550 | |||
551 | #define AR_PHY_CH2_EXT_CCA 0xb9bc | ||
552 | #define AR_PHY_CH2_EXT_MINCCA_PWR 0xFF800000 | ||
553 | #define AR_PHY_CH2_EXT_MINCCA_PWR_S 23 | ||
554 | |||
555 | #define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \ | ||
556 | int r; \ | ||
557 | for (r = 0; r < ((iniarray)->ia_rows); r++) { \ | ||
558 | REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \ | ||
559 | DO_DELAY(regWr); \ | ||
560 | } \ | ||
561 | } while (0) | ||
562 | |||
563 | #define ATH9K_IS_MIC_ENABLED(ah) \ | ||
564 | ((ah)->sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE) | ||
565 | |||
566 | #define ANTSWAP_AB 0x0001 | ||
567 | #define REDUCE_CHAIN_0 0x00000050 | ||
568 | #define REDUCE_CHAIN_1 0x00000051 | ||
569 | |||
570 | #define RF_BANK_SETUP(_bank, _iniarray, _col) do { \ | ||
571 | int i; \ | ||
572 | for (i = 0; i < (_iniarray)->ia_rows; i++) \ | ||
573 | (_bank)[i] = INI_RA((_iniarray), i, _col);; \ | ||
574 | } while (0) | ||
575 | |||
576 | #endif | ||
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c deleted file mode 100644 index a13668b9b6dc..000000000000 --- a/drivers/net/wireless/ath9k/rc.c +++ /dev/null | |||
@@ -1,1752 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004 Video54 Technologies, Inc. | ||
3 | * Copyright (c) 2004-2009 Atheros Communications, Inc. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and/or distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #include "ath9k.h" | ||
19 | |||
20 | static struct ath_rate_table ar5416_11na_ratetable = { | ||
21 | 42, | ||
22 | { | ||
23 | { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ | ||
24 | 5400, 0x0b, 0x00, 12, | ||
25 | 0, 2, 1, 0, 0, 0, 0, 0 }, | ||
26 | { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ | ||
27 | 7800, 0x0f, 0x00, 18, | ||
28 | 0, 3, 1, 1, 1, 1, 1, 0 }, | ||
29 | { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ | ||
30 | 10000, 0x0a, 0x00, 24, | ||
31 | 2, 4, 2, 2, 2, 2, 2, 0 }, | ||
32 | { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ | ||
33 | 13900, 0x0e, 0x00, 36, | ||
34 | 2, 6, 2, 3, 3, 3, 3, 0 }, | ||
35 | { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ | ||
36 | 17300, 0x09, 0x00, 48, | ||
37 | 4, 10, 3, 4, 4, 4, 4, 0 }, | ||
38 | { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ | ||
39 | 23000, 0x0d, 0x00, 72, | ||
40 | 4, 14, 3, 5, 5, 5, 5, 0 }, | ||
41 | { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ | ||
42 | 27400, 0x08, 0x00, 96, | ||
43 | 4, 20, 3, 6, 6, 6, 6, 0 }, | ||
44 | { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ | ||
45 | 29300, 0x0c, 0x00, 108, | ||
46 | 4, 23, 3, 7, 7, 7, 7, 0 }, | ||
47 | { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ | ||
48 | 6400, 0x80, 0x00, 0, | ||
49 | 0, 2, 3, 8, 24, 8, 24, 3216 }, | ||
50 | { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ | ||
51 | 12700, 0x81, 0x00, 1, | ||
52 | 2, 4, 3, 9, 25, 9, 25, 6434 }, | ||
53 | { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ | ||
54 | 18800, 0x82, 0x00, 2, | ||
55 | 2, 6, 3, 10, 26, 10, 26, 9650 }, | ||
56 | { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ | ||
57 | 25000, 0x83, 0x00, 3, | ||
58 | 4, 10, 3, 11, 27, 11, 27, 12868 }, | ||
59 | { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ | ||
60 | 36700, 0x84, 0x00, 4, | ||
61 | 4, 14, 3, 12, 28, 12, 28, 19304 }, | ||
62 | { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ | ||
63 | 48100, 0x85, 0x00, 5, | ||
64 | 4, 20, 3, 13, 29, 13, 29, 25740 }, | ||
65 | { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ | ||
66 | 53500, 0x86, 0x00, 6, | ||
67 | 4, 23, 3, 14, 30, 14, 30, 28956 }, | ||
68 | { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ | ||
69 | 59000, 0x87, 0x00, 7, | ||
70 | 4, 25, 3, 15, 31, 15, 32, 32180 }, | ||
71 | { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ | ||
72 | 12700, 0x88, 0x00, | ||
73 | 8, 0, 2, 3, 16, 33, 16, 33, 6430 }, | ||
74 | { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ | ||
75 | 24800, 0x89, 0x00, 9, | ||
76 | 2, 4, 3, 17, 34, 17, 34, 12860 }, | ||
77 | { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ | ||
78 | 36600, 0x8a, 0x00, 10, | ||
79 | 2, 6, 3, 18, 35, 18, 35, 19300 }, | ||
80 | { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ | ||
81 | 48100, 0x8b, 0x00, 11, | ||
82 | 4, 10, 3, 19, 36, 19, 36, 25736 }, | ||
83 | { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ | ||
84 | 69500, 0x8c, 0x00, 12, | ||
85 | 4, 14, 3, 20, 37, 20, 37, 38600 }, | ||
86 | { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ | ||
87 | 89500, 0x8d, 0x00, 13, | ||
88 | 4, 20, 3, 21, 38, 21, 38, 51472 }, | ||
89 | { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ | ||
90 | 98900, 0x8e, 0x00, 14, | ||
91 | 4, 23, 3, 22, 39, 22, 39, 57890 }, | ||
92 | { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ | ||
93 | 108300, 0x8f, 0x00, 15, | ||
94 | 4, 25, 3, 23, 40, 23, 41, 64320 }, | ||
95 | { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ | ||
96 | 13200, 0x80, 0x00, 0, | ||
97 | 0, 2, 3, 8, 24, 24, 24, 6684 }, | ||
98 | { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ | ||
99 | 25900, 0x81, 0x00, 1, | ||
100 | 2, 4, 3, 9, 25, 25, 25, 13368 }, | ||
101 | { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ | ||
102 | 38600, 0x82, 0x00, 2, | ||
103 | 2, 6, 3, 10, 26, 26, 26, 20052 }, | ||
104 | { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ | ||
105 | 49800, 0x83, 0x00, 3, | ||
106 | 4, 10, 3, 11, 27, 27, 27, 26738 }, | ||
107 | { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ | ||
108 | 72200, 0x84, 0x00, 4, | ||
109 | 4, 14, 3, 12, 28, 28, 28, 40104 }, | ||
110 | { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ | ||
111 | 92900, 0x85, 0x00, 5, | ||
112 | 4, 20, 3, 13, 29, 29, 29, 53476 }, | ||
113 | { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ | ||
114 | 102700, 0x86, 0x00, 6, | ||
115 | 4, 23, 3, 14, 30, 30, 30, 60156 }, | ||
116 | { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ | ||
117 | 112000, 0x87, 0x00, 7, | ||
118 | 4, 25, 3, 15, 31, 32, 32, 66840 }, | ||
119 | { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ | ||
120 | 122000, 0x87, 0x00, 7, | ||
121 | 4, 25, 3, 15, 31, 32, 32, 74200 }, | ||
122 | { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ | ||
123 | 25800, 0x88, 0x00, 8, | ||
124 | 0, 2, 3, 16, 33, 33, 33, 13360 }, | ||
125 | { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ | ||
126 | 49800, 0x89, 0x00, 9, | ||
127 | 2, 4, 3, 17, 34, 34, 34, 26720 }, | ||
128 | { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ | ||
129 | 71900, 0x8a, 0x00, 10, | ||
130 | 2, 6, 3, 18, 35, 35, 35, 40080 }, | ||
131 | { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ | ||
132 | 92500, 0x8b, 0x00, 11, | ||
133 | 4, 10, 3, 19, 36, 36, 36, 53440 }, | ||
134 | { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ | ||
135 | 130300, 0x8c, 0x00, 12, | ||
136 | 4, 14, 3, 20, 37, 37, 37, 80160 }, | ||
137 | { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ | ||
138 | 162800, 0x8d, 0x00, 13, | ||
139 | 4, 20, 3, 21, 38, 38, 38, 106880 }, | ||
140 | { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ | ||
141 | 178200, 0x8e, 0x00, 14, | ||
142 | 4, 23, 3, 22, 39, 39, 39, 120240 }, | ||
143 | { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ | ||
144 | 192100, 0x8f, 0x00, 15, | ||
145 | 4, 25, 3, 23, 40, 41, 41, 133600 }, | ||
146 | { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ | ||
147 | 207000, 0x8f, 0x00, 15, | ||
148 | 4, 25, 3, 23, 40, 41, 41, 148400 }, | ||
149 | }, | ||
150 | 50, /* probe interval */ | ||
151 | 50, /* rssi reduce interval */ | ||
152 | WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ | ||
153 | }; | ||
154 | |||
155 | /* 4ms frame limit not used for NG mode. The values filled | ||
156 | * for HT are the 64K max aggregate limit */ | ||
157 | |||
158 | static struct ath_rate_table ar5416_11ng_ratetable = { | ||
159 | 46, | ||
160 | { | ||
161 | { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ | ||
162 | 900, 0x1b, 0x00, 2, | ||
163 | 0, 0, 1, 0, 0, 0, 0, 0 }, | ||
164 | { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ | ||
165 | 1900, 0x1a, 0x04, 4, | ||
166 | 1, 1, 1, 1, 1, 1, 1, 0 }, | ||
167 | { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ | ||
168 | 4900, 0x19, 0x04, 11, | ||
169 | 2, 2, 2, 2, 2, 2, 2, 0 }, | ||
170 | { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ | ||
171 | 8100, 0x18, 0x04, 22, | ||
172 | 3, 3, 2, 3, 3, 3, 3, 0 }, | ||
173 | { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ | ||
174 | 5400, 0x0b, 0x00, 12, | ||
175 | 4, 2, 1, 4, 4, 4, 4, 0 }, | ||
176 | { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ | ||
177 | 7800, 0x0f, 0x00, 18, | ||
178 | 4, 3, 1, 5, 5, 5, 5, 0 }, | ||
179 | { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ | ||
180 | 10100, 0x0a, 0x00, 24, | ||
181 | 6, 4, 1, 6, 6, 6, 6, 0 }, | ||
182 | { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ | ||
183 | 14100, 0x0e, 0x00, 36, | ||
184 | 6, 6, 2, 7, 7, 7, 7, 0 }, | ||
185 | { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ | ||
186 | 17700, 0x09, 0x00, 48, | ||
187 | 8, 10, 3, 8, 8, 8, 8, 0 }, | ||
188 | { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ | ||
189 | 23700, 0x0d, 0x00, 72, | ||
190 | 8, 14, 3, 9, 9, 9, 9, 0 }, | ||
191 | { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ | ||
192 | 27400, 0x08, 0x00, 96, | ||
193 | 8, 20, 3, 10, 10, 10, 10, 0 }, | ||
194 | { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ | ||
195 | 30900, 0x0c, 0x00, 108, | ||
196 | 8, 23, 3, 11, 11, 11, 11, 0 }, | ||
197 | { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ | ||
198 | 6400, 0x80, 0x00, 0, | ||
199 | 4, 2, 3, 12, 28, 12, 28, 3216 }, | ||
200 | { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ | ||
201 | 12700, 0x81, 0x00, 1, | ||
202 | 6, 4, 3, 13, 29, 13, 29, 6434 }, | ||
203 | { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ | ||
204 | 18800, 0x82, 0x00, 2, | ||
205 | 6, 6, 3, 14, 30, 14, 30, 9650 }, | ||
206 | { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ | ||
207 | 25000, 0x83, 0x00, 3, | ||
208 | 8, 10, 3, 15, 31, 15, 31, 12868 }, | ||
209 | { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ | ||
210 | 36700, 0x84, 0x00, 4, | ||
211 | 8, 14, 3, 16, 32, 16, 32, 19304 }, | ||
212 | { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ | ||
213 | 48100, 0x85, 0x00, 5, | ||
214 | 8, 20, 3, 17, 33, 17, 33, 25740 }, | ||
215 | { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ | ||
216 | 53500, 0x86, 0x00, 6, | ||
217 | 8, 23, 3, 18, 34, 18, 34, 28956 }, | ||
218 | { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ | ||
219 | 59000, 0x87, 0x00, 7, | ||
220 | 8, 25, 3, 19, 35, 19, 36, 32180 }, | ||
221 | { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ | ||
222 | 12700, 0x88, 0x00, 8, | ||
223 | 4, 2, 3, 20, 37, 20, 37, 6430 }, | ||
224 | { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ | ||
225 | 24800, 0x89, 0x00, 9, | ||
226 | 6, 4, 3, 21, 38, 21, 38, 12860 }, | ||
227 | { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ | ||
228 | 36600, 0x8a, 0x00, 10, | ||
229 | 6, 6, 3, 22, 39, 22, 39, 19300 }, | ||
230 | { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ | ||
231 | 48100, 0x8b, 0x00, 11, | ||
232 | 8, 10, 3, 23, 40, 23, 40, 25736 }, | ||
233 | { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ | ||
234 | 69500, 0x8c, 0x00, 12, | ||
235 | 8, 14, 3, 24, 41, 24, 41, 38600 }, | ||
236 | { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ | ||
237 | 89500, 0x8d, 0x00, 13, | ||
238 | 8, 20, 3, 25, 42, 25, 42, 51472 }, | ||
239 | { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ | ||
240 | 98900, 0x8e, 0x00, 14, | ||
241 | 8, 23, 3, 26, 43, 26, 44, 57890 }, | ||
242 | { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ | ||
243 | 108300, 0x8f, 0x00, 15, | ||
244 | 8, 25, 3, 27, 44, 27, 45, 64320 }, | ||
245 | { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ | ||
246 | 13200, 0x80, 0x00, 0, | ||
247 | 8, 2, 3, 12, 28, 28, 28, 6684 }, | ||
248 | { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ | ||
249 | 25900, 0x81, 0x00, 1, | ||
250 | 8, 4, 3, 13, 29, 29, 29, 13368 }, | ||
251 | { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ | ||
252 | 38600, 0x82, 0x00, 2, | ||
253 | 8, 6, 3, 14, 30, 30, 30, 20052 }, | ||
254 | { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ | ||
255 | 49800, 0x83, 0x00, 3, | ||
256 | 8, 10, 3, 15, 31, 31, 31, 26738 }, | ||
257 | { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ | ||
258 | 72200, 0x84, 0x00, 4, | ||
259 | 8, 14, 3, 16, 32, 32, 32, 40104 }, | ||
260 | { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ | ||
261 | 92900, 0x85, 0x00, 5, | ||
262 | 8, 20, 3, 17, 33, 33, 33, 53476 }, | ||
263 | { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ | ||
264 | 102700, 0x86, 0x00, 6, | ||
265 | 8, 23, 3, 18, 34, 34, 34, 60156 }, | ||
266 | { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ | ||
267 | 112000, 0x87, 0x00, 7, | ||
268 | 8, 23, 3, 19, 35, 36, 36, 66840 }, | ||
269 | { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ | ||
270 | 122000, 0x87, 0x00, 7, | ||
271 | 8, 25, 3, 19, 35, 36, 36, 74200 }, | ||
272 | { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ | ||
273 | 25800, 0x88, 0x00, 8, | ||
274 | 8, 2, 3, 20, 37, 37, 37, 13360 }, | ||
275 | { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ | ||
276 | 49800, 0x89, 0x00, 9, | ||
277 | 8, 4, 3, 21, 38, 38, 38, 26720 }, | ||
278 | { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ | ||
279 | 71900, 0x8a, 0x00, 10, | ||
280 | 8, 6, 3, 22, 39, 39, 39, 40080 }, | ||
281 | { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ | ||
282 | 92500, 0x8b, 0x00, 11, | ||
283 | 8, 10, 3, 23, 40, 40, 40, 53440 }, | ||
284 | { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ | ||
285 | 130300, 0x8c, 0x00, 12, | ||
286 | 8, 14, 3, 24, 41, 41, 41, 80160 }, | ||
287 | { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ | ||
288 | 162800, 0x8d, 0x00, 13, | ||
289 | 8, 20, 3, 25, 42, 42, 42, 106880 }, | ||
290 | { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ | ||
291 | 178200, 0x8e, 0x00, 14, | ||
292 | 8, 23, 3, 26, 43, 43, 43, 120240 }, | ||
293 | { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ | ||
294 | 192100, 0x8f, 0x00, 15, | ||
295 | 8, 23, 3, 27, 44, 45, 45, 133600 }, | ||
296 | { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ | ||
297 | 207000, 0x8f, 0x00, 15, | ||
298 | 8, 25, 3, 27, 44, 45, 45, 148400 }, | ||
299 | }, | ||
300 | 50, /* probe interval */ | ||
301 | 50, /* rssi reduce interval */ | ||
302 | WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ | ||
303 | }; | ||
304 | |||
305 | static struct ath_rate_table ar5416_11a_ratetable = { | ||
306 | 8, | ||
307 | { | ||
308 | { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ | ||
309 | 5400, 0x0b, 0x00, (0x80|12), | ||
310 | 0, 2, 1, 0, 0 }, | ||
311 | { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ | ||
312 | 7800, 0x0f, 0x00, 18, | ||
313 | 0, 3, 1, 1, 0 }, | ||
314 | { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ | ||
315 | 10000, 0x0a, 0x00, (0x80|24), | ||
316 | 2, 4, 2, 2, 0 }, | ||
317 | { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ | ||
318 | 13900, 0x0e, 0x00, 36, | ||
319 | 2, 6, 2, 3, 0 }, | ||
320 | { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ | ||
321 | 17300, 0x09, 0x00, (0x80|48), | ||
322 | 4, 10, 3, 4, 0 }, | ||
323 | { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ | ||
324 | 23000, 0x0d, 0x00, 72, | ||
325 | 4, 14, 3, 5, 0 }, | ||
326 | { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ | ||
327 | 27400, 0x08, 0x00, 96, | ||
328 | 4, 19, 3, 6, 0 }, | ||
329 | { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ | ||
330 | 29300, 0x0c, 0x00, 108, | ||
331 | 4, 23, 3, 7, 0 }, | ||
332 | }, | ||
333 | 50, /* probe interval */ | ||
334 | 50, /* rssi reduce interval */ | ||
335 | 0, /* Phy rates allowed initially */ | ||
336 | }; | ||
337 | |||
338 | static struct ath_rate_table ar5416_11g_ratetable = { | ||
339 | 12, | ||
340 | { | ||
341 | { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ | ||
342 | 900, 0x1b, 0x00, 2, | ||
343 | 0, 0, 1, 0, 0 }, | ||
344 | { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ | ||
345 | 1900, 0x1a, 0x04, 4, | ||
346 | 1, 1, 1, 1, 0 }, | ||
347 | { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ | ||
348 | 4900, 0x19, 0x04, 11, | ||
349 | 2, 2, 2, 2, 0 }, | ||
350 | { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ | ||
351 | 8100, 0x18, 0x04, 22, | ||
352 | 3, 3, 2, 3, 0 }, | ||
353 | { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ | ||
354 | 5400, 0x0b, 0x00, 12, | ||
355 | 4, 2, 1, 4, 0 }, | ||
356 | { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ | ||
357 | 7800, 0x0f, 0x00, 18, | ||
358 | 4, 3, 1, 5, 0 }, | ||
359 | { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ | ||
360 | 10000, 0x0a, 0x00, 24, | ||
361 | 6, 4, 1, 6, 0 }, | ||
362 | { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ | ||
363 | 13900, 0x0e, 0x00, 36, | ||
364 | 6, 6, 2, 7, 0 }, | ||
365 | { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ | ||
366 | 17300, 0x09, 0x00, 48, | ||
367 | 8, 10, 3, 8, 0 }, | ||
368 | { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ | ||
369 | 23000, 0x0d, 0x00, 72, | ||
370 | 8, 14, 3, 9, 0 }, | ||
371 | { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ | ||
372 | 27400, 0x08, 0x00, 96, | ||
373 | 8, 19, 3, 10, 0 }, | ||
374 | { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ | ||
375 | 29300, 0x0c, 0x00, 108, | ||
376 | 8, 23, 3, 11, 0 }, | ||
377 | }, | ||
378 | 50, /* probe interval */ | ||
379 | 50, /* rssi reduce interval */ | ||
380 | 0, /* Phy rates allowed initially */ | ||
381 | }; | ||
382 | |||
383 | static struct ath_rate_table ar5416_11b_ratetable = { | ||
384 | 4, | ||
385 | { | ||
386 | { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ | ||
387 | 900, 0x1b, 0x00, (0x80|2), | ||
388 | 0, 0, 1, 0, 0 }, | ||
389 | { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ | ||
390 | 1800, 0x1a, 0x04, (0x80|4), | ||
391 | 1, 1, 1, 1, 0 }, | ||
392 | { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ | ||
393 | 4300, 0x19, 0x04, (0x80|11), | ||
394 | 1, 2, 2, 2, 0 }, | ||
395 | { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ | ||
396 | 7100, 0x18, 0x04, (0x80|22), | ||
397 | 1, 4, 100, 3, 0 }, | ||
398 | }, | ||
399 | 100, /* probe interval */ | ||
400 | 100, /* rssi reduce interval */ | ||
401 | 0, /* Phy rates allowed initially */ | ||
402 | }; | ||
403 | |||
404 | static inline int8_t median(int8_t a, int8_t b, int8_t c) | ||
405 | { | ||
406 | if (a >= b) { | ||
407 | if (b >= c) | ||
408 | return b; | ||
409 | else if (a > c) | ||
410 | return c; | ||
411 | else | ||
412 | return a; | ||
413 | } else { | ||
414 | if (a >= c) | ||
415 | return a; | ||
416 | else if (b >= c) | ||
417 | return c; | ||
418 | else | ||
419 | return b; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | static void ath_rc_sort_validrates(struct ath_rate_table *rate_table, | ||
424 | struct ath_rate_priv *ath_rc_priv) | ||
425 | { | ||
426 | u8 i, j, idx, idx_next; | ||
427 | |||
428 | for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) { | ||
429 | for (j = 0; j <= i-1; j++) { | ||
430 | idx = ath_rc_priv->valid_rate_index[j]; | ||
431 | idx_next = ath_rc_priv->valid_rate_index[j+1]; | ||
432 | |||
433 | if (rate_table->info[idx].ratekbps > | ||
434 | rate_table->info[idx_next].ratekbps) { | ||
435 | ath_rc_priv->valid_rate_index[j] = idx_next; | ||
436 | ath_rc_priv->valid_rate_index[j+1] = idx; | ||
437 | } | ||
438 | } | ||
439 | } | ||
440 | } | ||
441 | |||
442 | static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv) | ||
443 | { | ||
444 | u8 i; | ||
445 | |||
446 | for (i = 0; i < ath_rc_priv->rate_table_size; i++) | ||
447 | ath_rc_priv->valid_rate_index[i] = 0; | ||
448 | } | ||
449 | |||
450 | static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv, | ||
451 | u8 index, int valid_tx_rate) | ||
452 | { | ||
453 | ASSERT(index <= ath_rc_priv->rate_table_size); | ||
454 | ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0; | ||
455 | } | ||
456 | |||
457 | static inline int ath_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv, | ||
458 | u8 index) | ||
459 | { | ||
460 | ASSERT(index <= ath_rc_priv->rate_table_size); | ||
461 | return ath_rc_priv->valid_rate_index[index]; | ||
462 | } | ||
463 | |||
464 | static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table, | ||
465 | struct ath_rate_priv *ath_rc_priv, | ||
466 | u8 cur_valid_txrate, | ||
467 | u8 *next_idx) | ||
468 | { | ||
469 | u8 i; | ||
470 | |||
471 | for (i = 0; i < ath_rc_priv->max_valid_rate - 1; i++) { | ||
472 | if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) { | ||
473 | *next_idx = ath_rc_priv->valid_rate_index[i+1]; | ||
474 | return 1; | ||
475 | } | ||
476 | } | ||
477 | |||
478 | /* No more valid rates */ | ||
479 | *next_idx = 0; | ||
480 | |||
481 | return 0; | ||
482 | } | ||
483 | |||
484 | /* Return true only for single stream */ | ||
485 | |||
486 | static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw) | ||
487 | { | ||
488 | if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG)) | ||
489 | return 0; | ||
490 | if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG)) | ||
491 | return 0; | ||
492 | if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG)) | ||
493 | return 0; | ||
494 | if (!ignore_cw && WLAN_RC_PHY_HT(phy)) | ||
495 | if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG)) | ||
496 | return 0; | ||
497 | if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG)) | ||
498 | return 0; | ||
499 | return 1; | ||
500 | } | ||
501 | |||
502 | static inline int | ||
503 | ath_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table, | ||
504 | struct ath_rate_priv *ath_rc_priv, | ||
505 | u8 cur_valid_txrate, u8 *next_idx) | ||
506 | { | ||
507 | int8_t i; | ||
508 | |||
509 | for (i = 1; i < ath_rc_priv->max_valid_rate ; i++) { | ||
510 | if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) { | ||
511 | *next_idx = ath_rc_priv->valid_rate_index[i-1]; | ||
512 | return 1; | ||
513 | } | ||
514 | } | ||
515 | |||
516 | return 0; | ||
517 | } | ||
518 | |||
519 | static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv, | ||
520 | struct ath_rate_table *rate_table, | ||
521 | u32 capflag) | ||
522 | { | ||
523 | u8 i, hi = 0; | ||
524 | u32 valid; | ||
525 | |||
526 | for (i = 0; i < rate_table->rate_cnt; i++) { | ||
527 | valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? | ||
528 | rate_table->info[i].valid_single_stream : | ||
529 | rate_table->info[i].valid); | ||
530 | if (valid == 1) { | ||
531 | u32 phy = rate_table->info[i].phy; | ||
532 | u8 valid_rate_count = 0; | ||
533 | |||
534 | if (!ath_rc_valid_phyrate(phy, capflag, 0)) | ||
535 | continue; | ||
536 | |||
537 | valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy]; | ||
538 | |||
539 | ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i; | ||
540 | ath_rc_priv->valid_phy_ratecnt[phy] += 1; | ||
541 | ath_rc_set_valid_txmask(ath_rc_priv, i, 1); | ||
542 | hi = A_MAX(hi, i); | ||
543 | } | ||
544 | } | ||
545 | |||
546 | return hi; | ||
547 | } | ||
548 | |||
549 | static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, | ||
550 | struct ath_rate_table *rate_table, | ||
551 | struct ath_rateset *rateset, | ||
552 | u32 capflag) | ||
553 | { | ||
554 | u8 i, j, hi = 0; | ||
555 | |||
556 | /* Use intersection of working rates and valid rates */ | ||
557 | for (i = 0; i < rateset->rs_nrates; i++) { | ||
558 | for (j = 0; j < rate_table->rate_cnt; j++) { | ||
559 | u32 phy = rate_table->info[j].phy; | ||
560 | u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? | ||
561 | rate_table->info[j].valid_single_stream : | ||
562 | rate_table->info[j].valid); | ||
563 | u8 rate = rateset->rs_rates[i]; | ||
564 | u8 dot11rate = rate_table->info[j].dot11rate; | ||
565 | |||
566 | /* We allow a rate only if its valid and the | ||
567 | * capflag matches one of the validity | ||
568 | * (VALID/VALID_20/VALID_40) flags */ | ||
569 | |||
570 | if (((rate & 0x7F) == (dot11rate & 0x7F)) && | ||
571 | ((valid & WLAN_RC_CAP_MODE(capflag)) == | ||
572 | WLAN_RC_CAP_MODE(capflag)) && | ||
573 | !WLAN_RC_PHY_HT(phy)) { | ||
574 | u8 valid_rate_count = 0; | ||
575 | |||
576 | if (!ath_rc_valid_phyrate(phy, capflag, 0)) | ||
577 | continue; | ||
578 | |||
579 | valid_rate_count = | ||
580 | ath_rc_priv->valid_phy_ratecnt[phy]; | ||
581 | |||
582 | ath_rc_priv->valid_phy_rateidx[phy] | ||
583 | [valid_rate_count] = j; | ||
584 | ath_rc_priv->valid_phy_ratecnt[phy] += 1; | ||
585 | ath_rc_set_valid_txmask(ath_rc_priv, j, 1); | ||
586 | hi = A_MAX(hi, j); | ||
587 | } | ||
588 | } | ||
589 | } | ||
590 | |||
591 | return hi; | ||
592 | } | ||
593 | |||
594 | static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, | ||
595 | struct ath_rate_table *rate_table, | ||
596 | u8 *mcs_set, u32 capflag) | ||
597 | { | ||
598 | struct ath_rateset *rateset = (struct ath_rateset *)mcs_set; | ||
599 | |||
600 | u8 i, j, hi = 0; | ||
601 | |||
602 | /* Use intersection of working rates and valid rates */ | ||
603 | for (i = 0; i < rateset->rs_nrates; i++) { | ||
604 | for (j = 0; j < rate_table->rate_cnt; j++) { | ||
605 | u32 phy = rate_table->info[j].phy; | ||
606 | u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? | ||
607 | rate_table->info[j].valid_single_stream : | ||
608 | rate_table->info[j].valid); | ||
609 | u8 rate = rateset->rs_rates[i]; | ||
610 | u8 dot11rate = rate_table->info[j].dot11rate; | ||
611 | |||
612 | if (((rate & 0x7F) != (dot11rate & 0x7F)) || | ||
613 | !WLAN_RC_PHY_HT(phy) || | ||
614 | !WLAN_RC_PHY_HT_VALID(valid, capflag)) | ||
615 | continue; | ||
616 | |||
617 | if (!ath_rc_valid_phyrate(phy, capflag, 0)) | ||
618 | continue; | ||
619 | |||
620 | ath_rc_priv->valid_phy_rateidx[phy] | ||
621 | [ath_rc_priv->valid_phy_ratecnt[phy]] = j; | ||
622 | ath_rc_priv->valid_phy_ratecnt[phy] += 1; | ||
623 | ath_rc_set_valid_txmask(ath_rc_priv, j, 1); | ||
624 | hi = A_MAX(hi, j); | ||
625 | } | ||
626 | } | ||
627 | |||
628 | return hi; | ||
629 | } | ||
630 | |||
631 | static u8 ath_rc_ratefind_ht(struct ath_softc *sc, | ||
632 | struct ath_rate_priv *ath_rc_priv, | ||
633 | struct ath_rate_table *rate_table, | ||
634 | int *is_probing) | ||
635 | { | ||
636 | u32 dt, best_thruput, this_thruput, now_msec; | ||
637 | u8 rate, next_rate, best_rate, maxindex, minindex; | ||
638 | int8_t rssi_last, rssi_reduce = 0, index = 0; | ||
639 | |||
640 | *is_probing = 0; | ||
641 | |||
642 | rssi_last = median(ath_rc_priv->rssi_last, | ||
643 | ath_rc_priv->rssi_last_prev, | ||
644 | ath_rc_priv->rssi_last_prev2); | ||
645 | |||
646 | /* | ||
647 | * Age (reduce) last ack rssi based on how old it is. | ||
648 | * The bizarre numbers are so the delta is 160msec, | ||
649 | * meaning we divide by 16. | ||
650 | * 0msec <= dt <= 25msec: don't derate | ||
651 | * 25msec <= dt <= 185msec: derate linearly from 0 to 10dB | ||
652 | * 185msec <= dt: derate by 10dB | ||
653 | */ | ||
654 | |||
655 | now_msec = jiffies_to_msecs(jiffies); | ||
656 | dt = now_msec - ath_rc_priv->rssi_time; | ||
657 | |||
658 | if (dt >= 185) | ||
659 | rssi_reduce = 10; | ||
660 | else if (dt >= 25) | ||
661 | rssi_reduce = (u8)((dt - 25) >> 4); | ||
662 | |||
663 | /* Now reduce rssi_last by rssi_reduce */ | ||
664 | if (rssi_last < rssi_reduce) | ||
665 | rssi_last = 0; | ||
666 | else | ||
667 | rssi_last -= rssi_reduce; | ||
668 | |||
669 | /* | ||
670 | * Now look up the rate in the rssi table and return it. | ||
671 | * If no rates match then we return 0 (lowest rate) | ||
672 | */ | ||
673 | |||
674 | best_thruput = 0; | ||
675 | maxindex = ath_rc_priv->max_valid_rate-1; | ||
676 | |||
677 | minindex = 0; | ||
678 | best_rate = minindex; | ||
679 | |||
680 | /* | ||
681 | * Try the higher rate first. It will reduce memory moving time | ||
682 | * if we have very good channel characteristics. | ||
683 | */ | ||
684 | for (index = maxindex; index >= minindex ; index--) { | ||
685 | u8 per_thres; | ||
686 | |||
687 | rate = ath_rc_priv->valid_rate_index[index]; | ||
688 | if (rate > ath_rc_priv->rate_max_phy) | ||
689 | continue; | ||
690 | |||
691 | /* | ||
692 | * For TCP the average collision rate is around 11%, | ||
693 | * so we ignore PERs less than this. This is to | ||
694 | * prevent the rate we are currently using (whose | ||
695 | * PER might be in the 10-15 range because of TCP | ||
696 | * collisions) looking worse than the next lower | ||
697 | * rate whose PER has decayed close to 0. If we | ||
698 | * used to next lower rate, its PER would grow to | ||
699 | * 10-15 and we would be worse off then staying | ||
700 | * at the current rate. | ||
701 | */ | ||
702 | per_thres = ath_rc_priv->state[rate].per; | ||
703 | if (per_thres < 12) | ||
704 | per_thres = 12; | ||
705 | |||
706 | this_thruput = rate_table->info[rate].user_ratekbps * | ||
707 | (100 - per_thres); | ||
708 | |||
709 | if (best_thruput <= this_thruput) { | ||
710 | best_thruput = this_thruput; | ||
711 | best_rate = rate; | ||
712 | } | ||
713 | } | ||
714 | |||
715 | rate = best_rate; | ||
716 | ath_rc_priv->rssi_last_lookup = rssi_last; | ||
717 | |||
718 | /* | ||
719 | * Must check the actual rate (ratekbps) to account for | ||
720 | * non-monoticity of 11g's rate table | ||
721 | */ | ||
722 | |||
723 | if (rate >= ath_rc_priv->rate_max_phy) { | ||
724 | rate = ath_rc_priv->rate_max_phy; | ||
725 | |||
726 | /* Probe the next allowed phy state */ | ||
727 | if (ath_rc_get_nextvalid_txrate(rate_table, | ||
728 | ath_rc_priv, rate, &next_rate) && | ||
729 | (now_msec - ath_rc_priv->probe_time > | ||
730 | rate_table->probe_interval) && | ||
731 | (ath_rc_priv->hw_maxretry_pktcnt >= 1)) { | ||
732 | rate = next_rate; | ||
733 | ath_rc_priv->probe_rate = rate; | ||
734 | ath_rc_priv->probe_time = now_msec; | ||
735 | ath_rc_priv->hw_maxretry_pktcnt = 0; | ||
736 | *is_probing = 1; | ||
737 | } | ||
738 | } | ||
739 | |||
740 | if (rate > (ath_rc_priv->rate_table_size - 1)) | ||
741 | rate = ath_rc_priv->rate_table_size - 1; | ||
742 | |||
743 | ASSERT((rate_table->info[rate].valid && | ||
744 | (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) || | ||
745 | (rate_table->info[rate].valid_single_stream && | ||
746 | !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))); | ||
747 | |||
748 | return rate; | ||
749 | } | ||
750 | |||
751 | static void ath_rc_rate_set_series(struct ath_rate_table *rate_table, | ||
752 | struct ieee80211_tx_rate *rate, | ||
753 | struct ieee80211_tx_rate_control *txrc, | ||
754 | u8 tries, u8 rix, int rtsctsenable) | ||
755 | { | ||
756 | rate->count = tries; | ||
757 | rate->idx = rix; | ||
758 | |||
759 | if (txrc->short_preamble) | ||
760 | rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; | ||
761 | if (txrc->rts || rtsctsenable) | ||
762 | rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; | ||
763 | if (WLAN_RC_PHY_40(rate_table->info[rix].phy)) | ||
764 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; | ||
765 | if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy)) | ||
766 | rate->flags |= IEEE80211_TX_RC_SHORT_GI; | ||
767 | if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) | ||
768 | rate->flags |= IEEE80211_TX_RC_MCS; | ||
769 | } | ||
770 | |||
771 | static void ath_rc_rate_set_rtscts(struct ath_softc *sc, | ||
772 | struct ath_rate_table *rate_table, | ||
773 | struct ieee80211_tx_info *tx_info) | ||
774 | { | ||
775 | struct ieee80211_tx_rate *rates = tx_info->control.rates; | ||
776 | int i = 0, rix = 0, cix, enable_g_protection = 0; | ||
777 | |||
778 | /* get the cix for the lowest valid rix */ | ||
779 | for (i = 3; i >= 0; i--) { | ||
780 | if (rates[i].count && (rates[i].idx >= 0)) { | ||
781 | rix = rates[i].idx; | ||
782 | break; | ||
783 | } | ||
784 | } | ||
785 | cix = rate_table->info[rix].ctrl_rate; | ||
786 | |||
787 | /* All protection frames are transmited at 2Mb/s for 802.11g, | ||
788 | * otherwise we transmit them at 1Mb/s */ | ||
789 | if (sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ && | ||
790 | !conf_is_ht(&sc->hw->conf)) | ||
791 | enable_g_protection = 1; | ||
792 | |||
793 | /* | ||
794 | * If 802.11g protection is enabled, determine whether to use RTS/CTS or | ||
795 | * just CTS. Note that this is only done for OFDM/HT unicast frames. | ||
796 | */ | ||
797 | if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) && | ||
798 | !(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) && | ||
799 | (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM || | ||
800 | WLAN_RC_PHY_HT(rate_table->info[rix].phy))) { | ||
801 | rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT; | ||
802 | cix = rate_table->info[enable_g_protection].ctrl_rate; | ||
803 | } | ||
804 | |||
805 | tx_info->control.rts_cts_rate_idx = cix; | ||
806 | } | ||
807 | |||
808 | static u8 ath_rc_rate_getidx(struct ath_softc *sc, | ||
809 | struct ath_rate_priv *ath_rc_priv, | ||
810 | struct ath_rate_table *rate_table, | ||
811 | u8 rix, u16 stepdown, | ||
812 | u16 min_rate) | ||
813 | { | ||
814 | u32 j; | ||
815 | u8 nextindex; | ||
816 | |||
817 | if (min_rate) { | ||
818 | for (j = RATE_TABLE_SIZE; j > 0; j--) { | ||
819 | if (ath_rc_get_nextlowervalid_txrate(rate_table, | ||
820 | ath_rc_priv, rix, &nextindex)) | ||
821 | rix = nextindex; | ||
822 | else | ||
823 | break; | ||
824 | } | ||
825 | } else { | ||
826 | for (j = stepdown; j > 0; j--) { | ||
827 | if (ath_rc_get_nextlowervalid_txrate(rate_table, | ||
828 | ath_rc_priv, rix, &nextindex)) | ||
829 | rix = nextindex; | ||
830 | else | ||
831 | break; | ||
832 | } | ||
833 | } | ||
834 | return rix; | ||
835 | } | ||
836 | |||
837 | static void ath_rc_ratefind(struct ath_softc *sc, | ||
838 | struct ath_rate_priv *ath_rc_priv, | ||
839 | struct ieee80211_tx_rate_control *txrc) | ||
840 | { | ||
841 | struct ath_rate_table *rate_table; | ||
842 | struct sk_buff *skb = txrc->skb; | ||
843 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
844 | struct ieee80211_tx_rate *rates = tx_info->control.rates; | ||
845 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
846 | __le16 fc = hdr->frame_control; | ||
847 | u8 try_per_rate = 0, i = 0, rix, nrix; | ||
848 | int is_probe = 0; | ||
849 | |||
850 | rate_table = sc->cur_rate_table; | ||
851 | rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, &is_probe); | ||
852 | nrix = rix; | ||
853 | |||
854 | if (is_probe) { | ||
855 | /* set one try for probe rates. For the | ||
856 | * probes don't enable rts */ | ||
857 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, | ||
858 | 1, nrix, 0); | ||
859 | |||
860 | try_per_rate = (ATH_11N_TXMAXTRY/4); | ||
861 | /* Get the next tried/allowed rate. No RTS for the next series | ||
862 | * after the probe rate | ||
863 | */ | ||
864 | nrix = ath_rc_rate_getidx(sc, ath_rc_priv, | ||
865 | rate_table, nrix, 1, 0); | ||
866 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, | ||
867 | try_per_rate, nrix, 0); | ||
868 | |||
869 | tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
870 | } else { | ||
871 | try_per_rate = (ATH_11N_TXMAXTRY/4); | ||
872 | /* Set the choosen rate. No RTS for first series entry. */ | ||
873 | ath_rc_rate_set_series(rate_table, &rates[i++], txrc, | ||
874 | try_per_rate, nrix, 0); | ||
875 | } | ||
876 | |||
877 | /* Fill in the other rates for multirate retry */ | ||
878 | for ( ; i < 4; i++) { | ||
879 | u8 try_num; | ||
880 | u8 min_rate; | ||
881 | |||
882 | try_num = ((i + 1) == 4) ? | ||
883 | ATH_11N_TXMAXTRY - (try_per_rate * i) : try_per_rate ; | ||
884 | min_rate = (((i + 1) == 4) && 0); | ||
885 | |||
886 | nrix = ath_rc_rate_getidx(sc, ath_rc_priv, | ||
887 | rate_table, nrix, 1, min_rate); | ||
888 | /* All other rates in the series have RTS enabled */ | ||
889 | ath_rc_rate_set_series(rate_table, &rates[i], txrc, | ||
890 | try_num, nrix, 1); | ||
891 | } | ||
892 | |||
893 | /* | ||
894 | * NB:Change rate series to enable aggregation when operating | ||
895 | * at lower MCS rates. When first rate in series is MCS2 | ||
896 | * in HT40 @ 2.4GHz, series should look like: | ||
897 | * | ||
898 | * {MCS2, MCS1, MCS0, MCS0}. | ||
899 | * | ||
900 | * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should | ||
901 | * look like: | ||
902 | * | ||
903 | * {MCS3, MCS2, MCS1, MCS1} | ||
904 | * | ||
905 | * So, set fourth rate in series to be same as third one for | ||
906 | * above conditions. | ||
907 | */ | ||
908 | if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) && | ||
909 | (conf_is_ht(&sc->hw->conf))) { | ||
910 | u8 dot11rate = rate_table->info[rix].dot11rate; | ||
911 | u8 phy = rate_table->info[rix].phy; | ||
912 | if (i == 4 && | ||
913 | ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) || | ||
914 | (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) { | ||
915 | rates[3].idx = rates[2].idx; | ||
916 | rates[3].flags = rates[2].flags; | ||
917 | } | ||
918 | } | ||
919 | |||
920 | /* | ||
921 | * Force hardware to use computed duration for next | ||
922 | * fragment by disabling multi-rate retry, which | ||
923 | * updates duration based on the multi-rate duration table. | ||
924 | * | ||
925 | * FIXME: Fix duration | ||
926 | */ | ||
927 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) && | ||
928 | (ieee80211_has_morefrags(fc) || | ||
929 | (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG))) { | ||
930 | rates[1].count = rates[2].count = rates[3].count = 0; | ||
931 | rates[1].idx = rates[2].idx = rates[3].idx = 0; | ||
932 | rates[0].count = ATH_TXMAXTRY; | ||
933 | } | ||
934 | |||
935 | /* Setup RTS/CTS */ | ||
936 | ath_rc_rate_set_rtscts(sc, rate_table, tx_info); | ||
937 | } | ||
938 | |||
939 | static bool ath_rc_update_per(struct ath_softc *sc, | ||
940 | struct ath_rate_table *rate_table, | ||
941 | struct ath_rate_priv *ath_rc_priv, | ||
942 | struct ath_tx_info_priv *tx_info_priv, | ||
943 | int tx_rate, int xretries, int retries, | ||
944 | u32 now_msec) | ||
945 | { | ||
946 | bool state_change = false; | ||
947 | int count; | ||
948 | u8 last_per; | ||
949 | static u32 nretry_to_per_lookup[10] = { | ||
950 | 100 * 0 / 1, | ||
951 | 100 * 1 / 4, | ||
952 | 100 * 1 / 2, | ||
953 | 100 * 3 / 4, | ||
954 | 100 * 4 / 5, | ||
955 | 100 * 5 / 6, | ||
956 | 100 * 6 / 7, | ||
957 | 100 * 7 / 8, | ||
958 | 100 * 8 / 9, | ||
959 | 100 * 9 / 10 | ||
960 | }; | ||
961 | |||
962 | last_per = ath_rc_priv->state[tx_rate].per; | ||
963 | |||
964 | if (xretries) { | ||
965 | if (xretries == 1) { | ||
966 | ath_rc_priv->state[tx_rate].per += 30; | ||
967 | if (ath_rc_priv->state[tx_rate].per > 100) | ||
968 | ath_rc_priv->state[tx_rate].per = 100; | ||
969 | } else { | ||
970 | /* xretries == 2 */ | ||
971 | count = ARRAY_SIZE(nretry_to_per_lookup); | ||
972 | if (retries >= count) | ||
973 | retries = count - 1; | ||
974 | |||
975 | /* new_PER = 7/8*old_PER + 1/8*(currentPER) */ | ||
976 | ath_rc_priv->state[tx_rate].per = | ||
977 | (u8)(last_per - (last_per >> 3) + (100 >> 3)); | ||
978 | } | ||
979 | |||
980 | /* xretries == 1 or 2 */ | ||
981 | |||
982 | if (ath_rc_priv->probe_rate == tx_rate) | ||
983 | ath_rc_priv->probe_rate = 0; | ||
984 | |||
985 | } else { /* xretries == 0 */ | ||
986 | count = ARRAY_SIZE(nretry_to_per_lookup); | ||
987 | if (retries >= count) | ||
988 | retries = count - 1; | ||
989 | |||
990 | if (tx_info_priv->n_bad_frames) { | ||
991 | /* new_PER = 7/8*old_PER + 1/8*(currentPER) | ||
992 | * Assuming that n_frames is not 0. The current PER | ||
993 | * from the retries is 100 * retries / (retries+1), | ||
994 | * since the first retries attempts failed, and the | ||
995 | * next one worked. For the one that worked, | ||
996 | * n_bad_frames subframes out of n_frames wored, | ||
997 | * so the PER for that part is | ||
998 | * 100 * n_bad_frames / n_frames, and it contributes | ||
999 | * 100 * n_bad_frames / (n_frames * (retries+1)) to | ||
1000 | * the above PER. The expression below is a | ||
1001 | * simplified version of the sum of these two terms. | ||
1002 | */ | ||
1003 | if (tx_info_priv->n_frames > 0) { | ||
1004 | int n_frames, n_bad_frames; | ||
1005 | u8 cur_per, new_per; | ||
1006 | |||
1007 | n_bad_frames = retries * tx_info_priv->n_frames + | ||
1008 | tx_info_priv->n_bad_frames; | ||
1009 | n_frames = tx_info_priv->n_frames * (retries + 1); | ||
1010 | cur_per = (100 * n_bad_frames / n_frames) >> 3; | ||
1011 | new_per = (u8)(last_per - (last_per >> 3) + cur_per); | ||
1012 | ath_rc_priv->state[tx_rate].per = new_per; | ||
1013 | } | ||
1014 | } else { | ||
1015 | ath_rc_priv->state[tx_rate].per = | ||
1016 | (u8)(last_per - (last_per >> 3) + | ||
1017 | (nretry_to_per_lookup[retries] >> 3)); | ||
1018 | } | ||
1019 | |||
1020 | ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev; | ||
1021 | ath_rc_priv->rssi_last_prev = ath_rc_priv->rssi_last; | ||
1022 | ath_rc_priv->rssi_last = tx_info_priv->tx.ts_rssi; | ||
1023 | ath_rc_priv->rssi_time = now_msec; | ||
1024 | |||
1025 | /* | ||
1026 | * If we got at most one retry then increase the max rate if | ||
1027 | * this was a probe. Otherwise, ignore the probe. | ||
1028 | */ | ||
1029 | if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) { | ||
1030 | if (retries > 0 || 2 * tx_info_priv->n_bad_frames > | ||
1031 | tx_info_priv->n_frames) { | ||
1032 | /* | ||
1033 | * Since we probed with just a single attempt, | ||
1034 | * any retries means the probe failed. Also, | ||
1035 | * if the attempt worked, but more than half | ||
1036 | * the subframes were bad then also consider | ||
1037 | * the probe a failure. | ||
1038 | */ | ||
1039 | ath_rc_priv->probe_rate = 0; | ||
1040 | } else { | ||
1041 | u8 probe_rate = 0; | ||
1042 | |||
1043 | ath_rc_priv->rate_max_phy = | ||
1044 | ath_rc_priv->probe_rate; | ||
1045 | probe_rate = ath_rc_priv->probe_rate; | ||
1046 | |||
1047 | if (ath_rc_priv->state[probe_rate].per > 30) | ||
1048 | ath_rc_priv->state[probe_rate].per = 20; | ||
1049 | |||
1050 | ath_rc_priv->probe_rate = 0; | ||
1051 | |||
1052 | /* | ||
1053 | * Since this probe succeeded, we allow the next | ||
1054 | * probe twice as soon. This allows the maxRate | ||
1055 | * to move up faster if the probes are | ||
1056 | * succesful. | ||
1057 | */ | ||
1058 | ath_rc_priv->probe_time = | ||
1059 | now_msec - rate_table->probe_interval / 2; | ||
1060 | } | ||
1061 | } | ||
1062 | |||
1063 | if (retries > 0) { | ||
1064 | /* | ||
1065 | * Don't update anything. We don't know if | ||
1066 | * this was because of collisions or poor signal. | ||
1067 | * | ||
1068 | * Later: if rssi_ack is close to | ||
1069 | * ath_rc_priv->state[txRate].rssi_thres and we see lots | ||
1070 | * of retries, then we could increase | ||
1071 | * ath_rc_priv->state[txRate].rssi_thres. | ||
1072 | */ | ||
1073 | ath_rc_priv->hw_maxretry_pktcnt = 0; | ||
1074 | } else { | ||
1075 | int32_t rssi_ackAvg; | ||
1076 | int8_t rssi_thres; | ||
1077 | int8_t rssi_ack_vmin; | ||
1078 | |||
1079 | /* | ||
1080 | * It worked with no retries. First ignore bogus (small) | ||
1081 | * rssi_ack values. | ||
1082 | */ | ||
1083 | if (tx_rate == ath_rc_priv->rate_max_phy && | ||
1084 | ath_rc_priv->hw_maxretry_pktcnt < 255) { | ||
1085 | ath_rc_priv->hw_maxretry_pktcnt++; | ||
1086 | } | ||
1087 | |||
1088 | if (tx_info_priv->tx.ts_rssi < | ||
1089 | rate_table->info[tx_rate].rssi_ack_validmin) | ||
1090 | goto exit; | ||
1091 | |||
1092 | /* Average the rssi */ | ||
1093 | if (tx_rate != ath_rc_priv->rssi_sum_rate) { | ||
1094 | ath_rc_priv->rssi_sum_rate = tx_rate; | ||
1095 | ath_rc_priv->rssi_sum = | ||
1096 | ath_rc_priv->rssi_sum_cnt = 0; | ||
1097 | } | ||
1098 | |||
1099 | ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi; | ||
1100 | ath_rc_priv->rssi_sum_cnt++; | ||
1101 | |||
1102 | if (ath_rc_priv->rssi_sum_cnt < 4) | ||
1103 | goto exit; | ||
1104 | |||
1105 | rssi_ackAvg = | ||
1106 | (ath_rc_priv->rssi_sum + 2) / 4; | ||
1107 | rssi_thres = | ||
1108 | ath_rc_priv->state[tx_rate].rssi_thres; | ||
1109 | rssi_ack_vmin = | ||
1110 | rate_table->info[tx_rate].rssi_ack_validmin; | ||
1111 | |||
1112 | ath_rc_priv->rssi_sum = | ||
1113 | ath_rc_priv->rssi_sum_cnt = 0; | ||
1114 | |||
1115 | /* Now reduce the current rssi threshold */ | ||
1116 | if ((rssi_ackAvg < rssi_thres + 2) && | ||
1117 | (rssi_thres > rssi_ack_vmin)) { | ||
1118 | ath_rc_priv->state[tx_rate].rssi_thres--; | ||
1119 | } | ||
1120 | |||
1121 | state_change = true; | ||
1122 | } | ||
1123 | } | ||
1124 | exit: | ||
1125 | return state_change; | ||
1126 | } | ||
1127 | |||
1128 | /* Update PER, RSSI and whatever else that the code thinks it is doing. | ||
1129 | If you can make sense of all this, you really need to go out more. */ | ||
1130 | |||
1131 | static void ath_rc_update_ht(struct ath_softc *sc, | ||
1132 | struct ath_rate_priv *ath_rc_priv, | ||
1133 | struct ath_tx_info_priv *tx_info_priv, | ||
1134 | int tx_rate, int xretries, int retries) | ||
1135 | { | ||
1136 | #define CHK_RSSI(rate) \ | ||
1137 | ((ath_rc_priv->state[(rate)].rssi_thres + \ | ||
1138 | rate_table->info[(rate)].rssi_ack_deltamin) > \ | ||
1139 | ath_rc_priv->state[(rate)+1].rssi_thres) | ||
1140 | |||
1141 | u32 now_msec = jiffies_to_msecs(jiffies); | ||
1142 | int rate; | ||
1143 | u8 last_per; | ||
1144 | bool state_change = false; | ||
1145 | struct ath_rate_table *rate_table = sc->cur_rate_table; | ||
1146 | int size = ath_rc_priv->rate_table_size; | ||
1147 | |||
1148 | if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt)) | ||
1149 | return; | ||
1150 | |||
1151 | /* To compensate for some imbalance between ctrl and ext. channel */ | ||
1152 | |||
1153 | if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy)) | ||
1154 | tx_info_priv->tx.ts_rssi = | ||
1155 | tx_info_priv->tx.ts_rssi < 3 ? 0 : | ||
1156 | tx_info_priv->tx.ts_rssi - 3; | ||
1157 | |||
1158 | last_per = ath_rc_priv->state[tx_rate].per; | ||
1159 | |||
1160 | /* Update PER first */ | ||
1161 | state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv, | ||
1162 | tx_info_priv, tx_rate, xretries, | ||
1163 | retries, now_msec); | ||
1164 | |||
1165 | /* | ||
1166 | * If this rate looks bad (high PER) then stop using it for | ||
1167 | * a while (except if we are probing). | ||
1168 | */ | ||
1169 | if (ath_rc_priv->state[tx_rate].per >= 55 && tx_rate > 0 && | ||
1170 | rate_table->info[tx_rate].ratekbps <= | ||
1171 | rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) { | ||
1172 | ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv, | ||
1173 | (u8)tx_rate, &ath_rc_priv->rate_max_phy); | ||
1174 | |||
1175 | /* Don't probe for a little while. */ | ||
1176 | ath_rc_priv->probe_time = now_msec; | ||
1177 | } | ||
1178 | |||
1179 | if (state_change) { | ||
1180 | /* | ||
1181 | * Make sure the rates above this have higher rssi thresholds. | ||
1182 | * (Note: Monotonicity is kept within the OFDM rates and | ||
1183 | * within the CCK rates. However, no adjustment is | ||
1184 | * made to keep the rssi thresholds monotonically | ||
1185 | * increasing between the CCK and OFDM rates.) | ||
1186 | */ | ||
1187 | for (rate = tx_rate; rate < size - 1; rate++) { | ||
1188 | if (rate_table->info[rate+1].phy != | ||
1189 | rate_table->info[tx_rate].phy) | ||
1190 | break; | ||
1191 | |||
1192 | if (CHK_RSSI(rate)) { | ||
1193 | ath_rc_priv->state[rate+1].rssi_thres = | ||
1194 | ath_rc_priv->state[rate].rssi_thres + | ||
1195 | rate_table->info[rate].rssi_ack_deltamin; | ||
1196 | } | ||
1197 | } | ||
1198 | |||
1199 | /* Make sure the rates below this have lower rssi thresholds. */ | ||
1200 | for (rate = tx_rate - 1; rate >= 0; rate--) { | ||
1201 | if (rate_table->info[rate].phy != | ||
1202 | rate_table->info[tx_rate].phy) | ||
1203 | break; | ||
1204 | |||
1205 | if (CHK_RSSI(rate)) { | ||
1206 | if (ath_rc_priv->state[rate+1].rssi_thres < | ||
1207 | rate_table->info[rate].rssi_ack_deltamin) | ||
1208 | ath_rc_priv->state[rate].rssi_thres = 0; | ||
1209 | else { | ||
1210 | ath_rc_priv->state[rate].rssi_thres = | ||
1211 | ath_rc_priv->state[rate+1].rssi_thres - | ||
1212 | rate_table->info[rate].rssi_ack_deltamin; | ||
1213 | } | ||
1214 | |||
1215 | if (ath_rc_priv->state[rate].rssi_thres < | ||
1216 | rate_table->info[rate].rssi_ack_validmin) { | ||
1217 | ath_rc_priv->state[rate].rssi_thres = | ||
1218 | rate_table->info[rate].rssi_ack_validmin; | ||
1219 | } | ||
1220 | } | ||
1221 | } | ||
1222 | } | ||
1223 | |||
1224 | /* Make sure the rates below this have lower PER */ | ||
1225 | /* Monotonicity is kept only for rates below the current rate. */ | ||
1226 | if (ath_rc_priv->state[tx_rate].per < last_per) { | ||
1227 | for (rate = tx_rate - 1; rate >= 0; rate--) { | ||
1228 | if (rate_table->info[rate].phy != | ||
1229 | rate_table->info[tx_rate].phy) | ||
1230 | break; | ||
1231 | |||
1232 | if (ath_rc_priv->state[rate].per > | ||
1233 | ath_rc_priv->state[rate+1].per) { | ||
1234 | ath_rc_priv->state[rate].per = | ||
1235 | ath_rc_priv->state[rate+1].per; | ||
1236 | } | ||
1237 | } | ||
1238 | } | ||
1239 | |||
1240 | /* Maintain monotonicity for rates above the current rate */ | ||
1241 | for (rate = tx_rate; rate < size - 1; rate++) { | ||
1242 | if (ath_rc_priv->state[rate+1].per < | ||
1243 | ath_rc_priv->state[rate].per) | ||
1244 | ath_rc_priv->state[rate+1].per = | ||
1245 | ath_rc_priv->state[rate].per; | ||
1246 | } | ||
1247 | |||
1248 | /* Every so often, we reduce the thresholds and | ||
1249 | * PER (different for CCK and OFDM). */ | ||
1250 | if (now_msec - ath_rc_priv->rssi_down_time >= | ||
1251 | rate_table->rssi_reduce_interval) { | ||
1252 | |||
1253 | for (rate = 0; rate < size; rate++) { | ||
1254 | if (ath_rc_priv->state[rate].rssi_thres > | ||
1255 | rate_table->info[rate].rssi_ack_validmin) | ||
1256 | ath_rc_priv->state[rate].rssi_thres -= 1; | ||
1257 | } | ||
1258 | ath_rc_priv->rssi_down_time = now_msec; | ||
1259 | } | ||
1260 | |||
1261 | /* Every so often, we reduce the thresholds | ||
1262 | * and PER (different for CCK and OFDM). */ | ||
1263 | if (now_msec - ath_rc_priv->per_down_time >= | ||
1264 | rate_table->rssi_reduce_interval) { | ||
1265 | for (rate = 0; rate < size; rate++) { | ||
1266 | ath_rc_priv->state[rate].per = | ||
1267 | 7 * ath_rc_priv->state[rate].per / 8; | ||
1268 | } | ||
1269 | |||
1270 | ath_rc_priv->per_down_time = now_msec; | ||
1271 | } | ||
1272 | |||
1273 | ath_debug_stat_retries(sc, tx_rate, xretries, retries, | ||
1274 | ath_rc_priv->state[tx_rate].per); | ||
1275 | |||
1276 | #undef CHK_RSSI | ||
1277 | } | ||
1278 | |||
1279 | static int ath_rc_get_rateindex(struct ath_rate_table *rate_table, | ||
1280 | struct ieee80211_tx_rate *rate) | ||
1281 | { | ||
1282 | int rix; | ||
1283 | |||
1284 | if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && | ||
1285 | (rate->flags & IEEE80211_TX_RC_SHORT_GI)) | ||
1286 | rix = rate_table->info[rate->idx].ht_index; | ||
1287 | else if (rate->flags & IEEE80211_TX_RC_SHORT_GI) | ||
1288 | rix = rate_table->info[rate->idx].sgi_index; | ||
1289 | else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | ||
1290 | rix = rate_table->info[rate->idx].cw40index; | ||
1291 | else | ||
1292 | rix = rate_table->info[rate->idx].base_index; | ||
1293 | |||
1294 | return rix; | ||
1295 | } | ||
1296 | |||
1297 | static void ath_rc_tx_status(struct ath_softc *sc, | ||
1298 | struct ath_rate_priv *ath_rc_priv, | ||
1299 | struct ieee80211_tx_info *tx_info, | ||
1300 | int final_ts_idx, int xretries, int long_retry) | ||
1301 | { | ||
1302 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
1303 | struct ath_rate_table *rate_table; | ||
1304 | struct ieee80211_tx_rate *rates = tx_info->status.rates; | ||
1305 | u8 flags; | ||
1306 | u32 i = 0, rix; | ||
1307 | |||
1308 | rate_table = sc->cur_rate_table; | ||
1309 | |||
1310 | /* | ||
1311 | * If the first rate is not the final index, there | ||
1312 | * are intermediate rate failures to be processed. | ||
1313 | */ | ||
1314 | if (final_ts_idx != 0) { | ||
1315 | /* Process intermediate rates that failed.*/ | ||
1316 | for (i = 0; i < final_ts_idx ; i++) { | ||
1317 | if (rates[i].count != 0 && (rates[i].idx >= 0)) { | ||
1318 | flags = rates[i].flags; | ||
1319 | |||
1320 | /* If HT40 and we have switched mode from | ||
1321 | * 40 to 20 => don't update */ | ||
1322 | |||
1323 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && | ||
1324 | !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG)) | ||
1325 | return; | ||
1326 | |||
1327 | rix = ath_rc_get_rateindex(rate_table, &rates[i]); | ||
1328 | ath_rc_update_ht(sc, ath_rc_priv, | ||
1329 | tx_info_priv, rix, | ||
1330 | xretries ? 1 : 2, | ||
1331 | rates[i].count); | ||
1332 | } | ||
1333 | } | ||
1334 | } else { | ||
1335 | /* | ||
1336 | * Handle the special case of MIMO PS burst, where the second | ||
1337 | * aggregate is sent out with only one rate and one try. | ||
1338 | * Treating it as an excessive retry penalizes the rate | ||
1339 | * inordinately. | ||
1340 | */ | ||
1341 | if (rates[0].count == 1 && xretries == 1) | ||
1342 | xretries = 2; | ||
1343 | } | ||
1344 | |||
1345 | flags = rates[i].flags; | ||
1346 | |||
1347 | /* If HT40 and we have switched mode from 40 to 20 => don't update */ | ||
1348 | if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && | ||
1349 | !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG)) | ||
1350 | return; | ||
1351 | |||
1352 | rix = ath_rc_get_rateindex(rate_table, &rates[i]); | ||
1353 | ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix, | ||
1354 | xretries, long_retry); | ||
1355 | } | ||
1356 | |||
1357 | static struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc, | ||
1358 | enum ieee80211_band band, | ||
1359 | bool is_ht, bool is_cw_40) | ||
1360 | { | ||
1361 | int mode = 0; | ||
1362 | |||
1363 | switch(band) { | ||
1364 | case IEEE80211_BAND_2GHZ: | ||
1365 | mode = ATH9K_MODE_11G; | ||
1366 | if (is_ht) | ||
1367 | mode = ATH9K_MODE_11NG_HT20; | ||
1368 | if (is_cw_40) | ||
1369 | mode = ATH9K_MODE_11NG_HT40PLUS; | ||
1370 | break; | ||
1371 | case IEEE80211_BAND_5GHZ: | ||
1372 | mode = ATH9K_MODE_11A; | ||
1373 | if (is_ht) | ||
1374 | mode = ATH9K_MODE_11NA_HT20; | ||
1375 | if (is_cw_40) | ||
1376 | mode = ATH9K_MODE_11NA_HT40PLUS; | ||
1377 | break; | ||
1378 | default: | ||
1379 | DPRINTF(sc, ATH_DBG_CONFIG, "Invalid band\n"); | ||
1380 | return NULL; | ||
1381 | } | ||
1382 | |||
1383 | BUG_ON(mode >= ATH9K_MODE_MAX); | ||
1384 | |||
1385 | DPRINTF(sc, ATH_DBG_CONFIG, "Choosing rate table for mode: %d\n", mode); | ||
1386 | return sc->hw_rate_table[mode]; | ||
1387 | } | ||
1388 | |||
1389 | static void ath_rc_init(struct ath_softc *sc, | ||
1390 | struct ath_rate_priv *ath_rc_priv, | ||
1391 | struct ieee80211_supported_band *sband, | ||
1392 | struct ieee80211_sta *sta, | ||
1393 | struct ath_rate_table *rate_table) | ||
1394 | { | ||
1395 | struct ath_rateset *rateset = &ath_rc_priv->neg_rates; | ||
1396 | u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates; | ||
1397 | u8 i, j, k, hi = 0, hthi = 0; | ||
1398 | |||
1399 | if (!rate_table) { | ||
1400 | DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n"); | ||
1401 | return; | ||
1402 | } | ||
1403 | |||
1404 | /* Initial rate table size. Will change depending | ||
1405 | * on the working rate set */ | ||
1406 | ath_rc_priv->rate_table_size = RATE_TABLE_SIZE; | ||
1407 | |||
1408 | /* Initialize thresholds according to the global rate table */ | ||
1409 | for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) { | ||
1410 | ath_rc_priv->state[i].rssi_thres = | ||
1411 | rate_table->info[i].rssi_ack_validmin; | ||
1412 | ath_rc_priv->state[i].per = 0; | ||
1413 | } | ||
1414 | |||
1415 | /* Determine the valid rates */ | ||
1416 | ath_rc_init_valid_txmask(ath_rc_priv); | ||
1417 | |||
1418 | for (i = 0; i < WLAN_RC_PHY_MAX; i++) { | ||
1419 | for (j = 0; j < MAX_TX_RATE_PHY; j++) | ||
1420 | ath_rc_priv->valid_phy_rateidx[i][j] = 0; | ||
1421 | ath_rc_priv->valid_phy_ratecnt[i] = 0; | ||
1422 | } | ||
1423 | |||
1424 | if (!rateset->rs_nrates) { | ||
1425 | /* No working rate, just initialize valid rates */ | ||
1426 | hi = ath_rc_init_validrates(ath_rc_priv, rate_table, | ||
1427 | ath_rc_priv->ht_cap); | ||
1428 | } else { | ||
1429 | /* Use intersection of working rates and valid rates */ | ||
1430 | hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table, | ||
1431 | rateset, ath_rc_priv->ht_cap); | ||
1432 | if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) { | ||
1433 | hthi = ath_rc_setvalid_htrates(ath_rc_priv, | ||
1434 | rate_table, | ||
1435 | ht_mcs, | ||
1436 | ath_rc_priv->ht_cap); | ||
1437 | } | ||
1438 | hi = A_MAX(hi, hthi); | ||
1439 | } | ||
1440 | |||
1441 | ath_rc_priv->rate_table_size = hi + 1; | ||
1442 | ath_rc_priv->rate_max_phy = 0; | ||
1443 | ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE); | ||
1444 | |||
1445 | for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) { | ||
1446 | for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) { | ||
1447 | ath_rc_priv->valid_rate_index[k++] = | ||
1448 | ath_rc_priv->valid_phy_rateidx[i][j]; | ||
1449 | } | ||
1450 | |||
1451 | if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, 1) | ||
1452 | || !ath_rc_priv->valid_phy_ratecnt[i]) | ||
1453 | continue; | ||
1454 | |||
1455 | ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1]; | ||
1456 | } | ||
1457 | ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE); | ||
1458 | ASSERT(k <= RATE_TABLE_SIZE); | ||
1459 | |||
1460 | ath_rc_priv->max_valid_rate = k; | ||
1461 | ath_rc_sort_validrates(rate_table, ath_rc_priv); | ||
1462 | ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; | ||
1463 | sc->cur_rate_table = rate_table; | ||
1464 | |||
1465 | DPRINTF(sc, ATH_DBG_CONFIG, "RC Initialized with capabilities: 0x%x\n", | ||
1466 | ath_rc_priv->ht_cap); | ||
1467 | } | ||
1468 | |||
1469 | static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, | ||
1470 | bool is_cw40, bool is_sgi40) | ||
1471 | { | ||
1472 | u8 caps = 0; | ||
1473 | |||
1474 | if (sta->ht_cap.ht_supported) { | ||
1475 | caps = WLAN_RC_HT_FLAG; | ||
1476 | if (sc->sc_ah->caps.tx_chainmask != 1 && | ||
1477 | ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL)) { | ||
1478 | if (sta->ht_cap.mcs.rx_mask[1]) | ||
1479 | caps |= WLAN_RC_DS_FLAG; | ||
1480 | } | ||
1481 | if (is_cw40) | ||
1482 | caps |= WLAN_RC_40_FLAG; | ||
1483 | if (is_sgi40) | ||
1484 | caps |= WLAN_RC_SGI_FLAG; | ||
1485 | } | ||
1486 | |||
1487 | return caps; | ||
1488 | } | ||
1489 | |||
1490 | /***********************************/ | ||
1491 | /* mac80211 Rate Control callbacks */ | ||
1492 | /***********************************/ | ||
1493 | |||
1494 | static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | ||
1495 | struct ieee80211_sta *sta, void *priv_sta, | ||
1496 | struct sk_buff *skb) | ||
1497 | { | ||
1498 | struct ath_softc *sc = priv; | ||
1499 | struct ath_rate_priv *ath_rc_priv = priv_sta; | ||
1500 | struct ath_tx_info_priv *tx_info_priv = NULL; | ||
1501 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1502 | struct ieee80211_hdr *hdr; | ||
1503 | int final_ts_idx, tx_status = 0, is_underrun = 0; | ||
1504 | __le16 fc; | ||
1505 | |||
1506 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1507 | fc = hdr->frame_control; | ||
1508 | tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
1509 | final_ts_idx = tx_info_priv->tx.ts_rateindex; | ||
1510 | |||
1511 | if (!priv_sta || !ieee80211_is_data(fc) || | ||
1512 | !tx_info_priv->update_rc) | ||
1513 | goto exit; | ||
1514 | |||
1515 | if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT) | ||
1516 | goto exit; | ||
1517 | |||
1518 | /* | ||
1519 | * If underrun error is seen assume it as an excessive retry only | ||
1520 | * if prefetch trigger level have reached the max (0x3f for 5416) | ||
1521 | * Adjust the long retry as if the frame was tried ATH_11N_TXMAXTRY | ||
1522 | * times. This affects how ratectrl updates PER for the failed rate. | ||
1523 | */ | ||
1524 | if (tx_info_priv->tx.ts_flags & | ||
1525 | (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) && | ||
1526 | ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) { | ||
1527 | tx_status = 1; | ||
1528 | is_underrun = 1; | ||
1529 | } | ||
1530 | |||
1531 | if ((tx_info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) || | ||
1532 | (tx_info_priv->tx.ts_status & ATH9K_TXERR_FIFO)) | ||
1533 | tx_status = 1; | ||
1534 | |||
1535 | ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, | ||
1536 | (is_underrun) ? ATH_11N_TXMAXTRY : | ||
1537 | tx_info_priv->tx.ts_longretry); | ||
1538 | |||
1539 | /* Check if aggregation has to be enabled for this tid */ | ||
1540 | if (conf_is_ht(&sc->hw->conf) && | ||
1541 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { | ||
1542 | if (ieee80211_is_data_qos(fc)) { | ||
1543 | u8 *qc, tid; | ||
1544 | struct ath_node *an; | ||
1545 | |||
1546 | qc = ieee80211_get_qos_ctl(hdr); | ||
1547 | tid = qc[0] & 0xf; | ||
1548 | an = (struct ath_node *)sta->drv_priv; | ||
1549 | |||
1550 | if(ath_tx_aggr_check(sc, an, tid)) | ||
1551 | ieee80211_start_tx_ba_session(sc->hw, hdr->addr1, tid); | ||
1552 | } | ||
1553 | } | ||
1554 | |||
1555 | ath_debug_stat_rc(sc, skb); | ||
1556 | exit: | ||
1557 | kfree(tx_info_priv); | ||
1558 | } | ||
1559 | |||
1560 | static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | ||
1561 | struct ieee80211_tx_rate_control *txrc) | ||
1562 | { | ||
1563 | struct ieee80211_supported_band *sband = txrc->sband; | ||
1564 | struct sk_buff *skb = txrc->skb; | ||
1565 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1566 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1567 | struct ath_softc *sc = priv; | ||
1568 | struct ath_rate_priv *ath_rc_priv = priv_sta; | ||
1569 | __le16 fc = hdr->frame_control; | ||
1570 | |||
1571 | /* lowest rate for management and multicast/broadcast frames */ | ||
1572 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || | ||
1573 | !sta) { | ||
1574 | tx_info->control.rates[0].idx = rate_lowest_index(sband, sta); | ||
1575 | tx_info->control.rates[0].count = | ||
1576 | is_multicast_ether_addr(hdr->addr1) ? 1 : ATH_MGT_TXMAXTRY; | ||
1577 | return; | ||
1578 | } | ||
1579 | |||
1580 | /* Find tx rate for unicast frames */ | ||
1581 | ath_rc_ratefind(sc, ath_rc_priv, txrc); | ||
1582 | } | ||
1583 | |||
1584 | static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, | ||
1585 | struct ieee80211_sta *sta, void *priv_sta) | ||
1586 | { | ||
1587 | struct ath_softc *sc = priv; | ||
1588 | struct ath_rate_priv *ath_rc_priv = priv_sta; | ||
1589 | struct ath_rate_table *rate_table = NULL; | ||
1590 | bool is_cw40, is_sgi40; | ||
1591 | int i, j = 0; | ||
1592 | |||
1593 | for (i = 0; i < sband->n_bitrates; i++) { | ||
1594 | if (sta->supp_rates[sband->band] & BIT(i)) { | ||
1595 | ath_rc_priv->neg_rates.rs_rates[j] | ||
1596 | = (sband->bitrates[i].bitrate * 2) / 10; | ||
1597 | j++; | ||
1598 | } | ||
1599 | } | ||
1600 | ath_rc_priv->neg_rates.rs_nrates = j; | ||
1601 | |||
1602 | if (sta->ht_cap.ht_supported) { | ||
1603 | for (i = 0, j = 0; i < 77; i++) { | ||
1604 | if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8))) | ||
1605 | ath_rc_priv->neg_ht_rates.rs_rates[j++] = i; | ||
1606 | if (j == ATH_RATE_MAX) | ||
1607 | break; | ||
1608 | } | ||
1609 | ath_rc_priv->neg_ht_rates.rs_nrates = j; | ||
1610 | } | ||
1611 | |||
1612 | is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
1613 | is_sgi40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; | ||
1614 | |||
1615 | /* Choose rate table first */ | ||
1616 | |||
1617 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) || | ||
1618 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) || | ||
1619 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) { | ||
1620 | rate_table = ath_choose_rate_table(sc, sband->band, | ||
1621 | sta->ht_cap.ht_supported, | ||
1622 | is_cw40); | ||
1623 | } else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { | ||
1624 | /* cur_rate_table would be set on init through config() */ | ||
1625 | rate_table = sc->cur_rate_table; | ||
1626 | } | ||
1627 | |||
1628 | ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40); | ||
1629 | ath_rc_init(sc, priv_sta, sband, sta, rate_table); | ||
1630 | } | ||
1631 | |||
1632 | static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, | ||
1633 | struct ieee80211_sta *sta, void *priv_sta, | ||
1634 | u32 changed) | ||
1635 | { | ||
1636 | struct ath_softc *sc = priv; | ||
1637 | struct ath_rate_priv *ath_rc_priv = priv_sta; | ||
1638 | struct ath_rate_table *rate_table = NULL; | ||
1639 | bool oper_cw40 = false, oper_sgi40; | ||
1640 | bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ? | ||
1641 | true : false; | ||
1642 | bool local_sgi40 = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ? | ||
1643 | true : false; | ||
1644 | |||
1645 | /* FIXME: Handle AP mode later when we support CWM */ | ||
1646 | |||
1647 | if (changed & IEEE80211_RC_HT_CHANGED) { | ||
1648 | if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) | ||
1649 | return; | ||
1650 | |||
1651 | if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS || | ||
1652 | sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS) | ||
1653 | oper_cw40 = true; | ||
1654 | |||
1655 | oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? | ||
1656 | true : false; | ||
1657 | |||
1658 | if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) { | ||
1659 | rate_table = ath_choose_rate_table(sc, sband->band, | ||
1660 | sta->ht_cap.ht_supported, | ||
1661 | oper_cw40); | ||
1662 | ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, | ||
1663 | oper_cw40, oper_sgi40); | ||
1664 | ath_rc_init(sc, priv_sta, sband, sta, rate_table); | ||
1665 | |||
1666 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
1667 | "Operating HT Bandwidth changed to: %d\n", | ||
1668 | sc->hw->conf.channel_type); | ||
1669 | } | ||
1670 | } | ||
1671 | } | ||
1672 | |||
1673 | static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | ||
1674 | { | ||
1675 | struct ath_wiphy *aphy = hw->priv; | ||
1676 | return aphy->sc; | ||
1677 | } | ||
1678 | |||
1679 | static void ath_rate_free(void *priv) | ||
1680 | { | ||
1681 | return; | ||
1682 | } | ||
1683 | |||
1684 | static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | ||
1685 | { | ||
1686 | struct ath_softc *sc = priv; | ||
1687 | struct ath_rate_priv *rate_priv; | ||
1688 | |||
1689 | rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp); | ||
1690 | if (!rate_priv) { | ||
1691 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1692 | "Unable to allocate private rc structure\n"); | ||
1693 | return NULL; | ||
1694 | } | ||
1695 | |||
1696 | rate_priv->rssi_down_time = jiffies_to_msecs(jiffies); | ||
1697 | rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max; | ||
1698 | |||
1699 | return rate_priv; | ||
1700 | } | ||
1701 | |||
1702 | static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta, | ||
1703 | void *priv_sta) | ||
1704 | { | ||
1705 | struct ath_rate_priv *rate_priv = priv_sta; | ||
1706 | kfree(rate_priv); | ||
1707 | } | ||
1708 | |||
1709 | static struct rate_control_ops ath_rate_ops = { | ||
1710 | .module = NULL, | ||
1711 | .name = "ath9k_rate_control", | ||
1712 | .tx_status = ath_tx_status, | ||
1713 | .get_rate = ath_get_rate, | ||
1714 | .rate_init = ath_rate_init, | ||
1715 | .rate_update = ath_rate_update, | ||
1716 | .alloc = ath_rate_alloc, | ||
1717 | .free = ath_rate_free, | ||
1718 | .alloc_sta = ath_rate_alloc_sta, | ||
1719 | .free_sta = ath_rate_free_sta, | ||
1720 | }; | ||
1721 | |||
1722 | void ath_rate_attach(struct ath_softc *sc) | ||
1723 | { | ||
1724 | sc->hw_rate_table[ATH9K_MODE_11B] = | ||
1725 | &ar5416_11b_ratetable; | ||
1726 | sc->hw_rate_table[ATH9K_MODE_11A] = | ||
1727 | &ar5416_11a_ratetable; | ||
1728 | sc->hw_rate_table[ATH9K_MODE_11G] = | ||
1729 | &ar5416_11g_ratetable; | ||
1730 | sc->hw_rate_table[ATH9K_MODE_11NA_HT20] = | ||
1731 | &ar5416_11na_ratetable; | ||
1732 | sc->hw_rate_table[ATH9K_MODE_11NG_HT20] = | ||
1733 | &ar5416_11ng_ratetable; | ||
1734 | sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS] = | ||
1735 | &ar5416_11na_ratetable; | ||
1736 | sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS] = | ||
1737 | &ar5416_11na_ratetable; | ||
1738 | sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS] = | ||
1739 | &ar5416_11ng_ratetable; | ||
1740 | sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] = | ||
1741 | &ar5416_11ng_ratetable; | ||
1742 | } | ||
1743 | |||
1744 | int ath_rate_control_register(void) | ||
1745 | { | ||
1746 | return ieee80211_rate_control_register(&ath_rate_ops); | ||
1747 | } | ||
1748 | |||
1749 | void ath_rate_control_unregister(void) | ||
1750 | { | ||
1751 | ieee80211_rate_control_unregister(&ath_rate_ops); | ||
1752 | } | ||
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h deleted file mode 100644 index e3abd76103fd..000000000000 --- a/drivers/net/wireless/ath9k/rc.h +++ /dev/null | |||
@@ -1,216 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004 Sam Leffler, Errno Consulting | ||
3 | * Copyright (c) 2004 Video54 Technologies, Inc. | ||
4 | * Copyright (c) 2008-2009 Atheros Communications Inc. | ||
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 | ||
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
17 | */ | ||
18 | |||
19 | #ifndef RC_H | ||
20 | #define RC_H | ||
21 | |||
22 | struct ath_softc; | ||
23 | |||
24 | #define ATH_RATE_MAX 30 | ||
25 | #define RATE_TABLE_SIZE 64 | ||
26 | #define MAX_TX_RATE_PHY 48 | ||
27 | |||
28 | /* VALID_ALL - valid for 20/40/Legacy, | ||
29 | * VALID - Legacy only, | ||
30 | * VALID_20 - HT 20 only, | ||
31 | * VALID_40 - HT 40 only */ | ||
32 | |||
33 | #define INVALID 0x0 | ||
34 | #define VALID 0x1 | ||
35 | #define VALID_20 0x2 | ||
36 | #define VALID_40 0x4 | ||
37 | #define VALID_2040 (VALID_20|VALID_40) | ||
38 | #define VALID_ALL (VALID_2040|VALID) | ||
39 | |||
40 | enum { | ||
41 | WLAN_RC_PHY_OFDM, | ||
42 | WLAN_RC_PHY_CCK, | ||
43 | WLAN_RC_PHY_HT_20_SS, | ||
44 | WLAN_RC_PHY_HT_20_DS, | ||
45 | WLAN_RC_PHY_HT_40_SS, | ||
46 | WLAN_RC_PHY_HT_40_DS, | ||
47 | WLAN_RC_PHY_HT_20_SS_HGI, | ||
48 | WLAN_RC_PHY_HT_20_DS_HGI, | ||
49 | WLAN_RC_PHY_HT_40_SS_HGI, | ||
50 | WLAN_RC_PHY_HT_40_DS_HGI, | ||
51 | WLAN_RC_PHY_MAX | ||
52 | }; | ||
53 | |||
54 | #define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \ | ||
55 | || (_phy == WLAN_RC_PHY_HT_40_DS) \ | ||
56 | || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ | ||
57 | || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) | ||
58 | #define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \ | ||
59 | || (_phy == WLAN_RC_PHY_HT_40_DS) \ | ||
60 | || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ | ||
61 | || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) | ||
62 | #define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \ | ||
63 | || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ | ||
64 | || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ | ||
65 | || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) | ||
66 | |||
67 | #define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS) | ||
68 | |||
69 | #define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ? \ | ||
70 | (capflag & WLAN_RC_40_FLAG) ? VALID_40 : VALID_20 : VALID)) | ||
71 | |||
72 | /* Return TRUE if flag supports HT20 && client supports HT20 or | ||
73 | * return TRUE if flag supports HT40 && client supports HT40. | ||
74 | * This is used becos some rates overlap between HT20/HT40. | ||
75 | */ | ||
76 | #define WLAN_RC_PHY_HT_VALID(flag, capflag) \ | ||
77 | (((flag & VALID_20) && !(capflag & WLAN_RC_40_FLAG)) || \ | ||
78 | ((flag & VALID_40) && (capflag & WLAN_RC_40_FLAG))) | ||
79 | |||
80 | #define WLAN_RC_DS_FLAG (0x01) | ||
81 | #define WLAN_RC_40_FLAG (0x02) | ||
82 | #define WLAN_RC_SGI_FLAG (0x04) | ||
83 | #define WLAN_RC_HT_FLAG (0x08) | ||
84 | |||
85 | /** | ||
86 | * struct ath_rate_table - Rate Control table | ||
87 | * @valid: valid for use in rate control | ||
88 | * @valid_single_stream: valid for use in rate control for | ||
89 | * single stream operation | ||
90 | * @phy: CCK/OFDM | ||
91 | * @ratekbps: rate in Kbits per second | ||
92 | * @user_ratekbps: user rate in Kbits per second | ||
93 | * @ratecode: rate that goes into HW descriptors | ||
94 | * @short_preamble: Mask for enabling short preamble in ratecode for CCK | ||
95 | * @dot11rate: value that goes into supported | ||
96 | * rates info element of MLME | ||
97 | * @ctrl_rate: Index of next lower basic rate, used for duration computation | ||
98 | * @max_4ms_framelen: maximum frame length(bytes) for tx duration | ||
99 | * @probe_interval: interval for rate control to probe for other rates | ||
100 | * @rssi_reduce_interval: interval for rate control to reduce rssi | ||
101 | * @initial_ratemax: initial ratemax value | ||
102 | */ | ||
103 | struct ath_rate_table { | ||
104 | int rate_cnt; | ||
105 | struct { | ||
106 | int valid; | ||
107 | int valid_single_stream; | ||
108 | u8 phy; | ||
109 | u32 ratekbps; | ||
110 | u32 user_ratekbps; | ||
111 | u8 ratecode; | ||
112 | u8 short_preamble; | ||
113 | u8 dot11rate; | ||
114 | u8 ctrl_rate; | ||
115 | int8_t rssi_ack_validmin; | ||
116 | int8_t rssi_ack_deltamin; | ||
117 | u8 base_index; | ||
118 | u8 cw40index; | ||
119 | u8 sgi_index; | ||
120 | u8 ht_index; | ||
121 | u32 max_4ms_framelen; | ||
122 | } info[RATE_TABLE_SIZE]; | ||
123 | u32 probe_interval; | ||
124 | u32 rssi_reduce_interval; | ||
125 | u8 initial_ratemax; | ||
126 | }; | ||
127 | |||
128 | struct ath_tx_ratectrl_state { | ||
129 | int8_t rssi_thres; /* required rssi for this rate (dB) */ | ||
130 | u8 per; /* recent estimate of packet error rate (%) */ | ||
131 | }; | ||
132 | |||
133 | struct ath_rateset { | ||
134 | u8 rs_nrates; | ||
135 | u8 rs_rates[ATH_RATE_MAX]; | ||
136 | }; | ||
137 | |||
138 | /** | ||
139 | * struct ath_rate_priv - Rate Control priv data | ||
140 | * @state: RC state | ||
141 | * @rssi_last: last ACK rssi | ||
142 | * @rssi_last_lookup: last ACK rssi used for lookup | ||
143 | * @rssi_last_prev: previous last ACK rssi | ||
144 | * @rssi_last_prev2: 2nd previous last ACK rssi | ||
145 | * @rssi_sum_cnt: count of rssi_sum for averaging | ||
146 | * @rssi_sum_rate: rate that we are averaging | ||
147 | * @rssi_sum: running sum of rssi for averaging | ||
148 | * @probe_rate: rate we are probing at | ||
149 | * @rssi_time: msec timestamp for last ack rssi | ||
150 | * @rssi_down_time: msec timestamp for last down step | ||
151 | * @probe_time: msec timestamp for last probe | ||
152 | * @hw_maxretry_pktcnt: num of packets since we got HW max retry error | ||
153 | * @max_valid_rate: maximum number of valid rate | ||
154 | * @per_down_time: msec timestamp for last PER down step | ||
155 | * @valid_phy_ratecnt: valid rate count | ||
156 | * @rate_max_phy: phy index for the max rate | ||
157 | * @probe_interval: interval for ratectrl to probe for other rates | ||
158 | * @prev_data_rix: rate idx of last data frame | ||
159 | * @ht_cap: HT capabilities | ||
160 | * @neg_rates: Negotatied rates | ||
161 | * @neg_ht_rates: Negotiated HT rates | ||
162 | */ | ||
163 | struct ath_rate_priv { | ||
164 | int8_t rssi_last; | ||
165 | int8_t rssi_last_lookup; | ||
166 | int8_t rssi_last_prev; | ||
167 | int8_t rssi_last_prev2; | ||
168 | int32_t rssi_sum_cnt; | ||
169 | int32_t rssi_sum_rate; | ||
170 | int32_t rssi_sum; | ||
171 | u8 rate_table_size; | ||
172 | u8 probe_rate; | ||
173 | u8 hw_maxretry_pktcnt; | ||
174 | u8 max_valid_rate; | ||
175 | u8 valid_rate_index[RATE_TABLE_SIZE]; | ||
176 | u8 ht_cap; | ||
177 | u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX]; | ||
178 | u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE]; | ||
179 | u8 rate_max_phy; | ||
180 | u32 rssi_time; | ||
181 | u32 rssi_down_time; | ||
182 | u32 probe_time; | ||
183 | u32 per_down_time; | ||
184 | u32 probe_interval; | ||
185 | u32 prev_data_rix; | ||
186 | u32 tx_triglevel_max; | ||
187 | struct ath_tx_ratectrl_state state[RATE_TABLE_SIZE]; | ||
188 | struct ath_rateset neg_rates; | ||
189 | struct ath_rateset neg_ht_rates; | ||
190 | struct ath_rate_softc *asc; | ||
191 | }; | ||
192 | |||
193 | enum ath9k_internal_frame_type { | ||
194 | ATH9K_NOT_INTERNAL, | ||
195 | ATH9K_INT_PAUSE, | ||
196 | ATH9K_INT_UNPAUSE | ||
197 | }; | ||
198 | |||
199 | struct ath_tx_info_priv { | ||
200 | struct ath_wiphy *aphy; | ||
201 | struct ath_tx_status tx; | ||
202 | int n_frames; | ||
203 | int n_bad_frames; | ||
204 | bool update_rc; | ||
205 | enum ath9k_internal_frame_type frame_type; | ||
206 | }; | ||
207 | |||
208 | #define ATH_TX_INFO_PRIV(tx_info) \ | ||
209 | ((struct ath_tx_info_priv *)((tx_info)->rate_driver_data[0])) | ||
210 | |||
211 | void ath_rate_attach(struct ath_softc *sc); | ||
212 | u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate); | ||
213 | int ath_rate_control_register(void); | ||
214 | void ath_rate_control_unregister(void); | ||
215 | |||
216 | #endif /* RC_H */ | ||
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c deleted file mode 100644 index b46badd21f73..000000000000 --- a/drivers/net/wireless/ath9k/recv.c +++ /dev/null | |||
@@ -1,704 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 "ath9k.h" | ||
18 | |||
19 | static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc, | ||
20 | struct ieee80211_hdr *hdr) | ||
21 | { | ||
22 | struct ieee80211_hw *hw = sc->pri_wiphy->hw; | ||
23 | int i; | ||
24 | |||
25 | spin_lock_bh(&sc->wiphy_lock); | ||
26 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
27 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
28 | if (aphy == NULL) | ||
29 | continue; | ||
30 | if (compare_ether_addr(hdr->addr1, aphy->hw->wiphy->perm_addr) | ||
31 | == 0) { | ||
32 | hw = aphy->hw; | ||
33 | break; | ||
34 | } | ||
35 | } | ||
36 | spin_unlock_bh(&sc->wiphy_lock); | ||
37 | return hw; | ||
38 | } | ||
39 | |||
40 | /* | ||
41 | * Setup and link descriptors. | ||
42 | * | ||
43 | * 11N: we can no longer afford to self link the last descriptor. | ||
44 | * MAC acknowledges BA status as long as it copies frames to host | ||
45 | * buffer (or rx fifo). This can incorrectly acknowledge packets | ||
46 | * to a sender if last desc is self-linked. | ||
47 | */ | ||
48 | static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) | ||
49 | { | ||
50 | struct ath_hw *ah = sc->sc_ah; | ||
51 | struct ath_desc *ds; | ||
52 | struct sk_buff *skb; | ||
53 | |||
54 | ATH_RXBUF_RESET(bf); | ||
55 | |||
56 | ds = bf->bf_desc; | ||
57 | ds->ds_link = 0; /* link to null */ | ||
58 | ds->ds_data = bf->bf_buf_addr; | ||
59 | |||
60 | /* virtual addr of the beginning of the buffer. */ | ||
61 | skb = bf->bf_mpdu; | ||
62 | ASSERT(skb != NULL); | ||
63 | ds->ds_vdata = skb->data; | ||
64 | |||
65 | /* setup rx descriptors. The rx.bufsize here tells the harware | ||
66 | * how much data it can DMA to us and that we are prepared | ||
67 | * to process */ | ||
68 | ath9k_hw_setuprxdesc(ah, ds, | ||
69 | sc->rx.bufsize, | ||
70 | 0); | ||
71 | |||
72 | if (sc->rx.rxlink == NULL) | ||
73 | ath9k_hw_putrxbuf(ah, bf->bf_daddr); | ||
74 | else | ||
75 | *sc->rx.rxlink = bf->bf_daddr; | ||
76 | |||
77 | sc->rx.rxlink = &ds->ds_link; | ||
78 | ath9k_hw_rxena(ah); | ||
79 | } | ||
80 | |||
81 | static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) | ||
82 | { | ||
83 | /* XXX block beacon interrupts */ | ||
84 | ath9k_hw_setantenna(sc->sc_ah, antenna); | ||
85 | sc->rx.defant = antenna; | ||
86 | sc->rx.rxotherant = 0; | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * Extend 15-bit time stamp from rx descriptor to | ||
91 | * a full 64-bit TSF using the current h/w TSF. | ||
92 | */ | ||
93 | static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp) | ||
94 | { | ||
95 | u64 tsf; | ||
96 | |||
97 | tsf = ath9k_hw_gettsf64(sc->sc_ah); | ||
98 | if ((tsf & 0x7fff) < rstamp) | ||
99 | tsf -= 0x8000; | ||
100 | return (tsf & ~0x7fff) | rstamp; | ||
101 | } | ||
102 | |||
103 | static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len, gfp_t gfp_mask) | ||
104 | { | ||
105 | struct sk_buff *skb; | ||
106 | u32 off; | ||
107 | |||
108 | /* | ||
109 | * Cache-line-align. This is important (for the | ||
110 | * 5210 at least) as not doing so causes bogus data | ||
111 | * in rx'd frames. | ||
112 | */ | ||
113 | |||
114 | /* Note: the kernel can allocate a value greater than | ||
115 | * what we ask it to give us. We really only need 4 KB as that | ||
116 | * is this hardware supports and in fact we need at least 3849 | ||
117 | * as that is the MAX AMSDU size this hardware supports. | ||
118 | * Unfortunately this means we may get 8 KB here from the | ||
119 | * kernel... and that is actually what is observed on some | ||
120 | * systems :( */ | ||
121 | skb = __dev_alloc_skb(len + sc->cachelsz - 1, gfp_mask); | ||
122 | if (skb != NULL) { | ||
123 | off = ((unsigned long) skb->data) % sc->cachelsz; | ||
124 | if (off != 0) | ||
125 | skb_reserve(skb, sc->cachelsz - off); | ||
126 | } else { | ||
127 | DPRINTF(sc, ATH_DBG_FATAL, | ||
128 | "skbuff alloc of size %u failed\n", len); | ||
129 | return NULL; | ||
130 | } | ||
131 | |||
132 | return skb; | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * For Decrypt or Demic errors, we only mark packet status here and always push | ||
137 | * up the frame up to let mac80211 handle the actual error case, be it no | ||
138 | * decryption key or real decryption error. This let us keep statistics there. | ||
139 | */ | ||
140 | static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, | ||
141 | struct ieee80211_rx_status *rx_status, bool *decrypt_error, | ||
142 | struct ath_softc *sc) | ||
143 | { | ||
144 | struct ieee80211_hdr *hdr; | ||
145 | u8 ratecode; | ||
146 | __le16 fc; | ||
147 | struct ieee80211_hw *hw; | ||
148 | |||
149 | hdr = (struct ieee80211_hdr *)skb->data; | ||
150 | fc = hdr->frame_control; | ||
151 | memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); | ||
152 | hw = ath_get_virt_hw(sc, hdr); | ||
153 | |||
154 | if (ds->ds_rxstat.rs_more) { | ||
155 | /* | ||
156 | * Frame spans multiple descriptors; this cannot happen yet | ||
157 | * as we don't support jumbograms. If not in monitor mode, | ||
158 | * discard the frame. Enable this if you want to see | ||
159 | * error frames in Monitor mode. | ||
160 | */ | ||
161 | if (sc->sc_ah->opmode != NL80211_IFTYPE_MONITOR) | ||
162 | goto rx_next; | ||
163 | } else if (ds->ds_rxstat.rs_status != 0) { | ||
164 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) | ||
165 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | ||
166 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) | ||
167 | goto rx_next; | ||
168 | |||
169 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) { | ||
170 | *decrypt_error = true; | ||
171 | } else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) { | ||
172 | if (ieee80211_is_ctl(fc)) | ||
173 | /* | ||
174 | * Sometimes, we get invalid | ||
175 | * MIC failures on valid control frames. | ||
176 | * Remove these mic errors. | ||
177 | */ | ||
178 | ds->ds_rxstat.rs_status &= ~ATH9K_RXERR_MIC; | ||
179 | else | ||
180 | rx_status->flag |= RX_FLAG_MMIC_ERROR; | ||
181 | } | ||
182 | /* | ||
183 | * Reject error frames with the exception of | ||
184 | * decryption and MIC failures. For monitor mode, | ||
185 | * we also ignore the CRC error. | ||
186 | */ | ||
187 | if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) { | ||
188 | if (ds->ds_rxstat.rs_status & | ||
189 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | | ||
190 | ATH9K_RXERR_CRC)) | ||
191 | goto rx_next; | ||
192 | } else { | ||
193 | if (ds->ds_rxstat.rs_status & | ||
194 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) { | ||
195 | goto rx_next; | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | |||
200 | ratecode = ds->ds_rxstat.rs_rate; | ||
201 | |||
202 | if (ratecode & 0x80) { | ||
203 | /* HT rate */ | ||
204 | rx_status->flag |= RX_FLAG_HT; | ||
205 | if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040) | ||
206 | rx_status->flag |= RX_FLAG_40MHZ; | ||
207 | if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI) | ||
208 | rx_status->flag |= RX_FLAG_SHORT_GI; | ||
209 | rx_status->rate_idx = ratecode & 0x7f; | ||
210 | } else { | ||
211 | int i = 0, cur_band, n_rates; | ||
212 | |||
213 | cur_band = hw->conf.channel->band; | ||
214 | n_rates = sc->sbands[cur_band].n_bitrates; | ||
215 | |||
216 | for (i = 0; i < n_rates; i++) { | ||
217 | if (sc->sbands[cur_band].bitrates[i].hw_value == | ||
218 | ratecode) { | ||
219 | rx_status->rate_idx = i; | ||
220 | break; | ||
221 | } | ||
222 | |||
223 | if (sc->sbands[cur_band].bitrates[i].hw_value_short == | ||
224 | ratecode) { | ||
225 | rx_status->rate_idx = i; | ||
226 | rx_status->flag |= RX_FLAG_SHORTPRE; | ||
227 | break; | ||
228 | } | ||
229 | } | ||
230 | } | ||
231 | |||
232 | rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp); | ||
233 | rx_status->band = hw->conf.channel->band; | ||
234 | rx_status->freq = hw->conf.channel->center_freq; | ||
235 | rx_status->noise = sc->ani.noise_floor; | ||
236 | rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi; | ||
237 | rx_status->antenna = ds->ds_rxstat.rs_antenna; | ||
238 | |||
239 | /* at 45 you will be able to use MCS 15 reliably. A more elaborate | ||
240 | * scheme can be used here but it requires tables of SNR/throughput for | ||
241 | * each possible mode used. */ | ||
242 | rx_status->qual = ds->ds_rxstat.rs_rssi * 100 / 45; | ||
243 | |||
244 | /* rssi can be more than 45 though, anything above that | ||
245 | * should be considered at 100% */ | ||
246 | if (rx_status->qual > 100) | ||
247 | rx_status->qual = 100; | ||
248 | |||
249 | rx_status->flag |= RX_FLAG_TSFT; | ||
250 | |||
251 | return 1; | ||
252 | rx_next: | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static void ath_opmode_init(struct ath_softc *sc) | ||
257 | { | ||
258 | struct ath_hw *ah = sc->sc_ah; | ||
259 | u32 rfilt, mfilt[2]; | ||
260 | |||
261 | /* configure rx filter */ | ||
262 | rfilt = ath_calcrxfilter(sc); | ||
263 | ath9k_hw_setrxfilter(ah, rfilt); | ||
264 | |||
265 | /* configure bssid mask */ | ||
266 | if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | ||
267 | ath9k_hw_setbssidmask(sc); | ||
268 | |||
269 | /* configure operational mode */ | ||
270 | ath9k_hw_setopmode(ah); | ||
271 | |||
272 | /* Handle any link-level address change. */ | ||
273 | ath9k_hw_setmac(ah, sc->sc_ah->macaddr); | ||
274 | |||
275 | /* calculate and install multicast filter */ | ||
276 | mfilt[0] = mfilt[1] = ~0; | ||
277 | ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); | ||
278 | } | ||
279 | |||
280 | int ath_rx_init(struct ath_softc *sc, int nbufs) | ||
281 | { | ||
282 | struct sk_buff *skb; | ||
283 | struct ath_buf *bf; | ||
284 | int error = 0; | ||
285 | |||
286 | spin_lock_init(&sc->rx.rxflushlock); | ||
287 | sc->sc_flags &= ~SC_OP_RXFLUSH; | ||
288 | spin_lock_init(&sc->rx.rxbuflock); | ||
289 | |||
290 | sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN, | ||
291 | min(sc->cachelsz, (u16)64)); | ||
292 | |||
293 | DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", | ||
294 | sc->cachelsz, sc->rx.bufsize); | ||
295 | |||
296 | /* Initialize rx descriptors */ | ||
297 | |||
298 | error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf, | ||
299 | "rx", nbufs, 1); | ||
300 | if (error != 0) { | ||
301 | DPRINTF(sc, ATH_DBG_FATAL, | ||
302 | "failed to allocate rx descriptors: %d\n", error); | ||
303 | goto err; | ||
304 | } | ||
305 | |||
306 | list_for_each_entry(bf, &sc->rx.rxbuf, list) { | ||
307 | skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL); | ||
308 | if (skb == NULL) { | ||
309 | error = -ENOMEM; | ||
310 | goto err; | ||
311 | } | ||
312 | |||
313 | bf->bf_mpdu = skb; | ||
314 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, | ||
315 | sc->rx.bufsize, | ||
316 | DMA_FROM_DEVICE); | ||
317 | if (unlikely(dma_mapping_error(sc->dev, | ||
318 | bf->bf_buf_addr))) { | ||
319 | dev_kfree_skb_any(skb); | ||
320 | bf->bf_mpdu = NULL; | ||
321 | DPRINTF(sc, ATH_DBG_FATAL, | ||
322 | "dma_mapping_error() on RX init\n"); | ||
323 | error = -ENOMEM; | ||
324 | goto err; | ||
325 | } | ||
326 | bf->bf_dmacontext = bf->bf_buf_addr; | ||
327 | } | ||
328 | sc->rx.rxlink = NULL; | ||
329 | |||
330 | err: | ||
331 | if (error) | ||
332 | ath_rx_cleanup(sc); | ||
333 | |||
334 | return error; | ||
335 | } | ||
336 | |||
337 | void ath_rx_cleanup(struct ath_softc *sc) | ||
338 | { | ||
339 | struct sk_buff *skb; | ||
340 | struct ath_buf *bf; | ||
341 | |||
342 | list_for_each_entry(bf, &sc->rx.rxbuf, list) { | ||
343 | skb = bf->bf_mpdu; | ||
344 | if (skb) { | ||
345 | dma_unmap_single(sc->dev, bf->bf_buf_addr, | ||
346 | sc->rx.bufsize, DMA_FROM_DEVICE); | ||
347 | dev_kfree_skb(skb); | ||
348 | } | ||
349 | } | ||
350 | |||
351 | if (sc->rx.rxdma.dd_desc_len != 0) | ||
352 | ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf); | ||
353 | } | ||
354 | |||
355 | /* | ||
356 | * Calculate the receive filter according to the | ||
357 | * operating mode and state: | ||
358 | * | ||
359 | * o always accept unicast, broadcast, and multicast traffic | ||
360 | * o maintain current state of phy error reception (the hal | ||
361 | * may enable phy error frames for noise immunity work) | ||
362 | * o probe request frames are accepted only when operating in | ||
363 | * hostap, adhoc, or monitor modes | ||
364 | * o enable promiscuous mode according to the interface state | ||
365 | * o accept beacons: | ||
366 | * - when operating in adhoc mode so the 802.11 layer creates | ||
367 | * node table entries for peers, | ||
368 | * - when operating in station mode for collecting rssi data when | ||
369 | * the station is otherwise quiet, or | ||
370 | * - when operating as a repeater so we see repeater-sta beacons | ||
371 | * - when scanning | ||
372 | */ | ||
373 | |||
374 | u32 ath_calcrxfilter(struct ath_softc *sc) | ||
375 | { | ||
376 | #define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR) | ||
377 | |||
378 | u32 rfilt; | ||
379 | |||
380 | rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE) | ||
381 | | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST | ||
382 | | ATH9K_RX_FILTER_MCAST; | ||
383 | |||
384 | /* If not a STA, enable processing of Probe Requests */ | ||
385 | if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) | ||
386 | rfilt |= ATH9K_RX_FILTER_PROBEREQ; | ||
387 | |||
388 | /* | ||
389 | * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station | ||
390 | * mode interface or when in monitor mode. AP mode does not need this | ||
391 | * since it receives all in-BSS frames anyway. | ||
392 | */ | ||
393 | if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) && | ||
394 | (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) || | ||
395 | (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR)) | ||
396 | rfilt |= ATH9K_RX_FILTER_PROM; | ||
397 | |||
398 | if (sc->rx.rxfilter & FIF_CONTROL) | ||
399 | rfilt |= ATH9K_RX_FILTER_CONTROL; | ||
400 | |||
401 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && | ||
402 | !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC)) | ||
403 | rfilt |= ATH9K_RX_FILTER_MYBEACON; | ||
404 | else | ||
405 | rfilt |= ATH9K_RX_FILTER_BEACON; | ||
406 | |||
407 | /* If in HOSTAP mode, want to enable reception of PSPOLL frames */ | ||
408 | if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) | ||
409 | rfilt |= ATH9K_RX_FILTER_PSPOLL; | ||
410 | |||
411 | if (sc->sec_wiphy) { | ||
412 | /* TODO: only needed if more than one BSSID is in use in | ||
413 | * station/adhoc mode */ | ||
414 | /* TODO: for older chips, may need to add ATH9K_RX_FILTER_PROM | ||
415 | */ | ||
416 | rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; | ||
417 | } | ||
418 | |||
419 | return rfilt; | ||
420 | |||
421 | #undef RX_FILTER_PRESERVE | ||
422 | } | ||
423 | |||
424 | int ath_startrecv(struct ath_softc *sc) | ||
425 | { | ||
426 | struct ath_hw *ah = sc->sc_ah; | ||
427 | struct ath_buf *bf, *tbf; | ||
428 | |||
429 | spin_lock_bh(&sc->rx.rxbuflock); | ||
430 | if (list_empty(&sc->rx.rxbuf)) | ||
431 | goto start_recv; | ||
432 | |||
433 | sc->rx.rxlink = NULL; | ||
434 | list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) { | ||
435 | ath_rx_buf_link(sc, bf); | ||
436 | } | ||
437 | |||
438 | /* We could have deleted elements so the list may be empty now */ | ||
439 | if (list_empty(&sc->rx.rxbuf)) | ||
440 | goto start_recv; | ||
441 | |||
442 | bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list); | ||
443 | ath9k_hw_putrxbuf(ah, bf->bf_daddr); | ||
444 | ath9k_hw_rxena(ah); | ||
445 | |||
446 | start_recv: | ||
447 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
448 | ath_opmode_init(sc); | ||
449 | ath9k_hw_startpcureceive(ah); | ||
450 | |||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | bool ath_stoprecv(struct ath_softc *sc) | ||
455 | { | ||
456 | struct ath_hw *ah = sc->sc_ah; | ||
457 | bool stopped; | ||
458 | |||
459 | ath9k_hw_stoppcurecv(ah); | ||
460 | ath9k_hw_setrxfilter(ah, 0); | ||
461 | stopped = ath9k_hw_stopdmarecv(ah); | ||
462 | sc->rx.rxlink = NULL; | ||
463 | |||
464 | return stopped; | ||
465 | } | ||
466 | |||
467 | void ath_flushrecv(struct ath_softc *sc) | ||
468 | { | ||
469 | spin_lock_bh(&sc->rx.rxflushlock); | ||
470 | sc->sc_flags |= SC_OP_RXFLUSH; | ||
471 | ath_rx_tasklet(sc, 1); | ||
472 | sc->sc_flags &= ~SC_OP_RXFLUSH; | ||
473 | spin_unlock_bh(&sc->rx.rxflushlock); | ||
474 | } | ||
475 | |||
476 | int ath_rx_tasklet(struct ath_softc *sc, int flush) | ||
477 | { | ||
478 | #define PA2DESC(_sc, _pa) \ | ||
479 | ((struct ath_desc *)((caddr_t)(_sc)->rx.rxdma.dd_desc + \ | ||
480 | ((_pa) - (_sc)->rx.rxdma.dd_desc_paddr))) | ||
481 | |||
482 | struct ath_buf *bf; | ||
483 | struct ath_desc *ds; | ||
484 | struct sk_buff *skb = NULL, *requeue_skb; | ||
485 | struct ieee80211_rx_status rx_status; | ||
486 | struct ath_hw *ah = sc->sc_ah; | ||
487 | struct ieee80211_hdr *hdr; | ||
488 | int hdrlen, padsize, retval; | ||
489 | bool decrypt_error = false; | ||
490 | u8 keyix; | ||
491 | __le16 fc; | ||
492 | |||
493 | spin_lock_bh(&sc->rx.rxbuflock); | ||
494 | |||
495 | do { | ||
496 | /* If handling rx interrupt and flush is in progress => exit */ | ||
497 | if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0)) | ||
498 | break; | ||
499 | |||
500 | if (list_empty(&sc->rx.rxbuf)) { | ||
501 | sc->rx.rxlink = NULL; | ||
502 | break; | ||
503 | } | ||
504 | |||
505 | bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list); | ||
506 | ds = bf->bf_desc; | ||
507 | |||
508 | /* | ||
509 | * Must provide the virtual address of the current | ||
510 | * descriptor, the physical address, and the virtual | ||
511 | * address of the next descriptor in the h/w chain. | ||
512 | * This allows the HAL to look ahead to see if the | ||
513 | * hardware is done with a descriptor by checking the | ||
514 | * done bit in the following descriptor and the address | ||
515 | * of the current descriptor the DMA engine is working | ||
516 | * on. All this is necessary because of our use of | ||
517 | * a self-linked list to avoid rx overruns. | ||
518 | */ | ||
519 | retval = ath9k_hw_rxprocdesc(ah, ds, | ||
520 | bf->bf_daddr, | ||
521 | PA2DESC(sc, ds->ds_link), | ||
522 | 0); | ||
523 | if (retval == -EINPROGRESS) { | ||
524 | struct ath_buf *tbf; | ||
525 | struct ath_desc *tds; | ||
526 | |||
527 | if (list_is_last(&bf->list, &sc->rx.rxbuf)) { | ||
528 | sc->rx.rxlink = NULL; | ||
529 | break; | ||
530 | } | ||
531 | |||
532 | tbf = list_entry(bf->list.next, struct ath_buf, list); | ||
533 | |||
534 | /* | ||
535 | * On some hardware the descriptor status words could | ||
536 | * get corrupted, including the done bit. Because of | ||
537 | * this, check if the next descriptor's done bit is | ||
538 | * set or not. | ||
539 | * | ||
540 | * If the next descriptor's done bit is set, the current | ||
541 | * descriptor has been corrupted. Force s/w to discard | ||
542 | * this descriptor and continue... | ||
543 | */ | ||
544 | |||
545 | tds = tbf->bf_desc; | ||
546 | retval = ath9k_hw_rxprocdesc(ah, tds, tbf->bf_daddr, | ||
547 | PA2DESC(sc, tds->ds_link), 0); | ||
548 | if (retval == -EINPROGRESS) { | ||
549 | break; | ||
550 | } | ||
551 | } | ||
552 | |||
553 | skb = bf->bf_mpdu; | ||
554 | if (!skb) | ||
555 | continue; | ||
556 | |||
557 | /* | ||
558 | * Synchronize the DMA transfer with CPU before | ||
559 | * 1. accessing the frame | ||
560 | * 2. requeueing the same buffer to h/w | ||
561 | */ | ||
562 | dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, | ||
563 | sc->rx.bufsize, | ||
564 | DMA_FROM_DEVICE); | ||
565 | |||
566 | /* | ||
567 | * If we're asked to flush receive queue, directly | ||
568 | * chain it back at the queue without processing it. | ||
569 | */ | ||
570 | if (flush) | ||
571 | goto requeue; | ||
572 | |||
573 | if (!ds->ds_rxstat.rs_datalen) | ||
574 | goto requeue; | ||
575 | |||
576 | /* The status portion of the descriptor could get corrupted. */ | ||
577 | if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen) | ||
578 | goto requeue; | ||
579 | |||
580 | if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc)) | ||
581 | goto requeue; | ||
582 | |||
583 | /* Ensure we always have an skb to requeue once we are done | ||
584 | * processing the current buffer's skb */ | ||
585 | requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_ATOMIC); | ||
586 | |||
587 | /* If there is no memory we ignore the current RX'd frame, | ||
588 | * tell hardware it can give us a new frame using the old | ||
589 | * skb and put it at the tail of the sc->rx.rxbuf list for | ||
590 | * processing. */ | ||
591 | if (!requeue_skb) | ||
592 | goto requeue; | ||
593 | |||
594 | /* Unmap the frame */ | ||
595 | dma_unmap_single(sc->dev, bf->bf_buf_addr, | ||
596 | sc->rx.bufsize, | ||
597 | DMA_FROM_DEVICE); | ||
598 | |||
599 | skb_put(skb, ds->ds_rxstat.rs_datalen); | ||
600 | skb->protocol = cpu_to_be16(ETH_P_CONTROL); | ||
601 | |||
602 | /* see if any padding is done by the hw and remove it */ | ||
603 | hdr = (struct ieee80211_hdr *)skb->data; | ||
604 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
605 | fc = hdr->frame_control; | ||
606 | |||
607 | /* The MAC header is padded to have 32-bit boundary if the | ||
608 | * packet payload is non-zero. The general calculation for | ||
609 | * padsize would take into account odd header lengths: | ||
610 | * padsize = (4 - hdrlen % 4) % 4; However, since only | ||
611 | * even-length headers are used, padding can only be 0 or 2 | ||
612 | * bytes and we can optimize this a bit. In addition, we must | ||
613 | * not try to remove padding from short control frames that do | ||
614 | * not have payload. */ | ||
615 | padsize = hdrlen & 3; | ||
616 | if (padsize && hdrlen >= 24) { | ||
617 | memmove(skb->data + padsize, skb->data, hdrlen); | ||
618 | skb_pull(skb, padsize); | ||
619 | } | ||
620 | |||
621 | keyix = ds->ds_rxstat.rs_keyix; | ||
622 | |||
623 | if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) { | ||
624 | rx_status.flag |= RX_FLAG_DECRYPTED; | ||
625 | } else if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) | ||
626 | && !decrypt_error && skb->len >= hdrlen + 4) { | ||
627 | keyix = skb->data[hdrlen + 3] >> 6; | ||
628 | |||
629 | if (test_bit(keyix, sc->keymap)) | ||
630 | rx_status.flag |= RX_FLAG_DECRYPTED; | ||
631 | } | ||
632 | if (ah->sw_mgmt_crypto && | ||
633 | (rx_status.flag & RX_FLAG_DECRYPTED) && | ||
634 | ieee80211_is_mgmt(hdr->frame_control)) { | ||
635 | /* Use software decrypt for management frames. */ | ||
636 | rx_status.flag &= ~RX_FLAG_DECRYPTED; | ||
637 | } | ||
638 | |||
639 | /* Send the frame to mac80211 */ | ||
640 | if (hdr->addr1[5] & 0x01) { | ||
641 | int i; | ||
642 | /* | ||
643 | * Deliver broadcast/multicast frames to all suitable | ||
644 | * virtual wiphys. | ||
645 | */ | ||
646 | /* TODO: filter based on channel configuration */ | ||
647 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
648 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
649 | struct sk_buff *nskb; | ||
650 | if (aphy == NULL) | ||
651 | continue; | ||
652 | nskb = skb_copy(skb, GFP_ATOMIC); | ||
653 | if (nskb) | ||
654 | __ieee80211_rx(aphy->hw, nskb, | ||
655 | &rx_status); | ||
656 | } | ||
657 | __ieee80211_rx(sc->hw, skb, &rx_status); | ||
658 | } else { | ||
659 | /* Deliver unicast frames based on receiver address */ | ||
660 | __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb, | ||
661 | &rx_status); | ||
662 | } | ||
663 | |||
664 | /* We will now give hardware our shiny new allocated skb */ | ||
665 | bf->bf_mpdu = requeue_skb; | ||
666 | bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data, | ||
667 | sc->rx.bufsize, | ||
668 | DMA_FROM_DEVICE); | ||
669 | if (unlikely(dma_mapping_error(sc->dev, | ||
670 | bf->bf_buf_addr))) { | ||
671 | dev_kfree_skb_any(requeue_skb); | ||
672 | bf->bf_mpdu = NULL; | ||
673 | DPRINTF(sc, ATH_DBG_FATAL, | ||
674 | "dma_mapping_error() on RX\n"); | ||
675 | break; | ||
676 | } | ||
677 | bf->bf_dmacontext = bf->bf_buf_addr; | ||
678 | |||
679 | /* | ||
680 | * change the default rx antenna if rx diversity chooses the | ||
681 | * other antenna 3 times in a row. | ||
682 | */ | ||
683 | if (sc->rx.defant != ds->ds_rxstat.rs_antenna) { | ||
684 | if (++sc->rx.rxotherant >= 3) | ||
685 | ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna); | ||
686 | } else { | ||
687 | sc->rx.rxotherant = 0; | ||
688 | } | ||
689 | |||
690 | if (ieee80211_is_beacon(fc) && | ||
691 | (sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) { | ||
692 | sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; | ||
693 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); | ||
694 | } | ||
695 | requeue: | ||
696 | list_move_tail(&bf->list, &sc->rx.rxbuf); | ||
697 | ath_rx_buf_link(sc, bf); | ||
698 | } while (1); | ||
699 | |||
700 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
701 | |||
702 | return 0; | ||
703 | #undef PA2DESC | ||
704 | } | ||
diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath9k/reg.h deleted file mode 100644 index 52605246679f..000000000000 --- a/drivers/net/wireless/ath9k/reg.h +++ /dev/null | |||
@@ -1,1511 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 REG_H | ||
18 | #define REG_H | ||
19 | |||
20 | #define AR_CR 0x0008 | ||
21 | #define AR_CR_RXE 0x00000004 | ||
22 | #define AR_CR_RXD 0x00000020 | ||
23 | #define AR_CR_SWI 0x00000040 | ||
24 | |||
25 | #define AR_RXDP 0x000C | ||
26 | |||
27 | #define AR_CFG 0x0014 | ||
28 | #define AR_CFG_SWTD 0x00000001 | ||
29 | #define AR_CFG_SWTB 0x00000002 | ||
30 | #define AR_CFG_SWRD 0x00000004 | ||
31 | #define AR_CFG_SWRB 0x00000008 | ||
32 | #define AR_CFG_SWRG 0x00000010 | ||
33 | #define AR_CFG_AP_ADHOC_INDICATION 0x00000020 | ||
34 | #define AR_CFG_PHOK 0x00000100 | ||
35 | #define AR_CFG_CLK_GATE_DIS 0x00000400 | ||
36 | #define AR_CFG_EEBS 0x00000200 | ||
37 | #define AR_CFG_PCI_MASTER_REQ_Q_THRESH 0x00060000 | ||
38 | #define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S 17 | ||
39 | |||
40 | #define AR_MIRT 0x0020 | ||
41 | #define AR_MIRT_VAL 0x0000ffff | ||
42 | #define AR_MIRT_VAL_S 16 | ||
43 | |||
44 | #define AR_IER 0x0024 | ||
45 | #define AR_IER_ENABLE 0x00000001 | ||
46 | #define AR_IER_DISABLE 0x00000000 | ||
47 | |||
48 | #define AR_TIMT 0x0028 | ||
49 | #define AR_TIMT_LAST 0x0000ffff | ||
50 | #define AR_TIMT_LAST_S 0 | ||
51 | #define AR_TIMT_FIRST 0xffff0000 | ||
52 | #define AR_TIMT_FIRST_S 16 | ||
53 | |||
54 | #define AR_RIMT 0x002C | ||
55 | #define AR_RIMT_LAST 0x0000ffff | ||
56 | #define AR_RIMT_LAST_S 0 | ||
57 | #define AR_RIMT_FIRST 0xffff0000 | ||
58 | #define AR_RIMT_FIRST_S 16 | ||
59 | |||
60 | #define AR_DMASIZE_4B 0x00000000 | ||
61 | #define AR_DMASIZE_8B 0x00000001 | ||
62 | #define AR_DMASIZE_16B 0x00000002 | ||
63 | #define AR_DMASIZE_32B 0x00000003 | ||
64 | #define AR_DMASIZE_64B 0x00000004 | ||
65 | #define AR_DMASIZE_128B 0x00000005 | ||
66 | #define AR_DMASIZE_256B 0x00000006 | ||
67 | #define AR_DMASIZE_512B 0x00000007 | ||
68 | |||
69 | #define AR_TXCFG 0x0030 | ||
70 | #define AR_TXCFG_DMASZ_MASK 0x00000007 | ||
71 | #define AR_TXCFG_DMASZ_4B 0 | ||
72 | #define AR_TXCFG_DMASZ_8B 1 | ||
73 | #define AR_TXCFG_DMASZ_16B 2 | ||
74 | #define AR_TXCFG_DMASZ_32B 3 | ||
75 | #define AR_TXCFG_DMASZ_64B 4 | ||
76 | #define AR_TXCFG_DMASZ_128B 5 | ||
77 | #define AR_TXCFG_DMASZ_256B 6 | ||
78 | #define AR_TXCFG_DMASZ_512B 7 | ||
79 | #define AR_FTRIG 0x000003F0 | ||
80 | #define AR_FTRIG_S 4 | ||
81 | #define AR_FTRIG_IMMED 0x00000000 | ||
82 | #define AR_FTRIG_64B 0x00000010 | ||
83 | #define AR_FTRIG_128B 0x00000020 | ||
84 | #define AR_FTRIG_192B 0x00000030 | ||
85 | #define AR_FTRIG_256B 0x00000040 | ||
86 | #define AR_FTRIG_512B 0x00000080 | ||
87 | #define AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY 0x00000800 | ||
88 | |||
89 | #define AR_RXCFG 0x0034 | ||
90 | #define AR_RXCFG_CHIRP 0x00000008 | ||
91 | #define AR_RXCFG_ZLFDMA 0x00000010 | ||
92 | #define AR_RXCFG_DMASZ_MASK 0x00000007 | ||
93 | #define AR_RXCFG_DMASZ_4B 0 | ||
94 | #define AR_RXCFG_DMASZ_8B 1 | ||
95 | #define AR_RXCFG_DMASZ_16B 2 | ||
96 | #define AR_RXCFG_DMASZ_32B 3 | ||
97 | #define AR_RXCFG_DMASZ_64B 4 | ||
98 | #define AR_RXCFG_DMASZ_128B 5 | ||
99 | #define AR_RXCFG_DMASZ_256B 6 | ||
100 | #define AR_RXCFG_DMASZ_512B 7 | ||
101 | |||
102 | #define AR_MIBC 0x0040 | ||
103 | #define AR_MIBC_COW 0x00000001 | ||
104 | #define AR_MIBC_FMC 0x00000002 | ||
105 | #define AR_MIBC_CMC 0x00000004 | ||
106 | #define AR_MIBC_MCS 0x00000008 | ||
107 | |||
108 | #define AR_TOPS 0x0044 | ||
109 | #define AR_TOPS_MASK 0x0000FFFF | ||
110 | |||
111 | #define AR_RXNPTO 0x0048 | ||
112 | #define AR_RXNPTO_MASK 0x000003FF | ||
113 | |||
114 | #define AR_TXNPTO 0x004C | ||
115 | #define AR_TXNPTO_MASK 0x000003FF | ||
116 | #define AR_TXNPTO_QCU_MASK 0x000FFC00 | ||
117 | |||
118 | #define AR_RPGTO 0x0050 | ||
119 | #define AR_RPGTO_MASK 0x000003FF | ||
120 | |||
121 | #define AR_RPCNT 0x0054 | ||
122 | #define AR_RPCNT_MASK 0x0000001F | ||
123 | |||
124 | #define AR_MACMISC 0x0058 | ||
125 | #define AR_MACMISC_PCI_EXT_FORCE 0x00000010 | ||
126 | #define AR_MACMISC_DMA_OBS 0x000001E0 | ||
127 | #define AR_MACMISC_DMA_OBS_S 5 | ||
128 | #define AR_MACMISC_DMA_OBS_LINE_0 0 | ||
129 | #define AR_MACMISC_DMA_OBS_LINE_1 1 | ||
130 | #define AR_MACMISC_DMA_OBS_LINE_2 2 | ||
131 | #define AR_MACMISC_DMA_OBS_LINE_3 3 | ||
132 | #define AR_MACMISC_DMA_OBS_LINE_4 4 | ||
133 | #define AR_MACMISC_DMA_OBS_LINE_5 5 | ||
134 | #define AR_MACMISC_DMA_OBS_LINE_6 6 | ||
135 | #define AR_MACMISC_DMA_OBS_LINE_7 7 | ||
136 | #define AR_MACMISC_DMA_OBS_LINE_8 8 | ||
137 | #define AR_MACMISC_MISC_OBS 0x00000E00 | ||
138 | #define AR_MACMISC_MISC_OBS_S 9 | ||
139 | #define AR_MACMISC_MISC_OBS_BUS_LSB 0x00007000 | ||
140 | #define AR_MACMISC_MISC_OBS_BUS_LSB_S 12 | ||
141 | #define AR_MACMISC_MISC_OBS_BUS_MSB 0x00038000 | ||
142 | #define AR_MACMISC_MISC_OBS_BUS_MSB_S 15 | ||
143 | #define AR_MACMISC_MISC_OBS_BUS_1 1 | ||
144 | |||
145 | #define AR_GTXTO 0x0064 | ||
146 | #define AR_GTXTO_TIMEOUT_COUNTER 0x0000FFFF | ||
147 | #define AR_GTXTO_TIMEOUT_LIMIT 0xFFFF0000 | ||
148 | #define AR_GTXTO_TIMEOUT_LIMIT_S 16 | ||
149 | |||
150 | #define AR_GTTM 0x0068 | ||
151 | #define AR_GTTM_USEC 0x00000001 | ||
152 | #define AR_GTTM_IGNORE_IDLE 0x00000002 | ||
153 | #define AR_GTTM_RESET_IDLE 0x00000004 | ||
154 | #define AR_GTTM_CST_USEC 0x00000008 | ||
155 | |||
156 | #define AR_CST 0x006C | ||
157 | #define AR_CST_TIMEOUT_COUNTER 0x0000FFFF | ||
158 | #define AR_CST_TIMEOUT_LIMIT 0xFFFF0000 | ||
159 | #define AR_CST_TIMEOUT_LIMIT_S 16 | ||
160 | |||
161 | #define AR_ISR 0x0080 | ||
162 | #define AR_ISR_RXOK 0x00000001 | ||
163 | #define AR_ISR_RXDESC 0x00000002 | ||
164 | #define AR_ISR_RXERR 0x00000004 | ||
165 | #define AR_ISR_RXNOPKT 0x00000008 | ||
166 | #define AR_ISR_RXEOL 0x00000010 | ||
167 | #define AR_ISR_RXORN 0x00000020 | ||
168 | #define AR_ISR_TXOK 0x00000040 | ||
169 | #define AR_ISR_TXDESC 0x00000080 | ||
170 | #define AR_ISR_TXERR 0x00000100 | ||
171 | #define AR_ISR_TXNOPKT 0x00000200 | ||
172 | #define AR_ISR_TXEOL 0x00000400 | ||
173 | #define AR_ISR_TXURN 0x00000800 | ||
174 | #define AR_ISR_MIB 0x00001000 | ||
175 | #define AR_ISR_SWI 0x00002000 | ||
176 | #define AR_ISR_RXPHY 0x00004000 | ||
177 | #define AR_ISR_RXKCM 0x00008000 | ||
178 | #define AR_ISR_SWBA 0x00010000 | ||
179 | #define AR_ISR_BRSSI 0x00020000 | ||
180 | #define AR_ISR_BMISS 0x00040000 | ||
181 | #define AR_ISR_BNR 0x00100000 | ||
182 | #define AR_ISR_RXCHIRP 0x00200000 | ||
183 | #define AR_ISR_BCNMISC 0x00800000 | ||
184 | #define AR_ISR_TIM 0x00800000 | ||
185 | #define AR_ISR_QCBROVF 0x02000000 | ||
186 | #define AR_ISR_QCBRURN 0x04000000 | ||
187 | #define AR_ISR_QTRIG 0x08000000 | ||
188 | #define AR_ISR_GENTMR 0x10000000 | ||
189 | |||
190 | #define AR_ISR_TXMINTR 0x00080000 | ||
191 | #define AR_ISR_RXMINTR 0x01000000 | ||
192 | #define AR_ISR_TXINTM 0x40000000 | ||
193 | #define AR_ISR_RXINTM 0x80000000 | ||
194 | |||
195 | #define AR_ISR_S0 0x0084 | ||
196 | #define AR_ISR_S0_QCU_TXOK 0x000003FF | ||
197 | #define AR_ISR_S0_QCU_TXOK_S 0 | ||
198 | #define AR_ISR_S0_QCU_TXDESC 0x03FF0000 | ||
199 | #define AR_ISR_S0_QCU_TXDESC_S 16 | ||
200 | |||
201 | #define AR_ISR_S1 0x0088 | ||
202 | #define AR_ISR_S1_QCU_TXERR 0x000003FF | ||
203 | #define AR_ISR_S1_QCU_TXERR_S 0 | ||
204 | #define AR_ISR_S1_QCU_TXEOL 0x03FF0000 | ||
205 | #define AR_ISR_S1_QCU_TXEOL_S 16 | ||
206 | |||
207 | #define AR_ISR_S2 0x008c | ||
208 | #define AR_ISR_S2_QCU_TXURN 0x000003FF | ||
209 | #define AR_ISR_S2_CST 0x00400000 | ||
210 | #define AR_ISR_S2_GTT 0x00800000 | ||
211 | #define AR_ISR_S2_TIM 0x01000000 | ||
212 | #define AR_ISR_S2_CABEND 0x02000000 | ||
213 | #define AR_ISR_S2_DTIMSYNC 0x04000000 | ||
214 | #define AR_ISR_S2_BCNTO 0x08000000 | ||
215 | #define AR_ISR_S2_CABTO 0x10000000 | ||
216 | #define AR_ISR_S2_DTIM 0x20000000 | ||
217 | #define AR_ISR_S2_TSFOOR 0x40000000 | ||
218 | #define AR_ISR_S2_TBTT_TIME 0x80000000 | ||
219 | |||
220 | #define AR_ISR_S3 0x0090 | ||
221 | #define AR_ISR_S3_QCU_QCBROVF 0x000003FF | ||
222 | #define AR_ISR_S3_QCU_QCBRURN 0x03FF0000 | ||
223 | |||
224 | #define AR_ISR_S4 0x0094 | ||
225 | #define AR_ISR_S4_QCU_QTRIG 0x000003FF | ||
226 | #define AR_ISR_S4_RESV0 0xFFFFFC00 | ||
227 | |||
228 | #define AR_ISR_S5 0x0098 | ||
229 | #define AR_ISR_S5_TIMER_TRIG 0x000000FF | ||
230 | #define AR_ISR_S5_TIMER_THRESH 0x0007FE00 | ||
231 | #define AR_ISR_S5_TIM_TIMER 0x00000010 | ||
232 | #define AR_ISR_S5_DTIM_TIMER 0x00000020 | ||
233 | #define AR_ISR_S5_S 0x00d8 | ||
234 | #define AR_IMR_S5 0x00b8 | ||
235 | #define AR_IMR_S5_TIM_TIMER 0x00000010 | ||
236 | #define AR_IMR_S5_DTIM_TIMER 0x00000020 | ||
237 | |||
238 | |||
239 | #define AR_IMR 0x00a0 | ||
240 | #define AR_IMR_RXOK 0x00000001 | ||
241 | #define AR_IMR_RXDESC 0x00000002 | ||
242 | #define AR_IMR_RXERR 0x00000004 | ||
243 | #define AR_IMR_RXNOPKT 0x00000008 | ||
244 | #define AR_IMR_RXEOL 0x00000010 | ||
245 | #define AR_IMR_RXORN 0x00000020 | ||
246 | #define AR_IMR_TXOK 0x00000040 | ||
247 | #define AR_IMR_TXDESC 0x00000080 | ||
248 | #define AR_IMR_TXERR 0x00000100 | ||
249 | #define AR_IMR_TXNOPKT 0x00000200 | ||
250 | #define AR_IMR_TXEOL 0x00000400 | ||
251 | #define AR_IMR_TXURN 0x00000800 | ||
252 | #define AR_IMR_MIB 0x00001000 | ||
253 | #define AR_IMR_SWI 0x00002000 | ||
254 | #define AR_IMR_RXPHY 0x00004000 | ||
255 | #define AR_IMR_RXKCM 0x00008000 | ||
256 | #define AR_IMR_SWBA 0x00010000 | ||
257 | #define AR_IMR_BRSSI 0x00020000 | ||
258 | #define AR_IMR_BMISS 0x00040000 | ||
259 | #define AR_IMR_BNR 0x00100000 | ||
260 | #define AR_IMR_RXCHIRP 0x00200000 | ||
261 | #define AR_IMR_BCNMISC 0x00800000 | ||
262 | #define AR_IMR_TIM 0x00800000 | ||
263 | #define AR_IMR_QCBROVF 0x02000000 | ||
264 | #define AR_IMR_QCBRURN 0x04000000 | ||
265 | #define AR_IMR_QTRIG 0x08000000 | ||
266 | #define AR_IMR_GENTMR 0x10000000 | ||
267 | |||
268 | #define AR_IMR_TXMINTR 0x00080000 | ||
269 | #define AR_IMR_RXMINTR 0x01000000 | ||
270 | #define AR_IMR_TXINTM 0x40000000 | ||
271 | #define AR_IMR_RXINTM 0x80000000 | ||
272 | |||
273 | #define AR_IMR_S0 0x00a4 | ||
274 | #define AR_IMR_S0_QCU_TXOK 0x000003FF | ||
275 | #define AR_IMR_S0_QCU_TXOK_S 0 | ||
276 | #define AR_IMR_S0_QCU_TXDESC 0x03FF0000 | ||
277 | #define AR_IMR_S0_QCU_TXDESC_S 16 | ||
278 | |||
279 | #define AR_IMR_S1 0x00a8 | ||
280 | #define AR_IMR_S1_QCU_TXERR 0x000003FF | ||
281 | #define AR_IMR_S1_QCU_TXERR_S 0 | ||
282 | #define AR_IMR_S1_QCU_TXEOL 0x03FF0000 | ||
283 | #define AR_IMR_S1_QCU_TXEOL_S 16 | ||
284 | |||
285 | #define AR_IMR_S2 0x00ac | ||
286 | #define AR_IMR_S2_QCU_TXURN 0x000003FF | ||
287 | #define AR_IMR_S2_QCU_TXURN_S 0 | ||
288 | #define AR_IMR_S2_CST 0x00400000 | ||
289 | #define AR_IMR_S2_GTT 0x00800000 | ||
290 | #define AR_IMR_S2_TIM 0x01000000 | ||
291 | #define AR_IMR_S2_CABEND 0x02000000 | ||
292 | #define AR_IMR_S2_DTIMSYNC 0x04000000 | ||
293 | #define AR_IMR_S2_BCNTO 0x08000000 | ||
294 | #define AR_IMR_S2_CABTO 0x10000000 | ||
295 | #define AR_IMR_S2_DTIM 0x20000000 | ||
296 | #define AR_IMR_S2_TSFOOR 0x40000000 | ||
297 | |||
298 | #define AR_IMR_S3 0x00b0 | ||
299 | #define AR_IMR_S3_QCU_QCBROVF 0x000003FF | ||
300 | #define AR_IMR_S3_QCU_QCBRURN 0x03FF0000 | ||
301 | #define AR_IMR_S3_QCU_QCBRURN_S 16 | ||
302 | |||
303 | #define AR_IMR_S4 0x00b4 | ||
304 | #define AR_IMR_S4_QCU_QTRIG 0x000003FF | ||
305 | #define AR_IMR_S4_RESV0 0xFFFFFC00 | ||
306 | |||
307 | #define AR_IMR_S5 0x00b8 | ||
308 | #define AR_IMR_S5_TIMER_TRIG 0x000000FF | ||
309 | #define AR_IMR_S5_TIMER_THRESH 0x0000FF00 | ||
310 | |||
311 | |||
312 | #define AR_ISR_RAC 0x00c0 | ||
313 | #define AR_ISR_S0_S 0x00c4 | ||
314 | #define AR_ISR_S0_QCU_TXOK 0x000003FF | ||
315 | #define AR_ISR_S0_QCU_TXOK_S 0 | ||
316 | #define AR_ISR_S0_QCU_TXDESC 0x03FF0000 | ||
317 | #define AR_ISR_S0_QCU_TXDESC_S 16 | ||
318 | |||
319 | #define AR_ISR_S1_S 0x00c8 | ||
320 | #define AR_ISR_S1_QCU_TXERR 0x000003FF | ||
321 | #define AR_ISR_S1_QCU_TXERR_S 0 | ||
322 | #define AR_ISR_S1_QCU_TXEOL 0x03FF0000 | ||
323 | #define AR_ISR_S1_QCU_TXEOL_S 16 | ||
324 | |||
325 | #define AR_ISR_S2_S 0x00cc | ||
326 | #define AR_ISR_S3_S 0x00d0 | ||
327 | #define AR_ISR_S4_S 0x00d4 | ||
328 | #define AR_ISR_S5_S 0x00d8 | ||
329 | #define AR_DMADBG_0 0x00e0 | ||
330 | #define AR_DMADBG_1 0x00e4 | ||
331 | #define AR_DMADBG_2 0x00e8 | ||
332 | #define AR_DMADBG_3 0x00ec | ||
333 | #define AR_DMADBG_4 0x00f0 | ||
334 | #define AR_DMADBG_5 0x00f4 | ||
335 | #define AR_DMADBG_6 0x00f8 | ||
336 | #define AR_DMADBG_7 0x00fc | ||
337 | |||
338 | #define AR_NUM_QCU 10 | ||
339 | #define AR_QCU_0 0x0001 | ||
340 | #define AR_QCU_1 0x0002 | ||
341 | #define AR_QCU_2 0x0004 | ||
342 | #define AR_QCU_3 0x0008 | ||
343 | #define AR_QCU_4 0x0010 | ||
344 | #define AR_QCU_5 0x0020 | ||
345 | #define AR_QCU_6 0x0040 | ||
346 | #define AR_QCU_7 0x0080 | ||
347 | #define AR_QCU_8 0x0100 | ||
348 | #define AR_QCU_9 0x0200 | ||
349 | |||
350 | #define AR_Q0_TXDP 0x0800 | ||
351 | #define AR_Q1_TXDP 0x0804 | ||
352 | #define AR_Q2_TXDP 0x0808 | ||
353 | #define AR_Q3_TXDP 0x080c | ||
354 | #define AR_Q4_TXDP 0x0810 | ||
355 | #define AR_Q5_TXDP 0x0814 | ||
356 | #define AR_Q6_TXDP 0x0818 | ||
357 | #define AR_Q7_TXDP 0x081c | ||
358 | #define AR_Q8_TXDP 0x0820 | ||
359 | #define AR_Q9_TXDP 0x0824 | ||
360 | #define AR_QTXDP(_i) (AR_Q0_TXDP + ((_i)<<2)) | ||
361 | |||
362 | #define AR_Q_TXE 0x0840 | ||
363 | #define AR_Q_TXE_M 0x000003FF | ||
364 | |||
365 | #define AR_Q_TXD 0x0880 | ||
366 | #define AR_Q_TXD_M 0x000003FF | ||
367 | |||
368 | #define AR_Q0_CBRCFG 0x08c0 | ||
369 | #define AR_Q1_CBRCFG 0x08c4 | ||
370 | #define AR_Q2_CBRCFG 0x08c8 | ||
371 | #define AR_Q3_CBRCFG 0x08cc | ||
372 | #define AR_Q4_CBRCFG 0x08d0 | ||
373 | #define AR_Q5_CBRCFG 0x08d4 | ||
374 | #define AR_Q6_CBRCFG 0x08d8 | ||
375 | #define AR_Q7_CBRCFG 0x08dc | ||
376 | #define AR_Q8_CBRCFG 0x08e0 | ||
377 | #define AR_Q9_CBRCFG 0x08e4 | ||
378 | #define AR_QCBRCFG(_i) (AR_Q0_CBRCFG + ((_i)<<2)) | ||
379 | #define AR_Q_CBRCFG_INTERVAL 0x00FFFFFF | ||
380 | #define AR_Q_CBRCFG_INTERVAL_S 0 | ||
381 | #define AR_Q_CBRCFG_OVF_THRESH 0xFF000000 | ||
382 | #define AR_Q_CBRCFG_OVF_THRESH_S 24 | ||
383 | |||
384 | #define AR_Q0_RDYTIMECFG 0x0900 | ||
385 | #define AR_Q1_RDYTIMECFG 0x0904 | ||
386 | #define AR_Q2_RDYTIMECFG 0x0908 | ||
387 | #define AR_Q3_RDYTIMECFG 0x090c | ||
388 | #define AR_Q4_RDYTIMECFG 0x0910 | ||
389 | #define AR_Q5_RDYTIMECFG 0x0914 | ||
390 | #define AR_Q6_RDYTIMECFG 0x0918 | ||
391 | #define AR_Q7_RDYTIMECFG 0x091c | ||
392 | #define AR_Q8_RDYTIMECFG 0x0920 | ||
393 | #define AR_Q9_RDYTIMECFG 0x0924 | ||
394 | #define AR_QRDYTIMECFG(_i) (AR_Q0_RDYTIMECFG + ((_i)<<2)) | ||
395 | #define AR_Q_RDYTIMECFG_DURATION 0x00FFFFFF | ||
396 | #define AR_Q_RDYTIMECFG_DURATION_S 0 | ||
397 | #define AR_Q_RDYTIMECFG_EN 0x01000000 | ||
398 | |||
399 | #define AR_Q_ONESHOTARM_SC 0x0940 | ||
400 | #define AR_Q_ONESHOTARM_SC_M 0x000003FF | ||
401 | #define AR_Q_ONESHOTARM_SC_RESV0 0xFFFFFC00 | ||
402 | |||
403 | #define AR_Q_ONESHOTARM_CC 0x0980 | ||
404 | #define AR_Q_ONESHOTARM_CC_M 0x000003FF | ||
405 | #define AR_Q_ONESHOTARM_CC_RESV0 0xFFFFFC00 | ||
406 | |||
407 | #define AR_Q0_MISC 0x09c0 | ||
408 | #define AR_Q1_MISC 0x09c4 | ||
409 | #define AR_Q2_MISC 0x09c8 | ||
410 | #define AR_Q3_MISC 0x09cc | ||
411 | #define AR_Q4_MISC 0x09d0 | ||
412 | #define AR_Q5_MISC 0x09d4 | ||
413 | #define AR_Q6_MISC 0x09d8 | ||
414 | #define AR_Q7_MISC 0x09dc | ||
415 | #define AR_Q8_MISC 0x09e0 | ||
416 | #define AR_Q9_MISC 0x09e4 | ||
417 | #define AR_QMISC(_i) (AR_Q0_MISC + ((_i)<<2)) | ||
418 | #define AR_Q_MISC_FSP 0x0000000F | ||
419 | #define AR_Q_MISC_FSP_ASAP 0 | ||
420 | #define AR_Q_MISC_FSP_CBR 1 | ||
421 | #define AR_Q_MISC_FSP_DBA_GATED 2 | ||
422 | #define AR_Q_MISC_FSP_TIM_GATED 3 | ||
423 | #define AR_Q_MISC_FSP_BEACON_SENT_GATED 4 | ||
424 | #define AR_Q_MISC_FSP_BEACON_RCVD_GATED 5 | ||
425 | #define AR_Q_MISC_ONE_SHOT_EN 0x00000010 | ||
426 | #define AR_Q_MISC_CBR_INCR_DIS1 0x00000020 | ||
427 | #define AR_Q_MISC_CBR_INCR_DIS0 0x00000040 | ||
428 | #define AR_Q_MISC_BEACON_USE 0x00000080 | ||
429 | #define AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN 0x00000100 | ||
430 | #define AR_Q_MISC_RDYTIME_EXP_POLICY 0x00000200 | ||
431 | #define AR_Q_MISC_RESET_CBR_EXP_CTR 0x00000400 | ||
432 | #define AR_Q_MISC_DCU_EARLY_TERM_REQ 0x00000800 | ||
433 | #define AR_Q_MISC_RESV0 0xFFFFF000 | ||
434 | |||
435 | #define AR_Q0_STS 0x0a00 | ||
436 | #define AR_Q1_STS 0x0a04 | ||
437 | #define AR_Q2_STS 0x0a08 | ||
438 | #define AR_Q3_STS 0x0a0c | ||
439 | #define AR_Q4_STS 0x0a10 | ||
440 | #define AR_Q5_STS 0x0a14 | ||
441 | #define AR_Q6_STS 0x0a18 | ||
442 | #define AR_Q7_STS 0x0a1c | ||
443 | #define AR_Q8_STS 0x0a20 | ||
444 | #define AR_Q9_STS 0x0a24 | ||
445 | #define AR_QSTS(_i) (AR_Q0_STS + ((_i)<<2)) | ||
446 | #define AR_Q_STS_PEND_FR_CNT 0x00000003 | ||
447 | #define AR_Q_STS_RESV0 0x000000FC | ||
448 | #define AR_Q_STS_CBR_EXP_CNT 0x0000FF00 | ||
449 | #define AR_Q_STS_RESV1 0xFFFF0000 | ||
450 | |||
451 | #define AR_Q_RDYTIMESHDN 0x0a40 | ||
452 | #define AR_Q_RDYTIMESHDN_M 0x000003FF | ||
453 | |||
454 | |||
455 | #define AR_NUM_DCU 10 | ||
456 | #define AR_DCU_0 0x0001 | ||
457 | #define AR_DCU_1 0x0002 | ||
458 | #define AR_DCU_2 0x0004 | ||
459 | #define AR_DCU_3 0x0008 | ||
460 | #define AR_DCU_4 0x0010 | ||
461 | #define AR_DCU_5 0x0020 | ||
462 | #define AR_DCU_6 0x0040 | ||
463 | #define AR_DCU_7 0x0080 | ||
464 | #define AR_DCU_8 0x0100 | ||
465 | #define AR_DCU_9 0x0200 | ||
466 | |||
467 | #define AR_D0_QCUMASK 0x1000 | ||
468 | #define AR_D1_QCUMASK 0x1004 | ||
469 | #define AR_D2_QCUMASK 0x1008 | ||
470 | #define AR_D3_QCUMASK 0x100c | ||
471 | #define AR_D4_QCUMASK 0x1010 | ||
472 | #define AR_D5_QCUMASK 0x1014 | ||
473 | #define AR_D6_QCUMASK 0x1018 | ||
474 | #define AR_D7_QCUMASK 0x101c | ||
475 | #define AR_D8_QCUMASK 0x1020 | ||
476 | #define AR_D9_QCUMASK 0x1024 | ||
477 | #define AR_DQCUMASK(_i) (AR_D0_QCUMASK + ((_i)<<2)) | ||
478 | #define AR_D_QCUMASK 0x000003FF | ||
479 | #define AR_D_QCUMASK_RESV0 0xFFFFFC00 | ||
480 | |||
481 | #define AR_D_TXBLK_CMD 0x1038 | ||
482 | #define AR_D_TXBLK_DATA(i) (AR_D_TXBLK_CMD+(i)) | ||
483 | |||
484 | #define AR_D0_LCL_IFS 0x1040 | ||
485 | #define AR_D1_LCL_IFS 0x1044 | ||
486 | #define AR_D2_LCL_IFS 0x1048 | ||
487 | #define AR_D3_LCL_IFS 0x104c | ||
488 | #define AR_D4_LCL_IFS 0x1050 | ||
489 | #define AR_D5_LCL_IFS 0x1054 | ||
490 | #define AR_D6_LCL_IFS 0x1058 | ||
491 | #define AR_D7_LCL_IFS 0x105c | ||
492 | #define AR_D8_LCL_IFS 0x1060 | ||
493 | #define AR_D9_LCL_IFS 0x1064 | ||
494 | #define AR_DLCL_IFS(_i) (AR_D0_LCL_IFS + ((_i)<<2)) | ||
495 | #define AR_D_LCL_IFS_CWMIN 0x000003FF | ||
496 | #define AR_D_LCL_IFS_CWMIN_S 0 | ||
497 | #define AR_D_LCL_IFS_CWMAX 0x000FFC00 | ||
498 | #define AR_D_LCL_IFS_CWMAX_S 10 | ||
499 | #define AR_D_LCL_IFS_AIFS 0x0FF00000 | ||
500 | #define AR_D_LCL_IFS_AIFS_S 20 | ||
501 | |||
502 | #define AR_D_LCL_IFS_RESV0 0xF0000000 | ||
503 | |||
504 | #define AR_D0_RETRY_LIMIT 0x1080 | ||
505 | #define AR_D1_RETRY_LIMIT 0x1084 | ||
506 | #define AR_D2_RETRY_LIMIT 0x1088 | ||
507 | #define AR_D3_RETRY_LIMIT 0x108c | ||
508 | #define AR_D4_RETRY_LIMIT 0x1090 | ||
509 | #define AR_D5_RETRY_LIMIT 0x1094 | ||
510 | #define AR_D6_RETRY_LIMIT 0x1098 | ||
511 | #define AR_D7_RETRY_LIMIT 0x109c | ||
512 | #define AR_D8_RETRY_LIMIT 0x10a0 | ||
513 | #define AR_D9_RETRY_LIMIT 0x10a4 | ||
514 | #define AR_DRETRY_LIMIT(_i) (AR_D0_RETRY_LIMIT + ((_i)<<2)) | ||
515 | #define AR_D_RETRY_LIMIT_FR_SH 0x0000000F | ||
516 | #define AR_D_RETRY_LIMIT_FR_SH_S 0 | ||
517 | #define AR_D_RETRY_LIMIT_STA_SH 0x00003F00 | ||
518 | #define AR_D_RETRY_LIMIT_STA_SH_S 8 | ||
519 | #define AR_D_RETRY_LIMIT_STA_LG 0x000FC000 | ||
520 | #define AR_D_RETRY_LIMIT_STA_LG_S 14 | ||
521 | #define AR_D_RETRY_LIMIT_RESV0 0xFFF00000 | ||
522 | |||
523 | #define AR_D0_CHNTIME 0x10c0 | ||
524 | #define AR_D1_CHNTIME 0x10c4 | ||
525 | #define AR_D2_CHNTIME 0x10c8 | ||
526 | #define AR_D3_CHNTIME 0x10cc | ||
527 | #define AR_D4_CHNTIME 0x10d0 | ||
528 | #define AR_D5_CHNTIME 0x10d4 | ||
529 | #define AR_D6_CHNTIME 0x10d8 | ||
530 | #define AR_D7_CHNTIME 0x10dc | ||
531 | #define AR_D8_CHNTIME 0x10e0 | ||
532 | #define AR_D9_CHNTIME 0x10e4 | ||
533 | #define AR_DCHNTIME(_i) (AR_D0_CHNTIME + ((_i)<<2)) | ||
534 | #define AR_D_CHNTIME_DUR 0x000FFFFF | ||
535 | #define AR_D_CHNTIME_DUR_S 0 | ||
536 | #define AR_D_CHNTIME_EN 0x00100000 | ||
537 | #define AR_D_CHNTIME_RESV0 0xFFE00000 | ||
538 | |||
539 | #define AR_D0_MISC 0x1100 | ||
540 | #define AR_D1_MISC 0x1104 | ||
541 | #define AR_D2_MISC 0x1108 | ||
542 | #define AR_D3_MISC 0x110c | ||
543 | #define AR_D4_MISC 0x1110 | ||
544 | #define AR_D5_MISC 0x1114 | ||
545 | #define AR_D6_MISC 0x1118 | ||
546 | #define AR_D7_MISC 0x111c | ||
547 | #define AR_D8_MISC 0x1120 | ||
548 | #define AR_D9_MISC 0x1124 | ||
549 | #define AR_DMISC(_i) (AR_D0_MISC + ((_i)<<2)) | ||
550 | #define AR_D_MISC_BKOFF_THRESH 0x0000003F | ||
551 | #define AR_D_MISC_RETRY_CNT_RESET_EN 0x00000040 | ||
552 | #define AR_D_MISC_CW_RESET_EN 0x00000080 | ||
553 | #define AR_D_MISC_FRAG_WAIT_EN 0x00000100 | ||
554 | #define AR_D_MISC_FRAG_BKOFF_EN 0x00000200 | ||
555 | #define AR_D_MISC_CW_BKOFF_EN 0x00001000 | ||
556 | #define AR_D_MISC_VIR_COL_HANDLING 0x0000C000 | ||
557 | #define AR_D_MISC_VIR_COL_HANDLING_S 14 | ||
558 | #define AR_D_MISC_VIR_COL_HANDLING_DEFAULT 0 | ||
559 | #define AR_D_MISC_VIR_COL_HANDLING_IGNORE 1 | ||
560 | #define AR_D_MISC_BEACON_USE 0x00010000 | ||
561 | #define AR_D_MISC_ARB_LOCKOUT_CNTRL 0x00060000 | ||
562 | #define AR_D_MISC_ARB_LOCKOUT_CNTRL_S 17 | ||
563 | #define AR_D_MISC_ARB_LOCKOUT_CNTRL_NONE 0 | ||
564 | #define AR_D_MISC_ARB_LOCKOUT_CNTRL_INTRA_FR 1 | ||
565 | #define AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL 2 | ||
566 | #define AR_D_MISC_ARB_LOCKOUT_IGNORE 0x00080000 | ||
567 | #define AR_D_MISC_SEQ_NUM_INCR_DIS 0x00100000 | ||
568 | #define AR_D_MISC_POST_FR_BKOFF_DIS 0x00200000 | ||
569 | #define AR_D_MISC_VIT_COL_CW_BKOFF_EN 0x00400000 | ||
570 | #define AR_D_MISC_BLOWN_IFS_RETRY_EN 0x00800000 | ||
571 | #define AR_D_MISC_RESV0 0xFF000000 | ||
572 | |||
573 | #define AR_D_SEQNUM 0x1140 | ||
574 | |||
575 | #define AR_D_GBL_IFS_SIFS 0x1030 | ||
576 | #define AR_D_GBL_IFS_SIFS_M 0x0000FFFF | ||
577 | #define AR_D_GBL_IFS_SIFS_RESV0 0xFFFFFFFF | ||
578 | |||
579 | #define AR_D_TXBLK_BASE 0x1038 | ||
580 | #define AR_D_TXBLK_WRITE_BITMASK 0x0000FFFF | ||
581 | #define AR_D_TXBLK_WRITE_BITMASK_S 0 | ||
582 | #define AR_D_TXBLK_WRITE_SLICE 0x000F0000 | ||
583 | #define AR_D_TXBLK_WRITE_SLICE_S 16 | ||
584 | #define AR_D_TXBLK_WRITE_DCU 0x00F00000 | ||
585 | #define AR_D_TXBLK_WRITE_DCU_S 20 | ||
586 | #define AR_D_TXBLK_WRITE_COMMAND 0x0F000000 | ||
587 | #define AR_D_TXBLK_WRITE_COMMAND_S 24 | ||
588 | |||
589 | #define AR_D_GBL_IFS_SLOT 0x1070 | ||
590 | #define AR_D_GBL_IFS_SLOT_M 0x0000FFFF | ||
591 | #define AR_D_GBL_IFS_SLOT_RESV0 0xFFFF0000 | ||
592 | |||
593 | #define AR_D_GBL_IFS_EIFS 0x10b0 | ||
594 | #define AR_D_GBL_IFS_EIFS_M 0x0000FFFF | ||
595 | #define AR_D_GBL_IFS_EIFS_RESV0 0xFFFF0000 | ||
596 | |||
597 | #define AR_D_GBL_IFS_MISC 0x10f0 | ||
598 | #define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL 0x00000007 | ||
599 | #define AR_D_GBL_IFS_MISC_TURBO_MODE 0x00000008 | ||
600 | #define AR_D_GBL_IFS_MISC_USEC_DURATION 0x000FFC00 | ||
601 | #define AR_D_GBL_IFS_MISC_DCU_ARBITER_DLY 0x00300000 | ||
602 | #define AR_D_GBL_IFS_MISC_RANDOM_LFSR_SLICE_DIS 0x01000000 | ||
603 | #define AR_D_GBL_IFS_MISC_SLOT_XMIT_WIND_LEN 0x06000000 | ||
604 | #define AR_D_GBL_IFS_MISC_FORCE_XMIT_SLOT_BOUND 0x08000000 | ||
605 | #define AR_D_GBL_IFS_MISC_IGNORE_BACKOFF 0x10000000 | ||
606 | |||
607 | #define AR_D_FPCTL 0x1230 | ||
608 | #define AR_D_FPCTL_DCU 0x0000000F | ||
609 | #define AR_D_FPCTL_DCU_S 0 | ||
610 | #define AR_D_FPCTL_PREFETCH_EN 0x00000010 | ||
611 | #define AR_D_FPCTL_BURST_PREFETCH 0x00007FE0 | ||
612 | #define AR_D_FPCTL_BURST_PREFETCH_S 5 | ||
613 | |||
614 | #define AR_D_TXPSE 0x1270 | ||
615 | #define AR_D_TXPSE_CTRL 0x000003FF | ||
616 | #define AR_D_TXPSE_RESV0 0x0000FC00 | ||
617 | #define AR_D_TXPSE_STATUS 0x00010000 | ||
618 | #define AR_D_TXPSE_RESV1 0xFFFE0000 | ||
619 | |||
620 | #define AR_D_TXSLOTMASK 0x12f0 | ||
621 | #define AR_D_TXSLOTMASK_NUM 0x0000000F | ||
622 | |||
623 | #define AR_CFG_LED 0x1f04 | ||
624 | #define AR_CFG_SCLK_RATE_IND 0x00000003 | ||
625 | #define AR_CFG_SCLK_RATE_IND_S 0 | ||
626 | #define AR_CFG_SCLK_32MHZ 0x00000000 | ||
627 | #define AR_CFG_SCLK_4MHZ 0x00000001 | ||
628 | #define AR_CFG_SCLK_1MHZ 0x00000002 | ||
629 | #define AR_CFG_SCLK_32KHZ 0x00000003 | ||
630 | #define AR_CFG_LED_BLINK_SLOW 0x00000008 | ||
631 | #define AR_CFG_LED_BLINK_THRESH_SEL 0x00000070 | ||
632 | #define AR_CFG_LED_MODE_SEL 0x00000380 | ||
633 | #define AR_CFG_LED_MODE_SEL_S 7 | ||
634 | #define AR_CFG_LED_POWER 0x00000280 | ||
635 | #define AR_CFG_LED_POWER_S 7 | ||
636 | #define AR_CFG_LED_NETWORK 0x00000300 | ||
637 | #define AR_CFG_LED_NETWORK_S 7 | ||
638 | #define AR_CFG_LED_MODE_PROP 0x0 | ||
639 | #define AR_CFG_LED_MODE_RPROP 0x1 | ||
640 | #define AR_CFG_LED_MODE_SPLIT 0x2 | ||
641 | #define AR_CFG_LED_MODE_RAND 0x3 | ||
642 | #define AR_CFG_LED_MODE_POWER_OFF 0x4 | ||
643 | #define AR_CFG_LED_MODE_POWER_ON 0x5 | ||
644 | #define AR_CFG_LED_MODE_NETWORK_OFF 0x4 | ||
645 | #define AR_CFG_LED_MODE_NETWORK_ON 0x6 | ||
646 | #define AR_CFG_LED_ASSOC_CTL 0x00000c00 | ||
647 | #define AR_CFG_LED_ASSOC_CTL_S 10 | ||
648 | #define AR_CFG_LED_ASSOC_NONE 0x0 | ||
649 | #define AR_CFG_LED_ASSOC_ACTIVE 0x1 | ||
650 | #define AR_CFG_LED_ASSOC_PENDING 0x2 | ||
651 | |||
652 | #define AR_CFG_LED_BLINK_SLOW 0x00000008 | ||
653 | #define AR_CFG_LED_BLINK_SLOW_S 3 | ||
654 | |||
655 | #define AR_CFG_LED_BLINK_THRESH_SEL 0x00000070 | ||
656 | #define AR_CFG_LED_BLINK_THRESH_SEL_S 4 | ||
657 | |||
658 | #define AR_MAC_SLEEP 0x1f00 | ||
659 | #define AR_MAC_SLEEP_MAC_AWAKE 0x00000000 | ||
660 | #define AR_MAC_SLEEP_MAC_ASLEEP 0x00000001 | ||
661 | |||
662 | #define AR_RC 0x4000 | ||
663 | #define AR_RC_AHB 0x00000001 | ||
664 | #define AR_RC_APB 0x00000002 | ||
665 | #define AR_RC_HOSTIF 0x00000100 | ||
666 | |||
667 | #define AR_WA 0x4004 | ||
668 | #define AR9285_WA_DEFAULT 0x004a05cb | ||
669 | #define AR9280_WA_DEFAULT 0x0040073f | ||
670 | #define AR_WA_DEFAULT 0x0000073f | ||
671 | |||
672 | |||
673 | #define AR_PM_STATE 0x4008 | ||
674 | #define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000 | ||
675 | |||
676 | #define AR_HOST_TIMEOUT 0x4018 | ||
677 | #define AR_HOST_TIMEOUT_APB_CNTR 0x0000FFFF | ||
678 | #define AR_HOST_TIMEOUT_APB_CNTR_S 0 | ||
679 | #define AR_HOST_TIMEOUT_LCL_CNTR 0xFFFF0000 | ||
680 | #define AR_HOST_TIMEOUT_LCL_CNTR_S 16 | ||
681 | |||
682 | #define AR_EEPROM 0x401c | ||
683 | #define AR_EEPROM_ABSENT 0x00000100 | ||
684 | #define AR_EEPROM_CORRUPT 0x00000200 | ||
685 | #define AR_EEPROM_PROT_MASK 0x03FFFC00 | ||
686 | #define AR_EEPROM_PROT_MASK_S 10 | ||
687 | |||
688 | #define EEPROM_PROTECT_RP_0_31 0x0001 | ||
689 | #define EEPROM_PROTECT_WP_0_31 0x0002 | ||
690 | #define EEPROM_PROTECT_RP_32_63 0x0004 | ||
691 | #define EEPROM_PROTECT_WP_32_63 0x0008 | ||
692 | #define EEPROM_PROTECT_RP_64_127 0x0010 | ||
693 | #define EEPROM_PROTECT_WP_64_127 0x0020 | ||
694 | #define EEPROM_PROTECT_RP_128_191 0x0040 | ||
695 | #define EEPROM_PROTECT_WP_128_191 0x0080 | ||
696 | #define EEPROM_PROTECT_RP_192_255 0x0100 | ||
697 | #define EEPROM_PROTECT_WP_192_255 0x0200 | ||
698 | #define EEPROM_PROTECT_RP_256_511 0x0400 | ||
699 | #define EEPROM_PROTECT_WP_256_511 0x0800 | ||
700 | #define EEPROM_PROTECT_RP_512_1023 0x1000 | ||
701 | #define EEPROM_PROTECT_WP_512_1023 0x2000 | ||
702 | #define EEPROM_PROTECT_RP_1024_2047 0x4000 | ||
703 | #define EEPROM_PROTECT_WP_1024_2047 0x8000 | ||
704 | |||
705 | #define AR_SREV \ | ||
706 | ((AR_SREV_9100(ah)) ? 0x0600 : 0x4020) | ||
707 | |||
708 | #define AR_SREV_ID \ | ||
709 | ((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF) | ||
710 | #define AR_SREV_VERSION 0x000000F0 | ||
711 | #define AR_SREV_VERSION_S 4 | ||
712 | #define AR_SREV_REVISION 0x00000007 | ||
713 | |||
714 | #define AR_SREV_ID2 0xFFFFFFFF | ||
715 | #define AR_SREV_VERSION2 0xFFFC0000 | ||
716 | #define AR_SREV_VERSION2_S 18 | ||
717 | #define AR_SREV_TYPE2 0x0003F000 | ||
718 | #define AR_SREV_TYPE2_S 12 | ||
719 | #define AR_SREV_TYPE2_CHAIN 0x00001000 | ||
720 | #define AR_SREV_TYPE2_HOST_MODE 0x00002000 | ||
721 | #define AR_SREV_REVISION2 0x00000F00 | ||
722 | #define AR_SREV_REVISION2_S 8 | ||
723 | |||
724 | #define AR_SREV_VERSION_5416_PCI 0xD | ||
725 | #define AR_SREV_VERSION_5416_PCIE 0xC | ||
726 | #define AR_SREV_REVISION_5416_10 0 | ||
727 | #define AR_SREV_REVISION_5416_20 1 | ||
728 | #define AR_SREV_REVISION_5416_22 2 | ||
729 | #define AR_SREV_VERSION_9100 0x14 | ||
730 | #define AR_SREV_VERSION_9160 0x40 | ||
731 | #define AR_SREV_REVISION_9160_10 0 | ||
732 | #define AR_SREV_REVISION_9160_11 1 | ||
733 | #define AR_SREV_VERSION_9280 0x80 | ||
734 | #define AR_SREV_REVISION_9280_10 0 | ||
735 | #define AR_SREV_REVISION_9280_20 1 | ||
736 | #define AR_SREV_REVISION_9280_21 2 | ||
737 | #define AR_SREV_VERSION_9285 0xC0 | ||
738 | #define AR_SREV_REVISION_9285_10 0 | ||
739 | #define AR_SREV_REVISION_9285_11 1 | ||
740 | #define AR_SREV_REVISION_9285_12 2 | ||
741 | |||
742 | #define AR_SREV_5416(_ah) \ | ||
743 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ | ||
744 | ((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)) | ||
745 | #define AR_SREV_5416_20_OR_LATER(_ah) \ | ||
746 | (((AR_SREV_5416(_ah)) && \ | ||
747 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20)) || \ | ||
748 | ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100)) | ||
749 | #define AR_SREV_5416_22_OR_LATER(_ah) \ | ||
750 | (((AR_SREV_5416(_ah)) && \ | ||
751 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22)) || \ | ||
752 | ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100)) | ||
753 | |||
754 | #define AR_SREV_9100(ah) \ | ||
755 | ((ah->hw_version.macVersion) == AR_SREV_VERSION_9100) | ||
756 | #define AR_SREV_9100_OR_LATER(_ah) \ | ||
757 | (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100)) | ||
758 | |||
759 | #define AR_SREV_9160(_ah) \ | ||
760 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9160)) | ||
761 | #define AR_SREV_9160_10_OR_LATER(_ah) \ | ||
762 | (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9160)) | ||
763 | #define AR_SREV_9160_11(_ah) \ | ||
764 | (AR_SREV_9160(_ah) && \ | ||
765 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9160_11)) | ||
766 | #define AR_SREV_9280(_ah) \ | ||
767 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280)) | ||
768 | #define AR_SREV_9280_10_OR_LATER(_ah) \ | ||
769 | (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9280)) | ||
770 | #define AR_SREV_9280_20(_ah) \ | ||
771 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \ | ||
772 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20)) | ||
773 | #define AR_SREV_9280_20_OR_LATER(_ah) \ | ||
774 | (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9280) || \ | ||
775 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \ | ||
776 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20))) | ||
777 | |||
778 | #define AR_SREV_9285(_ah) \ | ||
779 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9285)) | ||
780 | #define AR_SREV_9285_10_OR_LATER(_ah) \ | ||
781 | (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285)) | ||
782 | #define AR_SREV_9285_11(_ah) \ | ||
783 | (AR_SREV_9285(ah) && \ | ||
784 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_11)) | ||
785 | #define AR_SREV_9285_11_OR_LATER(_ah) \ | ||
786 | (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \ | ||
787 | (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \ | ||
788 | AR_SREV_REVISION_9285_11))) | ||
789 | #define AR_SREV_9285_12(_ah) \ | ||
790 | (AR_SREV_9285(ah) && \ | ||
791 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_12)) | ||
792 | #define AR_SREV_9285_12_OR_LATER(_ah) \ | ||
793 | (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \ | ||
794 | (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \ | ||
795 | AR_SREV_REVISION_9285_12))) | ||
796 | |||
797 | #define AR_RADIO_SREV_MAJOR 0xf0 | ||
798 | #define AR_RAD5133_SREV_MAJOR 0xc0 | ||
799 | #define AR_RAD2133_SREV_MAJOR 0xd0 | ||
800 | #define AR_RAD5122_SREV_MAJOR 0xe0 | ||
801 | #define AR_RAD2122_SREV_MAJOR 0xf0 | ||
802 | |||
803 | #define AR_AHB_MODE 0x4024 | ||
804 | #define AR_AHB_EXACT_WR_EN 0x00000000 | ||
805 | #define AR_AHB_BUF_WR_EN 0x00000001 | ||
806 | #define AR_AHB_EXACT_RD_EN 0x00000000 | ||
807 | #define AR_AHB_CACHELINE_RD_EN 0x00000002 | ||
808 | #define AR_AHB_PREFETCH_RD_EN 0x00000004 | ||
809 | #define AR_AHB_PAGE_SIZE_1K 0x00000000 | ||
810 | #define AR_AHB_PAGE_SIZE_2K 0x00000008 | ||
811 | #define AR_AHB_PAGE_SIZE_4K 0x00000010 | ||
812 | |||
813 | #define AR_INTR_RTC_IRQ 0x00000001 | ||
814 | #define AR_INTR_MAC_IRQ 0x00000002 | ||
815 | #define AR_INTR_EEP_PROT_ACCESS 0x00000004 | ||
816 | #define AR_INTR_MAC_AWAKE 0x00020000 | ||
817 | #define AR_INTR_MAC_ASLEEP 0x00040000 | ||
818 | #define AR_INTR_SPURIOUS 0xFFFFFFFF | ||
819 | |||
820 | |||
821 | #define AR_INTR_SYNC_CAUSE_CLR 0x4028 | ||
822 | |||
823 | #define AR_INTR_SYNC_CAUSE 0x4028 | ||
824 | |||
825 | #define AR_INTR_SYNC_ENABLE 0x402c | ||
826 | #define AR_INTR_SYNC_ENABLE_GPIO 0xFFFC0000 | ||
827 | #define AR_INTR_SYNC_ENABLE_GPIO_S 18 | ||
828 | |||
829 | enum { | ||
830 | AR_INTR_SYNC_RTC_IRQ = 0x00000001, | ||
831 | AR_INTR_SYNC_MAC_IRQ = 0x00000002, | ||
832 | AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS = 0x00000004, | ||
833 | AR_INTR_SYNC_APB_TIMEOUT = 0x00000008, | ||
834 | AR_INTR_SYNC_PCI_MODE_CONFLICT = 0x00000010, | ||
835 | AR_INTR_SYNC_HOST1_FATAL = 0x00000020, | ||
836 | AR_INTR_SYNC_HOST1_PERR = 0x00000040, | ||
837 | AR_INTR_SYNC_TRCV_FIFO_PERR = 0x00000080, | ||
838 | AR_INTR_SYNC_RADM_CPL_EP = 0x00000100, | ||
839 | AR_INTR_SYNC_RADM_CPL_DLLP_ABORT = 0x00000200, | ||
840 | AR_INTR_SYNC_RADM_CPL_TLP_ABORT = 0x00000400, | ||
841 | AR_INTR_SYNC_RADM_CPL_ECRC_ERR = 0x00000800, | ||
842 | AR_INTR_SYNC_RADM_CPL_TIMEOUT = 0x00001000, | ||
843 | AR_INTR_SYNC_LOCAL_TIMEOUT = 0x00002000, | ||
844 | AR_INTR_SYNC_PM_ACCESS = 0x00004000, | ||
845 | AR_INTR_SYNC_MAC_AWAKE = 0x00008000, | ||
846 | AR_INTR_SYNC_MAC_ASLEEP = 0x00010000, | ||
847 | AR_INTR_SYNC_MAC_SLEEP_ACCESS = 0x00020000, | ||
848 | AR_INTR_SYNC_ALL = 0x0003FFFF, | ||
849 | |||
850 | |||
851 | AR_INTR_SYNC_DEFAULT = (AR_INTR_SYNC_HOST1_FATAL | | ||
852 | AR_INTR_SYNC_HOST1_PERR | | ||
853 | AR_INTR_SYNC_RADM_CPL_EP | | ||
854 | AR_INTR_SYNC_RADM_CPL_DLLP_ABORT | | ||
855 | AR_INTR_SYNC_RADM_CPL_TLP_ABORT | | ||
856 | AR_INTR_SYNC_RADM_CPL_ECRC_ERR | | ||
857 | AR_INTR_SYNC_RADM_CPL_TIMEOUT | | ||
858 | AR_INTR_SYNC_LOCAL_TIMEOUT | | ||
859 | AR_INTR_SYNC_MAC_SLEEP_ACCESS), | ||
860 | |||
861 | AR_INTR_SYNC_SPURIOUS = 0xFFFFFFFF, | ||
862 | |||
863 | }; | ||
864 | |||
865 | #define AR_INTR_ASYNC_MASK 0x4030 | ||
866 | #define AR_INTR_ASYNC_MASK_GPIO 0xFFFC0000 | ||
867 | #define AR_INTR_ASYNC_MASK_GPIO_S 18 | ||
868 | |||
869 | #define AR_INTR_SYNC_MASK 0x4034 | ||
870 | #define AR_INTR_SYNC_MASK_GPIO 0xFFFC0000 | ||
871 | #define AR_INTR_SYNC_MASK_GPIO_S 18 | ||
872 | |||
873 | #define AR_INTR_ASYNC_CAUSE_CLR 0x4038 | ||
874 | #define AR_INTR_ASYNC_CAUSE 0x4038 | ||
875 | |||
876 | #define AR_INTR_ASYNC_ENABLE 0x403c | ||
877 | #define AR_INTR_ASYNC_ENABLE_GPIO 0xFFFC0000 | ||
878 | #define AR_INTR_ASYNC_ENABLE_GPIO_S 18 | ||
879 | |||
880 | #define AR_PCIE_SERDES 0x4040 | ||
881 | #define AR_PCIE_SERDES2 0x4044 | ||
882 | #define AR_PCIE_PM_CTRL 0x4014 | ||
883 | #define AR_PCIE_PM_CTRL_ENA 0x00080000 | ||
884 | |||
885 | #define AR_NUM_GPIO 14 | ||
886 | #define AR928X_NUM_GPIO 10 | ||
887 | #define AR9285_NUM_GPIO 12 | ||
888 | |||
889 | #define AR_GPIO_IN_OUT 0x4048 | ||
890 | #define AR_GPIO_IN_VAL 0x0FFFC000 | ||
891 | #define AR_GPIO_IN_VAL_S 14 | ||
892 | #define AR928X_GPIO_IN_VAL 0x000FFC00 | ||
893 | #define AR928X_GPIO_IN_VAL_S 10 | ||
894 | #define AR9285_GPIO_IN_VAL 0x00FFF000 | ||
895 | #define AR9285_GPIO_IN_VAL_S 12 | ||
896 | |||
897 | #define AR_GPIO_OE_OUT 0x404c | ||
898 | #define AR_GPIO_OE_OUT_DRV 0x3 | ||
899 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 | ||
900 | #define AR_GPIO_OE_OUT_DRV_LOW 0x1 | ||
901 | #define AR_GPIO_OE_OUT_DRV_HI 0x2 | ||
902 | #define AR_GPIO_OE_OUT_DRV_ALL 0x3 | ||
903 | |||
904 | #define AR_GPIO_INTR_POL 0x4050 | ||
905 | #define AR_GPIO_INTR_POL_VAL 0x00001FFF | ||
906 | #define AR_GPIO_INTR_POL_VAL_S 0 | ||
907 | |||
908 | #define AR_GPIO_INPUT_EN_VAL 0x4054 | ||
909 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004 | ||
910 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2 | ||
911 | #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008 | ||
912 | #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_S 3 | ||
913 | #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_DEF 0x00000010 | ||
914 | #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_S 4 | ||
915 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF 0x00000080 | ||
916 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S 7 | ||
917 | #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB 0x00001000 | ||
918 | #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S 12 | ||
919 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB 0x00008000 | ||
920 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S 15 | ||
921 | #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000 | ||
922 | #define AR_GPIO_JTAG_DISABLE 0x00020000 | ||
923 | |||
924 | #define AR_GPIO_INPUT_MUX1 0x4058 | ||
925 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000 | ||
926 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16 | ||
927 | |||
928 | #define AR_GPIO_INPUT_MUX2 0x405c | ||
929 | #define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f | ||
930 | #define AR_GPIO_INPUT_MUX2_CLK25_S 0 | ||
931 | #define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0 | ||
932 | #define AR_GPIO_INPUT_MUX2_RFSILENT_S 4 | ||
933 | #define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00 | ||
934 | #define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8 | ||
935 | |||
936 | #define AR_GPIO_OUTPUT_MUX1 0x4060 | ||
937 | #define AR_GPIO_OUTPUT_MUX2 0x4064 | ||
938 | #define AR_GPIO_OUTPUT_MUX3 0x4068 | ||
939 | |||
940 | #define AR_INPUT_STATE 0x406c | ||
941 | |||
942 | #define AR_EEPROM_STATUS_DATA 0x407c | ||
943 | #define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff | ||
944 | #define AR_EEPROM_STATUS_DATA_VAL_S 0 | ||
945 | #define AR_EEPROM_STATUS_DATA_BUSY 0x00010000 | ||
946 | #define AR_EEPROM_STATUS_DATA_BUSY_ACCESS 0x00020000 | ||
947 | #define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000 | ||
948 | #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000 | ||
949 | |||
950 | #define AR_OBS 0x4080 | ||
951 | |||
952 | #define AR_PCIE_MSI 0x4094 | ||
953 | #define AR_PCIE_MSI_ENABLE 0x00000001 | ||
954 | |||
955 | |||
956 | #define AR_RTC_9160_PLL_DIV 0x000003ff | ||
957 | #define AR_RTC_9160_PLL_DIV_S 0 | ||
958 | #define AR_RTC_9160_PLL_REFDIV 0x00003C00 | ||
959 | #define AR_RTC_9160_PLL_REFDIV_S 10 | ||
960 | #define AR_RTC_9160_PLL_CLKSEL 0x0000C000 | ||
961 | #define AR_RTC_9160_PLL_CLKSEL_S 14 | ||
962 | |||
963 | #define AR_RTC_BASE 0x00020000 | ||
964 | #define AR_RTC_RC \ | ||
965 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000) | ||
966 | #define AR_RTC_RC_M 0x00000003 | ||
967 | #define AR_RTC_RC_MAC_WARM 0x00000001 | ||
968 | #define AR_RTC_RC_MAC_COLD 0x00000002 | ||
969 | #define AR_RTC_RC_COLD_RESET 0x00000004 | ||
970 | #define AR_RTC_RC_WARM_RESET 0x00000008 | ||
971 | |||
972 | #define AR_RTC_PLL_CONTROL \ | ||
973 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014) | ||
974 | |||
975 | #define AR_RTC_PLL_DIV 0x0000001f | ||
976 | #define AR_RTC_PLL_DIV_S 0 | ||
977 | #define AR_RTC_PLL_DIV2 0x00000020 | ||
978 | #define AR_RTC_PLL_REFDIV_5 0x000000c0 | ||
979 | #define AR_RTC_PLL_CLKSEL 0x00000300 | ||
980 | #define AR_RTC_PLL_CLKSEL_S 8 | ||
981 | |||
982 | #define AR_RTC_RESET \ | ||
983 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0040) : 0x7040) | ||
984 | #define AR_RTC_RESET_EN (0x00000001) | ||
985 | |||
986 | #define AR_RTC_STATUS \ | ||
987 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0044) : 0x7044) | ||
988 | |||
989 | #define AR_RTC_STATUS_M \ | ||
990 | ((AR_SREV_9100(ah)) ? 0x0000003f : 0x0000000f) | ||
991 | |||
992 | #define AR_RTC_PM_STATUS_M 0x0000000f | ||
993 | |||
994 | #define AR_RTC_STATUS_SHUTDOWN 0x00000001 | ||
995 | #define AR_RTC_STATUS_ON 0x00000002 | ||
996 | #define AR_RTC_STATUS_SLEEP 0x00000004 | ||
997 | #define AR_RTC_STATUS_WAKEUP 0x00000008 | ||
998 | |||
999 | #define AR_RTC_SLEEP_CLK \ | ||
1000 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048) | ||
1001 | #define AR_RTC_FORCE_DERIVED_CLK 0x2 | ||
1002 | |||
1003 | #define AR_RTC_FORCE_WAKE \ | ||
1004 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c) | ||
1005 | #define AR_RTC_FORCE_WAKE_EN 0x00000001 | ||
1006 | #define AR_RTC_FORCE_WAKE_ON_INT 0x00000002 | ||
1007 | |||
1008 | |||
1009 | #define AR_RTC_INTR_CAUSE \ | ||
1010 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0050) : 0x7050) | ||
1011 | |||
1012 | #define AR_RTC_INTR_ENABLE \ | ||
1013 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0054) : 0x7054) | ||
1014 | |||
1015 | #define AR_RTC_INTR_MASK \ | ||
1016 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0058) : 0x7058) | ||
1017 | |||
1018 | /* RTC_DERIVED_* - only for AR9100 */ | ||
1019 | |||
1020 | #define AR_RTC_DERIVED_CLK (AR_RTC_BASE + 0x0038) | ||
1021 | #define AR_RTC_DERIVED_CLK_PERIOD 0x0000fffe | ||
1022 | #define AR_RTC_DERIVED_CLK_PERIOD_S 1 | ||
1023 | |||
1024 | #define AR_SEQ_MASK 0x8060 | ||
1025 | |||
1026 | #define AR_AN_RF2G1_CH0 0x7810 | ||
1027 | #define AR_AN_RF2G1_CH0_OB 0x03800000 | ||
1028 | #define AR_AN_RF2G1_CH0_OB_S 23 | ||
1029 | #define AR_AN_RF2G1_CH0_DB 0x1C000000 | ||
1030 | #define AR_AN_RF2G1_CH0_DB_S 26 | ||
1031 | |||
1032 | #define AR_AN_RF5G1_CH0 0x7818 | ||
1033 | #define AR_AN_RF5G1_CH0_OB5 0x00070000 | ||
1034 | #define AR_AN_RF5G1_CH0_OB5_S 16 | ||
1035 | #define AR_AN_RF5G1_CH0_DB5 0x00380000 | ||
1036 | #define AR_AN_RF5G1_CH0_DB5_S 19 | ||
1037 | |||
1038 | #define AR_AN_RF2G1_CH1 0x7834 | ||
1039 | #define AR_AN_RF2G1_CH1_OB 0x03800000 | ||
1040 | #define AR_AN_RF2G1_CH1_OB_S 23 | ||
1041 | #define AR_AN_RF2G1_CH1_DB 0x1C000000 | ||
1042 | #define AR_AN_RF2G1_CH1_DB_S 26 | ||
1043 | |||
1044 | #define AR_AN_RF5G1_CH1 0x783C | ||
1045 | #define AR_AN_RF5G1_CH1_OB5 0x00070000 | ||
1046 | #define AR_AN_RF5G1_CH1_OB5_S 16 | ||
1047 | #define AR_AN_RF5G1_CH1_DB5 0x00380000 | ||
1048 | #define AR_AN_RF5G1_CH1_DB5_S 19 | ||
1049 | |||
1050 | #define AR_AN_TOP1 0x7890 | ||
1051 | #define AR_AN_TOP1_DACIPMODE 0x00040000 | ||
1052 | #define AR_AN_TOP1_DACIPMODE_S 18 | ||
1053 | |||
1054 | #define AR_AN_TOP2 0x7894 | ||
1055 | #define AR_AN_TOP2_XPABIAS_LVL 0xC0000000 | ||
1056 | #define AR_AN_TOP2_XPABIAS_LVL_S 30 | ||
1057 | #define AR_AN_TOP2_LOCALBIAS 0x00200000 | ||
1058 | #define AR_AN_TOP2_LOCALBIAS_S 21 | ||
1059 | #define AR_AN_TOP2_PWDCLKIND 0x00400000 | ||
1060 | #define AR_AN_TOP2_PWDCLKIND_S 22 | ||
1061 | |||
1062 | #define AR_AN_SYNTH9 0x7868 | ||
1063 | #define AR_AN_SYNTH9_REFDIVA 0xf8000000 | ||
1064 | #define AR_AN_SYNTH9_REFDIVA_S 27 | ||
1065 | |||
1066 | #define AR9285_AN_RF2G1 0x7820 | ||
1067 | #define AR9285_AN_RF2G1_ENPACAL 0x00000800 | ||
1068 | #define AR9285_AN_RF2G1_ENPACAL_S 11 | ||
1069 | #define AR9285_AN_RF2G1_PDPADRV1 0x02000000 | ||
1070 | #define AR9285_AN_RF2G1_PDPADRV1_S 25 | ||
1071 | #define AR9285_AN_RF2G1_PDPADRV2 0x01000000 | ||
1072 | #define AR9285_AN_RF2G1_PDPADRV2_S 24 | ||
1073 | #define AR9285_AN_RF2G1_PDPAOUT 0x00800000 | ||
1074 | #define AR9285_AN_RF2G1_PDPAOUT_S 23 | ||
1075 | |||
1076 | |||
1077 | #define AR9285_AN_RF2G2 0x7824 | ||
1078 | #define AR9285_AN_RF2G2_OFFCAL 0x00001000 | ||
1079 | #define AR9285_AN_RF2G2_OFFCAL_S 12 | ||
1080 | |||
1081 | #define AR9285_AN_RF2G3 0x7828 | ||
1082 | #define AR9285_AN_RF2G3_PDVCCOMP 0x02000000 | ||
1083 | #define AR9285_AN_RF2G3_PDVCCOMP_S 25 | ||
1084 | #define AR9285_AN_RF2G3_OB_0 0x00E00000 | ||
1085 | #define AR9285_AN_RF2G3_OB_0_S 21 | ||
1086 | #define AR9285_AN_RF2G3_OB_1 0x001C0000 | ||
1087 | #define AR9285_AN_RF2G3_OB_1_S 18 | ||
1088 | #define AR9285_AN_RF2G3_OB_2 0x00038000 | ||
1089 | #define AR9285_AN_RF2G3_OB_2_S 15 | ||
1090 | #define AR9285_AN_RF2G3_OB_3 0x00007000 | ||
1091 | #define AR9285_AN_RF2G3_OB_3_S 12 | ||
1092 | #define AR9285_AN_RF2G3_OB_4 0x00000E00 | ||
1093 | #define AR9285_AN_RF2G3_OB_4_S 9 | ||
1094 | |||
1095 | #define AR9285_AN_RF2G3_DB1_0 0x000001C0 | ||
1096 | #define AR9285_AN_RF2G3_DB1_0_S 6 | ||
1097 | #define AR9285_AN_RF2G3_DB1_1 0x00000038 | ||
1098 | #define AR9285_AN_RF2G3_DB1_1_S 3 | ||
1099 | #define AR9285_AN_RF2G3_DB1_2 0x00000007 | ||
1100 | #define AR9285_AN_RF2G3_DB1_2_S 0 | ||
1101 | #define AR9285_AN_RF2G4 0x782C | ||
1102 | #define AR9285_AN_RF2G4_DB1_3 0xE0000000 | ||
1103 | #define AR9285_AN_RF2G4_DB1_3_S 29 | ||
1104 | #define AR9285_AN_RF2G4_DB1_4 0x1C000000 | ||
1105 | #define AR9285_AN_RF2G4_DB1_4_S 26 | ||
1106 | |||
1107 | #define AR9285_AN_RF2G4_DB2_0 0x03800000 | ||
1108 | #define AR9285_AN_RF2G4_DB2_0_S 23 | ||
1109 | #define AR9285_AN_RF2G4_DB2_1 0x00700000 | ||
1110 | #define AR9285_AN_RF2G4_DB2_1_S 20 | ||
1111 | #define AR9285_AN_RF2G4_DB2_2 0x000E0000 | ||
1112 | #define AR9285_AN_RF2G4_DB2_2_S 17 | ||
1113 | #define AR9285_AN_RF2G4_DB2_3 0x0001C000 | ||
1114 | #define AR9285_AN_RF2G4_DB2_3_S 14 | ||
1115 | #define AR9285_AN_RF2G4_DB2_4 0x00003800 | ||
1116 | #define AR9285_AN_RF2G4_DB2_4_S 11 | ||
1117 | |||
1118 | #define AR9285_AN_RF2G6 0x7834 | ||
1119 | #define AR9285_AN_RF2G6_CCOMP 0x00007800 | ||
1120 | #define AR9285_AN_RF2G6_CCOMP_S 11 | ||
1121 | #define AR9285_AN_RF2G6_OFFS 0x03f00000 | ||
1122 | #define AR9285_AN_RF2G6_OFFS_S 20 | ||
1123 | |||
1124 | #define AR9285_AN_RF2G7 0x7838 | ||
1125 | #define AR9285_AN_RF2G7_PWDDB 0x00000002 | ||
1126 | #define AR9285_AN_RF2G7_PWDDB_S 1 | ||
1127 | #define AR9285_AN_RF2G7_PADRVGN2TAB0 0xE0000000 | ||
1128 | #define AR9285_AN_RF2G7_PADRVGN2TAB0_S 29 | ||
1129 | |||
1130 | #define AR9285_AN_RF2G8 0x783C | ||
1131 | #define AR9285_AN_RF2G8_PADRVGN2TAB0 0x0001C000 | ||
1132 | #define AR9285_AN_RF2G8_PADRVGN2TAB0_S 14 | ||
1133 | |||
1134 | |||
1135 | #define AR9285_AN_RF2G9 0x7840 | ||
1136 | #define AR9285_AN_RXTXBB1 0x7854 | ||
1137 | #define AR9285_AN_RXTXBB1_PDRXTXBB1 0x00000020 | ||
1138 | #define AR9285_AN_RXTXBB1_PDRXTXBB1_S 5 | ||
1139 | #define AR9285_AN_RXTXBB1_PDV2I 0x00000080 | ||
1140 | #define AR9285_AN_RXTXBB1_PDV2I_S 7 | ||
1141 | #define AR9285_AN_RXTXBB1_PDDACIF 0x00000100 | ||
1142 | #define AR9285_AN_RXTXBB1_PDDACIF_S 8 | ||
1143 | #define AR9285_AN_RXTXBB1_SPARE9 0x00000001 | ||
1144 | #define AR9285_AN_RXTXBB1_SPARE9_S 0 | ||
1145 | |||
1146 | #define AR9285_AN_TOP2 0x7868 | ||
1147 | |||
1148 | #define AR9285_AN_TOP3 0x786c | ||
1149 | #define AR9285_AN_TOP3_XPABIAS_LVL 0x0000000C | ||
1150 | #define AR9285_AN_TOP3_XPABIAS_LVL_S 2 | ||
1151 | #define AR9285_AN_TOP3_PWDDAC 0x00800000 | ||
1152 | #define AR9285_AN_TOP3_PWDDAC_S 23 | ||
1153 | |||
1154 | #define AR9285_AN_TOP4 0x7870 | ||
1155 | #define AR9285_AN_TOP4_DEFAULT 0x10142c00 | ||
1156 | |||
1157 | #define AR_STA_ID0 0x8000 | ||
1158 | #define AR_STA_ID1 0x8004 | ||
1159 | #define AR_STA_ID1_SADH_MASK 0x0000FFFF | ||
1160 | #define AR_STA_ID1_STA_AP 0x00010000 | ||
1161 | #define AR_STA_ID1_ADHOC 0x00020000 | ||
1162 | #define AR_STA_ID1_PWR_SAV 0x00040000 | ||
1163 | #define AR_STA_ID1_KSRCHDIS 0x00080000 | ||
1164 | #define AR_STA_ID1_PCF 0x00100000 | ||
1165 | #define AR_STA_ID1_USE_DEFANT 0x00200000 | ||
1166 | #define AR_STA_ID1_DEFANT_UPDATE 0x00400000 | ||
1167 | #define AR_STA_ID1_RTS_USE_DEF 0x00800000 | ||
1168 | #define AR_STA_ID1_ACKCTS_6MB 0x01000000 | ||
1169 | #define AR_STA_ID1_BASE_RATE_11B 0x02000000 | ||
1170 | #define AR_STA_ID1_SECTOR_SELF_GEN 0x04000000 | ||
1171 | #define AR_STA_ID1_CRPT_MIC_ENABLE 0x08000000 | ||
1172 | #define AR_STA_ID1_KSRCH_MODE 0x10000000 | ||
1173 | #define AR_STA_ID1_PRESERVE_SEQNUM 0x20000000 | ||
1174 | #define AR_STA_ID1_CBCIV_ENDIAN 0x40000000 | ||
1175 | #define AR_STA_ID1_MCAST_KSRCH 0x80000000 | ||
1176 | |||
1177 | #define AR_BSS_ID0 0x8008 | ||
1178 | #define AR_BSS_ID1 0x800C | ||
1179 | #define AR_BSS_ID1_U16 0x0000FFFF | ||
1180 | #define AR_BSS_ID1_AID 0x07FF0000 | ||
1181 | #define AR_BSS_ID1_AID_S 16 | ||
1182 | |||
1183 | #define AR_BCN_RSSI_AVE 0x8010 | ||
1184 | #define AR_BCN_RSSI_AVE_MASK 0x00000FFF | ||
1185 | |||
1186 | #define AR_TIME_OUT 0x8014 | ||
1187 | #define AR_TIME_OUT_ACK 0x00003FFF | ||
1188 | #define AR_TIME_OUT_ACK_S 0 | ||
1189 | #define AR_TIME_OUT_CTS 0x3FFF0000 | ||
1190 | #define AR_TIME_OUT_CTS_S 16 | ||
1191 | |||
1192 | #define AR_RSSI_THR 0x8018 | ||
1193 | #define AR_RSSI_THR_MASK 0x000000FF | ||
1194 | #define AR_RSSI_THR_BM_THR 0x0000FF00 | ||
1195 | #define AR_RSSI_THR_BM_THR_S 8 | ||
1196 | #define AR_RSSI_BCN_WEIGHT 0x1F000000 | ||
1197 | #define AR_RSSI_BCN_WEIGHT_S 24 | ||
1198 | #define AR_RSSI_BCN_RSSI_RST 0x20000000 | ||
1199 | |||
1200 | #define AR_USEC 0x801c | ||
1201 | #define AR_USEC_USEC 0x0000007F | ||
1202 | #define AR_USEC_TX_LAT 0x007FC000 | ||
1203 | #define AR_USEC_TX_LAT_S 14 | ||
1204 | #define AR_USEC_RX_LAT 0x1F800000 | ||
1205 | #define AR_USEC_RX_LAT_S 23 | ||
1206 | |||
1207 | #define AR_RESET_TSF 0x8020 | ||
1208 | #define AR_RESET_TSF_ONCE 0x01000000 | ||
1209 | |||
1210 | #define AR_MAX_CFP_DUR 0x8038 | ||
1211 | #define AR_CFP_VAL 0x0000FFFF | ||
1212 | |||
1213 | #define AR_RX_FILTER 0x803C | ||
1214 | #define AR_RX_COMPR_BAR 0x00000400 | ||
1215 | |||
1216 | #define AR_MCAST_FIL0 0x8040 | ||
1217 | #define AR_MCAST_FIL1 0x8044 | ||
1218 | |||
1219 | #define AR_DIAG_SW 0x8048 | ||
1220 | #define AR_DIAG_CACHE_ACK 0x00000001 | ||
1221 | #define AR_DIAG_ACK_DIS 0x00000002 | ||
1222 | #define AR_DIAG_CTS_DIS 0x00000004 | ||
1223 | #define AR_DIAG_ENCRYPT_DIS 0x00000008 | ||
1224 | #define AR_DIAG_DECRYPT_DIS 0x00000010 | ||
1225 | #define AR_DIAG_RX_DIS 0x00000020 | ||
1226 | #define AR_DIAG_LOOP_BACK 0x00000040 | ||
1227 | #define AR_DIAG_CORR_FCS 0x00000080 | ||
1228 | #define AR_DIAG_CHAN_INFO 0x00000100 | ||
1229 | #define AR_DIAG_SCRAM_SEED 0x0001FE00 | ||
1230 | #define AR_DIAG_SCRAM_SEED_S 8 | ||
1231 | #define AR_DIAG_FRAME_NV0 0x00020000 | ||
1232 | #define AR_DIAG_OBS_PT_SEL1 0x000C0000 | ||
1233 | #define AR_DIAG_OBS_PT_SEL1_S 18 | ||
1234 | #define AR_DIAG_FORCE_RX_CLEAR 0x00100000 | ||
1235 | #define AR_DIAG_IGNORE_VIRT_CS 0x00200000 | ||
1236 | #define AR_DIAG_FORCE_CH_IDLE_HIGH 0x00400000 | ||
1237 | #define AR_DIAG_EIFS_CTRL_ENA 0x00800000 | ||
1238 | #define AR_DIAG_DUAL_CHAIN_INFO 0x01000000 | ||
1239 | #define AR_DIAG_RX_ABORT 0x02000000 | ||
1240 | #define AR_DIAG_SATURATE_CYCLE_CNT 0x04000000 | ||
1241 | #define AR_DIAG_OBS_PT_SEL2 0x08000000 | ||
1242 | #define AR_DIAG_RX_CLEAR_CTL_LOW 0x10000000 | ||
1243 | #define AR_DIAG_RX_CLEAR_EXT_LOW 0x20000000 | ||
1244 | |||
1245 | #define AR_TSF_L32 0x804c | ||
1246 | #define AR_TSF_U32 0x8050 | ||
1247 | |||
1248 | #define AR_TST_ADDAC 0x8054 | ||
1249 | #define AR_DEF_ANTENNA 0x8058 | ||
1250 | |||
1251 | #define AR_AES_MUTE_MASK0 0x805c | ||
1252 | #define AR_AES_MUTE_MASK0_FC 0x0000FFFF | ||
1253 | #define AR_AES_MUTE_MASK0_QOS 0xFFFF0000 | ||
1254 | #define AR_AES_MUTE_MASK0_QOS_S 16 | ||
1255 | |||
1256 | #define AR_AES_MUTE_MASK1 0x8060 | ||
1257 | #define AR_AES_MUTE_MASK1_SEQ 0x0000FFFF | ||
1258 | #define AR_AES_MUTE_MASK1_FC_MGMT 0xFFFF0000 | ||
1259 | #define AR_AES_MUTE_MASK1_FC_MGMT_S 16 | ||
1260 | |||
1261 | #define AR_GATED_CLKS 0x8064 | ||
1262 | #define AR_GATED_CLKS_TX 0x00000002 | ||
1263 | #define AR_GATED_CLKS_RX 0x00000004 | ||
1264 | #define AR_GATED_CLKS_REG 0x00000008 | ||
1265 | |||
1266 | #define AR_OBS_BUS_CTRL 0x8068 | ||
1267 | #define AR_OBS_BUS_SEL_1 0x00040000 | ||
1268 | #define AR_OBS_BUS_SEL_2 0x00080000 | ||
1269 | #define AR_OBS_BUS_SEL_3 0x000C0000 | ||
1270 | #define AR_OBS_BUS_SEL_4 0x08040000 | ||
1271 | #define AR_OBS_BUS_SEL_5 0x08080000 | ||
1272 | |||
1273 | #define AR_OBS_BUS_1 0x806c | ||
1274 | #define AR_OBS_BUS_1_PCU 0x00000001 | ||
1275 | #define AR_OBS_BUS_1_RX_END 0x00000002 | ||
1276 | #define AR_OBS_BUS_1_RX_WEP 0x00000004 | ||
1277 | #define AR_OBS_BUS_1_RX_BEACON 0x00000008 | ||
1278 | #define AR_OBS_BUS_1_RX_FILTER 0x00000010 | ||
1279 | #define AR_OBS_BUS_1_TX_HCF 0x00000020 | ||
1280 | #define AR_OBS_BUS_1_QUIET_TIME 0x00000040 | ||
1281 | #define AR_OBS_BUS_1_CHAN_IDLE 0x00000080 | ||
1282 | #define AR_OBS_BUS_1_TX_HOLD 0x00000100 | ||
1283 | #define AR_OBS_BUS_1_TX_FRAME 0x00000200 | ||
1284 | #define AR_OBS_BUS_1_RX_FRAME 0x00000400 | ||
1285 | #define AR_OBS_BUS_1_RX_CLEAR 0x00000800 | ||
1286 | #define AR_OBS_BUS_1_WEP_STATE 0x0003F000 | ||
1287 | #define AR_OBS_BUS_1_WEP_STATE_S 12 | ||
1288 | #define AR_OBS_BUS_1_RX_STATE 0x01F00000 | ||
1289 | #define AR_OBS_BUS_1_RX_STATE_S 20 | ||
1290 | #define AR_OBS_BUS_1_TX_STATE 0x7E000000 | ||
1291 | #define AR_OBS_BUS_1_TX_STATE_S 25 | ||
1292 | |||
1293 | #define AR_LAST_TSTP 0x8080 | ||
1294 | #define AR_NAV 0x8084 | ||
1295 | #define AR_RTS_OK 0x8088 | ||
1296 | #define AR_RTS_FAIL 0x808c | ||
1297 | #define AR_ACK_FAIL 0x8090 | ||
1298 | #define AR_FCS_FAIL 0x8094 | ||
1299 | #define AR_BEACON_CNT 0x8098 | ||
1300 | |||
1301 | #define AR_SLEEP1 0x80d4 | ||
1302 | #define AR_SLEEP1_ASSUME_DTIM 0x00080000 | ||
1303 | #define AR_SLEEP1_CAB_TIMEOUT 0xFFE00000 | ||
1304 | #define AR_SLEEP1_CAB_TIMEOUT_S 21 | ||
1305 | |||
1306 | #define AR_SLEEP2 0x80d8 | ||
1307 | #define AR_SLEEP2_BEACON_TIMEOUT 0xFFE00000 | ||
1308 | #define AR_SLEEP2_BEACON_TIMEOUT_S 21 | ||
1309 | |||
1310 | #define AR_BSSMSKL 0x80e0 | ||
1311 | #define AR_BSSMSKU 0x80e4 | ||
1312 | |||
1313 | #define AR_TPC 0x80e8 | ||
1314 | #define AR_TPC_ACK 0x0000003f | ||
1315 | #define AR_TPC_ACK_S 0x00 | ||
1316 | #define AR_TPC_CTS 0x00003f00 | ||
1317 | #define AR_TPC_CTS_S 0x08 | ||
1318 | #define AR_TPC_CHIRP 0x003f0000 | ||
1319 | #define AR_TPC_CHIRP_S 0x16 | ||
1320 | |||
1321 | #define AR_TFCNT 0x80ec | ||
1322 | #define AR_RFCNT 0x80f0 | ||
1323 | #define AR_RCCNT 0x80f4 | ||
1324 | #define AR_CCCNT 0x80f8 | ||
1325 | |||
1326 | #define AR_QUIET1 0x80fc | ||
1327 | #define AR_QUIET1_NEXT_QUIET_S 0 | ||
1328 | #define AR_QUIET1_NEXT_QUIET_M 0x0000ffff | ||
1329 | #define AR_QUIET1_QUIET_ENABLE 0x00010000 | ||
1330 | #define AR_QUIET1_QUIET_ACK_CTS_ENABLE 0x00020000 | ||
1331 | #define AR_QUIET2 0x8100 | ||
1332 | #define AR_QUIET2_QUIET_PERIOD_S 0 | ||
1333 | #define AR_QUIET2_QUIET_PERIOD_M 0x0000ffff | ||
1334 | #define AR_QUIET2_QUIET_DUR_S 16 | ||
1335 | #define AR_QUIET2_QUIET_DUR 0xffff0000 | ||
1336 | |||
1337 | #define AR_TSF_PARM 0x8104 | ||
1338 | #define AR_TSF_INCREMENT_M 0x000000ff | ||
1339 | #define AR_TSF_INCREMENT_S 0x00 | ||
1340 | |||
1341 | #define AR_QOS_NO_ACK 0x8108 | ||
1342 | #define AR_QOS_NO_ACK_TWO_BIT 0x0000000f | ||
1343 | #define AR_QOS_NO_ACK_TWO_BIT_S 0 | ||
1344 | #define AR_QOS_NO_ACK_BIT_OFF 0x00000070 | ||
1345 | #define AR_QOS_NO_ACK_BIT_OFF_S 4 | ||
1346 | #define AR_QOS_NO_ACK_BYTE_OFF 0x00000180 | ||
1347 | #define AR_QOS_NO_ACK_BYTE_OFF_S 7 | ||
1348 | |||
1349 | #define AR_PHY_ERR 0x810c | ||
1350 | |||
1351 | #define AR_PHY_ERR_DCHIRP 0x00000008 | ||
1352 | #define AR_PHY_ERR_RADAR 0x00000020 | ||
1353 | #define AR_PHY_ERR_OFDM_TIMING 0x00020000 | ||
1354 | #define AR_PHY_ERR_CCK_TIMING 0x02000000 | ||
1355 | |||
1356 | #define AR_RXFIFO_CFG 0x8114 | ||
1357 | |||
1358 | |||
1359 | #define AR_MIC_QOS_CONTROL 0x8118 | ||
1360 | #define AR_MIC_QOS_SELECT 0x811c | ||
1361 | |||
1362 | #define AR_PCU_MISC 0x8120 | ||
1363 | #define AR_PCU_FORCE_BSSID_MATCH 0x00000001 | ||
1364 | #define AR_PCU_MIC_NEW_LOC_ENA 0x00000004 | ||
1365 | #define AR_PCU_TX_ADD_TSF 0x00000008 | ||
1366 | #define AR_PCU_CCK_SIFS_MODE 0x00000010 | ||
1367 | #define AR_PCU_RX_ANT_UPDT 0x00000800 | ||
1368 | #define AR_PCU_TXOP_TBTT_LIMIT_ENA 0x00001000 | ||
1369 | #define AR_PCU_MISS_BCN_IN_SLEEP 0x00004000 | ||
1370 | #define AR_PCU_BUG_12306_FIX_ENA 0x00020000 | ||
1371 | #define AR_PCU_FORCE_QUIET_COLL 0x00040000 | ||
1372 | #define AR_PCU_TBTT_PROTECT 0x00200000 | ||
1373 | #define AR_PCU_CLEAR_VMF 0x01000000 | ||
1374 | #define AR_PCU_CLEAR_BA_VALID 0x04000000 | ||
1375 | |||
1376 | |||
1377 | #define AR_FILT_OFDM 0x8124 | ||
1378 | #define AR_FILT_OFDM_COUNT 0x00FFFFFF | ||
1379 | |||
1380 | #define AR_FILT_CCK 0x8128 | ||
1381 | #define AR_FILT_CCK_COUNT 0x00FFFFFF | ||
1382 | |||
1383 | #define AR_PHY_ERR_1 0x812c | ||
1384 | #define AR_PHY_ERR_1_COUNT 0x00FFFFFF | ||
1385 | #define AR_PHY_ERR_MASK_1 0x8130 | ||
1386 | |||
1387 | #define AR_PHY_ERR_2 0x8134 | ||
1388 | #define AR_PHY_ERR_2_COUNT 0x00FFFFFF | ||
1389 | #define AR_PHY_ERR_MASK_2 0x8138 | ||
1390 | |||
1391 | #define AR_PHY_COUNTMAX (3 << 22) | ||
1392 | #define AR_MIBCNT_INTRMASK (3 << 22) | ||
1393 | |||
1394 | #define AR_TSFOOR_THRESHOLD 0x813c | ||
1395 | #define AR_TSFOOR_THRESHOLD_VAL 0x0000FFFF | ||
1396 | |||
1397 | #define AR_PHY_ERR_EIFS_MASK 8144 | ||
1398 | |||
1399 | #define AR_PHY_ERR_3 0x8168 | ||
1400 | #define AR_PHY_ERR_3_COUNT 0x00FFFFFF | ||
1401 | #define AR_PHY_ERR_MASK_3 0x816c | ||
1402 | |||
1403 | #define AR_TXSIFS 0x81d0 | ||
1404 | #define AR_TXSIFS_TIME 0x000000FF | ||
1405 | #define AR_TXSIFS_TX_LATENCY 0x00000F00 | ||
1406 | #define AR_TXSIFS_TX_LATENCY_S 8 | ||
1407 | #define AR_TXSIFS_ACK_SHIFT 0x00007000 | ||
1408 | #define AR_TXSIFS_ACK_SHIFT_S 12 | ||
1409 | |||
1410 | #define AR_TXOP_X 0x81ec | ||
1411 | #define AR_TXOP_X_VAL 0x000000FF | ||
1412 | |||
1413 | |||
1414 | #define AR_TXOP_0_3 0x81f0 | ||
1415 | #define AR_TXOP_4_7 0x81f4 | ||
1416 | #define AR_TXOP_8_11 0x81f8 | ||
1417 | #define AR_TXOP_12_15 0x81fc | ||
1418 | |||
1419 | |||
1420 | #define AR_NEXT_TBTT_TIMER 0x8200 | ||
1421 | #define AR_NEXT_DMA_BEACON_ALERT 0x8204 | ||
1422 | #define AR_NEXT_SWBA 0x8208 | ||
1423 | #define AR_NEXT_CFP 0x8208 | ||
1424 | #define AR_NEXT_HCF 0x820C | ||
1425 | #define AR_NEXT_TIM 0x8210 | ||
1426 | #define AR_NEXT_DTIM 0x8214 | ||
1427 | #define AR_NEXT_QUIET_TIMER 0x8218 | ||
1428 | #define AR_NEXT_NDP_TIMER 0x821C | ||
1429 | |||
1430 | #define AR_BEACON_PERIOD 0x8220 | ||
1431 | #define AR_DMA_BEACON_PERIOD 0x8224 | ||
1432 | #define AR_SWBA_PERIOD 0x8228 | ||
1433 | #define AR_HCF_PERIOD 0x822C | ||
1434 | #define AR_TIM_PERIOD 0x8230 | ||
1435 | #define AR_DTIM_PERIOD 0x8234 | ||
1436 | #define AR_QUIET_PERIOD 0x8238 | ||
1437 | #define AR_NDP_PERIOD 0x823C | ||
1438 | |||
1439 | #define AR_TIMER_MODE 0x8240 | ||
1440 | #define AR_TBTT_TIMER_EN 0x00000001 | ||
1441 | #define AR_DBA_TIMER_EN 0x00000002 | ||
1442 | #define AR_SWBA_TIMER_EN 0x00000004 | ||
1443 | #define AR_HCF_TIMER_EN 0x00000008 | ||
1444 | #define AR_TIM_TIMER_EN 0x00000010 | ||
1445 | #define AR_DTIM_TIMER_EN 0x00000020 | ||
1446 | #define AR_QUIET_TIMER_EN 0x00000040 | ||
1447 | #define AR_NDP_TIMER_EN 0x00000080 | ||
1448 | #define AR_TIMER_OVERFLOW_INDEX 0x00000700 | ||
1449 | #define AR_TIMER_OVERFLOW_INDEX_S 8 | ||
1450 | #define AR_TIMER_THRESH 0xFFFFF000 | ||
1451 | #define AR_TIMER_THRESH_S 12 | ||
1452 | |||
1453 | #define AR_SLP32_MODE 0x8244 | ||
1454 | #define AR_SLP32_HALF_CLK_LATENCY 0x000FFFFF | ||
1455 | #define AR_SLP32_ENA 0x00100000 | ||
1456 | #define AR_SLP32_TSF_WRITE_STATUS 0x00200000 | ||
1457 | |||
1458 | #define AR_SLP32_WAKE 0x8248 | ||
1459 | #define AR_SLP32_WAKE_XTL_TIME 0x0000FFFF | ||
1460 | |||
1461 | #define AR_SLP32_INC 0x824c | ||
1462 | #define AR_SLP32_TST_INC 0x000FFFFF | ||
1463 | |||
1464 | #define AR_SLP_CNT 0x8250 | ||
1465 | #define AR_SLP_CYCLE_CNT 0x8254 | ||
1466 | |||
1467 | #define AR_SLP_MIB_CTRL 0x8258 | ||
1468 | #define AR_SLP_MIB_CLEAR 0x00000001 | ||
1469 | #define AR_SLP_MIB_PENDING 0x00000002 | ||
1470 | |||
1471 | #define AR_2040_MODE 0x8318 | ||
1472 | #define AR_2040_JOINED_RX_CLEAR 0x00000001 | ||
1473 | |||
1474 | |||
1475 | #define AR_EXTRCCNT 0x8328 | ||
1476 | |||
1477 | #define AR_SELFGEN_MASK 0x832c | ||
1478 | |||
1479 | #define AR_PCU_TXBUF_CTRL 0x8340 | ||
1480 | #define AR_PCU_TXBUF_CTRL_SIZE_MASK 0x7FF | ||
1481 | #define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700 | ||
1482 | #define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380 | ||
1483 | |||
1484 | #define AR_PCU_MISC_MODE2 0x8344 | ||
1485 | #define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE 0x00000002 | ||
1486 | #define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT 0x00000004 | ||
1487 | |||
1488 | #define AR_KEYTABLE_0 0x8800 | ||
1489 | #define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32)) | ||
1490 | #define AR_KEY_CACHE_SIZE 128 | ||
1491 | #define AR_RSVD_KEYTABLE_ENTRIES 4 | ||
1492 | #define AR_KEY_TYPE 0x00000007 | ||
1493 | #define AR_KEYTABLE_TYPE_40 0x00000000 | ||
1494 | #define AR_KEYTABLE_TYPE_104 0x00000001 | ||
1495 | #define AR_KEYTABLE_TYPE_128 0x00000003 | ||
1496 | #define AR_KEYTABLE_TYPE_TKIP 0x00000004 | ||
1497 | #define AR_KEYTABLE_TYPE_AES 0x00000005 | ||
1498 | #define AR_KEYTABLE_TYPE_CCM 0x00000006 | ||
1499 | #define AR_KEYTABLE_TYPE_CLR 0x00000007 | ||
1500 | #define AR_KEYTABLE_ANT 0x00000008 | ||
1501 | #define AR_KEYTABLE_VALID 0x00008000 | ||
1502 | #define AR_KEYTABLE_KEY0(_n) (AR_KEYTABLE(_n) + 0) | ||
1503 | #define AR_KEYTABLE_KEY1(_n) (AR_KEYTABLE(_n) + 4) | ||
1504 | #define AR_KEYTABLE_KEY2(_n) (AR_KEYTABLE(_n) + 8) | ||
1505 | #define AR_KEYTABLE_KEY3(_n) (AR_KEYTABLE(_n) + 12) | ||
1506 | #define AR_KEYTABLE_KEY4(_n) (AR_KEYTABLE(_n) + 16) | ||
1507 | #define AR_KEYTABLE_TYPE(_n) (AR_KEYTABLE(_n) + 20) | ||
1508 | #define AR_KEYTABLE_MAC0(_n) (AR_KEYTABLE(_n) + 24) | ||
1509 | #define AR_KEYTABLE_MAC1(_n) (AR_KEYTABLE(_n) + 28) | ||
1510 | |||
1511 | #endif | ||
diff --git a/drivers/net/wireless/ath9k/virtual.c b/drivers/net/wireless/ath9k/virtual.c deleted file mode 100644 index 1ff429b027d7..000000000000 --- a/drivers/net/wireless/ath9k/virtual.c +++ /dev/null | |||
@@ -1,662 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 "ath9k.h" | ||
18 | |||
19 | struct ath9k_vif_iter_data { | ||
20 | int count; | ||
21 | u8 *addr; | ||
22 | }; | ||
23 | |||
24 | static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | ||
25 | { | ||
26 | struct ath9k_vif_iter_data *iter_data = data; | ||
27 | u8 *nbuf; | ||
28 | |||
29 | nbuf = krealloc(iter_data->addr, (iter_data->count + 1) * ETH_ALEN, | ||
30 | GFP_ATOMIC); | ||
31 | if (nbuf == NULL) | ||
32 | return; | ||
33 | |||
34 | memcpy(nbuf + iter_data->count * ETH_ALEN, mac, ETH_ALEN); | ||
35 | iter_data->addr = nbuf; | ||
36 | iter_data->count++; | ||
37 | } | ||
38 | |||
39 | void ath9k_set_bssid_mask(struct ieee80211_hw *hw) | ||
40 | { | ||
41 | struct ath_wiphy *aphy = hw->priv; | ||
42 | struct ath_softc *sc = aphy->sc; | ||
43 | struct ath9k_vif_iter_data iter_data; | ||
44 | int i, j; | ||
45 | u8 mask[ETH_ALEN]; | ||
46 | |||
47 | /* | ||
48 | * Add primary MAC address even if it is not in active use since it | ||
49 | * will be configured to the hardware as the starting point and the | ||
50 | * BSSID mask will need to be changed if another address is active. | ||
51 | */ | ||
52 | iter_data.addr = kmalloc(ETH_ALEN, GFP_ATOMIC); | ||
53 | if (iter_data.addr) { | ||
54 | memcpy(iter_data.addr, sc->sc_ah->macaddr, ETH_ALEN); | ||
55 | iter_data.count = 1; | ||
56 | } else | ||
57 | iter_data.count = 0; | ||
58 | |||
59 | /* Get list of all active MAC addresses */ | ||
60 | spin_lock_bh(&sc->wiphy_lock); | ||
61 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter, | ||
62 | &iter_data); | ||
63 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
64 | if (sc->sec_wiphy[i] == NULL) | ||
65 | continue; | ||
66 | ieee80211_iterate_active_interfaces_atomic( | ||
67 | sc->sec_wiphy[i]->hw, ath9k_vif_iter, &iter_data); | ||
68 | } | ||
69 | spin_unlock_bh(&sc->wiphy_lock); | ||
70 | |||
71 | /* Generate an address mask to cover all active addresses */ | ||
72 | memset(mask, 0, ETH_ALEN); | ||
73 | for (i = 0; i < iter_data.count; i++) { | ||
74 | u8 *a1 = iter_data.addr + i * ETH_ALEN; | ||
75 | for (j = i + 1; j < iter_data.count; j++) { | ||
76 | u8 *a2 = iter_data.addr + j * ETH_ALEN; | ||
77 | mask[0] |= a1[0] ^ a2[0]; | ||
78 | mask[1] |= a1[1] ^ a2[1]; | ||
79 | mask[2] |= a1[2] ^ a2[2]; | ||
80 | mask[3] |= a1[3] ^ a2[3]; | ||
81 | mask[4] |= a1[4] ^ a2[4]; | ||
82 | mask[5] |= a1[5] ^ a2[5]; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | kfree(iter_data.addr); | ||
87 | |||
88 | /* Invert the mask and configure hardware */ | ||
89 | sc->bssidmask[0] = ~mask[0]; | ||
90 | sc->bssidmask[1] = ~mask[1]; | ||
91 | sc->bssidmask[2] = ~mask[2]; | ||
92 | sc->bssidmask[3] = ~mask[3]; | ||
93 | sc->bssidmask[4] = ~mask[4]; | ||
94 | sc->bssidmask[5] = ~mask[5]; | ||
95 | |||
96 | ath9k_hw_setbssidmask(sc); | ||
97 | } | ||
98 | |||
99 | int ath9k_wiphy_add(struct ath_softc *sc) | ||
100 | { | ||
101 | int i, error; | ||
102 | struct ath_wiphy *aphy; | ||
103 | struct ieee80211_hw *hw; | ||
104 | u8 addr[ETH_ALEN]; | ||
105 | |||
106 | hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy), &ath9k_ops); | ||
107 | if (hw == NULL) | ||
108 | return -ENOMEM; | ||
109 | |||
110 | spin_lock_bh(&sc->wiphy_lock); | ||
111 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
112 | if (sc->sec_wiphy[i] == NULL) | ||
113 | break; | ||
114 | } | ||
115 | |||
116 | if (i == sc->num_sec_wiphy) { | ||
117 | /* No empty slot available; increase array length */ | ||
118 | struct ath_wiphy **n; | ||
119 | n = krealloc(sc->sec_wiphy, | ||
120 | (sc->num_sec_wiphy + 1) * | ||
121 | sizeof(struct ath_wiphy *), | ||
122 | GFP_ATOMIC); | ||
123 | if (n == NULL) { | ||
124 | spin_unlock_bh(&sc->wiphy_lock); | ||
125 | ieee80211_free_hw(hw); | ||
126 | return -ENOMEM; | ||
127 | } | ||
128 | n[i] = NULL; | ||
129 | sc->sec_wiphy = n; | ||
130 | sc->num_sec_wiphy++; | ||
131 | } | ||
132 | |||
133 | SET_IEEE80211_DEV(hw, sc->dev); | ||
134 | |||
135 | aphy = hw->priv; | ||
136 | aphy->sc = sc; | ||
137 | aphy->hw = hw; | ||
138 | sc->sec_wiphy[i] = aphy; | ||
139 | spin_unlock_bh(&sc->wiphy_lock); | ||
140 | |||
141 | memcpy(addr, sc->sc_ah->macaddr, ETH_ALEN); | ||
142 | addr[0] |= 0x02; /* Locally managed address */ | ||
143 | /* | ||
144 | * XOR virtual wiphy index into the least significant bits to generate | ||
145 | * a different MAC address for each virtual wiphy. | ||
146 | */ | ||
147 | addr[5] ^= i & 0xff; | ||
148 | addr[4] ^= (i & 0xff00) >> 8; | ||
149 | addr[3] ^= (i & 0xff0000) >> 16; | ||
150 | |||
151 | SET_IEEE80211_PERM_ADDR(hw, addr); | ||
152 | |||
153 | ath_set_hw_capab(sc, hw); | ||
154 | |||
155 | error = ieee80211_register_hw(hw); | ||
156 | |||
157 | if (error == 0) { | ||
158 | /* Make sure wiphy scheduler is started (if enabled) */ | ||
159 | ath9k_wiphy_set_scheduler(sc, sc->wiphy_scheduler_int); | ||
160 | } | ||
161 | |||
162 | return error; | ||
163 | } | ||
164 | |||
165 | int ath9k_wiphy_del(struct ath_wiphy *aphy) | ||
166 | { | ||
167 | struct ath_softc *sc = aphy->sc; | ||
168 | int i; | ||
169 | |||
170 | spin_lock_bh(&sc->wiphy_lock); | ||
171 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
172 | if (aphy == sc->sec_wiphy[i]) { | ||
173 | sc->sec_wiphy[i] = NULL; | ||
174 | spin_unlock_bh(&sc->wiphy_lock); | ||
175 | ieee80211_unregister_hw(aphy->hw); | ||
176 | ieee80211_free_hw(aphy->hw); | ||
177 | return 0; | ||
178 | } | ||
179 | } | ||
180 | spin_unlock_bh(&sc->wiphy_lock); | ||
181 | return -ENOENT; | ||
182 | } | ||
183 | |||
184 | static int ath9k_send_nullfunc(struct ath_wiphy *aphy, | ||
185 | struct ieee80211_vif *vif, const u8 *bssid, | ||
186 | int ps) | ||
187 | { | ||
188 | struct ath_softc *sc = aphy->sc; | ||
189 | struct ath_tx_control txctl; | ||
190 | struct sk_buff *skb; | ||
191 | struct ieee80211_hdr *hdr; | ||
192 | __le16 fc; | ||
193 | struct ieee80211_tx_info *info; | ||
194 | |||
195 | skb = dev_alloc_skb(24); | ||
196 | if (skb == NULL) | ||
197 | return -ENOMEM; | ||
198 | hdr = (struct ieee80211_hdr *) skb_put(skb, 24); | ||
199 | memset(hdr, 0, 24); | ||
200 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | | ||
201 | IEEE80211_FCTL_TODS); | ||
202 | if (ps) | ||
203 | fc |= cpu_to_le16(IEEE80211_FCTL_PM); | ||
204 | hdr->frame_control = fc; | ||
205 | memcpy(hdr->addr1, bssid, ETH_ALEN); | ||
206 | memcpy(hdr->addr2, aphy->hw->wiphy->perm_addr, ETH_ALEN); | ||
207 | memcpy(hdr->addr3, bssid, ETH_ALEN); | ||
208 | |||
209 | info = IEEE80211_SKB_CB(skb); | ||
210 | memset(info, 0, sizeof(*info)); | ||
211 | info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
212 | info->control.vif = vif; | ||
213 | info->control.rates[0].idx = 0; | ||
214 | info->control.rates[0].count = 4; | ||
215 | info->control.rates[1].idx = -1; | ||
216 | |||
217 | memset(&txctl, 0, sizeof(struct ath_tx_control)); | ||
218 | txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]]; | ||
219 | txctl.frame_type = ps ? ATH9K_INT_PAUSE : ATH9K_INT_UNPAUSE; | ||
220 | |||
221 | if (ath_tx_start(aphy->hw, skb, &txctl) != 0) | ||
222 | goto exit; | ||
223 | |||
224 | return 0; | ||
225 | exit: | ||
226 | dev_kfree_skb_any(skb); | ||
227 | return -1; | ||
228 | } | ||
229 | |||
230 | static bool __ath9k_wiphy_pausing(struct ath_softc *sc) | ||
231 | { | ||
232 | int i; | ||
233 | if (sc->pri_wiphy->state == ATH_WIPHY_PAUSING) | ||
234 | return true; | ||
235 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
236 | if (sc->sec_wiphy[i] && | ||
237 | sc->sec_wiphy[i]->state == ATH_WIPHY_PAUSING) | ||
238 | return true; | ||
239 | } | ||
240 | return false; | ||
241 | } | ||
242 | |||
243 | static bool ath9k_wiphy_pausing(struct ath_softc *sc) | ||
244 | { | ||
245 | bool ret; | ||
246 | spin_lock_bh(&sc->wiphy_lock); | ||
247 | ret = __ath9k_wiphy_pausing(sc); | ||
248 | spin_unlock_bh(&sc->wiphy_lock); | ||
249 | return ret; | ||
250 | } | ||
251 | |||
252 | static bool __ath9k_wiphy_scanning(struct ath_softc *sc) | ||
253 | { | ||
254 | int i; | ||
255 | if (sc->pri_wiphy->state == ATH_WIPHY_SCAN) | ||
256 | return true; | ||
257 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
258 | if (sc->sec_wiphy[i] && | ||
259 | sc->sec_wiphy[i]->state == ATH_WIPHY_SCAN) | ||
260 | return true; | ||
261 | } | ||
262 | return false; | ||
263 | } | ||
264 | |||
265 | bool ath9k_wiphy_scanning(struct ath_softc *sc) | ||
266 | { | ||
267 | bool ret; | ||
268 | spin_lock_bh(&sc->wiphy_lock); | ||
269 | ret = __ath9k_wiphy_scanning(sc); | ||
270 | spin_unlock_bh(&sc->wiphy_lock); | ||
271 | return ret; | ||
272 | } | ||
273 | |||
274 | static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy); | ||
275 | |||
276 | /* caller must hold wiphy_lock */ | ||
277 | static void __ath9k_wiphy_unpause_ch(struct ath_wiphy *aphy) | ||
278 | { | ||
279 | if (aphy == NULL) | ||
280 | return; | ||
281 | if (aphy->chan_idx != aphy->sc->chan_idx) | ||
282 | return; /* wiphy not on the selected channel */ | ||
283 | __ath9k_wiphy_unpause(aphy); | ||
284 | } | ||
285 | |||
286 | static void ath9k_wiphy_unpause_channel(struct ath_softc *sc) | ||
287 | { | ||
288 | int i; | ||
289 | spin_lock_bh(&sc->wiphy_lock); | ||
290 | __ath9k_wiphy_unpause_ch(sc->pri_wiphy); | ||
291 | for (i = 0; i < sc->num_sec_wiphy; i++) | ||
292 | __ath9k_wiphy_unpause_ch(sc->sec_wiphy[i]); | ||
293 | spin_unlock_bh(&sc->wiphy_lock); | ||
294 | } | ||
295 | |||
296 | void ath9k_wiphy_chan_work(struct work_struct *work) | ||
297 | { | ||
298 | struct ath_softc *sc = container_of(work, struct ath_softc, chan_work); | ||
299 | struct ath_wiphy *aphy = sc->next_wiphy; | ||
300 | |||
301 | if (aphy == NULL) | ||
302 | return; | ||
303 | |||
304 | /* | ||
305 | * All pending interfaces paused; ready to change | ||
306 | * channels. | ||
307 | */ | ||
308 | |||
309 | /* Change channels */ | ||
310 | mutex_lock(&sc->mutex); | ||
311 | /* XXX: remove me eventually */ | ||
312 | ath9k_update_ichannel(sc, aphy->hw, | ||
313 | &sc->sc_ah->channels[sc->chan_idx]); | ||
314 | ath_update_chainmask(sc, sc->chan_is_ht); | ||
315 | if (ath_set_channel(sc, aphy->hw, | ||
316 | &sc->sc_ah->channels[sc->chan_idx]) < 0) { | ||
317 | printk(KERN_DEBUG "ath9k: Failed to set channel for new " | ||
318 | "virtual wiphy\n"); | ||
319 | mutex_unlock(&sc->mutex); | ||
320 | return; | ||
321 | } | ||
322 | mutex_unlock(&sc->mutex); | ||
323 | |||
324 | ath9k_wiphy_unpause_channel(sc); | ||
325 | } | ||
326 | |||
327 | /* | ||
328 | * ath9k version of ieee80211_tx_status() for TX frames that are generated | ||
329 | * internally in the driver. | ||
330 | */ | ||
331 | void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
332 | { | ||
333 | struct ath_wiphy *aphy = hw->priv; | ||
334 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
335 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
336 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
337 | |||
338 | if (tx_info_priv && tx_info_priv->frame_type == ATH9K_INT_PAUSE && | ||
339 | aphy->state == ATH_WIPHY_PAUSING) { | ||
340 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) { | ||
341 | printk(KERN_DEBUG "ath9k: %s: no ACK for pause " | ||
342 | "frame\n", wiphy_name(hw->wiphy)); | ||
343 | /* | ||
344 | * The AP did not reply; ignore this to allow us to | ||
345 | * continue. | ||
346 | */ | ||
347 | } | ||
348 | aphy->state = ATH_WIPHY_PAUSED; | ||
349 | if (!ath9k_wiphy_pausing(aphy->sc)) { | ||
350 | /* | ||
351 | * Drop from tasklet to work to allow mutex for channel | ||
352 | * change. | ||
353 | */ | ||
354 | queue_work(aphy->sc->hw->workqueue, | ||
355 | &aphy->sc->chan_work); | ||
356 | } | ||
357 | } | ||
358 | |||
359 | kfree(tx_info_priv); | ||
360 | tx_info->rate_driver_data[0] = NULL; | ||
361 | |||
362 | dev_kfree_skb(skb); | ||
363 | } | ||
364 | |||
365 | static void ath9k_mark_paused(struct ath_wiphy *aphy) | ||
366 | { | ||
367 | struct ath_softc *sc = aphy->sc; | ||
368 | aphy->state = ATH_WIPHY_PAUSED; | ||
369 | if (!__ath9k_wiphy_pausing(sc)) | ||
370 | queue_work(sc->hw->workqueue, &sc->chan_work); | ||
371 | } | ||
372 | |||
373 | static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | ||
374 | { | ||
375 | struct ath_wiphy *aphy = data; | ||
376 | struct ath_vif *avp = (void *) vif->drv_priv; | ||
377 | |||
378 | switch (vif->type) { | ||
379 | case NL80211_IFTYPE_STATION: | ||
380 | if (!vif->bss_conf.assoc) { | ||
381 | ath9k_mark_paused(aphy); | ||
382 | break; | ||
383 | } | ||
384 | /* TODO: could avoid this if already in PS mode */ | ||
385 | if (ath9k_send_nullfunc(aphy, vif, avp->bssid, 1)) { | ||
386 | printk(KERN_DEBUG "%s: failed to send PS nullfunc\n", | ||
387 | __func__); | ||
388 | ath9k_mark_paused(aphy); | ||
389 | } | ||
390 | break; | ||
391 | case NL80211_IFTYPE_AP: | ||
392 | /* Beacon transmission is paused by aphy->state change */ | ||
393 | ath9k_mark_paused(aphy); | ||
394 | break; | ||
395 | default: | ||
396 | break; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | /* caller must hold wiphy_lock */ | ||
401 | static int __ath9k_wiphy_pause(struct ath_wiphy *aphy) | ||
402 | { | ||
403 | ieee80211_stop_queues(aphy->hw); | ||
404 | aphy->state = ATH_WIPHY_PAUSING; | ||
405 | /* | ||
406 | * TODO: handle PAUSING->PAUSED for the case where there are multiple | ||
407 | * active vifs (now we do it on the first vif getting ready; should be | ||
408 | * on the last) | ||
409 | */ | ||
410 | ieee80211_iterate_active_interfaces_atomic(aphy->hw, ath9k_pause_iter, | ||
411 | aphy); | ||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | int ath9k_wiphy_pause(struct ath_wiphy *aphy) | ||
416 | { | ||
417 | int ret; | ||
418 | spin_lock_bh(&aphy->sc->wiphy_lock); | ||
419 | ret = __ath9k_wiphy_pause(aphy); | ||
420 | spin_unlock_bh(&aphy->sc->wiphy_lock); | ||
421 | return ret; | ||
422 | } | ||
423 | |||
424 | static void ath9k_unpause_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | ||
425 | { | ||
426 | struct ath_wiphy *aphy = data; | ||
427 | struct ath_vif *avp = (void *) vif->drv_priv; | ||
428 | |||
429 | switch (vif->type) { | ||
430 | case NL80211_IFTYPE_STATION: | ||
431 | if (!vif->bss_conf.assoc) | ||
432 | break; | ||
433 | ath9k_send_nullfunc(aphy, vif, avp->bssid, 0); | ||
434 | break; | ||
435 | case NL80211_IFTYPE_AP: | ||
436 | /* Beacon transmission is re-enabled by aphy->state change */ | ||
437 | break; | ||
438 | default: | ||
439 | break; | ||
440 | } | ||
441 | } | ||
442 | |||
443 | /* caller must hold wiphy_lock */ | ||
444 | static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy) | ||
445 | { | ||
446 | ieee80211_iterate_active_interfaces_atomic(aphy->hw, | ||
447 | ath9k_unpause_iter, aphy); | ||
448 | aphy->state = ATH_WIPHY_ACTIVE; | ||
449 | ieee80211_wake_queues(aphy->hw); | ||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | int ath9k_wiphy_unpause(struct ath_wiphy *aphy) | ||
454 | { | ||
455 | int ret; | ||
456 | spin_lock_bh(&aphy->sc->wiphy_lock); | ||
457 | ret = __ath9k_wiphy_unpause(aphy); | ||
458 | spin_unlock_bh(&aphy->sc->wiphy_lock); | ||
459 | return ret; | ||
460 | } | ||
461 | |||
462 | static void __ath9k_wiphy_mark_all_paused(struct ath_softc *sc) | ||
463 | { | ||
464 | int i; | ||
465 | if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) | ||
466 | sc->pri_wiphy->state = ATH_WIPHY_PAUSED; | ||
467 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
468 | if (sc->sec_wiphy[i] && | ||
469 | sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) | ||
470 | sc->sec_wiphy[i]->state = ATH_WIPHY_PAUSED; | ||
471 | } | ||
472 | } | ||
473 | |||
474 | /* caller must hold wiphy_lock */ | ||
475 | static void __ath9k_wiphy_pause_all(struct ath_softc *sc) | ||
476 | { | ||
477 | int i; | ||
478 | if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) | ||
479 | __ath9k_wiphy_pause(sc->pri_wiphy); | ||
480 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
481 | if (sc->sec_wiphy[i] && | ||
482 | sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE) | ||
483 | __ath9k_wiphy_pause(sc->sec_wiphy[i]); | ||
484 | } | ||
485 | } | ||
486 | |||
487 | int ath9k_wiphy_select(struct ath_wiphy *aphy) | ||
488 | { | ||
489 | struct ath_softc *sc = aphy->sc; | ||
490 | bool now; | ||
491 | |||
492 | spin_lock_bh(&sc->wiphy_lock); | ||
493 | if (__ath9k_wiphy_scanning(sc)) { | ||
494 | /* | ||
495 | * For now, we are using mac80211 sw scan and it expects to | ||
496 | * have full control over channel changes, so avoid wiphy | ||
497 | * scheduling during a scan. This could be optimized if the | ||
498 | * scanning control were moved into the driver. | ||
499 | */ | ||
500 | spin_unlock_bh(&sc->wiphy_lock); | ||
501 | return -EBUSY; | ||
502 | } | ||
503 | if (__ath9k_wiphy_pausing(sc)) { | ||
504 | if (sc->wiphy_select_failures == 0) | ||
505 | sc->wiphy_select_first_fail = jiffies; | ||
506 | sc->wiphy_select_failures++; | ||
507 | if (time_after(jiffies, sc->wiphy_select_first_fail + HZ / 2)) | ||
508 | { | ||
509 | printk(KERN_DEBUG "ath9k: Previous wiphy select timed " | ||
510 | "out; disable/enable hw to recover\n"); | ||
511 | __ath9k_wiphy_mark_all_paused(sc); | ||
512 | /* | ||
513 | * TODO: this workaround to fix hardware is unlikely to | ||
514 | * be specific to virtual wiphy changes. It can happen | ||
515 | * on normal channel change, too, and as such, this | ||
516 | * should really be made more generic. For example, | ||
517 | * tricker radio disable/enable on GTT interrupt burst | ||
518 | * (say, 10 GTT interrupts received without any TX | ||
519 | * frame being completed) | ||
520 | */ | ||
521 | spin_unlock_bh(&sc->wiphy_lock); | ||
522 | ath_radio_disable(sc); | ||
523 | ath_radio_enable(sc); | ||
524 | queue_work(aphy->sc->hw->workqueue, | ||
525 | &aphy->sc->chan_work); | ||
526 | return -EBUSY; /* previous select still in progress */ | ||
527 | } | ||
528 | spin_unlock_bh(&sc->wiphy_lock); | ||
529 | return -EBUSY; /* previous select still in progress */ | ||
530 | } | ||
531 | sc->wiphy_select_failures = 0; | ||
532 | |||
533 | /* Store the new channel */ | ||
534 | sc->chan_idx = aphy->chan_idx; | ||
535 | sc->chan_is_ht = aphy->chan_is_ht; | ||
536 | sc->next_wiphy = aphy; | ||
537 | |||
538 | __ath9k_wiphy_pause_all(sc); | ||
539 | now = !__ath9k_wiphy_pausing(aphy->sc); | ||
540 | spin_unlock_bh(&sc->wiphy_lock); | ||
541 | |||
542 | if (now) { | ||
543 | /* Ready to request channel change immediately */ | ||
544 | queue_work(aphy->sc->hw->workqueue, &aphy->sc->chan_work); | ||
545 | } | ||
546 | |||
547 | /* | ||
548 | * wiphys will be unpaused in ath9k_tx_status() once channel has been | ||
549 | * changed if any wiphy needs time to become paused. | ||
550 | */ | ||
551 | |||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | bool ath9k_wiphy_started(struct ath_softc *sc) | ||
556 | { | ||
557 | int i; | ||
558 | spin_lock_bh(&sc->wiphy_lock); | ||
559 | if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) { | ||
560 | spin_unlock_bh(&sc->wiphy_lock); | ||
561 | return true; | ||
562 | } | ||
563 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
564 | if (sc->sec_wiphy[i] && | ||
565 | sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) { | ||
566 | spin_unlock_bh(&sc->wiphy_lock); | ||
567 | return true; | ||
568 | } | ||
569 | } | ||
570 | spin_unlock_bh(&sc->wiphy_lock); | ||
571 | return false; | ||
572 | } | ||
573 | |||
574 | static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy, | ||
575 | struct ath_wiphy *selected) | ||
576 | { | ||
577 | if (selected->state == ATH_WIPHY_SCAN) { | ||
578 | if (aphy == selected) | ||
579 | return; | ||
580 | /* | ||
581 | * Pause all other wiphys for the duration of the scan even if | ||
582 | * they are on the current channel now. | ||
583 | */ | ||
584 | } else if (aphy->chan_idx == selected->chan_idx) | ||
585 | return; | ||
586 | aphy->state = ATH_WIPHY_PAUSED; | ||
587 | ieee80211_stop_queues(aphy->hw); | ||
588 | } | ||
589 | |||
590 | void ath9k_wiphy_pause_all_forced(struct ath_softc *sc, | ||
591 | struct ath_wiphy *selected) | ||
592 | { | ||
593 | int i; | ||
594 | spin_lock_bh(&sc->wiphy_lock); | ||
595 | if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) | ||
596 | ath9k_wiphy_pause_chan(sc->pri_wiphy, selected); | ||
597 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
598 | if (sc->sec_wiphy[i] && | ||
599 | sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE) | ||
600 | ath9k_wiphy_pause_chan(sc->sec_wiphy[i], selected); | ||
601 | } | ||
602 | spin_unlock_bh(&sc->wiphy_lock); | ||
603 | } | ||
604 | |||
605 | void ath9k_wiphy_work(struct work_struct *work) | ||
606 | { | ||
607 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
608 | wiphy_work.work); | ||
609 | struct ath_wiphy *aphy = NULL; | ||
610 | bool first = true; | ||
611 | |||
612 | spin_lock_bh(&sc->wiphy_lock); | ||
613 | |||
614 | if (sc->wiphy_scheduler_int == 0) { | ||
615 | /* wiphy scheduler is disabled */ | ||
616 | spin_unlock_bh(&sc->wiphy_lock); | ||
617 | return; | ||
618 | } | ||
619 | |||
620 | try_again: | ||
621 | sc->wiphy_scheduler_index++; | ||
622 | while (sc->wiphy_scheduler_index <= sc->num_sec_wiphy) { | ||
623 | aphy = sc->sec_wiphy[sc->wiphy_scheduler_index - 1]; | ||
624 | if (aphy && aphy->state != ATH_WIPHY_INACTIVE) | ||
625 | break; | ||
626 | |||
627 | sc->wiphy_scheduler_index++; | ||
628 | aphy = NULL; | ||
629 | } | ||
630 | if (aphy == NULL) { | ||
631 | sc->wiphy_scheduler_index = 0; | ||
632 | if (sc->pri_wiphy->state == ATH_WIPHY_INACTIVE) { | ||
633 | if (first) { | ||
634 | first = false; | ||
635 | goto try_again; | ||
636 | } | ||
637 | /* No wiphy is ready to be scheduled */ | ||
638 | } else | ||
639 | aphy = sc->pri_wiphy; | ||
640 | } | ||
641 | |||
642 | spin_unlock_bh(&sc->wiphy_lock); | ||
643 | |||
644 | if (aphy && | ||
645 | aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN && | ||
646 | ath9k_wiphy_select(aphy)) { | ||
647 | printk(KERN_DEBUG "ath9k: Failed to schedule virtual wiphy " | ||
648 | "change\n"); | ||
649 | } | ||
650 | |||
651 | queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work, | ||
652 | sc->wiphy_scheduler_int); | ||
653 | } | ||
654 | |||
655 | void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int) | ||
656 | { | ||
657 | cancel_delayed_work_sync(&sc->wiphy_work); | ||
658 | sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int); | ||
659 | if (sc->wiphy_scheduler_int) | ||
660 | queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work, | ||
661 | sc->wiphy_scheduler_int); | ||
662 | } | ||
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c deleted file mode 100644 index 628b780d8844..000000000000 --- a/drivers/net/wireless/ath9k/xmit.c +++ /dev/null | |||
@@ -1,2171 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 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 "ath9k.h" | ||
18 | |||
19 | #define BITS_PER_BYTE 8 | ||
20 | #define OFDM_PLCP_BITS 22 | ||
21 | #define HT_RC_2_MCS(_rc) ((_rc) & 0x0f) | ||
22 | #define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) | ||
23 | #define L_STF 8 | ||
24 | #define L_LTF 8 | ||
25 | #define L_SIG 4 | ||
26 | #define HT_SIG 8 | ||
27 | #define HT_STF 4 | ||
28 | #define HT_LTF(_ns) (4 * (_ns)) | ||
29 | #define SYMBOL_TIME(_ns) ((_ns) << 2) /* ns * 4 us */ | ||
30 | #define SYMBOL_TIME_HALFGI(_ns) (((_ns) * 18 + 4) / 5) /* ns * 3.6 us */ | ||
31 | #define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2) | ||
32 | #define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18) | ||
33 | |||
34 | #define OFDM_SIFS_TIME 16 | ||
35 | |||
36 | static u32 bits_per_symbol[][2] = { | ||
37 | /* 20MHz 40MHz */ | ||
38 | { 26, 54 }, /* 0: BPSK */ | ||
39 | { 52, 108 }, /* 1: QPSK 1/2 */ | ||
40 | { 78, 162 }, /* 2: QPSK 3/4 */ | ||
41 | { 104, 216 }, /* 3: 16-QAM 1/2 */ | ||
42 | { 156, 324 }, /* 4: 16-QAM 3/4 */ | ||
43 | { 208, 432 }, /* 5: 64-QAM 2/3 */ | ||
44 | { 234, 486 }, /* 6: 64-QAM 3/4 */ | ||
45 | { 260, 540 }, /* 7: 64-QAM 5/6 */ | ||
46 | { 52, 108 }, /* 8: BPSK */ | ||
47 | { 104, 216 }, /* 9: QPSK 1/2 */ | ||
48 | { 156, 324 }, /* 10: QPSK 3/4 */ | ||
49 | { 208, 432 }, /* 11: 16-QAM 1/2 */ | ||
50 | { 312, 648 }, /* 12: 16-QAM 3/4 */ | ||
51 | { 416, 864 }, /* 13: 64-QAM 2/3 */ | ||
52 | { 468, 972 }, /* 14: 64-QAM 3/4 */ | ||
53 | { 520, 1080 }, /* 15: 64-QAM 5/6 */ | ||
54 | }; | ||
55 | |||
56 | #define IS_HT_RATE(_rate) ((_rate) & 0x80) | ||
57 | |||
58 | static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq, | ||
59 | struct ath_atx_tid *tid, | ||
60 | struct list_head *bf_head); | ||
61 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | ||
62 | struct list_head *bf_q, | ||
63 | int txok, int sendbar); | ||
64 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | ||
65 | struct list_head *head); | ||
66 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf); | ||
67 | static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, | ||
68 | int txok); | ||
69 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | ||
70 | int nbad, int txok, bool update_rc); | ||
71 | |||
72 | /*********************/ | ||
73 | /* Aggregation logic */ | ||
74 | /*********************/ | ||
75 | |||
76 | static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno) | ||
77 | { | ||
78 | struct ath_atx_tid *tid; | ||
79 | tid = ATH_AN_2_TID(an, tidno); | ||
80 | |||
81 | if (tid->state & AGGR_ADDBA_COMPLETE || | ||
82 | tid->state & AGGR_ADDBA_PROGRESS) | ||
83 | return 1; | ||
84 | else | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid) | ||
89 | { | ||
90 | struct ath_atx_ac *ac = tid->ac; | ||
91 | |||
92 | if (tid->paused) | ||
93 | return; | ||
94 | |||
95 | if (tid->sched) | ||
96 | return; | ||
97 | |||
98 | tid->sched = true; | ||
99 | list_add_tail(&tid->list, &ac->tid_q); | ||
100 | |||
101 | if (ac->sched) | ||
102 | return; | ||
103 | |||
104 | ac->sched = true; | ||
105 | list_add_tail(&ac->list, &txq->axq_acq); | ||
106 | } | ||
107 | |||
108 | static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | ||
109 | { | ||
110 | struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; | ||
111 | |||
112 | spin_lock_bh(&txq->axq_lock); | ||
113 | tid->paused++; | ||
114 | spin_unlock_bh(&txq->axq_lock); | ||
115 | } | ||
116 | |||
117 | static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | ||
118 | { | ||
119 | struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; | ||
120 | |||
121 | ASSERT(tid->paused > 0); | ||
122 | spin_lock_bh(&txq->axq_lock); | ||
123 | |||
124 | tid->paused--; | ||
125 | |||
126 | if (tid->paused > 0) | ||
127 | goto unlock; | ||
128 | |||
129 | if (list_empty(&tid->buf_q)) | ||
130 | goto unlock; | ||
131 | |||
132 | ath_tx_queue_tid(txq, tid); | ||
133 | ath_txq_schedule(sc, txq); | ||
134 | unlock: | ||
135 | spin_unlock_bh(&txq->axq_lock); | ||
136 | } | ||
137 | |||
138 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | ||
139 | { | ||
140 | struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; | ||
141 | struct ath_buf *bf; | ||
142 | struct list_head bf_head; | ||
143 | INIT_LIST_HEAD(&bf_head); | ||
144 | |||
145 | ASSERT(tid->paused > 0); | ||
146 | spin_lock_bh(&txq->axq_lock); | ||
147 | |||
148 | tid->paused--; | ||
149 | |||
150 | if (tid->paused > 0) { | ||
151 | spin_unlock_bh(&txq->axq_lock); | ||
152 | return; | ||
153 | } | ||
154 | |||
155 | while (!list_empty(&tid->buf_q)) { | ||
156 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); | ||
157 | ASSERT(!bf_isretried(bf)); | ||
158 | list_move_tail(&bf->list, &bf_head); | ||
159 | ath_tx_send_ht_normal(sc, txq, tid, &bf_head); | ||
160 | } | ||
161 | |||
162 | spin_unlock_bh(&txq->axq_lock); | ||
163 | } | ||
164 | |||
165 | static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, | ||
166 | int seqno) | ||
167 | { | ||
168 | int index, cindex; | ||
169 | |||
170 | index = ATH_BA_INDEX(tid->seq_start, seqno); | ||
171 | cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); | ||
172 | |||
173 | tid->tx_buf[cindex] = NULL; | ||
174 | |||
175 | while (tid->baw_head != tid->baw_tail && !tid->tx_buf[tid->baw_head]) { | ||
176 | INCR(tid->seq_start, IEEE80211_SEQ_MAX); | ||
177 | INCR(tid->baw_head, ATH_TID_MAX_BUFS); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid, | ||
182 | struct ath_buf *bf) | ||
183 | { | ||
184 | int index, cindex; | ||
185 | |||
186 | if (bf_isretried(bf)) | ||
187 | return; | ||
188 | |||
189 | index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno); | ||
190 | cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); | ||
191 | |||
192 | ASSERT(tid->tx_buf[cindex] == NULL); | ||
193 | tid->tx_buf[cindex] = bf; | ||
194 | |||
195 | if (index >= ((tid->baw_tail - tid->baw_head) & | ||
196 | (ATH_TID_MAX_BUFS - 1))) { | ||
197 | tid->baw_tail = cindex; | ||
198 | INCR(tid->baw_tail, ATH_TID_MAX_BUFS); | ||
199 | } | ||
200 | } | ||
201 | |||
202 | /* | ||
203 | * TODO: For frame(s) that are in the retry state, we will reuse the | ||
204 | * sequence number(s) without setting the retry bit. The | ||
205 | * alternative is to give up on these and BAR the receiver's window | ||
206 | * forward. | ||
207 | */ | ||
208 | static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, | ||
209 | struct ath_atx_tid *tid) | ||
210 | |||
211 | { | ||
212 | struct ath_buf *bf; | ||
213 | struct list_head bf_head; | ||
214 | INIT_LIST_HEAD(&bf_head); | ||
215 | |||
216 | for (;;) { | ||
217 | if (list_empty(&tid->buf_q)) | ||
218 | break; | ||
219 | |||
220 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); | ||
221 | list_move_tail(&bf->list, &bf_head); | ||
222 | |||
223 | if (bf_isretried(bf)) | ||
224 | ath_tx_update_baw(sc, tid, bf->bf_seqno); | ||
225 | |||
226 | spin_unlock(&txq->axq_lock); | ||
227 | ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); | ||
228 | spin_lock(&txq->axq_lock); | ||
229 | } | ||
230 | |||
231 | tid->seq_next = tid->seq_start; | ||
232 | tid->baw_tail = tid->baw_head; | ||
233 | } | ||
234 | |||
235 | static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf) | ||
236 | { | ||
237 | struct sk_buff *skb; | ||
238 | struct ieee80211_hdr *hdr; | ||
239 | |||
240 | bf->bf_state.bf_type |= BUF_RETRY; | ||
241 | bf->bf_retries++; | ||
242 | |||
243 | skb = bf->bf_mpdu; | ||
244 | hdr = (struct ieee80211_hdr *)skb->data; | ||
245 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY); | ||
246 | } | ||
247 | |||
248 | static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) | ||
249 | { | ||
250 | struct ath_buf *tbf; | ||
251 | |||
252 | spin_lock_bh(&sc->tx.txbuflock); | ||
253 | ASSERT(!list_empty((&sc->tx.txbuf))); | ||
254 | tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); | ||
255 | list_del(&tbf->list); | ||
256 | spin_unlock_bh(&sc->tx.txbuflock); | ||
257 | |||
258 | ATH_TXBUF_RESET(tbf); | ||
259 | |||
260 | tbf->bf_mpdu = bf->bf_mpdu; | ||
261 | tbf->bf_buf_addr = bf->bf_buf_addr; | ||
262 | *(tbf->bf_desc) = *(bf->bf_desc); | ||
263 | tbf->bf_state = bf->bf_state; | ||
264 | tbf->bf_dmacontext = bf->bf_dmacontext; | ||
265 | |||
266 | return tbf; | ||
267 | } | ||
268 | |||
269 | static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | ||
270 | struct ath_buf *bf, struct list_head *bf_q, | ||
271 | int txok) | ||
272 | { | ||
273 | struct ath_node *an = NULL; | ||
274 | struct sk_buff *skb; | ||
275 | struct ieee80211_sta *sta; | ||
276 | struct ieee80211_hdr *hdr; | ||
277 | struct ath_atx_tid *tid = NULL; | ||
278 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; | ||
279 | struct ath_desc *ds = bf_last->bf_desc; | ||
280 | struct list_head bf_head, bf_pending; | ||
281 | u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0; | ||
282 | u32 ba[WME_BA_BMP_SIZE >> 5]; | ||
283 | int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; | ||
284 | bool rc_update = true; | ||
285 | |||
286 | skb = bf->bf_mpdu; | ||
287 | hdr = (struct ieee80211_hdr *)skb->data; | ||
288 | |||
289 | rcu_read_lock(); | ||
290 | |||
291 | sta = ieee80211_find_sta(sc->hw, hdr->addr1); | ||
292 | if (!sta) { | ||
293 | rcu_read_unlock(); | ||
294 | return; | ||
295 | } | ||
296 | |||
297 | an = (struct ath_node *)sta->drv_priv; | ||
298 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | ||
299 | |||
300 | isaggr = bf_isaggr(bf); | ||
301 | memset(ba, 0, WME_BA_BMP_SIZE >> 3); | ||
302 | |||
303 | if (isaggr && txok) { | ||
304 | if (ATH_DS_TX_BA(ds)) { | ||
305 | seq_st = ATH_DS_BA_SEQ(ds); | ||
306 | memcpy(ba, ATH_DS_BA_BITMAP(ds), | ||
307 | WME_BA_BMP_SIZE >> 3); | ||
308 | } else { | ||
309 | /* | ||
310 | * AR5416 can become deaf/mute when BA | ||
311 | * issue happens. Chip needs to be reset. | ||
312 | * But AP code may have sychronization issues | ||
313 | * when perform internal reset in this routine. | ||
314 | * Only enable reset in STA mode for now. | ||
315 | */ | ||
316 | if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) | ||
317 | needreset = 1; | ||
318 | } | ||
319 | } | ||
320 | |||
321 | INIT_LIST_HEAD(&bf_pending); | ||
322 | INIT_LIST_HEAD(&bf_head); | ||
323 | |||
324 | nbad = ath_tx_num_badfrms(sc, bf, txok); | ||
325 | while (bf) { | ||
326 | txfail = txpending = 0; | ||
327 | bf_next = bf->bf_next; | ||
328 | |||
329 | if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) { | ||
330 | /* transmit completion, subframe is | ||
331 | * acked by block ack */ | ||
332 | acked_cnt++; | ||
333 | } else if (!isaggr && txok) { | ||
334 | /* transmit completion */ | ||
335 | acked_cnt++; | ||
336 | } else { | ||
337 | if (!(tid->state & AGGR_CLEANUP) && | ||
338 | ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) { | ||
339 | if (bf->bf_retries < ATH_MAX_SW_RETRIES) { | ||
340 | ath_tx_set_retry(sc, bf); | ||
341 | txpending = 1; | ||
342 | } else { | ||
343 | bf->bf_state.bf_type |= BUF_XRETRY; | ||
344 | txfail = 1; | ||
345 | sendbar = 1; | ||
346 | txfail_cnt++; | ||
347 | } | ||
348 | } else { | ||
349 | /* | ||
350 | * cleanup in progress, just fail | ||
351 | * the un-acked sub-frames | ||
352 | */ | ||
353 | txfail = 1; | ||
354 | } | ||
355 | } | ||
356 | |||
357 | if (bf_next == NULL) { | ||
358 | INIT_LIST_HEAD(&bf_head); | ||
359 | } else { | ||
360 | ASSERT(!list_empty(bf_q)); | ||
361 | list_move_tail(&bf->list, &bf_head); | ||
362 | } | ||
363 | |||
364 | if (!txpending) { | ||
365 | /* | ||
366 | * complete the acked-ones/xretried ones; update | ||
367 | * block-ack window | ||
368 | */ | ||
369 | spin_lock_bh(&txq->axq_lock); | ||
370 | ath_tx_update_baw(sc, tid, bf->bf_seqno); | ||
371 | spin_unlock_bh(&txq->axq_lock); | ||
372 | |||
373 | if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { | ||
374 | ath_tx_rc_status(bf, ds, nbad, txok, true); | ||
375 | rc_update = false; | ||
376 | } else { | ||
377 | ath_tx_rc_status(bf, ds, nbad, txok, false); | ||
378 | } | ||
379 | |||
380 | ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar); | ||
381 | } else { | ||
382 | /* retry the un-acked ones */ | ||
383 | if (bf->bf_next == NULL && bf_last->bf_stale) { | ||
384 | struct ath_buf *tbf; | ||
385 | |||
386 | tbf = ath_clone_txbuf(sc, bf_last); | ||
387 | ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc); | ||
388 | list_add_tail(&tbf->list, &bf_head); | ||
389 | } else { | ||
390 | /* | ||
391 | * Clear descriptor status words for | ||
392 | * software retry | ||
393 | */ | ||
394 | ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc); | ||
395 | } | ||
396 | |||
397 | /* | ||
398 | * Put this buffer to the temporary pending | ||
399 | * queue to retain ordering | ||
400 | */ | ||
401 | list_splice_tail_init(&bf_head, &bf_pending); | ||
402 | } | ||
403 | |||
404 | bf = bf_next; | ||
405 | } | ||
406 | |||
407 | if (tid->state & AGGR_CLEANUP) { | ||
408 | if (tid->baw_head == tid->baw_tail) { | ||
409 | tid->state &= ~AGGR_ADDBA_COMPLETE; | ||
410 | tid->addba_exchangeattempts = 0; | ||
411 | tid->state &= ~AGGR_CLEANUP; | ||
412 | |||
413 | /* send buffered frames as singles */ | ||
414 | ath_tx_flush_tid(sc, tid); | ||
415 | } | ||
416 | rcu_read_unlock(); | ||
417 | return; | ||
418 | } | ||
419 | |||
420 | /* prepend un-acked frames to the beginning of the pending frame queue */ | ||
421 | if (!list_empty(&bf_pending)) { | ||
422 | spin_lock_bh(&txq->axq_lock); | ||
423 | list_splice(&bf_pending, &tid->buf_q); | ||
424 | ath_tx_queue_tid(txq, tid); | ||
425 | spin_unlock_bh(&txq->axq_lock); | ||
426 | } | ||
427 | |||
428 | rcu_read_unlock(); | ||
429 | |||
430 | if (needreset) | ||
431 | ath_reset(sc, false); | ||
432 | } | ||
433 | |||
434 | static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | ||
435 | struct ath_atx_tid *tid) | ||
436 | { | ||
437 | struct ath_rate_table *rate_table = sc->cur_rate_table; | ||
438 | struct sk_buff *skb; | ||
439 | struct ieee80211_tx_info *tx_info; | ||
440 | struct ieee80211_tx_rate *rates; | ||
441 | struct ath_tx_info_priv *tx_info_priv; | ||
442 | u32 max_4ms_framelen, frmlen; | ||
443 | u16 aggr_limit, legacy = 0, maxampdu; | ||
444 | int i; | ||
445 | |||
446 | skb = bf->bf_mpdu; | ||
447 | tx_info = IEEE80211_SKB_CB(skb); | ||
448 | rates = tx_info->control.rates; | ||
449 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0]; | ||
450 | |||
451 | /* | ||
452 | * Find the lowest frame length among the rate series that will have a | ||
453 | * 4ms transmit duration. | ||
454 | * TODO - TXOP limit needs to be considered. | ||
455 | */ | ||
456 | max_4ms_framelen = ATH_AMPDU_LIMIT_MAX; | ||
457 | |||
458 | for (i = 0; i < 4; i++) { | ||
459 | if (rates[i].count) { | ||
460 | if (!WLAN_RC_PHY_HT(rate_table->info[rates[i].idx].phy)) { | ||
461 | legacy = 1; | ||
462 | break; | ||
463 | } | ||
464 | |||
465 | frmlen = rate_table->info[rates[i].idx].max_4ms_framelen; | ||
466 | max_4ms_framelen = min(max_4ms_framelen, frmlen); | ||
467 | } | ||
468 | } | ||
469 | |||
470 | /* | ||
471 | * limit aggregate size by the minimum rate if rate selected is | ||
472 | * not a probe rate, if rate selected is a probe rate then | ||
473 | * avoid aggregation of this packet. | ||
474 | */ | ||
475 | if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy) | ||
476 | return 0; | ||
477 | |||
478 | aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_DEFAULT); | ||
479 | |||
480 | /* | ||
481 | * h/w can accept aggregates upto 16 bit lengths (65535). | ||
482 | * The IE, however can hold upto 65536, which shows up here | ||
483 | * as zero. Ignore 65536 since we are constrained by hw. | ||
484 | */ | ||
485 | maxampdu = tid->an->maxampdu; | ||
486 | if (maxampdu) | ||
487 | aggr_limit = min(aggr_limit, maxampdu); | ||
488 | |||
489 | return aggr_limit; | ||
490 | } | ||
491 | |||
492 | /* | ||
493 | * Returns the number of delimiters to be added to | ||
494 | * meet the minimum required mpdudensity. | ||
495 | * caller should make sure that the rate is HT rate . | ||
496 | */ | ||
497 | static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, | ||
498 | struct ath_buf *bf, u16 frmlen) | ||
499 | { | ||
500 | struct ath_rate_table *rt = sc->cur_rate_table; | ||
501 | struct sk_buff *skb = bf->bf_mpdu; | ||
502 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
503 | u32 nsymbits, nsymbols, mpdudensity; | ||
504 | u16 minlen; | ||
505 | u8 rc, flags, rix; | ||
506 | int width, half_gi, ndelim, mindelim; | ||
507 | |||
508 | /* Select standard number of delimiters based on frame length alone */ | ||
509 | ndelim = ATH_AGGR_GET_NDELIM(frmlen); | ||
510 | |||
511 | /* | ||
512 | * If encryption enabled, hardware requires some more padding between | ||
513 | * subframes. | ||
514 | * TODO - this could be improved to be dependent on the rate. | ||
515 | * The hardware can keep up at lower rates, but not higher rates | ||
516 | */ | ||
517 | if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) | ||
518 | ndelim += ATH_AGGR_ENCRYPTDELIM; | ||
519 | |||
520 | /* | ||
521 | * Convert desired mpdu density from microeconds to bytes based | ||
522 | * on highest rate in rate series (i.e. first rate) to determine | ||
523 | * required minimum length for subframe. Take into account | ||
524 | * whether high rate is 20 or 40Mhz and half or full GI. | ||
525 | */ | ||
526 | mpdudensity = tid->an->mpdudensity; | ||
527 | |||
528 | /* | ||
529 | * If there is no mpdu density restriction, no further calculation | ||
530 | * is needed. | ||
531 | */ | ||
532 | if (mpdudensity == 0) | ||
533 | return ndelim; | ||
534 | |||
535 | rix = tx_info->control.rates[0].idx; | ||
536 | flags = tx_info->control.rates[0].flags; | ||
537 | rc = rt->info[rix].ratecode; | ||
538 | width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0; | ||
539 | half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0; | ||
540 | |||
541 | if (half_gi) | ||
542 | nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(mpdudensity); | ||
543 | else | ||
544 | nsymbols = NUM_SYMBOLS_PER_USEC(mpdudensity); | ||
545 | |||
546 | if (nsymbols == 0) | ||
547 | nsymbols = 1; | ||
548 | |||
549 | nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width]; | ||
550 | minlen = (nsymbols * nsymbits) / BITS_PER_BYTE; | ||
551 | |||
552 | if (frmlen < minlen) { | ||
553 | mindelim = (minlen - frmlen) / ATH_AGGR_DELIM_SZ; | ||
554 | ndelim = max(mindelim, ndelim); | ||
555 | } | ||
556 | |||
557 | return ndelim; | ||
558 | } | ||
559 | |||
560 | static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | ||
561 | struct ath_atx_tid *tid, | ||
562 | struct list_head *bf_q) | ||
563 | { | ||
564 | #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4) | ||
565 | struct ath_buf *bf, *bf_first, *bf_prev = NULL; | ||
566 | int rl = 0, nframes = 0, ndelim, prev_al = 0; | ||
567 | u16 aggr_limit = 0, al = 0, bpad = 0, | ||
568 | al_delta, h_baw = tid->baw_size / 2; | ||
569 | enum ATH_AGGR_STATUS status = ATH_AGGR_DONE; | ||
570 | |||
571 | bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list); | ||
572 | |||
573 | do { | ||
574 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); | ||
575 | |||
576 | /* do not step over block-ack window */ | ||
577 | if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) { | ||
578 | status = ATH_AGGR_BAW_CLOSED; | ||
579 | break; | ||
580 | } | ||
581 | |||
582 | if (!rl) { | ||
583 | aggr_limit = ath_lookup_rate(sc, bf, tid); | ||
584 | rl = 1; | ||
585 | } | ||
586 | |||
587 | /* do not exceed aggregation limit */ | ||
588 | al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen; | ||
589 | |||
590 | if (nframes && | ||
591 | (aggr_limit < (al + bpad + al_delta + prev_al))) { | ||
592 | status = ATH_AGGR_LIMITED; | ||
593 | break; | ||
594 | } | ||
595 | |||
596 | /* do not exceed subframe limit */ | ||
597 | if (nframes >= min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) { | ||
598 | status = ATH_AGGR_LIMITED; | ||
599 | break; | ||
600 | } | ||
601 | nframes++; | ||
602 | |||
603 | /* add padding for previous frame to aggregation length */ | ||
604 | al += bpad + al_delta; | ||
605 | |||
606 | /* | ||
607 | * Get the delimiters needed to meet the MPDU | ||
608 | * density for this node. | ||
609 | */ | ||
610 | ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen); | ||
611 | bpad = PADBYTES(al_delta) + (ndelim << 2); | ||
612 | |||
613 | bf->bf_next = NULL; | ||
614 | bf->bf_desc->ds_link = 0; | ||
615 | |||
616 | /* link buffers of this frame to the aggregate */ | ||
617 | ath_tx_addto_baw(sc, tid, bf); | ||
618 | ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim); | ||
619 | list_move_tail(&bf->list, bf_q); | ||
620 | if (bf_prev) { | ||
621 | bf_prev->bf_next = bf; | ||
622 | bf_prev->bf_desc->ds_link = bf->bf_daddr; | ||
623 | } | ||
624 | bf_prev = bf; | ||
625 | } while (!list_empty(&tid->buf_q)); | ||
626 | |||
627 | bf_first->bf_al = al; | ||
628 | bf_first->bf_nframes = nframes; | ||
629 | |||
630 | return status; | ||
631 | #undef PADBYTES | ||
632 | } | ||
633 | |||
634 | static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | ||
635 | struct ath_atx_tid *tid) | ||
636 | { | ||
637 | struct ath_buf *bf; | ||
638 | enum ATH_AGGR_STATUS status; | ||
639 | struct list_head bf_q; | ||
640 | |||
641 | do { | ||
642 | if (list_empty(&tid->buf_q)) | ||
643 | return; | ||
644 | |||
645 | INIT_LIST_HEAD(&bf_q); | ||
646 | |||
647 | status = ath_tx_form_aggr(sc, tid, &bf_q); | ||
648 | |||
649 | /* | ||
650 | * no frames picked up to be aggregated; | ||
651 | * block-ack window is not open. | ||
652 | */ | ||
653 | if (list_empty(&bf_q)) | ||
654 | break; | ||
655 | |||
656 | bf = list_first_entry(&bf_q, struct ath_buf, list); | ||
657 | bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); | ||
658 | |||
659 | /* if only one frame, send as non-aggregate */ | ||
660 | if (bf->bf_nframes == 1) { | ||
661 | bf->bf_state.bf_type &= ~BUF_AGGR; | ||
662 | ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); | ||
663 | ath_buf_set_rate(sc, bf); | ||
664 | ath_tx_txqaddbuf(sc, txq, &bf_q); | ||
665 | continue; | ||
666 | } | ||
667 | |||
668 | /* setup first desc of aggregate */ | ||
669 | bf->bf_state.bf_type |= BUF_AGGR; | ||
670 | ath_buf_set_rate(sc, bf); | ||
671 | ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al); | ||
672 | |||
673 | /* anchor last desc of aggregate */ | ||
674 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); | ||
675 | |||
676 | txq->axq_aggr_depth++; | ||
677 | ath_tx_txqaddbuf(sc, txq, &bf_q); | ||
678 | |||
679 | } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH && | ||
680 | status != ATH_AGGR_BAW_CLOSED); | ||
681 | } | ||
682 | |||
683 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | ||
684 | u16 tid, u16 *ssn) | ||
685 | { | ||
686 | struct ath_atx_tid *txtid; | ||
687 | struct ath_node *an; | ||
688 | |||
689 | an = (struct ath_node *)sta->drv_priv; | ||
690 | |||
691 | if (sc->sc_flags & SC_OP_TXAGGR) { | ||
692 | txtid = ATH_AN_2_TID(an, tid); | ||
693 | txtid->state |= AGGR_ADDBA_PROGRESS; | ||
694 | ath_tx_pause_tid(sc, txtid); | ||
695 | *ssn = txtid->seq_start; | ||
696 | } | ||
697 | |||
698 | return 0; | ||
699 | } | ||
700 | |||
701 | int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | ||
702 | { | ||
703 | struct ath_node *an = (struct ath_node *)sta->drv_priv; | ||
704 | struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); | ||
705 | struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; | ||
706 | struct ath_buf *bf; | ||
707 | struct list_head bf_head; | ||
708 | INIT_LIST_HEAD(&bf_head); | ||
709 | |||
710 | if (txtid->state & AGGR_CLEANUP) | ||
711 | return 0; | ||
712 | |||
713 | if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { | ||
714 | txtid->addba_exchangeattempts = 0; | ||
715 | return 0; | ||
716 | } | ||
717 | |||
718 | ath_tx_pause_tid(sc, txtid); | ||
719 | |||
720 | /* drop all software retried frames and mark this TID */ | ||
721 | spin_lock_bh(&txq->axq_lock); | ||
722 | while (!list_empty(&txtid->buf_q)) { | ||
723 | bf = list_first_entry(&txtid->buf_q, struct ath_buf, list); | ||
724 | if (!bf_isretried(bf)) { | ||
725 | /* | ||
726 | * NB: it's based on the assumption that | ||
727 | * software retried frame will always stay | ||
728 | * at the head of software queue. | ||
729 | */ | ||
730 | break; | ||
731 | } | ||
732 | list_move_tail(&bf->list, &bf_head); | ||
733 | ath_tx_update_baw(sc, txtid, bf->bf_seqno); | ||
734 | ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); | ||
735 | } | ||
736 | spin_unlock_bh(&txq->axq_lock); | ||
737 | |||
738 | if (txtid->baw_head != txtid->baw_tail) { | ||
739 | txtid->state |= AGGR_CLEANUP; | ||
740 | } else { | ||
741 | txtid->state &= ~AGGR_ADDBA_COMPLETE; | ||
742 | txtid->addba_exchangeattempts = 0; | ||
743 | ath_tx_flush_tid(sc, txtid); | ||
744 | } | ||
745 | |||
746 | return 0; | ||
747 | } | ||
748 | |||
749 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | ||
750 | { | ||
751 | struct ath_atx_tid *txtid; | ||
752 | struct ath_node *an; | ||
753 | |||
754 | an = (struct ath_node *)sta->drv_priv; | ||
755 | |||
756 | if (sc->sc_flags & SC_OP_TXAGGR) { | ||
757 | txtid = ATH_AN_2_TID(an, tid); | ||
758 | txtid->baw_size = | ||
759 | IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; | ||
760 | txtid->state |= AGGR_ADDBA_COMPLETE; | ||
761 | txtid->state &= ~AGGR_ADDBA_PROGRESS; | ||
762 | ath_tx_resume_tid(sc, txtid); | ||
763 | } | ||
764 | } | ||
765 | |||
766 | bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno) | ||
767 | { | ||
768 | struct ath_atx_tid *txtid; | ||
769 | |||
770 | if (!(sc->sc_flags & SC_OP_TXAGGR)) | ||
771 | return false; | ||
772 | |||
773 | txtid = ATH_AN_2_TID(an, tidno); | ||
774 | |||
775 | if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { | ||
776 | if (!(txtid->state & AGGR_ADDBA_PROGRESS) && | ||
777 | (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) { | ||
778 | txtid->addba_exchangeattempts++; | ||
779 | return true; | ||
780 | } | ||
781 | } | ||
782 | |||
783 | return false; | ||
784 | } | ||
785 | |||
786 | /********************/ | ||
787 | /* Queue Management */ | ||
788 | /********************/ | ||
789 | |||
790 | static void ath_txq_drain_pending_buffers(struct ath_softc *sc, | ||
791 | struct ath_txq *txq) | ||
792 | { | ||
793 | struct ath_atx_ac *ac, *ac_tmp; | ||
794 | struct ath_atx_tid *tid, *tid_tmp; | ||
795 | |||
796 | list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) { | ||
797 | list_del(&ac->list); | ||
798 | ac->sched = false; | ||
799 | list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) { | ||
800 | list_del(&tid->list); | ||
801 | tid->sched = false; | ||
802 | ath_tid_drain(sc, txq, tid); | ||
803 | } | ||
804 | } | ||
805 | } | ||
806 | |||
807 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | ||
808 | { | ||
809 | struct ath_hw *ah = sc->sc_ah; | ||
810 | struct ath9k_tx_queue_info qi; | ||
811 | int qnum; | ||
812 | |||
813 | memset(&qi, 0, sizeof(qi)); | ||
814 | qi.tqi_subtype = subtype; | ||
815 | qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; | ||
816 | qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; | ||
817 | qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; | ||
818 | qi.tqi_physCompBuf = 0; | ||
819 | |||
820 | /* | ||
821 | * Enable interrupts only for EOL and DESC conditions. | ||
822 | * We mark tx descriptors to receive a DESC interrupt | ||
823 | * when a tx queue gets deep; otherwise waiting for the | ||
824 | * EOL to reap descriptors. Note that this is done to | ||
825 | * reduce interrupt load and this only defers reaping | ||
826 | * descriptors, never transmitting frames. Aside from | ||
827 | * reducing interrupts this also permits more concurrency. | ||
828 | * The only potential downside is if the tx queue backs | ||
829 | * up in which case the top half of the kernel may backup | ||
830 | * due to a lack of tx descriptors. | ||
831 | * | ||
832 | * The UAPSD queue is an exception, since we take a desc- | ||
833 | * based intr on the EOSP frames. | ||
834 | */ | ||
835 | if (qtype == ATH9K_TX_QUEUE_UAPSD) | ||
836 | qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE; | ||
837 | else | ||
838 | qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | | ||
839 | TXQ_FLAG_TXDESCINT_ENABLE; | ||
840 | qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi); | ||
841 | if (qnum == -1) { | ||
842 | /* | ||
843 | * NB: don't print a message, this happens | ||
844 | * normally on parts with too few tx queues | ||
845 | */ | ||
846 | return NULL; | ||
847 | } | ||
848 | if (qnum >= ARRAY_SIZE(sc->tx.txq)) { | ||
849 | DPRINTF(sc, ATH_DBG_FATAL, | ||
850 | "qnum %u out of range, max %u!\n", | ||
851 | qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq)); | ||
852 | ath9k_hw_releasetxqueue(ah, qnum); | ||
853 | return NULL; | ||
854 | } | ||
855 | if (!ATH_TXQ_SETUP(sc, qnum)) { | ||
856 | struct ath_txq *txq = &sc->tx.txq[qnum]; | ||
857 | |||
858 | txq->axq_qnum = qnum; | ||
859 | txq->axq_link = NULL; | ||
860 | INIT_LIST_HEAD(&txq->axq_q); | ||
861 | INIT_LIST_HEAD(&txq->axq_acq); | ||
862 | spin_lock_init(&txq->axq_lock); | ||
863 | txq->axq_depth = 0; | ||
864 | txq->axq_aggr_depth = 0; | ||
865 | txq->axq_totalqueued = 0; | ||
866 | txq->axq_linkbuf = NULL; | ||
867 | sc->tx.txqsetup |= 1<<qnum; | ||
868 | } | ||
869 | return &sc->tx.txq[qnum]; | ||
870 | } | ||
871 | |||
872 | static int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype) | ||
873 | { | ||
874 | int qnum; | ||
875 | |||
876 | switch (qtype) { | ||
877 | case ATH9K_TX_QUEUE_DATA: | ||
878 | if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) { | ||
879 | DPRINTF(sc, ATH_DBG_FATAL, | ||
880 | "HAL AC %u out of range, max %zu!\n", | ||
881 | haltype, ARRAY_SIZE(sc->tx.hwq_map)); | ||
882 | return -1; | ||
883 | } | ||
884 | qnum = sc->tx.hwq_map[haltype]; | ||
885 | break; | ||
886 | case ATH9K_TX_QUEUE_BEACON: | ||
887 | qnum = sc->beacon.beaconq; | ||
888 | break; | ||
889 | case ATH9K_TX_QUEUE_CAB: | ||
890 | qnum = sc->beacon.cabq->axq_qnum; | ||
891 | break; | ||
892 | default: | ||
893 | qnum = -1; | ||
894 | } | ||
895 | return qnum; | ||
896 | } | ||
897 | |||
898 | struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) | ||
899 | { | ||
900 | struct ath_txq *txq = NULL; | ||
901 | int qnum; | ||
902 | |||
903 | qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc); | ||
904 | txq = &sc->tx.txq[qnum]; | ||
905 | |||
906 | spin_lock_bh(&txq->axq_lock); | ||
907 | |||
908 | if (txq->axq_depth >= (ATH_TXBUF - 20)) { | ||
909 | DPRINTF(sc, ATH_DBG_XMIT, | ||
910 | "TX queue: %d is full, depth: %d\n", | ||
911 | qnum, txq->axq_depth); | ||
912 | ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb)); | ||
913 | txq->stopped = 1; | ||
914 | spin_unlock_bh(&txq->axq_lock); | ||
915 | return NULL; | ||
916 | } | ||
917 | |||
918 | spin_unlock_bh(&txq->axq_lock); | ||
919 | |||
920 | return txq; | ||
921 | } | ||
922 | |||
923 | int ath_txq_update(struct ath_softc *sc, int qnum, | ||
924 | struct ath9k_tx_queue_info *qinfo) | ||
925 | { | ||
926 | struct ath_hw *ah = sc->sc_ah; | ||
927 | int error = 0; | ||
928 | struct ath9k_tx_queue_info qi; | ||
929 | |||
930 | if (qnum == sc->beacon.beaconq) { | ||
931 | /* | ||
932 | * XXX: for beacon queue, we just save the parameter. | ||
933 | * It will be picked up by ath_beaconq_config when | ||
934 | * it's necessary. | ||
935 | */ | ||
936 | sc->beacon.beacon_qi = *qinfo; | ||
937 | return 0; | ||
938 | } | ||
939 | |||
940 | ASSERT(sc->tx.txq[qnum].axq_qnum == qnum); | ||
941 | |||
942 | ath9k_hw_get_txq_props(ah, qnum, &qi); | ||
943 | qi.tqi_aifs = qinfo->tqi_aifs; | ||
944 | qi.tqi_cwmin = qinfo->tqi_cwmin; | ||
945 | qi.tqi_cwmax = qinfo->tqi_cwmax; | ||
946 | qi.tqi_burstTime = qinfo->tqi_burstTime; | ||
947 | qi.tqi_readyTime = qinfo->tqi_readyTime; | ||
948 | |||
949 | if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) { | ||
950 | DPRINTF(sc, ATH_DBG_FATAL, | ||
951 | "Unable to update hardware queue %u!\n", qnum); | ||
952 | error = -EIO; | ||
953 | } else { | ||
954 | ath9k_hw_resettxqueue(ah, qnum); | ||
955 | } | ||
956 | |||
957 | return error; | ||
958 | } | ||
959 | |||
960 | int ath_cabq_update(struct ath_softc *sc) | ||
961 | { | ||
962 | struct ath9k_tx_queue_info qi; | ||
963 | int qnum = sc->beacon.cabq->axq_qnum; | ||
964 | |||
965 | ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi); | ||
966 | /* | ||
967 | * Ensure the readytime % is within the bounds. | ||
968 | */ | ||
969 | if (sc->config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND) | ||
970 | sc->config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND; | ||
971 | else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND) | ||
972 | sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND; | ||
973 | |||
974 | qi.tqi_readyTime = (sc->hw->conf.beacon_int * | ||
975 | sc->config.cabqReadytime) / 100; | ||
976 | ath_txq_update(sc, qnum, &qi); | ||
977 | |||
978 | return 0; | ||
979 | } | ||
980 | |||
981 | /* | ||
982 | * Drain a given TX queue (could be Beacon or Data) | ||
983 | * | ||
984 | * This assumes output has been stopped and | ||
985 | * we do not need to block ath_tx_tasklet. | ||
986 | */ | ||
987 | void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | ||
988 | { | ||
989 | struct ath_buf *bf, *lastbf; | ||
990 | struct list_head bf_head; | ||
991 | |||
992 | INIT_LIST_HEAD(&bf_head); | ||
993 | |||
994 | for (;;) { | ||
995 | spin_lock_bh(&txq->axq_lock); | ||
996 | |||
997 | if (list_empty(&txq->axq_q)) { | ||
998 | txq->axq_link = NULL; | ||
999 | txq->axq_linkbuf = NULL; | ||
1000 | spin_unlock_bh(&txq->axq_lock); | ||
1001 | break; | ||
1002 | } | ||
1003 | |||
1004 | bf = list_first_entry(&txq->axq_q, struct ath_buf, list); | ||
1005 | |||
1006 | if (bf->bf_stale) { | ||
1007 | list_del(&bf->list); | ||
1008 | spin_unlock_bh(&txq->axq_lock); | ||
1009 | |||
1010 | spin_lock_bh(&sc->tx.txbuflock); | ||
1011 | list_add_tail(&bf->list, &sc->tx.txbuf); | ||
1012 | spin_unlock_bh(&sc->tx.txbuflock); | ||
1013 | continue; | ||
1014 | } | ||
1015 | |||
1016 | lastbf = bf->bf_lastbf; | ||
1017 | if (!retry_tx) | ||
1018 | lastbf->bf_desc->ds_txstat.ts_flags = | ||
1019 | ATH9K_TX_SW_ABORTED; | ||
1020 | |||
1021 | /* remove ath_buf's of the same mpdu from txq */ | ||
1022 | list_cut_position(&bf_head, &txq->axq_q, &lastbf->list); | ||
1023 | txq->axq_depth--; | ||
1024 | |||
1025 | spin_unlock_bh(&txq->axq_lock); | ||
1026 | |||
1027 | if (bf_isampdu(bf)) | ||
1028 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0); | ||
1029 | else | ||
1030 | ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); | ||
1031 | } | ||
1032 | |||
1033 | /* flush any pending frames if aggregation is enabled */ | ||
1034 | if (sc->sc_flags & SC_OP_TXAGGR) { | ||
1035 | if (!retry_tx) { | ||
1036 | spin_lock_bh(&txq->axq_lock); | ||
1037 | ath_txq_drain_pending_buffers(sc, txq); | ||
1038 | spin_unlock_bh(&txq->axq_lock); | ||
1039 | } | ||
1040 | } | ||
1041 | } | ||
1042 | |||
1043 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | ||
1044 | { | ||
1045 | struct ath_hw *ah = sc->sc_ah; | ||
1046 | struct ath_txq *txq; | ||
1047 | int i, npend = 0; | ||
1048 | |||
1049 | if (sc->sc_flags & SC_OP_INVALID) | ||
1050 | return; | ||
1051 | |||
1052 | /* Stop beacon queue */ | ||
1053 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
1054 | |||
1055 | /* Stop data queues */ | ||
1056 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
1057 | if (ATH_TXQ_SETUP(sc, i)) { | ||
1058 | txq = &sc->tx.txq[i]; | ||
1059 | ath9k_hw_stoptxdma(ah, txq->axq_qnum); | ||
1060 | npend += ath9k_hw_numtxpending(ah, txq->axq_qnum); | ||
1061 | } | ||
1062 | } | ||
1063 | |||
1064 | if (npend) { | ||
1065 | int r; | ||
1066 | |||
1067 | DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n"); | ||
1068 | |||
1069 | spin_lock_bh(&sc->sc_resetlock); | ||
1070 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true); | ||
1071 | if (r) | ||
1072 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1073 | "Unable to reset hardware; reset status %u\n", | ||
1074 | r); | ||
1075 | spin_unlock_bh(&sc->sc_resetlock); | ||
1076 | } | ||
1077 | |||
1078 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
1079 | if (ATH_TXQ_SETUP(sc, i)) | ||
1080 | ath_draintxq(sc, &sc->tx.txq[i], retry_tx); | ||
1081 | } | ||
1082 | } | ||
1083 | |||
1084 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) | ||
1085 | { | ||
1086 | ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum); | ||
1087 | sc->tx.txqsetup &= ~(1<<txq->axq_qnum); | ||
1088 | } | ||
1089 | |||
1090 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) | ||
1091 | { | ||
1092 | struct ath_atx_ac *ac; | ||
1093 | struct ath_atx_tid *tid; | ||
1094 | |||
1095 | if (list_empty(&txq->axq_acq)) | ||
1096 | return; | ||
1097 | |||
1098 | ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list); | ||
1099 | list_del(&ac->list); | ||
1100 | ac->sched = false; | ||
1101 | |||
1102 | do { | ||
1103 | if (list_empty(&ac->tid_q)) | ||
1104 | return; | ||
1105 | |||
1106 | tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list); | ||
1107 | list_del(&tid->list); | ||
1108 | tid->sched = false; | ||
1109 | |||
1110 | if (tid->paused) | ||
1111 | continue; | ||
1112 | |||
1113 | if ((txq->axq_depth % 2) == 0) | ||
1114 | ath_tx_sched_aggr(sc, txq, tid); | ||
1115 | |||
1116 | /* | ||
1117 | * add tid to round-robin queue if more frames | ||
1118 | * are pending for the tid | ||
1119 | */ | ||
1120 | if (!list_empty(&tid->buf_q)) | ||
1121 | ath_tx_queue_tid(txq, tid); | ||
1122 | |||
1123 | break; | ||
1124 | } while (!list_empty(&ac->tid_q)); | ||
1125 | |||
1126 | if (!list_empty(&ac->tid_q)) { | ||
1127 | if (!ac->sched) { | ||
1128 | ac->sched = true; | ||
1129 | list_add_tail(&ac->list, &txq->axq_acq); | ||
1130 | } | ||
1131 | } | ||
1132 | } | ||
1133 | |||
1134 | int ath_tx_setup(struct ath_softc *sc, int haltype) | ||
1135 | { | ||
1136 | struct ath_txq *txq; | ||
1137 | |||
1138 | if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) { | ||
1139 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1140 | "HAL AC %u out of range, max %zu!\n", | ||
1141 | haltype, ARRAY_SIZE(sc->tx.hwq_map)); | ||
1142 | return 0; | ||
1143 | } | ||
1144 | txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype); | ||
1145 | if (txq != NULL) { | ||
1146 | sc->tx.hwq_map[haltype] = txq->axq_qnum; | ||
1147 | return 1; | ||
1148 | } else | ||
1149 | return 0; | ||
1150 | } | ||
1151 | |||
1152 | /***********/ | ||
1153 | /* TX, DMA */ | ||
1154 | /***********/ | ||
1155 | |||
1156 | /* | ||
1157 | * Insert a chain of ath_buf (descriptors) on a txq and | ||
1158 | * assume the descriptors are already chained together by caller. | ||
1159 | */ | ||
1160 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | ||
1161 | struct list_head *head) | ||
1162 | { | ||
1163 | struct ath_hw *ah = sc->sc_ah; | ||
1164 | struct ath_buf *bf; | ||
1165 | |||
1166 | /* | ||
1167 | * Insert the frame on the outbound list and | ||
1168 | * pass it on to the hardware. | ||
1169 | */ | ||
1170 | |||
1171 | if (list_empty(head)) | ||
1172 | return; | ||
1173 | |||
1174 | bf = list_first_entry(head, struct ath_buf, list); | ||
1175 | |||
1176 | list_splice_tail_init(head, &txq->axq_q); | ||
1177 | txq->axq_depth++; | ||
1178 | txq->axq_totalqueued++; | ||
1179 | txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list); | ||
1180 | |||
1181 | DPRINTF(sc, ATH_DBG_QUEUE, | ||
1182 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); | ||
1183 | |||
1184 | if (txq->axq_link == NULL) { | ||
1185 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); | ||
1186 | DPRINTF(sc, ATH_DBG_XMIT, | ||
1187 | "TXDP[%u] = %llx (%p)\n", | ||
1188 | txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); | ||
1189 | } else { | ||
1190 | *txq->axq_link = bf->bf_daddr; | ||
1191 | DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n", | ||
1192 | txq->axq_qnum, txq->axq_link, | ||
1193 | ito64(bf->bf_daddr), bf->bf_desc); | ||
1194 | } | ||
1195 | txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link); | ||
1196 | ath9k_hw_txstart(ah, txq->axq_qnum); | ||
1197 | } | ||
1198 | |||
1199 | static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) | ||
1200 | { | ||
1201 | struct ath_buf *bf = NULL; | ||
1202 | |||
1203 | spin_lock_bh(&sc->tx.txbuflock); | ||
1204 | |||
1205 | if (unlikely(list_empty(&sc->tx.txbuf))) { | ||
1206 | spin_unlock_bh(&sc->tx.txbuflock); | ||
1207 | return NULL; | ||
1208 | } | ||
1209 | |||
1210 | bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); | ||
1211 | list_del(&bf->list); | ||
1212 | |||
1213 | spin_unlock_bh(&sc->tx.txbuflock); | ||
1214 | |||
1215 | return bf; | ||
1216 | } | ||
1217 | |||
1218 | static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | ||
1219 | struct list_head *bf_head, | ||
1220 | struct ath_tx_control *txctl) | ||
1221 | { | ||
1222 | struct ath_buf *bf; | ||
1223 | |||
1224 | bf = list_first_entry(bf_head, struct ath_buf, list); | ||
1225 | bf->bf_state.bf_type |= BUF_AMPDU; | ||
1226 | |||
1227 | /* | ||
1228 | * Do not queue to h/w when any of the following conditions is true: | ||
1229 | * - there are pending frames in software queue | ||
1230 | * - the TID is currently paused for ADDBA/BAR request | ||
1231 | * - seqno is not within block-ack window | ||
1232 | * - h/w queue depth exceeds low water mark | ||
1233 | */ | ||
1234 | if (!list_empty(&tid->buf_q) || tid->paused || | ||
1235 | !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) || | ||
1236 | txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) { | ||
1237 | /* | ||
1238 | * Add this frame to software queue for scheduling later | ||
1239 | * for aggregation. | ||
1240 | */ | ||
1241 | list_move_tail(&bf->list, &tid->buf_q); | ||
1242 | ath_tx_queue_tid(txctl->txq, tid); | ||
1243 | return; | ||
1244 | } | ||
1245 | |||
1246 | /* Add sub-frame to BAW */ | ||
1247 | ath_tx_addto_baw(sc, tid, bf); | ||
1248 | |||
1249 | /* Queue to h/w without aggregation */ | ||
1250 | bf->bf_nframes = 1; | ||
1251 | bf->bf_lastbf = bf; | ||
1252 | ath_buf_set_rate(sc, bf); | ||
1253 | ath_tx_txqaddbuf(sc, txctl->txq, bf_head); | ||
1254 | } | ||
1255 | |||
1256 | static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq, | ||
1257 | struct ath_atx_tid *tid, | ||
1258 | struct list_head *bf_head) | ||
1259 | { | ||
1260 | struct ath_buf *bf; | ||
1261 | |||
1262 | bf = list_first_entry(bf_head, struct ath_buf, list); | ||
1263 | bf->bf_state.bf_type &= ~BUF_AMPDU; | ||
1264 | |||
1265 | /* update starting sequence number for subsequent ADDBA request */ | ||
1266 | INCR(tid->seq_start, IEEE80211_SEQ_MAX); | ||
1267 | |||
1268 | bf->bf_nframes = 1; | ||
1269 | bf->bf_lastbf = bf; | ||
1270 | ath_buf_set_rate(sc, bf); | ||
1271 | ath_tx_txqaddbuf(sc, txq, bf_head); | ||
1272 | } | ||
1273 | |||
1274 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | ||
1275 | struct list_head *bf_head) | ||
1276 | { | ||
1277 | struct ath_buf *bf; | ||
1278 | |||
1279 | bf = list_first_entry(bf_head, struct ath_buf, list); | ||
1280 | |||
1281 | bf->bf_lastbf = bf; | ||
1282 | bf->bf_nframes = 1; | ||
1283 | ath_buf_set_rate(sc, bf); | ||
1284 | ath_tx_txqaddbuf(sc, txq, bf_head); | ||
1285 | } | ||
1286 | |||
1287 | static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) | ||
1288 | { | ||
1289 | struct ieee80211_hdr *hdr; | ||
1290 | enum ath9k_pkt_type htype; | ||
1291 | __le16 fc; | ||
1292 | |||
1293 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1294 | fc = hdr->frame_control; | ||
1295 | |||
1296 | if (ieee80211_is_beacon(fc)) | ||
1297 | htype = ATH9K_PKT_TYPE_BEACON; | ||
1298 | else if (ieee80211_is_probe_resp(fc)) | ||
1299 | htype = ATH9K_PKT_TYPE_PROBE_RESP; | ||
1300 | else if (ieee80211_is_atim(fc)) | ||
1301 | htype = ATH9K_PKT_TYPE_ATIM; | ||
1302 | else if (ieee80211_is_pspoll(fc)) | ||
1303 | htype = ATH9K_PKT_TYPE_PSPOLL; | ||
1304 | else | ||
1305 | htype = ATH9K_PKT_TYPE_NORMAL; | ||
1306 | |||
1307 | return htype; | ||
1308 | } | ||
1309 | |||
1310 | static bool is_pae(struct sk_buff *skb) | ||
1311 | { | ||
1312 | struct ieee80211_hdr *hdr; | ||
1313 | __le16 fc; | ||
1314 | |||
1315 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1316 | fc = hdr->frame_control; | ||
1317 | |||
1318 | if (ieee80211_is_data(fc)) { | ||
1319 | if (ieee80211_is_nullfunc(fc) || | ||
1320 | /* Port Access Entity (IEEE 802.1X) */ | ||
1321 | (skb->protocol == cpu_to_be16(ETH_P_PAE))) { | ||
1322 | return true; | ||
1323 | } | ||
1324 | } | ||
1325 | |||
1326 | return false; | ||
1327 | } | ||
1328 | |||
1329 | static int get_hw_crypto_keytype(struct sk_buff *skb) | ||
1330 | { | ||
1331 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1332 | |||
1333 | if (tx_info->control.hw_key) { | ||
1334 | if (tx_info->control.hw_key->alg == ALG_WEP) | ||
1335 | return ATH9K_KEY_TYPE_WEP; | ||
1336 | else if (tx_info->control.hw_key->alg == ALG_TKIP) | ||
1337 | return ATH9K_KEY_TYPE_TKIP; | ||
1338 | else if (tx_info->control.hw_key->alg == ALG_CCMP) | ||
1339 | return ATH9K_KEY_TYPE_AES; | ||
1340 | } | ||
1341 | |||
1342 | return ATH9K_KEY_TYPE_CLEAR; | ||
1343 | } | ||
1344 | |||
1345 | static void assign_aggr_tid_seqno(struct sk_buff *skb, | ||
1346 | struct ath_buf *bf) | ||
1347 | { | ||
1348 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1349 | struct ieee80211_hdr *hdr; | ||
1350 | struct ath_node *an; | ||
1351 | struct ath_atx_tid *tid; | ||
1352 | __le16 fc; | ||
1353 | u8 *qc; | ||
1354 | |||
1355 | if (!tx_info->control.sta) | ||
1356 | return; | ||
1357 | |||
1358 | an = (struct ath_node *)tx_info->control.sta->drv_priv; | ||
1359 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1360 | fc = hdr->frame_control; | ||
1361 | |||
1362 | if (ieee80211_is_data_qos(fc)) { | ||
1363 | qc = ieee80211_get_qos_ctl(hdr); | ||
1364 | bf->bf_tidno = qc[0] & 0xf; | ||
1365 | } | ||
1366 | |||
1367 | /* | ||
1368 | * For HT capable stations, we save tidno for later use. | ||
1369 | * We also override seqno set by upper layer with the one | ||
1370 | * in tx aggregation state. | ||
1371 | * | ||
1372 | * If fragmentation is on, the sequence number is | ||
1373 | * not overridden, since it has been | ||
1374 | * incremented by the fragmentation routine. | ||
1375 | * | ||
1376 | * FIXME: check if the fragmentation threshold exceeds | ||
1377 | * IEEE80211 max. | ||
1378 | */ | ||
1379 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | ||
1380 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << | ||
1381 | IEEE80211_SEQ_SEQ_SHIFT); | ||
1382 | bf->bf_seqno = tid->seq_next; | ||
1383 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | ||
1384 | } | ||
1385 | |||
1386 | static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb, | ||
1387 | struct ath_txq *txq) | ||
1388 | { | ||
1389 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1390 | int flags = 0; | ||
1391 | |||
1392 | flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ | ||
1393 | flags |= ATH9K_TXDESC_INTREQ; | ||
1394 | |||
1395 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) | ||
1396 | flags |= ATH9K_TXDESC_NOACK; | ||
1397 | |||
1398 | return flags; | ||
1399 | } | ||
1400 | |||
1401 | /* | ||
1402 | * rix - rate index | ||
1403 | * pktlen - total bytes (delims + data + fcs + pads + pad delims) | ||
1404 | * width - 0 for 20 MHz, 1 for 40 MHz | ||
1405 | * half_gi - to use 4us v/s 3.6 us for symbol time | ||
1406 | */ | ||
1407 | static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, | ||
1408 | int width, int half_gi, bool shortPreamble) | ||
1409 | { | ||
1410 | struct ath_rate_table *rate_table = sc->cur_rate_table; | ||
1411 | u32 nbits, nsymbits, duration, nsymbols; | ||
1412 | u8 rc; | ||
1413 | int streams, pktlen; | ||
1414 | |||
1415 | pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen; | ||
1416 | rc = rate_table->info[rix].ratecode; | ||
1417 | |||
1418 | /* for legacy rates, use old function to compute packet duration */ | ||
1419 | if (!IS_HT_RATE(rc)) | ||
1420 | return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen, | ||
1421 | rix, shortPreamble); | ||
1422 | |||
1423 | /* find number of symbols: PLCP + data */ | ||
1424 | nbits = (pktlen << 3) + OFDM_PLCP_BITS; | ||
1425 | nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width]; | ||
1426 | nsymbols = (nbits + nsymbits - 1) / nsymbits; | ||
1427 | |||
1428 | if (!half_gi) | ||
1429 | duration = SYMBOL_TIME(nsymbols); | ||
1430 | else | ||
1431 | duration = SYMBOL_TIME_HALFGI(nsymbols); | ||
1432 | |||
1433 | /* addup duration for legacy/ht training and signal fields */ | ||
1434 | streams = HT_RC_2_STREAMS(rc); | ||
1435 | duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); | ||
1436 | |||
1437 | return duration; | ||
1438 | } | ||
1439 | |||
1440 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | ||
1441 | { | ||
1442 | struct ath_rate_table *rt = sc->cur_rate_table; | ||
1443 | struct ath9k_11n_rate_series series[4]; | ||
1444 | struct sk_buff *skb; | ||
1445 | struct ieee80211_tx_info *tx_info; | ||
1446 | struct ieee80211_tx_rate *rates; | ||
1447 | struct ieee80211_hdr *hdr; | ||
1448 | int i, flags = 0; | ||
1449 | u8 rix = 0, ctsrate = 0; | ||
1450 | bool is_pspoll; | ||
1451 | |||
1452 | memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); | ||
1453 | |||
1454 | skb = bf->bf_mpdu; | ||
1455 | tx_info = IEEE80211_SKB_CB(skb); | ||
1456 | rates = tx_info->control.rates; | ||
1457 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1458 | is_pspoll = ieee80211_is_pspoll(hdr->frame_control); | ||
1459 | |||
1460 | /* | ||
1461 | * We check if Short Preamble is needed for the CTS rate by | ||
1462 | * checking the BSS's global flag. | ||
1463 | * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. | ||
1464 | */ | ||
1465 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) | ||
1466 | ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode | | ||
1467 | rt->info[tx_info->control.rts_cts_rate_idx].short_preamble; | ||
1468 | else | ||
1469 | ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode; | ||
1470 | |||
1471 | /* | ||
1472 | * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. | ||
1473 | * Check the first rate in the series to decide whether RTS/CTS | ||
1474 | * or CTS-to-self has to be used. | ||
1475 | */ | ||
1476 | if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) | ||
1477 | flags = ATH9K_TXDESC_CTSENA; | ||
1478 | else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) | ||
1479 | flags = ATH9K_TXDESC_RTSENA; | ||
1480 | |||
1481 | /* FIXME: Handle aggregation protection */ | ||
1482 | if (sc->config.ath_aggr_prot && | ||
1483 | (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) { | ||
1484 | flags = ATH9K_TXDESC_RTSENA; | ||
1485 | } | ||
1486 | |||
1487 | /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ | ||
1488 | if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit)) | ||
1489 | flags &= ~(ATH9K_TXDESC_RTSENA); | ||
1490 | |||
1491 | for (i = 0; i < 4; i++) { | ||
1492 | if (!rates[i].count || (rates[i].idx < 0)) | ||
1493 | continue; | ||
1494 | |||
1495 | rix = rates[i].idx; | ||
1496 | series[i].Tries = rates[i].count; | ||
1497 | series[i].ChSel = sc->tx_chainmask; | ||
1498 | |||
1499 | if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | ||
1500 | series[i].Rate = rt->info[rix].ratecode | | ||
1501 | rt->info[rix].short_preamble; | ||
1502 | else | ||
1503 | series[i].Rate = rt->info[rix].ratecode; | ||
1504 | |||
1505 | if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) | ||
1506 | series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; | ||
1507 | if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | ||
1508 | series[i].RateFlags |= ATH9K_RATESERIES_2040; | ||
1509 | if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) | ||
1510 | series[i].RateFlags |= ATH9K_RATESERIES_HALFGI; | ||
1511 | |||
1512 | series[i].PktDuration = ath_pkt_duration(sc, rix, bf, | ||
1513 | (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) != 0, | ||
1514 | (rates[i].flags & IEEE80211_TX_RC_SHORT_GI), | ||
1515 | (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)); | ||
1516 | } | ||
1517 | |||
1518 | /* set dur_update_en for l-sig computation except for PS-Poll frames */ | ||
1519 | ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc, | ||
1520 | bf->bf_lastbf->bf_desc, | ||
1521 | !is_pspoll, ctsrate, | ||
1522 | 0, series, 4, flags); | ||
1523 | |||
1524 | if (sc->config.ath_aggr_prot && flags) | ||
1525 | ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192); | ||
1526 | } | ||
1527 | |||
1528 | static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | ||
1529 | struct sk_buff *skb, | ||
1530 | struct ath_tx_control *txctl) | ||
1531 | { | ||
1532 | struct ath_wiphy *aphy = hw->priv; | ||
1533 | struct ath_softc *sc = aphy->sc; | ||
1534 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1535 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1536 | struct ath_tx_info_priv *tx_info_priv; | ||
1537 | int hdrlen; | ||
1538 | __le16 fc; | ||
1539 | |||
1540 | tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC); | ||
1541 | if (unlikely(!tx_info_priv)) | ||
1542 | return -ENOMEM; | ||
1543 | tx_info->rate_driver_data[0] = tx_info_priv; | ||
1544 | tx_info_priv->aphy = aphy; | ||
1545 | tx_info_priv->frame_type = txctl->frame_type; | ||
1546 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
1547 | fc = hdr->frame_control; | ||
1548 | |||
1549 | ATH_TXBUF_RESET(bf); | ||
1550 | |||
1551 | bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); | ||
1552 | |||
1553 | if (conf_is_ht(&sc->hw->conf) && !is_pae(skb)) | ||
1554 | bf->bf_state.bf_type |= BUF_HT; | ||
1555 | |||
1556 | bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq); | ||
1557 | |||
1558 | bf->bf_keytype = get_hw_crypto_keytype(skb); | ||
1559 | if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) { | ||
1560 | bf->bf_frmlen += tx_info->control.hw_key->icv_len; | ||
1561 | bf->bf_keyix = tx_info->control.hw_key->hw_key_idx; | ||
1562 | } else { | ||
1563 | bf->bf_keyix = ATH9K_TXKEYIX_INVALID; | ||
1564 | } | ||
1565 | |||
1566 | if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR)) | ||
1567 | assign_aggr_tid_seqno(skb, bf); | ||
1568 | |||
1569 | bf->bf_mpdu = skb; | ||
1570 | |||
1571 | bf->bf_dmacontext = dma_map_single(sc->dev, skb->data, | ||
1572 | skb->len, DMA_TO_DEVICE); | ||
1573 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) { | ||
1574 | bf->bf_mpdu = NULL; | ||
1575 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
1576 | "dma_mapping_error() on TX\n"); | ||
1577 | return -ENOMEM; | ||
1578 | } | ||
1579 | |||
1580 | bf->bf_buf_addr = bf->bf_dmacontext; | ||
1581 | return 0; | ||
1582 | } | ||
1583 | |||
1584 | /* FIXME: tx power */ | ||
1585 | static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | ||
1586 | struct ath_tx_control *txctl) | ||
1587 | { | ||
1588 | struct sk_buff *skb = bf->bf_mpdu; | ||
1589 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1590 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1591 | struct ath_node *an = NULL; | ||
1592 | struct list_head bf_head; | ||
1593 | struct ath_desc *ds; | ||
1594 | struct ath_atx_tid *tid; | ||
1595 | struct ath_hw *ah = sc->sc_ah; | ||
1596 | int frm_type; | ||
1597 | __le16 fc; | ||
1598 | |||
1599 | frm_type = get_hw_packet_type(skb); | ||
1600 | fc = hdr->frame_control; | ||
1601 | |||
1602 | INIT_LIST_HEAD(&bf_head); | ||
1603 | list_add_tail(&bf->list, &bf_head); | ||
1604 | |||
1605 | ds = bf->bf_desc; | ||
1606 | ds->ds_link = 0; | ||
1607 | ds->ds_data = bf->bf_buf_addr; | ||
1608 | |||
1609 | ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER, | ||
1610 | bf->bf_keyix, bf->bf_keytype, bf->bf_flags); | ||
1611 | |||
1612 | ath9k_hw_filltxdesc(ah, ds, | ||
1613 | skb->len, /* segment length */ | ||
1614 | true, /* first segment */ | ||
1615 | true, /* last segment */ | ||
1616 | ds); /* first descriptor */ | ||
1617 | |||
1618 | spin_lock_bh(&txctl->txq->axq_lock); | ||
1619 | |||
1620 | if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) && | ||
1621 | tx_info->control.sta) { | ||
1622 | an = (struct ath_node *)tx_info->control.sta->drv_priv; | ||
1623 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | ||
1624 | |||
1625 | if (!ieee80211_is_data_qos(fc)) { | ||
1626 | ath_tx_send_normal(sc, txctl->txq, &bf_head); | ||
1627 | goto tx_done; | ||
1628 | } | ||
1629 | |||
1630 | if (ath_aggr_query(sc, an, bf->bf_tidno)) { | ||
1631 | /* | ||
1632 | * Try aggregation if it's a unicast data frame | ||
1633 | * and the destination is HT capable. | ||
1634 | */ | ||
1635 | ath_tx_send_ampdu(sc, tid, &bf_head, txctl); | ||
1636 | } else { | ||
1637 | /* | ||
1638 | * Send this frame as regular when ADDBA | ||
1639 | * exchange is neither complete nor pending. | ||
1640 | */ | ||
1641 | ath_tx_send_ht_normal(sc, txctl->txq, | ||
1642 | tid, &bf_head); | ||
1643 | } | ||
1644 | } else { | ||
1645 | ath_tx_send_normal(sc, txctl->txq, &bf_head); | ||
1646 | } | ||
1647 | |||
1648 | tx_done: | ||
1649 | spin_unlock_bh(&txctl->txq->axq_lock); | ||
1650 | } | ||
1651 | |||
1652 | /* Upon failure caller should free skb */ | ||
1653 | int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
1654 | struct ath_tx_control *txctl) | ||
1655 | { | ||
1656 | struct ath_wiphy *aphy = hw->priv; | ||
1657 | struct ath_softc *sc = aphy->sc; | ||
1658 | struct ath_buf *bf; | ||
1659 | int r; | ||
1660 | |||
1661 | bf = ath_tx_get_buffer(sc); | ||
1662 | if (!bf) { | ||
1663 | DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n"); | ||
1664 | return -1; | ||
1665 | } | ||
1666 | |||
1667 | r = ath_tx_setup_buffer(hw, bf, skb, txctl); | ||
1668 | if (unlikely(r)) { | ||
1669 | struct ath_txq *txq = txctl->txq; | ||
1670 | |||
1671 | DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n"); | ||
1672 | |||
1673 | /* upon ath_tx_processq() this TX queue will be resumed, we | ||
1674 | * guarantee this will happen by knowing beforehand that | ||
1675 | * we will at least have to run TX completionon one buffer | ||
1676 | * on the queue */ | ||
1677 | spin_lock_bh(&txq->axq_lock); | ||
1678 | if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) { | ||
1679 | ieee80211_stop_queue(sc->hw, | ||
1680 | skb_get_queue_mapping(skb)); | ||
1681 | txq->stopped = 1; | ||
1682 | } | ||
1683 | spin_unlock_bh(&txq->axq_lock); | ||
1684 | |||
1685 | spin_lock_bh(&sc->tx.txbuflock); | ||
1686 | list_add_tail(&bf->list, &sc->tx.txbuf); | ||
1687 | spin_unlock_bh(&sc->tx.txbuflock); | ||
1688 | |||
1689 | return r; | ||
1690 | } | ||
1691 | |||
1692 | ath_tx_start_dma(sc, bf, txctl); | ||
1693 | |||
1694 | return 0; | ||
1695 | } | ||
1696 | |||
1697 | void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1698 | { | ||
1699 | struct ath_wiphy *aphy = hw->priv; | ||
1700 | struct ath_softc *sc = aphy->sc; | ||
1701 | int hdrlen, padsize; | ||
1702 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1703 | struct ath_tx_control txctl; | ||
1704 | |||
1705 | memset(&txctl, 0, sizeof(struct ath_tx_control)); | ||
1706 | |||
1707 | /* | ||
1708 | * As a temporary workaround, assign seq# here; this will likely need | ||
1709 | * to be cleaned up to work better with Beacon transmission and virtual | ||
1710 | * BSSes. | ||
1711 | */ | ||
1712 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
1713 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
1714 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | ||
1715 | sc->tx.seq_no += 0x10; | ||
1716 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
1717 | hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); | ||
1718 | } | ||
1719 | |||
1720 | /* Add the padding after the header if this is not already done */ | ||
1721 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
1722 | if (hdrlen & 3) { | ||
1723 | padsize = hdrlen % 4; | ||
1724 | if (skb_headroom(skb) < padsize) { | ||
1725 | DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n"); | ||
1726 | dev_kfree_skb_any(skb); | ||
1727 | return; | ||
1728 | } | ||
1729 | skb_push(skb, padsize); | ||
1730 | memmove(skb->data, skb->data + padsize, hdrlen); | ||
1731 | } | ||
1732 | |||
1733 | txctl.txq = sc->beacon.cabq; | ||
1734 | |||
1735 | DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb); | ||
1736 | |||
1737 | if (ath_tx_start(hw, skb, &txctl) != 0) { | ||
1738 | DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n"); | ||
1739 | goto exit; | ||
1740 | } | ||
1741 | |||
1742 | return; | ||
1743 | exit: | ||
1744 | dev_kfree_skb_any(skb); | ||
1745 | } | ||
1746 | |||
1747 | /*****************/ | ||
1748 | /* TX Completion */ | ||
1749 | /*****************/ | ||
1750 | |||
1751 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | ||
1752 | int tx_flags) | ||
1753 | { | ||
1754 | struct ieee80211_hw *hw = sc->hw; | ||
1755 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1756 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
1757 | int hdrlen, padsize; | ||
1758 | int frame_type = ATH9K_NOT_INTERNAL; | ||
1759 | |||
1760 | DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); | ||
1761 | |||
1762 | if (tx_info_priv) { | ||
1763 | hw = tx_info_priv->aphy->hw; | ||
1764 | frame_type = tx_info_priv->frame_type; | ||
1765 | } | ||
1766 | |||
1767 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || | ||
1768 | tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | ||
1769 | kfree(tx_info_priv); | ||
1770 | tx_info->rate_driver_data[0] = NULL; | ||
1771 | } | ||
1772 | |||
1773 | if (tx_flags & ATH_TX_BAR) | ||
1774 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | ||
1775 | |||
1776 | if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) { | ||
1777 | /* Frame was ACKed */ | ||
1778 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | ||
1779 | } | ||
1780 | |||
1781 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
1782 | padsize = hdrlen & 3; | ||
1783 | if (padsize && hdrlen >= 24) { | ||
1784 | /* | ||
1785 | * Remove MAC header padding before giving the frame back to | ||
1786 | * mac80211. | ||
1787 | */ | ||
1788 | memmove(skb->data + padsize, skb->data, hdrlen); | ||
1789 | skb_pull(skb, padsize); | ||
1790 | } | ||
1791 | |||
1792 | if (frame_type == ATH9K_NOT_INTERNAL) | ||
1793 | ieee80211_tx_status(hw, skb); | ||
1794 | else | ||
1795 | ath9k_tx_status(hw, skb); | ||
1796 | } | ||
1797 | |||
1798 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | ||
1799 | struct list_head *bf_q, | ||
1800 | int txok, int sendbar) | ||
1801 | { | ||
1802 | struct sk_buff *skb = bf->bf_mpdu; | ||
1803 | unsigned long flags; | ||
1804 | int tx_flags = 0; | ||
1805 | |||
1806 | |||
1807 | if (sendbar) | ||
1808 | tx_flags = ATH_TX_BAR; | ||
1809 | |||
1810 | if (!txok) { | ||
1811 | tx_flags |= ATH_TX_ERROR; | ||
1812 | |||
1813 | if (bf_isxretried(bf)) | ||
1814 | tx_flags |= ATH_TX_XRETRY; | ||
1815 | } | ||
1816 | |||
1817 | dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); | ||
1818 | ath_tx_complete(sc, skb, tx_flags); | ||
1819 | |||
1820 | /* | ||
1821 | * Return the list of ath_buf of this mpdu to free queue | ||
1822 | */ | ||
1823 | spin_lock_irqsave(&sc->tx.txbuflock, flags); | ||
1824 | list_splice_tail_init(bf_q, &sc->tx.txbuf); | ||
1825 | spin_unlock_irqrestore(&sc->tx.txbuflock, flags); | ||
1826 | } | ||
1827 | |||
1828 | static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, | ||
1829 | int txok) | ||
1830 | { | ||
1831 | struct ath_buf *bf_last = bf->bf_lastbf; | ||
1832 | struct ath_desc *ds = bf_last->bf_desc; | ||
1833 | u16 seq_st = 0; | ||
1834 | u32 ba[WME_BA_BMP_SIZE >> 5]; | ||
1835 | int ba_index; | ||
1836 | int nbad = 0; | ||
1837 | int isaggr = 0; | ||
1838 | |||
1839 | if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED) | ||
1840 | return 0; | ||
1841 | |||
1842 | isaggr = bf_isaggr(bf); | ||
1843 | if (isaggr) { | ||
1844 | seq_st = ATH_DS_BA_SEQ(ds); | ||
1845 | memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3); | ||
1846 | } | ||
1847 | |||
1848 | while (bf) { | ||
1849 | ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno); | ||
1850 | if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index))) | ||
1851 | nbad++; | ||
1852 | |||
1853 | bf = bf->bf_next; | ||
1854 | } | ||
1855 | |||
1856 | return nbad; | ||
1857 | } | ||
1858 | |||
1859 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | ||
1860 | int nbad, int txok, bool update_rc) | ||
1861 | { | ||
1862 | struct sk_buff *skb = bf->bf_mpdu; | ||
1863 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1864 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1865 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
1866 | struct ieee80211_hw *hw = tx_info_priv->aphy->hw; | ||
1867 | u8 i, tx_rateindex; | ||
1868 | |||
1869 | if (txok) | ||
1870 | tx_info->status.ack_signal = ds->ds_txstat.ts_rssi; | ||
1871 | |||
1872 | tx_rateindex = ds->ds_txstat.ts_rateindex; | ||
1873 | WARN_ON(tx_rateindex >= hw->max_rates); | ||
1874 | |||
1875 | tx_info_priv->update_rc = update_rc; | ||
1876 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) | ||
1877 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | ||
1878 | |||
1879 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && | ||
1880 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { | ||
1881 | if (ieee80211_is_data(hdr->frame_control)) { | ||
1882 | memcpy(&tx_info_priv->tx, &ds->ds_txstat, | ||
1883 | sizeof(tx_info_priv->tx)); | ||
1884 | tx_info_priv->n_frames = bf->bf_nframes; | ||
1885 | tx_info_priv->n_bad_frames = nbad; | ||
1886 | } | ||
1887 | } | ||
1888 | |||
1889 | for (i = tx_rateindex + 1; i < hw->max_rates; i++) | ||
1890 | tx_info->status.rates[i].count = 0; | ||
1891 | |||
1892 | tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1; | ||
1893 | } | ||
1894 | |||
1895 | static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) | ||
1896 | { | ||
1897 | int qnum; | ||
1898 | |||
1899 | spin_lock_bh(&txq->axq_lock); | ||
1900 | if (txq->stopped && | ||
1901 | sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) { | ||
1902 | qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc); | ||
1903 | if (qnum != -1) { | ||
1904 | ieee80211_wake_queue(sc->hw, qnum); | ||
1905 | txq->stopped = 0; | ||
1906 | } | ||
1907 | } | ||
1908 | spin_unlock_bh(&txq->axq_lock); | ||
1909 | } | ||
1910 | |||
1911 | static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | ||
1912 | { | ||
1913 | struct ath_hw *ah = sc->sc_ah; | ||
1914 | struct ath_buf *bf, *lastbf, *bf_held = NULL; | ||
1915 | struct list_head bf_head; | ||
1916 | struct ath_desc *ds; | ||
1917 | int txok; | ||
1918 | int status; | ||
1919 | |||
1920 | DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", | ||
1921 | txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), | ||
1922 | txq->axq_link); | ||
1923 | |||
1924 | for (;;) { | ||
1925 | spin_lock_bh(&txq->axq_lock); | ||
1926 | if (list_empty(&txq->axq_q)) { | ||
1927 | txq->axq_link = NULL; | ||
1928 | txq->axq_linkbuf = NULL; | ||
1929 | spin_unlock_bh(&txq->axq_lock); | ||
1930 | break; | ||
1931 | } | ||
1932 | bf = list_first_entry(&txq->axq_q, struct ath_buf, list); | ||
1933 | |||
1934 | /* | ||
1935 | * There is a race condition that a BH gets scheduled | ||
1936 | * after sw writes TxE and before hw re-load the last | ||
1937 | * descriptor to get the newly chained one. | ||
1938 | * Software must keep the last DONE descriptor as a | ||
1939 | * holding descriptor - software does so by marking | ||
1940 | * it with the STALE flag. | ||
1941 | */ | ||
1942 | bf_held = NULL; | ||
1943 | if (bf->bf_stale) { | ||
1944 | bf_held = bf; | ||
1945 | if (list_is_last(&bf_held->list, &txq->axq_q)) { | ||
1946 | txq->axq_link = NULL; | ||
1947 | txq->axq_linkbuf = NULL; | ||
1948 | spin_unlock_bh(&txq->axq_lock); | ||
1949 | |||
1950 | /* | ||
1951 | * The holding descriptor is the last | ||
1952 | * descriptor in queue. It's safe to remove | ||
1953 | * the last holding descriptor in BH context. | ||
1954 | */ | ||
1955 | spin_lock_bh(&sc->tx.txbuflock); | ||
1956 | list_move_tail(&bf_held->list, &sc->tx.txbuf); | ||
1957 | spin_unlock_bh(&sc->tx.txbuflock); | ||
1958 | |||
1959 | break; | ||
1960 | } else { | ||
1961 | bf = list_entry(bf_held->list.next, | ||
1962 | struct ath_buf, list); | ||
1963 | } | ||
1964 | } | ||
1965 | |||
1966 | lastbf = bf->bf_lastbf; | ||
1967 | ds = lastbf->bf_desc; | ||
1968 | |||
1969 | status = ath9k_hw_txprocdesc(ah, ds); | ||
1970 | if (status == -EINPROGRESS) { | ||
1971 | spin_unlock_bh(&txq->axq_lock); | ||
1972 | break; | ||
1973 | } | ||
1974 | if (bf->bf_desc == txq->axq_lastdsWithCTS) | ||
1975 | txq->axq_lastdsWithCTS = NULL; | ||
1976 | if (ds == txq->axq_gatingds) | ||
1977 | txq->axq_gatingds = NULL; | ||
1978 | |||
1979 | /* | ||
1980 | * Remove ath_buf's of the same transmit unit from txq, | ||
1981 | * however leave the last descriptor back as the holding | ||
1982 | * descriptor for hw. | ||
1983 | */ | ||
1984 | lastbf->bf_stale = true; | ||
1985 | INIT_LIST_HEAD(&bf_head); | ||
1986 | if (!list_is_singular(&lastbf->list)) | ||
1987 | list_cut_position(&bf_head, | ||
1988 | &txq->axq_q, lastbf->list.prev); | ||
1989 | |||
1990 | txq->axq_depth--; | ||
1991 | if (bf_isaggr(bf)) | ||
1992 | txq->axq_aggr_depth--; | ||
1993 | |||
1994 | txok = (ds->ds_txstat.ts_status == 0); | ||
1995 | spin_unlock_bh(&txq->axq_lock); | ||
1996 | |||
1997 | if (bf_held) { | ||
1998 | spin_lock_bh(&sc->tx.txbuflock); | ||
1999 | list_move_tail(&bf_held->list, &sc->tx.txbuf); | ||
2000 | spin_unlock_bh(&sc->tx.txbuflock); | ||
2001 | } | ||
2002 | |||
2003 | if (!bf_isampdu(bf)) { | ||
2004 | /* | ||
2005 | * This frame is sent out as a single frame. | ||
2006 | * Use hardware retry status for this frame. | ||
2007 | */ | ||
2008 | bf->bf_retries = ds->ds_txstat.ts_longretry; | ||
2009 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) | ||
2010 | bf->bf_state.bf_type |= BUF_XRETRY; | ||
2011 | ath_tx_rc_status(bf, ds, 0, txok, true); | ||
2012 | } | ||
2013 | |||
2014 | if (bf_isampdu(bf)) | ||
2015 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok); | ||
2016 | else | ||
2017 | ath_tx_complete_buf(sc, bf, &bf_head, txok, 0); | ||
2018 | |||
2019 | ath_wake_mac80211_queue(sc, txq); | ||
2020 | |||
2021 | spin_lock_bh(&txq->axq_lock); | ||
2022 | if (sc->sc_flags & SC_OP_TXAGGR) | ||
2023 | ath_txq_schedule(sc, txq); | ||
2024 | spin_unlock_bh(&txq->axq_lock); | ||
2025 | } | ||
2026 | } | ||
2027 | |||
2028 | |||
2029 | void ath_tx_tasklet(struct ath_softc *sc) | ||
2030 | { | ||
2031 | int i; | ||
2032 | u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1); | ||
2033 | |||
2034 | ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask); | ||
2035 | |||
2036 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
2037 | if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i))) | ||
2038 | ath_tx_processq(sc, &sc->tx.txq[i]); | ||
2039 | } | ||
2040 | } | ||
2041 | |||
2042 | /*****************/ | ||
2043 | /* Init, Cleanup */ | ||
2044 | /*****************/ | ||
2045 | |||
2046 | int ath_tx_init(struct ath_softc *sc, int nbufs) | ||
2047 | { | ||
2048 | int error = 0; | ||
2049 | |||
2050 | spin_lock_init(&sc->tx.txbuflock); | ||
2051 | |||
2052 | error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf, | ||
2053 | "tx", nbufs, 1); | ||
2054 | if (error != 0) { | ||
2055 | DPRINTF(sc, ATH_DBG_FATAL, | ||
2056 | "Failed to allocate tx descriptors: %d\n", error); | ||
2057 | goto err; | ||
2058 | } | ||
2059 | |||
2060 | error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, | ||
2061 | "beacon", ATH_BCBUF, 1); | ||
2062 | if (error != 0) { | ||
2063 | DPRINTF(sc, ATH_DBG_FATAL, | ||
2064 | "Failed to allocate beacon descriptors: %d\n", error); | ||
2065 | goto err; | ||
2066 | } | ||
2067 | |||
2068 | err: | ||
2069 | if (error != 0) | ||
2070 | ath_tx_cleanup(sc); | ||
2071 | |||
2072 | return error; | ||
2073 | } | ||
2074 | |||
2075 | void ath_tx_cleanup(struct ath_softc *sc) | ||
2076 | { | ||
2077 | if (sc->beacon.bdma.dd_desc_len != 0) | ||
2078 | ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf); | ||
2079 | |||
2080 | if (sc->tx.txdma.dd_desc_len != 0) | ||
2081 | ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf); | ||
2082 | } | ||
2083 | |||
2084 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | ||
2085 | { | ||
2086 | struct ath_atx_tid *tid; | ||
2087 | struct ath_atx_ac *ac; | ||
2088 | int tidno, acno; | ||
2089 | |||
2090 | for (tidno = 0, tid = &an->tid[tidno]; | ||
2091 | tidno < WME_NUM_TID; | ||
2092 | tidno++, tid++) { | ||
2093 | tid->an = an; | ||
2094 | tid->tidno = tidno; | ||
2095 | tid->seq_start = tid->seq_next = 0; | ||
2096 | tid->baw_size = WME_MAX_BA; | ||
2097 | tid->baw_head = tid->baw_tail = 0; | ||
2098 | tid->sched = false; | ||
2099 | tid->paused = false; | ||
2100 | tid->state &= ~AGGR_CLEANUP; | ||
2101 | INIT_LIST_HEAD(&tid->buf_q); | ||
2102 | acno = TID_TO_WME_AC(tidno); | ||
2103 | tid->ac = &an->ac[acno]; | ||
2104 | tid->state &= ~AGGR_ADDBA_COMPLETE; | ||
2105 | tid->state &= ~AGGR_ADDBA_PROGRESS; | ||
2106 | tid->addba_exchangeattempts = 0; | ||
2107 | } | ||
2108 | |||
2109 | for (acno = 0, ac = &an->ac[acno]; | ||
2110 | acno < WME_NUM_AC; acno++, ac++) { | ||
2111 | ac->sched = false; | ||
2112 | INIT_LIST_HEAD(&ac->tid_q); | ||
2113 | |||
2114 | switch (acno) { | ||
2115 | case WME_AC_BE: | ||
2116 | ac->qnum = ath_tx_get_qnum(sc, | ||
2117 | ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); | ||
2118 | break; | ||
2119 | case WME_AC_BK: | ||
2120 | ac->qnum = ath_tx_get_qnum(sc, | ||
2121 | ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK); | ||
2122 | break; | ||
2123 | case WME_AC_VI: | ||
2124 | ac->qnum = ath_tx_get_qnum(sc, | ||
2125 | ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI); | ||
2126 | break; | ||
2127 | case WME_AC_VO: | ||
2128 | ac->qnum = ath_tx_get_qnum(sc, | ||
2129 | ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO); | ||
2130 | break; | ||
2131 | } | ||
2132 | } | ||
2133 | } | ||
2134 | |||
2135 | void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | ||
2136 | { | ||
2137 | int i; | ||
2138 | struct ath_atx_ac *ac, *ac_tmp; | ||
2139 | struct ath_atx_tid *tid, *tid_tmp; | ||
2140 | struct ath_txq *txq; | ||
2141 | |||
2142 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
2143 | if (ATH_TXQ_SETUP(sc, i)) { | ||
2144 | txq = &sc->tx.txq[i]; | ||
2145 | |||
2146 | spin_lock(&txq->axq_lock); | ||
2147 | |||
2148 | list_for_each_entry_safe(ac, | ||
2149 | ac_tmp, &txq->axq_acq, list) { | ||
2150 | tid = list_first_entry(&ac->tid_q, | ||
2151 | struct ath_atx_tid, list); | ||
2152 | if (tid && tid->an != an) | ||
2153 | continue; | ||
2154 | list_del(&ac->list); | ||
2155 | ac->sched = false; | ||
2156 | |||
2157 | list_for_each_entry_safe(tid, | ||
2158 | tid_tmp, &ac->tid_q, list) { | ||
2159 | list_del(&tid->list); | ||
2160 | tid->sched = false; | ||
2161 | ath_tid_drain(sc, txq, tid); | ||
2162 | tid->state &= ~AGGR_ADDBA_COMPLETE; | ||
2163 | tid->addba_exchangeattempts = 0; | ||
2164 | tid->state &= ~AGGR_CLEANUP; | ||
2165 | } | ||
2166 | } | ||
2167 | |||
2168 | spin_unlock(&txq->axq_lock); | ||
2169 | } | ||
2170 | } | ||
2171 | } | ||