aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath5k
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath5k')
-rw-r--r--drivers/net/wireless/ath/ath5k/Kconfig29
-rw-r--r--drivers/net/wireless/ath/ath5k/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath5k/ahb.c248
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.c87
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.h7
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h384
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c80
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c2808
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h64
-rw-r--r--drivers/net/wireless/ath/ath5k/caps.c57
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c227
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h42
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.c199
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.h18
-rw-r--r--drivers/net/wireless/ath/ath5k/dma.c188
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c255
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h30
-rw-r--r--drivers/net/wireless/ath/ath5k/initvals.c409
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c11
-rw-r--r--drivers/net/wireless/ath/ath5k/mac80211-ops.c833
-rw-r--r--drivers/net/wireless/ath/ath5k/pci.c363
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c829
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c833
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c777
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h138
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c1233
-rw-r--r--drivers/net/wireless/ath/ath5k/rfbuffer.h1173
-rw-r--r--drivers/net/wireless/ath/ath5k/sysfs.c13
-rw-r--r--drivers/net/wireless/ath/ath5k/trace.h107
29 files changed, 6387 insertions, 5058 deletions
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index eb83b7b4d0e3..e18a9aa7b6ca 100644
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -1,9 +1,12 @@
1config ATH5K 1config ATH5K
2 tristate "Atheros 5xxx wireless cards support" 2 tristate "Atheros 5xxx wireless cards support"
3 depends on PCI && MAC80211 3 depends on (PCI || ATHEROS_AR231X) && MAC80211
4 select MAC80211_LEDS 4 select MAC80211_LEDS
5 select LEDS_CLASS 5 select LEDS_CLASS
6 select NEW_LEDS 6 select NEW_LEDS
7 select AVERAGE
8 select ATH5K_AHB if (ATHEROS_AR231X && !PCI)
9 select ATH5K_PCI if (!ATHEROS_AR231X && PCI)
7 ---help--- 10 ---help---
8 This module adds support for wireless adapters based on 11 This module adds support for wireless adapters based on
9 Atheros 5xxx chipset. 12 Atheros 5xxx chipset.
@@ -37,3 +40,27 @@ config ATH5K_DEBUG
37 40
38 modprobe ath5k debug=0x00000400 41 modprobe ath5k debug=0x00000400
39 42
43config ATH5K_TRACER
44 bool "Atheros 5xxx tracer"
45 depends on ATH5K
46 depends on EVENT_TRACING
47 ---help---
48 Say Y here to enable tracepoints for the ath5k driver
49 using the kernel tracing infrastructure. Select this
50 option if you are interested in debugging the driver.
51
52 If unsure, say N.
53
54config ATH5K_AHB
55 bool "Atheros 5xxx AHB bus support"
56 depends on (ATHEROS_AR231X && !PCI)
57 ---help---
58 This adds support for WiSoC type chipsets of the 5xxx Atheros
59 family.
60
61config ATH5K_PCI
62 bool "Atheros 5xxx PCI bus support"
63 depends on (!ATHEROS_AR231X && PCI)
64 ---help---
65 This adds support for PCI type chipsets of the 5xxx Atheros
66 family.
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
index 2242a140e4fe..f60b3899afc4 100644
--- a/drivers/net/wireless/ath/ath5k/Makefile
+++ b/drivers/net/wireless/ath/ath5k/Makefile
@@ -14,5 +14,8 @@ ath5k-y += led.o
14ath5k-y += rfkill.o 14ath5k-y += rfkill.o
15ath5k-y += ani.o 15ath5k-y += ani.o
16ath5k-y += sysfs.o 16ath5k-y += sysfs.o
17ath5k-y += mac80211-ops.o
17ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o 18ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
19ath5k-$(CONFIG_ATH5K_AHB) += ahb.o
20ath5k-$(CONFIG_ATH5K_PCI) += pci.o
18obj-$(CONFIG_ATH5K) += ath5k.o 21obj-$(CONFIG_ATH5K) += ath5k.o
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c
new file mode 100644
index 000000000000..ea9982781559
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/ahb.c
@@ -0,0 +1,248 @@
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/etherdevice.h>
22#include <ar231x_platform.h>
23#include "ath5k.h"
24#include "debug.h"
25#include "base.h"
26#include "reg.h"
27#include "debug.h"
28
29/* return bus cachesize in 4B word units */
30static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz)
31{
32 *csz = L1_CACHE_BYTES >> 2;
33}
34
35static bool
36ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
37{
38 struct ath5k_softc *sc = common->priv;
39 struct platform_device *pdev = to_platform_device(sc->dev);
40 struct ar231x_board_config *bcfg = pdev->dev.platform_data;
41 u16 *eeprom, *eeprom_end;
42
43
44
45 bcfg = pdev->dev.platform_data;
46 eeprom = (u16 *) bcfg->radio;
47 eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ;
48
49 eeprom += off;
50 if (eeprom > eeprom_end)
51 return false;
52
53 *data = *eeprom;
54 return true;
55}
56
57int ath5k_hw_read_srev(struct ath5k_hw *ah)
58{
59 struct ath5k_softc *sc = ah->ah_sc;
60 struct platform_device *pdev = to_platform_device(sc->dev);
61 struct ar231x_board_config *bcfg = pdev->dev.platform_data;
62 ah->ah_mac_srev = bcfg->devid;
63 return 0;
64}
65
66static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
67{
68 struct ath5k_softc *sc = ah->ah_sc;
69 struct platform_device *pdev = to_platform_device(sc->dev);
70 struct ar231x_board_config *bcfg = pdev->dev.platform_data;
71 u8 *cfg_mac;
72
73 if (to_platform_device(sc->dev)->id == 0)
74 cfg_mac = bcfg->config->wlan0_mac;
75 else
76 cfg_mac = bcfg->config->wlan1_mac;
77
78 memcpy(mac, cfg_mac, ETH_ALEN);
79 return 0;
80}
81
82static const struct ath_bus_ops ath_ahb_bus_ops = {
83 .ath_bus_type = ATH_AHB,
84 .read_cachesize = ath5k_ahb_read_cachesize,
85 .eeprom_read = ath5k_ahb_eeprom_read,
86 .eeprom_read_mac = ath5k_ahb_eeprom_read_mac,
87};
88
89/*Initialization*/
90static int ath_ahb_probe(struct platform_device *pdev)
91{
92 struct ar231x_board_config *bcfg = pdev->dev.platform_data;
93 struct ath5k_softc *sc;
94 struct ieee80211_hw *hw;
95 struct resource *res;
96 void __iomem *mem;
97 int irq;
98 int ret = 0;
99 u32 reg;
100
101 if (!pdev->dev.platform_data) {
102 dev_err(&pdev->dev, "no platform data specified\n");
103 ret = -EINVAL;
104 goto err_out;
105 }
106
107 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
108 if (res == NULL) {
109 dev_err(&pdev->dev, "no memory resource found\n");
110 ret = -ENXIO;
111 goto err_out;
112 }
113
114 mem = ioremap_nocache(res->start, resource_size(res));
115 if (mem == NULL) {
116 dev_err(&pdev->dev, "ioremap failed\n");
117 ret = -ENOMEM;
118 goto err_out;
119 }
120
121 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
122 if (res == NULL) {
123 dev_err(&pdev->dev, "no IRQ resource found\n");
124 ret = -ENXIO;
125 goto err_out;
126 }
127
128 irq = res->start;
129
130 hw = ieee80211_alloc_hw(sizeof(struct ath5k_softc), &ath5k_hw_ops);
131 if (hw == NULL) {
132 dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
133 ret = -ENOMEM;
134 goto err_out;
135 }
136
137 sc = hw->priv;
138 sc->hw = hw;
139 sc->dev = &pdev->dev;
140 sc->iobase = mem;
141 sc->irq = irq;
142 sc->devid = bcfg->devid;
143
144 if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
145 /* Enable WMAC AHB arbitration */
146 reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
147 reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN;
148 __raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
149
150 /* Enable global WMAC swapping */
151 reg = __raw_readl((void __iomem *) AR5K_AR2315_BYTESWAP);
152 reg |= AR5K_AR2315_BYTESWAP_WMAC;
153 __raw_writel(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
154 } else {
155 /* Enable WMAC DMA access (assuming 5312 or 231x*/
156 /* TODO: check other platforms */
157 reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);
158 if (to_platform_device(sc->dev)->id == 0)
159 reg |= AR5K_AR5312_ENABLE_WLAN0;
160 else
161 reg |= AR5K_AR5312_ENABLE_WLAN1;
162 __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
163
164 /*
165 * On a dual-band AR5312, the multiband radio is only
166 * used as pass-through. Disable 2 GHz support in the
167 * driver for it
168 */
169 if (to_platform_device(sc->dev)->id == 0 &&
170 (bcfg->config->flags & (BD_WLAN0|BD_WLAN1)) ==
171 (BD_WLAN1|BD_WLAN0))
172 __set_bit(ATH_STAT_2G_DISABLED, sc->status);
173 }
174
175 ret = ath5k_init_softc(sc, &ath_ahb_bus_ops);
176 if (ret != 0) {
177 dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
178 ret = -ENODEV;
179 goto err_free_hw;
180 }
181
182 platform_set_drvdata(pdev, hw);
183
184 return 0;
185
186 err_free_hw:
187 ieee80211_free_hw(hw);
188 platform_set_drvdata(pdev, NULL);
189 err_out:
190 return ret;
191}
192
193static int ath_ahb_remove(struct platform_device *pdev)
194{
195 struct ar231x_board_config *bcfg = pdev->dev.platform_data;
196 struct ieee80211_hw *hw = platform_get_drvdata(pdev);
197 struct ath5k_softc *sc;
198 u32 reg;
199
200 if (!hw)
201 return 0;
202
203 sc = hw->priv;
204
205 if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
206 /* Disable WMAC AHB arbitration */
207 reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
208 reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN;
209 __raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
210 } else {
211 /*Stop DMA access */
212 reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);
213 if (to_platform_device(sc->dev)->id == 0)
214 reg &= ~AR5K_AR5312_ENABLE_WLAN0;
215 else
216 reg &= ~AR5K_AR5312_ENABLE_WLAN1;
217 __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
218 }
219
220 ath5k_deinit_softc(sc);
221 platform_set_drvdata(pdev, NULL);
222
223 return 0;
224}
225
226static struct platform_driver ath_ahb_driver = {
227 .probe = ath_ahb_probe,
228 .remove = ath_ahb_remove,
229 .driver = {
230 .name = "ar231x-wmac",
231 .owner = THIS_MODULE,
232 },
233};
234
235static int __init
236ath5k_ahb_init(void)
237{
238 return platform_driver_register(&ath_ahb_driver);
239}
240
241static void __exit
242ath5k_ahb_exit(void)
243{
244 platform_driver_unregister(&ath_ahb_driver);
245}
246
247module_init(ath5k_ahb_init);
248module_exit(ath5k_ahb_exit);
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
index 26dbe65fedb0..f915f404302d 100644
--- a/drivers/net/wireless/ath/ath5k/ani.c
+++ b/drivers/net/wireless/ath/ath5k/ani.c
@@ -58,20 +58,20 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
58{ 58{
59 /* TODO: 59 /* TODO:
60 * ANI documents suggest the following five levels to use, but the HAL 60 * ANI documents suggest the following five levels to use, but the HAL
61 * and ath9k use only use the last two levels, making this 61 * and ath9k use only the last two levels, making this
62 * essentially an on/off option. There *may* be a reason for this (???), 62 * essentially an on/off option. There *may* be a reason for this (???),
63 * so i stick with the HAL version for now... 63 * so i stick with the HAL version for now...
64 */ 64 */
65#if 0 65#if 0
66 const s8 hi[] = { -18, -18, -16, -14, -12 }; 66 static const s8 lo[] = { -52, -56, -60, -64, -70 };
67 const s8 lo[] = { -52, -56, -60, -64, -70 }; 67 static const s8 hi[] = { -18, -18, -16, -14, -12 };
68 const s8 sz[] = { -34, -41, -48, -55, -62 }; 68 static const s8 sz[] = { -34, -41, -48, -55, -62 };
69 const s8 fr[] = { -70, -72, -75, -78, -80 }; 69 static const s8 fr[] = { -70, -72, -75, -78, -80 };
70#else 70#else
71 const s8 sz[] = { -55, -62 }; 71 static const s8 lo[] = { -64, -70 };
72 const s8 lo[] = { -64, -70 }; 72 static const s8 hi[] = { -14, -12 };
73 const s8 hi[] = { -14, -12 }; 73 static const s8 sz[] = { -55, -62 };
74 const s8 fr[] = { -78, -80 }; 74 static const s8 fr[] = { -78, -80 };
75#endif 75#endif
76 if (level < 0 || level >= ARRAY_SIZE(sz)) { 76 if (level < 0 || level >= ARRAY_SIZE(sz)) {
77 ATH5K_ERR(ah->ah_sc, "noise immuniy level %d out of range", 77 ATH5K_ERR(ah->ah_sc, "noise immuniy level %d out of range",
@@ -102,7 +102,7 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
102void 102void
103ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level) 103ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
104{ 104{
105 const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; 105 static const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
106 106
107 if (level < 0 || level >= ARRAY_SIZE(val) || 107 if (level < 0 || level >= ARRAY_SIZE(val) ||
108 level > ah->ah_sc->ani_state.max_spur_level) { 108 level > ah->ah_sc->ani_state.max_spur_level) {
@@ -127,7 +127,7 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
127void 127void
128ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level) 128ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
129{ 129{
130 const int val[] = { 0, 4, 8 }; 130 static const int val[] = { 0, 4, 8 };
131 131
132 if (level < 0 || level >= ARRAY_SIZE(val)) { 132 if (level < 0 || level >= ARRAY_SIZE(val)) {
133 ATH5K_ERR(ah->ah_sc, "firstep level %d out of range", level); 133 ATH5K_ERR(ah->ah_sc, "firstep level %d out of range", level);
@@ -151,12 +151,12 @@ ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
151void 151void
152ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on) 152ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on)
153{ 153{
154 const int m1l[] = { 127, 50 }; 154 static const int m1l[] = { 127, 50 };
155 const int m2l[] = { 127, 40 }; 155 static const int m2l[] = { 127, 40 };
156 const int m1[] = { 127, 0x4d }; 156 static const int m1[] = { 127, 0x4d };
157 const int m2[] = { 127, 0x40 }; 157 static const int m2[] = { 127, 0x40 };
158 const int m2cnt[] = { 31, 16 }; 158 static const int m2cnt[] = { 31, 16 };
159 const int m2lcnt[] = { 63, 48 }; 159 static const int m2lcnt[] = { 63, 48 };
160 160
161 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR, 161 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
162 AR5K_PHY_WEAK_OFDM_LOW_THR_M1, m1l[on]); 162 AR5K_PHY_WEAK_OFDM_LOW_THR_M1, m1l[on]);
@@ -192,7 +192,7 @@ ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on)
192void 192void
193ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on) 193ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on)
194{ 194{
195 const int val[] = { 8, 6 }; 195 static const int val[] = { 8, 6 };
196 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_CCK_CROSSCORR, 196 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_CCK_CROSSCORR,
197 AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR, val[on]); 197 AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR, val[on]);
198 ah->ah_sc->ani_state.cck_weak_sig = on; 198 ah->ah_sc->ani_state.cck_weak_sig = on;
@@ -216,7 +216,7 @@ static void
216ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as, 216ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
217 bool ofdm_trigger) 217 bool ofdm_trigger)
218{ 218{
219 int rssi = ah->ah_beacon_rssi_avg.avg; 219 int rssi = ewma_read(&ah->ah_beacon_rssi_avg);
220 220
221 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "raise immunity (%s)", 221 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "raise immunity (%s)",
222 ofdm_trigger ? "ODFM" : "CCK"); 222 ofdm_trigger ? "ODFM" : "CCK");
@@ -301,7 +301,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
301static void 301static void
302ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as) 302ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
303{ 303{
304 int rssi = ah->ah_beacon_rssi_avg.avg; 304 int rssi = ewma_read(&ah->ah_beacon_rssi_avg);
305 305
306 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "lower immunity"); 306 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "lower immunity");
307 307
@@ -355,41 +355,28 @@ ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
355 355
356 356
357/** 357/**
358 * ath5k_hw_ani_get_listen_time() - Calculate time spent listening 358 * ath5k_hw_ani_get_listen_time() - Update counters and return listening time
359 * 359 *
360 * Return an approximation of the time spent "listening" in milliseconds (ms) 360 * Return an approximation of the time spent "listening" in milliseconds (ms)
361 * since the last call of this function by deducting the cycles spent 361 * since the last call of this function.
362 * transmitting and receiving from the total cycle count. 362 * Save a snapshot of the counter values for debugging/statistics.
363 * Save profile count values for debugging/statistics and because we might want
364 * to use them later.
365 *
366 * We assume no one else clears these registers!
367 */ 363 */
368static int 364static int
369ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as) 365ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as)
370{ 366{
367 struct ath_common *common = ath5k_hw_common(ah);
371 int listen; 368 int listen;
372 369
373 /* freeze */ 370 spin_lock_bh(&common->cc_lock);
374 ath5k_hw_reg_write(ah, AR5K_MIBC_FMC, AR5K_MIBC); 371
375 /* read */ 372 ath_hw_cycle_counters_update(common);
376 as->pfc_cycles = ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE); 373 memcpy(&as->last_cc, &common->cc_ani, sizeof(as->last_cc));
377 as->pfc_busy = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR); 374
378 as->pfc_tx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX); 375 /* clears common->cc_ani */
379 as->pfc_rx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX); 376 listen = ath_hw_get_listen_time(common);
380 /* clear */ 377
381 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX); 378 spin_unlock_bh(&common->cc_lock);
382 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX); 379
383 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
384 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
385 /* un-freeze */
386 ath5k_hw_reg_write(ah, 0, AR5K_MIBC);
387
388 /* TODO: where does 44000 come from? (11g clock rate?) */
389 listen = (as->pfc_cycles - as->pfc_rx - as->pfc_tx) / 44000;
390
391 if (as->pfc_cycles == 0 || listen < 0)
392 return 0;
393 return listen; 380 return listen;
394} 381}
395 382
@@ -552,9 +539,9 @@ ath5k_ani_mib_intr(struct ath5k_hw *ah)
552 if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO) 539 if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO)
553 return; 540 return;
554 541
555 /* if one of the errors triggered, we can get a superfluous second 542 /* If one of the errors triggered, we can get a superfluous second
556 * interrupt, even though we have already reset the register. the 543 * interrupt, even though we have already reset the register. The
557 * function detects that so we can return early */ 544 * function detects that so we can return early. */
558 if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0) 545 if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0)
559 return; 546 return;
560 547
diff --git a/drivers/net/wireless/ath/ath5k/ani.h b/drivers/net/wireless/ath/ath5k/ani.h
index 55cf26d8522c..034015397093 100644
--- a/drivers/net/wireless/ath/ath5k/ani.h
+++ b/drivers/net/wireless/ath/ath5k/ani.h
@@ -27,7 +27,7 @@
27#define ATH5K_ANI_RSSI_THR_HIGH 40 27#define ATH5K_ANI_RSSI_THR_HIGH 40
28#define ATH5K_ANI_RSSI_THR_LOW 7 28#define ATH5K_ANI_RSSI_THR_LOW 7
29 29
30/* maximum availabe levels */ 30/* maximum available levels */
31#define ATH5K_ANI_MAX_FIRSTEP_LVL 2 31#define ATH5K_ANI_MAX_FIRSTEP_LVL 2
32#define ATH5K_ANI_MAX_NOISE_IMM_LVL 1 32#define ATH5K_ANI_MAX_NOISE_IMM_LVL 1
33 33
@@ -75,10 +75,7 @@ struct ath5k_ani_state {
75 unsigned int cck_errors; 75 unsigned int cck_errors;
76 76
77 /* debug/statistics only: numbers from last ANI calibration */ 77 /* debug/statistics only: numbers from last ANI calibration */
78 unsigned int pfc_tx; 78 struct ath_cycle_counters last_cc;
79 unsigned int pfc_rx;
80 unsigned int pfc_busy;
81 unsigned int pfc_cycles;
82 unsigned int last_listen; 79 unsigned int last_listen;
83 unsigned int last_ofdm_errors; 80 unsigned int last_ofdm_errors;
84 unsigned int last_cck_errors; 81 unsigned int last_cck_errors;
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index ea6362a8988d..bb50700436fe 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -25,6 +25,7 @@
25 25
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/average.h>
28#include <net/mac80211.h> 29#include <net/mac80211.h>
29 30
30/* RX/TX descriptor hw structs 31/* RX/TX descriptor hw structs
@@ -153,19 +154,6 @@
153 udelay(1); \ 154 udelay(1); \
154} while (0) 155} while (0)
155 156
156/* Register dumps are done per operation mode */
157#define AR5K_INI_RFGAIN_5GHZ 0
158#define AR5K_INI_RFGAIN_2GHZ 1
159
160/* TODO: Clean this up */
161#define AR5K_INI_VAL_11A 0
162#define AR5K_INI_VAL_11A_TURBO 1
163#define AR5K_INI_VAL_11B 2
164#define AR5K_INI_VAL_11G 3
165#define AR5K_INI_VAL_11G_TURBO 4
166#define AR5K_INI_VAL_XR 0
167#define AR5K_INI_VAL_MAX 5
168
169/* 157/*
170 * Some tuneable values (these should be changeable by the user) 158 * Some tuneable values (these should be changeable by the user)
171 * TODO: Make use of them and add more options OR use debug/configfs 159 * TODO: Make use of them and add more options OR use debug/configfs
@@ -175,7 +163,7 @@
175#define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF 0 163#define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF 0
176#define AR5K_TUNE_RADAR_ALERT false 164#define AR5K_TUNE_RADAR_ALERT false
177#define AR5K_TUNE_MIN_TX_FIFO_THRES 1 165#define AR5K_TUNE_MIN_TX_FIFO_THRES 1
178#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_LEN / 64) + 1) 166#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_FRAME_LEN / 64) + 1)
179#define AR5K_TUNE_REGISTER_TIMEOUT 20000 167#define AR5K_TUNE_REGISTER_TIMEOUT 20000
180/* Register for RSSI threshold has a mask of 0xff, so 255 seems to 168/* Register for RSSI threshold has a mask of 0xff, so 255 seems to
181 * be the max value. */ 169 * be the max value. */
@@ -206,6 +194,8 @@
206#define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */ 194#define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */
207#define ATH5K_TUNE_CALIBRATION_INTERVAL_NF 60000 /* 60 sec */ 195#define ATH5K_TUNE_CALIBRATION_INTERVAL_NF 60000 /* 60 sec */
208 196
197#define ATH5K_TX_COMPLETE_POLL_INT 3000 /* 3 sec */
198
209#define AR5K_INIT_CARR_SENSE_EN 1 199#define AR5K_INIT_CARR_SENSE_EN 1
210 200
211/*Swap RX/TX Descriptor for big endian archs*/ 201/*Swap RX/TX Descriptor for big endian archs*/
@@ -219,45 +209,61 @@
219 209
220/* Initial values */ 210/* Initial values */
221#define AR5K_INIT_CYCRSSI_THR1 2 211#define AR5K_INIT_CYCRSSI_THR1 2
222#define AR5K_INIT_TX_LATENCY 502
223#define AR5K_INIT_USEC 39
224#define AR5K_INIT_USEC_TURBO 79
225#define AR5K_INIT_USEC_32 31
226#define AR5K_INIT_SLOT_TIME 396
227#define AR5K_INIT_SLOT_TIME_TURBO 480
228#define AR5K_INIT_ACK_CTS_TIMEOUT 1024
229#define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO 0x08000800
230#define AR5K_INIT_PROG_IFS 920
231#define AR5K_INIT_PROG_IFS_TURBO 960
232#define AR5K_INIT_EIFS 3440
233#define AR5K_INIT_EIFS_TURBO 6880
234#define AR5K_INIT_SIFS 560
235#define AR5K_INIT_SIFS_TURBO 480
236#define AR5K_INIT_SH_RETRY 10
237#define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY
238#define AR5K_INIT_SSH_RETRY 32
239#define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY
240#define AR5K_INIT_TX_RETRY 10
241
242#define AR5K_INIT_TRANSMIT_LATENCY ( \
243 (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \
244 (AR5K_INIT_USEC) \
245)
246#define AR5K_INIT_TRANSMIT_LATENCY_TURBO ( \
247 (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \
248 (AR5K_INIT_USEC_TURBO) \
249)
250#define AR5K_INIT_PROTO_TIME_CNTRL ( \
251 (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) | \
252 (AR5K_INIT_PROG_IFS) \
253)
254#define AR5K_INIT_PROTO_TIME_CNTRL_TURBO ( \
255 (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \
256 (AR5K_INIT_PROG_IFS_TURBO) \
257)
258 212
259/* token to use for aifs, cwmin, cwmax in MadWiFi */ 213/* Tx retry limit defaults from standard */
260#define AR5K_TXQ_USEDEFAULT ((u32) -1) 214#define AR5K_INIT_RETRY_SHORT 7
215#define AR5K_INIT_RETRY_LONG 4
216
217/* Slot time */
218#define AR5K_INIT_SLOT_TIME_TURBO 6
219#define AR5K_INIT_SLOT_TIME_DEFAULT 9
220#define AR5K_INIT_SLOT_TIME_HALF_RATE 13
221#define AR5K_INIT_SLOT_TIME_QUARTER_RATE 21
222#define AR5K_INIT_SLOT_TIME_B 20
223#define AR5K_SLOT_TIME_MAX 0xffff
224
225/* SIFS */
226#define AR5K_INIT_SIFS_TURBO 6
227#define AR5K_INIT_SIFS_DEFAULT_BG 10
228#define AR5K_INIT_SIFS_DEFAULT_A 16
229#define AR5K_INIT_SIFS_HALF_RATE 32
230#define AR5K_INIT_SIFS_QUARTER_RATE 64
231
232/* Used to calculate tx time for non 5/10/40MHz
233 * operation */
234/* It's preamble time + signal time (16 + 4) */
235#define AR5K_INIT_OFDM_PREAMPLE_TIME 20
236/* Preamble time for 40MHz (turbo) operation (min ?) */
237#define AR5K_INIT_OFDM_PREAMBLE_TIME_MIN 14
238#define AR5K_INIT_OFDM_SYMBOL_TIME 4
239#define AR5K_INIT_OFDM_PLCP_BITS 22
240
241/* Rx latency for 5 and 10MHz operation (max ?) */
242#define AR5K_INIT_RX_LAT_MAX 63
243/* Tx latencies from initvals (5212 only but no problem
244 * because we only tweak them on 5212) */
245#define AR5K_INIT_TX_LAT_A 54
246#define AR5K_INIT_TX_LAT_BG 384
247/* Tx latency for 40MHz (turbo) operation (min ?) */
248#define AR5K_INIT_TX_LAT_MIN 32
249/* Default Tx/Rx latencies (same for 5211)*/
250#define AR5K_INIT_TX_LATENCY_5210 54
251#define AR5K_INIT_RX_LATENCY_5210 29
252
253/* Tx frame to Tx data start delay */
254#define AR5K_INIT_TXF2TXD_START_DEFAULT 14
255#define AR5K_INIT_TXF2TXD_START_DELAY_10MHZ 12
256#define AR5K_INIT_TXF2TXD_START_DELAY_5MHZ 13
257
258/* We need to increase PHY switch and agc settling time
259 * on turbo mode */
260#define AR5K_SWITCH_SETTLING 5760
261#define AR5K_SWITCH_SETTLING_TURBO 7168
262
263#define AR5K_AGC_SETTLING 28
264/* 38 on 5210 but shouldn't matter */
265#define AR5K_AGC_SETTLING_TURBO 37
266
261 267
262/* GENERIC CHIPSET DEFINITIONS */ 268/* GENERIC CHIPSET DEFINITIONS */
263 269
@@ -303,12 +309,19 @@ struct ath5k_srev_name {
303#define AR5K_SREV_AR5311B 0x30 /* Spirit */ 309#define AR5K_SREV_AR5311B 0x30 /* Spirit */
304#define AR5K_SREV_AR5211 0x40 /* Oahu */ 310#define AR5K_SREV_AR5211 0x40 /* Oahu */
305#define AR5K_SREV_AR5212 0x50 /* Venice */ 311#define AR5K_SREV_AR5212 0x50 /* Venice */
312#define AR5K_SREV_AR5312_R2 0x52 /* AP31 */
306#define AR5K_SREV_AR5212_V4 0x54 /* ??? */ 313#define AR5K_SREV_AR5212_V4 0x54 /* ??? */
307#define AR5K_SREV_AR5213 0x55 /* ??? */ 314#define AR5K_SREV_AR5213 0x55 /* ??? */
315#define AR5K_SREV_AR5312_R7 0x57 /* AP30 */
316#define AR5K_SREV_AR2313_R8 0x58 /* AP43 */
308#define AR5K_SREV_AR5213A 0x59 /* Hainan */ 317#define AR5K_SREV_AR5213A 0x59 /* Hainan */
309#define AR5K_SREV_AR2413 0x78 /* Griffin lite */ 318#define AR5K_SREV_AR2413 0x78 /* Griffin lite */
310#define AR5K_SREV_AR2414 0x70 /* Griffin */ 319#define AR5K_SREV_AR2414 0x70 /* Griffin */
320#define AR5K_SREV_AR2315_R6 0x86 /* AP51-Light */
321#define AR5K_SREV_AR2315_R7 0x87 /* AP51-Full */
311#define AR5K_SREV_AR5424 0x90 /* Condor */ 322#define AR5K_SREV_AR5424 0x90 /* Condor */
323#define AR5K_SREV_AR2317_R1 0x90 /* AP61-Light */
324#define AR5K_SREV_AR2317_R2 0x91 /* AP61-Full */
312#define AR5K_SREV_AR5413 0xa4 /* Eagle lite */ 325#define AR5K_SREV_AR5413 0xa4 /* Eagle lite */
313#define AR5K_SREV_AR5414 0xa0 /* Eagle */ 326#define AR5K_SREV_AR5414 0xa0 /* Eagle */
314#define AR5K_SREV_AR2415 0xb0 /* Talon */ 327#define AR5K_SREV_AR2415 0xb0 /* Talon */
@@ -343,15 +356,12 @@ struct ath5k_srev_name {
343#define AR5K_SREV_PHY_5413 0x61 356#define AR5K_SREV_PHY_5413 0x61
344#define AR5K_SREV_PHY_2425 0x70 357#define AR5K_SREV_PHY_2425 0x70
345 358
346/* IEEE defs */
347#define IEEE80211_MAX_LEN 2500
348
349/* TODO add support to mac80211 for vendor-specific rates and modes */ 359/* TODO add support to mac80211 for vendor-specific rates and modes */
350 360
351/* 361/*
352 * Some of this information is based on Documentation from: 362 * Some of this information is based on Documentation from:
353 * 363 *
354 * http://madwifi.org/wiki/ChipsetFeatures/SuperAG 364 * http://madwifi-project.org/wiki/ChipsetFeatures/SuperAG
355 * 365 *
356 * Modulation for Atheros' eXtended Range - range enhancing extension that is 366 * Modulation for Atheros' eXtended Range - range enhancing extension that is
357 * supposed to double the distance an Atheros client device can keep a 367 * supposed to double the distance an Atheros client device can keep a
@@ -407,12 +417,10 @@ struct ath5k_srev_name {
407 417
408enum ath5k_driver_mode { 418enum ath5k_driver_mode {
409 AR5K_MODE_11A = 0, 419 AR5K_MODE_11A = 0,
410 AR5K_MODE_11A_TURBO = 1, 420 AR5K_MODE_11B = 1,
411 AR5K_MODE_11B = 2, 421 AR5K_MODE_11G = 2,
412 AR5K_MODE_11G = 3,
413 AR5K_MODE_11G_TURBO = 4,
414 AR5K_MODE_XR = 0, 422 AR5K_MODE_XR = 0,
415 AR5K_MODE_MAX = 5 423 AR5K_MODE_MAX = 3
416}; 424};
417 425
418enum ath5k_ant_mode { 426enum ath5k_ant_mode {
@@ -426,6 +434,12 @@ enum ath5k_ant_mode {
426 AR5K_ANTMODE_MAX, 434 AR5K_ANTMODE_MAX,
427}; 435};
428 436
437enum ath5k_bw_mode {
438 AR5K_BWMODE_DEFAULT = 0, /* 20MHz, default operation */
439 AR5K_BWMODE_5MHZ = 1, /* Quarter rate */
440 AR5K_BWMODE_10MHZ = 2, /* Half rate */
441 AR5K_BWMODE_40MHZ = 3 /* Turbo */
442};
429 443
430/****************\ 444/****************\
431 TX DEFINITIONS 445 TX DEFINITIONS
@@ -438,12 +452,10 @@ struct ath5k_tx_status {
438 u16 ts_seqnum; 452 u16 ts_seqnum;
439 u16 ts_tstamp; 453 u16 ts_tstamp;
440 u8 ts_status; 454 u8 ts_status;
441 u8 ts_rate[4];
442 u8 ts_retry[4];
443 u8 ts_final_idx; 455 u8 ts_final_idx;
456 u8 ts_final_retry;
444 s8 ts_rssi; 457 s8 ts_rssi;
445 u8 ts_shortretry; 458 u8 ts_shortretry;
446 u8 ts_longretry;
447 u8 ts_virtcol; 459 u8 ts_virtcol;
448 u8 ts_antenna; 460 u8 ts_antenna;
449}; 461};
@@ -498,7 +510,7 @@ enum ath5k_tx_queue_id {
498 AR5K_TX_QUEUE_ID_NOQCU_DATA = 0, 510 AR5K_TX_QUEUE_ID_NOQCU_DATA = 0,
499 AR5K_TX_QUEUE_ID_NOQCU_BEACON = 1, 511 AR5K_TX_QUEUE_ID_NOQCU_BEACON = 1,
500 AR5K_TX_QUEUE_ID_DATA_MIN = 0, /*IEEE80211_TX_QUEUE_DATA0*/ 512 AR5K_TX_QUEUE_ID_DATA_MIN = 0, /*IEEE80211_TX_QUEUE_DATA0*/
501 AR5K_TX_QUEUE_ID_DATA_MAX = 4, /*IEEE80211_TX_QUEUE_DATA4*/ 513 AR5K_TX_QUEUE_ID_DATA_MAX = 3, /*IEEE80211_TX_QUEUE_DATA3*/
502 AR5K_TX_QUEUE_ID_DATA_SVP = 5, /*IEEE80211_TX_QUEUE_SVP - Spectralink Voice Protocol*/ 514 AR5K_TX_QUEUE_ID_DATA_SVP = 5, /*IEEE80211_TX_QUEUE_SVP - Spectralink Voice Protocol*/
503 AR5K_TX_QUEUE_ID_CAB = 6, /*IEEE80211_TX_QUEUE_AFTER_BEACON*/ 515 AR5K_TX_QUEUE_ID_CAB = 6, /*IEEE80211_TX_QUEUE_AFTER_BEACON*/
504 AR5K_TX_QUEUE_ID_BEACON = 7, /*IEEE80211_TX_QUEUE_BEACON*/ 516 AR5K_TX_QUEUE_ID_BEACON = 7, /*IEEE80211_TX_QUEUE_BEACON*/
@@ -531,9 +543,9 @@ struct ath5k_txq_info {
531 enum ath5k_tx_queue tqi_type; 543 enum ath5k_tx_queue tqi_type;
532 enum ath5k_tx_queue_subtype tqi_subtype; 544 enum ath5k_tx_queue_subtype tqi_subtype;
533 u16 tqi_flags; /* Tx queue flags (see above) */ 545 u16 tqi_flags; /* Tx queue flags (see above) */
534 u32 tqi_aifs; /* Arbitrated Interframe Space */ 546 u8 tqi_aifs; /* Arbitrated Interframe Space */
535 s32 tqi_cw_min; /* Minimum Contention Window */ 547 u16 tqi_cw_min; /* Minimum Contention Window */
536 s32 tqi_cw_max; /* Maximum Contention Window */ 548 u16 tqi_cw_max; /* Maximum Contention Window */
537 u32 tqi_cbr_period; /* Constant bit rate period */ 549 u32 tqi_cbr_period; /* Constant bit rate period */
538 u32 tqi_cbr_overflow_limit; 550 u32 tqi_cbr_overflow_limit;
539 u32 tqi_burst_time; 551 u32 tqi_burst_time;
@@ -658,7 +670,6 @@ struct ath5k_gain {
658 670
659/* channel_flags */ 671/* channel_flags */
660#define CHANNEL_CW_INT 0x0008 /* Contention Window interference detected */ 672#define CHANNEL_CW_INT 0x0008 /* Contention Window interference detected */
661#define CHANNEL_TURBO 0x0010 /* Turbo Channel */
662#define CHANNEL_CCK 0x0020 /* CCK channel */ 673#define CHANNEL_CCK 0x0020 /* CCK channel */
663#define CHANNEL_OFDM 0x0040 /* OFDM channel */ 674#define CHANNEL_OFDM 0x0040 /* OFDM channel */
664#define CHANNEL_2GHZ 0x0080 /* 2GHz channel. */ 675#define CHANNEL_2GHZ 0x0080 /* 2GHz channel. */
@@ -670,16 +681,10 @@ struct ath5k_gain {
670#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM) 681#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
671#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK) 682#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
672#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM) 683#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
673#define CHANNEL_T (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
674#define CHANNEL_TG (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
675#define CHANNEL_108A CHANNEL_T
676#define CHANNEL_108G CHANNEL_TG
677#define CHANNEL_X (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR) 684#define CHANNEL_X (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR)
678 685
679#define CHANNEL_ALL (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ| \ 686#define CHANNEL_ALL (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ)
680 CHANNEL_TURBO)
681 687
682#define CHANNEL_ALL_NOTURBO (CHANNEL_ALL & ~CHANNEL_TURBO)
683#define CHANNEL_MODES CHANNEL_ALL 688#define CHANNEL_MODES CHANNEL_ALL
684 689
685/* 690/*
@@ -867,6 +872,19 @@ enum ath5k_int {
867 AR5K_INT_QTRIG = 0x40000000, /* Non common */ 872 AR5K_INT_QTRIG = 0x40000000, /* Non common */
868 AR5K_INT_GLOBAL = 0x80000000, 873 AR5K_INT_GLOBAL = 0x80000000,
869 874
875 AR5K_INT_TX_ALL = AR5K_INT_TXOK
876 | AR5K_INT_TXDESC
877 | AR5K_INT_TXERR
878 | AR5K_INT_TXEOL
879 | AR5K_INT_TXURN,
880
881 AR5K_INT_RX_ALL = AR5K_INT_RXOK
882 | AR5K_INT_RXDESC
883 | AR5K_INT_RXERR
884 | AR5K_INT_RXNOFRM
885 | AR5K_INT_RXEOL
886 | AR5K_INT_RXORN,
887
870 AR5K_INT_COMMON = AR5K_INT_RXOK 888 AR5K_INT_COMMON = AR5K_INT_RXOK
871 | AR5K_INT_RXDESC 889 | AR5K_INT_RXDESC
872 | AR5K_INT_RXERR 890 | AR5K_INT_RXERR
@@ -1028,17 +1046,15 @@ struct ath5k_hw {
1028 enum ath5k_int ah_imr; 1046 enum ath5k_int ah_imr;
1029 1047
1030 struct ieee80211_channel *ah_current_channel; 1048 struct ieee80211_channel *ah_current_channel;
1031 bool ah_turbo;
1032 bool ah_calibration; 1049 bool ah_calibration;
1033 bool ah_single_chip; 1050 bool ah_single_chip;
1034 bool ah_aes_support;
1035 bool ah_combined_mic;
1036 1051
1037 enum ath5k_version ah_version; 1052 enum ath5k_version ah_version;
1038 enum ath5k_radio ah_radio; 1053 enum ath5k_radio ah_radio;
1039 u32 ah_phy; 1054 u32 ah_phy;
1040 u32 ah_mac_srev; 1055 u32 ah_mac_srev;
1041 u16 ah_mac_version; 1056 u16 ah_mac_version;
1057 u16 ah_mac_revision;
1042 u16 ah_phy_revision; 1058 u16 ah_phy_revision;
1043 u16 ah_radio_5ghz_revision; 1059 u16 ah_radio_5ghz_revision;
1044 u16 ah_radio_2ghz_revision; 1060 u16 ah_radio_2ghz_revision;
@@ -1046,19 +1062,19 @@ struct ath5k_hw {
1046#define ah_modes ah_capabilities.cap_mode 1062#define ah_modes ah_capabilities.cap_mode
1047#define ah_ee_version ah_capabilities.cap_eeprom.ee_version 1063#define ah_ee_version ah_capabilities.cap_eeprom.ee_version
1048 1064
1049 u32 ah_atim_window; 1065 u8 ah_retry_long;
1050 u32 ah_aifs; 1066 u8 ah_retry_short;
1051 u32 ah_cw_min; 1067
1052 u32 ah_cw_max;
1053 u32 ah_limit_tx_retries;
1054 u8 ah_coverage_class; 1068 u8 ah_coverage_class;
1069 bool ah_ack_bitrate_high;
1070 u8 ah_bwmode;
1071 bool ah_short_slot;
1055 1072
1056 /* Antenna Control */ 1073 /* Antenna Control */
1057 u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; 1074 u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
1058 u8 ah_ant_mode; 1075 u8 ah_ant_mode;
1059 u8 ah_tx_ant; 1076 u8 ah_tx_ant;
1060 u8 ah_def_ant; 1077 u8 ah_def_ant;
1061 bool ah_software_retry;
1062 1078
1063 struct ath5k_capabilities ah_capabilities; 1079 struct ath5k_capabilities ah_capabilities;
1064 1080
@@ -1094,12 +1110,14 @@ struct ath5k_hw {
1094 /* Values in 0.25dB units */ 1110 /* Values in 0.25dB units */
1095 s16 txp_min_pwr; 1111 s16 txp_min_pwr;
1096 s16 txp_max_pwr; 1112 s16 txp_max_pwr;
1113 s16 txp_cur_pwr;
1097 /* Values in 0.5dB units */ 1114 /* Values in 0.5dB units */
1098 s16 txp_offset; 1115 s16 txp_offset;
1099 s16 txp_ofdm; 1116 s16 txp_ofdm;
1100 s16 txp_cck_ofdm_gainf_delta; 1117 s16 txp_cck_ofdm_gainf_delta;
1101 /* Value in dB units */ 1118 /* Value in dB units */
1102 s16 txp_cck_ofdm_pwr_delta; 1119 s16 txp_cck_ofdm_pwr_delta;
1120 bool txp_setup;
1103 } ah_txpower; 1121 } ah_txpower;
1104 1122
1105 struct { 1123 struct {
@@ -1111,7 +1129,7 @@ struct ath5k_hw {
1111 struct ath5k_nfcal_hist ah_nfcal_hist; 1129 struct ath5k_nfcal_hist ah_nfcal_hist;
1112 1130
1113 /* average beacon RSSI in our BSS (used by ANI) */ 1131 /* average beacon RSSI in our BSS (used by ANI) */
1114 struct ath5k_avg_val ah_beacon_rssi_avg; 1132 struct ewma ah_beacon_rssi_avg;
1115 1133
1116 /* noise floor from last periodic calibration */ 1134 /* noise floor from last periodic calibration */
1117 s32 ah_noise_floor; 1135 s32 ah_noise_floor;
@@ -1137,39 +1155,80 @@ struct ath5k_hw {
1137 struct ath5k_rx_status *); 1155 struct ath5k_rx_status *);
1138}; 1156};
1139 1157
1158struct ath_bus_ops {
1159 enum ath_bus_type ath_bus_type;
1160 void (*read_cachesize)(struct ath_common *common, int *csz);
1161 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
1162 int (*eeprom_read_mac)(struct ath5k_hw *ah, u8 *mac);
1163};
1164
1140/* 1165/*
1141 * Prototypes 1166 * Prototypes
1142 */ 1167 */
1168extern const struct ieee80211_ops ath5k_hw_ops;
1143 1169
1144/* Attach/Detach Functions */ 1170/* Initialization and detach functions */
1145int ath5k_hw_attach(struct ath5k_softc *sc); 1171int ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops);
1146void ath5k_hw_detach(struct ath5k_hw *ah); 1172void ath5k_deinit_softc(struct ath5k_softc *sc);
1173int ath5k_hw_init(struct ath5k_softc *sc);
1174void ath5k_hw_deinit(struct ath5k_hw *ah);
1147 1175
1148int ath5k_sysfs_register(struct ath5k_softc *sc); 1176int ath5k_sysfs_register(struct ath5k_softc *sc);
1149void ath5k_sysfs_unregister(struct ath5k_softc *sc); 1177void ath5k_sysfs_unregister(struct ath5k_softc *sc);
1150 1178
1179/* base.c */
1180struct ath5k_buf;
1181struct ath5k_txq;
1182
1183void set_beacon_filter(struct ieee80211_hw *hw, bool enable);
1184bool ath_any_vif_assoc(struct ath5k_softc *sc);
1185void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
1186 struct ath5k_txq *txq);
1187int ath5k_init_hw(struct ath5k_softc *sc);
1188int ath5k_stop_hw(struct ath5k_softc *sc);
1189void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif);
1190void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
1191 struct ieee80211_vif *vif);
1192int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan);
1193void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
1194int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
1195void ath5k_beacon_config(struct ath5k_softc *sc);
1196void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
1197void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
1198
1199/*Chip id helper functions */
1200const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
1201int ath5k_hw_read_srev(struct ath5k_hw *ah);
1202
1151/* LED functions */ 1203/* LED functions */
1152int ath5k_init_leds(struct ath5k_softc *sc); 1204int ath5k_init_leds(struct ath5k_softc *sc);
1153void ath5k_led_enable(struct ath5k_softc *sc); 1205void ath5k_led_enable(struct ath5k_softc *sc);
1154void ath5k_led_off(struct ath5k_softc *sc); 1206void ath5k_led_off(struct ath5k_softc *sc);
1155void ath5k_unregister_leds(struct ath5k_softc *sc); 1207void ath5k_unregister_leds(struct ath5k_softc *sc);
1156 1208
1209
1157/* Reset Functions */ 1210/* Reset Functions */
1158int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); 1211int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
1159int ath5k_hw_on_hold(struct ath5k_hw *ah); 1212int ath5k_hw_on_hold(struct ath5k_hw *ah);
1160int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, 1213int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1161 struct ieee80211_channel *channel, bool change_channel); 1214 struct ieee80211_channel *channel, bool fast, bool skip_pcu);
1162int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, 1215int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
1163 bool is_set); 1216 bool is_set);
1164/* Power management functions */ 1217/* Power management functions */
1165 1218
1219
1220/* Clock rate related functions */
1221unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
1222unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
1223void ath5k_hw_set_clockrate(struct ath5k_hw *ah);
1224
1225
1166/* DMA Related Functions */ 1226/* DMA Related Functions */
1167void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); 1227void ath5k_hw_start_rx_dma(struct ath5k_hw *ah);
1168int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
1169u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); 1228u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah);
1170void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); 1229int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
1171int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); 1230int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue);
1172int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); 1231int ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue);
1173u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); 1232u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue);
1174int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, 1233int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue,
1175 u32 phys_addr); 1234 u32 phys_addr);
@@ -1179,42 +1238,42 @@ bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
1179int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); 1238int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
1180enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask); 1239enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask);
1181void ath5k_hw_update_mib_counters(struct ath5k_hw *ah); 1240void ath5k_hw_update_mib_counters(struct ath5k_hw *ah);
1241/* Init/Stop functions */
1242void ath5k_hw_dma_init(struct ath5k_hw *ah);
1243int ath5k_hw_dma_stop(struct ath5k_hw *ah);
1182 1244
1183/* EEPROM access functions */ 1245/* EEPROM access functions */
1184int ath5k_eeprom_init(struct ath5k_hw *ah); 1246int ath5k_eeprom_init(struct ath5k_hw *ah);
1185void ath5k_eeprom_detach(struct ath5k_hw *ah); 1247void ath5k_eeprom_detach(struct ath5k_hw *ah);
1186int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); 1248
1187 1249
1188/* Protocol Control Unit Functions */ 1250/* Protocol Control Unit Functions */
1251/* Helpers */
1252int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
1253 int len, struct ieee80211_rate *rate, bool shortpre);
1254unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah);
1255unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah);
1189extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); 1256extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
1190void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); 1257void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
1191/* BSSID Functions */ 1258/* RX filter control*/
1192int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); 1259int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
1193void ath5k_hw_set_associd(struct ath5k_hw *ah); 1260void ath5k_hw_set_bssid(struct ath5k_hw *ah);
1194void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); 1261void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
1195/* Receive start/stop functions */
1196void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
1197void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
1198/* RX Filter functions */
1199void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); 1262void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
1200u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah); 1263u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
1201void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter); 1264void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
1265/* Receive (DRU) start/stop functions */
1266void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
1267void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
1202/* Beacon control functions */ 1268/* Beacon control functions */
1203u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); 1269u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
1204void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); 1270void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
1205void ath5k_hw_reset_tsf(struct ath5k_hw *ah); 1271void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
1206void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval); 1272void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
1207/* ACK bit rate */ 1273bool ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval);
1208void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); 1274/* Init function */
1209/* Clock rate related functions */ 1275void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1210unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); 1276 u8 mode);
1211unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
1212unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah);
1213/* Key table (WEP) functions */
1214int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
1215int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
1216 const struct ieee80211_key_conf *key, const u8 *mac);
1217int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac);
1218 1277
1219/* Queue Control Unit, DFS Control Unit Functions */ 1278/* Queue Control Unit, DFS Control Unit Functions */
1220int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, 1279int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
@@ -1224,10 +1283,14 @@ int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
1224int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, 1283int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
1225 enum ath5k_tx_queue queue_type, 1284 enum ath5k_tx_queue queue_type,
1226 struct ath5k_txq_info *queue_info); 1285 struct ath5k_txq_info *queue_info);
1286void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah,
1287 unsigned int queue);
1227u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); 1288u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
1228void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); 1289void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1229int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); 1290int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1230int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); 1291int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time);
1292/* Init function */
1293int ath5k_hw_init_queues(struct ath5k_hw *ah);
1231 1294
1232/* Hardware Descriptor Functions */ 1295/* Hardware Descriptor Functions */
1233int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); 1296int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
@@ -1237,6 +1300,7 @@ int ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
1237 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, 1300 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
1238 u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3); 1301 u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3);
1239 1302
1303
1240/* GPIO Functions */ 1304/* GPIO Functions */
1241void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); 1305void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
1242int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); 1306int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
@@ -1246,11 +1310,13 @@ int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
1246void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, 1310void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
1247 u32 interrupt_level); 1311 u32 interrupt_level);
1248 1312
1249/* rfkill Functions */ 1313
1314/* RFkill Functions */
1250void ath5k_rfkill_hw_start(struct ath5k_hw *ah); 1315void ath5k_rfkill_hw_start(struct ath5k_hw *ah);
1251void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); 1316void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
1252 1317
1253/* Misc functions */ 1318
1319/* Misc functions TODO: Cleanup */
1254int ath5k_hw_set_capabilities(struct ath5k_hw *ah); 1320int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
1255int ath5k_hw_get_capability(struct ath5k_hw *ah, 1321int ath5k_hw_get_capability(struct ath5k_hw *ah,
1256 enum ath5k_capability_type cap_type, u32 capability, 1322 enum ath5k_capability_type cap_type, u32 capability,
@@ -1258,19 +1324,20 @@ int ath5k_hw_get_capability(struct ath5k_hw *ah,
1258int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id); 1324int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
1259int ath5k_hw_disable_pspoll(struct ath5k_hw *ah); 1325int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
1260 1326
1327
1261/* Initial register settings functions */ 1328/* Initial register settings functions */
1262int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); 1329int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
1263 1330
1264/* Initialize RF */ 1331
1265int ath5k_hw_rfregs_init(struct ath5k_hw *ah, 1332/* PHY functions */
1266 struct ieee80211_channel *channel, 1333/* Misc PHY functions */
1267 unsigned int mode); 1334u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
1268int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq); 1335int ath5k_hw_phy_disable(struct ath5k_hw *ah);
1336/* Gain_F optimization */
1269enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); 1337enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
1270int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); 1338int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
1271/* PHY/RF channel functions */ 1339/* PHY/RF channel functions */
1272bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); 1340bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
1273int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1274/* PHY calibration */ 1341/* PHY calibration */
1275void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); 1342void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
1276int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, 1343int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
@@ -1279,18 +1346,14 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah);
1279/* Spur mitigation */ 1346/* Spur mitigation */
1280bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, 1347bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
1281 struct ieee80211_channel *channel); 1348 struct ieee80211_channel *channel);
1282void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1283 struct ieee80211_channel *channel);
1284/* Misc PHY functions */
1285u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
1286int ath5k_hw_phy_disable(struct ath5k_hw *ah);
1287/* Antenna control */ 1349/* Antenna control */
1288void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); 1350void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
1289void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode); 1351void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode);
1290/* TX power setup */ 1352/* TX power setup */
1291int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
1292 u8 ee_mode, u8 txpower);
1293int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); 1353int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
1354/* Init function */
1355int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
1356 u8 mode, bool fast);
1294 1357
1295/* 1358/*
1296 * Functions used internaly 1359 * Functions used internaly
@@ -1306,6 +1369,32 @@ static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
1306 return &(ath5k_hw_common(ah)->regulatory); 1369 return &(ath5k_hw_common(ah)->regulatory);
1307} 1370}
1308 1371
1372#ifdef CONFIG_ATHEROS_AR231X
1373#define AR5K_AR2315_PCI_BASE ((void __iomem *)0xb0100000)
1374
1375static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
1376{
1377 /* On AR2315 and AR2317 the PCI clock domain registers
1378 * are outside of the WMAC register space */
1379 if (unlikely((reg >= 0x4000) && (reg < 0x5000) &&
1380 (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6)))
1381 return AR5K_AR2315_PCI_BASE + reg;
1382
1383 return ah->ah_iobase + reg;
1384}
1385
1386static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
1387{
1388 return __raw_readl(ath5k_ahb_reg(ah, reg));
1389}
1390
1391static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
1392{
1393 __raw_writel(val, ath5k_ahb_reg(ah, reg));
1394}
1395
1396#else
1397
1309static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) 1398static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
1310{ 1399{
1311 return ioread32(ah->ah_iobase + reg); 1400 return ioread32(ah->ah_iobase + reg);
@@ -1316,6 +1405,24 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
1316 iowrite32(val, ah->ah_iobase + reg); 1405 iowrite32(val, ah->ah_iobase + reg);
1317} 1406}
1318 1407
1408#endif
1409
1410static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah)
1411{
1412 return ath5k_hw_common(ah)->bus_ops->ath_bus_type;
1413}
1414
1415static inline void ath5k_read_cachesize(struct ath_common *common, int *csz)
1416{
1417 common->bus_ops->read_cachesize(common, csz);
1418}
1419
1420static inline bool ath5k_hw_nvram_read(struct ath5k_hw *ah, u32 off, u16 *data)
1421{
1422 struct ath_common *common = ath5k_hw_common(ah);
1423 return common->bus_ops->eeprom_read(common, off, data);
1424}
1425
1319static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) 1426static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
1320{ 1427{
1321 u32 retval = 0, bit, i; 1428 u32 retval = 0, bit, i;
@@ -1328,27 +1435,4 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
1328 return retval; 1435 return retval;
1329} 1436}
1330 1437
1331#define AVG_SAMPLES 8
1332#define AVG_FACTOR 1000
1333
1334/**
1335 * ath5k_moving_average - Exponentially weighted moving average
1336 * @avg: average structure
1337 * @val: current value
1338 *
1339 * This implementation make use of a struct ath5k_avg_val to prevent rounding
1340 * errors.
1341 */
1342static inline struct ath5k_avg_val
1343ath5k_moving_average(const struct ath5k_avg_val avg, const int val)
1344{
1345 struct ath5k_avg_val new;
1346 new.avg_weight = avg.avg_weight ?
1347 (((avg.avg_weight * ((AVG_SAMPLES) - 1)) +
1348 (val * (AVG_FACTOR))) / (AVG_SAMPLES)) :
1349 (val * (AVG_FACTOR));
1350 new.avg = new.avg_weight / (AVG_FACTOR);
1351 return new;
1352}
1353
1354#endif 1438#endif
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index b32e28caeee2..1588401de3c4 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -93,16 +93,16 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
93} 93}
94 94
95/** 95/**
96 * ath5k_hw_attach - Check if hw is supported and init the needed structs 96 * ath5k_hw_init - Check if hw is supported and init the needed structs
97 * 97 *
98 * @sc: The &struct ath5k_softc we got from the driver's attach function 98 * @sc: The &struct ath5k_softc we got from the driver's init_softc function
99 * 99 *
100 * Check if the device is supported, perform a POST and initialize the needed 100 * Check if the device is supported, perform a POST and initialize the needed
101 * structs. Returns -ENOMEM if we don't have memory for the needed structs, 101 * structs. Returns -ENOMEM if we don't have memory for the needed structs,
102 * -ENODEV if the device is not supported or prints an error msg if something 102 * -ENODEV if the device is not supported or prints an error msg if something
103 * else went wrong. 103 * else went wrong.
104 */ 104 */
105int ath5k_hw_attach(struct ath5k_softc *sc) 105int ath5k_hw_init(struct ath5k_softc *sc)
106{ 106{
107 struct ath5k_hw *ah = sc->ah; 107 struct ath5k_hw *ah = sc->ah;
108 struct ath_common *common = ath5k_hw_common(ah); 108 struct ath_common *common = ath5k_hw_common(ah);
@@ -115,14 +115,11 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
115 * HW information 115 * HW information
116 */ 116 */
117 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; 117 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
118 ah->ah_turbo = false; 118 ah->ah_bwmode = AR5K_BWMODE_DEFAULT;
119 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; 119 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
120 ah->ah_imr = 0; 120 ah->ah_imr = 0;
121 ah->ah_atim_window = 0; 121 ah->ah_retry_short = AR5K_INIT_RETRY_SHORT;
122 ah->ah_aifs = AR5K_TUNE_AIFS; 122 ah->ah_retry_long = AR5K_INIT_RETRY_LONG;
123 ah->ah_cw_min = AR5K_TUNE_CWMIN;
124 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
125 ah->ah_software_retry = false;
126 ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; 123 ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT;
127 ah->ah_noise_floor = -95; /* until first NF calibration is run */ 124 ah->ah_noise_floor = -95; /* until first NF calibration is run */
128 sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO; 125 sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO;
@@ -131,7 +128,8 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
131 /* 128 /*
132 * Find the mac version 129 * Find the mac version
133 */ 130 */
134 srev = ath5k_hw_reg_read(ah, AR5K_SREV); 131 ath5k_hw_read_srev(ah);
132 srev = ah->ah_mac_srev;
135 if (srev < AR5K_SREV_AR5311) 133 if (srev < AR5K_SREV_AR5311)
136 ah->ah_version = AR5K_AR5210; 134 ah->ah_version = AR5K_AR5210;
137 else if (srev < AR5K_SREV_AR5212) 135 else if (srev < AR5K_SREV_AR5212)
@@ -139,26 +137,28 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
139 else 137 else
140 ah->ah_version = AR5K_AR5212; 138 ah->ah_version = AR5K_AR5212;
141 139
142 /*Fill the ath5k_hw struct with the needed functions*/ 140 /* Get the MAC revision */
141 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
142 ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
143
144 /* Fill the ath5k_hw struct with the needed functions */
143 ret = ath5k_hw_init_desc_functions(ah); 145 ret = ath5k_hw_init_desc_functions(ah);
144 if (ret) 146 if (ret)
145 goto err_free; 147 goto err;
146 148
147 /* Bring device out of sleep and reset it's units */ 149 /* Bring device out of sleep and reset its units */
148 ret = ath5k_hw_nic_wakeup(ah, 0, true); 150 ret = ath5k_hw_nic_wakeup(ah, 0, true);
149 if (ret) 151 if (ret)
150 goto err_free; 152 goto err;
151 153
152 /* Get MAC, PHY and RADIO revisions */ 154 /* Get PHY and RADIO revisions */
153 ah->ah_mac_srev = srev;
154 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
155 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & 155 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
156 0xffffffff; 156 0xffffffff;
157 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, 157 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
158 CHANNEL_5GHZ); 158 CHANNEL_5GHZ);
159 ah->ah_phy = AR5K_PHY(0); 159 ah->ah_phy = AR5K_PHY(0);
160 160
161 /* Try to identify radio chip based on it's srev */ 161 /* Try to identify radio chip based on its srev */
162 switch (ah->ah_radio_5ghz_revision & 0xf0) { 162 switch (ah->ah_radio_5ghz_revision & 0xf0) {
163 case AR5K_SREV_RAD_5111: 163 case AR5K_SREV_RAD_5111:
164 ah->ah_radio = AR5K_RF5111; 164 ah->ah_radio = AR5K_RF5111;
@@ -220,7 +220,8 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
220 ah->ah_radio = AR5K_RF5112; 220 ah->ah_radio = AR5K_RF5112;
221 ah->ah_single_chip = false; 221 ah->ah_single_chip = false;
222 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B; 222 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B;
223 } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) { 223 } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4) ||
224 ah->ah_mac_version == (AR5K_SREV_AR2315_R6 >> 4)) {
224 ah->ah_radio = AR5K_RF2316; 225 ah->ah_radio = AR5K_RF2316;
225 ah->ah_single_chip = true; 226 ah->ah_single_chip = true;
226 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316; 227 ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
@@ -237,7 +238,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
237 } else { 238 } else {
238 ATH5K_ERR(sc, "Couldn't identify radio revision.\n"); 239 ATH5K_ERR(sc, "Couldn't identify radio revision.\n");
239 ret = -ENODEV; 240 ret = -ENODEV;
240 goto err_free; 241 goto err;
241 } 242 }
242 } 243 }
243 244
@@ -247,7 +248,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
247 (srev < AR5K_SREV_AR2425)) { 248 (srev < AR5K_SREV_AR2425)) {
248 ATH5K_ERR(sc, "Device not yet supported.\n"); 249 ATH5K_ERR(sc, "Device not yet supported.\n");
249 ret = -ENODEV; 250 ret = -ENODEV;
250 goto err_free; 251 goto err;
251 } 252 }
252 253
253 /* 254 /*
@@ -255,7 +256,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
255 */ 256 */
256 ret = ath5k_hw_post(ah); 257 ret = ath5k_hw_post(ah);
257 if (ret) 258 if (ret)
258 goto err_free; 259 goto err;
259 260
260 /* Enable pci core retry fix on Hainan (5213A) and later chips */ 261 /* Enable pci core retry fix on Hainan (5213A) and later chips */
261 if (srev >= AR5K_SREV_AR5213A) 262 if (srev >= AR5K_SREV_AR5213A)
@@ -268,7 +269,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
268 ret = ath5k_eeprom_init(ah); 269 ret = ath5k_eeprom_init(ah);
269 if (ret) { 270 if (ret) {
270 ATH5K_ERR(sc, "unable to init EEPROM\n"); 271 ATH5K_ERR(sc, "unable to init EEPROM\n");
271 goto err_free; 272 goto err;
272 } 273 }
273 274
274 ee = &ah->ah_capabilities.cap_eeprom; 275 ee = &ah->ah_capabilities.cap_eeprom;
@@ -276,7 +277,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
276 /* 277 /*
277 * Write PCI-E power save settings 278 * Write PCI-E power save settings
278 */ 279 */
279 if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) { 280 if ((ah->ah_version == AR5K_AR5212) && pdev && (pci_is_pcie(pdev))) {
280 ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES); 281 ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
281 ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES); 282 ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
282 283
@@ -308,18 +309,26 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
308 /* Get misc capabilities */ 309 /* Get misc capabilities */
309 ret = ath5k_hw_set_capabilities(ah); 310 ret = ath5k_hw_set_capabilities(ah);
310 if (ret) { 311 if (ret) {
311 ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n", 312 ATH5K_ERR(sc, "unable to get device capabilities\n");
312 sc->pdev->device); 313 goto err;
313 goto err_free; 314 }
315
316 if (test_bit(ATH_STAT_2G_DISABLED, sc->status)) {
317 __clear_bit(AR5K_MODE_11B, ah->ah_capabilities.cap_mode);
318 __clear_bit(AR5K_MODE_11G, ah->ah_capabilities.cap_mode);
314 } 319 }
315 320
316 /* Crypto settings */ 321 /* Crypto settings */
317 ah->ah_aes_support = srev >= AR5K_SREV_AR5212_V4 && 322 common->keymax = (sc->ah->ah_version == AR5K_AR5210 ?
318 (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && 323 AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211);
319 !AR5K_EEPROM_AES_DIS(ee->ee_misc5)); 324
325 if (srev >= AR5K_SREV_AR5212_V4 &&
326 (ee->ee_version < AR5K_EEPROM_VERSION_5_0 ||
327 !AR5K_EEPROM_AES_DIS(ee->ee_misc5)))
328 common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM;
320 329
321 if (srev >= AR5K_SREV_AR2414) { 330 if (srev >= AR5K_SREV_AR2414) {
322 ah->ah_combined_mic = true; 331 common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
323 AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE, 332 AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE,
324 AR5K_MISC_MODE_COMBINED_MIC); 333 AR5K_MISC_MODE_COMBINED_MIC);
325 } 334 }
@@ -329,7 +338,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
329 338
330 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ 339 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
331 memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); 340 memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN);
332 ath5k_hw_set_associd(ah); 341 ath5k_hw_set_bssid(ah);
333 ath5k_hw_set_opmode(ah, sc->opmode); 342 ath5k_hw_set_opmode(ah, sc->opmode);
334 343
335 ath5k_hw_rfgain_opt_init(ah); 344 ath5k_hw_rfgain_opt_init(ah);
@@ -340,17 +349,16 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
340 ath5k_hw_set_ledstate(ah, AR5K_LED_INIT); 349 ath5k_hw_set_ledstate(ah, AR5K_LED_INIT);
341 350
342 return 0; 351 return 0;
343err_free: 352err:
344 kfree(ah);
345 return ret; 353 return ret;
346} 354}
347 355
348/** 356/**
349 * ath5k_hw_detach - Free the ath5k_hw struct 357 * ath5k_hw_deinit - Free the ath5k_hw struct
350 * 358 *
351 * @ah: The &struct ath5k_hw 359 * @ah: The &struct ath5k_hw
352 */ 360 */
353void ath5k_hw_detach(struct ath5k_hw *ah) 361void ath5k_hw_deinit(struct ath5k_hw *ah)
354{ 362{
355 __set_bit(ATH_STAT_INVALID, ah->ah_sc->status); 363 __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
356 364
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index d77ce9906b6c..b6c5d3715b96 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -47,11 +47,10 @@
47#include <linux/io.h> 47#include <linux/io.h>
48#include <linux/netdevice.h> 48#include <linux/netdevice.h>
49#include <linux/cache.h> 49#include <linux/cache.h>
50#include <linux/pci.h>
51#include <linux/pci-aspm.h>
52#include <linux/ethtool.h> 50#include <linux/ethtool.h>
53#include <linux/uaccess.h> 51#include <linux/uaccess.h>
54#include <linux/slab.h> 52#include <linux/slab.h>
53#include <linux/etherdevice.h>
55 54
56#include <net/ieee80211_radiotap.h> 55#include <net/ieee80211_radiotap.h>
57 56
@@ -62,18 +61,21 @@
62#include "debug.h" 61#include "debug.h"
63#include "ani.h" 62#include "ani.h"
64 63
65static int modparam_nohwcrypt; 64#define CREATE_TRACE_POINTS
66module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 65#include "trace.h"
66
67int ath5k_modparam_nohwcrypt;
68module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, S_IRUGO);
67MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 69MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
68 70
69static int modparam_all_channels; 71static int modparam_all_channels;
70module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO); 72module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO);
71MODULE_PARM_DESC(all_channels, "Expose all channels the device can use."); 73MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
72 74
75static int modparam_fastchanswitch;
76module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO);
77MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios.");
73 78
74/******************\
75* Internal defines *
76\******************/
77 79
78/* Module info */ 80/* Module info */
79MODULE_AUTHOR("Jiri Slaby"); 81MODULE_AUTHOR("Jiri Slaby");
@@ -81,35 +83,24 @@ MODULE_AUTHOR("Nick Kossifidis");
81MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); 83MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards.");
82MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); 84MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
83MODULE_LICENSE("Dual BSD/GPL"); 85MODULE_LICENSE("Dual BSD/GPL");
84MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); 86
85 87static int ath5k_init(struct ieee80211_hw *hw);
86 88static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
87/* Known PCI ids */ 89 bool skip_pcu);
88static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { 90int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
89 { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */ 91void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
90 { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */
91 { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/
92 { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */
93 { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */
94 { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */
95 { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */
96 { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */
97 { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */
98 { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */
99 { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */
100 { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */
101 { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */
102 { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */
103 { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */
104 { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
105 { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
106 { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
107 { 0 }
108};
109MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
110 92
111/* Known SREVs */ 93/* Known SREVs */
112static const struct ath5k_srev_name srev_names[] = { 94static const struct ath5k_srev_name srev_names[] = {
95#ifdef CONFIG_ATHEROS_AR231X
96 { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R2 },
97 { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R7 },
98 { "2313", AR5K_VERSION_MAC, AR5K_SREV_AR2313_R8 },
99 { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R6 },
100 { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R7 },
101 { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R1 },
102 { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R2 },
103#else
113 { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, 104 { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 },
114 { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 }, 105 { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 },
115 { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A }, 106 { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A },
@@ -128,6 +119,7 @@ static const struct ath5k_srev_name srev_names[] = {
128 { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 }, 119 { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 },
129 { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 }, 120 { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 },
130 { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 }, 121 { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 },
122#endif
131 { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN }, 123 { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN },
132 { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, 124 { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 },
133 { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, 125 { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 },
@@ -141,10 +133,12 @@ static const struct ath5k_srev_name srev_names[] = {
141 { "2112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112B }, 133 { "2112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112B },
142 { "2413", AR5K_VERSION_RAD, AR5K_SREV_RAD_2413 }, 134 { "2413", AR5K_VERSION_RAD, AR5K_SREV_RAD_2413 },
143 { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, 135 { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 },
144 { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 },
145 { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 },
146 { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, 136 { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 },
147 { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, 137 { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 },
138#ifdef CONFIG_ATHEROS_AR231X
139 { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 },
140 { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 },
141#endif
148 { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, 142 { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN },
149}; 143};
150 144
@@ -190,190 +184,6 @@ static const struct ieee80211_rate ath5k_rates[] = {
190 /* XR missing */ 184 /* XR missing */
191}; 185};
192 186
193/*
194 * Prototypes - PCI stack related functions
195 */
196static int __devinit ath5k_pci_probe(struct pci_dev *pdev,
197 const struct pci_device_id *id);
198static void __devexit ath5k_pci_remove(struct pci_dev *pdev);
199#ifdef CONFIG_PM_SLEEP
200static int ath5k_pci_suspend(struct device *dev);
201static int ath5k_pci_resume(struct device *dev);
202
203static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
204#define ATH5K_PM_OPS (&ath5k_pm_ops)
205#else
206#define ATH5K_PM_OPS NULL
207#endif /* CONFIG_PM_SLEEP */
208
209static struct pci_driver ath5k_pci_driver = {
210 .name = KBUILD_MODNAME,
211 .id_table = ath5k_pci_id_table,
212 .probe = ath5k_pci_probe,
213 .remove = __devexit_p(ath5k_pci_remove),
214 .driver.pm = ATH5K_PM_OPS,
215};
216
217
218
219/*
220 * Prototypes - MAC 802.11 stack related functions
221 */
222static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
223static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
224 struct ath5k_txq *txq);
225static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
226static int ath5k_start(struct ieee80211_hw *hw);
227static void ath5k_stop(struct ieee80211_hw *hw);
228static int ath5k_add_interface(struct ieee80211_hw *hw,
229 struct ieee80211_vif *vif);
230static void ath5k_remove_interface(struct ieee80211_hw *hw,
231 struct ieee80211_vif *vif);
232static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
233static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
234 struct netdev_hw_addr_list *mc_list);
235static void ath5k_configure_filter(struct ieee80211_hw *hw,
236 unsigned int changed_flags,
237 unsigned int *new_flags,
238 u64 multicast);
239static int ath5k_set_key(struct ieee80211_hw *hw,
240 enum set_key_cmd cmd,
241 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
242 struct ieee80211_key_conf *key);
243static int ath5k_get_stats(struct ieee80211_hw *hw,
244 struct ieee80211_low_level_stats *stats);
245static int ath5k_get_survey(struct ieee80211_hw *hw,
246 int idx, struct survey_info *survey);
247static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
248static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
249static void ath5k_reset_tsf(struct ieee80211_hw *hw);
250static int ath5k_beacon_update(struct ieee80211_hw *hw,
251 struct ieee80211_vif *vif);
252static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
253 struct ieee80211_vif *vif,
254 struct ieee80211_bss_conf *bss_conf,
255 u32 changes);
256static void ath5k_sw_scan_start(struct ieee80211_hw *hw);
257static void ath5k_sw_scan_complete(struct ieee80211_hw *hw);
258static void ath5k_set_coverage_class(struct ieee80211_hw *hw,
259 u8 coverage_class);
260
261static const struct ieee80211_ops ath5k_hw_ops = {
262 .tx = ath5k_tx,
263 .start = ath5k_start,
264 .stop = ath5k_stop,
265 .add_interface = ath5k_add_interface,
266 .remove_interface = ath5k_remove_interface,
267 .config = ath5k_config,
268 .prepare_multicast = ath5k_prepare_multicast,
269 .configure_filter = ath5k_configure_filter,
270 .set_key = ath5k_set_key,
271 .get_stats = ath5k_get_stats,
272 .get_survey = ath5k_get_survey,
273 .conf_tx = NULL,
274 .get_tsf = ath5k_get_tsf,
275 .set_tsf = ath5k_set_tsf,
276 .reset_tsf = ath5k_reset_tsf,
277 .bss_info_changed = ath5k_bss_info_changed,
278 .sw_scan_start = ath5k_sw_scan_start,
279 .sw_scan_complete = ath5k_sw_scan_complete,
280 .set_coverage_class = ath5k_set_coverage_class,
281};
282
283/*
284 * Prototypes - Internal functions
285 */
286/* Attach detach */
287static int ath5k_attach(struct pci_dev *pdev,
288 struct ieee80211_hw *hw);
289static void ath5k_detach(struct pci_dev *pdev,
290 struct ieee80211_hw *hw);
291/* Channel/mode setup */
292static inline short ath5k_ieee2mhz(short chan);
293static unsigned int ath5k_copy_channels(struct ath5k_hw *ah,
294 struct ieee80211_channel *channels,
295 unsigned int mode,
296 unsigned int max);
297static int ath5k_setup_bands(struct ieee80211_hw *hw);
298static int ath5k_chan_set(struct ath5k_softc *sc,
299 struct ieee80211_channel *chan);
300static void ath5k_setcurmode(struct ath5k_softc *sc,
301 unsigned int mode);
302static void ath5k_mode_setup(struct ath5k_softc *sc);
303
304/* Descriptor setup */
305static int ath5k_desc_alloc(struct ath5k_softc *sc,
306 struct pci_dev *pdev);
307static void ath5k_desc_free(struct ath5k_softc *sc,
308 struct pci_dev *pdev);
309/* Buffers setup */
310static int ath5k_rxbuf_setup(struct ath5k_softc *sc,
311 struct ath5k_buf *bf);
312static int ath5k_txbuf_setup(struct ath5k_softc *sc,
313 struct ath5k_buf *bf,
314 struct ath5k_txq *txq, int padsize);
315
316static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc,
317 struct ath5k_buf *bf)
318{
319 BUG_ON(!bf);
320 if (!bf->skb)
321 return;
322 pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len,
323 PCI_DMA_TODEVICE);
324 dev_kfree_skb_any(bf->skb);
325 bf->skb = NULL;
326 bf->skbaddr = 0;
327 bf->desc->ds_data = 0;
328}
329
330static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc,
331 struct ath5k_buf *bf)
332{
333 struct ath5k_hw *ah = sc->ah;
334 struct ath_common *common = ath5k_hw_common(ah);
335
336 BUG_ON(!bf);
337 if (!bf->skb)
338 return;
339 pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize,
340 PCI_DMA_FROMDEVICE);
341 dev_kfree_skb_any(bf->skb);
342 bf->skb = NULL;
343 bf->skbaddr = 0;
344 bf->desc->ds_data = 0;
345}
346
347
348/* Queues setup */
349static struct ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc,
350 int qtype, int subtype);
351static int ath5k_beaconq_setup(struct ath5k_hw *ah);
352static int ath5k_beaconq_config(struct ath5k_softc *sc);
353static void ath5k_txq_drainq(struct ath5k_softc *sc,
354 struct ath5k_txq *txq);
355static void ath5k_txq_cleanup(struct ath5k_softc *sc);
356static void ath5k_txq_release(struct ath5k_softc *sc);
357/* Rx handling */
358static int ath5k_rx_start(struct ath5k_softc *sc);
359static void ath5k_rx_stop(struct ath5k_softc *sc);
360static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc,
361 struct sk_buff *skb,
362 struct ath5k_rx_status *rs);
363static void ath5k_tasklet_rx(unsigned long data);
364/* Tx handling */
365static void ath5k_tx_processq(struct ath5k_softc *sc,
366 struct ath5k_txq *txq);
367static void ath5k_tasklet_tx(unsigned long data);
368/* Beacon handling */
369static int ath5k_beacon_setup(struct ath5k_softc *sc,
370 struct ath5k_buf *bf);
371static void ath5k_beacon_send(struct ath5k_softc *sc);
372static void ath5k_beacon_config(struct ath5k_softc *sc);
373static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
374static void ath5k_tasklet_beacon(unsigned long data);
375static void ath5k_tasklet_ani(unsigned long data);
376
377static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) 187static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
378{ 188{
379 u64 tsf = ath5k_hw_get_tsf64(ah); 189 u64 tsf = ath5k_hw_get_tsf64(ah);
@@ -384,51 +194,7 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
384 return (tsf & ~0x7fff) | rstamp; 194 return (tsf & ~0x7fff) | rstamp;
385} 195}
386 196
387/* Interrupt handling */ 197const char *
388static int ath5k_init(struct ath5k_softc *sc);
389static int ath5k_stop_locked(struct ath5k_softc *sc);
390static int ath5k_stop_hw(struct ath5k_softc *sc);
391static irqreturn_t ath5k_intr(int irq, void *dev_id);
392static void ath5k_reset_work(struct work_struct *work);
393
394static void ath5k_tasklet_calibrate(unsigned long data);
395
396/*
397 * Module init/exit functions
398 */
399static int __init
400init_ath5k_pci(void)
401{
402 int ret;
403
404 ath5k_debug_init();
405
406 ret = pci_register_driver(&ath5k_pci_driver);
407 if (ret) {
408 printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
409 return ret;
410 }
411
412 return 0;
413}
414
415static void __exit
416exit_ath5k_pci(void)
417{
418 pci_unregister_driver(&ath5k_pci_driver);
419
420 ath5k_debug_finish();
421}
422
423module_init(init_ath5k_pci);
424module_exit(exit_ath5k_pci);
425
426
427/********************\
428* PCI Initialization *
429\********************/
430
431static const char *
432ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) 198ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
433{ 199{
434 const char *name = "xxxxx"; 200 const char *name = "xxxxx";
@@ -466,299 +232,6 @@ static const struct ath_ops ath5k_common_ops = {
466 .write = ath5k_iowrite32, 232 .write = ath5k_iowrite32,
467}; 233};
468 234
469static int __devinit
470ath5k_pci_probe(struct pci_dev *pdev,
471 const struct pci_device_id *id)
472{
473 void __iomem *mem;
474 struct ath5k_softc *sc;
475 struct ath_common *common;
476 struct ieee80211_hw *hw;
477 int ret;
478 u8 csz;
479
480 /*
481 * L0s needs to be disabled on all ath5k cards.
482 *
483 * For distributions shipping with CONFIG_PCIEASPM (this will be enabled
484 * by default in the future in 2.6.36) this will also mean both L1 and
485 * L0s will be disabled when a pre 1.1 PCIe device is detected. We do
486 * know L1 works correctly even for all ath5k pre 1.1 PCIe devices
487 * though but cannot currently undue the effect of a blacklist, for
488 * details you can read pcie_aspm_sanity_check() and see how it adjusts
489 * the device link capability.
490 *
491 * It may be possible in the future to implement some PCI API to allow
492 * drivers to override blacklists for pre 1.1 PCIe but for now it is
493 * best to accept that both L0s and L1 will be disabled completely for
494 * distributions shipping with CONFIG_PCIEASPM rather than having this
495 * issue present. Motivation for adding this new API will be to help
496 * with power consumption for some of these devices.
497 */
498 pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
499
500 ret = pci_enable_device(pdev);
501 if (ret) {
502 dev_err(&pdev->dev, "can't enable device\n");
503 goto err;
504 }
505
506 /* XXX 32-bit addressing only */
507 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
508 if (ret) {
509 dev_err(&pdev->dev, "32-bit DMA not available\n");
510 goto err_dis;
511 }
512
513 /*
514 * Cache line size is used to size and align various
515 * structures used to communicate with the hardware.
516 */
517 pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
518 if (csz == 0) {
519 /*
520 * Linux 2.4.18 (at least) writes the cache line size
521 * register as a 16-bit wide register which is wrong.
522 * We must have this setup properly for rx buffer
523 * DMA to work so force a reasonable value here if it
524 * comes up zero.
525 */
526 csz = L1_CACHE_BYTES >> 2;
527 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
528 }
529 /*
530 * The default setting of latency timer yields poor results,
531 * set it to the value used by other systems. It may be worth
532 * tweaking this setting more.
533 */
534 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
535
536 /* Enable bus mastering */
537 pci_set_master(pdev);
538
539 /*
540 * Disable the RETRY_TIMEOUT register (0x41) to keep
541 * PCI Tx retries from interfering with C3 CPU state.
542 */
543 pci_write_config_byte(pdev, 0x41, 0);
544
545 ret = pci_request_region(pdev, 0, "ath5k");
546 if (ret) {
547 dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
548 goto err_dis;
549 }
550
551 mem = pci_iomap(pdev, 0, 0);
552 if (!mem) {
553 dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
554 ret = -EIO;
555 goto err_reg;
556 }
557
558 /*
559 * Allocate hw (mac80211 main struct)
560 * and hw->priv (driver private data)
561 */
562 hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
563 if (hw == NULL) {
564 dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
565 ret = -ENOMEM;
566 goto err_map;
567 }
568
569 dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
570
571 /* Initialize driver private data */
572 SET_IEEE80211_DEV(hw, &pdev->dev);
573 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
574 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
575 IEEE80211_HW_SIGNAL_DBM;
576
577 hw->wiphy->interface_modes =
578 BIT(NL80211_IFTYPE_AP) |
579 BIT(NL80211_IFTYPE_STATION) |
580 BIT(NL80211_IFTYPE_ADHOC) |
581 BIT(NL80211_IFTYPE_MESH_POINT);
582
583 hw->extra_tx_headroom = 2;
584 hw->channel_change_time = 5000;
585 sc = hw->priv;
586 sc->hw = hw;
587 sc->pdev = pdev;
588
589 ath5k_debug_init_device(sc);
590
591 /*
592 * Mark the device as detached to avoid processing
593 * interrupts until setup is complete.
594 */
595 __set_bit(ATH_STAT_INVALID, sc->status);
596
597 sc->iobase = mem; /* So we can unmap it on detach */
598 sc->opmode = NL80211_IFTYPE_STATION;
599 sc->bintval = 1000;
600 mutex_init(&sc->lock);
601 spin_lock_init(&sc->rxbuflock);
602 spin_lock_init(&sc->txbuflock);
603 spin_lock_init(&sc->block);
604
605 /* Set private data */
606 pci_set_drvdata(pdev, sc);
607
608 /* Setup interrupt handler */
609 ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
610 if (ret) {
611 ATH5K_ERR(sc, "request_irq failed\n");
612 goto err_free;
613 }
614
615 /*If we passed the test malloc a ath5k_hw struct*/
616 sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
617 if (!sc->ah) {
618 ret = -ENOMEM;
619 ATH5K_ERR(sc, "out of memory\n");
620 goto err_irq;
621 }
622
623 sc->ah->ah_sc = sc;
624 sc->ah->ah_iobase = sc->iobase;
625 common = ath5k_hw_common(sc->ah);
626 common->ops = &ath5k_common_ops;
627 common->ah = sc->ah;
628 common->hw = hw;
629 common->cachelsz = csz << 2; /* convert to bytes */
630
631 /* Initialize device */
632 ret = ath5k_hw_attach(sc);
633 if (ret) {
634 goto err_free_ah;
635 }
636
637 /* set up multi-rate retry capabilities */
638 if (sc->ah->ah_version == AR5K_AR5212) {
639 hw->max_rates = 4;
640 hw->max_rate_tries = 11;
641 }
642
643 /* Finish private driver data initialization */
644 ret = ath5k_attach(pdev, hw);
645 if (ret)
646 goto err_ah;
647
648 ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
649 ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
650 sc->ah->ah_mac_srev,
651 sc->ah->ah_phy_revision);
652
653 if (!sc->ah->ah_single_chip) {
654 /* Single chip radio (!RF5111) */
655 if (sc->ah->ah_radio_5ghz_revision &&
656 !sc->ah->ah_radio_2ghz_revision) {
657 /* No 5GHz support -> report 2GHz radio */
658 if (!test_bit(AR5K_MODE_11A,
659 sc->ah->ah_capabilities.cap_mode)) {
660 ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
661 ath5k_chip_name(AR5K_VERSION_RAD,
662 sc->ah->ah_radio_5ghz_revision),
663 sc->ah->ah_radio_5ghz_revision);
664 /* No 2GHz support (5110 and some
665 * 5Ghz only cards) -> report 5Ghz radio */
666 } else if (!test_bit(AR5K_MODE_11B,
667 sc->ah->ah_capabilities.cap_mode)) {
668 ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
669 ath5k_chip_name(AR5K_VERSION_RAD,
670 sc->ah->ah_radio_5ghz_revision),
671 sc->ah->ah_radio_5ghz_revision);
672 /* Multiband radio */
673 } else {
674 ATH5K_INFO(sc, "RF%s multiband radio found"
675 " (0x%x)\n",
676 ath5k_chip_name(AR5K_VERSION_RAD,
677 sc->ah->ah_radio_5ghz_revision),
678 sc->ah->ah_radio_5ghz_revision);
679 }
680 }
681 /* Multi chip radio (RF5111 - RF2111) ->
682 * report both 2GHz/5GHz radios */
683 else if (sc->ah->ah_radio_5ghz_revision &&
684 sc->ah->ah_radio_2ghz_revision){
685 ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
686 ath5k_chip_name(AR5K_VERSION_RAD,
687 sc->ah->ah_radio_5ghz_revision),
688 sc->ah->ah_radio_5ghz_revision);
689 ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
690 ath5k_chip_name(AR5K_VERSION_RAD,
691 sc->ah->ah_radio_2ghz_revision),
692 sc->ah->ah_radio_2ghz_revision);
693 }
694 }
695
696
697 /* ready to process interrupts */
698 __clear_bit(ATH_STAT_INVALID, sc->status);
699
700 return 0;
701err_ah:
702 ath5k_hw_detach(sc->ah);
703err_irq:
704 free_irq(pdev->irq, sc);
705err_free_ah:
706 kfree(sc->ah);
707err_free:
708 ieee80211_free_hw(hw);
709err_map:
710 pci_iounmap(pdev, mem);
711err_reg:
712 pci_release_region(pdev, 0);
713err_dis:
714 pci_disable_device(pdev);
715err:
716 return ret;
717}
718
719static void __devexit
720ath5k_pci_remove(struct pci_dev *pdev)
721{
722 struct ath5k_softc *sc = pci_get_drvdata(pdev);
723
724 ath5k_debug_finish_device(sc);
725 ath5k_detach(pdev, sc->hw);
726 ath5k_hw_detach(sc->ah);
727 kfree(sc->ah);
728 free_irq(pdev->irq, sc);
729 pci_iounmap(pdev, sc->iobase);
730 pci_release_region(pdev, 0);
731 pci_disable_device(pdev);
732 ieee80211_free_hw(sc->hw);
733}
734
735#ifdef CONFIG_PM_SLEEP
736static int ath5k_pci_suspend(struct device *dev)
737{
738 struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
739
740 ath5k_led_off(sc);
741 return 0;
742}
743
744static int ath5k_pci_resume(struct device *dev)
745{
746 struct pci_dev *pdev = to_pci_dev(dev);
747 struct ath5k_softc *sc = pci_get_drvdata(pdev);
748
749 /*
750 * Suspend/Resume resets the PCI configuration space, so we have to
751 * re-disable the RETRY_TIMEOUT register (0x41) to keep
752 * PCI Tx retries from interfering with C3 CPU state
753 */
754 pci_write_config_byte(pdev, 0x41, 0);
755
756 ath5k_led_enable(sc);
757 return 0;
758}
759#endif /* CONFIG_PM_SLEEP */
760
761
762/***********************\ 235/***********************\
763* Driver Initialization * 236* Driver Initialization *
764\***********************/ 237\***********************/
@@ -772,260 +245,83 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re
772 return ath_reg_notifier_apply(wiphy, request, regulatory); 245 return ath_reg_notifier_apply(wiphy, request, regulatory);
773} 246}
774 247
775static int
776ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
777{
778 struct ath5k_softc *sc = hw->priv;
779 struct ath5k_hw *ah = sc->ah;
780 struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
781 u8 mac[ETH_ALEN] = {};
782 int ret;
783
784 ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
785
786 /*
787 * Check if the MAC has multi-rate retry support.
788 * We do this by trying to setup a fake extended
789 * descriptor. MAC's that don't have support will
790 * return false w/o doing anything. MAC's that do
791 * support it will return true w/o doing anything.
792 */
793 ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
794
795 if (ret < 0)
796 goto err;
797 if (ret > 0)
798 __set_bit(ATH_STAT_MRRETRY, sc->status);
799
800 /*
801 * Collect the channel list. The 802.11 layer
802 * is resposible for filtering this list based
803 * on settings like the phy mode and regulatory
804 * domain restrictions.
805 */
806 ret = ath5k_setup_bands(hw);
807 if (ret) {
808 ATH5K_ERR(sc, "can't get channels\n");
809 goto err;
810 }
811
812 /* NB: setup here so ath5k_rate_update is happy */
813 if (test_bit(AR5K_MODE_11A, ah->ah_modes))
814 ath5k_setcurmode(sc, AR5K_MODE_11A);
815 else
816 ath5k_setcurmode(sc, AR5K_MODE_11B);
817
818 /*
819 * Allocate tx+rx descriptors and populate the lists.
820 */
821 ret = ath5k_desc_alloc(sc, pdev);
822 if (ret) {
823 ATH5K_ERR(sc, "can't allocate descriptors\n");
824 goto err;
825 }
826
827 /*
828 * Allocate hardware transmit queues: one queue for
829 * beacon frames and one data queue for each QoS
830 * priority. Note that hw functions handle reseting
831 * these queues at the needed time.
832 */
833 ret = ath5k_beaconq_setup(ah);
834 if (ret < 0) {
835 ATH5K_ERR(sc, "can't setup a beacon xmit queue\n");
836 goto err_desc;
837 }
838 sc->bhalq = ret;
839 sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0);
840 if (IS_ERR(sc->cabq)) {
841 ATH5K_ERR(sc, "can't setup cab queue\n");
842 ret = PTR_ERR(sc->cabq);
843 goto err_bhal;
844 }
845
846 sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
847 if (IS_ERR(sc->txq)) {
848 ATH5K_ERR(sc, "can't setup xmit queue\n");
849 ret = PTR_ERR(sc->txq);
850 goto err_queues;
851 }
852
853 tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
854 tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
855 tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc);
856 tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
857 tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc);
858
859 INIT_WORK(&sc->reset_work, ath5k_reset_work);
860
861 ret = ath5k_eeprom_read_mac(ah, mac);
862 if (ret) {
863 ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
864 sc->pdev->device);
865 goto err_queues;
866 }
867
868 SET_IEEE80211_PERM_ADDR(hw, mac);
869 /* All MAC address bits matter for ACKs */
870 memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
871 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
872
873 regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
874 ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
875 if (ret) {
876 ATH5K_ERR(sc, "can't initialize regulatory system\n");
877 goto err_queues;
878 }
879
880 ret = ieee80211_register_hw(hw);
881 if (ret) {
882 ATH5K_ERR(sc, "can't register ieee80211 hw\n");
883 goto err_queues;
884 }
885
886 if (!ath_is_world_regd(regulatory))
887 regulatory_hint(hw->wiphy, regulatory->alpha2);
888
889 ath5k_init_leds(sc);
890
891 ath5k_sysfs_register(sc);
892
893 return 0;
894err_queues:
895 ath5k_txq_release(sc);
896err_bhal:
897 ath5k_hw_release_tx_queue(ah, sc->bhalq);
898err_desc:
899 ath5k_desc_free(sc, pdev);
900err:
901 return ret;
902}
903
904static void
905ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
906{
907 struct ath5k_softc *sc = hw->priv;
908
909 /*
910 * NB: the order of these is important:
911 * o call the 802.11 layer before detaching ath5k_hw to
912 * insure callbacks into the driver to delete global
913 * key cache entries can be handled
914 * o reclaim the tx queue data structures after calling
915 * the 802.11 layer as we'll get called back to reclaim
916 * node state and potentially want to use them
917 * o to cleanup the tx queues the hal is called, so detach
918 * it last
919 * XXX: ??? detach ath5k_hw ???
920 * Other than that, it's straightforward...
921 */
922 ieee80211_unregister_hw(hw);
923 ath5k_desc_free(sc, pdev);
924 ath5k_txq_release(sc);
925 ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
926 ath5k_unregister_leds(sc);
927
928 ath5k_sysfs_unregister(sc);
929 /*
930 * NB: can't reclaim these until after ieee80211_ifdetach
931 * returns because we'll get called back to reclaim node
932 * state and potentially want to use them.
933 */
934}
935
936
937
938
939/********************\ 248/********************\
940* Channel/mode setup * 249* Channel/mode setup *
941\********************/ 250\********************/
942 251
943/* 252/*
944 * Convert IEEE channel number to MHz frequency.
945 */
946static inline short
947ath5k_ieee2mhz(short chan)
948{
949 if (chan <= 14 || chan >= 27)
950 return ieee80211chan2mhz(chan);
951 else
952 return 2212 + chan * 20;
953}
954
955/*
956 * Returns true for the channel numbers used without all_channels modparam. 253 * Returns true for the channel numbers used without all_channels modparam.
957 */ 254 */
958static bool ath5k_is_standard_channel(short chan) 255static bool ath5k_is_standard_channel(short chan, enum ieee80211_band band)
959{ 256{
960 return ((chan <= 14) || 257 if (band == IEEE80211_BAND_2GHZ && chan <= 14)
961 /* UNII 1,2 */ 258 return true;
962 ((chan & 3) == 0 && chan >= 36 && chan <= 64) || 259
260 return /* UNII 1,2 */
261 (((chan & 3) == 0 && chan >= 36 && chan <= 64) ||
963 /* midband */ 262 /* midband */
964 ((chan & 3) == 0 && chan >= 100 && chan <= 140) || 263 ((chan & 3) == 0 && chan >= 100 && chan <= 140) ||
965 /* UNII-3 */ 264 /* UNII-3 */
966 ((chan & 3) == 1 && chan >= 149 && chan <= 165)); 265 ((chan & 3) == 1 && chan >= 149 && chan <= 165) ||
266 /* 802.11j 5.030-5.080 GHz (20MHz) */
267 (chan == 8 || chan == 12 || chan == 16) ||
268 /* 802.11j 4.9GHz (20MHz) */
269 (chan == 184 || chan == 188 || chan == 192 || chan == 196));
967} 270}
968 271
969static unsigned int 272static unsigned int
970ath5k_copy_channels(struct ath5k_hw *ah, 273ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels,
971 struct ieee80211_channel *channels, 274 unsigned int mode, unsigned int max)
972 unsigned int mode,
973 unsigned int max)
974{ 275{
975 unsigned int i, count, size, chfreq, freq, ch; 276 unsigned int count, size, chfreq, freq, ch;
976 277 enum ieee80211_band band;
977 if (!test_bit(mode, ah->ah_modes))
978 return 0;
979 278
980 switch (mode) { 279 switch (mode) {
981 case AR5K_MODE_11A: 280 case AR5K_MODE_11A:
982 case AR5K_MODE_11A_TURBO:
983 /* 1..220, but 2GHz frequencies are filtered by check_channel */ 281 /* 1..220, but 2GHz frequencies are filtered by check_channel */
984 size = 220 ; 282 size = 220;
985 chfreq = CHANNEL_5GHZ; 283 chfreq = CHANNEL_5GHZ;
284 band = IEEE80211_BAND_5GHZ;
986 break; 285 break;
987 case AR5K_MODE_11B: 286 case AR5K_MODE_11B:
988 case AR5K_MODE_11G: 287 case AR5K_MODE_11G:
989 case AR5K_MODE_11G_TURBO:
990 size = 26; 288 size = 26;
991 chfreq = CHANNEL_2GHZ; 289 chfreq = CHANNEL_2GHZ;
290 band = IEEE80211_BAND_2GHZ;
992 break; 291 break;
993 default: 292 default:
994 ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n"); 293 ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n");
995 return 0; 294 return 0;
996 } 295 }
997 296
998 for (i = 0, count = 0; i < size && max > 0; i++) { 297 count = 0;
999 ch = i + 1 ; 298 for (ch = 1; ch <= size && count < max; ch++) {
1000 freq = ath5k_ieee2mhz(ch); 299 freq = ieee80211_channel_to_frequency(ch, band);
300
301 if (freq == 0) /* mapping failed - not a standard channel */
302 continue;
1001 303
1002 /* Check if channel is supported by the chipset */ 304 /* Check if channel is supported by the chipset */
1003 if (!ath5k_channel_ok(ah, freq, chfreq)) 305 if (!ath5k_channel_ok(ah, freq, chfreq))
1004 continue; 306 continue;
1005 307
1006 if (!modparam_all_channels && !ath5k_is_standard_channel(ch)) 308 if (!modparam_all_channels &&
309 !ath5k_is_standard_channel(ch, band))
1007 continue; 310 continue;
1008 311
1009 /* Write channel info and increment counter */ 312 /* Write channel info and increment counter */
1010 channels[count].center_freq = freq; 313 channels[count].center_freq = freq;
1011 channels[count].band = (chfreq == CHANNEL_2GHZ) ? 314 channels[count].band = band;
1012 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
1013 switch (mode) { 315 switch (mode) {
1014 case AR5K_MODE_11A: 316 case AR5K_MODE_11A:
1015 case AR5K_MODE_11G: 317 case AR5K_MODE_11G:
1016 channels[count].hw_value = chfreq | CHANNEL_OFDM; 318 channels[count].hw_value = chfreq | CHANNEL_OFDM;
1017 break; 319 break;
1018 case AR5K_MODE_11A_TURBO:
1019 case AR5K_MODE_11G_TURBO:
1020 channels[count].hw_value = chfreq |
1021 CHANNEL_OFDM | CHANNEL_TURBO;
1022 break;
1023 case AR5K_MODE_11B: 320 case AR5K_MODE_11B:
1024 channels[count].hw_value = CHANNEL_B; 321 channels[count].hw_value = CHANNEL_B;
1025 } 322 }
1026 323
1027 count++; 324 count++;
1028 max--;
1029 } 325 }
1030 326
1031 return count; 327 return count;
@@ -1070,7 +366,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
1070 sband->n_bitrates = 12; 366 sband->n_bitrates = 12;
1071 367
1072 sband->channels = sc->channels; 368 sband->channels = sc->channels;
1073 sband->n_channels = ath5k_copy_channels(ah, sband->channels, 369 sband->n_channels = ath5k_setup_channels(ah, sband->channels,
1074 AR5K_MODE_11G, max_c); 370 AR5K_MODE_11G, max_c);
1075 371
1076 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; 372 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
@@ -1096,7 +392,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
1096 } 392 }
1097 393
1098 sband->channels = sc->channels; 394 sband->channels = sc->channels;
1099 sband->n_channels = ath5k_copy_channels(ah, sband->channels, 395 sband->n_channels = ath5k_setup_channels(ah, sband->channels,
1100 AR5K_MODE_11B, max_c); 396 AR5K_MODE_11B, max_c);
1101 397
1102 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; 398 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
@@ -1116,7 +412,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
1116 sband->n_bitrates = 8; 412 sband->n_bitrates = 8;
1117 413
1118 sband->channels = &sc->channels[count_c]; 414 sband->channels = &sc->channels[count_c];
1119 sband->n_channels = ath5k_copy_channels(ah, sband->channels, 415 sband->n_channels = ath5k_setup_channels(ah, sband->channels,
1120 AR5K_MODE_11A, max_c); 416 AR5K_MODE_11A, max_c);
1121 417
1122 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; 418 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
@@ -1135,7 +431,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
1135 * 431 *
1136 * Called with sc->lock. 432 * Called with sc->lock.
1137 */ 433 */
1138static int 434int
1139ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) 435ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
1140{ 436{
1141 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, 437 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
@@ -1148,38 +444,102 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
1148 * hardware at the new frequency, and then re-enable 444 * hardware at the new frequency, and then re-enable
1149 * the relevant bits of the h/w. 445 * the relevant bits of the h/w.
1150 */ 446 */
1151 return ath5k_reset(sc, chan); 447 return ath5k_reset(sc, chan, true);
1152} 448}
1153 449
1154static void 450void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1155ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
1156{ 451{
1157 sc->curmode = mode; 452 struct ath5k_vif_iter_data *iter_data = data;
453 int i;
454 struct ath5k_vif *avf = (void *)vif->drv_priv;
1158 455
1159 if (mode == AR5K_MODE_11A) { 456 if (iter_data->hw_macaddr)
1160 sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ]; 457 for (i = 0; i < ETH_ALEN; i++)
1161 } else { 458 iter_data->mask[i] &=
1162 sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ]; 459 ~(iter_data->hw_macaddr[i] ^ mac[i]);
460
461 if (!iter_data->found_active) {
462 iter_data->found_active = true;
463 memcpy(iter_data->active_mac, mac, ETH_ALEN);
464 }
465
466 if (iter_data->need_set_hw_addr && iter_data->hw_macaddr)
467 if (compare_ether_addr(iter_data->hw_macaddr, mac) == 0)
468 iter_data->need_set_hw_addr = false;
469
470 if (!iter_data->any_assoc) {
471 if (avf->assoc)
472 iter_data->any_assoc = true;
473 }
474
475 /* Calculate combined mode - when APs are active, operate in AP mode.
476 * Otherwise use the mode of the new interface. This can currently
477 * only deal with combinations of APs and STAs. Only one ad-hoc
478 * interfaces is allowed.
479 */
480 if (avf->opmode == NL80211_IFTYPE_AP)
481 iter_data->opmode = NL80211_IFTYPE_AP;
482 else {
483 if (avf->opmode == NL80211_IFTYPE_STATION)
484 iter_data->n_stas++;
485 if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED)
486 iter_data->opmode = avf->opmode;
1163 } 487 }
1164} 488}
1165 489
1166static void 490void
1167ath5k_mode_setup(struct ath5k_softc *sc) 491ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
492 struct ieee80211_vif *vif)
1168{ 493{
1169 struct ath5k_hw *ah = sc->ah; 494 struct ath_common *common = ath5k_hw_common(sc->ah);
495 struct ath5k_vif_iter_data iter_data;
1170 u32 rfilt; 496 u32 rfilt;
1171 497
1172 /* configure rx filter */ 498 /*
1173 rfilt = sc->filter_flags; 499 * Use the hardware MAC address as reference, the hardware uses it
1174 ath5k_hw_set_rx_filter(ah, rfilt); 500 * together with the BSSID mask when matching addresses.
1175 501 */
1176 if (ath5k_hw_hasbssidmask(ah)) 502 iter_data.hw_macaddr = common->macaddr;
1177 ath5k_hw_set_bssid_mask(ah, sc->bssidmask); 503 memset(&iter_data.mask, 0xff, ETH_ALEN);
1178 504 iter_data.found_active = false;
1179 /* configure operational mode */ 505 iter_data.need_set_hw_addr = true;
1180 ath5k_hw_set_opmode(ah, sc->opmode); 506 iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED;
507 iter_data.n_stas = 0;
508
509 if (vif)
510 ath5k_vif_iter(&iter_data, vif->addr, vif);
511
512 /* Get list of all active MAC addresses */
513 ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter,
514 &iter_data);
515 memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN);
516
517 sc->opmode = iter_data.opmode;
518 if (sc->opmode == NL80211_IFTYPE_UNSPECIFIED)
519 /* Nothing active, default to station mode */
520 sc->opmode = NL80211_IFTYPE_STATION;
521
522 ath5k_hw_set_opmode(sc->ah, sc->opmode);
523 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n",
524 sc->opmode, ath_opmode_to_string(sc->opmode));
525
526 if (iter_data.need_set_hw_addr && iter_data.found_active)
527 ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac);
528
529 if (ath5k_hw_hasbssidmask(sc->ah))
530 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
531
532 /* Set up RX Filter */
533 if (iter_data.n_stas > 1) {
534 /* If you have multiple STA interfaces connected to
535 * different APs, ARPs are not received (most of the time?)
536 * Enabling PROMISC appears to fix that probem.
537 */
538 sc->filter_flags |= AR5K_RX_FILTER_PROM;
539 }
1181 540
1182 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode); 541 rfilt = sc->filter_flags;
542 ath5k_hw_set_rx_filter(sc->ah, rfilt);
1183 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); 543 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
1184} 544}
1185 545
@@ -1193,7 +553,7 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
1193 "hw_rix out of bounds: %x\n", hw_rix)) 553 "hw_rix out of bounds: %x\n", hw_rix))
1194 return 0; 554 return 0;
1195 555
1196 rix = sc->rate_idx[sc->curband->band][hw_rix]; 556 rix = sc->rate_idx[sc->curchan->band][hw_rix];
1197 if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix)) 557 if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix))
1198 rix = 0; 558 rix = 0;
1199 559
@@ -1224,10 +584,11 @@ struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
1224 return NULL; 584 return NULL;
1225 } 585 }
1226 586
1227 *skb_addr = pci_map_single(sc->pdev, 587 *skb_addr = dma_map_single(sc->dev,
1228 skb->data, common->rx_bufsize, 588 skb->data, common->rx_bufsize,
1229 PCI_DMA_FROMDEVICE); 589 DMA_FROM_DEVICE);
1230 if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) { 590
591 if (unlikely(dma_mapping_error(sc->dev, *skb_addr))) {
1231 ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); 592 ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
1232 dev_kfree_skb(skb); 593 dev_kfree_skb(skb);
1233 return NULL; 594 return NULL;
@@ -1323,8 +684,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1323 flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; 684 flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
1324 685
1325 /* XXX endianness */ 686 /* XXX endianness */
1326 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, 687 bf->skbaddr = dma_map_single(sc->dev, skb->data, skb->len,
1327 PCI_DMA_TODEVICE); 688 DMA_TO_DEVICE);
1328 689
1329 rate = ieee80211_get_tx_rate(sc->hw, info); 690 rate = ieee80211_get_tx_rate(sc->hw, info);
1330 if (!rate) { 691 if (!rate) {
@@ -1352,13 +713,13 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1352 flags |= AR5K_TXDESC_RTSENA; 713 flags |= AR5K_TXDESC_RTSENA;
1353 cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; 714 cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
1354 duration = le16_to_cpu(ieee80211_rts_duration(sc->hw, 715 duration = le16_to_cpu(ieee80211_rts_duration(sc->hw,
1355 sc->vif, pktlen, info)); 716 info->control.vif, pktlen, info));
1356 } 717 }
1357 if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { 718 if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
1358 flags |= AR5K_TXDESC_CTSENA; 719 flags |= AR5K_TXDESC_CTSENA;
1359 cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; 720 cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
1360 duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw, 721 duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw,
1361 sc->vif, pktlen, info)); 722 info->control.vif, pktlen, info));
1362 } 723 }
1363 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 724 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
1364 ieee80211_get_hdrlen_from_skb(skb), padsize, 725 ieee80211_get_hdrlen_from_skb(skb), padsize,
@@ -1391,6 +752,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1391 752
1392 spin_lock_bh(&txq->lock); 753 spin_lock_bh(&txq->lock);
1393 list_add_tail(&bf->list, &txq->q); 754 list_add_tail(&bf->list, &txq->q);
755 txq->txq_len++;
1394 if (txq->link == NULL) /* is this first packet? */ 756 if (txq->link == NULL) /* is this first packet? */
1395 ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); 757 ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr);
1396 else /* no, so only link it */ 758 else /* no, so only link it */
@@ -1403,7 +765,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1403 765
1404 return 0; 766 return 0;
1405err_unmap: 767err_unmap:
1406 pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE); 768 dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE);
1407 return ret; 769 return ret;
1408} 770}
1409 771
@@ -1412,7 +774,7 @@ err_unmap:
1412\*******************/ 774\*******************/
1413 775
1414static int 776static int
1415ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev) 777ath5k_desc_alloc(struct ath5k_softc *sc)
1416{ 778{
1417 struct ath5k_desc *ds; 779 struct ath5k_desc *ds;
1418 struct ath5k_buf *bf; 780 struct ath5k_buf *bf;
@@ -1423,7 +785,9 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
1423 /* allocate descriptors */ 785 /* allocate descriptors */
1424 sc->desc_len = sizeof(struct ath5k_desc) * 786 sc->desc_len = sizeof(struct ath5k_desc) *
1425 (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1); 787 (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1);
1426 sc->desc = pci_alloc_consistent(pdev, sc->desc_len, &sc->desc_daddr); 788
789 sc->desc = dma_alloc_coherent(sc->dev, sc->desc_len,
790 &sc->desc_daddr, GFP_KERNEL);
1427 if (sc->desc == NULL) { 791 if (sc->desc == NULL) {
1428 ATH5K_ERR(sc, "can't allocate descriptors\n"); 792 ATH5K_ERR(sc, "can't allocate descriptors\n");
1429 ret = -ENOMEM; 793 ret = -ENOMEM;
@@ -1459,44 +823,75 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
1459 list_add_tail(&bf->list, &sc->txbuf); 823 list_add_tail(&bf->list, &sc->txbuf);
1460 } 824 }
1461 825
1462 /* beacon buffer */ 826 /* beacon buffers */
1463 bf->desc = ds; 827 INIT_LIST_HEAD(&sc->bcbuf);
1464 bf->daddr = da; 828 for (i = 0; i < ATH_BCBUF; i++, bf++, ds++, da += sizeof(*ds)) {
1465 sc->bbuf = bf; 829 bf->desc = ds;
830 bf->daddr = da;
831 list_add_tail(&bf->list, &sc->bcbuf);
832 }
1466 833
1467 return 0; 834 return 0;
1468err_free: 835err_free:
1469 pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); 836 dma_free_coherent(sc->dev, sc->desc_len, sc->desc, sc->desc_daddr);
1470err: 837err:
1471 sc->desc = NULL; 838 sc->desc = NULL;
1472 return ret; 839 return ret;
1473} 840}
1474 841
842void
843ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf)
844{
845 BUG_ON(!bf);
846 if (!bf->skb)
847 return;
848 dma_unmap_single(sc->dev, bf->skbaddr, bf->skb->len,
849 DMA_TO_DEVICE);
850 dev_kfree_skb_any(bf->skb);
851 bf->skb = NULL;
852 bf->skbaddr = 0;
853 bf->desc->ds_data = 0;
854}
855
856void
857ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf)
858{
859 struct ath5k_hw *ah = sc->ah;
860 struct ath_common *common = ath5k_hw_common(ah);
861
862 BUG_ON(!bf);
863 if (!bf->skb)
864 return;
865 dma_unmap_single(sc->dev, bf->skbaddr, common->rx_bufsize,
866 DMA_FROM_DEVICE);
867 dev_kfree_skb_any(bf->skb);
868 bf->skb = NULL;
869 bf->skbaddr = 0;
870 bf->desc->ds_data = 0;
871}
872
1475static void 873static void
1476ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev) 874ath5k_desc_free(struct ath5k_softc *sc)
1477{ 875{
1478 struct ath5k_buf *bf; 876 struct ath5k_buf *bf;
1479 877
1480 ath5k_txbuf_free_skb(sc, sc->bbuf);
1481 list_for_each_entry(bf, &sc->txbuf, list) 878 list_for_each_entry(bf, &sc->txbuf, list)
1482 ath5k_txbuf_free_skb(sc, bf); 879 ath5k_txbuf_free_skb(sc, bf);
1483 list_for_each_entry(bf, &sc->rxbuf, list) 880 list_for_each_entry(bf, &sc->rxbuf, list)
1484 ath5k_rxbuf_free_skb(sc, bf); 881 ath5k_rxbuf_free_skb(sc, bf);
882 list_for_each_entry(bf, &sc->bcbuf, list)
883 ath5k_txbuf_free_skb(sc, bf);
1485 884
1486 /* Free memory associated with all descriptors */ 885 /* Free memory associated with all descriptors */
1487 pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); 886 dma_free_coherent(sc->dev, sc->desc_len, sc->desc, sc->desc_daddr);
1488 sc->desc = NULL; 887 sc->desc = NULL;
1489 sc->desc_daddr = 0; 888 sc->desc_daddr = 0;
1490 889
1491 kfree(sc->bufptr); 890 kfree(sc->bufptr);
1492 sc->bufptr = NULL; 891 sc->bufptr = NULL;
1493 sc->bbuf = NULL;
1494} 892}
1495 893
1496 894
1497
1498
1499
1500/**************\ 895/**************\
1501* Queues setup * 896* Queues setup *
1502\**************/ 897\**************/
@@ -1509,16 +904,18 @@ ath5k_txq_setup(struct ath5k_softc *sc,
1509 struct ath5k_txq *txq; 904 struct ath5k_txq *txq;
1510 struct ath5k_txq_info qi = { 905 struct ath5k_txq_info qi = {
1511 .tqi_subtype = subtype, 906 .tqi_subtype = subtype,
1512 .tqi_aifs = AR5K_TXQ_USEDEFAULT, 907 /* XXX: default values not correct for B and XR channels,
1513 .tqi_cw_min = AR5K_TXQ_USEDEFAULT, 908 * but who cares? */
1514 .tqi_cw_max = AR5K_TXQ_USEDEFAULT 909 .tqi_aifs = AR5K_TUNE_AIFS,
910 .tqi_cw_min = AR5K_TUNE_CWMIN,
911 .tqi_cw_max = AR5K_TUNE_CWMAX
1515 }; 912 };
1516 int qnum; 913 int qnum;
1517 914
1518 /* 915 /*
1519 * Enable interrupts only for EOL and DESC conditions. 916 * Enable interrupts only for EOL and DESC conditions.
1520 * We mark tx descriptors to receive a DESC interrupt 917 * We mark tx descriptors to receive a DESC interrupt
1521 * when a tx queue gets deep; otherwise waiting for the 918 * when a tx queue gets deep; otherwise we wait for the
1522 * EOL to reap descriptors. Note that this is done to 919 * EOL to reap descriptors. Note that this is done to
1523 * reduce interrupt load and this only defers reaping 920 * reduce interrupt load and this only defers reaping
1524 * descriptors, never transmitting frames. Aside from 921 * descriptors, never transmitting frames. Aside from
@@ -1550,6 +947,10 @@ ath5k_txq_setup(struct ath5k_softc *sc,
1550 INIT_LIST_HEAD(&txq->q); 947 INIT_LIST_HEAD(&txq->q);
1551 spin_lock_init(&txq->lock); 948 spin_lock_init(&txq->lock);
1552 txq->setup = true; 949 txq->setup = true;
950 txq->txq_len = 0;
951 txq->txq_max = ATH5K_TXQ_LEN_MAX;
952 txq->txq_poll_mark = false;
953 txq->txq_stuck = 0;
1553 } 954 }
1554 return &sc->txqs[qnum]; 955 return &sc->txqs[qnum];
1555} 956}
@@ -1558,9 +959,11 @@ static int
1558ath5k_beaconq_setup(struct ath5k_hw *ah) 959ath5k_beaconq_setup(struct ath5k_hw *ah)
1559{ 960{
1560 struct ath5k_txq_info qi = { 961 struct ath5k_txq_info qi = {
1561 .tqi_aifs = AR5K_TXQ_USEDEFAULT, 962 /* XXX: default values not correct for B and XR channels,
1562 .tqi_cw_min = AR5K_TXQ_USEDEFAULT, 963 * but who cares? */
1563 .tqi_cw_max = AR5K_TXQ_USEDEFAULT, 964 .tqi_aifs = AR5K_TUNE_AIFS,
965 .tqi_cw_min = AR5K_TUNE_CWMIN,
966 .tqi_cw_max = AR5K_TUNE_CWMAX,
1564 /* NB: for dynamic turbo, don't enable any other interrupts */ 967 /* NB: for dynamic turbo, don't enable any other interrupts */
1565 .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE 968 .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE
1566 }; 969 };
@@ -1594,7 +997,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
1594 */ 997 */
1595 qi.tqi_aifs = 0; 998 qi.tqi_aifs = 0;
1596 qi.tqi_cw_min = 0; 999 qi.tqi_cw_min = 0;
1597 qi.tqi_cw_max = 2 * ah->ah_cw_min; 1000 qi.tqi_cw_max = 2 * AR5K_TUNE_CWMIN;
1598 } 1001 }
1599 1002
1600 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, 1003 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
@@ -1626,60 +1029,44 @@ err:
1626 return ret; 1029 return ret;
1627} 1030}
1628 1031
1032/**
1033 * ath5k_drain_tx_buffs - Empty tx buffers
1034 *
1035 * @sc The &struct ath5k_softc
1036 *
1037 * Empty tx buffers from all queues in preparation
1038 * of a reset or during shutdown.
1039 *
1040 * NB: this assumes output has been stopped and
1041 * we do not need to block ath5k_tx_tasklet
1042 */
1629static void 1043static void
1630ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) 1044ath5k_drain_tx_buffs(struct ath5k_softc *sc)
1631{ 1045{
1046 struct ath5k_txq *txq;
1632 struct ath5k_buf *bf, *bf0; 1047 struct ath5k_buf *bf, *bf0;
1048 int i;
1633 1049
1634 /* 1050 for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
1635 * NB: this assumes output has been stopped and 1051 if (sc->txqs[i].setup) {
1636 * we do not need to block ath5k_tx_tasklet 1052 txq = &sc->txqs[i];
1637 */ 1053 spin_lock_bh(&txq->lock);
1638 spin_lock_bh(&txq->lock); 1054 list_for_each_entry_safe(bf, bf0, &txq->q, list) {
1639 list_for_each_entry_safe(bf, bf0, &txq->q, list) { 1055 ath5k_debug_printtxbuf(sc, bf);
1640 ath5k_debug_printtxbuf(sc, bf);
1641
1642 ath5k_txbuf_free_skb(sc, bf);
1643
1644 spin_lock_bh(&sc->txbuflock);
1645 list_move_tail(&bf->list, &sc->txbuf);
1646 sc->txbuf_len++;
1647 spin_unlock_bh(&sc->txbuflock);
1648 }
1649 txq->link = NULL;
1650 spin_unlock_bh(&txq->lock);
1651}
1652 1056
1653/* 1057 ath5k_txbuf_free_skb(sc, bf);
1654 * Drain the transmit queues and reclaim resources.
1655 */
1656static void
1657ath5k_txq_cleanup(struct ath5k_softc *sc)
1658{
1659 struct ath5k_hw *ah = sc->ah;
1660 unsigned int i;
1661 1058
1662 /* XXX return value */ 1059 spin_lock_bh(&sc->txbuflock);
1663 if (likely(!test_bit(ATH_STAT_INVALID, sc->status))) { 1060 list_move_tail(&bf->list, &sc->txbuf);
1664 /* don't touch the hardware if marked invalid */ 1061 sc->txbuf_len++;
1665 ath5k_hw_stop_tx_dma(ah, sc->bhalq); 1062 txq->txq_len--;
1666 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n", 1063 spin_unlock_bh(&sc->txbuflock);
1667 ath5k_hw_get_txdp(ah, sc->bhalq));
1668 for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
1669 if (sc->txqs[i].setup) {
1670 ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum);
1671 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, "
1672 "link %p\n",
1673 sc->txqs[i].qnum,
1674 ath5k_hw_get_txdp(ah,
1675 sc->txqs[i].qnum),
1676 sc->txqs[i].link);
1677 } 1064 }
1065 txq->link = NULL;
1066 txq->txq_poll_mark = false;
1067 spin_unlock_bh(&txq->lock);
1068 }
1678 } 1069 }
1679
1680 for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
1681 if (sc->txqs[i].setup)
1682 ath5k_txq_drainq(sc, &sc->txqs[i]);
1683} 1070}
1684 1071
1685static void 1072static void
@@ -1696,8 +1083,6 @@ ath5k_txq_release(struct ath5k_softc *sc)
1696} 1083}
1697 1084
1698 1085
1699
1700
1701/*************\ 1086/*************\
1702* RX Handling * 1087* RX Handling *
1703\*************/ 1088\*************/
@@ -1713,7 +1098,7 @@ ath5k_rx_start(struct ath5k_softc *sc)
1713 struct ath5k_buf *bf; 1098 struct ath5k_buf *bf;
1714 int ret; 1099 int ret;
1715 1100
1716 common->rx_bufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz); 1101 common->rx_bufsize = roundup(IEEE80211_MAX_FRAME_LEN, common->cachelsz);
1717 1102
1718 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n", 1103 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n",
1719 common->cachelsz, common->rx_bufsize); 1104 common->cachelsz, common->rx_bufsize);
@@ -1732,7 +1117,7 @@ ath5k_rx_start(struct ath5k_softc *sc)
1732 spin_unlock_bh(&sc->rxbuflock); 1117 spin_unlock_bh(&sc->rxbuflock);
1733 1118
1734 ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ 1119 ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */
1735 ath5k_mode_setup(sc); /* set filters, etc. */ 1120 ath5k_update_bssid_mask_and_opmode(sc, NULL); /* set filters, etc. */
1736 ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ 1121 ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */
1737 1122
1738 return 0; 1123 return 0;
@@ -1741,16 +1126,19 @@ err:
1741} 1126}
1742 1127
1743/* 1128/*
1744 * Disable the receive h/w in preparation for a reset. 1129 * Disable the receive logic on PCU (DRU)
1130 * In preparation for a shutdown.
1131 *
1132 * Note: Doesn't stop rx DMA, ath5k_hw_dma_stop
1133 * does.
1745 */ 1134 */
1746static void 1135static void
1747ath5k_rx_stop(struct ath5k_softc *sc) 1136ath5k_rx_stop(struct ath5k_softc *sc)
1748{ 1137{
1749 struct ath5k_hw *ah = sc->ah; 1138 struct ath5k_hw *ah = sc->ah;
1750 1139
1751 ath5k_hw_stop_rx_pcu(ah); /* disable PCU */
1752 ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ 1140 ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */
1753 ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ 1141 ath5k_hw_stop_rx_pcu(ah); /* disable PCU */
1754 1142
1755 ath5k_debug_printrxbuffs(sc, ah); 1143 ath5k_debug_printrxbuffs(sc, ah);
1756} 1144}
@@ -1840,6 +1228,15 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
1840 */ 1228 */
1841 if (hw_tu >= sc->nexttbtt) 1229 if (hw_tu >= sc->nexttbtt)
1842 ath5k_beacon_update_timers(sc, bc_tstamp); 1230 ath5k_beacon_update_timers(sc, bc_tstamp);
1231
1232 /* Check if the beacon timers are still correct, because a TSF
1233 * update might have created a window between them - for a
1234 * longer description see the comment of this function: */
1235 if (!ath5k_hw_check_beacon_timers(sc->ah, sc->bintval)) {
1236 ath5k_beacon_update_timers(sc, bc_tstamp);
1237 ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
1238 "fixed beacon timers after beacon receive\n");
1239 }
1843 } 1240 }
1844} 1241}
1845 1242
@@ -1855,15 +1252,14 @@ ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi)
1855 memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0) 1252 memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0)
1856 return; 1253 return;
1857 1254
1858 ah->ah_beacon_rssi_avg = ath5k_moving_average(ah->ah_beacon_rssi_avg, 1255 ewma_add(&ah->ah_beacon_rssi_avg, rssi);
1859 rssi);
1860 1256
1861 /* in IBSS mode we should keep RSSI statistics per neighbour */ 1257 /* in IBSS mode we should keep RSSI statistics per neighbour */
1862 /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */ 1258 /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */
1863} 1259}
1864 1260
1865/* 1261/*
1866 * Compute padding position. skb must contains an IEEE 802.11 frame 1262 * Compute padding position. skb must contain an IEEE 802.11 frame
1867 */ 1263 */
1868static int ath5k_common_padpos(struct sk_buff *skb) 1264static int ath5k_common_padpos(struct sk_buff *skb)
1869{ 1265{
@@ -1882,10 +1278,9 @@ static int ath5k_common_padpos(struct sk_buff *skb)
1882} 1278}
1883 1279
1884/* 1280/*
1885 * This function expects a 802.11 frame and returns the number of 1281 * This function expects an 802.11 frame and returns the number of
1886 * bytes added, or -1 if we don't have enought header room. 1282 * bytes added, or -1 if we don't have enough header room.
1887 */ 1283 */
1888
1889static int ath5k_add_padding(struct sk_buff *skb) 1284static int ath5k_add_padding(struct sk_buff *skb)
1890{ 1285{
1891 int padpos = ath5k_common_padpos(skb); 1286 int padpos = ath5k_common_padpos(skb);
@@ -1905,10 +1300,18 @@ static int ath5k_add_padding(struct sk_buff *skb)
1905} 1300}
1906 1301
1907/* 1302/*
1908 * This function expects a 802.11 frame and returns the number of 1303 * The MAC header is padded to have 32-bit boundary if the
1909 * bytes removed 1304 * packet payload is non-zero. The general calculation for
1305 * padsize would take into account odd header lengths:
1306 * padsize = 4 - (hdrlen & 3); however, since only
1307 * even-length headers are used, padding can only be 0 or 2
1308 * bytes and we can optimize this a bit. We must not try to
1309 * remove padding from short control frames that do not have a
1310 * payload.
1311 *
1312 * This function expects an 802.11 frame and returns the number of
1313 * bytes removed.
1910 */ 1314 */
1911
1912static int ath5k_remove_padding(struct sk_buff *skb) 1315static int ath5k_remove_padding(struct sk_buff *skb)
1913{ 1316{
1914 int padpos = ath5k_common_padpos(skb); 1317 int padpos = ath5k_common_padpos(skb);
@@ -1929,14 +1332,6 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
1929{ 1332{
1930 struct ieee80211_rx_status *rxs; 1333 struct ieee80211_rx_status *rxs;
1931 1334
1932 /* The MAC header is padded to have 32-bit boundary if the
1933 * packet payload is non-zero. The general calculation for
1934 * padsize would take into account odd header lengths:
1935 * padsize = (4 - hdrlen % 4) % 4; However, since only
1936 * even-length headers are used, padding can only be 0 or 2
1937 * bytes and we can optimize this a bit. In addition, we must
1938 * not try to remove padding from short control frames that do
1939 * not have payload. */
1940 ath5k_remove_padding(skb); 1335 ath5k_remove_padding(skb);
1941 1336
1942 rxs = IEEE80211_SKB_RXCB(skb); 1337 rxs = IEEE80211_SKB_RXCB(skb);
@@ -1966,10 +1361,10 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
1966 * right now, so it's not too bad... 1361 * right now, so it's not too bad...
1967 */ 1362 */
1968 rxs->mactime = ath5k_extend_tsf(sc->ah, rs->rs_tstamp); 1363 rxs->mactime = ath5k_extend_tsf(sc->ah, rs->rs_tstamp);
1969 rxs->flag |= RX_FLAG_TSFT; 1364 rxs->flag |= RX_FLAG_MACTIME_MPDU;
1970 1365
1971 rxs->freq = sc->curchan->center_freq; 1366 rxs->freq = sc->curchan->center_freq;
1972 rxs->band = sc->curband->band; 1367 rxs->band = sc->curchan->band;
1973 1368
1974 rxs->signal = sc->ah->ah_noise_floor + rs->rs_rssi; 1369 rxs->signal = sc->ah->ah_noise_floor + rs->rs_rssi;
1975 1370
@@ -1984,10 +1379,10 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
1984 rxs->flag |= ath5k_rx_decrypted(sc, skb, rs); 1379 rxs->flag |= ath5k_rx_decrypted(sc, skb, rs);
1985 1380
1986 if (rxs->rate_idx >= 0 && rs->rs_rate == 1381 if (rxs->rate_idx >= 0 && rs->rs_rate ==
1987 sc->curband->bitrates[rxs->rate_idx].hw_value_short) 1382 sc->sbands[sc->curchan->band].bitrates[rxs->rate_idx].hw_value_short)
1988 rxs->flag |= RX_FLAG_SHORTPRE; 1383 rxs->flag |= RX_FLAG_SHORTPRE;
1989 1384
1990 ath5k_debug_dump_skb(sc, skb, "RX ", 0); 1385 trace_ath5k_rx(sc, skb);
1991 1386
1992 ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi); 1387 ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi);
1993 1388
@@ -2007,6 +1402,7 @@ static bool
2007ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) 1402ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
2008{ 1403{
2009 sc->stats.rx_all_count++; 1404 sc->stats.rx_all_count++;
1405 sc->stats.rx_bytes_count += rs->rs_datalen;
2010 1406
2011 if (unlikely(rs->rs_status)) { 1407 if (unlikely(rs->rs_status)) {
2012 if (rs->rs_status & AR5K_RXERR_CRC) 1408 if (rs->rs_status & AR5K_RXERR_CRC)
@@ -2040,9 +1436,8 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
2040 return true; 1436 return true;
2041 } 1437 }
2042 1438
2043 /* let crypto-error packets fall through in MNTR */ 1439 /* reject any frames with non-crypto errors */
2044 if ((rs->rs_status & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || 1440 if (rs->rs_status & ~(AR5K_RXERR_DECRYPT))
2045 sc->opmode != NL80211_IFTYPE_MONITOR)
2046 return false; 1441 return false;
2047 } 1442 }
2048 1443
@@ -2054,6 +1449,21 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
2054} 1449}
2055 1450
2056static void 1451static void
1452ath5k_set_current_imask(struct ath5k_softc *sc)
1453{
1454 enum ath5k_int imask = sc->imask;
1455 unsigned long flags;
1456
1457 spin_lock_irqsave(&sc->irqlock, flags);
1458 if (sc->rx_pending)
1459 imask &= ~AR5K_INT_RX_ALL;
1460 if (sc->tx_pending)
1461 imask &= ~AR5K_INT_TX_ALL;
1462 ath5k_hw_set_imr(sc->ah, imask);
1463 spin_unlock_irqrestore(&sc->irqlock, flags);
1464}
1465
1466static void
2057ath5k_tasklet_rx(unsigned long data) 1467ath5k_tasklet_rx(unsigned long data)
2058{ 1468{
2059 struct ath5k_rx_status rs = {}; 1469 struct ath5k_rx_status rs = {};
@@ -2100,9 +1510,9 @@ ath5k_tasklet_rx(unsigned long data)
2100 if (!next_skb) 1510 if (!next_skb)
2101 goto next; 1511 goto next;
2102 1512
2103 pci_unmap_single(sc->pdev, bf->skbaddr, 1513 dma_unmap_single(sc->dev, bf->skbaddr,
2104 common->rx_bufsize, 1514 common->rx_bufsize,
2105 PCI_DMA_FROMDEVICE); 1515 DMA_FROM_DEVICE);
2106 1516
2107 skb_put(skb, rs.rs_datalen); 1517 skb_put(skb, rs.rs_datalen);
2108 1518
@@ -2116,6 +1526,8 @@ next:
2116 } while (ath5k_rxbuf_setup(sc, bf) == 0); 1526 } while (ath5k_rxbuf_setup(sc, bf) == 0);
2117unlock: 1527unlock:
2118 spin_unlock(&sc->rxbuflock); 1528 spin_unlock(&sc->rxbuflock);
1529 sc->rx_pending = false;
1530 ath5k_set_current_imask(sc);
2119} 1531}
2120 1532
2121 1533
@@ -2123,6 +1535,122 @@ unlock:
2123* TX Handling * 1535* TX Handling *
2124\*************/ 1536\*************/
2125 1537
1538void
1539ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
1540 struct ath5k_txq *txq)
1541{
1542 struct ath5k_softc *sc = hw->priv;
1543 struct ath5k_buf *bf;
1544 unsigned long flags;
1545 int padsize;
1546
1547 trace_ath5k_tx(sc, skb, txq);
1548
1549 /*
1550 * The hardware expects the header padded to 4 byte boundaries.
1551 * If this is not the case, we add the padding after the header.
1552 */
1553 padsize = ath5k_add_padding(skb);
1554 if (padsize < 0) {
1555 ATH5K_ERR(sc, "tx hdrlen not %%4: not enough"
1556 " headroom to pad");
1557 goto drop_packet;
1558 }
1559
1560 if (txq->txq_len >= txq->txq_max)
1561 ieee80211_stop_queue(hw, txq->qnum);
1562
1563 spin_lock_irqsave(&sc->txbuflock, flags);
1564 if (list_empty(&sc->txbuf)) {
1565 ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
1566 spin_unlock_irqrestore(&sc->txbuflock, flags);
1567 ieee80211_stop_queues(hw);
1568 goto drop_packet;
1569 }
1570 bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
1571 list_del(&bf->list);
1572 sc->txbuf_len--;
1573 if (list_empty(&sc->txbuf))
1574 ieee80211_stop_queues(hw);
1575 spin_unlock_irqrestore(&sc->txbuflock, flags);
1576
1577 bf->skb = skb;
1578
1579 if (ath5k_txbuf_setup(sc, bf, txq, padsize)) {
1580 bf->skb = NULL;
1581 spin_lock_irqsave(&sc->txbuflock, flags);
1582 list_add_tail(&bf->list, &sc->txbuf);
1583 sc->txbuf_len++;
1584 spin_unlock_irqrestore(&sc->txbuflock, flags);
1585 goto drop_packet;
1586 }
1587 return;
1588
1589drop_packet:
1590 dev_kfree_skb_any(skb);
1591}
1592
1593static void
1594ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
1595 struct ath5k_txq *txq, struct ath5k_tx_status *ts)
1596{
1597 struct ieee80211_tx_info *info;
1598 u8 tries[3];
1599 int i;
1600
1601 sc->stats.tx_all_count++;
1602 sc->stats.tx_bytes_count += skb->len;
1603 info = IEEE80211_SKB_CB(skb);
1604
1605 tries[0] = info->status.rates[0].count;
1606 tries[1] = info->status.rates[1].count;
1607 tries[2] = info->status.rates[2].count;
1608
1609 ieee80211_tx_info_clear_status(info);
1610
1611 for (i = 0; i < ts->ts_final_idx; i++) {
1612 struct ieee80211_tx_rate *r =
1613 &info->status.rates[i];
1614
1615 r->count = tries[i];
1616 }
1617
1618 info->status.rates[ts->ts_final_idx].count = ts->ts_final_retry;
1619 info->status.rates[ts->ts_final_idx + 1].idx = -1;
1620
1621 if (unlikely(ts->ts_status)) {
1622 sc->stats.ack_fail++;
1623 if (ts->ts_status & AR5K_TXERR_FILT) {
1624 info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
1625 sc->stats.txerr_filt++;
1626 }
1627 if (ts->ts_status & AR5K_TXERR_XRETRY)
1628 sc->stats.txerr_retry++;
1629 if (ts->ts_status & AR5K_TXERR_FIFO)
1630 sc->stats.txerr_fifo++;
1631 } else {
1632 info->flags |= IEEE80211_TX_STAT_ACK;
1633 info->status.ack_signal = ts->ts_rssi;
1634
1635 /* count the successful attempt as well */
1636 info->status.rates[ts->ts_final_idx].count++;
1637 }
1638
1639 /*
1640 * Remove MAC header padding before giving the frame
1641 * back to mac80211.
1642 */
1643 ath5k_remove_padding(skb);
1644
1645 if (ts->ts_antenna > 0 && ts->ts_antenna < 5)
1646 sc->stats.antenna_tx[ts->ts_antenna]++;
1647 else
1648 sc->stats.antenna_tx[0]++; /* invalid */
1649
1650 trace_ath5k_tx_complete(sc, skb, txq, ts);
1651 ieee80211_tx_status(sc->hw, skb);
1652}
1653
2126static void 1654static void
2127ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) 1655ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
2128{ 1656{
@@ -2130,96 +1658,52 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
2130 struct ath5k_buf *bf, *bf0; 1658 struct ath5k_buf *bf, *bf0;
2131 struct ath5k_desc *ds; 1659 struct ath5k_desc *ds;
2132 struct sk_buff *skb; 1660 struct sk_buff *skb;
2133 struct ieee80211_tx_info *info; 1661 int ret;
2134 int i, ret;
2135 1662
2136 spin_lock(&txq->lock); 1663 spin_lock(&txq->lock);
2137 list_for_each_entry_safe(bf, bf0, &txq->q, list) { 1664 list_for_each_entry_safe(bf, bf0, &txq->q, list) {
2138 ds = bf->desc;
2139
2140 /*
2141 * It's possible that the hardware can say the buffer is
2142 * completed when it hasn't yet loaded the ds_link from
2143 * host memory and moved on. If there are more TX
2144 * descriptors in the queue, wait for TXDP to change
2145 * before processing this one.
2146 */
2147 if (ath5k_hw_get_txdp(sc->ah, txq->qnum) == bf->daddr &&
2148 !list_is_last(&bf->list, &txq->q))
2149 break;
2150
2151 ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
2152 if (unlikely(ret == -EINPROGRESS))
2153 break;
2154 else if (unlikely(ret)) {
2155 ATH5K_ERR(sc, "error %d while processing queue %u\n",
2156 ret, txq->qnum);
2157 break;
2158 }
2159
2160 sc->stats.tx_all_count++;
2161 skb = bf->skb;
2162 info = IEEE80211_SKB_CB(skb);
2163 bf->skb = NULL;
2164 1665
2165 pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, 1666 txq->txq_poll_mark = false;
2166 PCI_DMA_TODEVICE);
2167 1667
2168 ieee80211_tx_info_clear_status(info); 1668 /* skb might already have been processed last time. */
2169 for (i = 0; i < 4; i++) { 1669 if (bf->skb != NULL) {
2170 struct ieee80211_tx_rate *r = 1670 ds = bf->desc;
2171 &info->status.rates[i];
2172 1671
2173 if (ts.ts_rate[i]) { 1672 ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
2174 r->idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]); 1673 if (unlikely(ret == -EINPROGRESS))
2175 r->count = ts.ts_retry[i]; 1674 break;
2176 } else { 1675 else if (unlikely(ret)) {
2177 r->idx = -1; 1676 ATH5K_ERR(sc,
2178 r->count = 0; 1677 "error %d while processing "
1678 "queue %u\n", ret, txq->qnum);
1679 break;
2179 } 1680 }
2180 }
2181 1681
2182 /* count the successful attempt as well */ 1682 skb = bf->skb;
2183 info->status.rates[ts.ts_final_idx].count++; 1683 bf->skb = NULL;
2184 1684
2185 if (unlikely(ts.ts_status)) { 1685 dma_unmap_single(sc->dev, bf->skbaddr, skb->len,
2186 sc->stats.ack_fail++; 1686 DMA_TO_DEVICE);
2187 if (ts.ts_status & AR5K_TXERR_FILT) { 1687 ath5k_tx_frame_completed(sc, skb, txq, &ts);
2188 info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
2189 sc->stats.txerr_filt++;
2190 }
2191 if (ts.ts_status & AR5K_TXERR_XRETRY)
2192 sc->stats.txerr_retry++;
2193 if (ts.ts_status & AR5K_TXERR_FIFO)
2194 sc->stats.txerr_fifo++;
2195 } else {
2196 info->flags |= IEEE80211_TX_STAT_ACK;
2197 info->status.ack_signal = ts.ts_rssi;
2198 } 1688 }
2199 1689
2200 /* 1690 /*
2201 * Remove MAC header padding before giving the frame 1691 * It's possible that the hardware can say the buffer is
2202 * back to mac80211. 1692 * completed when it hasn't yet loaded the ds_link from
1693 * host memory and moved on.
1694 * Always keep the last descriptor to avoid HW races...
2203 */ 1695 */
2204 ath5k_remove_padding(skb); 1696 if (ath5k_hw_get_txdp(sc->ah, txq->qnum) != bf->daddr) {
2205 1697 spin_lock(&sc->txbuflock);
2206 if (ts.ts_antenna > 0 && ts.ts_antenna < 5) 1698 list_move_tail(&bf->list, &sc->txbuf);
2207 sc->stats.antenna_tx[ts.ts_antenna]++; 1699 sc->txbuf_len++;
2208 else 1700 txq->txq_len--;
2209 sc->stats.antenna_tx[0]++; /* invalid */ 1701 spin_unlock(&sc->txbuflock);
2210 1702 }
2211 ieee80211_tx_status(sc->hw, skb);
2212
2213 spin_lock(&sc->txbuflock);
2214 list_move_tail(&bf->list, &sc->txbuf);
2215 sc->txbuf_len++;
2216 spin_unlock(&sc->txbuflock);
2217 } 1703 }
2218 if (likely(list_empty(&txq->q)))
2219 txq->link = NULL;
2220 spin_unlock(&txq->lock); 1704 spin_unlock(&txq->lock);
2221 if (sc->txbuf_len > ATH_TXBUF / 5) 1705 if (txq->txq_len < ATH5K_TXQ_LEN_LOW && txq->qnum < 4)
2222 ieee80211_wake_queues(sc->hw); 1706 ieee80211_wake_queue(sc->hw, txq->qnum);
2223} 1707}
2224 1708
2225static void 1709static void
@@ -2231,6 +1715,9 @@ ath5k_tasklet_tx(unsigned long data)
2231 for (i=0; i < AR5K_NUM_TX_QUEUES; i++) 1715 for (i=0; i < AR5K_NUM_TX_QUEUES; i++)
2232 if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i))) 1716 if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i)))
2233 ath5k_tx_processq(sc, &sc->txqs[i]); 1717 ath5k_tx_processq(sc, &sc->txqs[i]);
1718
1719 sc->tx_pending = false;
1720 ath5k_set_current_imask(sc);
2234} 1721}
2235 1722
2236 1723
@@ -2253,12 +1740,13 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2253 u32 flags; 1740 u32 flags;
2254 const int padsize = 0; 1741 const int padsize = 0;
2255 1742
2256 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, 1743 bf->skbaddr = dma_map_single(sc->dev, skb->data, skb->len,
2257 PCI_DMA_TODEVICE); 1744 DMA_TO_DEVICE);
2258 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] " 1745 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] "
2259 "skbaddr %llx\n", skb, skb->data, skb->len, 1746 "skbaddr %llx\n", skb, skb->data, skb->len,
2260 (unsigned long long)bf->skbaddr); 1747 (unsigned long long)bf->skbaddr);
2261 if (pci_dma_mapping_error(sc->pdev, bf->skbaddr)) { 1748
1749 if (dma_mapping_error(sc->dev, bf->skbaddr)) {
2262 ATH5K_ERR(sc, "beacon DMA mapping failed\n"); 1750 ATH5K_ERR(sc, "beacon DMA mapping failed\n");
2263 return -EIO; 1751 return -EIO;
2264 } 1752 }
@@ -2285,10 +1773,11 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2285 * default antenna which is supposed to be an omni. 1773 * default antenna which is supposed to be an omni.
2286 * 1774 *
2287 * Note2: On sectored scenarios it's possible to have 1775 * Note2: On sectored scenarios it's possible to have
2288 * multiple antennas (1omni -the default- and 14 sectors) 1776 * multiple antennas (1 omni -- the default -- and 14
2289 * so if we choose to actually support this mode we need 1777 * sectors), so if we choose to actually support this
2290 * to allow user to set how many antennas we have and tweak 1778 * mode, we need to allow the user to set how many antennas
2291 * the code below to send beacons on all of them. 1779 * we have and tweak the code below to send beacons
1780 * on all of them.
2292 */ 1781 */
2293 if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP) 1782 if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP)
2294 antenna = sc->bsent & 4 ? 2 : 1; 1783 antenna = sc->bsent & 4 ? 2 : 1;
@@ -2309,7 +1798,43 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2309 1798
2310 return 0; 1799 return 0;
2311err_unmap: 1800err_unmap:
2312 pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE); 1801 dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE);
1802 return ret;
1803}
1804
1805/*
1806 * Updates the beacon that is sent by ath5k_beacon_send. For adhoc,
1807 * this is called only once at config_bss time, for AP we do it every
1808 * SWBA interrupt so that the TIM will reflect buffered frames.
1809 *
1810 * Called with the beacon lock.
1811 */
1812int
1813ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1814{
1815 int ret;
1816 struct ath5k_softc *sc = hw->priv;
1817 struct ath5k_vif *avf = (void *)vif->drv_priv;
1818 struct sk_buff *skb;
1819
1820 if (WARN_ON(!vif)) {
1821 ret = -EINVAL;
1822 goto out;
1823 }
1824
1825 skb = ieee80211_beacon_get(hw, vif);
1826
1827 if (!skb) {
1828 ret = -ENOMEM;
1829 goto out;
1830 }
1831
1832 ath5k_txbuf_free_skb(sc, avf->bbuf);
1833 avf->bbuf->skb = skb;
1834 ret = ath5k_beacon_setup(sc, avf->bbuf);
1835 if (ret)
1836 avf->bbuf->skb = NULL;
1837out:
2313 return ret; 1838 return ret;
2314} 1839}
2315 1840
@@ -2324,20 +1849,17 @@ err_unmap:
2324static void 1849static void
2325ath5k_beacon_send(struct ath5k_softc *sc) 1850ath5k_beacon_send(struct ath5k_softc *sc)
2326{ 1851{
2327 struct ath5k_buf *bf = sc->bbuf;
2328 struct ath5k_hw *ah = sc->ah; 1852 struct ath5k_hw *ah = sc->ah;
1853 struct ieee80211_vif *vif;
1854 struct ath5k_vif *avf;
1855 struct ath5k_buf *bf;
2329 struct sk_buff *skb; 1856 struct sk_buff *skb;
2330 1857
2331 ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); 1858 ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
2332 1859
2333 if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
2334 sc->opmode == NL80211_IFTYPE_MONITOR)) {
2335 ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
2336 return;
2337 }
2338 /* 1860 /*
2339 * Check if the previous beacon has gone out. If 1861 * Check if the previous beacon has gone out. If
2340 * not don't don't try to post another, skip this 1862 * not, don't don't try to post another: skip this
2341 * period and wait for the next. Missed beacons 1863 * period and wait for the next. Missed beacons
2342 * indicate a problem and should not occur. If we 1864 * indicate a problem and should not occur. If we
2343 * miss too many consecutive beacons reset the device. 1865 * miss too many consecutive beacons reset the device.
@@ -2363,35 +1885,60 @@ ath5k_beacon_send(struct ath5k_softc *sc)
2363 sc->bmisscount = 0; 1885 sc->bmisscount = 0;
2364 } 1886 }
2365 1887
1888 if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) ||
1889 sc->opmode == NL80211_IFTYPE_MESH_POINT) {
1890 u64 tsf = ath5k_hw_get_tsf64(ah);
1891 u32 tsftu = TSF_TO_TU(tsf);
1892 int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval;
1893 vif = sc->bslot[(slot + 1) % ATH_BCBUF];
1894 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
1895 "tsf %llx tsftu %x intval %u slot %u vif %p\n",
1896 (unsigned long long)tsf, tsftu, sc->bintval, slot, vif);
1897 } else /* only one interface */
1898 vif = sc->bslot[0];
1899
1900 if (!vif)
1901 return;
1902
1903 avf = (void *)vif->drv_priv;
1904 bf = avf->bbuf;
1905 if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
1906 sc->opmode == NL80211_IFTYPE_MONITOR)) {
1907 ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
1908 return;
1909 }
1910
2366 /* 1911 /*
2367 * Stop any current dma and put the new frame on the queue. 1912 * Stop any current dma and put the new frame on the queue.
2368 * This should never fail since we check above that no frames 1913 * This should never fail since we check above that no frames
2369 * are still pending on the queue. 1914 * are still pending on the queue.
2370 */ 1915 */
2371 if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) { 1916 if (unlikely(ath5k_hw_stop_beacon_queue(ah, sc->bhalq))) {
2372 ATH5K_WARN(sc, "beacon queue %u didn't start/stop ?\n", sc->bhalq); 1917 ATH5K_WARN(sc, "beacon queue %u didn't start/stop ?\n", sc->bhalq);
2373 /* NB: hw still stops DMA, so proceed */ 1918 /* NB: hw still stops DMA, so proceed */
2374 } 1919 }
2375 1920
2376 /* refresh the beacon for AP mode */ 1921 /* refresh the beacon for AP or MESH mode */
2377 if (sc->opmode == NL80211_IFTYPE_AP) 1922 if (sc->opmode == NL80211_IFTYPE_AP ||
2378 ath5k_beacon_update(sc->hw, sc->vif); 1923 sc->opmode == NL80211_IFTYPE_MESH_POINT)
1924 ath5k_beacon_update(sc->hw, vif);
1925
1926 trace_ath5k_tx(sc, bf->skb, &sc->txqs[sc->bhalq]);
2379 1927
2380 ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); 1928 ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
2381 ath5k_hw_start_tx_dma(ah, sc->bhalq); 1929 ath5k_hw_start_tx_dma(ah, sc->bhalq);
2382 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", 1930 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
2383 sc->bhalq, (unsigned long long)bf->daddr, bf->desc); 1931 sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
2384 1932
2385 skb = ieee80211_get_buffered_bc(sc->hw, sc->vif); 1933 skb = ieee80211_get_buffered_bc(sc->hw, vif);
2386 while (skb) { 1934 while (skb) {
2387 ath5k_tx_queue(sc->hw, skb, sc->cabq); 1935 ath5k_tx_queue(sc->hw, skb, sc->cabq);
2388 skb = ieee80211_get_buffered_bc(sc->hw, sc->vif); 1936 skb = ieee80211_get_buffered_bc(sc->hw, vif);
2389 } 1937 }
2390 1938
2391 sc->bsent++; 1939 sc->bsent++;
2392} 1940}
2393 1941
2394
2395/** 1942/**
2396 * ath5k_beacon_update_timers - update beacon timers 1943 * ath5k_beacon_update_timers - update beacon timers
2397 * 1944 *
@@ -2408,7 +1955,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
2408 * when we otherwise know we have to update the timers, but we keep it in this 1955 * when we otherwise know we have to update the timers, but we keep it in this
2409 * function to have it all together in one place. 1956 * function to have it all together in one place.
2410 */ 1957 */
2411static void 1958void
2412ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) 1959ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
2413{ 1960{
2414 struct ath5k_hw *ah = sc->ah; 1961 struct ath5k_hw *ah = sc->ah;
@@ -2416,6 +1963,12 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
2416 u64 hw_tsf; 1963 u64 hw_tsf;
2417 1964
2418 intval = sc->bintval & AR5K_BEACON_PERIOD; 1965 intval = sc->bintval & AR5K_BEACON_PERIOD;
1966 if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
1967 intval /= ATH_BCBUF; /* staggered multi-bss beacons */
1968 if (intval < 15)
1969 ATH5K_WARN(sc, "intval %u is too low, min 15\n",
1970 intval);
1971 }
2419 if (WARN_ON(!intval)) 1972 if (WARN_ON(!intval))
2420 return; 1973 return;
2421 1974
@@ -2426,8 +1979,11 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
2426 hw_tsf = ath5k_hw_get_tsf64(ah); 1979 hw_tsf = ath5k_hw_get_tsf64(ah);
2427 hw_tu = TSF_TO_TU(hw_tsf); 1980 hw_tu = TSF_TO_TU(hw_tsf);
2428 1981
2429#define FUDGE 3 1982#define FUDGE AR5K_TUNE_SW_BEACON_RESP + 3
2430 /* we use FUDGE to make sure the next TBTT is ahead of the current TU */ 1983 /* We use FUDGE to make sure the next TBTT is ahead of the current TU.
1984 * Since we later subtract AR5K_TUNE_SW_BEACON_RESP (10) in the timer
1985 * configuration we need to make sure it is bigger than that. */
1986
2431 if (bc_tsf == -1) { 1987 if (bc_tsf == -1) {
2432 /* 1988 /*
2433 * no beacons received, called internally. 1989 * no beacons received, called internally.
@@ -2443,7 +1999,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
2443 intval |= AR5K_BEACON_RESET_TSF; 1999 intval |= AR5K_BEACON_RESET_TSF;
2444 } else if (bc_tsf > hw_tsf) { 2000 } else if (bc_tsf > hw_tsf) {
2445 /* 2001 /*
2446 * beacon received, SW merge happend but HW TSF not yet updated. 2002 * beacon received, SW merge happened but HW TSF not yet updated.
2447 * not possible to reconfigure timers yet, but next time we 2003 * not possible to reconfigure timers yet, but next time we
2448 * receive a beacon with the same BSSID, the hardware will 2004 * receive a beacon with the same BSSID, the hardware will
2449 * automatically update the TSF and then we need to reconfigure 2005 * automatically update the TSF and then we need to reconfigure
@@ -2493,7 +2049,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
2493 intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : ""); 2049 intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : "");
2494} 2050}
2495 2051
2496
2497/** 2052/**
2498 * ath5k_beacon_config - Configure the beacon queues and interrupts 2053 * ath5k_beacon_config - Configure the beacon queues and interrupts
2499 * 2054 *
@@ -2502,7 +2057,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
2502 * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA 2057 * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
2503 * interrupts to detect TSF updates only. 2058 * interrupts to detect TSF updates only.
2504 */ 2059 */
2505static void 2060void
2506ath5k_beacon_config(struct ath5k_softc *sc) 2061ath5k_beacon_config(struct ath5k_softc *sc)
2507{ 2062{
2508 struct ath5k_hw *ah = sc->ah; 2063 struct ath5k_hw *ah = sc->ah;
@@ -2530,7 +2085,7 @@ ath5k_beacon_config(struct ath5k_softc *sc)
2530 } else 2085 } else
2531 ath5k_beacon_update_timers(sc, -1); 2086 ath5k_beacon_update_timers(sc, -1);
2532 } else { 2087 } else {
2533 ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq); 2088 ath5k_hw_stop_beacon_queue(sc->ah, sc->bhalq);
2534 } 2089 }
2535 2090
2536 ath5k_hw_set_imr(ah, sc->imask); 2091 ath5k_hw_set_imr(ah, sc->imask);
@@ -2572,155 +2127,6 @@ static void ath5k_tasklet_beacon(unsigned long data)
2572* Interrupt handling * 2127* Interrupt handling *
2573\********************/ 2128\********************/
2574 2129
2575static int
2576ath5k_init(struct ath5k_softc *sc)
2577{
2578 struct ath5k_hw *ah = sc->ah;
2579 int ret, i;
2580
2581 mutex_lock(&sc->lock);
2582
2583 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
2584
2585 /*
2586 * Stop anything previously setup. This is safe
2587 * no matter this is the first time through or not.
2588 */
2589 ath5k_stop_locked(sc);
2590
2591 /*
2592 * The basic interface to setting the hardware in a good
2593 * state is ``reset''. On return the hardware is known to
2594 * be powered up and with interrupts disabled. This must
2595 * be followed by initialization of the appropriate bits
2596 * and then setup of the interrupt mask.
2597 */
2598 sc->curchan = sc->hw->conf.channel;
2599 sc->curband = &sc->sbands[sc->curchan->band];
2600 sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
2601 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
2602 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
2603
2604 ret = ath5k_reset(sc, NULL);
2605 if (ret)
2606 goto done;
2607
2608 ath5k_rfkill_hw_start(ah);
2609
2610 /*
2611 * Reset the key cache since some parts do not reset the
2612 * contents on initial power up or resume from suspend.
2613 */
2614 for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
2615 ath5k_hw_reset_key(ah, i);
2616
2617 ath5k_hw_set_ack_bitrate_high(ah, true);
2618 ret = 0;
2619done:
2620 mmiowb();
2621 mutex_unlock(&sc->lock);
2622 return ret;
2623}
2624
2625static int
2626ath5k_stop_locked(struct ath5k_softc *sc)
2627{
2628 struct ath5k_hw *ah = sc->ah;
2629
2630 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n",
2631 test_bit(ATH_STAT_INVALID, sc->status));
2632
2633 /*
2634 * Shutdown the hardware and driver:
2635 * stop output from above
2636 * disable interrupts
2637 * turn off timers
2638 * turn off the radio
2639 * clear transmit machinery
2640 * clear receive machinery
2641 * drain and release tx queues
2642 * reclaim beacon resources
2643 * power down hardware
2644 *
2645 * Note that some of this work is not possible if the
2646 * hardware is gone (invalid).
2647 */
2648 ieee80211_stop_queues(sc->hw);
2649
2650 if (!test_bit(ATH_STAT_INVALID, sc->status)) {
2651 ath5k_led_off(sc);
2652 ath5k_hw_set_imr(ah, 0);
2653 synchronize_irq(sc->pdev->irq);
2654 }
2655 ath5k_txq_cleanup(sc);
2656 if (!test_bit(ATH_STAT_INVALID, sc->status)) {
2657 ath5k_rx_stop(sc);
2658 ath5k_hw_phy_disable(ah);
2659 }
2660
2661 return 0;
2662}
2663
2664static void stop_tasklets(struct ath5k_softc *sc)
2665{
2666 tasklet_kill(&sc->rxtq);
2667 tasklet_kill(&sc->txtq);
2668 tasklet_kill(&sc->calib);
2669 tasklet_kill(&sc->beacontq);
2670 tasklet_kill(&sc->ani_tasklet);
2671}
2672
2673/*
2674 * Stop the device, grabbing the top-level lock to protect
2675 * against concurrent entry through ath5k_init (which can happen
2676 * if another thread does a system call and the thread doing the
2677 * stop is preempted).
2678 */
2679static int
2680ath5k_stop_hw(struct ath5k_softc *sc)
2681{
2682 int ret;
2683
2684 mutex_lock(&sc->lock);
2685 ret = ath5k_stop_locked(sc);
2686 if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
2687 /*
2688 * Don't set the card in full sleep mode!
2689 *
2690 * a) When the device is in this state it must be carefully
2691 * woken up or references to registers in the PCI clock
2692 * domain may freeze the bus (and system). This varies
2693 * by chip and is mostly an issue with newer parts
2694 * (madwifi sources mentioned srev >= 0x78) that go to
2695 * sleep more quickly.
2696 *
2697 * b) On older chips full sleep results a weird behaviour
2698 * during wakeup. I tested various cards with srev < 0x78
2699 * and they don't wake up after module reload, a second
2700 * module reload is needed to bring the card up again.
2701 *
2702 * Until we figure out what's going on don't enable
2703 * full chip reset on any chip (this is what Legacy HAL
2704 * and Sam's HAL do anyway). Instead Perform a full reset
2705 * on the device (same as initial state after attach) and
2706 * leave it idle (keep MAC/BB on warm reset) */
2707 ret = ath5k_hw_on_hold(sc->ah);
2708
2709 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
2710 "putting device to sleep\n");
2711 }
2712 ath5k_txbuf_free_skb(sc, sc->bbuf);
2713
2714 mmiowb();
2715 mutex_unlock(&sc->lock);
2716
2717 stop_tasklets(sc);
2718
2719 ath5k_rfkill_hw_stop(sc->ah);
2720
2721 return ret;
2722}
2723
2724static void 2130static void
2725ath5k_intr_calibration_poll(struct ath5k_hw *ah) 2131ath5k_intr_calibration_poll(struct ath5k_hw *ah)
2726{ 2132{
@@ -2741,7 +2147,21 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah)
2741 * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ 2147 * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */
2742} 2148}
2743 2149
2744static irqreturn_t 2150static void
2151ath5k_schedule_rx(struct ath5k_softc *sc)
2152{
2153 sc->rx_pending = true;
2154 tasklet_schedule(&sc->rxtq);
2155}
2156
2157static void
2158ath5k_schedule_tx(struct ath5k_softc *sc)
2159{
2160 sc->tx_pending = true;
2161 tasklet_schedule(&sc->txtq);
2162}
2163
2164irqreturn_t
2745ath5k_intr(int irq, void *dev_id) 2165ath5k_intr(int irq, void *dev_id)
2746{ 2166{
2747 struct ath5k_softc *sc = dev_id; 2167 struct ath5k_softc *sc = dev_id;
@@ -2750,7 +2170,8 @@ ath5k_intr(int irq, void *dev_id)
2750 unsigned int counter = 1000; 2170 unsigned int counter = 1000;
2751 2171
2752 if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) || 2172 if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) ||
2753 !ath5k_hw_is_intr_pending(ah))) 2173 ((ath5k_get_bus_type(ah) != ATH_AHB) &&
2174 !ath5k_hw_is_intr_pending(ah))))
2754 return IRQ_NONE; 2175 return IRQ_NONE;
2755 2176
2756 do { 2177 do {
@@ -2782,7 +2203,7 @@ ath5k_intr(int irq, void *dev_id)
2782 ieee80211_queue_work(sc->hw, &sc->reset_work); 2203 ieee80211_queue_work(sc->hw, &sc->reset_work);
2783 } 2204 }
2784 else 2205 else
2785 tasklet_schedule(&sc->rxtq); 2206 ath5k_schedule_rx(sc);
2786 } else { 2207 } else {
2787 if (status & AR5K_INT_SWBA) { 2208 if (status & AR5K_INT_SWBA) {
2788 tasklet_hi_schedule(&sc->beacontq); 2209 tasklet_hi_schedule(&sc->beacontq);
@@ -2800,10 +2221,10 @@ ath5k_intr(int irq, void *dev_id)
2800 ath5k_hw_update_tx_triglevel(ah, true); 2221 ath5k_hw_update_tx_triglevel(ah, true);
2801 } 2222 }
2802 if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) 2223 if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR))
2803 tasklet_schedule(&sc->rxtq); 2224 ath5k_schedule_rx(sc);
2804 if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC 2225 if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC
2805 | AR5K_INT_TXERR | AR5K_INT_TXEOL)) 2226 | AR5K_INT_TXERR | AR5K_INT_TXEOL))
2806 tasklet_schedule(&sc->txtq); 2227 ath5k_schedule_tx(sc);
2807 if (status & AR5K_INT_BMISS) { 2228 if (status & AR5K_INT_BMISS) {
2808 /* TODO */ 2229 /* TODO */
2809 } 2230 }
@@ -2816,8 +2237,15 @@ ath5k_intr(int irq, void *dev_id)
2816 tasklet_schedule(&sc->rf_kill.toggleq); 2237 tasklet_schedule(&sc->rf_kill.toggleq);
2817 2238
2818 } 2239 }
2240
2241 if (ath5k_get_bus_type(ah) == ATH_AHB)
2242 break;
2243
2819 } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); 2244 } while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
2820 2245
2246 if (sc->rx_pending || sc->tx_pending)
2247 ath5k_set_current_imask(sc);
2248
2821 if (unlikely(!counter)) 2249 if (unlikely(!counter))
2822 ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); 2250 ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
2823 2251
@@ -2857,14 +2285,13 @@ ath5k_tasklet_calibrate(unsigned long data)
2857 sc->curchan->center_freq)); 2285 sc->curchan->center_freq));
2858 2286
2859 /* Noise floor calibration interrupts rx/tx path while I/Q calibration 2287 /* Noise floor calibration interrupts rx/tx path while I/Q calibration
2860 * doesn't. We stop the queues so that calibration doesn't interfere 2288 * doesn't.
2861 * with TX and don't run it as often */ 2289 * TODO: We should stop TX here, so that it doesn't interfere.
2290 * Note that stopping the queues is not enough to stop TX! */
2862 if (time_is_before_eq_jiffies(ah->ah_cal_next_nf)) { 2291 if (time_is_before_eq_jiffies(ah->ah_cal_next_nf)) {
2863 ah->ah_cal_next_nf = jiffies + 2292 ah->ah_cal_next_nf = jiffies +
2864 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_NF); 2293 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_NF);
2865 ieee80211_stop_queues(sc->hw);
2866 ath5k_hw_update_noise_floor(ah); 2294 ath5k_hw_update_noise_floor(ah);
2867 ieee80211_wake_queues(sc->hw);
2868 } 2295 }
2869 2296
2870 ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; 2297 ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL;
@@ -2883,570 +2310,676 @@ ath5k_tasklet_ani(unsigned long data)
2883} 2310}
2884 2311
2885 2312
2886/********************\ 2313static void
2887* Mac80211 functions * 2314ath5k_tx_complete_poll_work(struct work_struct *work)
2888\********************/
2889
2890static int
2891ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2892{
2893 struct ath5k_softc *sc = hw->priv;
2894
2895 return ath5k_tx_queue(hw, skb, sc->txq);
2896}
2897
2898static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2899 struct ath5k_txq *txq)
2900{ 2315{
2901 struct ath5k_softc *sc = hw->priv; 2316 struct ath5k_softc *sc = container_of(work, struct ath5k_softc,
2902 struct ath5k_buf *bf; 2317 tx_complete_work.work);
2903 unsigned long flags; 2318 struct ath5k_txq *txq;
2904 int padsize; 2319 int i;
2905 2320 bool needreset = false;
2906 ath5k_debug_dump_skb(sc, skb, "TX ", 1);
2907 2321
2908 if (sc->opmode == NL80211_IFTYPE_MONITOR) 2322 mutex_lock(&sc->lock);
2909 ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n");
2910 2323
2911 /* 2324 for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
2912 * the hardware expects the header padded to 4 byte boundaries 2325 if (sc->txqs[i].setup) {
2913 * if this is not the case we add the padding after the header 2326 txq = &sc->txqs[i];
2914 */ 2327 spin_lock_bh(&txq->lock);
2915 padsize = ath5k_add_padding(skb); 2328 if (txq->txq_len > 1) {
2916 if (padsize < 0) { 2329 if (txq->txq_poll_mark) {
2917 ATH5K_ERR(sc, "tx hdrlen not %%4: not enough" 2330 ATH5K_DBG(sc, ATH5K_DEBUG_XMIT,
2918 " headroom to pad"); 2331 "TX queue stuck %d\n",
2919 goto drop_packet; 2332 txq->qnum);
2333 needreset = true;
2334 txq->txq_stuck++;
2335 spin_unlock_bh(&txq->lock);
2336 break;
2337 } else {
2338 txq->txq_poll_mark = true;
2339 }
2340 }
2341 spin_unlock_bh(&txq->lock);
2342 }
2920 } 2343 }
2921 2344
2922 spin_lock_irqsave(&sc->txbuflock, flags); 2345 if (needreset) {
2923 if (list_empty(&sc->txbuf)) { 2346 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
2924 ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); 2347 "TX queues stuck, resetting\n");
2925 spin_unlock_irqrestore(&sc->txbuflock, flags); 2348 ath5k_reset(sc, NULL, true);
2926 ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
2927 goto drop_packet;
2928 } 2349 }
2929 bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
2930 list_del(&bf->list);
2931 sc->txbuf_len--;
2932 if (list_empty(&sc->txbuf))
2933 ieee80211_stop_queues(hw);
2934 spin_unlock_irqrestore(&sc->txbuflock, flags);
2935
2936 bf->skb = skb;
2937 2350
2938 if (ath5k_txbuf_setup(sc, bf, txq, padsize)) { 2351 mutex_unlock(&sc->lock);
2939 bf->skb = NULL;
2940 spin_lock_irqsave(&sc->txbuflock, flags);
2941 list_add_tail(&bf->list, &sc->txbuf);
2942 sc->txbuf_len++;
2943 spin_unlock_irqrestore(&sc->txbuflock, flags);
2944 goto drop_packet;
2945 }
2946 return NETDEV_TX_OK;
2947 2352
2948drop_packet: 2353 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
2949 dev_kfree_skb_any(skb); 2354 msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
2950 return NETDEV_TX_OK;
2951} 2355}
2952 2356
2953/* 2357
2954 * Reset the hardware. If chan is not NULL, then also pause rx/tx 2358/*************************\
2955 * and change to the given channel. 2359* Initialization routines *
2956 * 2360\*************************/
2957 * This should be called with sc->lock. 2361
2958 */ 2362int
2959static int 2363ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
2960ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
2961{ 2364{
2962 struct ath5k_hw *ah = sc->ah; 2365 struct ieee80211_hw *hw = sc->hw;
2366 struct ath_common *common;
2963 int ret; 2367 int ret;
2368 int csz;
2964 2369
2965 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); 2370 /* Initialize driver private data */
2371 SET_IEEE80211_DEV(hw, sc->dev);
2372 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
2373 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
2374 IEEE80211_HW_SIGNAL_DBM |
2375 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
2966 2376
2967 ath5k_hw_set_imr(ah, 0); 2377 hw->wiphy->interface_modes =
2968 synchronize_irq(sc->pdev->irq); 2378 BIT(NL80211_IFTYPE_AP) |
2969 stop_tasklets(sc); 2379 BIT(NL80211_IFTYPE_STATION) |
2380 BIT(NL80211_IFTYPE_ADHOC) |
2381 BIT(NL80211_IFTYPE_MESH_POINT);
2970 2382
2971 if (chan) { 2383 /* both antennas can be configured as RX or TX */
2972 ath5k_txq_cleanup(sc); 2384 hw->wiphy->available_antennas_tx = 0x3;
2973 ath5k_rx_stop(sc); 2385 hw->wiphy->available_antennas_rx = 0x3;
2974 2386
2975 sc->curchan = chan; 2387 hw->extra_tx_headroom = 2;
2976 sc->curband = &sc->sbands[chan->band]; 2388 hw->channel_change_time = 5000;
2977 }
2978 ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL);
2979 if (ret) {
2980 ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
2981 goto err;
2982 }
2983 2389
2984 ret = ath5k_rx_start(sc); 2390 /*
2391 * Mark the device as detached to avoid processing
2392 * interrupts until setup is complete.
2393 */
2394 __set_bit(ATH_STAT_INVALID, sc->status);
2395
2396 sc->opmode = NL80211_IFTYPE_STATION;
2397 sc->bintval = 1000;
2398 mutex_init(&sc->lock);
2399 spin_lock_init(&sc->rxbuflock);
2400 spin_lock_init(&sc->txbuflock);
2401 spin_lock_init(&sc->block);
2402 spin_lock_init(&sc->irqlock);
2403
2404 /* Setup interrupt handler */
2405 ret = request_irq(sc->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
2985 if (ret) { 2406 if (ret) {
2986 ATH5K_ERR(sc, "can't start recv logic\n"); 2407 ATH5K_ERR(sc, "request_irq failed\n");
2987 goto err; 2408 goto err;
2988 } 2409 }
2989 2410
2990 ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode); 2411 /* If we passed the test, malloc an ath5k_hw struct */
2412 sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
2413 if (!sc->ah) {
2414 ret = -ENOMEM;
2415 ATH5K_ERR(sc, "out of memory\n");
2416 goto err_irq;
2417 }
2991 2418
2992 ah->ah_cal_next_full = jiffies; 2419 sc->ah->ah_sc = sc;
2993 ah->ah_cal_next_ani = jiffies; 2420 sc->ah->ah_iobase = sc->iobase;
2994 ah->ah_cal_next_nf = jiffies; 2421 common = ath5k_hw_common(sc->ah);
2422 common->ops = &ath5k_common_ops;
2423 common->bus_ops = bus_ops;
2424 common->ah = sc->ah;
2425 common->hw = hw;
2426 common->priv = sc;
2995 2427
2996 /* 2428 /*
2997 * Change channels and update the h/w rate map if we're switching; 2429 * Cache line size is used to size and align various
2998 * e.g. 11a to 11b/g. 2430 * structures used to communicate with the hardware.
2999 *
3000 * We may be doing a reset in response to an ioctl that changes the
3001 * channel so update any state that might change as a result.
3002 *
3003 * XXX needed?
3004 */ 2431 */
3005/* ath5k_chan_change(sc, c); */ 2432 ath5k_read_cachesize(common, &csz);
2433 common->cachelsz = csz << 2; /* convert to bytes */
3006 2434
3007 ath5k_beacon_config(sc); 2435 spin_lock_init(&common->cc_lock);
3008 /* intrs are enabled by ath5k_beacon_config */
3009 2436
3010 ieee80211_wake_queues(sc->hw); 2437 /* Initialize device */
2438 ret = ath5k_hw_init(sc);
2439 if (ret)
2440 goto err_free_ah;
2441
2442 /* set up multi-rate retry capabilities */
2443 if (sc->ah->ah_version == AR5K_AR5212) {
2444 hw->max_rates = 4;
2445 hw->max_rate_tries = max(AR5K_INIT_RETRY_SHORT,
2446 AR5K_INIT_RETRY_LONG);
2447 }
2448
2449 hw->vif_data_size = sizeof(struct ath5k_vif);
2450
2451 /* Finish private driver data initialization */
2452 ret = ath5k_init(hw);
2453 if (ret)
2454 goto err_ah;
2455
2456 ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
2457 ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
2458 sc->ah->ah_mac_srev,
2459 sc->ah->ah_phy_revision);
2460
2461 if (!sc->ah->ah_single_chip) {
2462 /* Single chip radio (!RF5111) */
2463 if (sc->ah->ah_radio_5ghz_revision &&
2464 !sc->ah->ah_radio_2ghz_revision) {
2465 /* No 5GHz support -> report 2GHz radio */
2466 if (!test_bit(AR5K_MODE_11A,
2467 sc->ah->ah_capabilities.cap_mode)) {
2468 ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
2469 ath5k_chip_name(AR5K_VERSION_RAD,
2470 sc->ah->ah_radio_5ghz_revision),
2471 sc->ah->ah_radio_5ghz_revision);
2472 /* No 2GHz support (5110 and some
2473 * 5Ghz only cards) -> report 5Ghz radio */
2474 } else if (!test_bit(AR5K_MODE_11B,
2475 sc->ah->ah_capabilities.cap_mode)) {
2476 ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
2477 ath5k_chip_name(AR5K_VERSION_RAD,
2478 sc->ah->ah_radio_5ghz_revision),
2479 sc->ah->ah_radio_5ghz_revision);
2480 /* Multiband radio */
2481 } else {
2482 ATH5K_INFO(sc, "RF%s multiband radio found"
2483 " (0x%x)\n",
2484 ath5k_chip_name(AR5K_VERSION_RAD,
2485 sc->ah->ah_radio_5ghz_revision),
2486 sc->ah->ah_radio_5ghz_revision);
2487 }
2488 }
2489 /* Multi chip radio (RF5111 - RF2111) ->
2490 * report both 2GHz/5GHz radios */
2491 else if (sc->ah->ah_radio_5ghz_revision &&
2492 sc->ah->ah_radio_2ghz_revision){
2493 ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
2494 ath5k_chip_name(AR5K_VERSION_RAD,
2495 sc->ah->ah_radio_5ghz_revision),
2496 sc->ah->ah_radio_5ghz_revision);
2497 ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
2498 ath5k_chip_name(AR5K_VERSION_RAD,
2499 sc->ah->ah_radio_2ghz_revision),
2500 sc->ah->ah_radio_2ghz_revision);
2501 }
2502 }
2503
2504 ath5k_debug_init_device(sc);
2505
2506 /* ready to process interrupts */
2507 __clear_bit(ATH_STAT_INVALID, sc->status);
3011 2508
3012 return 0; 2509 return 0;
2510err_ah:
2511 ath5k_hw_deinit(sc->ah);
2512err_free_ah:
2513 kfree(sc->ah);
2514err_irq:
2515 free_irq(sc->irq, sc);
3013err: 2516err:
3014 return ret; 2517 return ret;
3015} 2518}
3016 2519
3017static void ath5k_reset_work(struct work_struct *work) 2520static int
2521ath5k_stop_locked(struct ath5k_softc *sc)
3018{ 2522{
3019 struct ath5k_softc *sc = container_of(work, struct ath5k_softc, 2523 struct ath5k_hw *ah = sc->ah;
3020 reset_work);
3021 2524
3022 mutex_lock(&sc->lock); 2525 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n",
3023 ath5k_reset(sc, sc->curchan); 2526 test_bit(ATH_STAT_INVALID, sc->status));
3024 mutex_unlock(&sc->lock);
3025}
3026 2527
3027static int ath5k_start(struct ieee80211_hw *hw) 2528 /*
3028{ 2529 * Shutdown the hardware and driver:
3029 return ath5k_init(hw->priv); 2530 * stop output from above
3030} 2531 * disable interrupts
2532 * turn off timers
2533 * turn off the radio
2534 * clear transmit machinery
2535 * clear receive machinery
2536 * drain and release tx queues
2537 * reclaim beacon resources
2538 * power down hardware
2539 *
2540 * Note that some of this work is not possible if the
2541 * hardware is gone (invalid).
2542 */
2543 ieee80211_stop_queues(sc->hw);
3031 2544
3032static void ath5k_stop(struct ieee80211_hw *hw) 2545 if (!test_bit(ATH_STAT_INVALID, sc->status)) {
3033{ 2546 ath5k_led_off(sc);
3034 ath5k_stop_hw(hw->priv); 2547 ath5k_hw_set_imr(ah, 0);
2548 synchronize_irq(sc->irq);
2549 ath5k_rx_stop(sc);
2550 ath5k_hw_dma_stop(ah);
2551 ath5k_drain_tx_buffs(sc);
2552 ath5k_hw_phy_disable(ah);
2553 }
2554
2555 return 0;
3035} 2556}
3036 2557
3037static int ath5k_add_interface(struct ieee80211_hw *hw, 2558int
3038 struct ieee80211_vif *vif) 2559ath5k_init_hw(struct ath5k_softc *sc)
3039{ 2560{
3040 struct ath5k_softc *sc = hw->priv; 2561 struct ath5k_hw *ah = sc->ah;
3041 int ret; 2562 struct ath_common *common = ath5k_hw_common(ah);
2563 int ret, i;
3042 2564
3043 mutex_lock(&sc->lock); 2565 mutex_lock(&sc->lock);
3044 if (sc->vif) {
3045 ret = 0;
3046 goto end;
3047 }
3048 2566
3049 sc->vif = vif; 2567 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
3050 2568
3051 switch (vif->type) { 2569 /*
3052 case NL80211_IFTYPE_AP: 2570 * Stop anything previously setup. This is safe
3053 case NL80211_IFTYPE_STATION: 2571 * no matter this is the first time through or not.
3054 case NL80211_IFTYPE_ADHOC: 2572 */
3055 case NL80211_IFTYPE_MESH_POINT: 2573 ath5k_stop_locked(sc);
3056 case NL80211_IFTYPE_MONITOR: 2574
3057 sc->opmode = vif->type; 2575 /*
3058 break; 2576 * The basic interface to setting the hardware in a good
3059 default: 2577 * state is ``reset''. On return the hardware is known to
3060 ret = -EOPNOTSUPP; 2578 * be powered up and with interrupts disabled. This must
3061 goto end; 2579 * be followed by initialization of the appropriate bits
3062 } 2580 * and then setup of the interrupt mask.
2581 */
2582 sc->curchan = sc->hw->conf.channel;
2583 sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
2584 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
2585 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
3063 2586
3064 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode); 2587 ret = ath5k_reset(sc, NULL, false);
2588 if (ret)
2589 goto done;
3065 2590
3066 ath5k_hw_set_lladdr(sc->ah, vif->addr); 2591 ath5k_rfkill_hw_start(ah);
3067 ath5k_mode_setup(sc); 2592
2593 /*
2594 * Reset the key cache since some parts do not reset the
2595 * contents on initial power up or resume from suspend.
2596 */
2597 for (i = 0; i < common->keymax; i++)
2598 ath_hw_keyreset(common, (u16) i);
2599
2600 /* Use higher rates for acks instead of base
2601 * rate */
2602 ah->ah_ack_bitrate_high = true;
2603
2604 for (i = 0; i < ARRAY_SIZE(sc->bslot); i++)
2605 sc->bslot[i] = NULL;
3068 2606
3069 ret = 0; 2607 ret = 0;
3070end: 2608done:
2609 mmiowb();
3071 mutex_unlock(&sc->lock); 2610 mutex_unlock(&sc->lock);
2611
2612 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
2613 msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
2614
3072 return ret; 2615 return ret;
3073} 2616}
3074 2617
3075static void 2618static void stop_tasklets(struct ath5k_softc *sc)
3076ath5k_remove_interface(struct ieee80211_hw *hw,
3077 struct ieee80211_vif *vif)
3078{ 2619{
3079 struct ath5k_softc *sc = hw->priv; 2620 sc->rx_pending = false;
3080 u8 mac[ETH_ALEN] = {}; 2621 sc->tx_pending = false;
3081 2622 tasklet_kill(&sc->rxtq);
3082 mutex_lock(&sc->lock); 2623 tasklet_kill(&sc->txtq);
3083 if (sc->vif != vif) 2624 tasklet_kill(&sc->calib);
3084 goto end; 2625 tasklet_kill(&sc->beacontq);
3085 2626 tasklet_kill(&sc->ani_tasklet);
3086 ath5k_hw_set_lladdr(sc->ah, mac);
3087 sc->vif = NULL;
3088end:
3089 mutex_unlock(&sc->lock);
3090} 2627}
3091 2628
3092/* 2629/*
3093 * TODO: Phy disable/diversity etc 2630 * Stop the device, grabbing the top-level lock to protect
2631 * against concurrent entry through ath5k_init (which can happen
2632 * if another thread does a system call and the thread doing the
2633 * stop is preempted).
3094 */ 2634 */
3095static int 2635int
3096ath5k_config(struct ieee80211_hw *hw, u32 changed) 2636ath5k_stop_hw(struct ath5k_softc *sc)
3097{ 2637{
3098 struct ath5k_softc *sc = hw->priv; 2638 int ret;
3099 struct ath5k_hw *ah = sc->ah;
3100 struct ieee80211_conf *conf = &hw->conf;
3101 int ret = 0;
3102 2639
3103 mutex_lock(&sc->lock); 2640 mutex_lock(&sc->lock);
2641 ret = ath5k_stop_locked(sc);
2642 if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
2643 /*
2644 * Don't set the card in full sleep mode!
2645 *
2646 * a) When the device is in this state it must be carefully
2647 * woken up or references to registers in the PCI clock
2648 * domain may freeze the bus (and system). This varies
2649 * by chip and is mostly an issue with newer parts
2650 * (madwifi sources mentioned srev >= 0x78) that go to
2651 * sleep more quickly.
2652 *
2653 * b) On older chips full sleep results a weird behaviour
2654 * during wakeup. I tested various cards with srev < 0x78
2655 * and they don't wake up after module reload, a second
2656 * module reload is needed to bring the card up again.
2657 *
2658 * Until we figure out what's going on don't enable
2659 * full chip reset on any chip (this is what Legacy HAL
2660 * and Sam's HAL do anyway). Instead Perform a full reset
2661 * on the device (same as initial state after attach) and
2662 * leave it idle (keep MAC/BB on warm reset) */
2663 ret = ath5k_hw_on_hold(sc->ah);
3104 2664
3105 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 2665 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
3106 ret = ath5k_chan_set(sc, conf->channel); 2666 "putting device to sleep\n");
3107 if (ret < 0)
3108 goto unlock;
3109 }
3110
3111 if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
3112 (sc->power_level != conf->power_level)) {
3113 sc->power_level = conf->power_level;
3114
3115 /* Half dB steps */
3116 ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2));
3117 } 2667 }
3118 2668
3119 /* TODO: 2669 mmiowb();
3120 * 1) Move this on config_interface and handle each case
3121 * separately eg. when we have only one STA vif, use
3122 * AR5K_ANTMODE_SINGLE_AP
3123 *
3124 * 2) Allow the user to change antenna mode eg. when only
3125 * one antenna is present
3126 *
3127 * 3) Allow the user to set default/tx antenna when possible
3128 *
3129 * 4) Default mode should handle 90% of the cases, together
3130 * with fixed a/b and single AP modes we should be able to
3131 * handle 99%. Sectored modes are extreme cases and i still
3132 * haven't found a usage for them. If we decide to support them,
3133 * then we must allow the user to set how many tx antennas we
3134 * have available
3135 */
3136 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
3137
3138unlock:
3139 mutex_unlock(&sc->lock); 2670 mutex_unlock(&sc->lock);
3140 return ret;
3141}
3142 2671
3143static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, 2672 stop_tasklets(sc);
3144 struct netdev_hw_addr_list *mc_list)
3145{
3146 u32 mfilt[2], val;
3147 u8 pos;
3148 struct netdev_hw_addr *ha;
3149 2673
3150 mfilt[0] = 0; 2674 cancel_delayed_work_sync(&sc->tx_complete_work);
3151 mfilt[1] = 1;
3152 2675
3153 netdev_hw_addr_list_for_each(ha, mc_list) { 2676 ath5k_rfkill_hw_stop(sc->ah);
3154 /* calculate XOR of eight 6-bit values */
3155 val = get_unaligned_le32(ha->addr + 0);
3156 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
3157 val = get_unaligned_le32(ha->addr + 3);
3158 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
3159 pos &= 0x3f;
3160 mfilt[pos / 32] |= (1 << (pos % 32));
3161 /* XXX: we might be able to just do this instead,
3162 * but not sure, needs testing, if we do use this we'd
3163 * neet to inform below to not reset the mcast */
3164 /* ath5k_hw_set_mcast_filterindex(ah,
3165 * ha->addr[5]); */
3166 }
3167 2677
3168 return ((u64)(mfilt[1]) << 32) | mfilt[0]; 2678 return ret;
3169} 2679}
3170 2680
3171#define SUPPORTED_FIF_FLAGS \
3172 FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \
3173 FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
3174 FIF_BCN_PRBRESP_PROMISC
3175/* 2681/*
3176 * o always accept unicast, broadcast, and multicast traffic 2682 * Reset the hardware. If chan is not NULL, then also pause rx/tx
3177 * o multicast traffic for all BSSIDs will be enabled if mac80211 2683 * and change to the given channel.
3178 * says it should be 2684 *
3179 * o maintain current state of phy ofdm or phy cck error reception. 2685 * This should be called with sc->lock.
3180 * If the hardware detects any of these type of errors then
3181 * ath5k_hw_get_rx_filter() will pass to us the respective
3182 * hardware filters to be able to receive these type of frames.
3183 * o probe request frames are accepted only when operating in
3184 * hostap, adhoc, or monitor modes
3185 * o enable promiscuous mode according to the interface state
3186 * o accept beacons:
3187 * - when operating in adhoc mode so the 802.11 layer creates
3188 * node table entries for peers,
3189 * - when operating in station mode for collecting rssi data when
3190 * the station is otherwise quiet, or
3191 * - when scanning
3192 */ 2686 */
3193static void ath5k_configure_filter(struct ieee80211_hw *hw, 2687static int
3194 unsigned int changed_flags, 2688ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
3195 unsigned int *new_flags, 2689 bool skip_pcu)
3196 u64 multicast)
3197{ 2690{
3198 struct ath5k_softc *sc = hw->priv;
3199 struct ath5k_hw *ah = sc->ah; 2691 struct ath5k_hw *ah = sc->ah;
3200 u32 mfilt[2], rfilt; 2692 struct ath_common *common = ath5k_hw_common(ah);
2693 int ret, ani_mode;
2694 bool fast;
3201 2695
3202 mutex_lock(&sc->lock); 2696 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
3203 2697
3204 mfilt[0] = multicast; 2698 ath5k_hw_set_imr(ah, 0);
3205 mfilt[1] = multicast >> 32; 2699 synchronize_irq(sc->irq);
2700 stop_tasklets(sc);
3206 2701
3207 /* Only deal with supported flags */ 2702 /* Save ani mode and disable ANI during
3208 changed_flags &= SUPPORTED_FIF_FLAGS; 2703 * reset. If we don't we might get false
3209 *new_flags &= SUPPORTED_FIF_FLAGS; 2704 * PHY error interrupts. */
2705 ani_mode = ah->ah_sc->ani_state.ani_mode;
2706 ath5k_ani_init(ah, ATH5K_ANI_MODE_OFF);
2707
2708 /* We are going to empty hw queues
2709 * so we should also free any remaining
2710 * tx buffers */
2711 ath5k_drain_tx_buffs(sc);
2712 if (chan)
2713 sc->curchan = chan;
3210 2714
3211 /* If HW detects any phy or radar errors, leave those filters on. 2715 fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0;
3212 * Also, always enable Unicast, Broadcasts and Multicast
3213 * XXX: move unicast, bssid broadcasts and multicast to mac80211 */
3214 rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) |
3215 (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST |
3216 AR5K_RX_FILTER_MCAST);
3217 2716
3218 if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { 2717 ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast,
3219 if (*new_flags & FIF_PROMISC_IN_BSS) { 2718 skip_pcu);
3220 __set_bit(ATH_STAT_PROMISC, sc->status); 2719 if (ret) {
3221 } else { 2720 ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
3222 __clear_bit(ATH_STAT_PROMISC, sc->status); 2721 goto err;
3223 }
3224 } 2722 }
3225 2723
3226 if (test_bit(ATH_STAT_PROMISC, sc->status)) 2724 ret = ath5k_rx_start(sc);
3227 rfilt |= AR5K_RX_FILTER_PROM; 2725 if (ret) {
3228 2726 ATH5K_ERR(sc, "can't start recv logic\n");
3229 /* Note, AR5K_RX_FILTER_MCAST is already enabled */ 2727 goto err;
3230 if (*new_flags & FIF_ALLMULTI) {
3231 mfilt[0] = ~0;
3232 mfilt[1] = ~0;
3233 } 2728 }
3234 2729
3235 /* This is the best we can do */ 2730 ath5k_ani_init(ah, ani_mode);
3236 if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL))
3237 rfilt |= AR5K_RX_FILTER_PHYERR;
3238 2731
3239 /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons 2732 ah->ah_cal_next_full = jiffies;
3240 * and probes for any BSSID, this needs testing */ 2733 ah->ah_cal_next_ani = jiffies;
3241 if (*new_flags & FIF_BCN_PRBRESP_PROMISC) 2734 ah->ah_cal_next_nf = jiffies;
3242 rfilt |= AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ; 2735 ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8);
3243 2736
3244 /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not 2737 /* clear survey data and cycle counters */
3245 * set we should only pass on control frames for this 2738 memset(&sc->survey, 0, sizeof(sc->survey));
3246 * station. This needs testing. I believe right now this 2739 spin_lock_bh(&common->cc_lock);
3247 * enables *all* control frames, which is OK.. but 2740 ath_hw_cycle_counters_update(common);
3248 * but we should see if we can improve on granularity */ 2741 memset(&common->cc_survey, 0, sizeof(common->cc_survey));
3249 if (*new_flags & FIF_CONTROL) 2742 memset(&common->cc_ani, 0, sizeof(common->cc_ani));
3250 rfilt |= AR5K_RX_FILTER_CONTROL; 2743 spin_unlock_bh(&common->cc_lock);
3251 2744
3252 /* Additional settings per mode -- this is per ath5k */ 2745 /*
2746 * Change channels and update the h/w rate map if we're switching;
2747 * e.g. 11a to 11b/g.
2748 *
2749 * We may be doing a reset in response to an ioctl that changes the
2750 * channel so update any state that might change as a result.
2751 *
2752 * XXX needed?
2753 */
2754/* ath5k_chan_change(sc, c); */
3253 2755
3254 /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */ 2756 ath5k_beacon_config(sc);
2757 /* intrs are enabled by ath5k_beacon_config */
3255 2758
3256 switch (sc->opmode) { 2759 ieee80211_wake_queues(sc->hw);
3257 case NL80211_IFTYPE_MESH_POINT:
3258 case NL80211_IFTYPE_MONITOR:
3259 rfilt |= AR5K_RX_FILTER_CONTROL |
3260 AR5K_RX_FILTER_BEACON |
3261 AR5K_RX_FILTER_PROBEREQ |
3262 AR5K_RX_FILTER_PROM;
3263 break;
3264 case NL80211_IFTYPE_AP:
3265 case NL80211_IFTYPE_ADHOC:
3266 rfilt |= AR5K_RX_FILTER_PROBEREQ |
3267 AR5K_RX_FILTER_BEACON;
3268 break;
3269 case NL80211_IFTYPE_STATION:
3270 if (sc->assoc)
3271 rfilt |= AR5K_RX_FILTER_BEACON;
3272 default:
3273 break;
3274 }
3275 2760
3276 /* Set filters */ 2761 return 0;
3277 ath5k_hw_set_rx_filter(ah, rfilt); 2762err:
2763 return ret;
2764}
3278 2765
3279 /* Set multicast bits */ 2766static void ath5k_reset_work(struct work_struct *work)
3280 ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]); 2767{
3281 /* Set the cached hw filter flags, this will alter actually 2768 struct ath5k_softc *sc = container_of(work, struct ath5k_softc,
3282 * be set in HW */ 2769 reset_work);
3283 sc->filter_flags = rfilt;
3284 2770
2771 mutex_lock(&sc->lock);
2772 ath5k_reset(sc, NULL, true);
3285 mutex_unlock(&sc->lock); 2773 mutex_unlock(&sc->lock);
3286} 2774}
3287 2775
3288static int 2776static int
3289ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 2777ath5k_init(struct ieee80211_hw *hw)
3290 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
3291 struct ieee80211_key_conf *key)
3292{ 2778{
2779
3293 struct ath5k_softc *sc = hw->priv; 2780 struct ath5k_softc *sc = hw->priv;
3294 struct ath5k_hw *ah = sc->ah; 2781 struct ath5k_hw *ah = sc->ah;
3295 struct ath_common *common = ath5k_hw_common(ah); 2782 struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
3296 int ret = 0; 2783 struct ath5k_txq *txq;
2784 u8 mac[ETH_ALEN] = {};
2785 int ret;
3297 2786
3298 if (modparam_nohwcrypt)
3299 return -EOPNOTSUPP;
3300 2787
3301 if (sc->opmode == NL80211_IFTYPE_AP) 2788 /*
3302 return -EOPNOTSUPP; 2789 * Check if the MAC has multi-rate retry support.
2790 * We do this by trying to setup a fake extended
2791 * descriptor. MACs that don't have support will
2792 * return false w/o doing anything. MACs that do
2793 * support it will return true w/o doing anything.
2794 */
2795 ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
3303 2796
3304 switch (key->alg) { 2797 if (ret < 0)
3305 case ALG_WEP: 2798 goto err;
3306 case ALG_TKIP: 2799 if (ret > 0)
3307 break; 2800 __set_bit(ATH_STAT_MRRETRY, sc->status);
3308 case ALG_CCMP:
3309 if (sc->ah->ah_aes_support)
3310 break;
3311 2801
3312 return -EOPNOTSUPP; 2802 /*
3313 default: 2803 * Collect the channel list. The 802.11 layer
3314 WARN_ON(1); 2804 * is resposible for filtering this list based
3315 return -EINVAL; 2805 * on settings like the phy mode and regulatory
2806 * domain restrictions.
2807 */
2808 ret = ath5k_setup_bands(hw);
2809 if (ret) {
2810 ATH5K_ERR(sc, "can't get channels\n");
2811 goto err;
3316 } 2812 }
3317 2813
3318 mutex_lock(&sc->lock); 2814 /*
2815 * Allocate tx+rx descriptors and populate the lists.
2816 */
2817 ret = ath5k_desc_alloc(sc);
2818 if (ret) {
2819 ATH5K_ERR(sc, "can't allocate descriptors\n");
2820 goto err;
2821 }
3319 2822
3320 switch (cmd) { 2823 /*
3321 case SET_KEY: 2824 * Allocate hardware transmit queues: one queue for
3322 ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, 2825 * beacon frames and one data queue for each QoS
3323 sta ? sta->addr : NULL); 2826 * priority. Note that hw functions handle resetting
3324 if (ret) { 2827 * these queues at the needed time.
3325 ATH5K_ERR(sc, "can't set the key\n"); 2828 */
3326 goto unlock; 2829 ret = ath5k_beaconq_setup(ah);
3327 } 2830 if (ret < 0) {
3328 __set_bit(key->keyidx, common->keymap); 2831 ATH5K_ERR(sc, "can't setup a beacon xmit queue\n");
3329 key->hw_key_idx = key->keyidx; 2832 goto err_desc;
3330 key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV | 2833 }
3331 IEEE80211_KEY_FLAG_GENERATE_MMIC); 2834 sc->bhalq = ret;
3332 break; 2835 sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0);
3333 case DISABLE_KEY: 2836 if (IS_ERR(sc->cabq)) {
3334 ath5k_hw_reset_key(sc->ah, key->keyidx); 2837 ATH5K_ERR(sc, "can't setup cab queue\n");
3335 __clear_bit(key->keyidx, common->keymap); 2838 ret = PTR_ERR(sc->cabq);
3336 break; 2839 goto err_bhal;
3337 default:
3338 ret = -EINVAL;
3339 goto unlock;
3340 } 2840 }
3341 2841
3342unlock: 2842 /* 5211 and 5212 usually support 10 queues but we better rely on the
3343 mmiowb(); 2843 * capability information */
3344 mutex_unlock(&sc->lock); 2844 if (ah->ah_capabilities.cap_queues.q_tx_num >= 6) {
3345 return ret; 2845 /* This order matches mac80211's queue priority, so we can
3346} 2846 * directly use the mac80211 queue number without any mapping */
2847 txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO);
2848 if (IS_ERR(txq)) {
2849 ATH5K_ERR(sc, "can't setup xmit queue\n");
2850 ret = PTR_ERR(txq);
2851 goto err_queues;
2852 }
2853 txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI);
2854 if (IS_ERR(txq)) {
2855 ATH5K_ERR(sc, "can't setup xmit queue\n");
2856 ret = PTR_ERR(txq);
2857 goto err_queues;
2858 }
2859 txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
2860 if (IS_ERR(txq)) {
2861 ATH5K_ERR(sc, "can't setup xmit queue\n");
2862 ret = PTR_ERR(txq);
2863 goto err_queues;
2864 }
2865 txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
2866 if (IS_ERR(txq)) {
2867 ATH5K_ERR(sc, "can't setup xmit queue\n");
2868 ret = PTR_ERR(txq);
2869 goto err_queues;
2870 }
2871 hw->queues = 4;
2872 } else {
2873 /* older hardware (5210) can only support one data queue */
2874 txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
2875 if (IS_ERR(txq)) {
2876 ATH5K_ERR(sc, "can't setup xmit queue\n");
2877 ret = PTR_ERR(txq);
2878 goto err_queues;
2879 }
2880 hw->queues = 1;
2881 }
3347 2882
3348static int 2883 tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
3349ath5k_get_stats(struct ieee80211_hw *hw, 2884 tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
3350 struct ieee80211_low_level_stats *stats) 2885 tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc);
3351{ 2886 tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
3352 struct ath5k_softc *sc = hw->priv; 2887 tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc);
3353 2888
3354 /* Force update */ 2889 INIT_WORK(&sc->reset_work, ath5k_reset_work);
3355 ath5k_hw_update_mib_counters(sc->ah); 2890 INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work);
3356 2891
3357 stats->dot11ACKFailureCount = sc->stats.ack_fail; 2892 ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac);
3358 stats->dot11RTSFailureCount = sc->stats.rts_fail; 2893 if (ret) {
3359 stats->dot11RTSSuccessCount = sc->stats.rts_ok; 2894 ATH5K_ERR(sc, "unable to read address from EEPROM\n");
3360 stats->dot11FCSErrorCount = sc->stats.fcs_error; 2895 goto err_queues;
2896 }
3361 2897
3362 return 0; 2898 SET_IEEE80211_PERM_ADDR(hw, mac);
3363} 2899 memcpy(&sc->lladdr, mac, ETH_ALEN);
2900 /* All MAC address bits matter for ACKs */
2901 ath5k_update_bssid_mask_and_opmode(sc, NULL);
3364 2902
3365static int ath5k_get_survey(struct ieee80211_hw *hw, int idx, 2903 regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
3366 struct survey_info *survey) 2904 ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
3367{ 2905 if (ret) {
3368 struct ath5k_softc *sc = hw->priv; 2906 ATH5K_ERR(sc, "can't initialize regulatory system\n");
3369 struct ieee80211_conf *conf = &hw->conf; 2907 goto err_queues;
2908 }
3370 2909
3371 if (idx != 0) 2910 ret = ieee80211_register_hw(hw);
3372 return -ENOENT; 2911 if (ret) {
2912 ATH5K_ERR(sc, "can't register ieee80211 hw\n");
2913 goto err_queues;
2914 }
3373 2915
3374 survey->channel = conf->channel; 2916 if (!ath_is_world_regd(regulatory))
3375 survey->filled = SURVEY_INFO_NOISE_DBM; 2917 regulatory_hint(hw->wiphy, regulatory->alpha2);
3376 survey->noise = sc->ah->ah_noise_floor;
3377 2918
3378 return 0; 2919 ath5k_init_leds(sc);
3379}
3380 2920
3381static u64 2921 ath5k_sysfs_register(sc);
3382ath5k_get_tsf(struct ieee80211_hw *hw)
3383{
3384 struct ath5k_softc *sc = hw->priv;
3385 2922
3386 return ath5k_hw_get_tsf64(sc->ah); 2923 return 0;
2924err_queues:
2925 ath5k_txq_release(sc);
2926err_bhal:
2927 ath5k_hw_release_tx_queue(ah, sc->bhalq);
2928err_desc:
2929 ath5k_desc_free(sc);
2930err:
2931 return ret;
3387} 2932}
3388 2933
3389static void 2934void
3390ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf) 2935ath5k_deinit_softc(struct ath5k_softc *sc)
3391{ 2936{
3392 struct ath5k_softc *sc = hw->priv; 2937 struct ieee80211_hw *hw = sc->hw;
3393 2938
3394 ath5k_hw_set_tsf64(sc->ah, tsf); 2939 /*
3395} 2940 * NB: the order of these is important:
3396 2941 * o call the 802.11 layer before detaching ath5k_hw to
3397static void 2942 * ensure callbacks into the driver to delete global
3398ath5k_reset_tsf(struct ieee80211_hw *hw) 2943 * key cache entries can be handled
3399{ 2944 * o reclaim the tx queue data structures after calling
3400 struct ath5k_softc *sc = hw->priv; 2945 * the 802.11 layer as we'll get called back to reclaim
2946 * node state and potentially want to use them
2947 * o to cleanup the tx queues the hal is called, so detach
2948 * it last
2949 * XXX: ??? detach ath5k_hw ???
2950 * Other than that, it's straightforward...
2951 */
2952 ieee80211_unregister_hw(hw);
2953 ath5k_desc_free(sc);
2954 ath5k_txq_release(sc);
2955 ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
2956 ath5k_unregister_leds(sc);
3401 2957
2958 ath5k_sysfs_unregister(sc);
3402 /* 2959 /*
3403 * in IBSS mode we need to update the beacon timers too. 2960 * NB: can't reclaim these until after ieee80211_ifdetach
3404 * this will also reset the TSF if we call it with 0 2961 * returns because we'll get called back to reclaim node
2962 * state and potentially want to use them.
3405 */ 2963 */
3406 if (sc->opmode == NL80211_IFTYPE_ADHOC) 2964 ath5k_hw_deinit(sc->ah);
3407 ath5k_beacon_update_timers(sc, 0); 2965 free_irq(sc->irq, sc);
3408 else
3409 ath5k_hw_reset_tsf(sc->ah);
3410} 2966}
3411 2967
3412/* 2968bool
3413 * Updates the beacon that is sent by ath5k_beacon_send. For adhoc, 2969ath_any_vif_assoc(struct ath5k_softc *sc)
3414 * this is called only once at config_bss time, for AP we do it every
3415 * SWBA interrupt so that the TIM will reflect buffered frames.
3416 *
3417 * Called with the beacon lock.
3418 */
3419static int
3420ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
3421{ 2970{
3422 int ret; 2971 struct ath5k_vif_iter_data iter_data;
3423 struct ath5k_softc *sc = hw->priv; 2972 iter_data.hw_macaddr = NULL;
3424 struct sk_buff *skb; 2973 iter_data.any_assoc = false;
2974 iter_data.need_set_hw_addr = false;
2975 iter_data.found_active = true;
3425 2976
3426 if (WARN_ON(!vif)) { 2977 ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter,
3427 ret = -EINVAL; 2978 &iter_data);
3428 goto out; 2979 return iter_data.any_assoc;
3429 }
3430
3431 skb = ieee80211_beacon_get(hw, vif);
3432
3433 if (!skb) {
3434 ret = -ENOMEM;
3435 goto out;
3436 }
3437
3438 ath5k_debug_dump_skb(sc, skb, "BC ", 1);
3439
3440 ath5k_txbuf_free_skb(sc, sc->bbuf);
3441 sc->bbuf->skb = skb;
3442 ret = ath5k_beacon_setup(sc, sc->bbuf);
3443 if (ret)
3444 sc->bbuf->skb = NULL;
3445out:
3446 return ret;
3447} 2980}
3448 2981
3449static void 2982void
3450set_beacon_filter(struct ieee80211_hw *hw, bool enable) 2983set_beacon_filter(struct ieee80211_hw *hw, bool enable)
3451{ 2984{
3452 struct ath5k_softc *sc = hw->priv; 2985 struct ath5k_softc *sc = hw->priv;
@@ -3460,94 +2993,3 @@ set_beacon_filter(struct ieee80211_hw *hw, bool enable)
3460 ath5k_hw_set_rx_filter(ah, rfilt); 2993 ath5k_hw_set_rx_filter(ah, rfilt);
3461 sc->filter_flags = rfilt; 2994 sc->filter_flags = rfilt;
3462} 2995}
3463
3464static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3465 struct ieee80211_vif *vif,
3466 struct ieee80211_bss_conf *bss_conf,
3467 u32 changes)
3468{
3469 struct ath5k_softc *sc = hw->priv;
3470 struct ath5k_hw *ah = sc->ah;
3471 struct ath_common *common = ath5k_hw_common(ah);
3472 unsigned long flags;
3473
3474 mutex_lock(&sc->lock);
3475 if (WARN_ON(sc->vif != vif))
3476 goto unlock;
3477
3478 if (changes & BSS_CHANGED_BSSID) {
3479 /* Cache for later use during resets */
3480 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
3481 common->curaid = 0;
3482 ath5k_hw_set_associd(ah);
3483 mmiowb();
3484 }
3485
3486 if (changes & BSS_CHANGED_BEACON_INT)
3487 sc->bintval = bss_conf->beacon_int;
3488
3489 if (changes & BSS_CHANGED_ASSOC) {
3490 sc->assoc = bss_conf->assoc;
3491 if (sc->opmode == NL80211_IFTYPE_STATION)
3492 set_beacon_filter(hw, sc->assoc);
3493 ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
3494 AR5K_LED_ASSOC : AR5K_LED_INIT);
3495 if (bss_conf->assoc) {
3496 ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
3497 "Bss Info ASSOC %d, bssid: %pM\n",
3498 bss_conf->aid, common->curbssid);
3499 common->curaid = bss_conf->aid;
3500 ath5k_hw_set_associd(ah);
3501 /* Once ANI is available you would start it here */
3502 }
3503 }
3504
3505 if (changes & BSS_CHANGED_BEACON) {
3506 spin_lock_irqsave(&sc->block, flags);
3507 ath5k_beacon_update(hw, vif);
3508 spin_unlock_irqrestore(&sc->block, flags);
3509 }
3510
3511 if (changes & BSS_CHANGED_BEACON_ENABLED)
3512 sc->enable_beacon = bss_conf->enable_beacon;
3513
3514 if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED |
3515 BSS_CHANGED_BEACON_INT))
3516 ath5k_beacon_config(sc);
3517
3518 unlock:
3519 mutex_unlock(&sc->lock);
3520}
3521
3522static void ath5k_sw_scan_start(struct ieee80211_hw *hw)
3523{
3524 struct ath5k_softc *sc = hw->priv;
3525 if (!sc->assoc)
3526 ath5k_hw_set_ledstate(sc->ah, AR5K_LED_SCAN);
3527}
3528
3529static void ath5k_sw_scan_complete(struct ieee80211_hw *hw)
3530{
3531 struct ath5k_softc *sc = hw->priv;
3532 ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
3533 AR5K_LED_ASSOC : AR5K_LED_INIT);
3534}
3535
3536/**
3537 * ath5k_set_coverage_class - Set IEEE 802.11 coverage class
3538 *
3539 * @hw: struct ieee80211_hw pointer
3540 * @coverage_class: IEEE 802.11 coverage class number
3541 *
3542 * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given
3543 * coverage class. The values are persistent, they are restored after device
3544 * reset.
3545 */
3546static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
3547{
3548 struct ath5k_softc *sc = hw->priv;
3549
3550 mutex_lock(&sc->lock);
3551 ath5k_hw_set_coverage_class(sc->ah, coverage_class);
3552 mutex_unlock(&sc->lock);
3553}
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index dc1241f9c4e8..b294f3305011 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -58,7 +58,9 @@
58 58
59#define ATH_RXBUF 40 /* number of RX buffers */ 59#define ATH_RXBUF 40 /* number of RX buffers */
60#define ATH_TXBUF 200 /* number of TX buffers */ 60#define ATH_TXBUF 200 /* number of TX buffers */
61#define ATH_BCBUF 1 /* number of beacon buffers */ 61#define ATH_BCBUF 4 /* number of beacon buffers */
62#define ATH5K_TXQ_LEN_MAX (ATH_TXBUF / 4) /* bufs per queue */
63#define ATH5K_TXQ_LEN_LOW (ATH5K_TXQ_LEN_MAX / 2) /* low mark */
62 64
63struct ath5k_buf { 65struct ath5k_buf {
64 struct list_head list; 66 struct list_head list;
@@ -83,6 +85,10 @@ struct ath5k_txq {
83 struct list_head q; /* transmit queue */ 85 struct list_head q; /* transmit queue */
84 spinlock_t lock; /* lock on q and link */ 86 spinlock_t lock; /* lock on q and link */
85 bool setup; 87 bool setup;
88 int txq_len; /* number of queued buffers */
89 int txq_max; /* max allowed num of queued buffers */
90 bool txq_poll_mark;
91 unsigned int txq_stuck; /* informational counter */
86}; 92};
87 93
88#define ATH5K_LED_MAX_NAME_LEN 31 94#define ATH5K_LED_MAX_NAME_LEN 31
@@ -116,6 +122,13 @@ struct ath5k_statistics {
116 /* frame errors */ 122 /* frame errors */
117 unsigned int rx_all_count; /* all RX frames, including errors */ 123 unsigned int rx_all_count; /* all RX frames, including errors */
118 unsigned int tx_all_count; /* all TX frames, including errors */ 124 unsigned int tx_all_count; /* all TX frames, including errors */
125 unsigned int rx_bytes_count; /* all RX bytes, including errored pks
126 * and the MAC headers for each packet
127 */
128 unsigned int tx_bytes_count; /* all TX bytes, including errored pkts
129 * and the MAC headers and padding for
130 * each packet.
131 */
119 unsigned int rxerr_crc; 132 unsigned int rxerr_crc;
120 unsigned int rxerr_phy; 133 unsigned int rxerr_phy;
121 unsigned int rxerr_phy_code[32]; 134 unsigned int rxerr_phy_code[32];
@@ -146,10 +159,21 @@ struct ath5k_statistics {
146#define ATH_CHAN_MAX (14+14+14+252+20) 159#define ATH_CHAN_MAX (14+14+14+252+20)
147#endif 160#endif
148 161
162struct ath5k_vif {
163 bool assoc; /* are we associated or not */
164 enum nl80211_iftype opmode;
165 int bslot;
166 struct ath5k_buf *bbuf; /* beacon buffer */
167 u8 lladdr[ETH_ALEN];
168};
169
149/* Software Carrier, keeps track of the driver state 170/* Software Carrier, keeps track of the driver state
150 * associated with an instance of a device */ 171 * associated with an instance of a device */
151struct ath5k_softc { 172struct ath5k_softc {
152 struct pci_dev *pdev; /* for dma mapping */ 173 struct pci_dev *pdev;
174 struct device *dev; /* for dma mapping */
175 int irq;
176 u16 devid;
153 void __iomem *iobase; /* address of the device */ 177 void __iomem *iobase; /* address of the device */
154 struct mutex lock; /* dev-level lock */ 178 struct mutex lock; /* dev-level lock */
155 struct ieee80211_hw *hw; /* IEEE 802.11 common */ 179 struct ieee80211_hw *hw; /* IEEE 802.11 common */
@@ -160,8 +184,6 @@ struct ath5k_softc {
160 enum nl80211_iftype opmode; 184 enum nl80211_iftype opmode;
161 struct ath5k_hw *ah; /* Atheros HW */ 185 struct ath5k_hw *ah; /* Atheros HW */
162 186
163 struct ieee80211_supported_band *curband;
164
165#ifdef CONFIG_ATH5K_DEBUG 187#ifdef CONFIG_ATH5K_DEBUG
166 struct ath5k_dbg_info debug; /* debug info */ 188 struct ath5k_dbg_info debug; /* debug info */
167#endif /* CONFIG_ATH5K_DEBUG */ 189#endif /* CONFIG_ATH5K_DEBUG */
@@ -171,21 +193,26 @@ struct ath5k_softc {
171 dma_addr_t desc_daddr; /* DMA (physical) address */ 193 dma_addr_t desc_daddr; /* DMA (physical) address */
172 size_t desc_len; /* size of TX/RX descriptors */ 194 size_t desc_len; /* size of TX/RX descriptors */
173 195
174 DECLARE_BITMAP(status, 5); 196 DECLARE_BITMAP(status, 6);
175#define ATH_STAT_INVALID 0 /* disable hardware accesses */ 197#define ATH_STAT_INVALID 0 /* disable hardware accesses */
176#define ATH_STAT_MRRETRY 1 /* multi-rate retry support */ 198#define ATH_STAT_MRRETRY 1 /* multi-rate retry support */
177#define ATH_STAT_PROMISC 2 199#define ATH_STAT_PROMISC 2
178#define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */ 200#define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */
179#define ATH_STAT_STARTED 4 /* opened & irqs enabled */ 201#define ATH_STAT_STARTED 4 /* opened & irqs enabled */
202#define ATH_STAT_2G_DISABLED 5 /* multiband radio without 2G */
180 203
181 unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ 204 unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
182 unsigned int curmode; /* current phy mode */
183 struct ieee80211_channel *curchan; /* current h/w channel */ 205 struct ieee80211_channel *curchan; /* current h/w channel */
184 206
185 struct ieee80211_vif *vif; 207 u16 nvifs;
186 208
187 enum ath5k_int imask; /* interrupt mask copy */ 209 enum ath5k_int imask; /* interrupt mask copy */
188 210
211 spinlock_t irqlock;
212 bool rx_pending; /* rx tasklet pending */
213 bool tx_pending; /* tx tasklet pending */
214
215 u8 lladdr[ETH_ALEN];
189 u8 bssidmask[ETH_ALEN]; 216 u8 bssidmask[ETH_ALEN];
190 217
191 unsigned int led_pin, /* GPIO pin for driving LED */ 218 unsigned int led_pin, /* GPIO pin for driving LED */
@@ -204,7 +231,6 @@ struct ath5k_softc {
204 spinlock_t txbuflock; 231 spinlock_t txbuflock;
205 unsigned int txbuf_len; /* buf count in txbuf list */ 232 unsigned int txbuf_len; /* buf count in txbuf list */
206 struct ath5k_txq txqs[AR5K_NUM_TX_QUEUES]; /* tx queues */ 233 struct ath5k_txq txqs[AR5K_NUM_TX_QUEUES]; /* tx queues */
207 struct ath5k_txq *txq; /* main tx queue */
208 struct tasklet_struct txtq; /* tx intr tasklet */ 234 struct tasklet_struct txtq; /* tx intr tasklet */
209 struct ath5k_led tx_led; /* tx led */ 235 struct ath5k_led tx_led; /* tx led */
210 236
@@ -214,7 +240,10 @@ struct ath5k_softc {
214 240
215 spinlock_t block; /* protects beacon */ 241 spinlock_t block; /* protects beacon */
216 struct tasklet_struct beacontq; /* beacon intr tasklet */ 242 struct tasklet_struct beacontq; /* beacon intr tasklet */
217 struct ath5k_buf *bbuf; /* beacon buffer */ 243 struct list_head bcbuf; /* beacon buffer */
244 struct ieee80211_vif *bslot[ATH_BCBUF];
245 u16 num_ap_vifs;
246 u16 num_adhoc_vifs;
218 unsigned int bhalq, /* SW q for outgoing beacons */ 247 unsigned int bhalq, /* SW q for outgoing beacons */
219 bmisscount, /* missed beacon transmits */ 248 bmisscount, /* missed beacon transmits */
220 bintval, /* beacon interval in TU */ 249 bintval, /* beacon interval in TU */
@@ -230,8 +259,25 @@ struct ath5k_softc {
230 259
231 struct ath5k_ani_state ani_state; 260 struct ath5k_ani_state ani_state;
232 struct tasklet_struct ani_tasklet; /* ANI calibration */ 261 struct tasklet_struct ani_tasklet; /* ANI calibration */
262
263 struct delayed_work tx_complete_work;
264
265 struct survey_info survey; /* collected survey info */
233}; 266};
234 267
268struct ath5k_vif_iter_data {
269 const u8 *hw_macaddr;
270 u8 mask[ETH_ALEN];
271 u8 active_mac[ETH_ALEN]; /* first active MAC */
272 bool need_set_hw_addr;
273 bool found_active;
274 bool any_assoc;
275 enum nl80211_iftype opmode;
276 int n_stas;
277};
278void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif);
279
280
235#define ath5k_hw_hasbssidmask(_ah) \ 281#define ath5k_hw_hasbssidmask(_ah) \
236 (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0) 282 (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0)
237#define ath5k_hw_hasveol(_ah) \ 283#define ath5k_hw_hasveol(_ah) \
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c
index beae519aa735..7dd88e1c3ff8 100644
--- a/drivers/net/wireless/ath/ath5k/caps.c
+++ b/drivers/net/wireless/ath/ath5k/caps.c
@@ -32,24 +32,24 @@
32 */ 32 */
33int ath5k_hw_set_capabilities(struct ath5k_hw *ah) 33int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
34{ 34{
35 struct ath5k_capabilities *caps = &ah->ah_capabilities;
35 u16 ee_header; 36 u16 ee_header;
36 37
37 /* Capabilities stored in the EEPROM */ 38 /* Capabilities stored in the EEPROM */
38 ee_header = ah->ah_capabilities.cap_eeprom.ee_header; 39 ee_header = caps->cap_eeprom.ee_header;
39 40
40 if (ah->ah_version == AR5K_AR5210) { 41 if (ah->ah_version == AR5K_AR5210) {
41 /* 42 /*
42 * Set radio capabilities 43 * Set radio capabilities
43 * (The AR5110 only supports the middle 5GHz band) 44 * (The AR5110 only supports the middle 5GHz band)
44 */ 45 */
45 ah->ah_capabilities.cap_range.range_5ghz_min = 5120; 46 caps->cap_range.range_5ghz_min = 5120;
46 ah->ah_capabilities.cap_range.range_5ghz_max = 5430; 47 caps->cap_range.range_5ghz_max = 5430;
47 ah->ah_capabilities.cap_range.range_2ghz_min = 0; 48 caps->cap_range.range_2ghz_min = 0;
48 ah->ah_capabilities.cap_range.range_2ghz_max = 0; 49 caps->cap_range.range_2ghz_max = 0;
49 50
50 /* Set supported modes */ 51 /* Set supported modes */
51 __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode); 52 __set_bit(AR5K_MODE_11A, caps->cap_mode);
52 __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
53 } else { 53 } else {
54 /* 54 /*
55 * XXX The tranceiver supports frequencies from 4920 to 6100GHz 55 * XXX The tranceiver supports frequencies from 4920 to 6100GHz
@@ -57,9 +57,8 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
57 * XXX current ieee80211 implementation because the IEEE 57 * XXX current ieee80211 implementation because the IEEE
58 * XXX channel mapping does not support negative channel 58 * XXX channel mapping does not support negative channel
59 * XXX numbers (2312MHz is channel -19). Of course, this 59 * XXX numbers (2312MHz is channel -19). Of course, this
60 * XXX doesn't matter because these channels are out of range 60 * XXX doesn't matter because these channels are out of the
61 * XXX but some regulation domains like MKK (Japan) will 61 * XXX legal range.
62 * XXX support frequencies somewhere around 4.8GHz.
63 */ 62 */
64 63
65 /* 64 /*
@@ -67,18 +66,14 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
67 */ 66 */
68 67
69 if (AR5K_EEPROM_HDR_11A(ee_header)) { 68 if (AR5K_EEPROM_HDR_11A(ee_header)) {
70 /* 4920 */ 69 if (ath_is_49ghz_allowed(caps->cap_eeprom.ee_regdomain))
71 ah->ah_capabilities.cap_range.range_5ghz_min = 5005; 70 caps->cap_range.range_5ghz_min = 4920;
72 ah->ah_capabilities.cap_range.range_5ghz_max = 6100; 71 else
72 caps->cap_range.range_5ghz_min = 5005;
73 caps->cap_range.range_5ghz_max = 6100;
73 74
74 /* Set supported modes */ 75 /* Set supported modes */
75 __set_bit(AR5K_MODE_11A, 76 __set_bit(AR5K_MODE_11A, caps->cap_mode);
76 ah->ah_capabilities.cap_mode);
77 __set_bit(AR5K_MODE_11A_TURBO,
78 ah->ah_capabilities.cap_mode);
79 if (ah->ah_version == AR5K_AR5212)
80 __set_bit(AR5K_MODE_11G_TURBO,
81 ah->ah_capabilities.cap_mode);
82 } 77 }
83 78
84 /* Enable 802.11b if a 2GHz capable radio (2111/5112) is 79 /* Enable 802.11b if a 2GHz capable radio (2111/5112) is
@@ -87,32 +82,32 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
87 (AR5K_EEPROM_HDR_11G(ee_header) && 82 (AR5K_EEPROM_HDR_11G(ee_header) &&
88 ah->ah_version != AR5K_AR5211)) { 83 ah->ah_version != AR5K_AR5211)) {
89 /* 2312 */ 84 /* 2312 */
90 ah->ah_capabilities.cap_range.range_2ghz_min = 2412; 85 caps->cap_range.range_2ghz_min = 2412;
91 ah->ah_capabilities.cap_range.range_2ghz_max = 2732; 86 caps->cap_range.range_2ghz_max = 2732;
92 87
93 if (AR5K_EEPROM_HDR_11B(ee_header)) 88 if (AR5K_EEPROM_HDR_11B(ee_header))
94 __set_bit(AR5K_MODE_11B, 89 __set_bit(AR5K_MODE_11B, caps->cap_mode);
95 ah->ah_capabilities.cap_mode);
96 90
97 if (AR5K_EEPROM_HDR_11G(ee_header) && 91 if (AR5K_EEPROM_HDR_11G(ee_header) &&
98 ah->ah_version != AR5K_AR5211) 92 ah->ah_version != AR5K_AR5211)
99 __set_bit(AR5K_MODE_11G, 93 __set_bit(AR5K_MODE_11G, caps->cap_mode);
100 ah->ah_capabilities.cap_mode);
101 } 94 }
102 } 95 }
103 96
97 if ((ah->ah_radio_5ghz_revision & 0xf0) == AR5K_SREV_RAD_2112)
98 __clear_bit(AR5K_MODE_11A, caps->cap_mode);
99
104 /* Set number of supported TX queues */ 100 /* Set number of supported TX queues */
105 if (ah->ah_version == AR5K_AR5210) 101 if (ah->ah_version == AR5K_AR5210)
106 ah->ah_capabilities.cap_queues.q_tx_num = 102 caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU;
107 AR5K_NUM_TX_QUEUES_NOQCU;
108 else 103 else
109 ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES; 104 caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
110 105
111 /* newer hardware has PHY error counters */ 106 /* newer hardware has PHY error counters */
112 if (ah->ah_mac_srev >= AR5K_SREV_AR5213A) 107 if (ah->ah_mac_srev >= AR5K_SREV_AR5213A)
113 ah->ah_capabilities.cap_has_phyerr_counters = true; 108 caps->cap_has_phyerr_counters = true;
114 else 109 else
115 ah->ah_capabilities.cap_has_phyerr_counters = false; 110 caps->cap_has_phyerr_counters = false;
116 111
117 return 0; 112 return 0;
118} 113}
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 4cccc29964f6..0bf7313b8a17 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -71,8 +71,6 @@ module_param_named(debug, ath5k_debug, uint, 0);
71#include "reg.h" 71#include "reg.h"
72#include "ani.h" 72#include "ani.h"
73 73
74static struct dentry *ath5k_global_debugfs;
75
76static int ath5k_debugfs_open(struct inode *inode, struct file *file) 74static int ath5k_debugfs_open(struct inode *inode, struct file *file)
77{ 75{
78 file->private_data = inode->i_private; 76 file->private_data = inode->i_private;
@@ -271,6 +269,7 @@ static const struct file_operations fops_beacon = {
271 .write = write_file_beacon, 269 .write = write_file_beacon,
272 .open = ath5k_debugfs_open, 270 .open = ath5k_debugfs_open,
273 .owner = THIS_MODULE, 271 .owner = THIS_MODULE,
272 .llseek = default_llseek,
274}; 273};
275 274
276 275
@@ -290,6 +289,7 @@ static const struct file_operations fops_reset = {
290 .write = write_file_reset, 289 .write = write_file_reset,
291 .open = ath5k_debugfs_open, 290 .open = ath5k_debugfs_open,
292 .owner = THIS_MODULE, 291 .owner = THIS_MODULE,
292 .llseek = noop_llseek,
293}; 293};
294 294
295 295
@@ -308,10 +308,10 @@ static const struct {
308 { ATH5K_DEBUG_CALIBRATE, "calib", "periodic calibration" }, 308 { ATH5K_DEBUG_CALIBRATE, "calib", "periodic calibration" },
309 { ATH5K_DEBUG_TXPOWER, "txpower", "transmit power setting" }, 309 { ATH5K_DEBUG_TXPOWER, "txpower", "transmit power setting" },
310 { ATH5K_DEBUG_LED, "led", "LED management" }, 310 { ATH5K_DEBUG_LED, "led", "LED management" },
311 { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" },
312 { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
313 { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, 311 { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" },
312 { ATH5K_DEBUG_DMA, "dma", "dma start/stop" },
314 { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, 313 { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" },
314 { ATH5K_DEBUG_DESC, "desc", "descriptor chains" },
315 { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, 315 { ATH5K_DEBUG_ANY, "all", "show all debug levels" },
316}; 316};
317 317
@@ -369,6 +369,7 @@ static const struct file_operations fops_debug = {
369 .write = write_file_debug, 369 .write = write_file_debug,
370 .open = ath5k_debugfs_open, 370 .open = ath5k_debugfs_open,
371 .owner = THIS_MODULE, 371 .owner = THIS_MODULE,
372 .llseek = default_llseek,
372}; 373};
373 374
374 375
@@ -480,6 +481,61 @@ static const struct file_operations fops_antenna = {
480 .write = write_file_antenna, 481 .write = write_file_antenna,
481 .open = ath5k_debugfs_open, 482 .open = ath5k_debugfs_open,
482 .owner = THIS_MODULE, 483 .owner = THIS_MODULE,
484 .llseek = default_llseek,
485};
486
487/* debugfs: misc */
488
489static ssize_t read_file_misc(struct file *file, char __user *user_buf,
490 size_t count, loff_t *ppos)
491{
492 struct ath5k_softc *sc = file->private_data;
493 char buf[700];
494 unsigned int len = 0;
495 u32 filt = ath5k_hw_get_rx_filter(sc->ah);
496
497 len += snprintf(buf+len, sizeof(buf)-len, "bssid-mask: %pM\n",
498 sc->bssidmask);
499 len += snprintf(buf+len, sizeof(buf)-len, "filter-flags: 0x%x ",
500 filt);
501 if (filt & AR5K_RX_FILTER_UCAST)
502 len += snprintf(buf+len, sizeof(buf)-len, " UCAST");
503 if (filt & AR5K_RX_FILTER_MCAST)
504 len += snprintf(buf+len, sizeof(buf)-len, " MCAST");
505 if (filt & AR5K_RX_FILTER_BCAST)
506 len += snprintf(buf+len, sizeof(buf)-len, " BCAST");
507 if (filt & AR5K_RX_FILTER_CONTROL)
508 len += snprintf(buf+len, sizeof(buf)-len, " CONTROL");
509 if (filt & AR5K_RX_FILTER_BEACON)
510 len += snprintf(buf+len, sizeof(buf)-len, " BEACON");
511 if (filt & AR5K_RX_FILTER_PROM)
512 len += snprintf(buf+len, sizeof(buf)-len, " PROM");
513 if (filt & AR5K_RX_FILTER_XRPOLL)
514 len += snprintf(buf+len, sizeof(buf)-len, " XRPOLL");
515 if (filt & AR5K_RX_FILTER_PROBEREQ)
516 len += snprintf(buf+len, sizeof(buf)-len, " PROBEREQ");
517 if (filt & AR5K_RX_FILTER_PHYERR_5212)
518 len += snprintf(buf+len, sizeof(buf)-len, " PHYERR-5212");
519 if (filt & AR5K_RX_FILTER_RADARERR_5212)
520 len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5212");
521 if (filt & AR5K_RX_FILTER_PHYERR_5211)
522 snprintf(buf+len, sizeof(buf)-len, " PHYERR-5211");
523 if (filt & AR5K_RX_FILTER_RADARERR_5211)
524 len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211");
525
526 len += snprintf(buf+len, sizeof(buf)-len, "\nopmode: %s (%d)\n",
527 ath_opmode_to_string(sc->opmode), sc->opmode);
528
529 if (len > sizeof(buf))
530 len = sizeof(buf);
531
532 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
533}
534
535static const struct file_operations fops_misc = {
536 .read = read_file_misc,
537 .open = ath5k_debugfs_open,
538 .owner = THIS_MODULE,
483}; 539};
484 540
485 541
@@ -496,60 +552,64 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
496 552
497 len += snprintf(buf+len, sizeof(buf)-len, 553 len += snprintf(buf+len, sizeof(buf)-len,
498 "RX\n---------------------\n"); 554 "RX\n---------------------\n");
499 len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%d\t(%d%%)\n", 555 len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%u\t(%u%%)\n",
500 st->rxerr_crc, 556 st->rxerr_crc,
501 st->rx_all_count > 0 ? 557 st->rx_all_count > 0 ?
502 st->rxerr_crc*100/st->rx_all_count : 0); 558 st->rxerr_crc*100/st->rx_all_count : 0);
503 len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%d\t(%d%%)\n", 559 len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%u\t(%u%%)\n",
504 st->rxerr_phy, 560 st->rxerr_phy,
505 st->rx_all_count > 0 ? 561 st->rx_all_count > 0 ?
506 st->rxerr_phy*100/st->rx_all_count : 0); 562 st->rxerr_phy*100/st->rx_all_count : 0);
507 for (i = 0; i < 32; i++) { 563 for (i = 0; i < 32; i++) {
508 if (st->rxerr_phy_code[i]) 564 if (st->rxerr_phy_code[i])
509 len += snprintf(buf+len, sizeof(buf)-len, 565 len += snprintf(buf+len, sizeof(buf)-len,
510 " phy_err[%d]\t%d\n", 566 " phy_err[%u]\t%u\n",
511 i, st->rxerr_phy_code[i]); 567 i, st->rxerr_phy_code[i]);
512 } 568 }
513 569
514 len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n", 570 len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%u\t(%u%%)\n",
515 st->rxerr_fifo, 571 st->rxerr_fifo,
516 st->rx_all_count > 0 ? 572 st->rx_all_count > 0 ?
517 st->rxerr_fifo*100/st->rx_all_count : 0); 573 st->rxerr_fifo*100/st->rx_all_count : 0);
518 len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%d\t(%d%%)\n", 574 len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%u\t(%u%%)\n",
519 st->rxerr_decrypt, 575 st->rxerr_decrypt,
520 st->rx_all_count > 0 ? 576 st->rx_all_count > 0 ?
521 st->rxerr_decrypt*100/st->rx_all_count : 0); 577 st->rxerr_decrypt*100/st->rx_all_count : 0);
522 len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%d\t(%d%%)\n", 578 len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%u\t(%u%%)\n",
523 st->rxerr_mic, 579 st->rxerr_mic,
524 st->rx_all_count > 0 ? 580 st->rx_all_count > 0 ?
525 st->rxerr_mic*100/st->rx_all_count : 0); 581 st->rxerr_mic*100/st->rx_all_count : 0);
526 len += snprintf(buf+len, sizeof(buf)-len, "process\t%d\t(%d%%)\n", 582 len += snprintf(buf+len, sizeof(buf)-len, "process\t%u\t(%u%%)\n",
527 st->rxerr_proc, 583 st->rxerr_proc,
528 st->rx_all_count > 0 ? 584 st->rx_all_count > 0 ?
529 st->rxerr_proc*100/st->rx_all_count : 0); 585 st->rxerr_proc*100/st->rx_all_count : 0);
530 len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%d\t(%d%%)\n", 586 len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%u\t(%u%%)\n",
531 st->rxerr_jumbo, 587 st->rxerr_jumbo,
532 st->rx_all_count > 0 ? 588 st->rx_all_count > 0 ?
533 st->rxerr_jumbo*100/st->rx_all_count : 0); 589 st->rxerr_jumbo*100/st->rx_all_count : 0);
534 len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n", 590 len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%u]\n",
535 st->rx_all_count); 591 st->rx_all_count);
592 len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%u\n",
593 st->rx_bytes_count);
536 594
537 len += snprintf(buf+len, sizeof(buf)-len, 595 len += snprintf(buf+len, sizeof(buf)-len,
538 "\nTX\n---------------------\n"); 596 "\nTX\n---------------------\n");
539 len += snprintf(buf+len, sizeof(buf)-len, "retry\t%d\t(%d%%)\n", 597 len += snprintf(buf+len, sizeof(buf)-len, "retry\t%u\t(%u%%)\n",
540 st->txerr_retry, 598 st->txerr_retry,
541 st->tx_all_count > 0 ? 599 st->tx_all_count > 0 ?
542 st->txerr_retry*100/st->tx_all_count : 0); 600 st->txerr_retry*100/st->tx_all_count : 0);
543 len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n", 601 len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%u\t(%u%%)\n",
544 st->txerr_fifo, 602 st->txerr_fifo,
545 st->tx_all_count > 0 ? 603 st->tx_all_count > 0 ?
546 st->txerr_fifo*100/st->tx_all_count : 0); 604 st->txerr_fifo*100/st->tx_all_count : 0);
547 len += snprintf(buf+len, sizeof(buf)-len, "filter\t%d\t(%d%%)\n", 605 len += snprintf(buf+len, sizeof(buf)-len, "filter\t%u\t(%u%%)\n",
548 st->txerr_filt, 606 st->txerr_filt,
549 st->tx_all_count > 0 ? 607 st->tx_all_count > 0 ?
550 st->txerr_filt*100/st->tx_all_count : 0); 608 st->txerr_filt*100/st->tx_all_count : 0);
551 len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n", 609 len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%u]\n",
552 st->tx_all_count); 610 st->tx_all_count);
611 len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%u\n",
612 st->tx_bytes_count);
553 613
554 if (len > sizeof(buf)) 614 if (len > sizeof(buf))
555 len = sizeof(buf); 615 len = sizeof(buf);
@@ -591,6 +651,7 @@ static const struct file_operations fops_frameerrors = {
591 .write = write_file_frameerrors, 651 .write = write_file_frameerrors,
592 .open = ath5k_debugfs_open, 652 .open = ath5k_debugfs_open,
593 .owner = THIS_MODULE, 653 .owner = THIS_MODULE,
654 .llseek = default_llseek,
594}; 655};
595 656
596 657
@@ -656,21 +717,22 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
656 st->mib_intr); 717 st->mib_intr);
657 len += snprintf(buf+len, sizeof(buf)-len, 718 len += snprintf(buf+len, sizeof(buf)-len,
658 "beacon RSSI average:\t%d\n", 719 "beacon RSSI average:\t%d\n",
659 sc->ah->ah_beacon_rssi_avg.avg); 720 (int)ewma_read(&sc->ah->ah_beacon_rssi_avg));
721
722#define CC_PRINT(_struct, _field) \
723 _struct._field, \
724 _struct.cycles > 0 ? \
725 _struct._field*100/_struct.cycles : 0
726
660 len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n", 727 len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n",
661 as->pfc_tx, 728 CC_PRINT(as->last_cc, tx_frame));
662 as->pfc_cycles > 0 ?
663 as->pfc_tx*100/as->pfc_cycles : 0);
664 len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n", 729 len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n",
665 as->pfc_rx, 730 CC_PRINT(as->last_cc, rx_frame));
666 as->pfc_cycles > 0 ?
667 as->pfc_rx*100/as->pfc_cycles : 0);
668 len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n", 731 len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n",
669 as->pfc_busy, 732 CC_PRINT(as->last_cc, rx_busy));
670 as->pfc_cycles > 0 ? 733#undef CC_PRINT
671 as->pfc_busy*100/as->pfc_cycles : 0);
672 len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n", 734 len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n",
673 as->pfc_cycles); 735 as->last_cc.cycles);
674 len += snprintf(buf+len, sizeof(buf)-len, 736 len += snprintf(buf+len, sizeof(buf)-len,
675 "listen time\t\t%d\tlast: %d\n", 737 "listen time\t\t%d\tlast: %d\n",
676 as->listen_time, as->last_listen); 738 as->listen_time, as->last_listen);
@@ -748,6 +810,7 @@ static const struct file_operations fops_ani = {
748 .write = write_file_ani, 810 .write = write_file_ani,
749 .open = ath5k_debugfs_open, 811 .open = ath5k_debugfs_open,
750 .owner = THIS_MODULE, 812 .owner = THIS_MODULE,
813 .llseek = default_llseek,
751}; 814};
752 815
753 816
@@ -762,7 +825,7 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf,
762 825
763 struct ath5k_txq *txq; 826 struct ath5k_txq *txq;
764 struct ath5k_buf *bf, *bf0; 827 struct ath5k_buf *bf, *bf0;
765 int i, n = 0; 828 int i, n;
766 829
767 len += snprintf(buf+len, sizeof(buf)-len, 830 len += snprintf(buf+len, sizeof(buf)-len,
768 "available txbuffers: %d\n", sc->txbuf_len); 831 "available txbuffers: %d\n", sc->txbuf_len);
@@ -776,9 +839,16 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf,
776 if (!txq->setup) 839 if (!txq->setup)
777 continue; 840 continue;
778 841
842 n = 0;
843 spin_lock_bh(&txq->lock);
779 list_for_each_entry_safe(bf, bf0, &txq->q, list) 844 list_for_each_entry_safe(bf, bf0, &txq->q, list)
780 n++; 845 n++;
781 len += snprintf(buf+len, sizeof(buf)-len, " len: %d\n", n); 846 spin_unlock_bh(&txq->lock);
847
848 len += snprintf(buf+len, sizeof(buf)-len,
849 " len: %d bufs: %d\n", txq->txq_len, n);
850 len += snprintf(buf+len, sizeof(buf)-len,
851 " stuck: %d\n", txq->txq_stuck);
782 } 852 }
783 853
784 if (len > sizeof(buf)) 854 if (len > sizeof(buf))
@@ -811,80 +881,45 @@ static const struct file_operations fops_queue = {
811 .write = write_file_queue, 881 .write = write_file_queue,
812 .open = ath5k_debugfs_open, 882 .open = ath5k_debugfs_open,
813 .owner = THIS_MODULE, 883 .owner = THIS_MODULE,
884 .llseek = default_llseek,
814}; 885};
815 886
816 887
817/* init */
818
819void
820ath5k_debug_init(void)
821{
822 ath5k_global_debugfs = debugfs_create_dir("ath5k", NULL);
823}
824
825void 888void
826ath5k_debug_init_device(struct ath5k_softc *sc) 889ath5k_debug_init_device(struct ath5k_softc *sc)
827{ 890{
891 struct dentry *phydir;
892
828 sc->debug.level = ath5k_debug; 893 sc->debug.level = ath5k_debug;
829 894
830 sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy), 895 phydir = debugfs_create_dir("ath5k", sc->hw->wiphy->debugfsdir);
831 ath5k_global_debugfs); 896 if (!phydir)
897 return;
832 898
833 sc->debug.debugfs_debug = debugfs_create_file("debug", 899 debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, sc,
834 S_IWUSR | S_IRUSR, 900 &fops_debug);
835 sc->debug.debugfs_phydir, sc, &fops_debug);
836 901
837 sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUSR, 902 debugfs_create_file("registers", S_IRUSR, phydir, sc, &fops_registers);
838 sc->debug.debugfs_phydir, sc, &fops_registers);
839 903
840 sc->debug.debugfs_beacon = debugfs_create_file("beacon", 904 debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, sc,
841 S_IWUSR | S_IRUSR, 905 &fops_beacon);
842 sc->debug.debugfs_phydir, sc, &fops_beacon);
843 906
844 sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, 907 debugfs_create_file("reset", S_IWUSR, phydir, sc, &fops_reset);
845 sc->debug.debugfs_phydir, sc, &fops_reset);
846 908
847 sc->debug.debugfs_antenna = debugfs_create_file("antenna", 909 debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, sc,
848 S_IWUSR | S_IRUSR, 910 &fops_antenna);
849 sc->debug.debugfs_phydir, sc, &fops_antenna);
850 911
851 sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors", 912 debugfs_create_file("misc", S_IRUSR, phydir, sc, &fops_misc);
852 S_IWUSR | S_IRUSR,
853 sc->debug.debugfs_phydir, sc,
854 &fops_frameerrors);
855 913
856 sc->debug.debugfs_ani = debugfs_create_file("ani", 914 debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, sc,
857 S_IWUSR | S_IRUSR, 915 &fops_frameerrors);
858 sc->debug.debugfs_phydir, sc,
859 &fops_ani);
860 916
861 sc->debug.debugfs_queue = debugfs_create_file("queue", 917 debugfs_create_file("ani", S_IWUSR | S_IRUSR, phydir, sc, &fops_ani);
862 S_IWUSR | S_IRUSR,
863 sc->debug.debugfs_phydir, sc,
864 &fops_queue);
865}
866 918
867void 919 debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, sc,
868ath5k_debug_finish(void) 920 &fops_queue);
869{
870 debugfs_remove(ath5k_global_debugfs);
871} 921}
872 922
873void
874ath5k_debug_finish_device(struct ath5k_softc *sc)
875{
876 debugfs_remove(sc->debug.debugfs_debug);
877 debugfs_remove(sc->debug.debugfs_registers);
878 debugfs_remove(sc->debug.debugfs_beacon);
879 debugfs_remove(sc->debug.debugfs_reset);
880 debugfs_remove(sc->debug.debugfs_antenna);
881 debugfs_remove(sc->debug.debugfs_frameerrors);
882 debugfs_remove(sc->debug.debugfs_ani);
883 debugfs_remove(sc->debug.debugfs_queue);
884 debugfs_remove(sc->debug.debugfs_phydir);
885}
886
887
888/* functions used in other places */ 923/* functions used in other places */
889 924
890void 925void
@@ -955,7 +990,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
955 struct ath5k_rx_status rs = {}; 990 struct ath5k_rx_status rs = {};
956 int status; 991 int status;
957 992
958 if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) 993 if (likely(!(sc->debug.level & ATH5K_DEBUG_DESC)))
959 return; 994 return;
960 995
961 printk(KERN_DEBUG "rxdp %x, rxlink %p\n", 996 printk(KERN_DEBUG "rxdp %x, rxlink %p\n",
@@ -972,24 +1007,6 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
972} 1007}
973 1008
974void 1009void
975ath5k_debug_dump_skb(struct ath5k_softc *sc,
976 struct sk_buff *skb, const char *prefix, int tx)
977{
978 char buf[16];
979
980 if (likely(!((tx && (sc->debug.level & ATH5K_DEBUG_DUMP_TX)) ||
981 (!tx && (sc->debug.level & ATH5K_DEBUG_DUMP_RX)))))
982 return;
983
984 snprintf(buf, sizeof(buf), "%s %s", wiphy_name(sc->hw->wiphy), prefix);
985
986 print_hex_dump_bytes(buf, DUMP_PREFIX_NONE, skb->data,
987 min(200U, skb->len));
988
989 printk(KERN_DEBUG "\n");
990}
991
992void
993ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) 1010ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf)
994{ 1011{
995 struct ath5k_desc *ds = bf->desc; 1012 struct ath5k_desc *ds = bf->desc;
@@ -997,7 +1014,7 @@ ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf)
997 struct ath5k_tx_status ts = {}; 1014 struct ath5k_tx_status ts = {};
998 int done; 1015 int done;
999 1016
1000 if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) 1017 if (likely(!(sc->debug.level & ATH5K_DEBUG_DESC)))
1001 return; 1018 return;
1002 1019
1003 done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts); 1020 done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts);
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index 606ae94a9157..193dd2d4ea3c 100644
--- a/drivers/net/wireless/ath/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
@@ -68,16 +68,6 @@ struct ath5k_buf;
68 68
69struct ath5k_dbg_info { 69struct ath5k_dbg_info {
70 unsigned int level; /* debug level */ 70 unsigned int level; /* debug level */
71 /* debugfs entries */
72 struct dentry *debugfs_phydir;
73 struct dentry *debugfs_debug;
74 struct dentry *debugfs_registers;
75 struct dentry *debugfs_beacon;
76 struct dentry *debugfs_reset;
77 struct dentry *debugfs_antenna;
78 struct dentry *debugfs_frameerrors;
79 struct dentry *debugfs_ani;
80 struct dentry *debugfs_queue;
81}; 71};
82 72
83/** 73/**
@@ -94,7 +84,9 @@ struct ath5k_dbg_info {
94 * @ATH5K_DEBUG_DUMP_RX: print received skb content 84 * @ATH5K_DEBUG_DUMP_RX: print received skb content
95 * @ATH5K_DEBUG_DUMP_TX: print transmit skb content 85 * @ATH5K_DEBUG_DUMP_TX: print transmit skb content
96 * @ATH5K_DEBUG_DUMPBANDS: dump bands 86 * @ATH5K_DEBUG_DUMPBANDS: dump bands
87 * @ATH5K_DEBUG_DMA: debug dma start/stop
97 * @ATH5K_DEBUG_TRACE: trace function calls 88 * @ATH5K_DEBUG_TRACE: trace function calls
89 * @ATH5K_DEBUG_DESC: descriptor setup
98 * @ATH5K_DEBUG_ANY: show at any debug level 90 * @ATH5K_DEBUG_ANY: show at any debug level
99 * 91 *
100 * The debug level is used to control the amount and type of debugging output 92 * The debug level is used to control the amount and type of debugging output
@@ -113,10 +105,10 @@ enum ath5k_debug_level {
113 ATH5K_DEBUG_CALIBRATE = 0x00000020, 105 ATH5K_DEBUG_CALIBRATE = 0x00000020,
114 ATH5K_DEBUG_TXPOWER = 0x00000040, 106 ATH5K_DEBUG_TXPOWER = 0x00000040,
115 ATH5K_DEBUG_LED = 0x00000080, 107 ATH5K_DEBUG_LED = 0x00000080,
116 ATH5K_DEBUG_DUMP_RX = 0x00000100,
117 ATH5K_DEBUG_DUMP_TX = 0x00000200,
118 ATH5K_DEBUG_DUMPBANDS = 0x00000400, 108 ATH5K_DEBUG_DUMPBANDS = 0x00000400,
109 ATH5K_DEBUG_DMA = 0x00000800,
119 ATH5K_DEBUG_ANI = 0x00002000, 110 ATH5K_DEBUG_ANI = 0x00002000,
111 ATH5K_DEBUG_DESC = 0x00004000,
120 ATH5K_DEBUG_ANY = 0xffffffff 112 ATH5K_DEBUG_ANY = 0xffffffff
121}; 113};
122 114
@@ -135,28 +127,15 @@ enum ath5k_debug_level {
135 } while (0) 127 } while (0)
136 128
137void 129void
138ath5k_debug_init(void);
139
140void
141ath5k_debug_init_device(struct ath5k_softc *sc); 130ath5k_debug_init_device(struct ath5k_softc *sc);
142 131
143void 132void
144ath5k_debug_finish(void);
145
146void
147ath5k_debug_finish_device(struct ath5k_softc *sc);
148
149void
150ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); 133ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah);
151 134
152void 135void
153ath5k_debug_dump_bands(struct ath5k_softc *sc); 136ath5k_debug_dump_bands(struct ath5k_softc *sc);
154 137
155void 138void
156ath5k_debug_dump_skb(struct ath5k_softc *sc,
157 struct sk_buff *skb, const char *prefix, int tx);
158
159void
160ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf); 139ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf);
161 140
162#else /* no debugging */ 141#else /* no debugging */
@@ -171,28 +150,15 @@ ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...)
171{} 150{}
172 151
173static inline void 152static inline void
174ath5k_debug_init(void) {}
175
176static inline void
177ath5k_debug_init_device(struct ath5k_softc *sc) {} 153ath5k_debug_init_device(struct ath5k_softc *sc) {}
178 154
179static inline void 155static inline void
180ath5k_debug_finish(void) {}
181
182static inline void
183ath5k_debug_finish_device(struct ath5k_softc *sc) {}
184
185static inline void
186ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} 156ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {}
187 157
188static inline void 158static inline void
189ath5k_debug_dump_bands(struct ath5k_softc *sc) {} 159ath5k_debug_dump_bands(struct ath5k_softc *sc) {}
190 160
191static inline void 161static inline void
192ath5k_debug_dump_skb(struct ath5k_softc *sc,
193 struct sk_buff *skb, const char *prefix, int tx) {}
194
195static inline void
196ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) {} 162ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) {}
197 163
198#endif /* ifdef CONFIG_ATH5K_DEBUG */ 164#endif /* ifdef CONFIG_ATH5K_DEBUG */
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c
index 43244382f213..f82383b3ed30 100644
--- a/drivers/net/wireless/ath/ath5k/desc.c
+++ b/drivers/net/wireless/ath/ath5k/desc.c
@@ -26,9 +26,10 @@
26#include "debug.h" 26#include "debug.h"
27#include "base.h" 27#include "base.h"
28 28
29/* 29
30 * TX Descriptors 30/************************\
31 */ 31* TX Control descriptors *
32\************************/
32 33
33/* 34/*
34 * Initialize the 2-word tx control descriptor on 5210/5211 35 * Initialize the 2-word tx control descriptor on 5210/5211
@@ -50,7 +51,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
50 /* 51 /*
51 * Validate input 52 * Validate input
52 * - Zero retries don't make sense. 53 * - Zero retries don't make sense.
53 * - A zero rate will put the HW into a mode where it continously sends 54 * - A zero rate will put the HW into a mode where it continuously sends
54 * noise on the channel, so it is important to avoid this. 55 * noise on the channel, so it is important to avoid this.
55 */ 56 */
56 if (unlikely(tx_tries0 == 0)) { 57 if (unlikely(tx_tries0 == 0)) {
@@ -106,10 +107,13 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
106 case AR5K_PKT_TYPE_BEACON: 107 case AR5K_PKT_TYPE_BEACON:
107 case AR5K_PKT_TYPE_PROBE_RESP: 108 case AR5K_PKT_TYPE_PROBE_RESP:
108 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY; 109 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
110 break;
109 case AR5K_PKT_TYPE_PIFS: 111 case AR5K_PKT_TYPE_PIFS:
110 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; 112 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
113 break;
111 default: 114 default:
112 frame_type = type; 115 frame_type = type;
116 break;
113 } 117 }
114 118
115 tx_ctl->tx_control_0 |= 119 tx_ctl->tx_control_0 |=
@@ -184,12 +188,18 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
184 struct ath5k_hw_4w_tx_ctl *tx_ctl; 188 struct ath5k_hw_4w_tx_ctl *tx_ctl;
185 unsigned int frame_len; 189 unsigned int frame_len;
186 190
191 /*
192 * Use local variables for these to reduce load/store access on
193 * uncached memory
194 */
195 u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0;
196
187 tx_ctl = &desc->ud.ds_tx5212.tx_ctl; 197 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
188 198
189 /* 199 /*
190 * Validate input 200 * Validate input
191 * - Zero retries don't make sense. 201 * - Zero retries don't make sense.
192 * - A zero rate will put the HW into a mode where it continously sends 202 * - A zero rate will put the HW into a mode where it continuously sends
193 * noise on the channel, so it is important to avoid this. 203 * noise on the channel, so it is important to avoid this.
194 */ 204 */
195 if (unlikely(tx_tries0 == 0)) { 205 if (unlikely(tx_tries0 == 0)) {
@@ -207,8 +217,9 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
207 if (tx_power > AR5K_TUNE_MAX_TXPOWER) 217 if (tx_power > AR5K_TUNE_MAX_TXPOWER)
208 tx_power = AR5K_TUNE_MAX_TXPOWER; 218 tx_power = AR5K_TUNE_MAX_TXPOWER;
209 219
210 /* Clear descriptor */ 220 /* Clear descriptor status area */
211 memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc)); 221 memset(&desc->ud.ds_tx5212.tx_stat, 0,
222 sizeof(desc->ud.ds_tx5212.tx_stat));
212 223
213 /* Setup control descriptor */ 224 /* Setup control descriptor */
214 225
@@ -220,7 +231,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
220 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) 231 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
221 return -EINVAL; 232 return -EINVAL;
222 233
223 tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; 234 txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
224 235
225 /* Verify and set buffer length */ 236 /* Verify and set buffer length */
226 237
@@ -231,21 +242,17 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
231 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) 242 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
232 return -EINVAL; 243 return -EINVAL;
233 244
234 tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; 245 txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
235 246
236 tx_ctl->tx_control_0 |= 247 txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
237 AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | 248 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
238 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); 249 txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
239 tx_ctl->tx_control_1 |= AR5K_REG_SM(type, 250 txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
240 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); 251 txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
241 tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0,
242 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
243 tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
244 252
245#define _TX_FLAGS(_c, _flag) \ 253#define _TX_FLAGS(_c, _flag) \
246 if (flags & AR5K_TXDESC_##_flag) { \ 254 if (flags & AR5K_TXDESC_##_flag) { \
247 tx_ctl->tx_control_##_c |= \ 255 txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag; \
248 AR5K_4W_TX_DESC_CTL##_c##_##_flag; \
249 } 256 }
250 257
251 _TX_FLAGS(0, CLRDMASK); 258 _TX_FLAGS(0, CLRDMASK);
@@ -261,8 +268,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
261 * WEP crap 268 * WEP crap
262 */ 269 */
263 if (key_index != AR5K_TXKEYIX_INVALID) { 270 if (key_index != AR5K_TXKEYIX_INVALID) {
264 tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; 271 txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
265 tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, 272 txctl1 |= AR5K_REG_SM(key_index,
266 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); 273 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX);
267 } 274 }
268 275
@@ -273,12 +280,16 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
273 if ((flags & AR5K_TXDESC_RTSENA) && 280 if ((flags & AR5K_TXDESC_RTSENA) &&
274 (flags & AR5K_TXDESC_CTSENA)) 281 (flags & AR5K_TXDESC_CTSENA))
275 return -EINVAL; 282 return -EINVAL;
276 tx_ctl->tx_control_2 |= rtscts_duration & 283 txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
277 AR5K_4W_TX_DESC_CTL2_RTS_DURATION; 284 txctl3 |= AR5K_REG_SM(rtscts_rate,
278 tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
279 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); 285 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
280 } 286 }
281 287
288 tx_ctl->tx_control_0 = txctl0;
289 tx_ctl->tx_control_1 = txctl1;
290 tx_ctl->tx_control_2 = txctl2;
291 tx_ctl->tx_control_3 = txctl3;
292
282 return 0; 293 return 0;
283} 294}
284 295
@@ -299,7 +310,7 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
299 /* 310 /*
300 * Rates can be 0 as long as the retry count is 0 too. 311 * Rates can be 0 as long as the retry count is 0 too.
301 * A zero rate and nonzero retry count will put the HW into a mode where 312 * A zero rate and nonzero retry count will put the HW into a mode where
302 * it continously sends noise on the channel, so it is important to 313 * it continuously sends noise on the channel, so it is important to
303 * avoid this. 314 * avoid this.
304 */ 315 */
305 if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) || 316 if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
@@ -335,8 +346,13 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
335 return 0; 346 return 0;
336} 347}
337 348
349
350/***********************\
351* TX Status descriptors *
352\***********************/
353
338/* 354/*
339 * Proccess the tx status descriptor on 5210/5211 355 * Process the tx status descriptor on 5210/5211
340 */ 356 */
341static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, 357static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
342 struct ath5k_desc *desc, struct ath5k_tx_status *ts) 358 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
@@ -358,7 +374,7 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
358 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); 374 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
359 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, 375 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
360 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); 376 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
361 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, 377 ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0,
362 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); 378 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
363 /*TODO: ts->ts_virtcol + test*/ 379 /*TODO: ts->ts_virtcol + test*/
364 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, 380 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
@@ -367,9 +383,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
367 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); 383 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
368 ts->ts_antenna = 1; 384 ts->ts_antenna = 1;
369 ts->ts_status = 0; 385 ts->ts_status = 0;
370 ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0,
371 AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
372 ts->ts_retry[0] = ts->ts_longretry;
373 ts->ts_final_idx = 0; 386 ts->ts_final_idx = 0;
374 387
375 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { 388 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
@@ -388,97 +401,65 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
388} 401}
389 402
390/* 403/*
391 * Proccess a tx status descriptor on 5212 404 * Process a tx status descriptor on 5212
392 */ 405 */
393static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, 406static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
394 struct ath5k_desc *desc, struct ath5k_tx_status *ts) 407 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
395{ 408{
396 struct ath5k_hw_4w_tx_ctl *tx_ctl; 409 struct ath5k_hw_4w_tx_ctl *tx_ctl;
397 struct ath5k_hw_tx_status *tx_status; 410 struct ath5k_hw_tx_status *tx_status;
411 u32 txstat0, txstat1;
398 412
399 tx_ctl = &desc->ud.ds_tx5212.tx_ctl; 413 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
400 tx_status = &desc->ud.ds_tx5212.tx_stat; 414 tx_status = &desc->ud.ds_tx5212.tx_stat;
401 415
416 txstat1 = ACCESS_ONCE(tx_status->tx_status_1);
417
402 /* No frame has been send or error */ 418 /* No frame has been send or error */
403 if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE))) 419 if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE)))
404 return -EINPROGRESS; 420 return -EINPROGRESS;
405 421
422 txstat0 = ACCESS_ONCE(tx_status->tx_status_0);
423
406 /* 424 /*
407 * Get descriptor status 425 * Get descriptor status
408 */ 426 */
409 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, 427 ts->ts_tstamp = AR5K_REG_MS(txstat0,
410 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); 428 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
411 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, 429 ts->ts_shortretry = AR5K_REG_MS(txstat0,
412 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); 430 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
413 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, 431 ts->ts_final_retry = AR5K_REG_MS(txstat0,
414 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); 432 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
415 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, 433 ts->ts_seqnum = AR5K_REG_MS(txstat1,
416 AR5K_DESC_TX_STATUS1_SEQ_NUM); 434 AR5K_DESC_TX_STATUS1_SEQ_NUM);
417 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, 435 ts->ts_rssi = AR5K_REG_MS(txstat1,
418 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); 436 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
419 ts->ts_antenna = (tx_status->tx_status_1 & 437 ts->ts_antenna = (txstat1 &
420 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; 438 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1;
421 ts->ts_status = 0; 439 ts->ts_status = 0;
422 440
423 ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, 441 ts->ts_final_idx = AR5K_REG_MS(txstat1,
424 AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); 442 AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212);
425 443
426 /* The longretry counter has the number of un-acked retries
427 * for the final rate. To get the total number of retries
428 * we have to add the retry counters for the other rates
429 * as well
430 */
431 ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry;
432 switch (ts->ts_final_idx) {
433 case 3:
434 ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3,
435 AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
436
437 ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2,
438 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
439 ts->ts_longretry += ts->ts_retry[2];
440 /* fall through */
441 case 2:
442 ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3,
443 AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
444
445 ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2,
446 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
447 ts->ts_longretry += ts->ts_retry[1];
448 /* fall through */
449 case 1:
450 ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3,
451 AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
452
453 ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2,
454 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
455 ts->ts_longretry += ts->ts_retry[0];
456 /* fall through */
457 case 0:
458 ts->ts_rate[0] = tx_ctl->tx_control_3 &
459 AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
460 break;
461 }
462
463 /* TX error */ 444 /* TX error */
464 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { 445 if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
465 if (tx_status->tx_status_0 & 446 if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
466 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
467 ts->ts_status |= AR5K_TXERR_XRETRY; 447 ts->ts_status |= AR5K_TXERR_XRETRY;
468 448
469 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) 449 if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
470 ts->ts_status |= AR5K_TXERR_FIFO; 450 ts->ts_status |= AR5K_TXERR_FIFO;
471 451
472 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) 452 if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED)
473 ts->ts_status |= AR5K_TXERR_FILT; 453 ts->ts_status |= AR5K_TXERR_FILT;
474 } 454 }
475 455
476 return 0; 456 return 0;
477} 457}
478 458
479/* 459
480 * RX Descriptors 460/****************\
481 */ 461* RX Descriptors *
462\****************/
482 463
483/* 464/*
484 * Initialize an rx control descriptor 465 * Initialize an rx control descriptor
@@ -512,7 +493,7 @@ int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
512} 493}
513 494
514/* 495/*
515 * Proccess the rx status descriptor on 5210/5211 496 * Process the rx status descriptor on 5210/5211
516 */ 497 */
517static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, 498static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
518 struct ath5k_desc *desc, struct ath5k_rx_status *rs) 499 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
@@ -595,44 +576,44 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
595} 576}
596 577
597/* 578/*
598 * Proccess the rx status descriptor on 5212 579 * Process the rx status descriptor on 5212
599 */ 580 */
600static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, 581static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
601 struct ath5k_desc *desc, 582 struct ath5k_desc *desc,
602 struct ath5k_rx_status *rs) 583 struct ath5k_rx_status *rs)
603{ 584{
604 struct ath5k_hw_rx_status *rx_status; 585 struct ath5k_hw_rx_status *rx_status;
586 u32 rxstat0, rxstat1;
605 587
606 rx_status = &desc->ud.ds_rx.rx_stat; 588 rx_status = &desc->ud.ds_rx.rx_stat;
589 rxstat1 = ACCESS_ONCE(rx_status->rx_status_1);
607 590
608 /* No frame received / not ready */ 591 /* No frame received / not ready */
609 if (unlikely(!(rx_status->rx_status_1 & 592 if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE)))
610 AR5K_5212_RX_DESC_STATUS1_DONE)))
611 return -EINPROGRESS; 593 return -EINPROGRESS;
612 594
613 memset(rs, 0, sizeof(struct ath5k_rx_status)); 595 memset(rs, 0, sizeof(struct ath5k_rx_status));
596 rxstat0 = ACCESS_ONCE(rx_status->rx_status_0);
614 597
615 /* 598 /*
616 * Frame receive status 599 * Frame receive status
617 */ 600 */
618 rs->rs_datalen = rx_status->rx_status_0 & 601 rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
619 AR5K_5212_RX_DESC_STATUS0_DATA_LEN; 602 rs->rs_rssi = AR5K_REG_MS(rxstat0,
620 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
621 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); 603 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
622 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, 604 rs->rs_rate = AR5K_REG_MS(rxstat0,
623 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); 605 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
624 rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, 606 rs->rs_antenna = AR5K_REG_MS(rxstat0,
625 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); 607 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA);
626 rs->rs_more = !!(rx_status->rx_status_0 & 608 rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE);
627 AR5K_5212_RX_DESC_STATUS0_MORE); 609 rs->rs_tstamp = AR5K_REG_MS(rxstat1,
628 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
629 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); 610 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
630 611
631 /* 612 /*
632 * Key table status 613 * Key table status
633 */ 614 */
634 if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) 615 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
635 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, 616 rs->rs_keyix = AR5K_REG_MS(rxstat1,
636 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); 617 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
637 else 618 else
638 rs->rs_keyix = AR5K_RXKEYIX_INVALID; 619 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
@@ -640,32 +621,32 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
640 /* 621 /*
641 * Receive/descriptor errors 622 * Receive/descriptor errors
642 */ 623 */
643 if (!(rx_status->rx_status_1 & 624 if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
644 AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { 625 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
645 if (rx_status->rx_status_1 &
646 AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
647 rs->rs_status |= AR5K_RXERR_CRC; 626 rs->rs_status |= AR5K_RXERR_CRC;
648 627
649 if (rx_status->rx_status_1 & 628 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
650 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
651 rs->rs_status |= AR5K_RXERR_PHY; 629 rs->rs_status |= AR5K_RXERR_PHY;
652 rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, 630 rs->rs_phyerr = AR5K_REG_MS(rxstat1,
653 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); 631 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE);
654 if (!ah->ah_capabilities.cap_has_phyerr_counters) 632 if (!ah->ah_capabilities.cap_has_phyerr_counters)
655 ath5k_ani_phy_error_report(ah, rs->rs_phyerr); 633 ath5k_ani_phy_error_report(ah, rs->rs_phyerr);
656 } 634 }
657 635
658 if (rx_status->rx_status_1 & 636 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
659 AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
660 rs->rs_status |= AR5K_RXERR_DECRYPT; 637 rs->rs_status |= AR5K_RXERR_DECRYPT;
661 638
662 if (rx_status->rx_status_1 & 639 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
663 AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
664 rs->rs_status |= AR5K_RXERR_MIC; 640 rs->rs_status |= AR5K_RXERR_MIC;
665 } 641 }
666 return 0; 642 return 0;
667} 643}
668 644
645
646/********\
647* Attach *
648\********/
649
669/* 650/*
670 * Init function pointers inside ath5k_hw struct 651 * Init function pointers inside ath5k_hw struct
671 */ 652 */
diff --git a/drivers/net/wireless/ath/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h
index b2adb2a281c2..2509d0bf037d 100644
--- a/drivers/net/wireless/ath/ath5k/desc.h
+++ b/drivers/net/wireless/ath/ath5k/desc.h
@@ -26,7 +26,7 @@
26struct ath5k_hw_rx_ctl { 26struct ath5k_hw_rx_ctl {
27 u32 rx_control_0; /* RX control word 0 */ 27 u32 rx_control_0; /* RX control word 0 */
28 u32 rx_control_1; /* RX control word 1 */ 28 u32 rx_control_1; /* RX control word 1 */
29} __packed; 29} __packed __aligned(4);
30 30
31/* RX control word 1 fields/flags */ 31/* RX control word 1 fields/flags */
32#define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff /* data buffer length */ 32#define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff /* data buffer length */
@@ -39,7 +39,7 @@ struct ath5k_hw_rx_ctl {
39struct ath5k_hw_rx_status { 39struct ath5k_hw_rx_status {
40 u32 rx_status_0; /* RX status word 0 */ 40 u32 rx_status_0; /* RX status word 0 */
41 u32 rx_status_1; /* RX status word 1 */ 41 u32 rx_status_1; /* RX status word 1 */
42} __packed; 42} __packed __aligned(4);
43 43
44/* 5210/5211 */ 44/* 5210/5211 */
45/* RX status word 0 fields/flags */ 45/* RX status word 0 fields/flags */
@@ -129,7 +129,7 @@ enum ath5k_phy_error_code {
129struct ath5k_hw_2w_tx_ctl { 129struct ath5k_hw_2w_tx_ctl {
130 u32 tx_control_0; /* TX control word 0 */ 130 u32 tx_control_0; /* TX control word 0 */
131 u32 tx_control_1; /* TX control word 1 */ 131 u32 tx_control_1; /* TX control word 1 */
132} __packed; 132} __packed __aligned(4);
133 133
134/* TX control word 0 fields/flags */ 134/* TX control word 0 fields/flags */
135#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */ 135#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */
@@ -185,7 +185,7 @@ struct ath5k_hw_4w_tx_ctl {
185 u32 tx_control_1; /* TX control word 1 */ 185 u32 tx_control_1; /* TX control word 1 */
186 u32 tx_control_2; /* TX control word 2 */ 186 u32 tx_control_2; /* TX control word 2 */
187 u32 tx_control_3; /* TX control word 3 */ 187 u32 tx_control_3; /* TX control word 3 */
188} __packed; 188} __packed __aligned(4);
189 189
190/* TX control word 0 fields/flags */ 190/* TX control word 0 fields/flags */
191#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */ 191#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */
@@ -244,7 +244,7 @@ struct ath5k_hw_4w_tx_ctl {
244struct ath5k_hw_tx_status { 244struct ath5k_hw_tx_status {
245 u32 tx_status_0; /* TX status word 0 */ 245 u32 tx_status_0; /* TX status word 0 */
246 u32 tx_status_1; /* TX status word 1 */ 246 u32 tx_status_1; /* TX status word 1 */
247} __packed; 247} __packed __aligned(4);
248 248
249/* TX status word 0 fields/flags */ 249/* TX status word 0 fields/flags */
250#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 /* TX success */ 250#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 /* TX success */
@@ -282,7 +282,7 @@ struct ath5k_hw_tx_status {
282struct ath5k_hw_5210_tx_desc { 282struct ath5k_hw_5210_tx_desc {
283 struct ath5k_hw_2w_tx_ctl tx_ctl; 283 struct ath5k_hw_2w_tx_ctl tx_ctl;
284 struct ath5k_hw_tx_status tx_stat; 284 struct ath5k_hw_tx_status tx_stat;
285} __packed; 285} __packed __aligned(4);
286 286
287/* 287/*
288 * 5212 hardware TX descriptor 288 * 5212 hardware TX descriptor
@@ -290,7 +290,7 @@ struct ath5k_hw_5210_tx_desc {
290struct ath5k_hw_5212_tx_desc { 290struct ath5k_hw_5212_tx_desc {
291 struct ath5k_hw_4w_tx_ctl tx_ctl; 291 struct ath5k_hw_4w_tx_ctl tx_ctl;
292 struct ath5k_hw_tx_status tx_stat; 292 struct ath5k_hw_tx_status tx_stat;
293} __packed; 293} __packed __aligned(4);
294 294
295/* 295/*
296 * Common hardware RX descriptor 296 * Common hardware RX descriptor
@@ -298,7 +298,7 @@ struct ath5k_hw_5212_tx_desc {
298struct ath5k_hw_all_rx_desc { 298struct ath5k_hw_all_rx_desc {
299 struct ath5k_hw_rx_ctl rx_ctl; 299 struct ath5k_hw_rx_ctl rx_ctl;
300 struct ath5k_hw_rx_status rx_stat; 300 struct ath5k_hw_rx_status rx_stat;
301} __packed; 301} __packed __aligned(4);
302 302
303/* 303/*
304 * Atheros hardware DMA descriptor 304 * Atheros hardware DMA descriptor
@@ -313,7 +313,7 @@ struct ath5k_desc {
313 struct ath5k_hw_5212_tx_desc ds_tx5212; 313 struct ath5k_hw_5212_tx_desc ds_tx5212;
314 struct ath5k_hw_all_rx_desc ds_rx; 314 struct ath5k_hw_all_rx_desc ds_rx;
315 } ud; 315 } ud;
316} __packed; 316} __packed __aligned(4);
317 317
318#define AR5K_RXDESC_INTREQ 0x0020 318#define AR5K_RXDESC_INTREQ 0x0020
319 319
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c
index 484f31870ba8..21091c26a9a5 100644
--- a/drivers/net/wireless/ath/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -37,6 +37,7 @@
37#include "debug.h" 37#include "debug.h"
38#include "base.h" 38#include "base.h"
39 39
40
40/*********\ 41/*********\
41* Receive * 42* Receive *
42\*********/ 43\*********/
@@ -57,7 +58,7 @@ void ath5k_hw_start_rx_dma(struct ath5k_hw *ah)
57 * 58 *
58 * @ah: The &struct ath5k_hw 59 * @ah: The &struct ath5k_hw
59 */ 60 */
60int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) 61static int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
61{ 62{
62 unsigned int i; 63 unsigned int i;
63 64
@@ -69,7 +70,11 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
69 for (i = 1000; i > 0 && 70 for (i = 1000; i > 0 &&
70 (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0; 71 (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
71 i--) 72 i--)
72 udelay(10); 73 udelay(100);
74
75 if (!i)
76 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
77 "failed to stop RX DMA !\n");
73 78
74 return i ? 0 : -EBUSY; 79 return i ? 0 : -EBUSY;
75} 80}
@@ -90,11 +95,18 @@ u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
90 * @ah: The &struct ath5k_hw 95 * @ah: The &struct ath5k_hw
91 * @phys_addr: RX descriptor address 96 * @phys_addr: RX descriptor address
92 * 97 *
93 * XXX: Should we check if rx is enabled before setting rxdp ? 98 * Returns -EIO if rx is active
94 */ 99 */
95void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr) 100int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
96{ 101{
102 if (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) {
103 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
104 "tried to set RXDP while rx was active !\n");
105 return -EIO;
106 }
107
97 ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP); 108 ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
109 return 0;
98} 110}
99 111
100 112
@@ -125,7 +137,7 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
125 137
126 /* Return if queue is declared inactive */ 138 /* Return if queue is declared inactive */
127 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) 139 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
128 return -EIO; 140 return -EINVAL;
129 141
130 if (ah->ah_version == AR5K_AR5210) { 142 if (ah->ah_version == AR5K_AR5210) {
131 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR); 143 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
@@ -173,10 +185,10 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
173 * 185 *
174 * Stop DMA transmit on a specific hw queue and drain queue so we don't 186 * Stop DMA transmit on a specific hw queue and drain queue so we don't
175 * have any pending frames. Returns -EBUSY if we still have pending frames, 187 * have any pending frames. Returns -EBUSY if we still have pending frames,
176 * -EINVAL if queue number is out of range. 188 * -EINVAL if queue number is out of range or inactive.
177 * 189 *
178 */ 190 */
179int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) 191static int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
180{ 192{
181 unsigned int i = 40; 193 unsigned int i = 40;
182 u32 tx_queue, pending; 194 u32 tx_queue, pending;
@@ -185,7 +197,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
185 197
186 /* Return if queue is declared inactive */ 198 /* Return if queue is declared inactive */
187 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) 199 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
188 return -EIO; 200 return -EINVAL;
189 201
190 if (ah->ah_version == AR5K_AR5210) { 202 if (ah->ah_version == AR5K_AR5210) {
191 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR); 203 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
@@ -211,12 +223,31 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
211 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR); 223 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
212 ath5k_hw_reg_read(ah, AR5K_CR); 224 ath5k_hw_reg_read(ah, AR5K_CR);
213 } else { 225 } else {
226
227 /*
228 * Enable DCU early termination to quickly
229 * flush any pending frames from QCU
230 */
231 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
232 AR5K_QCU_MISC_DCU_EARLY);
233
214 /* 234 /*
215 * Schedule TX disable and wait until queue is empty 235 * Schedule TX disable and wait until queue is empty
216 */ 236 */
217 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue); 237 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
218 238
219 /*Check for pending frames*/ 239 /* Wait for queue to stop */
240 for (i = 1000; i > 0 &&
241 (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue) != 0);
242 i--)
243 udelay(100);
244
245 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
246 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
247 "queue %i didn't stop !\n", queue);
248
249 /* Check for pending frames */
250 i = 1000;
220 do { 251 do {
221 pending = ath5k_hw_reg_read(ah, 252 pending = ath5k_hw_reg_read(ah,
222 AR5K_QUEUE_STATUS(queue)) & 253 AR5K_QUEUE_STATUS(queue)) &
@@ -244,15 +275,15 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
244 275
245 /* Force channel idle high */ 276 /* Force channel idle high */
246 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, 277 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
247 AR5K_DIAG_SW_CHANEL_IDLE_HIGH); 278 AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);
248 279
249 /* Wait a while and disable mechanism */ 280 /* Wait a while and disable mechanism */
250 udelay(200); 281 udelay(400);
251 AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1, 282 AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1,
252 AR5K_QUIET_CTL1_QT_EN); 283 AR5K_QUIET_CTL1_QT_EN);
253 284
254 /* Re-check for pending frames */ 285 /* Re-check for pending frames */
255 i = 40; 286 i = 100;
256 do { 287 do {
257 pending = ath5k_hw_reg_read(ah, 288 pending = ath5k_hw_reg_read(ah,
258 AR5K_QUEUE_STATUS(queue)) & 289 AR5K_QUEUE_STATUS(queue)) &
@@ -261,13 +292,28 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
261 } while (--i && pending); 292 } while (--i && pending);
262 293
263 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211, 294 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,
264 AR5K_DIAG_SW_CHANEL_IDLE_HIGH); 295 AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);
296
297 if (pending)
298 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
299 "quiet mechanism didn't work q:%i !\n",
300 queue);
265 } 301 }
266 302
303 /*
304 * Disable DCU early termination
305 */
306 AR5K_REG_DISABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
307 AR5K_QCU_MISC_DCU_EARLY);
308
267 /* Clear register */ 309 /* Clear register */
268 ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD); 310 ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
269 if (pending) 311 if (pending) {
312 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
313 "tx dma didn't stop (q:%i, frm:%i) !\n",
314 queue, pending);
270 return -EBUSY; 315 return -EBUSY;
316 }
271 } 317 }
272 318
273 /* TODO: Check for success on 5210 else return error */ 319 /* TODO: Check for success on 5210 else return error */
@@ -275,6 +321,26 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
275} 321}
276 322
277/** 323/**
324 * ath5k_hw_stop_beacon_queue - Stop beacon queue
325 *
326 * @ah The &struct ath5k_hw
327 * @queue The queue number
328 *
329 * Returns -EIO if queue didn't stop
330 */
331int ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue)
332{
333 int ret;
334 ret = ath5k_hw_stop_tx_dma(ah, queue);
335 if (ret) {
336 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
337 "beacon queue didn't stop !\n");
338 return -EIO;
339 }
340 return 0;
341}
342
343/**
278 * ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue 344 * ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue
279 * 345 *
280 * @ah: The &struct ath5k_hw 346 * @ah: The &struct ath5k_hw
@@ -377,11 +443,11 @@ int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
377 * 443 *
378 * This function increases/decreases the tx trigger level for the tx fifo 444 * This function increases/decreases the tx trigger level for the tx fifo
379 * buffer (aka FIFO threshold) that is used to indicate when PCU flushes 445 * buffer (aka FIFO threshold) that is used to indicate when PCU flushes
380 * the buffer and transmits it's data. Lowering this results sending small 446 * the buffer and transmits its data. Lowering this results sending small
381 * frames more quickly but can lead to tx underruns, raising it a lot can 447 * frames more quickly but can lead to tx underruns, raising it a lot can
382 * result other problems (i think bmiss is related). Right now we start with 448 * result other problems (i think bmiss is related). Right now we start with
383 * the lowest possible (64Bytes) and if we get tx underrun we increase it using 449 * the lowest possible (64Bytes) and if we get tx underrun we increase it using
384 * the increase flag. Returns -EIO if we have have reached maximum/minimum. 450 * the increase flag. Returns -EIO if we have reached maximum/minimum.
385 * 451 *
386 * XXX: Link this with tx DMA size ? 452 * XXX: Link this with tx DMA size ?
387 * XXX: Use it to save interrupts ? 453 * XXX: Use it to save interrupts ?
@@ -427,6 +493,7 @@ done:
427 return ret; 493 return ret;
428} 494}
429 495
496
430/*******************\ 497/*******************\
431* Interrupt masking * 498* Interrupt masking *
432\*******************/ 499\*******************/
@@ -688,3 +755,92 @@ enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
688 return old_mask; 755 return old_mask;
689} 756}
690 757
758
759/********************\
760 Init/Stop functions
761\********************/
762
763/**
764 * ath5k_hw_dma_init - Initialize DMA unit
765 *
766 * @ah: The &struct ath5k_hw
767 *
768 * Set DMA size and pre-enable interrupts
769 * (driver handles tx/rx buffer setup and
770 * dma start/stop)
771 *
772 * XXX: Save/restore RXDP/TXDP registers ?
773 */
774void ath5k_hw_dma_init(struct ath5k_hw *ah)
775{
776 /*
777 * Set Rx/Tx DMA Configuration
778 *
779 * Set standard DMA size (128). Note that
780 * a DMA size of 512 causes rx overruns and tx errors
781 * on pci-e cards (tested on 5424 but since rx overruns
782 * also occur on 5416/5418 with madwifi we set 128
783 * for all PCI-E cards to be safe).
784 *
785 * XXX: need to check 5210 for this
786 * TODO: Check out tx triger level, it's always 64 on dumps but I
787 * guess we can tweak it and see how it goes ;-)
788 */
789 if (ah->ah_version != AR5K_AR5210) {
790 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
791 AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
792 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
793 AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
794 }
795
796 /* Pre-enable interrupts on 5211/5212*/
797 if (ah->ah_version != AR5K_AR5210)
798 ath5k_hw_set_imr(ah, ah->ah_imr);
799
800}
801
802/**
803 * ath5k_hw_dma_stop - stop DMA unit
804 *
805 * @ah: The &struct ath5k_hw
806 *
807 * Stop tx/rx DMA and interrupts. Returns
808 * -EBUSY if tx or rx dma failed to stop.
809 *
810 * XXX: Sometimes DMA unit hangs and we have
811 * stuck frames on tx queues, only a reset
812 * can fix that.
813 */
814int ath5k_hw_dma_stop(struct ath5k_hw *ah)
815{
816 int i, qmax, err;
817 err = 0;
818
819 /* Disable interrupts */
820 ath5k_hw_set_imr(ah, 0);
821
822 /* Stop rx dma */
823 err = ath5k_hw_stop_rx_dma(ah);
824 if (err)
825 return err;
826
827 /* Clear any pending interrupts
828 * and disable tx dma */
829 if (ah->ah_version != AR5K_AR5210) {
830 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
831 qmax = AR5K_NUM_TX_QUEUES;
832 } else {
833 /* PISR/SISR Not available on 5210 */
834 ath5k_hw_reg_read(ah, AR5K_ISR);
835 qmax = AR5K_NUM_TX_QUEUES_NOQCU;
836 }
837
838 for (i = 0; i < qmax; i++) {
839 err = ath5k_hw_stop_tx_dma(ah, i);
840 /* -EINVAL -> queue inactive */
841 if (err && err != -EINVAL)
842 return err;
843 }
844
845 return 0;
846}
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index ae316fec4a6a..392771f93759 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -28,45 +28,16 @@
28#include "debug.h" 28#include "debug.h"
29#include "base.h" 29#include "base.h"
30 30
31/*
32 * Read from eeprom
33 */
34static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
35{
36 u32 status, timeout;
37
38 /*
39 * Initialize EEPROM access
40 */
41 if (ah->ah_version == AR5K_AR5210) {
42 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
43 (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
44 } else {
45 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
46 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
47 AR5K_EEPROM_CMD_READ);
48 }
49
50 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
51 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
52 if (status & AR5K_EEPROM_STAT_RDDONE) {
53 if (status & AR5K_EEPROM_STAT_RDERR)
54 return -EIO;
55 *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
56 0xffff);
57 return 0;
58 }
59 udelay(15);
60 }
61 31
62 return -ETIMEDOUT; 32/******************\
63} 33* Helper functions *
34\******************/
64 35
65/* 36/*
66 * Translate binary channel representation in EEPROM to frequency 37 * Translate binary channel representation in EEPROM to frequency
67 */ 38 */
68static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin, 39static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
69 unsigned int mode) 40 unsigned int mode)
70{ 41{
71 u16 val; 42 u16 val;
72 43
@@ -89,6 +60,11 @@ static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
89 return val; 60 return val;
90} 61}
91 62
63
64/*********\
65* Parsers *
66\*********/
67
92/* 68/*
93 * Initialize eeprom & capabilities structs 69 * Initialize eeprom & capabilities structs
94 */ 70 */
@@ -96,7 +72,6 @@ static int
96ath5k_eeprom_init_header(struct ath5k_hw *ah) 72ath5k_eeprom_init_header(struct ath5k_hw *ah)
97{ 73{
98 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 74 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
99 int ret;
100 u16 val; 75 u16 val;
101 u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX; 76 u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX;
102 77
@@ -198,7 +173,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
198 * 173 *
199 * XXX: Serdes values seem to be fixed so 174 * XXX: Serdes values seem to be fixed so
200 * no need to read them here, we write them 175 * no need to read them here, we write them
201 * during ath5k_hw_attach */ 176 * during ath5k_hw_init */
202 AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val); 177 AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val);
203 ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ? 178 ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ?
204 true : false; 179 true : false;
@@ -216,7 +191,7 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
216 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 191 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
217 u32 o = *offset; 192 u32 o = *offset;
218 u16 val; 193 u16 val;
219 int ret, i = 0; 194 int i = 0;
220 195
221 AR5K_EEPROM_READ(o++, val); 196 AR5K_EEPROM_READ(o++, val);
222 ee->ee_switch_settling[mode] = (val >> 8) & 0x7f; 197 ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
@@ -276,7 +251,6 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
276 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 251 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
277 u32 o = *offset; 252 u32 o = *offset;
278 u16 val; 253 u16 val;
279 int ret;
280 254
281 ee->ee_n_piers[mode] = 0; 255 ee->ee_n_piers[mode] = 0;
282 AR5K_EEPROM_READ(o++, val); 256 AR5K_EEPROM_READ(o++, val);
@@ -539,7 +513,6 @@ ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
539 int o = *offset; 513 int o = *offset;
540 int i = 0; 514 int i = 0;
541 u8 freq1, freq2; 515 u8 freq1, freq2;
542 int ret;
543 u16 val; 516 u16 val;
544 517
545 ee->ee_n_piers[mode] = 0; 518 ee->ee_n_piers[mode] = 0;
@@ -575,7 +548,7 @@ ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
575{ 548{
576 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 549 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
577 struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a; 550 struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a;
578 int i, ret; 551 int i;
579 u16 val; 552 u16 val;
580 u8 mask; 553 u8 mask;
581 554
@@ -647,6 +620,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
647 return 0; 620 return 0;
648} 621}
649 622
623
650/* 624/*
651 * Read power calibration for RF5111 chips 625 * Read power calibration for RF5111 chips
652 * 626 *
@@ -661,7 +635,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
661 * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC 635 * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC
662 * steps that match with the power values we read from eeprom. On 636 * steps that match with the power values we read from eeprom. On
663 * older eeprom versions (< 3.2) these steps are equaly spaced at 637 * older eeprom versions (< 3.2) these steps are equaly spaced at
664 * 10% of the pcdac curve -until the curve reaches it's maximum- 638 * 10% of the pcdac curve -until the curve reaches its maximum-
665 * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2) 639 * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
666 * these 11 steps are spaced in a different way. This function returns 640 * these 11 steps are spaced in a different way. This function returns
667 * the pcdac steps based on eeprom version and curve min/max so that we 641 * the pcdac steps based on eeprom version and curve min/max so that we
@@ -686,6 +660,51 @@ ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
686 vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; 660 vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
687} 661}
688 662
663static int
664ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
665{
666 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
667 struct ath5k_chan_pcal_info *chinfo;
668 u8 pier, pdg;
669
670 switch (mode) {
671 case AR5K_EEPROM_MODE_11A:
672 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
673 return 0;
674 chinfo = ee->ee_pwr_cal_a;
675 break;
676 case AR5K_EEPROM_MODE_11B:
677 if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
678 return 0;
679 chinfo = ee->ee_pwr_cal_b;
680 break;
681 case AR5K_EEPROM_MODE_11G:
682 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
683 return 0;
684 chinfo = ee->ee_pwr_cal_g;
685 break;
686 default:
687 return -EINVAL;
688 }
689
690 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
691 if (!chinfo[pier].pd_curves)
692 continue;
693
694 for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) {
695 struct ath5k_pdgain_info *pd =
696 &chinfo[pier].pd_curves[pdg];
697
698 kfree(pd->pd_step);
699 kfree(pd->pd_pwr);
700 }
701
702 kfree(chinfo[pier].pd_curves);
703 }
704
705 return 0;
706}
707
689/* Convert RF5111 specific data to generic raw data 708/* Convert RF5111 specific data to generic raw data
690 * used by interpolation code */ 709 * used by interpolation code */
691static int 710static int
@@ -710,7 +729,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
710 GFP_KERNEL); 729 GFP_KERNEL);
711 730
712 if (!chinfo[pier].pd_curves) 731 if (!chinfo[pier].pd_curves)
713 return -ENOMEM; 732 goto err_out;
714 733
715 /* Only one curve for RF5111 734 /* Only one curve for RF5111
716 * find out which one and place 735 * find out which one and place
@@ -734,12 +753,12 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
734 pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, 753 pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
735 sizeof(u8), GFP_KERNEL); 754 sizeof(u8), GFP_KERNEL);
736 if (!pd->pd_step) 755 if (!pd->pd_step)
737 return -ENOMEM; 756 goto err_out;
738 757
739 pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, 758 pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
740 sizeof(s16), GFP_KERNEL); 759 sizeof(s16), GFP_KERNEL);
741 if (!pd->pd_pwr) 760 if (!pd->pd_pwr)
742 return -ENOMEM; 761 goto err_out;
743 762
744 /* Fill raw dataset 763 /* Fill raw dataset
745 * (convert power to 0.25dB units 764 * (convert power to 0.25dB units
@@ -760,6 +779,10 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
760 } 779 }
761 780
762 return 0; 781 return 0;
782
783err_out:
784 ath5k_eeprom_free_pcal_info(ah, mode);
785 return -ENOMEM;
763} 786}
764 787
765/* Parse EEPROM data */ 788/* Parse EEPROM data */
@@ -893,7 +916,7 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
893 GFP_KERNEL); 916 GFP_KERNEL);
894 917
895 if (!chinfo[pier].pd_curves) 918 if (!chinfo[pier].pd_curves)
896 return -ENOMEM; 919 goto err_out;
897 920
898 /* Fill pd_curves */ 921 /* Fill pd_curves */
899 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { 922 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
@@ -912,14 +935,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
912 sizeof(u8), GFP_KERNEL); 935 sizeof(u8), GFP_KERNEL);
913 936
914 if (!pd->pd_step) 937 if (!pd->pd_step)
915 return -ENOMEM; 938 goto err_out;
916 939
917 pd->pd_pwr = kcalloc(pd->pd_points, 940 pd->pd_pwr = kcalloc(pd->pd_points,
918 sizeof(s16), GFP_KERNEL); 941 sizeof(s16), GFP_KERNEL);
919 942
920 if (!pd->pd_pwr) 943 if (!pd->pd_pwr)
921 return -ENOMEM; 944 goto err_out;
922
923 945
924 /* Fill raw dataset 946 /* Fill raw dataset
925 * (all power levels are in 0.25dB units) */ 947 * (all power levels are in 0.25dB units) */
@@ -951,13 +973,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
951 sizeof(u8), GFP_KERNEL); 973 sizeof(u8), GFP_KERNEL);
952 974
953 if (!pd->pd_step) 975 if (!pd->pd_step)
954 return -ENOMEM; 976 goto err_out;
955 977
956 pd->pd_pwr = kcalloc(pd->pd_points, 978 pd->pd_pwr = kcalloc(pd->pd_points,
957 sizeof(s16), GFP_KERNEL); 979 sizeof(s16), GFP_KERNEL);
958 980
959 if (!pd->pd_pwr) 981 if (!pd->pd_pwr)
960 return -ENOMEM; 982 goto err_out;
961 983
962 /* Fill raw dataset 984 /* Fill raw dataset
963 * (all power levels are in 0.25dB units) */ 985 * (all power levels are in 0.25dB units) */
@@ -980,6 +1002,10 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
980 } 1002 }
981 1003
982 return 0; 1004 return 0;
1005
1006err_out:
1007 ath5k_eeprom_free_pcal_info(ah, mode);
1008 return -ENOMEM;
983} 1009}
984 1010
985/* Parse EEPROM data */ 1011/* Parse EEPROM data */
@@ -993,7 +1019,6 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
993 u32 offset; 1019 u32 offset;
994 u8 i, c; 1020 u8 i, c;
995 u16 val; 1021 u16 val;
996 int ret;
997 u8 pd_gains = 0; 1022 u8 pd_gains = 0;
998 1023
999 /* Count how many curves we have and 1024 /* Count how many curves we have and
@@ -1107,13 +1132,13 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
1107 * 1132 *
1108 * To recreate the curves we read here the points and interpolate 1133 * To recreate the curves we read here the points and interpolate
1109 * later. Note that in most cases only 2 (higher and lower) curves are 1134 * later. Note that in most cases only 2 (higher and lower) curves are
1110 * used (like RF5112) but vendors have the oportunity to include all 1135 * used (like RF5112) but vendors have the opportunity to include all
1111 * 4 curves on eeprom. The final curve (higher power) has an extra 1136 * 4 curves on eeprom. The final curve (higher power) has an extra
1112 * point for better accuracy like RF5112. 1137 * point for better accuracy like RF5112.
1113 */ 1138 */
1114 1139
1115/* For RF2413 power calibration data doesn't start on a fixed location and 1140/* For RF2413 power calibration data doesn't start on a fixed location and
1116 * if a mode is not supported, it's section is missing -not zeroed-. 1141 * if a mode is not supported, its section is missing -not zeroed-.
1117 * So we need to calculate the starting offset for each section by using 1142 * So we need to calculate the starting offset for each section by using
1118 * these two functions */ 1143 * these two functions */
1119 1144
@@ -1183,7 +1208,7 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
1183 GFP_KERNEL); 1208 GFP_KERNEL);
1184 1209
1185 if (!chinfo[pier].pd_curves) 1210 if (!chinfo[pier].pd_curves)
1186 return -ENOMEM; 1211 goto err_out;
1187 1212
1188 /* Fill pd_curves */ 1213 /* Fill pd_curves */
1189 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { 1214 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
@@ -1204,13 +1229,13 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
1204 sizeof(u8), GFP_KERNEL); 1229 sizeof(u8), GFP_KERNEL);
1205 1230
1206 if (!pd->pd_step) 1231 if (!pd->pd_step)
1207 return -ENOMEM; 1232 goto err_out;
1208 1233
1209 pd->pd_pwr = kcalloc(pd->pd_points, 1234 pd->pd_pwr = kcalloc(pd->pd_points,
1210 sizeof(s16), GFP_KERNEL); 1235 sizeof(s16), GFP_KERNEL);
1211 1236
1212 if (!pd->pd_pwr) 1237 if (!pd->pd_pwr)
1213 return -ENOMEM; 1238 goto err_out;
1214 1239
1215 /* Fill raw dataset 1240 /* Fill raw dataset
1216 * convert all pwr levels to 1241 * convert all pwr levels to
@@ -1240,6 +1265,10 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
1240 } 1265 }
1241 1266
1242 return 0; 1267 return 0;
1268
1269err_out:
1270 ath5k_eeprom_free_pcal_info(ah, mode);
1271 return -ENOMEM;
1243} 1272}
1244 1273
1245/* Parse EEPROM data */ 1274/* Parse EEPROM data */
@@ -1251,7 +1280,7 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
1251 struct ath5k_chan_pcal_info *chinfo; 1280 struct ath5k_chan_pcal_info *chinfo;
1252 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; 1281 u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
1253 u32 offset; 1282 u32 offset;
1254 int idx, i, ret; 1283 int idx, i;
1255 u16 val; 1284 u16 val;
1256 u8 pd_gains = 0; 1285 u8 pd_gains = 0;
1257 1286
@@ -1329,7 +1358,7 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
1329 /* 1358 /*
1330 * Pd gain 0 is not the last pd gain 1359 * Pd gain 0 is not the last pd gain
1331 * so it only has 2 pd points. 1360 * so it only has 2 pd points.
1332 * Continue wih pd gain 1. 1361 * Continue with pd gain 1.
1333 */ 1362 */
1334 pcinfo->pwr_i[1] = (val >> 10) & 0x1f; 1363 pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
1335 1364
@@ -1442,7 +1471,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
1442 u8 *rate_target_pwr_num; 1471 u8 *rate_target_pwr_num;
1443 u32 offset; 1472 u32 offset;
1444 u16 val; 1473 u16 val;
1445 int ret, i; 1474 int i;
1446 1475
1447 offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1); 1476 offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1);
1448 rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode]; 1477 rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode];
@@ -1514,6 +1543,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
1514 return 0; 1543 return 0;
1515} 1544}
1516 1545
1546
1517/* 1547/*
1518 * Read per channel calibration info from EEPROM 1548 * Read per channel calibration info from EEPROM
1519 * 1549 *
@@ -1560,62 +1590,6 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
1560 return 0; 1590 return 0;
1561} 1591}
1562 1592
1563static int
1564ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
1565{
1566 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1567 struct ath5k_chan_pcal_info *chinfo;
1568 u8 pier, pdg;
1569
1570 switch (mode) {
1571 case AR5K_EEPROM_MODE_11A:
1572 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
1573 return 0;
1574 chinfo = ee->ee_pwr_cal_a;
1575 break;
1576 case AR5K_EEPROM_MODE_11B:
1577 if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
1578 return 0;
1579 chinfo = ee->ee_pwr_cal_b;
1580 break;
1581 case AR5K_EEPROM_MODE_11G:
1582 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
1583 return 0;
1584 chinfo = ee->ee_pwr_cal_g;
1585 break;
1586 default:
1587 return -EINVAL;
1588 }
1589
1590 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
1591 if (!chinfo[pier].pd_curves)
1592 continue;
1593
1594 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
1595 struct ath5k_pdgain_info *pd =
1596 &chinfo[pier].pd_curves[pdg];
1597
1598 if (pd != NULL) {
1599 kfree(pd->pd_step);
1600 kfree(pd->pd_pwr);
1601 }
1602 }
1603
1604 kfree(chinfo[pier].pd_curves);
1605 }
1606
1607 return 0;
1608}
1609
1610void
1611ath5k_eeprom_detach(struct ath5k_hw *ah)
1612{
1613 u8 mode;
1614
1615 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
1616 ath5k_eeprom_free_pcal_info(ah, mode);
1617}
1618
1619/* Read conformance test limits used for regulatory control */ 1593/* Read conformance test limits used for regulatory control */
1620static int 1594static int
1621ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) 1595ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
@@ -1624,7 +1598,7 @@ ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
1624 struct ath5k_edge_power *rep; 1598 struct ath5k_edge_power *rep;
1625 unsigned int fmask, pmask; 1599 unsigned int fmask, pmask;
1626 unsigned int ctl_mode; 1600 unsigned int ctl_mode;
1627 int ret, i, j; 1601 int i, j;
1628 u32 offset; 1602 u32 offset;
1629 u16 val; 1603 u16 val;
1630 1604
@@ -1756,6 +1730,11 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
1756 return ret; 1730 return ret;
1757} 1731}
1758 1732
1733
1734/***********************\
1735* Init/Detach functions *
1736\***********************/
1737
1759/* 1738/*
1760 * Initialize eeprom data structure 1739 * Initialize eeprom data structure
1761 */ 1740 */
@@ -1787,35 +1766,27 @@ ath5k_eeprom_init(struct ath5k_hw *ah)
1787 return 0; 1766 return 0;
1788} 1767}
1789 1768
1790/* 1769void
1791 * Read the MAC address from eeprom 1770ath5k_eeprom_detach(struct ath5k_hw *ah)
1792 */
1793int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
1794{ 1771{
1795 u8 mac_d[ETH_ALEN] = {}; 1772 u8 mode;
1796 u32 total, offset;
1797 u16 data;
1798 int octet, ret;
1799
1800 ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
1801 if (ret)
1802 return ret;
1803 1773
1804 for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { 1774 for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
1805 ret = ath5k_hw_eeprom_read(ah, offset, &data); 1775 ath5k_eeprom_free_pcal_info(ah, mode);
1806 if (ret) 1776}
1807 return ret;
1808 1777
1809 total += data; 1778int
1810 mac_d[octet + 1] = data & 0xff; 1779ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel)
1811 mac_d[octet] = data >> 8; 1780{
1812 octet += 2; 1781 switch (channel->hw_value & CHANNEL_MODES) {
1782 case CHANNEL_A:
1783 case CHANNEL_XR:
1784 return AR5K_EEPROM_MODE_11A;
1785 case CHANNEL_G:
1786 return AR5K_EEPROM_MODE_11G;
1787 case CHANNEL_B:
1788 return AR5K_EEPROM_MODE_11B;
1789 default:
1790 return -1;
1813 } 1791 }
1814
1815 if (!total || total == 3 * 0xffff)
1816 return -EINVAL;
1817
1818 memcpy(mac, mac_d, ETH_ALEN);
1819
1820 return 0;
1821} 1792}
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index c4a6d5f26af4..6511c27d938e 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -241,9 +241,8 @@ enum ath5k_eeprom_freq_bands{
241#define AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz 6250 241#define AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz 6250
242 242
243#define AR5K_EEPROM_READ(_o, _v) do { \ 243#define AR5K_EEPROM_READ(_o, _v) do { \
244 ret = ath5k_hw_eeprom_read(ah, (_o), &(_v)); \ 244 if (!ath5k_hw_nvram_read(ah, (_o), &(_v))) \
245 if (ret) \ 245 return -EIO; \
246 return ret; \
247} while (0) 246} while (0)
248 247
249#define AR5K_EEPROM_READ_HDR(_o, _v) \ 248#define AR5K_EEPROM_READ_HDR(_o, _v) \
@@ -269,29 +268,6 @@ enum ath5k_ctl_mode {
269 AR5K_CTL_MODE_M = 15, 268 AR5K_CTL_MODE_M = 15,
270}; 269};
271 270
272/* Default CTL ids for the 3 main reg domains.
273 * Atheros only uses these by default but vendors
274 * can have up to 32 different CTLs for different
275 * scenarios. Note that theese values are ORed with
276 * the mode id (above) so we can have up to 24 CTL
277 * datasets out of these 3 main regdomains. That leaves
278 * 8 ids that can be used by vendors and since 0x20 is
279 * missing from HAL sources i guess this is the set of
280 * custom CTLs vendors can use. */
281#define AR5K_CTL_FCC 0x10
282#define AR5K_CTL_CUSTOM 0x20
283#define AR5K_CTL_ETSI 0x30
284#define AR5K_CTL_MKK 0x40
285
286/* Indicates a CTL with only mode set and
287 * no reg domain mapping, such CTLs are used
288 * for world roaming domains or simply when
289 * a reg domain is not set */
290#define AR5K_CTL_NO_REGDOMAIN 0xf0
291
292/* Indicates an empty (invalid) CTL */
293#define AR5K_CTL_NO_CTL 0xff
294
295/* Per channel calibration data, used for power table setup */ 271/* Per channel calibration data, used for power table setup */
296struct ath5k_chan_pcal_info_rf5111 { 272struct ath5k_chan_pcal_info_rf5111 {
297 /* Power levels in half dbm units 273 /* Power levels in half dbm units
@@ -517,3 +493,5 @@ struct ath5k_eeprom_info {
517 u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; 493 u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
518}; 494};
519 495
496int
497ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel);
diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c
index 8fa439308828..e49340d18df4 100644
--- a/drivers/net/wireless/ath/ath5k/initvals.c
+++ b/drivers/net/wireless/ath/ath5k/initvals.c
@@ -44,7 +44,7 @@ struct ath5k_ini {
44 44
45struct ath5k_ini_mode { 45struct ath5k_ini_mode {
46 u16 mode_register; 46 u16 mode_register;
47 u32 mode_value[5]; 47 u32 mode_value[3];
48}; 48};
49 49
50/* Initial register settings for AR5210 */ 50/* Initial register settings for AR5210 */
@@ -391,76 +391,74 @@ static const struct ath5k_ini ar5211_ini[] = {
391 */ 391 */
392static const struct ath5k_ini_mode ar5211_ini_mode[] = { 392static const struct ath5k_ini_mode ar5211_ini_mode[] = {
393 { AR5K_TXCFG, 393 { AR5K_TXCFG,
394 /* a aTurbo b g (OFDM) */ 394 /* A/XR B G */
395 { 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } }, 395 { 0x00000015, 0x0000001d, 0x00000015 } },
396 { AR5K_QUEUE_DFS_LOCAL_IFS(0), 396 { AR5K_QUEUE_DFS_LOCAL_IFS(0),
397 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, 397 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
398 { AR5K_QUEUE_DFS_LOCAL_IFS(1), 398 { AR5K_QUEUE_DFS_LOCAL_IFS(1),
399 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, 399 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
400 { AR5K_QUEUE_DFS_LOCAL_IFS(2), 400 { AR5K_QUEUE_DFS_LOCAL_IFS(2),
401 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, 401 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
402 { AR5K_QUEUE_DFS_LOCAL_IFS(3), 402 { AR5K_QUEUE_DFS_LOCAL_IFS(3),
403 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, 403 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
404 { AR5K_QUEUE_DFS_LOCAL_IFS(4), 404 { AR5K_QUEUE_DFS_LOCAL_IFS(4),
405 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, 405 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
406 { AR5K_QUEUE_DFS_LOCAL_IFS(5), 406 { AR5K_QUEUE_DFS_LOCAL_IFS(5),
407 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, 407 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
408 { AR5K_QUEUE_DFS_LOCAL_IFS(6), 408 { AR5K_QUEUE_DFS_LOCAL_IFS(6),
409 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, 409 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
410 { AR5K_QUEUE_DFS_LOCAL_IFS(7), 410 { AR5K_QUEUE_DFS_LOCAL_IFS(7),
411 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, 411 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
412 { AR5K_QUEUE_DFS_LOCAL_IFS(8), 412 { AR5K_QUEUE_DFS_LOCAL_IFS(8),
413 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, 413 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
414 { AR5K_QUEUE_DFS_LOCAL_IFS(9), 414 { AR5K_QUEUE_DFS_LOCAL_IFS(9),
415 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, 415 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
416 { AR5K_DCU_GBL_IFS_SLOT, 416 { AR5K_DCU_GBL_IFS_SLOT,
417 { 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } }, 417 { 0x00000168, 0x000001b8, 0x00000168 } },
418 { AR5K_DCU_GBL_IFS_SIFS, 418 { AR5K_DCU_GBL_IFS_SIFS,
419 { 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } }, 419 { 0x00000230, 0x000000b0, 0x00000230 } },
420 { AR5K_DCU_GBL_IFS_EIFS, 420 { AR5K_DCU_GBL_IFS_EIFS,
421 { 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } }, 421 { 0x00000d98, 0x00001f48, 0x00000d98 } },
422 { AR5K_DCU_GBL_IFS_MISC, 422 { AR5K_DCU_GBL_IFS_MISC,
423 { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } }, 423 { 0x0000a0e0, 0x00005880, 0x0000a0e0 } },
424 { AR5K_TIME_OUT, 424 { AR5K_TIME_OUT,
425 { 0x04000400, 0x08000800, 0x20003000, 0x04000400 } }, 425 { 0x04000400, 0x20003000, 0x04000400 } },
426 { AR5K_USEC_5211, 426 { AR5K_USEC_5211,
427 { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } }, 427 { 0x0e8d8fa7, 0x01608f95, 0x0e8d8fa7 } },
428 { AR5K_PHY_TURBO,
429 { 0x00000000, 0x00000003, 0x00000000, 0x00000000 } },
430 { AR5K_PHY(8), 428 { AR5K_PHY(8),
431 { 0x02020200, 0x02020200, 0x02010200, 0x02020200 } }, 429 { 0x02020200, 0x02010200, 0x02020200 } },
432 { AR5K_PHY(9), 430 { AR5K_PHY_RF_CTL2,
433 { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } }, 431 { 0x00000e0e, 0x00000707, 0x00000e0e } },
434 { AR5K_PHY(10), 432 { AR5K_PHY_RF_CTL3,
435 { 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } }, 433 { 0x0a020001, 0x05010000, 0x0a020001 } },
436 { AR5K_PHY(13), 434 { AR5K_PHY_RF_CTL4,
437 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, 435 { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
438 { AR5K_PHY(14), 436 { AR5K_PHY_PA_CTL,
439 { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } }, 437 { 0x00000007, 0x0000000b, 0x0000000b } },
440 { AR5K_PHY(17), 438 { AR5K_PHY_SETTLING,
441 { 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } }, 439 { 0x1372169c, 0x137216a8, 0x1372169c } },
442 { AR5K_PHY(18), 440 { AR5K_PHY_GAIN,
443 { 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } }, 441 { 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
444 { AR5K_PHY(20), 442 { AR5K_PHY_DESIRED_SIZE,
445 { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } }, 443 { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
446 { AR5K_PHY_SIG, 444 { AR5K_PHY_SIG,
447 { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } }, 445 { 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
448 { AR5K_PHY_AGCCOARSE, 446 { AR5K_PHY_AGCCOARSE,
449 { 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } }, 447 { 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
450 { AR5K_PHY_AGCCTL, 448 { AR5K_PHY_AGCCTL,
451 { 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } }, 449 { 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
452 { AR5K_PHY_NF, 450 { AR5K_PHY_NF,
453 { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } }, 451 { 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
454 { AR5K_PHY_RX_DELAY, 452 { AR5K_PHY_RX_DELAY,
455 { 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } }, 453 { 0x00002710, 0x0000157c, 0x00002710 } },
456 { AR5K_PHY(70), 454 { AR5K_PHY(70),
457 { 0x00000190, 0x00000190, 0x00000084, 0x00000190 } }, 455 { 0x00000190, 0x00000084, 0x00000190 } },
458 { AR5K_PHY_FRAME_CTL_5211, 456 { AR5K_PHY_FRAME_CTL_5211,
459 { 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } }, 457 { 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
460 { AR5K_PHY_PCDAC_TXPOWER_BASE, 458 { AR5K_PHY_PCDAC_TXPOWER_BASE,
461 { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } }, 459 { 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
462 { AR5K_RF_BUFFER_CONTROL_4, 460 { AR5K_RF_BUFFER_CONTROL_4,
463 { 0x00000010, 0x00000014, 0x00000010, 0x00000010 } }, 461 { 0x00000010, 0x00000010, 0x00000010 } },
464}; 462};
465 463
466/* Initial register settings for AR5212 */ 464/* Initial register settings for AR5212 */
@@ -677,89 +675,87 @@ static const struct ath5k_ini ar5212_ini_common_start[] = {
677/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */ 675/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */
678static const struct ath5k_ini_mode ar5212_ini_mode_start[] = { 676static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
679 { AR5K_QUEUE_DFS_LOCAL_IFS(0), 677 { AR5K_QUEUE_DFS_LOCAL_IFS(0),
680 /* a/XR aTurbo b g (DYN) gTurbo */ 678 /* A/XR B G */
681 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 679 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
682 { AR5K_QUEUE_DFS_LOCAL_IFS(1), 680 { AR5K_QUEUE_DFS_LOCAL_IFS(1),
683 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 681 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
684 { AR5K_QUEUE_DFS_LOCAL_IFS(2), 682 { AR5K_QUEUE_DFS_LOCAL_IFS(2),
685 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 683 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
686 { AR5K_QUEUE_DFS_LOCAL_IFS(3), 684 { AR5K_QUEUE_DFS_LOCAL_IFS(3),
687 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 685 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
688 { AR5K_QUEUE_DFS_LOCAL_IFS(4), 686 { AR5K_QUEUE_DFS_LOCAL_IFS(4),
689 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 687 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
690 { AR5K_QUEUE_DFS_LOCAL_IFS(5), 688 { AR5K_QUEUE_DFS_LOCAL_IFS(5),
691 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 689 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
692 { AR5K_QUEUE_DFS_LOCAL_IFS(6), 690 { AR5K_QUEUE_DFS_LOCAL_IFS(6),
693 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 691 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
694 { AR5K_QUEUE_DFS_LOCAL_IFS(7), 692 { AR5K_QUEUE_DFS_LOCAL_IFS(7),
695 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 693 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
696 { AR5K_QUEUE_DFS_LOCAL_IFS(8), 694 { AR5K_QUEUE_DFS_LOCAL_IFS(8),
697 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 695 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
698 { AR5K_QUEUE_DFS_LOCAL_IFS(9), 696 { AR5K_QUEUE_DFS_LOCAL_IFS(9),
699 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } }, 697 { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
700 { AR5K_DCU_GBL_IFS_SIFS, 698 { AR5K_DCU_GBL_IFS_SIFS,
701 { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } }, 699 { 0x00000230, 0x000000b0, 0x00000160 } },
702 { AR5K_DCU_GBL_IFS_SLOT, 700 { AR5K_DCU_GBL_IFS_SLOT,
703 { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } }, 701 { 0x00000168, 0x000001b8, 0x0000018c } },
704 { AR5K_DCU_GBL_IFS_EIFS, 702 { AR5K_DCU_GBL_IFS_EIFS,
705 { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } }, 703 { 0x00000e60, 0x00001f1c, 0x00003e38 } },
706 { AR5K_DCU_GBL_IFS_MISC, 704 { AR5K_DCU_GBL_IFS_MISC,
707 { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } }, 705 { 0x0000a0e0, 0x00005880, 0x0000b0e0 } },
708 { AR5K_TIME_OUT, 706 { AR5K_TIME_OUT,
709 { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } }, 707 { 0x03e803e8, 0x04200420, 0x08400840 } },
710 { AR5K_PHY_TURBO,
711 { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
712 { AR5K_PHY(8), 708 { AR5K_PHY(8),
713 { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } }, 709 { 0x02020200, 0x02010200, 0x02020200 } },
714 { AR5K_PHY_RF_CTL2, 710 { AR5K_PHY_RF_CTL2,
715 { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } }, 711 { 0x00000e0e, 0x00000707, 0x00000e0e } },
716 { AR5K_PHY_SETTLING, 712 { AR5K_PHY_SETTLING,
717 { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } }, 713 { 0x1372161c, 0x13721722, 0x137216a2 } },
718 { AR5K_PHY_AGCCTL, 714 { AR5K_PHY_AGCCTL,
719 { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d10 } }, 715 { 0x00009d10, 0x00009d18, 0x00009d18 } },
720 { AR5K_PHY_NF, 716 { AR5K_PHY_NF,
721 { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } }, 717 { 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
722 { AR5K_PHY_WEAK_OFDM_HIGH_THR, 718 { AR5K_PHY_WEAK_OFDM_HIGH_THR,
723 { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } }, 719 { 0x409a4190, 0x409a4190, 0x409a4190 } },
724 { AR5K_PHY(70), 720 { AR5K_PHY(70),
725 { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } }, 721 { 0x000001b8, 0x00000084, 0x00000108 } },
726 { AR5K_PHY_OFDM_SELFCORR, 722 { AR5K_PHY_OFDM_SELFCORR,
727 { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } }, 723 { 0x10058a05, 0x10058a05, 0x10058a05 } },
728 { 0xa230, 724 { 0xa230,
729 { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } }, 725 { 0x00000000, 0x00000000, 0x00000108 } },
730}; 726};
731 727
732/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */ 728/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */
733static const struct ath5k_ini_mode rf5111_ini_mode_end[] = { 729static const struct ath5k_ini_mode rf5111_ini_mode_end[] = {
734 { AR5K_TXCFG, 730 { AR5K_TXCFG,
735 /* a/XR aTurbo b g (DYN) gTurbo */ 731 /* A/XR B G */
736 { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } }, 732 { 0x00008015, 0x00008015, 0x00008015 } },
737 { AR5K_USEC_5211, 733 { AR5K_USEC_5211,
738 { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } }, 734 { 0x128d8fa7, 0x04e00f95, 0x12e00fab } },
739 { AR5K_PHY_RF_CTL3, 735 { AR5K_PHY_RF_CTL3,
740 { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } }, 736 { 0x0a020001, 0x05010100, 0x0a020001 } },
741 { AR5K_PHY_RF_CTL4, 737 { AR5K_PHY_RF_CTL4,
742 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, 738 { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
743 { AR5K_PHY_PA_CTL, 739 { AR5K_PHY_PA_CTL,
744 { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } }, 740 { 0x00000007, 0x0000000b, 0x0000000b } },
745 { AR5K_PHY_GAIN, 741 { AR5K_PHY_GAIN,
746 { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } }, 742 { 0x0018da5a, 0x0018ca69, 0x0018ca69 } },
747 { AR5K_PHY_DESIRED_SIZE, 743 { AR5K_PHY_DESIRED_SIZE,
748 { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } }, 744 { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
749 { AR5K_PHY_SIG, 745 { AR5K_PHY_SIG,
750 { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } }, 746 { 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e } },
751 { AR5K_PHY_AGCCOARSE, 747 { AR5K_PHY_AGCCOARSE,
752 { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } }, 748 { 0x3137665e, 0x3137665e, 0x3137665e } },
753 { AR5K_PHY_WEAK_OFDM_LOW_THR, 749 { AR5K_PHY_WEAK_OFDM_LOW_THR,
754 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } }, 750 { 0x050cb081, 0x050cb081, 0x050cb080 } },
755 { AR5K_PHY_RX_DELAY, 751 { AR5K_PHY_RX_DELAY,
756 { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } }, 752 { 0x00002710, 0x0000157c, 0x00002af8 } },
757 { AR5K_PHY_FRAME_CTL_5211, 753 { AR5K_PHY_FRAME_CTL_5211,
758 { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } }, 754 { 0xf7b81020, 0xf7b80d20, 0xf7b81020 } },
759 { AR5K_PHY_GAIN_2GHZ, 755 { AR5K_PHY_GAIN_2GHZ,
760 { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } }, 756 { 0x642c416a, 0x6440416a, 0x6440416a } },
761 { AR5K_PHY_CCK_RX_CTL_4, 757 { AR5K_PHY_CCK_RX_CTL_4,
762 { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } }, 758 { 0x1883800a, 0x1873800a, 0x1883800a } },
763}; 759};
764 760
765static const struct ath5k_ini rf5111_ini_common_end[] = { 761static const struct ath5k_ini rf5111_ini_common_end[] = {
@@ -782,38 +778,38 @@ static const struct ath5k_ini rf5111_ini_common_end[] = {
782/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */ 778/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */
783static const struct ath5k_ini_mode rf5112_ini_mode_end[] = { 779static const struct ath5k_ini_mode rf5112_ini_mode_end[] = {
784 { AR5K_TXCFG, 780 { AR5K_TXCFG,
785 /* a/XR aTurbo b g (DYN) gTurbo */ 781 /* A/XR B G */
786 { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } }, 782 { 0x00008015, 0x00008015, 0x00008015 } },
787 { AR5K_USEC_5211, 783 { AR5K_USEC_5211,
788 { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } }, 784 { 0x128d93a7, 0x04e01395, 0x12e013ab } },
789 { AR5K_PHY_RF_CTL3, 785 { AR5K_PHY_RF_CTL3,
790 { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } }, 786 { 0x0a020001, 0x05020100, 0x0a020001 } },
791 { AR5K_PHY_RF_CTL4, 787 { AR5K_PHY_RF_CTL4,
792 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, 788 { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
793 { AR5K_PHY_PA_CTL, 789 { AR5K_PHY_PA_CTL,
794 { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } }, 790 { 0x00000007, 0x0000000b, 0x0000000b } },
795 { AR5K_PHY_GAIN, 791 { AR5K_PHY_GAIN,
796 { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } }, 792 { 0x0018da6d, 0x0018ca75, 0x0018ca75 } },
797 { AR5K_PHY_DESIRED_SIZE, 793 { AR5K_PHY_DESIRED_SIZE,
798 { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } }, 794 { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
799 { AR5K_PHY_SIG, 795 { AR5K_PHY_SIG,
800 { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7e800d2e } }, 796 { 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e } },
801 { AR5K_PHY_AGCCOARSE, 797 { AR5K_PHY_AGCCOARSE,
802 { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } }, 798 { 0x3137665e, 0x3137665e, 0x3137665e } },
803 { AR5K_PHY_WEAK_OFDM_LOW_THR, 799 { AR5K_PHY_WEAK_OFDM_LOW_THR,
804 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } }, 800 { 0x050cb081, 0x050cb081, 0x050cb081 } },
805 { AR5K_PHY_RX_DELAY, 801 { AR5K_PHY_RX_DELAY,
806 { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } }, 802 { 0x000007d0, 0x0000044c, 0x00000898 } },
807 { AR5K_PHY_FRAME_CTL_5211, 803 { AR5K_PHY_FRAME_CTL_5211,
808 { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } }, 804 { 0xf7b81020, 0xf7b80d10, 0xf7b81010 } },
809 { AR5K_PHY_CCKTXCTL, 805 { AR5K_PHY_CCKTXCTL,
810 { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } }, 806 { 0x00000000, 0x00000008, 0x00000008 } },
811 { AR5K_PHY_CCK_CROSSCORR, 807 { AR5K_PHY_CCK_CROSSCORR,
812 { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, 808 { 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
813 { AR5K_PHY_GAIN_2GHZ, 809 { AR5K_PHY_GAIN_2GHZ,
814 { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } }, 810 { 0x642c0140, 0x6442c160, 0x6442c160 } },
815 { AR5K_PHY_CCK_RX_CTL_4, 811 { AR5K_PHY_CCK_RX_CTL_4,
816 { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } }, 812 { 0x1883800a, 0x1873800a, 0x1883800a } },
817}; 813};
818 814
819static const struct ath5k_ini rf5112_ini_common_end[] = { 815static const struct ath5k_ini rf5112_ini_common_end[] = {
@@ -833,66 +829,66 @@ static const struct ath5k_ini rf5112_ini_common_end[] = {
833/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */ 829/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */
834static const struct ath5k_ini_mode rf5413_ini_mode_end[] = { 830static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
835 { AR5K_TXCFG, 831 { AR5K_TXCFG,
836 /* a/XR aTurbo b g (DYN) gTurbo */ 832 /* A/XR B G */
837 { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } }, 833 { 0x00000015, 0x00000015, 0x00000015 } },
838 { AR5K_USEC_5211, 834 { AR5K_USEC_5211,
839 { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } }, 835 { 0x128d93a7, 0x04e01395, 0x12e013ab } },
840 { AR5K_PHY_RF_CTL3, 836 { AR5K_PHY_RF_CTL3,
841 { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } }, 837 { 0x0a020001, 0x05020100, 0x0a020001 } },
842 { AR5K_PHY_RF_CTL4, 838 { AR5K_PHY_RF_CTL4,
843 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, 839 { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
844 { AR5K_PHY_PA_CTL, 840 { AR5K_PHY_PA_CTL,
845 { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } }, 841 { 0x00000007, 0x0000000b, 0x0000000b } },
846 { AR5K_PHY_GAIN, 842 { AR5K_PHY_GAIN,
847 { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } }, 843 { 0x0018fa61, 0x001a1a63, 0x001a1a63 } },
848 { AR5K_PHY_DESIRED_SIZE, 844 { AR5K_PHY_DESIRED_SIZE,
849 { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } }, 845 { 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da } },
850 { AR5K_PHY_SIG, 846 { AR5K_PHY_SIG,
851 { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } }, 847 { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
852 { AR5K_PHY_AGCCOARSE, 848 { AR5K_PHY_AGCCOARSE,
853 { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } }, 849 { 0x3139605e, 0x3139605e, 0x3139605e } },
854 { AR5K_PHY_WEAK_OFDM_LOW_THR, 850 { AR5K_PHY_WEAK_OFDM_LOW_THR,
855 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } }, 851 { 0x050cb081, 0x050cb081, 0x050cb081 } },
856 { AR5K_PHY_RX_DELAY, 852 { AR5K_PHY_RX_DELAY,
857 { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } }, 853 { 0x000007d0, 0x0000044c, 0x00000898 } },
858 { AR5K_PHY_FRAME_CTL_5211, 854 { AR5K_PHY_FRAME_CTL_5211,
859 { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } }, 855 { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } },
860 { AR5K_PHY_CCKTXCTL, 856 { AR5K_PHY_CCKTXCTL,
861 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 857 { 0x00000000, 0x00000000, 0x00000000 } },
862 { AR5K_PHY_CCK_CROSSCORR, 858 { AR5K_PHY_CCK_CROSSCORR,
863 { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, 859 { 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
864 { AR5K_PHY_GAIN_2GHZ, 860 { AR5K_PHY_GAIN_2GHZ,
865 { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } }, 861 { 0x002ec1e0, 0x002ac120, 0x002ac120 } },
866 { AR5K_PHY_CCK_RX_CTL_4, 862 { AR5K_PHY_CCK_RX_CTL_4,
867 { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } }, 863 { 0x1883800a, 0x1863800a, 0x1883800a } },
868 { 0xa300, 864 { 0xa300,
869 { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } }, 865 { 0x18010000, 0x18010000, 0x18010000 } },
870 { 0xa304, 866 { 0xa304,
871 { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } }, 867 { 0x30032602, 0x30032602, 0x30032602 } },
872 { 0xa308, 868 { 0xa308,
873 { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } }, 869 { 0x48073e06, 0x48073e06, 0x48073e06 } },
874 { 0xa30c, 870 { 0xa30c,
875 { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } }, 871 { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
876 { 0xa310, 872 { 0xa310,
877 { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } }, 873 { 0x641a600f, 0x641a600f, 0x641a600f } },
878 { 0xa314, 874 { 0xa314,
879 { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } }, 875 { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
880 { 0xa318, 876 { 0xa318,
881 { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } }, 877 { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
882 { 0xa31c, 878 { 0xa31c,
883 { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } }, 879 { 0x90cf865b, 0x8ecf865b, 0x8ecf865b } },
884 { 0xa320, 880 { 0xa320,
885 { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } }, 881 { 0x9d4f970f, 0x9b4f970f, 0x9b4f970f } },
886 { 0xa324, 882 { 0xa324,
887 { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } }, 883 { 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f } },
888 { 0xa328, 884 { 0xa328,
889 { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } }, 885 { 0xb55faf1f, 0xb35faf1f, 0xb35faf1f } },
890 { 0xa32c, 886 { 0xa32c,
891 { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } }, 887 { 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f } },
892 { 0xa330, 888 { 0xa330,
893 { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } }, 889 { 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f } },
894 { 0xa334, 890 { 0xa334,
895 { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } }, 891 { 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
896}; 892};
897 893
898static const struct ath5k_ini rf5413_ini_common_end[] = { 894static const struct ath5k_ini rf5413_ini_common_end[] = {
@@ -972,38 +968,38 @@ static const struct ath5k_ini rf5413_ini_common_end[] = {
972/* XXX: a mode ? */ 968/* XXX: a mode ? */
973static const struct ath5k_ini_mode rf2413_ini_mode_end[] = { 969static const struct ath5k_ini_mode rf2413_ini_mode_end[] = {
974 { AR5K_TXCFG, 970 { AR5K_TXCFG,
975 /* a/XR aTurbo b g (DYN) gTurbo */ 971 /* A/XR B G */
976 { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } }, 972 { 0x00000015, 0x00000015, 0x00000015 } },
977 { AR5K_USEC_5211, 973 { AR5K_USEC_5211,
978 { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } }, 974 { 0x128d93a7, 0x04e01395, 0x12e013ab } },
979 { AR5K_PHY_RF_CTL3, 975 { AR5K_PHY_RF_CTL3,
980 { 0x0a020001, 0x0a020001, 0x05020000, 0x0a020001, 0x0a020001 } }, 976 { 0x0a020001, 0x05020000, 0x0a020001 } },
981 { AR5K_PHY_RF_CTL4, 977 { AR5K_PHY_RF_CTL4,
982 { 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00 } }, 978 { 0x00000e00, 0x00000e00, 0x00000e00 } },
983 { AR5K_PHY_PA_CTL, 979 { AR5K_PHY_PA_CTL,
984 { 0x00000002, 0x00000002, 0x0000000a, 0x0000000a, 0x0000000a } }, 980 { 0x00000002, 0x0000000a, 0x0000000a } },
985 { AR5K_PHY_GAIN, 981 { AR5K_PHY_GAIN,
986 { 0x0018da6d, 0x0018da6d, 0x001a6a64, 0x001a6a64, 0x001a6a64 } }, 982 { 0x0018da6d, 0x001a6a64, 0x001a6a64 } },
987 { AR5K_PHY_DESIRED_SIZE, 983 { AR5K_PHY_DESIRED_SIZE,
988 { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da, 0x0de8b0da } }, 984 { 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da } },
989 { AR5K_PHY_SIG, 985 { AR5K_PHY_SIG,
990 { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e, 0x7e800d2e } }, 986 { 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e } },
991 { AR5K_PHY_AGCCOARSE, 987 { AR5K_PHY_AGCCOARSE,
992 { 0x3137665e, 0x3137665e, 0x3137665e, 0x3139605e, 0x3137665e } }, 988 { 0x3137665e, 0x3137665e, 0x3139605e } },
993 { AR5K_PHY_WEAK_OFDM_LOW_THR, 989 { AR5K_PHY_WEAK_OFDM_LOW_THR,
994 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } }, 990 { 0x050cb081, 0x050cb081, 0x050cb081 } },
995 { AR5K_PHY_RX_DELAY, 991 { AR5K_PHY_RX_DELAY,
996 { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } }, 992 { 0x000007d0, 0x0000044c, 0x00000898 } },
997 { AR5K_PHY_FRAME_CTL_5211, 993 { AR5K_PHY_FRAME_CTL_5211,
998 { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } }, 994 { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } },
999 { AR5K_PHY_CCKTXCTL, 995 { AR5K_PHY_CCKTXCTL,
1000 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 996 { 0x00000000, 0x00000000, 0x00000000 } },
1001 { AR5K_PHY_CCK_CROSSCORR, 997 { AR5K_PHY_CCK_CROSSCORR,
1002 { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, 998 { 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
1003 { AR5K_PHY_GAIN_2GHZ, 999 { AR5K_PHY_GAIN_2GHZ,
1004 { 0x002c0140, 0x002c0140, 0x0042c140, 0x0042c140, 0x0042c140 } }, 1000 { 0x002c0140, 0x0042c140, 0x0042c140 } },
1005 { AR5K_PHY_CCK_RX_CTL_4, 1001 { AR5K_PHY_CCK_RX_CTL_4,
1006 { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } }, 1002 { 0x1883800a, 0x1863800a, 0x1883800a } },
1007}; 1003};
1008 1004
1009static const struct ath5k_ini rf2413_ini_common_end[] = { 1005static const struct ath5k_ini rf2413_ini_common_end[] = {
@@ -1094,52 +1090,50 @@ static const struct ath5k_ini rf2413_ini_common_end[] = {
1094/* XXX: a mode ? */ 1090/* XXX: a mode ? */
1095static const struct ath5k_ini_mode rf2425_ini_mode_end[] = { 1091static const struct ath5k_ini_mode rf2425_ini_mode_end[] = {
1096 { AR5K_TXCFG, 1092 { AR5K_TXCFG,
1097 /* a/XR aTurbo b g (DYN) gTurbo */ 1093 /* A/XR B G */
1098 { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } }, 1094 { 0x00000015, 0x00000015, 0x00000015 } },
1099 { AR5K_USEC_5211, 1095 { AR5K_USEC_5211,
1100 { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } }, 1096 { 0x128d93a7, 0x04e01395, 0x12e013ab } },
1101 { AR5K_PHY_TURBO,
1102 { 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001 } },
1103 { AR5K_PHY_RF_CTL3, 1097 { AR5K_PHY_RF_CTL3,
1104 { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } }, 1098 { 0x0a020001, 0x05020100, 0x0a020001 } },
1105 { AR5K_PHY_RF_CTL4, 1099 { AR5K_PHY_RF_CTL4,
1106 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } }, 1100 { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
1107 { AR5K_PHY_PA_CTL, 1101 { AR5K_PHY_PA_CTL,
1108 { 0x00000003, 0x00000003, 0x0000000b, 0x0000000b, 0x0000000b } }, 1102 { 0x00000003, 0x0000000b, 0x0000000b } },
1109 { AR5K_PHY_SETTLING, 1103 { AR5K_PHY_SETTLING,
1110 { 0x1372161c, 0x13721c25, 0x13721722, 0x13721422, 0x13721c25 } }, 1104 { 0x1372161c, 0x13721722, 0x13721422 } },
1111 { AR5K_PHY_GAIN, 1105 { AR5K_PHY_GAIN,
1112 { 0x0018fa61, 0x0018fa61, 0x00199a65, 0x00199a65, 0x00199a65 } }, 1106 { 0x0018fa61, 0x00199a65, 0x00199a65 } },
1113 { AR5K_PHY_DESIRED_SIZE, 1107 { AR5K_PHY_DESIRED_SIZE,
1114 { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } }, 1108 { 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da } },
1115 { AR5K_PHY_SIG, 1109 { AR5K_PHY_SIG,
1116 { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } }, 1110 { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
1117 { AR5K_PHY_AGCCOARSE, 1111 { AR5K_PHY_AGCCOARSE,
1118 { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } }, 1112 { 0x3139605e, 0x3139605e, 0x3139605e } },
1119 { AR5K_PHY_WEAK_OFDM_LOW_THR, 1113 { AR5K_PHY_WEAK_OFDM_LOW_THR,
1120 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } }, 1114 { 0x050cb081, 0x050cb081, 0x050cb081 } },
1121 { AR5K_PHY_RX_DELAY, 1115 { AR5K_PHY_RX_DELAY,
1122 { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } }, 1116 { 0x000007d0, 0x0000044c, 0x00000898 } },
1123 { AR5K_PHY_FRAME_CTL_5211, 1117 { AR5K_PHY_FRAME_CTL_5211,
1124 { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } }, 1118 { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } },
1125 { AR5K_PHY_CCKTXCTL, 1119 { AR5K_PHY_CCKTXCTL,
1126 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 1120 { 0x00000000, 0x00000000, 0x00000000 } },
1127 { AR5K_PHY_CCK_CROSSCORR, 1121 { AR5K_PHY_CCK_CROSSCORR,
1128 { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } }, 1122 { 0xd6be6788, 0xd03e6788, 0xd03e6788 } },
1129 { AR5K_PHY_GAIN_2GHZ, 1123 { AR5K_PHY_GAIN_2GHZ,
1130 { 0x00000140, 0x00000140, 0x0052c140, 0x0052c140, 0x0052c140 } }, 1124 { 0x00000140, 0x0052c140, 0x0052c140 } },
1131 { AR5K_PHY_CCK_RX_CTL_4, 1125 { AR5K_PHY_CCK_RX_CTL_4,
1132 { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } }, 1126 { 0x1883800a, 0x1863800a, 0x1883800a } },
1133 { 0xa324, 1127 { 0xa324,
1134 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, 1128 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
1135 { 0xa328, 1129 { 0xa328,
1136 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, 1130 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
1137 { 0xa32c, 1131 { 0xa32c,
1138 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, 1132 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
1139 { 0xa330, 1133 { 0xa330,
1140 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, 1134 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
1141 { 0xa334, 1135 { 0xa334,
1142 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, 1136 { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
1143}; 1137};
1144 1138
1145static const struct ath5k_ini rf2425_ini_common_end[] = { 1139static const struct ath5k_ini rf2425_ini_common_end[] = {
@@ -1368,15 +1362,15 @@ static const struct ath5k_ini rf5112_ini_bbgain[] = {
1368 * Write initial register dump 1362 * Write initial register dump
1369 */ 1363 */
1370static void ath5k_hw_ini_registers(struct ath5k_hw *ah, unsigned int size, 1364static void ath5k_hw_ini_registers(struct ath5k_hw *ah, unsigned int size,
1371 const struct ath5k_ini *ini_regs, bool change_channel) 1365 const struct ath5k_ini *ini_regs, bool skip_pcu)
1372{ 1366{
1373 unsigned int i; 1367 unsigned int i;
1374 1368
1375 /* Write initial registers */ 1369 /* Write initial registers */
1376 for (i = 0; i < size; i++) { 1370 for (i = 0; i < size; i++) {
1377 /* On channel change there is 1371 /* Skip PCU registers if
1378 * no need to mess with PCU */ 1372 * requested */
1379 if (change_channel && 1373 if (skip_pcu &&
1380 ini_regs[i].ini_register >= AR5K_PCU_MIN && 1374 ini_regs[i].ini_register >= AR5K_PCU_MIN &&
1381 ini_regs[i].ini_register <= AR5K_PCU_MAX) 1375 ini_regs[i].ini_register <= AR5K_PCU_MAX)
1382 continue; 1376 continue;
@@ -1409,7 +1403,7 @@ static void ath5k_hw_ini_mode_registers(struct ath5k_hw *ah,
1409 1403
1410} 1404}
1411 1405
1412int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel) 1406int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool skip_pcu)
1413{ 1407{
1414 /* 1408 /*
1415 * Write initial register settings 1409 * Write initial register settings
@@ -1427,7 +1421,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
1427 * Write initial settings common for all modes 1421 * Write initial settings common for all modes
1428 */ 1422 */
1429 ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start), 1423 ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start),
1430 ar5212_ini_common_start, change_channel); 1424 ar5212_ini_common_start, skip_pcu);
1431 1425
1432 /* Second set of mode-specific settings */ 1426 /* Second set of mode-specific settings */
1433 switch (ah->ah_radio) { 1427 switch (ah->ah_radio) {
@@ -1439,12 +1433,12 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
1439 1433
1440 ath5k_hw_ini_registers(ah, 1434 ath5k_hw_ini_registers(ah,
1441 ARRAY_SIZE(rf5111_ini_common_end), 1435 ARRAY_SIZE(rf5111_ini_common_end),
1442 rf5111_ini_common_end, change_channel); 1436 rf5111_ini_common_end, skip_pcu);
1443 1437
1444 /* Baseband gain table */ 1438 /* Baseband gain table */
1445 ath5k_hw_ini_registers(ah, 1439 ath5k_hw_ini_registers(ah,
1446 ARRAY_SIZE(rf5111_ini_bbgain), 1440 ARRAY_SIZE(rf5111_ini_bbgain),
1447 rf5111_ini_bbgain, change_channel); 1441 rf5111_ini_bbgain, skip_pcu);
1448 1442
1449 break; 1443 break;
1450 case AR5K_RF5112: 1444 case AR5K_RF5112:
@@ -1455,11 +1449,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
1455 1449
1456 ath5k_hw_ini_registers(ah, 1450 ath5k_hw_ini_registers(ah,
1457 ARRAY_SIZE(rf5112_ini_common_end), 1451 ARRAY_SIZE(rf5112_ini_common_end),
1458 rf5112_ini_common_end, change_channel); 1452 rf5112_ini_common_end, skip_pcu);
1459 1453
1460 ath5k_hw_ini_registers(ah, 1454 ath5k_hw_ini_registers(ah,
1461 ARRAY_SIZE(rf5112_ini_bbgain), 1455 ARRAY_SIZE(rf5112_ini_bbgain),
1462 rf5112_ini_bbgain, change_channel); 1456 rf5112_ini_bbgain, skip_pcu);
1463 1457
1464 break; 1458 break;
1465 case AR5K_RF5413: 1459 case AR5K_RF5413:
@@ -1470,11 +1464,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
1470 1464
1471 ath5k_hw_ini_registers(ah, 1465 ath5k_hw_ini_registers(ah,
1472 ARRAY_SIZE(rf5413_ini_common_end), 1466 ARRAY_SIZE(rf5413_ini_common_end),
1473 rf5413_ini_common_end, change_channel); 1467 rf5413_ini_common_end, skip_pcu);
1474 1468
1475 ath5k_hw_ini_registers(ah, 1469 ath5k_hw_ini_registers(ah,
1476 ARRAY_SIZE(rf5112_ini_bbgain), 1470 ARRAY_SIZE(rf5112_ini_bbgain),
1477 rf5112_ini_bbgain, change_channel); 1471 rf5112_ini_bbgain, skip_pcu);
1478 1472
1479 break; 1473 break;
1480 case AR5K_RF2316: 1474 case AR5K_RF2316:
@@ -1486,7 +1480,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
1486 1480
1487 ath5k_hw_ini_registers(ah, 1481 ath5k_hw_ini_registers(ah,
1488 ARRAY_SIZE(rf2413_ini_common_end), 1482 ARRAY_SIZE(rf2413_ini_common_end),
1489 rf2413_ini_common_end, change_channel); 1483 rf2413_ini_common_end, skip_pcu);
1490 1484
1491 /* Override settings from rf2413_ini_common_end */ 1485 /* Override settings from rf2413_ini_common_end */
1492 if (ah->ah_radio == AR5K_RF2316) { 1486 if (ah->ah_radio == AR5K_RF2316) {
@@ -1498,9 +1492,32 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
1498 1492
1499 ath5k_hw_ini_registers(ah, 1493 ath5k_hw_ini_registers(ah,
1500 ARRAY_SIZE(rf5112_ini_bbgain), 1494 ARRAY_SIZE(rf5112_ini_bbgain),
1501 rf5112_ini_bbgain, change_channel); 1495 rf5112_ini_bbgain, skip_pcu);
1502 break; 1496 break;
1503 case AR5K_RF2317: 1497 case AR5K_RF2317:
1498
1499 ath5k_hw_ini_mode_registers(ah,
1500 ARRAY_SIZE(rf2413_ini_mode_end),
1501 rf2413_ini_mode_end, mode);
1502
1503 ath5k_hw_ini_registers(ah,
1504 ARRAY_SIZE(rf2425_ini_common_end),
1505 rf2425_ini_common_end, skip_pcu);
1506
1507 /* Override settings from rf2413_ini_mode_end */
1508 ath5k_hw_reg_write(ah, 0x00180a65, AR5K_PHY_GAIN);
1509
1510 /* Override settings from rf2413_ini_common_end */
1511 ath5k_hw_reg_write(ah, 0x00004000, AR5K_PHY_AGC);
1512 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TPC_RG5,
1513 AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP, 0xa);
1514 ath5k_hw_reg_write(ah, 0x800000a8, 0x8140);
1515 ath5k_hw_reg_write(ah, 0x000000ff, 0x9958);
1516
1517 ath5k_hw_ini_registers(ah,
1518 ARRAY_SIZE(rf5112_ini_bbgain),
1519 rf5112_ini_bbgain, skip_pcu);
1520 break;
1504 case AR5K_RF2425: 1521 case AR5K_RF2425:
1505 1522
1506 ath5k_hw_ini_mode_registers(ah, 1523 ath5k_hw_ini_mode_registers(ah,
@@ -1509,11 +1526,11 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
1509 1526
1510 ath5k_hw_ini_registers(ah, 1527 ath5k_hw_ini_registers(ah,
1511 ARRAY_SIZE(rf2425_ini_common_end), 1528 ARRAY_SIZE(rf2425_ini_common_end),
1512 rf2425_ini_common_end, change_channel); 1529 rf2425_ini_common_end, skip_pcu);
1513 1530
1514 ath5k_hw_ini_registers(ah, 1531 ath5k_hw_ini_registers(ah,
1515 ARRAY_SIZE(rf5112_ini_bbgain), 1532 ARRAY_SIZE(rf5112_ini_bbgain),
1516 rf5112_ini_bbgain, change_channel); 1533 rf5112_ini_bbgain, skip_pcu);
1517 break; 1534 break;
1518 default: 1535 default:
1519 return -EINVAL; 1536 return -EINVAL;
@@ -1538,17 +1555,17 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
1538 * Write initial settings common for all modes 1555 * Write initial settings common for all modes
1539 */ 1556 */
1540 ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5211_ini), 1557 ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5211_ini),
1541 ar5211_ini, change_channel); 1558 ar5211_ini, skip_pcu);
1542 1559
1543 /* AR5211 only comes with 5111 */ 1560 /* AR5211 only comes with 5111 */
1544 1561
1545 /* Baseband gain table */ 1562 /* Baseband gain table */
1546 ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain), 1563 ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain),
1547 rf5111_ini_bbgain, change_channel); 1564 rf5111_ini_bbgain, skip_pcu);
1548 /* For AR5210 (for mode settings check out ath5k_hw_reset_tx_queue) */ 1565 /* For AR5210 (for mode settings check out ath5k_hw_reset_tx_queue) */
1549 } else if (ah->ah_version == AR5K_AR5210) { 1566 } else if (ah->ah_version == AR5K_AR5210) {
1550 ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5210_ini), 1567 ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5210_ini),
1551 ar5210_ini, change_channel); 1568 ar5210_ini, skip_pcu);
1552 } 1569 }
1553 1570
1554 return 0; 1571 return 0;
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index 67aa52e9bf94..576edf2965dc 100644
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -133,7 +133,7 @@ ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
133 led->led_dev.default_trigger = trigger; 133 led->led_dev.default_trigger = trigger;
134 led->led_dev.brightness_set = ath5k_led_brightness_set; 134 led->led_dev.brightness_set = ath5k_led_brightness_set;
135 135
136 err = led_classdev_register(&sc->pdev->dev, &led->led_dev); 136 err = led_classdev_register(sc->dev, &led->led_dev);
137 if (err) { 137 if (err) {
138 ATH5K_WARN(sc, "could not register LED %s\n", name); 138 ATH5K_WARN(sc, "could not register LED %s\n", name);
139 led->sc = NULL; 139 led->sc = NULL;
@@ -161,11 +161,20 @@ int ath5k_init_leds(struct ath5k_softc *sc)
161{ 161{
162 int ret = 0; 162 int ret = 0;
163 struct ieee80211_hw *hw = sc->hw; 163 struct ieee80211_hw *hw = sc->hw;
164#ifndef CONFIG_ATHEROS_AR231X
164 struct pci_dev *pdev = sc->pdev; 165 struct pci_dev *pdev = sc->pdev;
166#endif
165 char name[ATH5K_LED_MAX_NAME_LEN + 1]; 167 char name[ATH5K_LED_MAX_NAME_LEN + 1];
166 const struct pci_device_id *match; 168 const struct pci_device_id *match;
167 169
170 if (!sc->pdev)
171 return 0;
172
173#ifdef CONFIG_ATHEROS_AR231X
174 match = NULL;
175#else
168 match = pci_match_id(&ath5k_led_devices[0], pdev); 176 match = pci_match_id(&ath5k_led_devices[0], pdev);
177#endif
169 if (match) { 178 if (match) {
170 __set_bit(ATH_STAT_LEDSOFT, sc->status); 179 __set_bit(ATH_STAT_LEDSOFT, sc->status);
171 sc->led_pin = ATH_PIN(match->driver_data); 180 sc->led_pin = ATH_PIN(match->driver_data);
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
new file mode 100644
index 000000000000..807bd6440169
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -0,0 +1,833 @@
1/*-
2 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
3 * Copyright (c) 2004-2005 Atheros Communications, Inc.
4 * Copyright (c) 2006 Devicescape Software, Inc.
5 * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
6 * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
7 * Copyright (c) 2010 Bruno Randolf <br1@einfach.org>
8 *
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
19 * redistribution must be conditioned upon including a substantially
20 * similar Disclaimer requirement for further binary redistribution.
21 * 3. Neither the names of the above-listed copyright holders nor the names
22 * of any contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * Alternatively, this software may be distributed under the terms of the
26 * GNU General Public License ("GPL") version 2 as published by the Free
27 * Software Foundation.
28 *
29 * NO WARRANTY
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
33 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
34 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
35 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
38 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
40 * THE POSSIBILITY OF SUCH DAMAGES.
41 *
42 */
43
44#include <asm/unaligned.h>
45
46#include "base.h"
47#include "reg.h"
48
49extern int ath5k_modparam_nohwcrypt;
50
51/********************\
52* Mac80211 functions *
53\********************/
54
55static void
56ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
57{
58 struct ath5k_softc *sc = hw->priv;
59 u16 qnum = skb_get_queue_mapping(skb);
60
61 if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) {
62 dev_kfree_skb_any(skb);
63 return;
64 }
65
66 ath5k_tx_queue(hw, skb, &sc->txqs[qnum]);
67}
68
69
70static int
71ath5k_start(struct ieee80211_hw *hw)
72{
73 return ath5k_init_hw(hw->priv);
74}
75
76
77static void
78ath5k_stop(struct ieee80211_hw *hw)
79{
80 ath5k_stop_hw(hw->priv);
81}
82
83
84static int
85ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
86{
87 struct ath5k_softc *sc = hw->priv;
88 int ret;
89 struct ath5k_vif *avf = (void *)vif->drv_priv;
90
91 mutex_lock(&sc->lock);
92
93 if ((vif->type == NL80211_IFTYPE_AP ||
94 vif->type == NL80211_IFTYPE_ADHOC)
95 && (sc->num_ap_vifs + sc->num_adhoc_vifs) >= ATH_BCBUF) {
96 ret = -ELNRNG;
97 goto end;
98 }
99
100 /* Don't allow other interfaces if one ad-hoc is configured.
101 * TODO: Fix the problems with ad-hoc and multiple other interfaces.
102 * We would need to operate the HW in ad-hoc mode to allow TSF updates
103 * for the IBSS, but this breaks with additional AP or STA interfaces
104 * at the moment. */
105 if (sc->num_adhoc_vifs ||
106 (sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
107 ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n");
108 ret = -ELNRNG;
109 goto end;
110 }
111
112 switch (vif->type) {
113 case NL80211_IFTYPE_AP:
114 case NL80211_IFTYPE_STATION:
115 case NL80211_IFTYPE_ADHOC:
116 case NL80211_IFTYPE_MESH_POINT:
117 avf->opmode = vif->type;
118 break;
119 default:
120 ret = -EOPNOTSUPP;
121 goto end;
122 }
123
124 sc->nvifs++;
125 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode);
126
127 /* Assign the vap/adhoc to a beacon xmit slot. */
128 if ((avf->opmode == NL80211_IFTYPE_AP) ||
129 (avf->opmode == NL80211_IFTYPE_ADHOC) ||
130 (avf->opmode == NL80211_IFTYPE_MESH_POINT)) {
131 int slot;
132
133 WARN_ON(list_empty(&sc->bcbuf));
134 avf->bbuf = list_first_entry(&sc->bcbuf, struct ath5k_buf,
135 list);
136 list_del(&avf->bbuf->list);
137
138 avf->bslot = 0;
139 for (slot = 0; slot < ATH_BCBUF; slot++) {
140 if (!sc->bslot[slot]) {
141 avf->bslot = slot;
142 break;
143 }
144 }
145 BUG_ON(sc->bslot[avf->bslot] != NULL);
146 sc->bslot[avf->bslot] = vif;
147 if (avf->opmode == NL80211_IFTYPE_AP)
148 sc->num_ap_vifs++;
149 else if (avf->opmode == NL80211_IFTYPE_ADHOC)
150 sc->num_adhoc_vifs++;
151 }
152
153 /* Any MAC address is fine, all others are included through the
154 * filter.
155 */
156 memcpy(&sc->lladdr, vif->addr, ETH_ALEN);
157 ath5k_hw_set_lladdr(sc->ah, vif->addr);
158
159 memcpy(&avf->lladdr, vif->addr, ETH_ALEN);
160
161 ath5k_update_bssid_mask_and_opmode(sc, vif);
162 ret = 0;
163end:
164 mutex_unlock(&sc->lock);
165 return ret;
166}
167
168
169static void
170ath5k_remove_interface(struct ieee80211_hw *hw,
171 struct ieee80211_vif *vif)
172{
173 struct ath5k_softc *sc = hw->priv;
174 struct ath5k_vif *avf = (void *)vif->drv_priv;
175 unsigned int i;
176
177 mutex_lock(&sc->lock);
178 sc->nvifs--;
179
180 if (avf->bbuf) {
181 ath5k_txbuf_free_skb(sc, avf->bbuf);
182 list_add_tail(&avf->bbuf->list, &sc->bcbuf);
183 for (i = 0; i < ATH_BCBUF; i++) {
184 if (sc->bslot[i] == vif) {
185 sc->bslot[i] = NULL;
186 break;
187 }
188 }
189 avf->bbuf = NULL;
190 }
191 if (avf->opmode == NL80211_IFTYPE_AP)
192 sc->num_ap_vifs--;
193 else if (avf->opmode == NL80211_IFTYPE_ADHOC)
194 sc->num_adhoc_vifs--;
195
196 ath5k_update_bssid_mask_and_opmode(sc, NULL);
197 mutex_unlock(&sc->lock);
198}
199
200
201/*
202 * TODO: Phy disable/diversity etc
203 */
204static int
205ath5k_config(struct ieee80211_hw *hw, u32 changed)
206{
207 struct ath5k_softc *sc = hw->priv;
208 struct ath5k_hw *ah = sc->ah;
209 struct ieee80211_conf *conf = &hw->conf;
210 int ret = 0;
211 int i;
212
213 mutex_lock(&sc->lock);
214
215 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
216 ret = ath5k_chan_set(sc, conf->channel);
217 if (ret < 0)
218 goto unlock;
219 }
220
221 if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
222 (sc->power_level != conf->power_level)) {
223 sc->power_level = conf->power_level;
224
225 /* Half dB steps */
226 ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2));
227 }
228
229 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
230 ah->ah_retry_long = conf->long_frame_max_tx_count;
231 ah->ah_retry_short = conf->short_frame_max_tx_count;
232
233 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++)
234 ath5k_hw_set_tx_retry_limits(ah, i);
235 }
236
237 /* TODO:
238 * 1) Move this on config_interface and handle each case
239 * separately eg. when we have only one STA vif, use
240 * AR5K_ANTMODE_SINGLE_AP
241 *
242 * 2) Allow the user to change antenna mode eg. when only
243 * one antenna is present
244 *
245 * 3) Allow the user to set default/tx antenna when possible
246 *
247 * 4) Default mode should handle 90% of the cases, together
248 * with fixed a/b and single AP modes we should be able to
249 * handle 99%. Sectored modes are extreme cases and i still
250 * haven't found a usage for them. If we decide to support them,
251 * then we must allow the user to set how many tx antennas we
252 * have available
253 */
254 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
255
256unlock:
257 mutex_unlock(&sc->lock);
258 return ret;
259}
260
261
262static void
263ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
264 struct ieee80211_bss_conf *bss_conf, u32 changes)
265{
266 struct ath5k_vif *avf = (void *)vif->drv_priv;
267 struct ath5k_softc *sc = hw->priv;
268 struct ath5k_hw *ah = sc->ah;
269 struct ath_common *common = ath5k_hw_common(ah);
270 unsigned long flags;
271
272 mutex_lock(&sc->lock);
273
274 if (changes & BSS_CHANGED_BSSID) {
275 /* Cache for later use during resets */
276 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
277 common->curaid = 0;
278 ath5k_hw_set_bssid(ah);
279 mmiowb();
280 }
281
282 if (changes & BSS_CHANGED_BEACON_INT)
283 sc->bintval = bss_conf->beacon_int;
284
285 if (changes & BSS_CHANGED_ERP_SLOT) {
286 int slot_time;
287
288 ah->ah_short_slot = bss_conf->use_short_slot;
289 slot_time = ath5k_hw_get_default_slottime(ah) +
290 3 * ah->ah_coverage_class;
291 ath5k_hw_set_ifs_intervals(ah, slot_time);
292 }
293
294 if (changes & BSS_CHANGED_ASSOC) {
295 avf->assoc = bss_conf->assoc;
296 if (bss_conf->assoc)
297 sc->assoc = bss_conf->assoc;
298 else
299 sc->assoc = ath_any_vif_assoc(sc);
300
301 if (sc->opmode == NL80211_IFTYPE_STATION)
302 set_beacon_filter(hw, sc->assoc);
303 ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
304 AR5K_LED_ASSOC : AR5K_LED_INIT);
305 if (bss_conf->assoc) {
306 ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
307 "Bss Info ASSOC %d, bssid: %pM\n",
308 bss_conf->aid, common->curbssid);
309 common->curaid = bss_conf->aid;
310 ath5k_hw_set_bssid(ah);
311 /* Once ANI is available you would start it here */
312 }
313 }
314
315 if (changes & BSS_CHANGED_BEACON) {
316 spin_lock_irqsave(&sc->block, flags);
317 ath5k_beacon_update(hw, vif);
318 spin_unlock_irqrestore(&sc->block, flags);
319 }
320
321 if (changes & BSS_CHANGED_BEACON_ENABLED)
322 sc->enable_beacon = bss_conf->enable_beacon;
323
324 if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED |
325 BSS_CHANGED_BEACON_INT))
326 ath5k_beacon_config(sc);
327
328 mutex_unlock(&sc->lock);
329}
330
331
332static u64
333ath5k_prepare_multicast(struct ieee80211_hw *hw,
334 struct netdev_hw_addr_list *mc_list)
335{
336 u32 mfilt[2], val;
337 u8 pos;
338 struct netdev_hw_addr *ha;
339
340 mfilt[0] = 0;
341 mfilt[1] = 1;
342
343 netdev_hw_addr_list_for_each(ha, mc_list) {
344 /* calculate XOR of eight 6-bit values */
345 val = get_unaligned_le32(ha->addr + 0);
346 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
347 val = get_unaligned_le32(ha->addr + 3);
348 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
349 pos &= 0x3f;
350 mfilt[pos / 32] |= (1 << (pos % 32));
351 /* XXX: we might be able to just do this instead,
352 * but not sure, needs testing, if we do use this we'd
353 * neet to inform below to not reset the mcast */
354 /* ath5k_hw_set_mcast_filterindex(ah,
355 * ha->addr[5]); */
356 }
357
358 return ((u64)(mfilt[1]) << 32) | mfilt[0];
359}
360
361
362/*
363 * o always accept unicast, broadcast, and multicast traffic
364 * o multicast traffic for all BSSIDs will be enabled if mac80211
365 * says it should be
366 * o maintain current state of phy ofdm or phy cck error reception.
367 * If the hardware detects any of these type of errors then
368 * ath5k_hw_get_rx_filter() will pass to us the respective
369 * hardware filters to be able to receive these type of frames.
370 * o probe request frames are accepted only when operating in
371 * hostap, adhoc, or monitor modes
372 * o enable promiscuous mode according to the interface state
373 * o accept beacons:
374 * - when operating in adhoc mode so the 802.11 layer creates
375 * node table entries for peers,
376 * - when operating in station mode for collecting rssi data when
377 * the station is otherwise quiet, or
378 * - when scanning
379 */
380static void
381ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
382 unsigned int *new_flags, u64 multicast)
383{
384#define SUPPORTED_FIF_FLAGS \
385 (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \
386 FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
387 FIF_BCN_PRBRESP_PROMISC)
388
389 struct ath5k_softc *sc = hw->priv;
390 struct ath5k_hw *ah = sc->ah;
391 u32 mfilt[2], rfilt;
392 struct ath5k_vif_iter_data iter_data; /* to count STA interfaces */
393
394 mutex_lock(&sc->lock);
395
396 mfilt[0] = multicast;
397 mfilt[1] = multicast >> 32;
398
399 /* Only deal with supported flags */
400 changed_flags &= SUPPORTED_FIF_FLAGS;
401 *new_flags &= SUPPORTED_FIF_FLAGS;
402
403 /* If HW detects any phy or radar errors, leave those filters on.
404 * Also, always enable Unicast, Broadcasts and Multicast
405 * XXX: move unicast, bssid broadcasts and multicast to mac80211 */
406 rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) |
407 (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST |
408 AR5K_RX_FILTER_MCAST);
409
410 if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) {
411 if (*new_flags & FIF_PROMISC_IN_BSS)
412 __set_bit(ATH_STAT_PROMISC, sc->status);
413 else
414 __clear_bit(ATH_STAT_PROMISC, sc->status);
415 }
416
417 if (test_bit(ATH_STAT_PROMISC, sc->status))
418 rfilt |= AR5K_RX_FILTER_PROM;
419
420 /* Note, AR5K_RX_FILTER_MCAST is already enabled */
421 if (*new_flags & FIF_ALLMULTI) {
422 mfilt[0] = ~0;
423 mfilt[1] = ~0;
424 }
425
426 /* This is the best we can do */
427 if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL))
428 rfilt |= AR5K_RX_FILTER_PHYERR;
429
430 /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
431 * and probes for any BSSID */
432 if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (sc->nvifs > 1))
433 rfilt |= AR5K_RX_FILTER_BEACON;
434
435 /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
436 * set we should only pass on control frames for this
437 * station. This needs testing. I believe right now this
438 * enables *all* control frames, which is OK.. but
439 * but we should see if we can improve on granularity */
440 if (*new_flags & FIF_CONTROL)
441 rfilt |= AR5K_RX_FILTER_CONTROL;
442
443 /* Additional settings per mode -- this is per ath5k */
444
445 /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */
446
447 switch (sc->opmode) {
448 case NL80211_IFTYPE_MESH_POINT:
449 rfilt |= AR5K_RX_FILTER_CONTROL |
450 AR5K_RX_FILTER_BEACON |
451 AR5K_RX_FILTER_PROBEREQ |
452 AR5K_RX_FILTER_PROM;
453 break;
454 case NL80211_IFTYPE_AP:
455 case NL80211_IFTYPE_ADHOC:
456 rfilt |= AR5K_RX_FILTER_PROBEREQ |
457 AR5K_RX_FILTER_BEACON;
458 break;
459 case NL80211_IFTYPE_STATION:
460 if (sc->assoc)
461 rfilt |= AR5K_RX_FILTER_BEACON;
462 default:
463 break;
464 }
465
466 iter_data.hw_macaddr = NULL;
467 iter_data.n_stas = 0;
468 iter_data.need_set_hw_addr = false;
469 ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter,
470 &iter_data);
471
472 /* Set up RX Filter */
473 if (iter_data.n_stas > 1) {
474 /* If you have multiple STA interfaces connected to
475 * different APs, ARPs are not received (most of the time?)
476 * Enabling PROMISC appears to fix that probem.
477 */
478 rfilt |= AR5K_RX_FILTER_PROM;
479 }
480
481 /* Set filters */
482 ath5k_hw_set_rx_filter(ah, rfilt);
483
484 /* Set multicast bits */
485 ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
486 /* Set the cached hw filter flags, this will later actually
487 * be set in HW */
488 sc->filter_flags = rfilt;
489
490 mutex_unlock(&sc->lock);
491}
492
493
494static int
495ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
496 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
497 struct ieee80211_key_conf *key)
498{
499 struct ath5k_softc *sc = hw->priv;
500 struct ath5k_hw *ah = sc->ah;
501 struct ath_common *common = ath5k_hw_common(ah);
502 int ret = 0;
503
504 if (ath5k_modparam_nohwcrypt)
505 return -EOPNOTSUPP;
506
507 switch (key->cipher) {
508 case WLAN_CIPHER_SUITE_WEP40:
509 case WLAN_CIPHER_SUITE_WEP104:
510 case WLAN_CIPHER_SUITE_TKIP:
511 break;
512 case WLAN_CIPHER_SUITE_CCMP:
513 if (common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)
514 break;
515 return -EOPNOTSUPP;
516 default:
517 WARN_ON(1);
518 return -EINVAL;
519 }
520
521 mutex_lock(&sc->lock);
522
523 switch (cmd) {
524 case SET_KEY:
525 ret = ath_key_config(common, vif, sta, key);
526 if (ret >= 0) {
527 key->hw_key_idx = ret;
528 /* push IV and Michael MIC generation to stack */
529 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
530 if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
531 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
532 if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
533 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
534 ret = 0;
535 }
536 break;
537 case DISABLE_KEY:
538 ath_key_delete(common, key);
539 break;
540 default:
541 ret = -EINVAL;
542 }
543
544 mmiowb();
545 mutex_unlock(&sc->lock);
546 return ret;
547}
548
549
550static void
551ath5k_sw_scan_start(struct ieee80211_hw *hw)
552{
553 struct ath5k_softc *sc = hw->priv;
554 if (!sc->assoc)
555 ath5k_hw_set_ledstate(sc->ah, AR5K_LED_SCAN);
556}
557
558
559static void
560ath5k_sw_scan_complete(struct ieee80211_hw *hw)
561{
562 struct ath5k_softc *sc = hw->priv;
563 ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
564 AR5K_LED_ASSOC : AR5K_LED_INIT);
565}
566
567
568static int
569ath5k_get_stats(struct ieee80211_hw *hw,
570 struct ieee80211_low_level_stats *stats)
571{
572 struct ath5k_softc *sc = hw->priv;
573
574 /* Force update */
575 ath5k_hw_update_mib_counters(sc->ah);
576
577 stats->dot11ACKFailureCount = sc->stats.ack_fail;
578 stats->dot11RTSFailureCount = sc->stats.rts_fail;
579 stats->dot11RTSSuccessCount = sc->stats.rts_ok;
580 stats->dot11FCSErrorCount = sc->stats.fcs_error;
581
582 return 0;
583}
584
585
586static int
587ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue,
588 const struct ieee80211_tx_queue_params *params)
589{
590 struct ath5k_softc *sc = hw->priv;
591 struct ath5k_hw *ah = sc->ah;
592 struct ath5k_txq_info qi;
593 int ret = 0;
594
595 if (queue >= ah->ah_capabilities.cap_queues.q_tx_num)
596 return 0;
597
598 mutex_lock(&sc->lock);
599
600 ath5k_hw_get_tx_queueprops(ah, queue, &qi);
601
602 qi.tqi_aifs = params->aifs;
603 qi.tqi_cw_min = params->cw_min;
604 qi.tqi_cw_max = params->cw_max;
605 qi.tqi_burst_time = params->txop;
606
607 ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
608 "Configure tx [queue %d], "
609 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
610 queue, params->aifs, params->cw_min,
611 params->cw_max, params->txop);
612
613 if (ath5k_hw_set_tx_queueprops(ah, queue, &qi)) {
614 ATH5K_ERR(sc,
615 "Unable to update hardware queue %u!\n", queue);
616 ret = -EIO;
617 } else
618 ath5k_hw_reset_tx_queue(ah, queue);
619
620 mutex_unlock(&sc->lock);
621
622 return ret;
623}
624
625
626static u64
627ath5k_get_tsf(struct ieee80211_hw *hw)
628{
629 struct ath5k_softc *sc = hw->priv;
630
631 return ath5k_hw_get_tsf64(sc->ah);
632}
633
634
635static void
636ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
637{
638 struct ath5k_softc *sc = hw->priv;
639
640 ath5k_hw_set_tsf64(sc->ah, tsf);
641}
642
643
644static void
645ath5k_reset_tsf(struct ieee80211_hw *hw)
646{
647 struct ath5k_softc *sc = hw->priv;
648
649 /*
650 * in IBSS mode we need to update the beacon timers too.
651 * this will also reset the TSF if we call it with 0
652 */
653 if (sc->opmode == NL80211_IFTYPE_ADHOC)
654 ath5k_beacon_update_timers(sc, 0);
655 else
656 ath5k_hw_reset_tsf(sc->ah);
657}
658
659
660static int
661ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)
662{
663 struct ath5k_softc *sc = hw->priv;
664 struct ieee80211_conf *conf = &hw->conf;
665 struct ath_common *common = ath5k_hw_common(sc->ah);
666 struct ath_cycle_counters *cc = &common->cc_survey;
667 unsigned int div = common->clockrate * 1000;
668
669 if (idx != 0)
670 return -ENOENT;
671
672 spin_lock_bh(&common->cc_lock);
673 ath_hw_cycle_counters_update(common);
674 if (cc->cycles > 0) {
675 sc->survey.channel_time += cc->cycles / div;
676 sc->survey.channel_time_busy += cc->rx_busy / div;
677 sc->survey.channel_time_rx += cc->rx_frame / div;
678 sc->survey.channel_time_tx += cc->tx_frame / div;
679 }
680 memset(cc, 0, sizeof(*cc));
681 spin_unlock_bh(&common->cc_lock);
682
683 memcpy(survey, &sc->survey, sizeof(*survey));
684
685 survey->channel = conf->channel;
686 survey->noise = sc->ah->ah_noise_floor;
687 survey->filled = SURVEY_INFO_NOISE_DBM |
688 SURVEY_INFO_CHANNEL_TIME |
689 SURVEY_INFO_CHANNEL_TIME_BUSY |
690 SURVEY_INFO_CHANNEL_TIME_RX |
691 SURVEY_INFO_CHANNEL_TIME_TX;
692
693 return 0;
694}
695
696
697/**
698 * ath5k_set_coverage_class - Set IEEE 802.11 coverage class
699 *
700 * @hw: struct ieee80211_hw pointer
701 * @coverage_class: IEEE 802.11 coverage class number
702 *
703 * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given
704 * coverage class. The values are persistent, they are restored after device
705 * reset.
706 */
707static void
708ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
709{
710 struct ath5k_softc *sc = hw->priv;
711
712 mutex_lock(&sc->lock);
713 ath5k_hw_set_coverage_class(sc->ah, coverage_class);
714 mutex_unlock(&sc->lock);
715}
716
717
718static int
719ath5k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
720{
721 struct ath5k_softc *sc = hw->priv;
722
723 if (tx_ant == 1 && rx_ant == 1)
724 ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_A);
725 else if (tx_ant == 2 && rx_ant == 2)
726 ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_B);
727 else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3)
728 ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_DEFAULT);
729 else
730 return -EINVAL;
731 return 0;
732}
733
734
735static int
736ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
737{
738 struct ath5k_softc *sc = hw->priv;
739
740 switch (sc->ah->ah_ant_mode) {
741 case AR5K_ANTMODE_FIXED_A:
742 *tx_ant = 1; *rx_ant = 1; break;
743 case AR5K_ANTMODE_FIXED_B:
744 *tx_ant = 2; *rx_ant = 2; break;
745 case AR5K_ANTMODE_DEFAULT:
746 *tx_ant = 3; *rx_ant = 3; break;
747 }
748 return 0;
749}
750
751
752static void ath5k_get_ringparam(struct ieee80211_hw *hw,
753 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
754{
755 struct ath5k_softc *sc = hw->priv;
756
757 *tx = sc->txqs[AR5K_TX_QUEUE_ID_DATA_MIN].txq_max;
758
759 *tx_max = ATH5K_TXQ_LEN_MAX;
760 *rx = *rx_max = ATH_RXBUF;
761}
762
763
764static int ath5k_set_ringparam(struct ieee80211_hw *hw, u32 tx, u32 rx)
765{
766 struct ath5k_softc *sc = hw->priv;
767 u16 qnum;
768
769 /* only support setting tx ring size for now */
770 if (rx != ATH_RXBUF)
771 return -EINVAL;
772
773 /* restrict tx ring size min/max */
774 if (!tx || tx > ATH5K_TXQ_LEN_MAX)
775 return -EINVAL;
776
777 for (qnum = 0; qnum < ARRAY_SIZE(sc->txqs); qnum++) {
778 if (!sc->txqs[qnum].setup)
779 continue;
780 if (sc->txqs[qnum].qnum < AR5K_TX_QUEUE_ID_DATA_MIN ||
781 sc->txqs[qnum].qnum > AR5K_TX_QUEUE_ID_DATA_MAX)
782 continue;
783
784 sc->txqs[qnum].txq_max = tx;
785 if (sc->txqs[qnum].txq_len >= sc->txqs[qnum].txq_max)
786 ieee80211_stop_queue(hw, sc->txqs[qnum].qnum);
787 }
788
789 return 0;
790}
791
792
793const struct ieee80211_ops ath5k_hw_ops = {
794 .tx = ath5k_tx,
795 .start = ath5k_start,
796 .stop = ath5k_stop,
797 .add_interface = ath5k_add_interface,
798 /* .change_interface = not implemented */
799 .remove_interface = ath5k_remove_interface,
800 .config = ath5k_config,
801 .bss_info_changed = ath5k_bss_info_changed,
802 .prepare_multicast = ath5k_prepare_multicast,
803 .configure_filter = ath5k_configure_filter,
804 /* .set_tim = not implemented */
805 .set_key = ath5k_set_key,
806 /* .update_tkip_key = not implemented */
807 /* .hw_scan = not implemented */
808 .sw_scan_start = ath5k_sw_scan_start,
809 .sw_scan_complete = ath5k_sw_scan_complete,
810 .get_stats = ath5k_get_stats,
811 /* .get_tkip_seq = not implemented */
812 /* .set_frag_threshold = not implemented */
813 /* .set_rts_threshold = not implemented */
814 /* .sta_add = not implemented */
815 /* .sta_remove = not implemented */
816 /* .sta_notify = not implemented */
817 .conf_tx = ath5k_conf_tx,
818 .get_tsf = ath5k_get_tsf,
819 .set_tsf = ath5k_set_tsf,
820 .reset_tsf = ath5k_reset_tsf,
821 /* .tx_last_beacon = not implemented */
822 /* .ampdu_action = not needed */
823 .get_survey = ath5k_get_survey,
824 .set_coverage_class = ath5k_set_coverage_class,
825 /* .rfkill_poll = not implemented */
826 /* .flush = not implemented */
827 /* .channel_switch = not implemented */
828 /* .napi_poll = not implemented */
829 .set_antenna = ath5k_set_antenna,
830 .get_antenna = ath5k_get_antenna,
831 .set_ringparam = ath5k_set_ringparam,
832 .get_ringparam = ath5k_get_ringparam,
833};
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c
new file mode 100644
index 000000000000..f2c0c236392f
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/pci.c
@@ -0,0 +1,363 @@
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 <linux/pci-aspm.h>
20#include <linux/etherdevice.h>
21#include "../ath.h"
22#include "ath5k.h"
23#include "debug.h"
24#include "base.h"
25#include "reg.h"
26
27/* Known PCI ids */
28static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {
29 { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */
30 { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */
31 { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/
32 { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */
33 { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */
34 { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */
35 { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */
36 { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */
37 { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */
38 { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */
39 { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */
40 { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */
41 { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */
42 { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */
43 { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */
44 { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
45 { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
46 { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
47 { 0 }
48};
49MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
50
51/* return bus cachesize in 4B word units */
52static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz)
53{
54 struct ath5k_softc *sc = (struct ath5k_softc *) common->priv;
55 u8 u8tmp;
56
57 pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, &u8tmp);
58 *csz = (int)u8tmp;
59
60 /*
61 * This check was put in to avoid "unpleasant" consequences if
62 * the bootrom has not fully initialized all PCI devices.
63 * Sometimes the cache line size register is not set
64 */
65
66 if (*csz == 0)
67 *csz = L1_CACHE_BYTES >> 2; /* Use the default size */
68}
69
70/*
71 * Read from eeprom
72 */
73static bool
74ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data)
75{
76 struct ath5k_hw *ah = (struct ath5k_hw *) common->ah;
77 u32 status, timeout;
78
79 /*
80 * Initialize EEPROM access
81 */
82 if (ah->ah_version == AR5K_AR5210) {
83 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
84 (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
85 } else {
86 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
87 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
88 AR5K_EEPROM_CMD_READ);
89 }
90
91 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
92 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
93 if (status & AR5K_EEPROM_STAT_RDDONE) {
94 if (status & AR5K_EEPROM_STAT_RDERR)
95 return false;
96 *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
97 0xffff);
98 return true;
99 }
100 udelay(15);
101 }
102
103 return false;
104}
105
106int ath5k_hw_read_srev(struct ath5k_hw *ah)
107{
108 ah->ah_mac_srev = ath5k_hw_reg_read(ah, AR5K_SREV);
109 return 0;
110}
111
112/*
113 * Read the MAC address from eeprom or platform_data
114 */
115static int ath5k_pci_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
116{
117 u8 mac_d[ETH_ALEN] = {};
118 u32 total, offset;
119 u16 data;
120 int octet;
121
122 AR5K_EEPROM_READ(0x20, data);
123
124 for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
125 AR5K_EEPROM_READ(offset, data);
126
127 total += data;
128 mac_d[octet + 1] = data & 0xff;
129 mac_d[octet] = data >> 8;
130 octet += 2;
131 }
132
133 if (!total || total == 3 * 0xffff)
134 return -EINVAL;
135
136 memcpy(mac, mac_d, ETH_ALEN);
137
138 return 0;
139}
140
141
142/* Common ath_bus_opts structure */
143static const struct ath_bus_ops ath_pci_bus_ops = {
144 .ath_bus_type = ATH_PCI,
145 .read_cachesize = ath5k_pci_read_cachesize,
146 .eeprom_read = ath5k_pci_eeprom_read,
147 .eeprom_read_mac = ath5k_pci_eeprom_read_mac,
148};
149
150/********************\
151* PCI Initialization *
152\********************/
153
154static int __devinit
155ath5k_pci_probe(struct pci_dev *pdev,
156 const struct pci_device_id *id)
157{
158 void __iomem *mem;
159 struct ath5k_softc *sc;
160 struct ieee80211_hw *hw;
161 int ret;
162 u8 csz;
163
164 /*
165 * L0s needs to be disabled on all ath5k cards.
166 *
167 * For distributions shipping with CONFIG_PCIEASPM (this will be enabled
168 * by default in the future in 2.6.36) this will also mean both L1 and
169 * L0s will be disabled when a pre 1.1 PCIe device is detected. We do
170 * know L1 works correctly even for all ath5k pre 1.1 PCIe devices
171 * though but cannot currently undue the effect of a blacklist, for
172 * details you can read pcie_aspm_sanity_check() and see how it adjusts
173 * the device link capability.
174 *
175 * It may be possible in the future to implement some PCI API to allow
176 * drivers to override blacklists for pre 1.1 PCIe but for now it is
177 * best to accept that both L0s and L1 will be disabled completely for
178 * distributions shipping with CONFIG_PCIEASPM rather than having this
179 * issue present. Motivation for adding this new API will be to help
180 * with power consumption for some of these devices.
181 */
182 pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
183
184 ret = pci_enable_device(pdev);
185 if (ret) {
186 dev_err(&pdev->dev, "can't enable device\n");
187 goto err;
188 }
189
190 /* XXX 32-bit addressing only */
191 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
192 if (ret) {
193 dev_err(&pdev->dev, "32-bit DMA not available\n");
194 goto err_dis;
195 }
196
197 /*
198 * Cache line size is used to size and align various
199 * structures used to communicate with the hardware.
200 */
201 pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
202 if (csz == 0) {
203 /*
204 * Linux 2.4.18 (at least) writes the cache line size
205 * register as a 16-bit wide register which is wrong.
206 * We must have this setup properly for rx buffer
207 * DMA to work so force a reasonable value here if it
208 * comes up zero.
209 */
210 csz = L1_CACHE_BYTES >> 2;
211 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
212 }
213 /*
214 * The default setting of latency timer yields poor results,
215 * set it to the value used by other systems. It may be worth
216 * tweaking this setting more.
217 */
218 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
219
220 /* Enable bus mastering */
221 pci_set_master(pdev);
222
223 /*
224 * Disable the RETRY_TIMEOUT register (0x41) to keep
225 * PCI Tx retries from interfering with C3 CPU state.
226 */
227 pci_write_config_byte(pdev, 0x41, 0);
228
229 ret = pci_request_region(pdev, 0, "ath5k");
230 if (ret) {
231 dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
232 goto err_dis;
233 }
234
235 mem = pci_iomap(pdev, 0, 0);
236 if (!mem) {
237 dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
238 ret = -EIO;
239 goto err_reg;
240 }
241
242 /*
243 * Allocate hw (mac80211 main struct)
244 * and hw->priv (driver private data)
245 */
246 hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
247 if (hw == NULL) {
248 dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
249 ret = -ENOMEM;
250 goto err_map;
251 }
252
253 dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
254
255 sc = hw->priv;
256 sc->hw = hw;
257 sc->pdev = pdev;
258 sc->dev = &pdev->dev;
259 sc->irq = pdev->irq;
260 sc->devid = id->device;
261 sc->iobase = mem; /* So we can unmap it on detach */
262
263 /* Initialize */
264 ret = ath5k_init_softc(sc, &ath_pci_bus_ops);
265 if (ret)
266 goto err_free;
267
268 /* Set private data */
269 pci_set_drvdata(pdev, hw);
270
271 return 0;
272err_free:
273 ieee80211_free_hw(hw);
274err_map:
275 pci_iounmap(pdev, mem);
276err_reg:
277 pci_release_region(pdev, 0);
278err_dis:
279 pci_disable_device(pdev);
280err:
281 return ret;
282}
283
284static void __devexit
285ath5k_pci_remove(struct pci_dev *pdev)
286{
287 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
288 struct ath5k_softc *sc = hw->priv;
289
290 ath5k_deinit_softc(sc);
291 pci_iounmap(pdev, sc->iobase);
292 pci_release_region(pdev, 0);
293 pci_disable_device(pdev);
294 ieee80211_free_hw(hw);
295}
296
297#ifdef CONFIG_PM_SLEEP
298static int ath5k_pci_suspend(struct device *dev)
299{
300 struct pci_dev *pdev = to_pci_dev(dev);
301 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
302 struct ath5k_softc *sc = hw->priv;
303
304 ath5k_led_off(sc);
305 return 0;
306}
307
308static int ath5k_pci_resume(struct device *dev)
309{
310 struct pci_dev *pdev = to_pci_dev(dev);
311 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
312 struct ath5k_softc *sc = hw->priv;
313
314 /*
315 * Suspend/Resume resets the PCI configuration space, so we have to
316 * re-disable the RETRY_TIMEOUT register (0x41) to keep
317 * PCI Tx retries from interfering with C3 CPU state
318 */
319 pci_write_config_byte(pdev, 0x41, 0);
320
321 ath5k_led_enable(sc);
322 return 0;
323}
324
325static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
326#define ATH5K_PM_OPS (&ath5k_pm_ops)
327#else
328#define ATH5K_PM_OPS NULL
329#endif /* CONFIG_PM_SLEEP */
330
331static struct pci_driver ath5k_pci_driver = {
332 .name = KBUILD_MODNAME,
333 .id_table = ath5k_pci_id_table,
334 .probe = ath5k_pci_probe,
335 .remove = __devexit_p(ath5k_pci_remove),
336 .driver.pm = ATH5K_PM_OPS,
337};
338
339/*
340 * Module init/exit functions
341 */
342static int __init
343init_ath5k_pci(void)
344{
345 int ret;
346
347 ret = pci_register_driver(&ath5k_pci_driver);
348 if (ret) {
349 printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
350 return ret;
351 }
352
353 return 0;
354}
355
356static void __exit
357exit_ath5k_pci(void)
358{
359 pci_unregister_driver(&ath5k_pci_driver);
360}
361
362module_init(init_ath5k_pci);
363module_exit(exit_ath5k_pci);
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 86fdb6ddfaaa..712a9ac4000e 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -31,87 +31,169 @@
31#include "debug.h" 31#include "debug.h"
32#include "base.h" 32#include "base.h"
33 33
34/*
35 * AR5212+ can use higher rates for ack transmition
36 * based on current tx rate instead of the base rate.
37 * It does this to better utilize channel usage.
38 * This is a mapping between G rates (that cover both
39 * CCK and OFDM) and ack rates that we use when setting
40 * rate -> duration table. This mapping is hw-based so
41 * don't change anything.
42 *
43 * To enable this functionality we must set
44 * ah->ah_ack_bitrate_high to true else base rate is
45 * used (1Mb for CCK, 6Mb for OFDM).
46 */
47static const unsigned int ack_rates_high[] =
48/* Tx -> ACK */
49/* 1Mb -> 1Mb */ { 0,
50/* 2MB -> 2Mb */ 1,
51/* 5.5Mb -> 2Mb */ 1,
52/* 11Mb -> 2Mb */ 1,
53/* 6Mb -> 6Mb */ 4,
54/* 9Mb -> 6Mb */ 4,
55/* 12Mb -> 12Mb */ 6,
56/* 18Mb -> 12Mb */ 6,
57/* 24Mb -> 24Mb */ 8,
58/* 36Mb -> 24Mb */ 8,
59/* 48Mb -> 24Mb */ 8,
60/* 54Mb -> 24Mb */ 8 };
61
34/*******************\ 62/*******************\
35* Generic functions * 63* Helper functions *
36\*******************/ 64\*******************/
37 65
38/** 66/**
39 * ath5k_hw_set_opmode - Set PCU operating mode 67 * ath5k_hw_get_frame_duration - Get tx time of a frame
40 * 68 *
41 * @ah: The &struct ath5k_hw 69 * @ah: The &struct ath5k_hw
42 * @op_mode: &enum nl80211_iftype operating mode 70 * @len: Frame's length in bytes
71 * @rate: The @struct ieee80211_rate
43 * 72 *
44 * Initialize PCU for the various operating modes (AP/STA etc) 73 * Calculate tx duration of a frame given it's rate and length
74 * It extends ieee80211_generic_frame_duration for non standard
75 * bwmodes.
45 */ 76 */
46int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode) 77int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
78 int len, struct ieee80211_rate *rate, bool shortpre)
47{ 79{
48 struct ath_common *common = ath5k_hw_common(ah); 80 struct ath5k_softc *sc = ah->ah_sc;
49 u32 pcu_reg, beacon_reg, low_id, high_id; 81 int sifs, preamble, plcp_bits, sym_time;
82 int bitrate, bits, symbols, symbol_bits;
83 int dur;
84
85 /* Fallback */
86 if (!ah->ah_bwmode) {
87 __le16 raw_dur = ieee80211_generic_frame_duration(sc->hw,
88 NULL, len, rate);
89
90 /* subtract difference between long and short preamble */
91 dur = le16_to_cpu(raw_dur);
92 if (shortpre)
93 dur -= 96;
94
95 return dur;
96 }
50 97
51 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode); 98 bitrate = rate->bitrate;
99 preamble = AR5K_INIT_OFDM_PREAMPLE_TIME;
100 plcp_bits = AR5K_INIT_OFDM_PLCP_BITS;
101 sym_time = AR5K_INIT_OFDM_SYMBOL_TIME;
52 102
53 /* Preserve rest settings */ 103 switch (ah->ah_bwmode) {
54 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; 104 case AR5K_BWMODE_40MHZ:
55 pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP 105 sifs = AR5K_INIT_SIFS_TURBO;
56 | AR5K_STA_ID1_KEYSRCH_MODE 106 preamble = AR5K_INIT_OFDM_PREAMBLE_TIME_MIN;
57 | (ah->ah_version == AR5K_AR5210 ? 107 break;
58 (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0)); 108 case AR5K_BWMODE_10MHZ:
109 sifs = AR5K_INIT_SIFS_HALF_RATE;
110 preamble *= 2;
111 sym_time *= 2;
112 break;
113 case AR5K_BWMODE_5MHZ:
114 sifs = AR5K_INIT_SIFS_QUARTER_RATE;
115 preamble *= 4;
116 sym_time *= 4;
117 break;
118 default:
119 sifs = AR5K_INIT_SIFS_DEFAULT_BG;
120 break;
121 }
59 122
60 beacon_reg = 0; 123 bits = plcp_bits + (len << 3);
124 /* Bit rate is in 100Kbits */
125 symbol_bits = bitrate * sym_time;
126 symbols = DIV_ROUND_UP(bits * 10, symbol_bits);
61 127
62 switch (op_mode) { 128 dur = sifs + preamble + (sym_time * symbols);
63 case NL80211_IFTYPE_ADHOC:
64 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
65 beacon_reg |= AR5K_BCR_ADHOC;
66 if (ah->ah_version == AR5K_AR5210)
67 pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
68 else
69 AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
70 break;
71 129
72 case NL80211_IFTYPE_AP: 130 return dur;
73 case NL80211_IFTYPE_MESH_POINT: 131}
74 pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
75 beacon_reg |= AR5K_BCR_AP;
76 if (ah->ah_version == AR5K_AR5210)
77 pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
78 else
79 AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
80 break;
81 132
82 case NL80211_IFTYPE_STATION: 133/**
83 pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE 134 * ath5k_hw_get_default_slottime - Get the default slot time for current mode
84 | (ah->ah_version == AR5K_AR5210 ? 135 *
85 AR5K_STA_ID1_PWR_SV : 0); 136 * @ah: The &struct ath5k_hw
86 case NL80211_IFTYPE_MONITOR: 137 */
87 pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE 138unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
88 | (ah->ah_version == AR5K_AR5210 ? 139{
89 AR5K_STA_ID1_NO_PSPOLL : 0); 140 struct ieee80211_channel *channel = ah->ah_current_channel;
90 break; 141 unsigned int slot_time;
91 142
143 switch (ah->ah_bwmode) {
144 case AR5K_BWMODE_40MHZ:
145 slot_time = AR5K_INIT_SLOT_TIME_TURBO;
146 break;
147 case AR5K_BWMODE_10MHZ:
148 slot_time = AR5K_INIT_SLOT_TIME_HALF_RATE;
149 break;
150 case AR5K_BWMODE_5MHZ:
151 slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE;
152 break;
153 case AR5K_BWMODE_DEFAULT:
92 default: 154 default:
93 return -EINVAL; 155 slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
156 if ((channel->hw_value & CHANNEL_CCK) && !ah->ah_short_slot)
157 slot_time = AR5K_INIT_SLOT_TIME_B;
158 break;
94 } 159 }
95 160
96 /* 161 return slot_time;
97 * Set PCU registers 162}
98 */
99 low_id = get_unaligned_le32(common->macaddr);
100 high_id = get_unaligned_le16(common->macaddr + 4);
101 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
102 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
103 163
104 /* 164/**
105 * Set Beacon Control Register on 5210 165 * ath5k_hw_get_default_sifs - Get the default SIFS for current mode
106 */ 166 *
107 if (ah->ah_version == AR5K_AR5210) 167 * @ah: The &struct ath5k_hw
108 ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR); 168 */
169unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
170{
171 struct ieee80211_channel *channel = ah->ah_current_channel;
172 unsigned int sifs;
109 173
110 return 0; 174 switch (ah->ah_bwmode) {
175 case AR5K_BWMODE_40MHZ:
176 sifs = AR5K_INIT_SIFS_TURBO;
177 break;
178 case AR5K_BWMODE_10MHZ:
179 sifs = AR5K_INIT_SIFS_HALF_RATE;
180 break;
181 case AR5K_BWMODE_5MHZ:
182 sifs = AR5K_INIT_SIFS_QUARTER_RATE;
183 break;
184 case AR5K_BWMODE_DEFAULT:
185 sifs = AR5K_INIT_SIFS_DEFAULT_BG;
186 default:
187 if (channel->hw_value & CHANNEL_5GHZ)
188 sifs = AR5K_INIT_SIFS_DEFAULT_A;
189 break;
190 }
191
192 return sifs;
111} 193}
112 194
113/** 195/**
114 * ath5k_hw_update - Update MIB counters (mac layer statistics) 196 * ath5k_hw_update_mib_counters - Update MIB counters (mac layer statistics)
115 * 197 *
116 * @ah: The &struct ath5k_hw 198 * @ah: The &struct ath5k_hw
117 * 199 *
@@ -133,35 +215,72 @@ void ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
133 stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT); 215 stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
134} 216}
135 217
218
219/******************\
220* ACK/CTS Timeouts *
221\******************/
222
136/** 223/**
137 * ath5k_hw_set_ack_bitrate - set bitrate for ACKs 224 * ath5k_hw_write_rate_duration - fill rate code to duration table
138 * 225 *
139 * @ah: The &struct ath5k_hw 226 * @ah: the &struct ath5k_hw
140 * @high: Flag to determine if we want to use high transmition rate 227 * @mode: one of enum ath5k_driver_mode
141 * for ACKs or not 228 *
229 * Write the rate code to duration table upon hw reset. This is a helper for
230 * ath5k_hw_pcu_init(). It seems all this is doing is setting an ACK timeout on
231 * the hardware, based on current mode, for each rate. The rates which are
232 * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
233 * different rate code so we write their value twice (one for long preamble
234 * and one for short).
235 *
236 * Note: Band doesn't matter here, if we set the values for OFDM it works
237 * on both a and g modes. So all we have to do is set values for all g rates
238 * that include all OFDM and CCK rates.
142 * 239 *
143 * If high flag is set, we tell hw to use a set of control rates based on
144 * the current transmition rate (check out control_rates array inside reset.c).
145 * If not hw just uses the lowest rate available for the current modulation
146 * scheme being used (1Mbit for CCK and 6Mbits for OFDM).
147 */ 240 */
148void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high) 241static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah)
149{ 242{
150 if (ah->ah_version != AR5K_AR5212) 243 struct ath5k_softc *sc = ah->ah_sc;
151 return; 244 struct ieee80211_rate *rate;
152 else { 245 unsigned int i;
153 u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB; 246 /* 802.11g covers both OFDM and CCK */
154 if (high) 247 u8 band = IEEE80211_BAND_2GHZ;
155 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val); 248
249 /* Write rate duration table */
250 for (i = 0; i < sc->sbands[band].n_bitrates; i++) {
251 u32 reg;
252 u16 tx_time;
253
254 if (ah->ah_ack_bitrate_high)
255 rate = &sc->sbands[band].bitrates[ack_rates_high[i]];
256 /* CCK -> 1Mb */
257 else if (i < 4)
258 rate = &sc->sbands[band].bitrates[0];
259 /* OFDM -> 6Mb */
156 else 260 else
157 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val); 261 rate = &sc->sbands[band].bitrates[4];
158 }
159}
160 262
263 /* Set ACK timeout */
264 reg = AR5K_RATE_DUR(rate->hw_value);
161 265
162/******************\ 266 /* An ACK frame consists of 10 bytes. If you add the FCS,
163* ACK/CTS Timeouts * 267 * which ieee80211_generic_frame_duration() adds,
164\******************/ 268 * its 14 bytes. Note we use the control rate and not the
269 * actual rate for this rate. See mac80211 tx.c
270 * ieee80211_duration() for a brief description of
271 * what rate we should choose to TX ACKs. */
272 tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false);
273
274 ath5k_hw_reg_write(ah, tx_time, reg);
275
276 if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
277 continue;
278
279 tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, true);
280 ath5k_hw_reg_write(ah, tx_time,
281 reg + (AR5K_SET_SHORT_PREAMBLE << 2));
282 }
283}
165 284
166/** 285/**
167 * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU 286 * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU
@@ -199,85 +318,10 @@ static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
199 return 0; 318 return 0;
200} 319}
201 320
202/**
203 * ath5k_hw_htoclock - Translate usec to hw clock units
204 *
205 * @ah: The &struct ath5k_hw
206 * @usec: value in microseconds
207 */
208unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
209{
210 return usec * ath5k_hw_get_clockrate(ah);
211}
212
213/**
214 * ath5k_hw_clocktoh - Translate hw clock units to usec
215 * @clock: value in hw clock units
216 */
217unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
218{
219 return clock / ath5k_hw_get_clockrate(ah);
220}
221
222/**
223 * ath5k_hw_get_clockrate - Get the clock rate for current mode
224 *
225 * @ah: The &struct ath5k_hw
226 */
227unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
228{
229 struct ieee80211_channel *channel = ah->ah_current_channel;
230 int clock;
231
232 if (channel->hw_value & CHANNEL_5GHZ)
233 clock = 40; /* 802.11a */
234 else if (channel->hw_value & CHANNEL_CCK)
235 clock = 22; /* 802.11b */
236 else
237 clock = 44; /* 802.11g */
238
239 /* Clock rate in turbo modes is twice the normal rate */
240 if (channel->hw_value & CHANNEL_TURBO)
241 clock *= 2;
242
243 return clock;
244}
245 321
246/** 322/*******************\
247 * ath5k_hw_get_default_slottime - Get the default slot time for current mode 323* RX filter Control *
248 * 324\*******************/
249 * @ah: The &struct ath5k_hw
250 */
251static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
252{
253 struct ieee80211_channel *channel = ah->ah_current_channel;
254
255 if (channel->hw_value & CHANNEL_TURBO)
256 return 6; /* both turbo modes */
257
258 if (channel->hw_value & CHANNEL_CCK)
259 return 20; /* 802.11b */
260
261 return 9; /* 802.11 a/g */
262}
263
264/**
265 * ath5k_hw_get_default_sifs - Get the default SIFS for current mode
266 *
267 * @ah: The &struct ath5k_hw
268 */
269static unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
270{
271 struct ieee80211_channel *channel = ah->ah_current_channel;
272
273 if (channel->hw_value & CHANNEL_TURBO)
274 return 8; /* both turbo modes */
275
276 if (channel->hw_value & CHANNEL_5GHZ)
277 return 16; /* 802.11a */
278
279 return 10; /* 802.11 b/g */
280}
281 325
282/** 326/**
283 * ath5k_hw_set_lladdr - Set station id 327 * ath5k_hw_set_lladdr - Set station id
@@ -308,27 +352,26 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
308} 352}
309 353
310/** 354/**
311 * ath5k_hw_set_associd - Set BSSID for association 355 * ath5k_hw_set_bssid - Set current BSSID on hw
312 * 356 *
313 * @ah: The &struct ath5k_hw 357 * @ah: The &struct ath5k_hw
314 * @bssid: BSSID
315 * @assoc_id: Assoc id
316 * 358 *
317 * Sets the BSSID which trigers the "SME Join" operation 359 * Sets the current BSSID and BSSID mask we have from the
360 * common struct into the hardware
318 */ 361 */
319void ath5k_hw_set_associd(struct ath5k_hw *ah) 362void ath5k_hw_set_bssid(struct ath5k_hw *ah)
320{ 363{
321 struct ath_common *common = ath5k_hw_common(ah); 364 struct ath_common *common = ath5k_hw_common(ah);
322 u16 tim_offset = 0; 365 u16 tim_offset = 0;
323 366
324 /* 367 /*
325 * Set simple BSSID mask on 5212 368 * Set BSSID mask on 5212
326 */ 369 */
327 if (ah->ah_version == AR5K_AR5212) 370 if (ah->ah_version == AR5K_AR5212)
328 ath_hw_setbssidmask(common); 371 ath_hw_setbssidmask(common);
329 372
330 /* 373 /*
331 * Set BSSID which triggers the "SME Join" operation 374 * Set BSSID
332 */ 375 */
333 ath5k_hw_reg_write(ah, 376 ath5k_hw_reg_write(ah,
334 get_unaligned_le32(common->curbssid), 377 get_unaligned_le32(common->curbssid),
@@ -360,39 +403,6 @@ void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
360 ath_hw_setbssidmask(common); 403 ath_hw_setbssidmask(common);
361} 404}
362 405
363/************\
364* RX Control *
365\************/
366
367/**
368 * ath5k_hw_start_rx_pcu - Start RX engine
369 *
370 * @ah: The &struct ath5k_hw
371 *
372 * Starts RX engine on PCU so that hw can process RXed frames
373 * (ACK etc).
374 *
375 * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
376 */
377void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
378{
379 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
380}
381
382/**
383 * at5k_hw_stop_rx_pcu - Stop RX engine
384 *
385 * @ah: The &struct ath5k_hw
386 *
387 * Stops RX engine on PCU
388 *
389 * TODO: Detach ANI here
390 */
391void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
392{
393 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
394}
395
396/* 406/*
397 * Set multicast filter 407 * Set multicast filter
398 */ 408 */
@@ -455,7 +465,7 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
455 } 465 }
456 466
457 /* 467 /*
458 * The AR5210 uses promiscous mode to detect radar activity 468 * The AR5210 uses promiscuous mode to detect radar activity
459 */ 469 */
460 if (ah->ah_version == AR5K_AR5210 && 470 if (ah->ah_version == AR5K_AR5210 &&
461 (filter & AR5K_RX_FILTER_RADARERR)) { 471 (filter & AR5K_RX_FILTER_RADARERR)) {
@@ -496,6 +506,10 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
496{ 506{
497 u32 tsf_lower, tsf_upper1, tsf_upper2; 507 u32 tsf_lower, tsf_upper1, tsf_upper2;
498 int i; 508 int i;
509 unsigned long flags;
510
511 /* This code is time critical - we don't want to be interrupted here */
512 local_irq_save(flags);
499 513
500 /* 514 /*
501 * While reading TSF upper and then lower part, the clock is still 515 * While reading TSF upper and then lower part, the clock is still
@@ -518,6 +532,8 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
518 tsf_upper1 = tsf_upper2; 532 tsf_upper1 = tsf_upper2;
519 } 533 }
520 534
535 local_irq_restore(flags);
536
521 WARN_ON( i == ATH5K_MAX_TSF_READ ); 537 WARN_ON( i == ATH5K_MAX_TSF_READ );
522 538
523 return (((u64)tsf_upper1 << 32) | tsf_lower); 539 return (((u64)tsf_upper1 << 32) | tsf_lower);
@@ -601,7 +617,7 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
601 /* Timer3 marks the end of our ATIM window 617 /* Timer3 marks the end of our ATIM window
602 * a zero length window is not allowed because 618 * a zero length window is not allowed because
603 * we 'll get no beacons */ 619 * we 'll get no beacons */
604 timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1); 620 timer3 = next_beacon + 1;
605 621
606 /* 622 /*
607 * Set the beacon register and enable all timers. 623 * Set the beacon register and enable all timers.
@@ -641,218 +657,281 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
641 657
642} 658}
643 659
660/**
661 * ath5k_check_timer_win - Check if timer B is timer A + window
662 *
663 * @a: timer a (before b)
664 * @b: timer b (after a)
665 * @window: difference between a and b
666 * @intval: timers are increased by this interval
667 *
668 * This helper function checks if timer B is timer A + window and covers
669 * cases where timer A or B might have already been updated or wrapped
670 * around (Timers are 16 bit).
671 *
672 * Returns true if O.K.
673 */
674static inline bool
675ath5k_check_timer_win(int a, int b, int window, int intval)
676{
677 /*
678 * 1.) usually B should be A + window
679 * 2.) A already updated, B not updated yet
680 * 3.) A already updated and has wrapped around
681 * 4.) B has wrapped around
682 */
683 if ((b - a == window) || /* 1.) */
684 (a - b == intval - window) || /* 2.) */
685 ((a | 0x10000) - b == intval - window) || /* 3.) */
686 ((b | 0x10000) - a == window)) /* 4.) */
687 return true; /* O.K. */
688 return false;
689}
644 690
645/*********************\ 691/**
646* Key table functions * 692 * ath5k_hw_check_beacon_timers - Check if the beacon timers are correct
647\*********************/ 693 *
648 694 * @ah: The &struct ath5k_hw
649/* 695 * @intval: beacon interval
650 * Reset a key entry on the table 696 *
697 * This is a workaround for IBSS mode:
698 *
699 * The need for this function arises from the fact that we have 4 separate
700 * HW timer registers (TIMER0 - TIMER3), which are closely related to the
701 * next beacon target time (NBTT), and that the HW updates these timers
702 * separately based on the current TSF value. The hardware increments each
703 * timer by the beacon interval, when the local TSF converted to TU is equal
704 * to the value stored in the timer.
705 *
706 * The reception of a beacon with the same BSSID can update the local HW TSF
707 * at any time - this is something we can't avoid. If the TSF jumps to a
708 * time which is later than the time stored in a timer, this timer will not
709 * be updated until the TSF in TU wraps around at 16 bit (the size of the
710 * timers) and reaches the time which is stored in the timer.
711 *
712 * The problem is that these timers are closely related to TIMER0 (NBTT) and
713 * that they define a time "window". When the TSF jumps between two timers
714 * (e.g. ATIM and NBTT), the one in the past will be left behind (not
715 * updated), while the one in the future will be updated every beacon
716 * interval. This causes the window to get larger, until the TSF wraps
717 * around as described above and the timer which was left behind gets
718 * updated again. But - because the beacon interval is usually not an exact
719 * divisor of the size of the timers (16 bit), an unwanted "window" between
720 * these timers has developed!
721 *
722 * This is especially important with the ATIM window, because during
723 * the ATIM window only ATIM frames and no data frames are allowed to be
724 * sent, which creates transmission pauses after each beacon. This symptom
725 * has been described as "ramping ping" because ping times increase linearly
726 * for some time and then drop down again. A wrong window on the DMA beacon
727 * timer has the same effect, so we check for these two conditions.
728 *
729 * Returns true if O.K.
651 */ 730 */
652int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry) 731bool
732ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval)
653{ 733{
654 unsigned int i, type; 734 unsigned int nbtt, atim, dma;
655 u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
656 735
657 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); 736 nbtt = ath5k_hw_reg_read(ah, AR5K_TIMER0);
737 atim = ath5k_hw_reg_read(ah, AR5K_TIMER3);
738 dma = ath5k_hw_reg_read(ah, AR5K_TIMER1) >> 3;
658 739
659 type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry)); 740 /* NOTE: SWBA is different. Having a wrong window there does not
741 * stop us from sending data and this condition is catched thru
742 * other means (SWBA interrupt) */
660 743
661 for (i = 0; i < AR5K_KEYCACHE_SIZE; i++) 744 if (ath5k_check_timer_win(nbtt, atim, 1, intval) &&
662 ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i)); 745 ath5k_check_timer_win(dma, nbtt, AR5K_TUNE_DMA_BEACON_RESP,
746 intval))
747 return true; /* O.K. */
748 return false;
749}
663 750
664 /* Reset associated MIC entry if TKIP 751/**
665 * is enabled located at offset (entry + 64) */ 752 * ath5k_hw_set_coverage_class - Set IEEE 802.11 coverage class
666 if (type == AR5K_KEYTABLE_TYPE_TKIP) { 753 *
667 AR5K_ASSERT_ENTRY(micentry, AR5K_KEYTABLE_SIZE); 754 * @ah: The &struct ath5k_hw
668 for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++) 755 * @coverage_class: IEEE 802.11 coverage class number
669 ath5k_hw_reg_write(ah, 0, 756 *
670 AR5K_KEYTABLE_OFF(micentry, i)); 757 * Sets IFS intervals and ACK/CTS timeouts for given coverage class.
671 } 758 */
759void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
760{
761 /* As defined by IEEE 802.11-2007 17.3.8.6 */
762 int slot_time = ath5k_hw_get_default_slottime(ah) + 3 * coverage_class;
763 int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time;
764 int cts_timeout = ack_timeout;
672 765
673 /* 766 ath5k_hw_set_ifs_intervals(ah, slot_time);
674 * Set NULL encryption on AR5212+ 767 ath5k_hw_set_ack_timeout(ah, ack_timeout);
675 * 768 ath5k_hw_set_cts_timeout(ah, cts_timeout);
676 * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5)
677 * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007
678 *
679 * Note2: Windows driver (ndiswrapper) sets this to
680 * 0x00000714 instead of 0x00000007
681 */
682 if (ah->ah_version >= AR5K_AR5211) {
683 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
684 AR5K_KEYTABLE_TYPE(entry));
685 769
686 if (type == AR5K_KEYTABLE_TYPE_TKIP) { 770 ah->ah_coverage_class = coverage_class;
687 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, 771}
688 AR5K_KEYTABLE_TYPE(micentry));
689 }
690 }
691 772
692 return 0; 773/***************************\
774* Init/Start/Stop functions *
775\***************************/
776
777/**
778 * ath5k_hw_start_rx_pcu - Start RX engine
779 *
780 * @ah: The &struct ath5k_hw
781 *
782 * Starts RX engine on PCU so that hw can process RXed frames
783 * (ACK etc).
784 *
785 * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
786 */
787void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
788{
789 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
693} 790}
694 791
695static 792/**
696int ath5k_keycache_type(const struct ieee80211_key_conf *key) 793 * at5k_hw_stop_rx_pcu - Stop RX engine
794 *
795 * @ah: The &struct ath5k_hw
796 *
797 * Stops RX engine on PCU
798 */
799void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
697{ 800{
698 switch (key->alg) { 801 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
699 case ALG_TKIP:
700 return AR5K_KEYTABLE_TYPE_TKIP;
701 case ALG_CCMP:
702 return AR5K_KEYTABLE_TYPE_CCM;
703 case ALG_WEP:
704 if (key->keylen == WLAN_KEY_LEN_WEP40)
705 return AR5K_KEYTABLE_TYPE_40;
706 else if (key->keylen == WLAN_KEY_LEN_WEP104)
707 return AR5K_KEYTABLE_TYPE_104;
708 return -EINVAL;
709 default:
710 return -EINVAL;
711 }
712 return -EINVAL;
713} 802}
714 803
715/* 804/**
716 * Set a key entry on the table 805 * ath5k_hw_set_opmode - Set PCU operating mode
806 *
807 * @ah: The &struct ath5k_hw
808 * @op_mode: &enum nl80211_iftype operating mode
809 *
810 * Configure PCU for the various operating modes (AP/STA etc)
717 */ 811 */
718int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, 812int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
719 const struct ieee80211_key_conf *key, const u8 *mac)
720{ 813{
721 unsigned int i; 814 struct ath_common *common = ath5k_hw_common(ah);
722 int keylen; 815 u32 pcu_reg, beacon_reg, low_id, high_id;
723 __le32 key_v[5] = {};
724 __le32 key0 = 0, key1 = 0;
725 __le32 *rxmic, *txmic;
726 int keytype;
727 u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
728 bool is_tkip;
729 const u8 *key_ptr;
730 816
731 is_tkip = (key->alg == ALG_TKIP); 817 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
732 818
733 /* 819 /* Preserve rest settings */
734 * key->keylen comes in from mac80211 in bytes. 820 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
735 * TKIP is 128 bit + 128 bit mic 821 pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
736 */ 822 | AR5K_STA_ID1_KEYSRCH_MODE
737 keylen = (is_tkip) ? (128 / 8) : key->keylen; 823 | (ah->ah_version == AR5K_AR5210 ?
824 (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
738 825
739 if (entry > AR5K_KEYTABLE_SIZE || 826 beacon_reg = 0;
740 (is_tkip && micentry > AR5K_KEYTABLE_SIZE))
741 return -EOPNOTSUPP;
742 827
743 if (unlikely(keylen > 16)) 828 switch (op_mode) {
744 return -EOPNOTSUPP; 829 case NL80211_IFTYPE_ADHOC:
830 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
831 beacon_reg |= AR5K_BCR_ADHOC;
832 if (ah->ah_version == AR5K_AR5210)
833 pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
834 else
835 AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
836 break;
745 837
746 keytype = ath5k_keycache_type(key); 838 case NL80211_IFTYPE_AP:
747 if (keytype < 0) 839 case NL80211_IFTYPE_MESH_POINT:
748 return keytype; 840 pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
841 beacon_reg |= AR5K_BCR_AP;
842 if (ah->ah_version == AR5K_AR5210)
843 pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
844 else
845 AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
846 break;
749 847
750 /* 848 case NL80211_IFTYPE_STATION:
751 * each key block is 6 bytes wide, written as pairs of 849 pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
752 * alternating 32 and 16 bit le values. 850 | (ah->ah_version == AR5K_AR5210 ?
753 */ 851 AR5K_STA_ID1_PWR_SV : 0);
754 key_ptr = key->key; 852 case NL80211_IFTYPE_MONITOR:
755 for (i = 0; keylen >= 6; keylen -= 6) { 853 pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
756 memcpy(&key_v[i], key_ptr, 6); 854 | (ah->ah_version == AR5K_AR5210 ?
757 i += 2; 855 AR5K_STA_ID1_NO_PSPOLL : 0);
758 key_ptr += 6; 856 break;
759 }
760 if (keylen)
761 memcpy(&key_v[i], key_ptr, keylen);
762 857
763 /* intentionally corrupt key until mic is installed */ 858 default:
764 if (is_tkip) { 859 return -EINVAL;
765 key0 = key_v[0] = ~key_v[0];
766 key1 = key_v[1] = ~key_v[1];
767 } 860 }
768 861
769 for (i = 0; i < ARRAY_SIZE(key_v); i++) 862 /*
770 ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]), 863 * Set PCU registers
771 AR5K_KEYTABLE_OFF(entry, i)); 864 */
772 865 low_id = get_unaligned_le32(common->macaddr);
773 ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry)); 866 high_id = get_unaligned_le16(common->macaddr + 4);
774 867 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
775 if (is_tkip) { 868 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
776 /* Install rx/tx MIC */
777 rxmic = (__le32 *) &key->key[16];
778 txmic = (__le32 *) &key->key[24];
779 869
780 if (ah->ah_combined_mic) { 870 /*
781 key_v[0] = rxmic[0]; 871 * Set Beacon Control Register on 5210
782 key_v[1] = cpu_to_le32(le32_to_cpu(txmic[0]) >> 16); 872 */
783 key_v[2] = rxmic[1]; 873 if (ah->ah_version == AR5K_AR5210)
784 key_v[3] = cpu_to_le32(le32_to_cpu(txmic[0]) & 0xffff); 874 ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
785 key_v[4] = txmic[1];
786 } else {
787 key_v[0] = rxmic[0];
788 key_v[1] = 0;
789 key_v[2] = rxmic[1];
790 key_v[3] = 0;
791 key_v[4] = 0;
792 }
793 for (i = 0; i < ARRAY_SIZE(key_v); i++)
794 ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
795 AR5K_KEYTABLE_OFF(micentry, i));
796
797 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
798 AR5K_KEYTABLE_TYPE(micentry));
799 ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC0(micentry));
800 ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC1(micentry));
801
802 /* restore first 2 words of key */
803 ath5k_hw_reg_write(ah, le32_to_cpu(~key0),
804 AR5K_KEYTABLE_OFF(entry, 0));
805 ath5k_hw_reg_write(ah, le32_to_cpu(~key1),
806 AR5K_KEYTABLE_OFF(entry, 1));
807 }
808 875
809 return ath5k_hw_set_key_lladdr(ah, entry, mac); 876 return 0;
810} 877}
811 878
812int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac) 879void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
880 u8 mode)
813{ 881{
814 u32 low_id, high_id; 882 /* Set bssid and bssid mask */
815 883 ath5k_hw_set_bssid(ah);
816 /* Invalid entry (key table overflow) */
817 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
818 884
819 /* 885 /* Set PCU config */
820 * MAC may be NULL if it's a broadcast key. In this case no need to 886 ath5k_hw_set_opmode(ah, op_mode);
821 * to compute get_unaligned_le32 and get_unaligned_le16 as we
822 * already know it.
823 */
824 if (!mac) {
825 low_id = 0xffffffff;
826 high_id = 0xffff | AR5K_KEYTABLE_VALID;
827 } else {
828 low_id = get_unaligned_le32(mac);
829 high_id = get_unaligned_le16(mac + 4) | AR5K_KEYTABLE_VALID;
830 }
831 887
832 ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry)); 888 /* Write rate duration table only on AR5212 and if
833 ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry)); 889 * virtual interface has already been brought up
890 * XXX: rethink this after new mode changes to
891 * mac80211 are integrated */
892 if (ah->ah_version == AR5K_AR5212 &&
893 ah->ah_sc->nvifs)
894 ath5k_hw_write_rate_duration(ah);
834 895
835 return 0; 896 /* Set RSSI/BRSSI thresholds
836} 897 *
898 * Note: If we decide to set this value
899 * dynamicaly, have in mind that when AR5K_RSSI_THR
900 * register is read it might return 0x40 if we haven't
901 * wrote anything to it plus BMISS RSSI threshold is zeroed.
902 * So doing a save/restore procedure here isn't the right
903 * choice. Instead store it on ath5k_hw */
904 ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
905 AR5K_TUNE_BMISS_THRES <<
906 AR5K_RSSI_THR_BMISS_S),
907 AR5K_RSSI_THR);
908
909 /* MIC QoS support */
910 if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
911 ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
912 ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
913 }
837 914
838/** 915 /* QoS NOACK Policy */
839 * ath5k_hw_set_coverage_class - Set IEEE 802.11 coverage class 916 if (ah->ah_version == AR5K_AR5212) {
840 * 917 ath5k_hw_reg_write(ah,
841 * @ah: The &struct ath5k_hw 918 AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
842 * @coverage_class: IEEE 802.11 coverage class number 919 AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |
843 * 920 AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
844 * Sets slot time, ACK timeout and CTS timeout for given coverage class. 921 AR5K_QOS_NOACK);
845 */ 922 }
846void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
847{
848 /* As defined by IEEE 802.11-2007 17.3.8.6 */
849 int slot_time = ath5k_hw_get_default_slottime(ah) + 3 * coverage_class;
850 int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time;
851 int cts_timeout = ack_timeout;
852 923
853 ath5k_hw_set_slot_time(ah, slot_time); 924 /* Restore slot time and ACK timeouts */
854 ath5k_hw_set_ack_timeout(ah, ack_timeout); 925 if (ah->ah_coverage_class > 0)
855 ath5k_hw_set_cts_timeout(ah, cts_timeout); 926 ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
856 927
857 ah->ah_coverage_class = coverage_class; 928 /* Set ACK bitrate mode (see ack_rates_high) */
929 if (ah->ah_version == AR5K_AR5212) {
930 u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
931 if (ah->ah_ack_bitrate_high)
932 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
933 else
934 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
935 }
936 return;
858} 937}
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 6284c389ba18..55441913344d 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -29,6 +29,95 @@
29#include "rfbuffer.h" 29#include "rfbuffer.h"
30#include "rfgain.h" 30#include "rfgain.h"
31 31
32
33/******************\
34* Helper functions *
35\******************/
36
37/*
38 * Get the PHY Chip revision
39 */
40u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
41{
42 unsigned int i;
43 u32 srev;
44 u16 ret;
45
46 /*
47 * Set the radio chip access register
48 */
49 switch (chan) {
50 case CHANNEL_2GHZ:
51 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
52 break;
53 case CHANNEL_5GHZ:
54 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
55 break;
56 default:
57 return 0;
58 }
59
60 mdelay(2);
61
62 /* ...wait until PHY is ready and read the selected radio revision */
63 ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
64
65 for (i = 0; i < 8; i++)
66 ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
67
68 if (ah->ah_version == AR5K_AR5210) {
69 srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;
70 ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
71 } else {
72 srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
73 ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
74 ((srev & 0x0f) << 4), 8);
75 }
76
77 /* Reset to the 5GHz mode */
78 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
79
80 return ret;
81}
82
83/*
84 * Check if a channel is supported
85 */
86bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
87{
88 /* Check if the channel is in our supported range */
89 if (flags & CHANNEL_2GHZ) {
90 if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
91 (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
92 return true;
93 } else if (flags & CHANNEL_5GHZ)
94 if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
95 (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
96 return true;
97
98 return false;
99}
100
101bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
102 struct ieee80211_channel *channel)
103{
104 u8 refclk_freq;
105
106 if ((ah->ah_radio == AR5K_RF5112) ||
107 (ah->ah_radio == AR5K_RF5413) ||
108 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
109 refclk_freq = 40;
110 else
111 refclk_freq = 32;
112
113 if ((channel->center_freq % refclk_freq != 0) &&
114 ((channel->center_freq % refclk_freq < 10) ||
115 (channel->center_freq % refclk_freq > 22)))
116 return true;
117 else
118 return false;
119}
120
32/* 121/*
33 * Used to modify RF Banks before writing them to AR5K_RF_BUFFER 122 * Used to modify RF Banks before writing them to AR5K_RF_BUFFER
34 */ 123 */
@@ -110,12 +199,124 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
110 return data; 199 return data;
111} 200}
112 201
202/**
203 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
204 *
205 * @ah: the &struct ath5k_hw
206 * @channel: the currently set channel upon reset
207 *
208 * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
209 * operation on the AR5212 upon reset. This is a helper for ath5k_hw_phy_init.
210 *
211 * Since delta slope is floating point we split it on its exponent and
212 * mantissa and provide these values on hw.
213 *
214 * For more infos i think this patent is related
215 * http://www.freepatentsonline.com/7184495.html
216 */
217static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
218 struct ieee80211_channel *channel)
219{
220 /* Get exponent and mantissa and set it */
221 u32 coef_scaled, coef_exp, coef_man,
222 ds_coef_exp, ds_coef_man, clock;
223
224 BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
225 !(channel->hw_value & CHANNEL_OFDM));
226
227 /* Get coefficient
228 * ALGO: coef = (5 * clock / carrier_freq) / 2
229 * we scale coef by shifting clock value by 24 for
230 * better precision since we use integers */
231 switch (ah->ah_bwmode) {
232 case AR5K_BWMODE_40MHZ:
233 clock = 40 * 2;
234 break;
235 case AR5K_BWMODE_10MHZ:
236 clock = 40 / 2;
237 break;
238 case AR5K_BWMODE_5MHZ:
239 clock = 40 / 4;
240 break;
241 default:
242 clock = 40;
243 break;
244 }
245 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
246
247 /* Get exponent
248 * ALGO: coef_exp = 14 - highest set bit position */
249 coef_exp = ilog2(coef_scaled);
250
251 /* Doesn't make sense if it's zero*/
252 if (!coef_scaled || !coef_exp)
253 return -EINVAL;
254
255 /* Note: we've shifted coef_scaled by 24 */
256 coef_exp = 14 - (coef_exp - 24);
257
258
259 /* Get mantissa (significant digits)
260 * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */
261 coef_man = coef_scaled +
262 (1 << (24 - coef_exp - 1));
263
264 /* Calculate delta slope coefficient exponent
265 * and mantissa (remove scaling) and set them on hw */
266 ds_coef_man = coef_man >> (24 - coef_exp);
267 ds_coef_exp = coef_exp - 16;
268
269 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
270 AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
271 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
272 AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
273
274 return 0;
275}
276
277int ath5k_hw_phy_disable(struct ath5k_hw *ah)
278{
279 /*Just a try M.F.*/
280 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
281
282 return 0;
283}
284
285/*
286 * Wait for synth to settle
287 */
288static void ath5k_hw_wait_for_synth(struct ath5k_hw *ah,
289 struct ieee80211_channel *channel)
290{
291 /*
292 * On 5211+ read activation -> rx delay
293 * and use it (100ns steps).
294 */
295 if (ah->ah_version != AR5K_AR5210) {
296 u32 delay;
297 delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
298 AR5K_PHY_RX_DELAY_M;
299 delay = (channel->hw_value & CHANNEL_CCK) ?
300 ((delay << 2) / 22) : (delay / 10);
301 if (ah->ah_bwmode == AR5K_BWMODE_10MHZ)
302 delay = delay << 1;
303 if (ah->ah_bwmode == AR5K_BWMODE_5MHZ)
304 delay = delay << 2;
305 /* XXX: /2 on turbo ? Let's be safe
306 * for now */
307 udelay(100 + delay);
308 } else {
309 mdelay(1);
310 }
311}
312
313
113/**********************\ 314/**********************\
114* RF Gain optimization * 315* RF Gain optimization *
115\**********************/ 316\**********************/
116 317
117/* 318/*
118 * This code is used to optimize rf gain on different environments 319 * This code is used to optimize RF gain on different environments
119 * (temperature mostly) based on feedback from a power detector. 320 * (temperature mostly) based on feedback from a power detector.
120 * 321 *
121 * It's only used on RF5111 and RF5112, later RF chips seem to have 322 * It's only used on RF5111 and RF5112, later RF chips seem to have
@@ -134,11 +335,11 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
134 * http://madwifi-project.org/ticket/1659 335 * http://madwifi-project.org/ticket/1659
135 * with various measurements and diagrams 336 * with various measurements and diagrams
136 * 337 *
137 * TODO: Deal with power drops due to probes by setting an apropriate 338 * TODO: Deal with power drops due to probes by setting an appropriate
138 * tx power on the probe packets ! Make this part of the calibration process. 339 * tx power on the probe packets ! Make this part of the calibration process.
139 */ 340 */
140 341
141/* Initialize ah_gain durring attach */ 342/* Initialize ah_gain during attach */
142int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah) 343int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
143{ 344{
144 /* Initialize the gain optimization values */ 345 /* Initialize the gain optimization values */
@@ -302,7 +503,7 @@ static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
302} 503}
303 504
304/* Perform gain_F adjustment by choosing the right set 505/* Perform gain_F adjustment by choosing the right set
305 * of parameters from rf gain optimization ladder */ 506 * of parameters from RF gain optimization ladder */
306static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah) 507static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
307{ 508{
308 const struct ath5k_gain_opt *go; 509 const struct ath5k_gain_opt *go;
@@ -367,7 +568,7 @@ done:
367 return ret; 568 return ret;
368} 569}
369 570
370/* Main callback for thermal rf gain calibration engine 571/* Main callback for thermal RF gain calibration engine
371 * Check for a new gain reading and schedule an adjustment 572 * Check for a new gain reading and schedule an adjustment
372 * if needed. 573 * if needed.
373 * 574 *
@@ -433,13 +634,13 @@ done:
433 return ah->ah_gain.g_state; 634 return ah->ah_gain.g_state;
434} 635}
435 636
436/* Write initial rf gain table to set the RF sensitivity 637/* Write initial RF gain table to set the RF sensitivity
437 * this one works on all RF chips and has nothing to do 638 * this one works on all RF chips and has nothing to do
438 * with gain_F calibration */ 639 * with gain_F calibration */
439int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) 640static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, enum ieee80211_band band)
440{ 641{
441 const struct ath5k_ini_rfgain *ath5k_rfg; 642 const struct ath5k_ini_rfgain *ath5k_rfg;
442 unsigned int i, size; 643 unsigned int i, size, index;
443 644
444 switch (ah->ah_radio) { 645 switch (ah->ah_radio) {
445 case AR5K_RF5111: 646 case AR5K_RF5111:
@@ -471,17 +672,11 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
471 return -EINVAL; 672 return -EINVAL;
472 } 673 }
473 674
474 switch (freq) { 675 index = (band == IEEE80211_BAND_2GHZ) ? 1 : 0;
475 case AR5K_INI_RFGAIN_2GHZ:
476 case AR5K_INI_RFGAIN_5GHZ:
477 break;
478 default:
479 return -EINVAL;
480 }
481 676
482 for (i = 0; i < size; i++) { 677 for (i = 0; i < size; i++) {
483 AR5K_REG_WAIT(i); 678 AR5K_REG_WAIT(i);
484 ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq], 679 ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[index],
485 (u32)ath5k_rfg[i].rfg_register); 680 (u32)ath5k_rfg[i].rfg_register);
486 } 681 }
487 682
@@ -494,12 +689,11 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
494* RF Registers setup * 689* RF Registers setup *
495\********************/ 690\********************/
496 691
497
498/* 692/*
499 * Setup RF registers by writing rf buffer on hw 693 * Setup RF registers by writing RF buffer on hw
500 */ 694 */
501int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, 695static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
502 unsigned int mode) 696 struct ieee80211_channel *channel, unsigned int mode)
503{ 697{
504 const struct ath5k_rf_reg *rf_regs; 698 const struct ath5k_rf_reg *rf_regs;
505 const struct ath5k_ini_rfbuffer *ini_rfb; 699 const struct ath5k_ini_rfbuffer *ini_rfb;
@@ -571,7 +765,7 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
571 return -EINVAL; 765 return -EINVAL;
572 } 766 }
573 767
574 /* If it's the first time we set rf buffer, allocate 768 /* If it's the first time we set RF buffer, allocate
575 * ah->ah_rf_banks based on ah->ah_rf_banks_size 769 * ah->ah_rf_banks based on ah->ah_rf_banks_size
576 * we set above */ 770 * we set above */
577 if (ah->ah_rf_banks == NULL) { 771 if (ah->ah_rf_banks == NULL) {
@@ -652,6 +846,11 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
652 846
653 g_step = &go->go_step[ah->ah_gain.g_step_idx]; 847 g_step = &go->go_step[ah->ah_gain.g_step_idx];
654 848
849 /* Set turbo mode (N/A on RF5413) */
850 if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) &&
851 (ah->ah_radio != AR5K_RF5413))
852 ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_TURBO, false);
853
655 /* Bank Modifications (chip-specific) */ 854 /* Bank Modifications (chip-specific) */
656 if (ah->ah_radio == AR5K_RF5111) { 855 if (ah->ah_radio == AR5K_RF5111) {
657 856
@@ -691,7 +890,23 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
691 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode], 890 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
692 AR5K_RF_PLO_SEL, true); 891 AR5K_RF_PLO_SEL, true);
693 892
694 /* TODO: Half/quarter channel support */ 893 /* Tweak power detectors for half/quarter rate support */
894 if (ah->ah_bwmode == AR5K_BWMODE_5MHZ ||
895 ah->ah_bwmode == AR5K_BWMODE_10MHZ) {
896 u8 wait_i;
897
898 ath5k_hw_rfb_op(ah, rf_regs, 0x1f,
899 AR5K_RF_WAIT_S, true);
900
901 wait_i = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ?
902 0x1f : 0x10;
903
904 ath5k_hw_rfb_op(ah, rf_regs, wait_i,
905 AR5K_RF_WAIT_I, true);
906 ath5k_hw_rfb_op(ah, rf_regs, 3,
907 AR5K_RF_MAX_TIME, true);
908
909 }
695 } 910 }
696 911
697 if (ah->ah_radio == AR5K_RF5112) { 912 if (ah->ah_radio == AR5K_RF5112) {
@@ -789,8 +1004,20 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
789 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode], 1004 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
790 AR5K_RF_GAIN_I, true); 1005 AR5K_RF_GAIN_I, true);
791 1006
792 /* TODO: Half/quarter channel support */ 1007 /* Tweak power detector for half/quarter rates */
1008 if (ah->ah_bwmode == AR5K_BWMODE_5MHZ ||
1009 ah->ah_bwmode == AR5K_BWMODE_10MHZ) {
1010 u8 pd_delay;
1011
1012 pd_delay = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ?
1013 0xf : 0x8;
1014
1015 ath5k_hw_rfb_op(ah, rf_regs, pd_delay,
1016 AR5K_RF_PD_PERIOD_A, true);
1017 ath5k_hw_rfb_op(ah, rf_regs, 0xf,
1018 AR5K_RF_PD_DELAY_A, true);
793 1019
1020 }
794 } 1021 }
795 1022
796 if (ah->ah_radio == AR5K_RF5413 && 1023 if (ah->ah_radio == AR5K_RF5413 &&
@@ -822,25 +1049,7 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
822\**************************/ 1049\**************************/
823 1050
824/* 1051/*
825 * Check if a channel is supported 1052 * Conversion needed for RF5110
826 */
827bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
828{
829 /* Check if the channel is in our supported range */
830 if (flags & CHANNEL_2GHZ) {
831 if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
832 (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
833 return true;
834 } else if (flags & CHANNEL_5GHZ)
835 if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
836 (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
837 return true;
838
839 return false;
840}
841
842/*
843 * Convertion needed for RF5110
844 */ 1053 */
845static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel) 1054static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel)
846{ 1055{
@@ -879,7 +1088,7 @@ static int ath5k_hw_rf5110_channel(struct ath5k_hw *ah,
879} 1088}
880 1089
881/* 1090/*
882 * Convertion needed for 5111 1091 * Conversion needed for 5111
883 */ 1092 */
884static int ath5k_hw_rf5111_chan2athchan(unsigned int ieee, 1093static int ath5k_hw_rf5111_chan2athchan(unsigned int ieee,
885 struct ath5k_athchan_2ghz *athchan) 1094 struct ath5k_athchan_2ghz *athchan)
@@ -1045,7 +1254,8 @@ static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
1045/* 1254/*
1046 * Set a channel on the radio chip 1255 * Set a channel on the radio chip
1047 */ 1256 */
1048int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) 1257static int ath5k_hw_channel(struct ath5k_hw *ah,
1258 struct ieee80211_channel *channel)
1049{ 1259{
1050 int ret; 1260 int ret;
1051 /* 1261 /*
@@ -1071,6 +1281,7 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
1071 case AR5K_RF5111: 1281 case AR5K_RF5111:
1072 ret = ath5k_hw_rf5111_channel(ah, channel); 1282 ret = ath5k_hw_rf5111_channel(ah, channel);
1073 break; 1283 break;
1284 case AR5K_RF2317:
1074 case AR5K_RF2425: 1285 case AR5K_RF2425:
1075 ret = ath5k_hw_rf2425_channel(ah, channel); 1286 ret = ath5k_hw_rf2425_channel(ah, channel);
1076 break; 1287 break;
@@ -1092,7 +1303,6 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
1092 } 1303 }
1093 1304
1094 ah->ah_current_channel = channel; 1305 ah->ah_current_channel = channel;
1095 ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
1096 1306
1097 return 0; 1307 return 0;
1098} 1308}
@@ -1101,18 +1311,12 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
1101 PHY calibration 1311 PHY calibration
1102\*****************/ 1312\*****************/
1103 1313
1104static int sign_extend(int val, const int nbits)
1105{
1106 int order = BIT(nbits-1);
1107 return (val ^ order) - order;
1108}
1109
1110static s32 ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah) 1314static s32 ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah)
1111{ 1315{
1112 s32 val; 1316 s32 val;
1113 1317
1114 val = ath5k_hw_reg_read(ah, AR5K_PHY_NF); 1318 val = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
1115 return sign_extend(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 9); 1319 return sign_extend32(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 8);
1116} 1320}
1117 1321
1118void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah) 1322void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah)
@@ -1180,22 +1384,7 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1180 return; 1384 return;
1181 } 1385 }
1182 1386
1183 switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) { 1387 ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel);
1184 case CHANNEL_A:
1185 case CHANNEL_T:
1186 case CHANNEL_XR:
1187 ee_mode = AR5K_EEPROM_MODE_11A;
1188 break;
1189 case CHANNEL_G:
1190 case CHANNEL_TG:
1191 ee_mode = AR5K_EEPROM_MODE_11G;
1192 break;
1193 default:
1194 case CHANNEL_B:
1195 ee_mode = AR5K_EEPROM_MODE_11B;
1196 break;
1197 }
1198
1199 1388
1200 /* completed NF calibration, test threshold */ 1389 /* completed NF calibration, test threshold */
1201 nf = ath5k_hw_read_measured_noise_floor(ah); 1390 nf = ath5k_hw_read_measured_noise_floor(ah);
@@ -1257,7 +1446,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
1257 * Disable beacons and RX/TX queues, wait 1446 * Disable beacons and RX/TX queues, wait
1258 */ 1447 */
1259 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210, 1448 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210,
1260 AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210); 1449 AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210);
1261 beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210); 1450 beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210);
1262 ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210); 1451 ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210);
1263 1452
@@ -1336,7 +1525,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
1336 * Re-enable RX/TX and beacons 1525 * Re-enable RX/TX and beacons
1337 */ 1526 */
1338 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210, 1527 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210,
1339 AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210); 1528 AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210);
1340 ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210); 1529 ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210);
1341 1530
1342 return 0; 1531 return 0;
@@ -1377,7 +1566,7 @@ ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah)
1377 1566
1378 /* protect against divide by 0 and loss of sign bits */ 1567 /* protect against divide by 0 and loss of sign bits */
1379 if (i_coffd == 0 || q_coffd < 2) 1568 if (i_coffd == 0 || q_coffd < 2)
1380 return -1; 1569 return 0;
1381 1570
1382 i_coff = (-iq_corr) / i_coffd; 1571 i_coff = (-iq_corr) / i_coffd;
1383 i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ 1572 i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */
@@ -1424,31 +1613,12 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1424 return ret; 1613 return ret;
1425} 1614}
1426 1615
1616
1427/***************************\ 1617/***************************\
1428* Spur mitigation functions * 1618* Spur mitigation functions *
1429\***************************/ 1619\***************************/
1430 1620
1431bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, 1621static void
1432 struct ieee80211_channel *channel)
1433{
1434 u8 refclk_freq;
1435
1436 if ((ah->ah_radio == AR5K_RF5112) ||
1437 (ah->ah_radio == AR5K_RF5413) ||
1438 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
1439 refclk_freq = 40;
1440 else
1441 refclk_freq = 32;
1442
1443 if ((channel->center_freq % refclk_freq != 0) &&
1444 ((channel->center_freq % refclk_freq < 10) ||
1445 (channel->center_freq % refclk_freq > 22)))
1446 return true;
1447 else
1448 return false;
1449}
1450
1451void
1452ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, 1622ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1453 struct ieee80211_channel *channel) 1623 struct ieee80211_channel *channel)
1454{ 1624{
@@ -1477,7 +1647,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1477 spur_chan_fbin = AR5K_EEPROM_NO_SPUR; 1647 spur_chan_fbin = AR5K_EEPROM_NO_SPUR;
1478 spur_detection_window = AR5K_SPUR_CHAN_WIDTH; 1648 spur_detection_window = AR5K_SPUR_CHAN_WIDTH;
1479 /* XXX: Half/Quarter channels ?*/ 1649 /* XXX: Half/Quarter channels ?*/
1480 if (channel->hw_value & CHANNEL_TURBO) 1650 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
1481 spur_detection_window *= 2; 1651 spur_detection_window *= 2;
1482 1652
1483 for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) { 1653 for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
@@ -1506,32 +1676,43 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1506 * Calculate deltas: 1676 * Calculate deltas:
1507 * spur_freq_sigma_delta -> spur_offset / sample_freq << 21 1677 * spur_freq_sigma_delta -> spur_offset / sample_freq << 21
1508 * spur_delta_phase -> spur_offset / chip_freq << 11 1678 * spur_delta_phase -> spur_offset / chip_freq << 11
1509 * Note: Both values have 100KHz resolution 1679 * Note: Both values have 100Hz resolution
1510 */ 1680 */
1511 /* XXX: Half/Quarter rate channels ? */ 1681 switch (ah->ah_bwmode) {
1512 switch (channel->hw_value) { 1682 case AR5K_BWMODE_40MHZ:
1513 case CHANNEL_A:
1514 /* Both sample_freq and chip_freq are 40MHz */
1515 spur_delta_phase = (spur_offset << 17) / 25;
1516 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1517 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
1518 break;
1519 case CHANNEL_G:
1520 /* sample_freq -> 40MHz chip_freq -> 44MHz
1521 * (for b compatibility) */
1522 spur_freq_sigma_delta = (spur_offset << 8) / 55;
1523 spur_delta_phase = (spur_offset << 17) / 25;
1524 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
1525 break;
1526 case CHANNEL_T:
1527 case CHANNEL_TG:
1528 /* Both sample_freq and chip_freq are 80MHz */ 1683 /* Both sample_freq and chip_freq are 80MHz */
1529 spur_delta_phase = (spur_offset << 16) / 25; 1684 spur_delta_phase = (spur_offset << 16) / 25;
1530 spur_freq_sigma_delta = (spur_delta_phase >> 10); 1685 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1531 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz; 1686 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz * 2;
1532 break; 1687 break;
1688 case AR5K_BWMODE_10MHZ:
1689 /* Both sample_freq and chip_freq are 20MHz (?) */
1690 spur_delta_phase = (spur_offset << 18) / 25;
1691 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1692 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 2;
1693 case AR5K_BWMODE_5MHZ:
1694 /* Both sample_freq and chip_freq are 10MHz (?) */
1695 spur_delta_phase = (spur_offset << 19) / 25;
1696 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1697 symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4;
1533 default: 1698 default:
1534 return; 1699 if (channel->hw_value == CHANNEL_A) {
1700 /* Both sample_freq and chip_freq are 40MHz */
1701 spur_delta_phase = (spur_offset << 17) / 25;
1702 spur_freq_sigma_delta =
1703 (spur_delta_phase >> 10);
1704 symbol_width =
1705 AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
1706 } else {
1707 /* sample_freq -> 40MHz chip_freq -> 44MHz
1708 * (for b compatibility) */
1709 spur_delta_phase = (spur_offset << 17) / 25;
1710 spur_freq_sigma_delta =
1711 (spur_offset << 8) / 55;
1712 symbol_width =
1713 AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
1714 }
1715 break;
1535 } 1716 }
1536 1717
1537 /* Calculate pilot and magnitude masks */ 1718 /* Calculate pilot and magnitude masks */
@@ -1582,7 +1763,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1582 else if (curr_sym_off >= 31 && curr_sym_off <= 46) 1763 else if (curr_sym_off >= 31 && curr_sym_off <= 46)
1583 mag_mask[2] |= 1764 mag_mask[2] |=
1584 plt_mag_map << (curr_sym_off - 31) * 2; 1765 plt_mag_map << (curr_sym_off - 31) * 2;
1585 else if (curr_sym_off >= 46 && curr_sym_off <= 53) 1766 else if (curr_sym_off >= 47 && curr_sym_off <= 53)
1586 mag_mask[3] |= 1767 mag_mask[3] |=
1587 plt_mag_map << (curr_sym_off - 47) * 2; 1768 plt_mag_map << (curr_sym_off - 47) * 2;
1588 1769
@@ -1671,63 +1852,6 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1671 } 1852 }
1672} 1853}
1673 1854
1674/********************\
1675 Misc PHY functions
1676\********************/
1677
1678int ath5k_hw_phy_disable(struct ath5k_hw *ah)
1679{
1680 /*Just a try M.F.*/
1681 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
1682
1683 return 0;
1684}
1685
1686/*
1687 * Get the PHY Chip revision
1688 */
1689u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
1690{
1691 unsigned int i;
1692 u32 srev;
1693 u16 ret;
1694
1695 /*
1696 * Set the radio chip access register
1697 */
1698 switch (chan) {
1699 case CHANNEL_2GHZ:
1700 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
1701 break;
1702 case CHANNEL_5GHZ:
1703 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
1704 break;
1705 default:
1706 return 0;
1707 }
1708
1709 mdelay(2);
1710
1711 /* ...wait until PHY is ready and read the selected radio revision */
1712 ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
1713
1714 for (i = 0; i < 8; i++)
1715 ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
1716
1717 if (ah->ah_version == AR5K_AR5210) {
1718 srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;
1719 ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
1720 } else {
1721 srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
1722 ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
1723 ((srev & 0x0f) << 4), 8);
1724 }
1725
1726 /* Reset to the 5GHz mode */
1727 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
1728
1729 return ret;
1730}
1731 1855
1732/*****************\ 1856/*****************\
1733* Antenna control * 1857* Antenna control *
@@ -1821,7 +1945,8 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
1821 struct ieee80211_channel *channel = ah->ah_current_channel; 1945 struct ieee80211_channel *channel = ah->ah_current_channel;
1822 bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div; 1946 bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
1823 bool use_def_for_sg; 1947 bool use_def_for_sg;
1824 u8 def_ant, tx_ant, ee_mode; 1948 int ee_mode;
1949 u8 def_ant, tx_ant;
1825 u32 sta_id1 = 0; 1950 u32 sta_id1 = 0;
1826 1951
1827 /* if channel is not initialized yet we can't set the antennas 1952 /* if channel is not initialized yet we can't set the antennas
@@ -1833,20 +1958,8 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
1833 1958
1834 def_ant = ah->ah_def_ant; 1959 def_ant = ah->ah_def_ant;
1835 1960
1836 switch (channel->hw_value & CHANNEL_MODES) { 1961 ee_mode = ath5k_eeprom_mode_from_channel(channel);
1837 case CHANNEL_A: 1962 if (ee_mode < 0) {
1838 case CHANNEL_T:
1839 case CHANNEL_XR:
1840 ee_mode = AR5K_EEPROM_MODE_11A;
1841 break;
1842 case CHANNEL_G:
1843 case CHANNEL_TG:
1844 ee_mode = AR5K_EEPROM_MODE_11G;
1845 break;
1846 case CHANNEL_B:
1847 ee_mode = AR5K_EEPROM_MODE_11B;
1848 break;
1849 default:
1850 ATH5K_ERR(ah->ah_sc, 1963 ATH5K_ERR(ah->ah_sc,
1851 "invalid channel: %d\n", channel->center_freq); 1964 "invalid channel: %d\n", channel->center_freq);
1852 return; 1965 return;
@@ -2088,7 +2201,7 @@ ath5k_create_power_curve(s16 pmin, s16 pmax,
2088/* 2201/*
2089 * Get the surrounding per-channel power calibration piers 2202 * Get the surrounding per-channel power calibration piers
2090 * for a given frequency so that we can interpolate between 2203 * for a given frequency so that we can interpolate between
2091 * them and come up with an apropriate dataset for our current 2204 * them and come up with an appropriate dataset for our current
2092 * channel. 2205 * channel.
2093 */ 2206 */
2094static void 2207static void
@@ -2274,20 +2387,20 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,
2274 2387
2275 switch (channel->hw_value & CHANNEL_MODES) { 2388 switch (channel->hw_value & CHANNEL_MODES) {
2276 case CHANNEL_A: 2389 case CHANNEL_A:
2277 ctl_mode |= AR5K_CTL_11A; 2390 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
2391 ctl_mode |= AR5K_CTL_TURBO;
2392 else
2393 ctl_mode |= AR5K_CTL_11A;
2278 break; 2394 break;
2279 case CHANNEL_G: 2395 case CHANNEL_G:
2280 ctl_mode |= AR5K_CTL_11G; 2396 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
2397 ctl_mode |= AR5K_CTL_TURBOG;
2398 else
2399 ctl_mode |= AR5K_CTL_11G;
2281 break; 2400 break;
2282 case CHANNEL_B: 2401 case CHANNEL_B:
2283 ctl_mode |= AR5K_CTL_11B; 2402 ctl_mode |= AR5K_CTL_11B;
2284 break; 2403 break;
2285 case CHANNEL_T:
2286 ctl_mode |= AR5K_CTL_TURBO;
2287 break;
2288 case CHANNEL_TG:
2289 ctl_mode |= AR5K_CTL_TURBOG;
2290 break;
2291 case CHANNEL_XR: 2404 case CHANNEL_XR:
2292 /* Fall through */ 2405 /* Fall through */
2293 default: 2406 default:
@@ -2481,7 +2594,7 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
2481 2594
2482/* Write PCDAC values on hw */ 2595/* Write PCDAC values on hw */
2483static void 2596static void
2484ath5k_setup_pcdac_table(struct ath5k_hw *ah) 2597ath5k_write_pcdac_table(struct ath5k_hw *ah)
2485{ 2598{
2486 u8 *pcdac_out = ah->ah_txpower.txp_pd_table; 2599 u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
2487 int i; 2600 int i;
@@ -2505,7 +2618,7 @@ ath5k_setup_pcdac_table(struct ath5k_hw *ah)
2505/* 2618/*
2506 * Set the gain boundaries and create final Power to PDADC table 2619 * Set the gain boundaries and create final Power to PDADC table
2507 * 2620 *
2508 * We can have up to 4 pd curves, we need to do a simmilar process 2621 * We can have up to 4 pd curves, we need to do a similar process
2509 * as we do for RF5112. This time we don't have an edge_flag but we 2622 * as we do for RF5112. This time we don't have an edge_flag but we
2510 * set the gain boundaries on a separate register. 2623 * set the gain boundaries on a separate register.
2511 */ 2624 */
@@ -2630,10 +2743,12 @@ ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
2630 2743
2631/* Write PDADC values on hw */ 2744/* Write PDADC values on hw */
2632static void 2745static void
2633ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah, 2746ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode)
2634 u8 pdcurves, u8 *pdg_to_idx)
2635{ 2747{
2748 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2636 u8 *pdadc_out = ah->ah_txpower.txp_pd_table; 2749 u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
2750 u8 *pdg_to_idx = ee->ee_pdc_to_idx[ee_mode];
2751 u8 pdcurves = ee->ee_pd_gains[ee_mode];
2637 u32 reg; 2752 u32 reg;
2638 u8 i; 2753 u8 i;
2639 2754
@@ -2711,13 +2826,13 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
2711 u32 target = channel->center_freq; 2826 u32 target = channel->center_freq;
2712 int pdg, i; 2827 int pdg, i;
2713 2828
2714 /* Get surounding freq piers for this channel */ 2829 /* Get surrounding freq piers for this channel */
2715 ath5k_get_chan_pcal_surrounding_piers(ah, channel, 2830 ath5k_get_chan_pcal_surrounding_piers(ah, channel,
2716 &pcinfo_L, 2831 &pcinfo_L,
2717 &pcinfo_R); 2832 &pcinfo_R);
2718 2833
2719 /* Loop over pd gain curves on 2834 /* Loop over pd gain curves on
2720 * surounding freq piers by index */ 2835 * surrounding freq piers by index */
2721 for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) { 2836 for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) {
2722 2837
2723 /* Fill curves in reverse order 2838 /* Fill curves in reverse order
@@ -2808,7 +2923,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
2808 } 2923 }
2809 2924
2810 /* Interpolate between curves 2925 /* Interpolate between curves
2811 * of surounding freq piers to 2926 * of surrounding freq piers to
2812 * get the final curve for this 2927 * get the final curve for this
2813 * pd gain. Re-use tmpL for interpolation 2928 * pd gain. Re-use tmpL for interpolation
2814 * output */ 2929 * output */
@@ -2832,7 +2947,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
2832 2947
2833 /* Fill min and max power levels for this 2948 /* Fill min and max power levels for this
2834 * channel by interpolating the values on 2949 * channel by interpolating the values on
2835 * surounding channels to complete the dataset */ 2950 * surrounding channels to complete the dataset */
2836 ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target, 2951 ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target,
2837 (s16) pcinfo_L->freq, 2952 (s16) pcinfo_L->freq,
2838 (s16) pcinfo_R->freq, 2953 (s16) pcinfo_R->freq,
@@ -2843,8 +2958,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
2843 (s16) pcinfo_R->freq, 2958 (s16) pcinfo_R->freq,
2844 pcinfo_L->max_pwr, pcinfo_R->max_pwr); 2959 pcinfo_L->max_pwr, pcinfo_R->max_pwr);
2845 2960
2846 /* We are ready to go, fill PCDAC/PDADC 2961 /* Fill PCDAC/PDADC table */
2847 * table and write settings on hardware */
2848 switch (type) { 2962 switch (type) {
2849 case AR5K_PWRTABLE_LINEAR_PCDAC: 2963 case AR5K_PWRTABLE_LINEAR_PCDAC:
2850 /* For RF5112 we can have one or two curves 2964 /* For RF5112 we can have one or two curves
@@ -2857,9 +2971,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
2857 * match max power value with max 2971 * match max power value with max
2858 * table index */ 2972 * table index */
2859 ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2); 2973 ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2);
2860
2861 /* Write settings on hw */
2862 ath5k_setup_pcdac_table(ah);
2863 break; 2974 break;
2864 case AR5K_PWRTABLE_PWR_TO_PCDAC: 2975 case AR5K_PWRTABLE_PWR_TO_PCDAC:
2865 /* We are done for RF5111 since it has only 2976 /* We are done for RF5111 since it has only
@@ -2869,9 +2980,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
2869 /* No rate powertable adjustment for RF5111 */ 2980 /* No rate powertable adjustment for RF5111 */
2870 ah->ah_txpower.txp_min_idx = 0; 2981 ah->ah_txpower.txp_min_idx = 0;
2871 ah->ah_txpower.txp_offset = 0; 2982 ah->ah_txpower.txp_offset = 0;
2872
2873 /* Write settings on hw */
2874 ath5k_setup_pcdac_table(ah);
2875 break; 2983 break;
2876 case AR5K_PWRTABLE_PWR_TO_PDADC: 2984 case AR5K_PWRTABLE_PWR_TO_PDADC:
2877 /* Set PDADC boundaries and fill 2985 /* Set PDADC boundaries and fill
@@ -2879,9 +2987,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
2879 ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max, 2987 ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
2880 ee->ee_pd_gains[ee_mode]); 2988 ee->ee_pd_gains[ee_mode]);
2881 2989
2882 /* Write settings on hw */
2883 ath5k_setup_pwr_to_pdadc_table(ah, pdg, pdg_curve_to_idx);
2884
2885 /* Set txp.offset, note that table_min 2990 /* Set txp.offset, note that table_min
2886 * can be negative */ 2991 * can be negative */
2887 ah->ah_txpower.txp_offset = table_min[0]; 2992 ah->ah_txpower.txp_offset = table_min[0];
@@ -2890,9 +2995,20 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
2890 return -EINVAL; 2995 return -EINVAL;
2891 } 2996 }
2892 2997
2998 ah->ah_txpower.txp_setup = true;
2999
2893 return 0; 3000 return 0;
2894} 3001}
2895 3002
3003/* Write power table for current channel to hw */
3004static void
3005ath5k_write_channel_powertable(struct ath5k_hw *ah, u8 ee_mode, u8 type)
3006{
3007 if (type == AR5K_PWRTABLE_PWR_TO_PDADC)
3008 ath5k_write_pwr_to_pdadc_table(ah, ee_mode);
3009 else
3010 ath5k_write_pcdac_table(ah);
3011}
2896 3012
2897/* 3013/*
2898 * Per-rate tx power setting 3014 * Per-rate tx power setting
@@ -2981,19 +3097,21 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
2981 3097
2982 /* Min/max in 0.25dB units */ 3098 /* Min/max in 0.25dB units */
2983 ah->ah_txpower.txp_min_pwr = 2 * rates[7]; 3099 ah->ah_txpower.txp_min_pwr = 2 * rates[7];
2984 ah->ah_txpower.txp_max_pwr = 2 * rates[0]; 3100 ah->ah_txpower.txp_cur_pwr = 2 * rates[0];
2985 ah->ah_txpower.txp_ofdm = rates[7]; 3101 ah->ah_txpower.txp_ofdm = rates[7];
2986} 3102}
2987 3103
2988 3104
2989/* 3105/*
2990 * Set transmition power 3106 * Set transmission power
2991 */ 3107 */
2992int 3108static int
2993ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, 3109ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
2994 u8 ee_mode, u8 txpower) 3110 u8 txpower)
2995{ 3111{
2996 struct ath5k_rate_pcal_info rate_info; 3112 struct ath5k_rate_pcal_info rate_info;
3113 struct ieee80211_channel *curr_channel = ah->ah_current_channel;
3114 int ee_mode;
2997 u8 type; 3115 u8 type;
2998 int ret; 3116 int ret;
2999 3117
@@ -3002,14 +3120,18 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3002 return -EINVAL; 3120 return -EINVAL;
3003 } 3121 }
3004 3122
3005 /* Reset TX power values */ 3123 ee_mode = ath5k_eeprom_mode_from_channel(channel);
3006 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); 3124 if (ee_mode < 0) {
3007 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; 3125 ATH5K_ERR(ah->ah_sc,
3008 ah->ah_txpower.txp_min_pwr = 0; 3126 "invalid channel: %d\n", channel->center_freq);
3009 ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER; 3127 return -EINVAL;
3128 }
3010 3129
3011 /* Initialize TX power table */ 3130 /* Initialize TX power table */
3012 switch (ah->ah_radio) { 3131 switch (ah->ah_radio) {
3132 case AR5K_RF5110:
3133 /* TODO */
3134 return 0;
3013 case AR5K_RF5111: 3135 case AR5K_RF5111:
3014 type = AR5K_PWRTABLE_PWR_TO_PCDAC; 3136 type = AR5K_PWRTABLE_PWR_TO_PCDAC;
3015 break; 3137 break;
@@ -3027,24 +3149,37 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3027 return -EINVAL; 3149 return -EINVAL;
3028 } 3150 }
3029 3151
3030 /* FIXME: Only on channel/mode change */ 3152 /*
3031 ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type); 3153 * If we don't change channel/mode skip tx powertable calculation
3032 if (ret) 3154 * and use the cached one.
3033 return ret; 3155 */
3156 if (!ah->ah_txpower.txp_setup ||
3157 (channel->hw_value != curr_channel->hw_value) ||
3158 (channel->center_freq != curr_channel->center_freq)) {
3159 /* Reset TX power values */
3160 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
3161 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
3162
3163 /* Calculate the powertable */
3164 ret = ath5k_setup_channel_powertable(ah, channel,
3165 ee_mode, type);
3166 if (ret)
3167 return ret;
3168 }
3169
3170 /* Write table on hw */
3171 ath5k_write_channel_powertable(ah, ee_mode, type);
3034 3172
3035 /* Limit max power if we have a CTL available */ 3173 /* Limit max power if we have a CTL available */
3036 ath5k_get_max_ctl_power(ah, channel); 3174 ath5k_get_max_ctl_power(ah, channel);
3037 3175
3038 /* FIXME: Tx power limit for this regdomain
3039 * XXX: Mac80211/CRDA will do that anyway ? */
3040
3041 /* FIXME: Antenna reduction stuff */ 3176 /* FIXME: Antenna reduction stuff */
3042 3177
3043 /* FIXME: Limit power on turbo modes */ 3178 /* FIXME: Limit power on turbo modes */
3044 3179
3045 /* FIXME: TPC scale reduction */ 3180 /* FIXME: TPC scale reduction */
3046 3181
3047 /* Get surounding channels for per-rate power table 3182 /* Get surrounding channels for per-rate power table
3048 * calibration */ 3183 * calibration */
3049 ath5k_get_rate_pcal_data(ah, channel, &rate_info); 3184 ath5k_get_rate_pcal_data(ah, channel, &rate_info);
3050 3185
@@ -3088,31 +3223,223 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3088 3223
3089int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) 3224int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
3090{ 3225{
3091 /*Just a try M.F.*/ 3226 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
3092 struct ieee80211_channel *channel = ah->ah_current_channel; 3227 "changing txpower to %d\n", txpower);
3093 u8 ee_mode;
3094 3228
3095 switch (channel->hw_value & CHANNEL_MODES) { 3229 return ath5k_hw_txpower(ah, ah->ah_current_channel, txpower);
3096 case CHANNEL_A: 3230}
3097 case CHANNEL_T: 3231
3098 case CHANNEL_XR: 3232/*************\
3099 ee_mode = AR5K_EEPROM_MODE_11A; 3233 Init function
3100 break; 3234\*************/
3101 case CHANNEL_G: 3235
3102 case CHANNEL_TG: 3236int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3103 ee_mode = AR5K_EEPROM_MODE_11G; 3237 u8 mode, bool fast)
3104 break; 3238{
3105 case CHANNEL_B: 3239 struct ieee80211_channel *curr_channel;
3106 ee_mode = AR5K_EEPROM_MODE_11B; 3240 int ret, i;
3107 break; 3241 u32 phy_tst1;
3108 default: 3242 ret = 0;
3109 ATH5K_ERR(ah->ah_sc, 3243
3110 "invalid channel: %d\n", channel->center_freq); 3244 /*
3245 * Sanity check for fast flag
3246 * Don't try fast channel change when changing modulation
3247 * mode/band. We check for chip compatibility on
3248 * ath5k_hw_reset.
3249 */
3250 curr_channel = ah->ah_current_channel;
3251 if (fast && (channel->hw_value != curr_channel->hw_value))
3111 return -EINVAL; 3252 return -EINVAL;
3253
3254 /*
3255 * On fast channel change we only set the synth parameters
3256 * while PHY is running, enable calibration and skip the rest.
3257 */
3258 if (fast) {
3259 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
3260 AR5K_PHY_RFBUS_REQ_REQUEST);
3261 for (i = 0; i < 100; i++) {
3262 if (ath5k_hw_reg_read(ah, AR5K_PHY_RFBUS_GRANT))
3263 break;
3264 udelay(5);
3265 }
3266 /* Failed */
3267 if (i >= 100)
3268 return -EIO;
3269
3270 /* Set channel and wait for synth */
3271 ret = ath5k_hw_channel(ah, channel);
3272 if (ret)
3273 return ret;
3274
3275 ath5k_hw_wait_for_synth(ah, channel);
3112 } 3276 }
3113 3277
3114 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER, 3278 /*
3115 "changing txpower to %d\n", txpower); 3279 * Set TX power
3280 *
3281 * Note: We need to do that before we set
3282 * RF buffer settings on 5211/5212+ so that we
3283 * properly set curve indices.
3284 */
3285 ret = ath5k_hw_txpower(ah, channel, ah->ah_txpower.txp_cur_pwr ?
3286 ah->ah_txpower.txp_cur_pwr / 2 : AR5K_TUNE_MAX_TXPOWER);
3287 if (ret)
3288 return ret;
3289
3290 /* Write OFDM timings on 5212*/
3291 if (ah->ah_version == AR5K_AR5212 &&
3292 channel->hw_value & CHANNEL_OFDM) {
3293
3294 ret = ath5k_hw_write_ofdm_timings(ah, channel);
3295 if (ret)
3296 return ret;
3297
3298 /* Spur info is available only from EEPROM versions
3299 * greater than 5.3, but the EEPROM routines will use
3300 * static values for older versions */
3301 if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
3302 ath5k_hw_set_spur_mitigation_filter(ah,
3303 channel);
3304 }
3305
3306 /* If we used fast channel switching
3307 * we are done, release RF bus and
3308 * fire up NF calibration.
3309 *
3310 * Note: Only NF calibration due to
3311 * channel change, not AGC calibration
3312 * since AGC is still running !
3313 */
3314 if (fast) {
3315 /*
3316 * Release RF Bus grant
3317 */
3318 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
3319 AR5K_PHY_RFBUS_REQ_REQUEST);
3320
3321 /*
3322 * Start NF calibration
3323 */
3324 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
3325 AR5K_PHY_AGCCTL_NF);
3116 3326
3117 return ath5k_hw_txpower(ah, channel, ee_mode, txpower); 3327 return ret;
3328 }
3329
3330 /*
3331 * For 5210 we do all initialization using
3332 * initvals, so we don't have to modify
3333 * any settings (5210 also only supports
3334 * a/aturbo modes)
3335 */
3336 if (ah->ah_version != AR5K_AR5210) {
3337
3338 /*
3339 * Write initial RF gain settings
3340 * This should work for both 5111/5112
3341 */
3342 ret = ath5k_hw_rfgain_init(ah, channel->band);
3343 if (ret)
3344 return ret;
3345
3346 mdelay(1);
3347
3348 /*
3349 * Write RF buffer
3350 */
3351 ret = ath5k_hw_rfregs_init(ah, channel, mode);
3352 if (ret)
3353 return ret;
3354
3355 /*Enable/disable 802.11b mode on 5111
3356 (enable 2111 frequency converter + CCK)*/
3357 if (ah->ah_radio == AR5K_RF5111) {
3358 if (mode == AR5K_MODE_11B)
3359 AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
3360 AR5K_TXCFG_B_MODE);
3361 else
3362 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
3363 AR5K_TXCFG_B_MODE);
3364 }
3365
3366 } else if (ah->ah_version == AR5K_AR5210) {
3367 mdelay(1);
3368 /* Disable phy and wait */
3369 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
3370 mdelay(1);
3371 }
3372
3373 /* Set channel on PHY */
3374 ret = ath5k_hw_channel(ah, channel);
3375 if (ret)
3376 return ret;
3377
3378 /*
3379 * Enable the PHY and wait until completion
3380 * This includes BaseBand and Synthesizer
3381 * activation.
3382 */
3383 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
3384
3385 ath5k_hw_wait_for_synth(ah, channel);
3386
3387 /*
3388 * Perform ADC test to see if baseband is ready
3389 * Set tx hold and check adc test register
3390 */
3391 phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
3392 ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
3393 for (i = 0; i <= 20; i++) {
3394 if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
3395 break;
3396 udelay(200);
3397 }
3398 ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
3399
3400 /*
3401 * Start automatic gain control calibration
3402 *
3403 * During AGC calibration RX path is re-routed to
3404 * a power detector so we don't receive anything.
3405 *
3406 * This method is used to calibrate some static offsets
3407 * used together with on-the fly I/Q calibration (the
3408 * one performed via ath5k_hw_phy_calibrate), which doesn't
3409 * interrupt rx path.
3410 *
3411 * While rx path is re-routed to the power detector we also
3412 * start a noise floor calibration to measure the
3413 * card's noise floor (the noise we measure when we are not
3414 * transmitting or receiving anything).
3415 *
3416 * If we are in a noisy environment, AGC calibration may time
3417 * out and/or noise floor calibration might timeout.
3418 */
3419 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
3420 AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);
3421
3422 /* At the same time start I/Q calibration for QAM constellation
3423 * -no need for CCK- */
3424 ah->ah_calibration = false;
3425 if (!(mode == AR5K_MODE_11B)) {
3426 ah->ah_calibration = true;
3427 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
3428 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
3429 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
3430 AR5K_PHY_IQ_RUN);
3431 }
3432
3433 /* Wait for gain calibration to finish (we check for I/Q calibration
3434 * during ath5k_phy_calibrate) */
3435 if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
3436 AR5K_PHY_AGCCTL_CAL, 0, false)) {
3437 ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
3438 channel->center_freq);
3439 }
3440
3441 /* Restore antenna mode */
3442 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
3443
3444 return ret;
3118} 3445}
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 4186ff4c6e9c..b18c5021aac3 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -25,6 +25,68 @@ Queue Control Unit, DFS Control Unit Functions
25#include "debug.h" 25#include "debug.h"
26#include "base.h" 26#include "base.h"
27 27
28
29/******************\
30* Helper functions *
31\******************/
32
33/*
34 * Get number of pending frames
35 * for a specific queue [5211+]
36 */
37u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
38{
39 u32 pending;
40 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
41
42 /* Return if queue is declared inactive */
43 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
44 return false;
45
46 /* XXX: How about AR5K_CFG_TXCNT ? */
47 if (ah->ah_version == AR5K_AR5210)
48 return false;
49
50 pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
51 pending &= AR5K_QCU_STS_FRMPENDCNT;
52
53 /* It's possible to have no frames pending even if TXE
54 * is set. To indicate that q has not stopped return
55 * true */
56 if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
57 return true;
58
59 return pending;
60}
61
62/*
63 * Set a transmit queue inactive
64 */
65void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
66{
67 if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
68 return;
69
70 /* This queue will be skipped in further operations */
71 ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
72 /*For SIMR setup*/
73 AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
74}
75
76/*
77 * Make sure cw is a power of 2 minus 1 and smaller than 1024
78 */
79static u16 ath5k_cw_validate(u16 cw_req)
80{
81 u32 cw = 1;
82 cw_req = min(cw_req, (u16)1023);
83
84 while (cw < cw_req)
85 cw = (cw << 1) | 1;
86
87 return cw;
88}
89
28/* 90/*
29 * Get properties for a transmit queue 91 * Get properties for a transmit queue
30 */ 92 */
@@ -39,21 +101,41 @@ int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
39 * Set properties for a transmit queue 101 * Set properties for a transmit queue
40 */ 102 */
41int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, 103int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
42 const struct ath5k_txq_info *queue_info) 104 const struct ath5k_txq_info *qinfo)
43{ 105{
106 struct ath5k_txq_info *qi;
107
44 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); 108 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
45 109
46 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) 110 qi = &ah->ah_txq[queue];
111
112 if (qi->tqi_type == AR5K_TX_QUEUE_INACTIVE)
47 return -EIO; 113 return -EIO;
48 114
49 memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info)); 115 /* copy and validate values */
116 qi->tqi_type = qinfo->tqi_type;
117 qi->tqi_subtype = qinfo->tqi_subtype;
118 qi->tqi_flags = qinfo->tqi_flags;
119 /*
120 * According to the docs: Although the AIFS field is 8 bit wide,
121 * the maximum supported value is 0xFC. Setting it higher than that
122 * will cause the DCU to hang.
123 */
124 qi->tqi_aifs = min(qinfo->tqi_aifs, (u8)0xFC);
125 qi->tqi_cw_min = ath5k_cw_validate(qinfo->tqi_cw_min);
126 qi->tqi_cw_max = ath5k_cw_validate(qinfo->tqi_cw_max);
127 qi->tqi_cbr_period = qinfo->tqi_cbr_period;
128 qi->tqi_cbr_overflow_limit = qinfo->tqi_cbr_overflow_limit;
129 qi->tqi_burst_time = qinfo->tqi_burst_time;
130 qi->tqi_ready_time = qinfo->tqi_ready_time;
50 131
51 /*XXX: Is this supported on 5210 ?*/ 132 /*XXX: Is this supported on 5210 ?*/
52 if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA && 133 /*XXX: Is this correct for AR5K_WME_AC_VI,VO ???*/
53 ((queue_info->tqi_subtype == AR5K_WME_AC_VI) || 134 if ((qinfo->tqi_type == AR5K_TX_QUEUE_DATA &&
54 (queue_info->tqi_subtype == AR5K_WME_AC_VO))) || 135 ((qinfo->tqi_subtype == AR5K_WME_AC_VI) ||
55 queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD) 136 (qinfo->tqi_subtype == AR5K_WME_AC_VO))) ||
56 ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS; 137 qinfo->tqi_type == AR5K_TX_QUEUE_UAPSD)
138 qi->tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
57 139
58 return 0; 140 return 0;
59} 141}
@@ -70,8 +152,8 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
70 /* 152 /*
71 * Get queue by type 153 * Get queue by type
72 */ 154 */
73 /*5210 only has 2 queues*/ 155 /* 5210 only has 2 queues */
74 if (ah->ah_version == AR5K_AR5210) { 156 if (ah->ah_capabilities.cap_queues.q_tx_num == 2) {
75 switch (queue_type) { 157 switch (queue_type) {
76 case AR5K_TX_QUEUE_DATA: 158 case AR5K_TX_QUEUE_DATA:
77 queue = AR5K_TX_QUEUE_ID_NOQCU_DATA; 159 queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
@@ -138,392 +220,431 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
138 return queue; 220 return queue;
139} 221}
140 222
141/*
142 * Get number of pending frames
143 * for a specific queue [5211+]
144 */
145u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
146{
147 u32 pending;
148 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
149
150 /* Return if queue is declared inactive */
151 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
152 return false;
153
154 /* XXX: How about AR5K_CFG_TXCNT ? */
155 if (ah->ah_version == AR5K_AR5210)
156 return false;
157
158 pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
159 pending &= AR5K_QCU_STS_FRMPENDCNT;
160
161 /* It's possible to have no frames pending even if TXE
162 * is set. To indicate that q has not stopped return
163 * true */
164 if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
165 return true;
166 223
167 return pending; 224/*******************************\
168} 225* Single QCU/DCU initialization *
226\*******************************/
169 227
170/* 228/*
171 * Set a transmit queue inactive 229 * Set tx retry limits on DCU
172 */ 230 */
173void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue) 231void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah,
232 unsigned int queue)
174{ 233{
175 if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num)) 234 /* Single data queue on AR5210 */
176 return; 235 if (ah->ah_version == AR5K_AR5210) {
236 struct ath5k_txq_info *tq = &ah->ah_txq[queue];
177 237
178 /* This queue will be skipped in further operations */ 238 if (queue > 0)
179 ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE; 239 return;
180 /*For SIMR setup*/ 240
181 AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue); 241 ath5k_hw_reg_write(ah,
242 (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
243 | AR5K_REG_SM(ah->ah_retry_long,
244 AR5K_NODCU_RETRY_LMT_SLG_RETRY)
245 | AR5K_REG_SM(ah->ah_retry_short,
246 AR5K_NODCU_RETRY_LMT_SSH_RETRY)
247 | AR5K_REG_SM(ah->ah_retry_long,
248 AR5K_NODCU_RETRY_LMT_LG_RETRY)
249 | AR5K_REG_SM(ah->ah_retry_short,
250 AR5K_NODCU_RETRY_LMT_SH_RETRY),
251 AR5K_NODCU_RETRY_LMT);
252 /* DCU on AR5211+ */
253 } else {
254 ath5k_hw_reg_write(ah,
255 AR5K_REG_SM(ah->ah_retry_long,
256 AR5K_DCU_RETRY_LMT_RTS)
257 | AR5K_REG_SM(ah->ah_retry_long,
258 AR5K_DCU_RETRY_LMT_STA_RTS)
259 | AR5K_REG_SM(max(ah->ah_retry_long, ah->ah_retry_short),
260 AR5K_DCU_RETRY_LMT_STA_DATA),
261 AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
262 }
182} 263}
183 264
184/* 265/**
185 * Set DFS properties for a transmit queue on DCU 266 * ath5k_hw_reset_tx_queue - Initialize a single hw queue
267 *
268 * @ah The &struct ath5k_hw
269 * @queue The hw queue number
270 *
271 * Set DFS properties for the given transmit queue on DCU
272 * and configures all queue-specific parameters.
186 */ 273 */
187int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) 274int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
188{ 275{
189 u32 cw_min, cw_max, retry_lg, retry_sh;
190 struct ath5k_txq_info *tq = &ah->ah_txq[queue]; 276 struct ath5k_txq_info *tq = &ah->ah_txq[queue];
191 277
192 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); 278 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
193 279
194 tq = &ah->ah_txq[queue]; 280 tq = &ah->ah_txq[queue];
195 281
196 if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE) 282 /* Skip if queue inactive or if we are on AR5210
283 * that doesn't have QCU/DCU */
284 if ((ah->ah_version == AR5K_AR5210) ||
285 (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE))
197 return 0; 286 return 0;
198 287
199 if (ah->ah_version == AR5K_AR5210) {
200 /* Only handle data queues, others will be ignored */
201 if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
202 return 0;
203
204 /* Set Slot time */
205 ath5k_hw_reg_write(ah, ah->ah_turbo ?
206 AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
207 AR5K_SLOT_TIME);
208 /* Set ACK_CTS timeout */
209 ath5k_hw_reg_write(ah, ah->ah_turbo ?
210 AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
211 AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
212 /* Set Transmit Latency */
213 ath5k_hw_reg_write(ah, ah->ah_turbo ?
214 AR5K_INIT_TRANSMIT_LATENCY_TURBO :
215 AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
216
217 /* Set IFS0 */
218 if (ah->ah_turbo) {
219 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
220 (ah->ah_aifs + tq->tqi_aifs) *
221 AR5K_INIT_SLOT_TIME_TURBO) <<
222 AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
223 AR5K_IFS0);
224 } else {
225 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
226 (ah->ah_aifs + tq->tqi_aifs) *
227 AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) |
228 AR5K_INIT_SIFS, AR5K_IFS0);
229 }
230
231 /* Set IFS1 */
232 ath5k_hw_reg_write(ah, ah->ah_turbo ?
233 AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
234 AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
235 /* Set AR5K_PHY_SETTLING */
236 ath5k_hw_reg_write(ah, ah->ah_turbo ?
237 (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
238 | 0x38 :
239 (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
240 | 0x1C,
241 AR5K_PHY_SETTLING);
242 /* Set Frame Control Register */
243 ath5k_hw_reg_write(ah, ah->ah_turbo ?
244 (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
245 AR5K_PHY_TURBO_SHORT | 0x2020) :
246 (AR5K_PHY_FRAME_CTL_INI | 0x1020),
247 AR5K_PHY_FRAME_CTL_5210);
248 }
249
250 /* 288 /*
251 * Calculate cwmin/max by channel mode 289 * Set contention window (cw_min/cw_max)
290 * and arbitrated interframe space (aifs)...
252 */ 291 */
253 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN; 292 ath5k_hw_reg_write(ah,
254 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX; 293 AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
255 ah->ah_aifs = AR5K_TUNE_AIFS; 294 AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
256 /*XR is only supported on 5212*/ 295 AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),
257 if (IS_CHAN_XR(ah->ah_current_channel) && 296 AR5K_QUEUE_DFS_LOCAL_IFS(queue));
258 ah->ah_version == AR5K_AR5212) {
259 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR;
260 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR;
261 ah->ah_aifs = AR5K_TUNE_AIFS_XR;
262 /*B mode is not supported on 5210*/
263 } else if (IS_CHAN_B(ah->ah_current_channel) &&
264 ah->ah_version != AR5K_AR5210) {
265 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B;
266 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B;
267 ah->ah_aifs = AR5K_TUNE_AIFS_11B;
268 }
269 297
270 cw_min = 1; 298 /*
271 while (cw_min < ah->ah_cw_min) 299 * Set tx retry limits for this queue
272 cw_min = (cw_min << 1) | 1; 300 */
301 ath5k_hw_set_tx_retry_limits(ah, queue);
273 302
274 cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) :
275 ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
276 cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) :
277 ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
278 303
279 /* 304 /*
280 * Calculate and set retry limits 305 * Set misc registers
281 */ 306 */
282 if (ah->ah_software_retry) {
283 /* XXX Need to test this */
284 retry_lg = ah->ah_limit_tx_retries;
285 retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
286 AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg;
287 } else {
288 retry_lg = AR5K_INIT_LG_RETRY;
289 retry_sh = AR5K_INIT_SH_RETRY;
290 }
291 307
292 /*No QCU/DCU [5210]*/ 308 /* Enable DCU to wait for next fragment from QCU */
293 if (ah->ah_version == AR5K_AR5210) { 309 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
294 ath5k_hw_reg_write(ah, 310 AR5K_DCU_MISC_FRAG_WAIT);
295 (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
296 | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
297 AR5K_NODCU_RETRY_LMT_SLG_RETRY)
298 | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
299 AR5K_NODCU_RETRY_LMT_SSH_RETRY)
300 | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
301 | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
302 AR5K_NODCU_RETRY_LMT);
303 } else {
304 /*QCU/DCU [5211+]*/
305 ath5k_hw_reg_write(ah,
306 AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
307 AR5K_DCU_RETRY_LMT_SLG_RETRY) |
308 AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
309 AR5K_DCU_RETRY_LMT_SSH_RETRY) |
310 AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
311 AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
312 AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
313 311
314 /*===Rest is also for QCU/DCU only [5211+]===*/ 312 /* On Maui and Spirit use the global seqnum on DCU */
313 if (ah->ah_mac_version < AR5K_SREV_AR5211)
314 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
315 AR5K_DCU_MISC_SEQNUM_CTL);
316
317 /* Constant bit rate period */
318 if (tq->tqi_cbr_period) {
319 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
320 AR5K_QCU_CBRCFG_INTVAL) |
321 AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
322 AR5K_QCU_CBRCFG_ORN_THRES),
323 AR5K_QUEUE_CBRCFG(queue));
315 324
316 /*
317 * Set initial content window (cw_min/cw_max)
318 * and arbitrated interframe space (aifs)...
319 */
320 ath5k_hw_reg_write(ah,
321 AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
322 AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
323 AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs,
324 AR5K_DCU_LCL_IFS_AIFS),
325 AR5K_QUEUE_DFS_LOCAL_IFS(queue));
326
327 /*
328 * Set misc registers
329 */
330 /* Enable DCU early termination for this queue */
331 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 325 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
332 AR5K_QCU_MISC_DCU_EARLY); 326 AR5K_QCU_MISC_FRSHED_CBR);
333 327
334 /* Enable DCU to wait for next fragment from QCU */ 328 if (tq->tqi_cbr_overflow_limit)
335 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
336 AR5K_DCU_MISC_FRAG_WAIT);
337
338 /* On Maui and Spirit use the global seqnum on DCU */
339 if (ah->ah_mac_version < AR5K_SREV_AR5211)
340 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
341 AR5K_DCU_MISC_SEQNUM_CTL);
342
343 if (tq->tqi_cbr_period) {
344 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
345 AR5K_QCU_CBRCFG_INTVAL) |
346 AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
347 AR5K_QCU_CBRCFG_ORN_THRES),
348 AR5K_QUEUE_CBRCFG(queue));
349 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 329 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
350 AR5K_QCU_MISC_FRSHED_CBR);
351 if (tq->tqi_cbr_overflow_limit)
352 AR5K_REG_ENABLE_BITS(ah,
353 AR5K_QUEUE_MISC(queue),
354 AR5K_QCU_MISC_CBR_THRES_ENABLE); 330 AR5K_QCU_MISC_CBR_THRES_ENABLE);
355 } 331 }
356 332
357 if (tq->tqi_ready_time && 333 /* Ready time interval */
358 (tq->tqi_type != AR5K_TX_QUEUE_CAB)) 334 if (tq->tqi_ready_time && (tq->tqi_type != AR5K_TX_QUEUE_CAB))
359 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time, 335 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
360 AR5K_QCU_RDYTIMECFG_INTVAL) | 336 AR5K_QCU_RDYTIMECFG_INTVAL) |
361 AR5K_QCU_RDYTIMECFG_ENABLE, 337 AR5K_QCU_RDYTIMECFG_ENABLE,
362 AR5K_QUEUE_RDYTIMECFG(queue)); 338 AR5K_QUEUE_RDYTIMECFG(queue));
363 339
364 if (tq->tqi_burst_time) { 340 if (tq->tqi_burst_time) {
365 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time, 341 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
366 AR5K_DCU_CHAN_TIME_DUR) | 342 AR5K_DCU_CHAN_TIME_DUR) |
367 AR5K_DCU_CHAN_TIME_ENABLE, 343 AR5K_DCU_CHAN_TIME_ENABLE,
368 AR5K_QUEUE_DFS_CHANNEL_TIME(queue)); 344 AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
369 345
370 if (tq->tqi_flags 346 if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
371 & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) 347 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
372 AR5K_REG_ENABLE_BITS(ah,
373 AR5K_QUEUE_MISC(queue),
374 AR5K_QCU_MISC_RDY_VEOL_POLICY); 348 AR5K_QCU_MISC_RDY_VEOL_POLICY);
375 } 349 }
376 350
377 if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) 351 /* Enable/disable Post frame backoff */
378 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS, 352 if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
379 AR5K_QUEUE_DFS_MISC(queue)); 353 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
354 AR5K_QUEUE_DFS_MISC(queue));
380 355
381 if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) 356 /* Enable/disable fragmentation burst backoff */
382 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG, 357 if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
383 AR5K_QUEUE_DFS_MISC(queue)); 358 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
359 AR5K_QUEUE_DFS_MISC(queue));
384 360
385 /* 361 /*
386 * Set registers by queue type 362 * Set registers by queue type
387 */ 363 */
388 switch (tq->tqi_type) { 364 switch (tq->tqi_type) {
389 case AR5K_TX_QUEUE_BEACON: 365 case AR5K_TX_QUEUE_BEACON:
390 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 366 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
391 AR5K_QCU_MISC_FRSHED_DBA_GT | 367 AR5K_QCU_MISC_FRSHED_DBA_GT |
392 AR5K_QCU_MISC_CBREXP_BCN_DIS | 368 AR5K_QCU_MISC_CBREXP_BCN_DIS |
393 AR5K_QCU_MISC_BCN_ENABLE); 369 AR5K_QCU_MISC_BCN_ENABLE);
394 370
395 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), 371 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
396 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << 372 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
397 AR5K_DCU_MISC_ARBLOCK_CTL_S) | 373 AR5K_DCU_MISC_ARBLOCK_CTL_S) |
398 AR5K_DCU_MISC_ARBLOCK_IGNORE | 374 AR5K_DCU_MISC_ARBLOCK_IGNORE |
399 AR5K_DCU_MISC_POST_FR_BKOFF_DIS | 375 AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
400 AR5K_DCU_MISC_BCN_ENABLE); 376 AR5K_DCU_MISC_BCN_ENABLE);
401 break; 377 break;
402 378
403 case AR5K_TX_QUEUE_CAB: 379 case AR5K_TX_QUEUE_CAB:
404 /* XXX: use BCN_SENT_GT, if we can figure out how */ 380 /* XXX: use BCN_SENT_GT, if we can figure out how */
405 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 381 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
406 AR5K_QCU_MISC_FRSHED_DBA_GT | 382 AR5K_QCU_MISC_FRSHED_DBA_GT |
407 AR5K_QCU_MISC_CBREXP_DIS | 383 AR5K_QCU_MISC_CBREXP_DIS |
408 AR5K_QCU_MISC_CBREXP_BCN_DIS); 384 AR5K_QCU_MISC_CBREXP_BCN_DIS);
409 385
410 ath5k_hw_reg_write(ah, ((tq->tqi_ready_time - 386 ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
411 (AR5K_TUNE_SW_BEACON_RESP - 387 (AR5K_TUNE_SW_BEACON_RESP -
412 AR5K_TUNE_DMA_BEACON_RESP) - 388 AR5K_TUNE_DMA_BEACON_RESP) -
413 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | 389 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
414 AR5K_QCU_RDYTIMECFG_ENABLE, 390 AR5K_QCU_RDYTIMECFG_ENABLE,
415 AR5K_QUEUE_RDYTIMECFG(queue)); 391 AR5K_QUEUE_RDYTIMECFG(queue));
416 392
417 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), 393 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
418 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << 394 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
419 AR5K_DCU_MISC_ARBLOCK_CTL_S)); 395 AR5K_DCU_MISC_ARBLOCK_CTL_S));
420 break; 396 break;
421 397
422 case AR5K_TX_QUEUE_UAPSD: 398 case AR5K_TX_QUEUE_UAPSD:
423 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 399 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
424 AR5K_QCU_MISC_CBREXP_DIS); 400 AR5K_QCU_MISC_CBREXP_DIS);
425 break; 401 break;
426 402
427 case AR5K_TX_QUEUE_DATA: 403 case AR5K_TX_QUEUE_DATA:
428 default: 404 default:
429 break; 405 break;
430 }
431
432 /* TODO: Handle frame compression */
433
434 /*
435 * Enable interrupts for this tx queue
436 * in the secondary interrupt mask registers
437 */
438 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
439 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
440
441 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
442 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
443
444 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
445 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
446
447 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
448 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
449
450 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
451 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
452
453 if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
454 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
455
456 if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
457 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
458
459 if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
460 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
461
462 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
463 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
464
465 /* Update secondary interrupt mask registers */
466
467 /* Filter out inactive queues */
468 ah->ah_txq_imr_txok &= ah->ah_txq_status;
469 ah->ah_txq_imr_txerr &= ah->ah_txq_status;
470 ah->ah_txq_imr_txurn &= ah->ah_txq_status;
471 ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
472 ah->ah_txq_imr_txeol &= ah->ah_txq_status;
473 ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
474 ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
475 ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
476 ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
477
478 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
479 AR5K_SIMR0_QCU_TXOK) |
480 AR5K_REG_SM(ah->ah_txq_imr_txdesc,
481 AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
482 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
483 AR5K_SIMR1_QCU_TXERR) |
484 AR5K_REG_SM(ah->ah_txq_imr_txeol,
485 AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
486 /* Update simr2 but don't overwrite rest simr2 settings */
487 AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
488 AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
489 AR5K_REG_SM(ah->ah_txq_imr_txurn,
490 AR5K_SIMR2_QCU_TXURN));
491 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
492 AR5K_SIMR3_QCBRORN) |
493 AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
494 AR5K_SIMR3_QCBRURN), AR5K_SIMR3);
495 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
496 AR5K_SIMR4_QTRIG), AR5K_SIMR4);
497 /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
498 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
499 AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
500 /* No queue has TXNOFRM enabled, disable the interrupt
501 * by setting AR5K_TXNOFRM to zero */
502 if (ah->ah_txq_imr_nofrm == 0)
503 ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
504
505 /* Set QCU mask for this DCU to save power */
506 AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
507 } 406 }
508 407
408 /* TODO: Handle frame compression */
409
410 /*
411 * Enable interrupts for this tx queue
412 * in the secondary interrupt mask registers
413 */
414 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
415 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
416
417 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
418 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
419
420 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
421 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
422
423 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
424 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
425
426 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
427 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
428
429 if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
430 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
431
432 if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
433 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
434
435 if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
436 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
437
438 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
439 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
440
441 /* Update secondary interrupt mask registers */
442
443 /* Filter out inactive queues */
444 ah->ah_txq_imr_txok &= ah->ah_txq_status;
445 ah->ah_txq_imr_txerr &= ah->ah_txq_status;
446 ah->ah_txq_imr_txurn &= ah->ah_txq_status;
447 ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
448 ah->ah_txq_imr_txeol &= ah->ah_txq_status;
449 ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
450 ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
451 ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
452 ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
453
454 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
455 AR5K_SIMR0_QCU_TXOK) |
456 AR5K_REG_SM(ah->ah_txq_imr_txdesc,
457 AR5K_SIMR0_QCU_TXDESC),
458 AR5K_SIMR0);
459
460 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
461 AR5K_SIMR1_QCU_TXERR) |
462 AR5K_REG_SM(ah->ah_txq_imr_txeol,
463 AR5K_SIMR1_QCU_TXEOL),
464 AR5K_SIMR1);
465
466 /* Update SIMR2 but don't overwrite rest simr2 settings */
467 AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
468 AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
469 AR5K_REG_SM(ah->ah_txq_imr_txurn,
470 AR5K_SIMR2_QCU_TXURN));
471
472 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
473 AR5K_SIMR3_QCBRORN) |
474 AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
475 AR5K_SIMR3_QCBRURN),
476 AR5K_SIMR3);
477
478 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
479 AR5K_SIMR4_QTRIG), AR5K_SIMR4);
480
481 /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
482 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
483 AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
484
485 /* No queue has TXNOFRM enabled, disable the interrupt
486 * by setting AR5K_TXNOFRM to zero */
487 if (ah->ah_txq_imr_nofrm == 0)
488 ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
489
490 /* Set QCU mask for this DCU to save power */
491 AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
492
509 return 0; 493 return 0;
510} 494}
511 495
512/* 496
513 * Set slot time on DCU 497/**************************\
498* Global QCU/DCU functions *
499\**************************/
500
501/**
502 * ath5k_hw_set_ifs_intervals - Set global inter-frame spaces on DCU
503 *
504 * @ah The &struct ath5k_hw
505 * @slot_time Slot time in us
506 *
507 * Sets the global IFS intervals on DCU (also works on AR5210) for
508 * the given slot time and the current bwmode.
514 */ 509 */
515int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) 510int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
516{ 511{
512 struct ieee80211_channel *channel = ah->ah_current_channel;
513 struct ath5k_softc *sc = ah->ah_sc;
514 struct ieee80211_rate *rate;
515 u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock;
517 u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time); 516 u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
518 517
519 if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX) 518 if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
520 return -EINVAL; 519 return -EINVAL;
521 520
522 if (ah->ah_version == AR5K_AR5210) 521 sifs = ath5k_hw_get_default_sifs(ah);
523 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME); 522 sifs_clock = ath5k_hw_htoclock(ah, sifs - 2);
523
524 /* EIFS
525 * Txtime of ack at lowest rate + SIFS + DIFS
526 * (DIFS = SIFS + 2 * Slot time)
527 *
528 * Note: HAL has some predefined values for EIFS
529 * Turbo: (37 + 2 * 6)
530 * Default: (74 + 2 * 9)
531 * Half: (149 + 2 * 13)
532 * Quarter: (298 + 2 * 21)
533 *
534 * (74 + 2 * 6) for AR5210 default and turbo !
535 *
536 * According to the formula we have
537 * ack_tx_time = 25 for turbo and
538 * ack_tx_time = 42.5 * clock multiplier
539 * for default/half/quarter.
540 *
541 * This can't be right, 42 is what we would get
542 * from ath5k_hw_get_frame_dur_for_bwmode or
543 * ieee80211_generic_frame_duration for zero frame
544 * length and without SIFS !
545 *
546 * Also we have different lowest rate for 802.11a
547 */
548 if (channel->hw_value & CHANNEL_5GHZ)
549 rate = &sc->sbands[IEEE80211_BAND_5GHZ].bitrates[0];
524 else 550 else
525 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT); 551 rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
552
553 ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false);
554
555 /* ack_tx_time includes an SIFS already */
556 eifs = ack_tx_time + sifs + 2 * slot_time;
557 eifs_clock = ath5k_hw_htoclock(ah, eifs);
558
559 /* Set IFS settings on AR5210 */
560 if (ah->ah_version == AR5K_AR5210) {
561 u32 pifs, pifs_clock, difs, difs_clock;
562
563 /* Set slot time */
564 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
565
566 /* Set EIFS */
567 eifs_clock = AR5K_REG_SM(eifs_clock, AR5K_IFS1_EIFS);
568
569 /* PIFS = Slot time + SIFS */
570 pifs = slot_time + sifs;
571 pifs_clock = ath5k_hw_htoclock(ah, pifs);
572 pifs_clock = AR5K_REG_SM(pifs_clock, AR5K_IFS1_PIFS);
573
574 /* DIFS = SIFS + 2 * Slot time */
575 difs = sifs + 2 * slot_time;
576 difs_clock = ath5k_hw_htoclock(ah, difs);
577
578 /* Set SIFS/DIFS */
579 ath5k_hw_reg_write(ah, (difs_clock <<
580 AR5K_IFS0_DIFS_S) | sifs_clock,
581 AR5K_IFS0);
582
583 /* Set PIFS/EIFS and preserve AR5K_INIT_CARR_SENSE_EN */
584 ath5k_hw_reg_write(ah, pifs_clock | eifs_clock |
585 (AR5K_INIT_CARR_SENSE_EN << AR5K_IFS1_CS_EN_S),
586 AR5K_IFS1);
587
588 return 0;
589 }
590
591 /* Set IFS slot time */
592 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);
593
594 /* Set EIFS interval */
595 ath5k_hw_reg_write(ah, eifs_clock, AR5K_DCU_GBL_IFS_EIFS);
596
597 /* Set SIFS interval in usecs */
598 AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
599 AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC,
600 sifs);
601
602 /* Set SIFS interval in clock cycles */
603 ath5k_hw_reg_write(ah, sifs_clock, AR5K_DCU_GBL_IFS_SIFS);
526 604
527 return 0; 605 return 0;
528} 606}
529 607
608
609int ath5k_hw_init_queues(struct ath5k_hw *ah)
610{
611 int i, ret;
612
613 /* TODO: HW Compression support for data queues */
614 /* TODO: Burst prefetch for data queues */
615
616 /*
617 * Reset queues and start beacon timers at the end of the reset routine
618 * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
619 * Note: If we want we can assign multiple qcus on one dcu.
620 */
621 if (ah->ah_version != AR5K_AR5210)
622 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
623 ret = ath5k_hw_reset_tx_queue(ah, i);
624 if (ret) {
625 ATH5K_ERR(ah->ah_sc,
626 "failed to reset TX queue #%d\n", i);
627 return ret;
628 }
629 }
630 else
631 /* No QCU/DCU on AR5210, just set tx
632 * retry limits. We set IFS parameters
633 * on ath5k_hw_set_ifs_intervals */
634 ath5k_hw_set_tx_retry_limits(ah, 0);
635
636 /* Set the turbo flag when operating on 40MHz */
637 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
638 AR5K_REG_ENABLE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
639 AR5K_DCU_GBL_IFS_MISC_TURBO_MODE);
640
641 /* If we didn't set IFS timings through
642 * ath5k_hw_set_coverage_class make sure
643 * we set them here */
644 if (!ah->ah_coverage_class) {
645 unsigned int slot_time = ath5k_hw_get_default_slottime(ah);
646 ath5k_hw_set_ifs_intervals(ah, slot_time);
647 }
648
649 return 0;
650}
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index 55b4ac6d236f..d12b827033c1 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -26,7 +26,6 @@
26 * Atheros presentations and papers like these: 26 * Atheros presentations and papers like these:
27 * 27 *
28 * 5210 - http://nova.stanford.edu/~bbaas/ps/isscc2002_slides.pdf 28 * 5210 - http://nova.stanford.edu/~bbaas/ps/isscc2002_slides.pdf
29 * http://www.it.iitb.ac.in/~janak/wifire/01222734.pdf
30 * 29 *
31 * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf 30 * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf
32 * 31 *
@@ -133,8 +132,8 @@
133 * As i can see in ar5k_ar5210_tx_start Reyk uses some of the values of BCR 132 * As i can see in ar5k_ar5210_tx_start Reyk uses some of the values of BCR
134 * for this register, so i guess TQ1V,TQ1FV and BDMAE have the same meaning 133 * for this register, so i guess TQ1V,TQ1FV and BDMAE have the same meaning
135 * here and SNP/SNAP means "snapshot" (so this register gets synced with BCR). 134 * here and SNP/SNAP means "snapshot" (so this register gets synced with BCR).
136 * So SNAPPEDBCRVALID sould also stand for "snapped BCR -values- valid", so i 135 * So SNAPPEDBCRVALID should also stand for "snapped BCR -values- valid", so i
137 * renamed it to SNAPSHOTSVALID to make more sense. I realy have no idea what 136 * renamed it to SNAPSHOTSVALID to make more sense. I really have no idea what
138 * else can it be. I also renamed SNPBCMD to SNPADHOC to match BCR. 137 * else can it be. I also renamed SNPBCMD to SNPADHOC to match BCR.
139 */ 138 */
140#define AR5K_BSR 0x002c /* Register Address */ 139#define AR5K_BSR 0x002c /* Register Address */
@@ -284,7 +283,7 @@
284 */ 283 */
285#define AR5K_ISR 0x001c /* Register Address [5210] */ 284#define AR5K_ISR 0x001c /* Register Address [5210] */
286#define AR5K_PISR 0x0080 /* Register Address [5211+] */ 285#define AR5K_PISR 0x0080 /* Register Address [5211+] */
287#define AR5K_ISR_RXOK 0x00000001 /* Frame successfuly recieved */ 286#define AR5K_ISR_RXOK 0x00000001 /* Frame successfuly received */
288#define AR5K_ISR_RXDESC 0x00000002 /* RX descriptor request */ 287#define AR5K_ISR_RXDESC 0x00000002 /* RX descriptor request */
289#define AR5K_ISR_RXERR 0x00000004 /* Receive error */ 288#define AR5K_ISR_RXERR 0x00000004 /* Receive error */
290#define AR5K_ISR_RXNOFRM 0x00000008 /* No frame received (receive timeout) */ 289#define AR5K_ISR_RXNOFRM 0x00000008 /* No frame received (receive timeout) */
@@ -373,12 +372,12 @@
373/* 372/*
374 * Interrupt Mask Registers 373 * Interrupt Mask Registers
375 * 374 *
376 * As whith ISRs 5210 has one IMR (AR5K_IMR) and 5211/5212 has one primary 375 * As with ISRs 5210 has one IMR (AR5K_IMR) and 5211/5212 has one primary
377 * (AR5K_PIMR) and 4 secondary IMRs (AR5K_SIMRx). Note that ISR/IMR flags match. 376 * (AR5K_PIMR) and 4 secondary IMRs (AR5K_SIMRx). Note that ISR/IMR flags match.
378 */ 377 */
379#define AR5K_IMR 0x0020 /* Register Address [5210] */ 378#define AR5K_IMR 0x0020 /* Register Address [5210] */
380#define AR5K_PIMR 0x00a0 /* Register Address [5211+] */ 379#define AR5K_PIMR 0x00a0 /* Register Address [5211+] */
381#define AR5K_IMR_RXOK 0x00000001 /* Frame successfuly recieved*/ 380#define AR5K_IMR_RXOK 0x00000001 /* Frame successfuly received*/
382#define AR5K_IMR_RXDESC 0x00000002 /* RX descriptor request*/ 381#define AR5K_IMR_RXDESC 0x00000002 /* RX descriptor request*/
383#define AR5K_IMR_RXERR 0x00000004 /* Receive error*/ 382#define AR5K_IMR_RXERR 0x00000004 /* Receive error*/
384#define AR5K_IMR_RXNOFRM 0x00000008 /* No frame received (receive timeout)*/ 383#define AR5K_IMR_RXNOFRM 0x00000008 /* No frame received (receive timeout)*/
@@ -687,16 +686,15 @@
687 686
688/* 687/*
689 * DCU retry limit registers 688 * DCU retry limit registers
689 * all these fields don't allow zero values
690 */ 690 */
691#define AR5K_DCU_RETRY_LMT_BASE 0x1080 /* Register Address -Queue0 DCU_RETRY_LMT */ 691#define AR5K_DCU_RETRY_LMT_BASE 0x1080 /* Register Address -Queue0 DCU_RETRY_LMT */
692#define AR5K_DCU_RETRY_LMT_SH_RETRY 0x0000000f /* Short retry limit mask */ 692#define AR5K_DCU_RETRY_LMT_RTS 0x0000000f /* RTS failure limit. Transmission fails if no CTS is received for this number of times */
693#define AR5K_DCU_RETRY_LMT_SH_RETRY_S 0 693#define AR5K_DCU_RETRY_LMT_RTS_S 0
694#define AR5K_DCU_RETRY_LMT_LG_RETRY 0x000000f0 /* Long retry limit mask */ 694#define AR5K_DCU_RETRY_LMT_STA_RTS 0x00003f00 /* STA RTS failure limit. If exceeded CW reset */
695#define AR5K_DCU_RETRY_LMT_LG_RETRY_S 4 695#define AR5K_DCU_RETRY_LMT_STA_RTS_S 8
696#define AR5K_DCU_RETRY_LMT_SSH_RETRY 0x00003f00 /* Station short retry limit mask (?) */ 696#define AR5K_DCU_RETRY_LMT_STA_DATA 0x000fc000 /* STA data failure limit. If exceeded CW reset. */
697#define AR5K_DCU_RETRY_LMT_SSH_RETRY_S 8 697#define AR5K_DCU_RETRY_LMT_STA_DATA_S 14
698#define AR5K_DCU_RETRY_LMT_SLG_RETRY 0x000fc000 /* Station long retry limit mask (?) */
699#define AR5K_DCU_RETRY_LMT_SLG_RETRY_S 14
700#define AR5K_QUEUE_DFS_RETRY_LIMIT(_q) AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q) 698#define AR5K_QUEUE_DFS_RETRY_LIMIT(_q) AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q)
701 699
702/* 700/*
@@ -788,6 +786,7 @@
788#define AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE 0x00000007 /* LFSR Slice Select */ 786#define AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE 0x00000007 /* LFSR Slice Select */
789#define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */ 787#define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */
790#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */ 788#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */
789#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC_S 4
791#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */ 790#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */
792#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S 10 791#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S 10
793#define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */ 792#define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */
@@ -896,7 +895,7 @@
896#define AR5K_PCICFG_SL_INTEN 0x00000800 /* Enable interrupts when asleep */ 895#define AR5K_PCICFG_SL_INTEN 0x00000800 /* Enable interrupts when asleep */
897#define AR5K_PCICFG_LED_BCTL 0x00001000 /* Led blink (?) [5210] */ 896#define AR5K_PCICFG_LED_BCTL 0x00001000 /* Led blink (?) [5210] */
898#define AR5K_PCICFG_RETRY_FIX 0x00001000 /* Enable pci core retry fix */ 897#define AR5K_PCICFG_RETRY_FIX 0x00001000 /* Enable pci core retry fix */
899#define AR5K_PCICFG_SL_INPEN 0x00002000 /* Sleep even whith pending interrupts*/ 898#define AR5K_PCICFG_SL_INPEN 0x00002000 /* Sleep even with pending interrupts*/
900#define AR5K_PCICFG_SPWR_DN 0x00010000 /* Mask for power status */ 899#define AR5K_PCICFG_SPWR_DN 0x00010000 /* Mask for power status */
901#define AR5K_PCICFG_LEDMODE 0x000e0000 /* Ledmode [5211+] */ 900#define AR5K_PCICFG_LEDMODE 0x000e0000 /* Ledmode [5211+] */
902#define AR5K_PCICFG_LEDMODE_PROP 0x00000000 /* Blink on standard traffic [5211+] */ 901#define AR5K_PCICFG_LEDMODE_PROP 0x00000000 /* Blink on standard traffic [5211+] */
@@ -1064,7 +1063,7 @@
1064/* 1063/*
1065 * EEPROM command register 1064 * EEPROM command register
1066 */ 1065 */
1067#define AR5K_EEPROM_CMD 0x6008 /* Register Addres */ 1066#define AR5K_EEPROM_CMD 0x6008 /* Register Address */
1068#define AR5K_EEPROM_CMD_READ 0x00000001 /* EEPROM read */ 1067#define AR5K_EEPROM_CMD_READ 0x00000001 /* EEPROM read */
1069#define AR5K_EEPROM_CMD_WRITE 0x00000002 /* EEPROM write */ 1068#define AR5K_EEPROM_CMD_WRITE 0x00000002 /* EEPROM write */
1070#define AR5K_EEPROM_CMD_RESET 0x00000004 /* EEPROM reset */ 1069#define AR5K_EEPROM_CMD_RESET 0x00000004 /* EEPROM reset */
@@ -1084,7 +1083,7 @@
1084/* 1083/*
1085 * EEPROM config register 1084 * EEPROM config register
1086 */ 1085 */
1087#define AR5K_EEPROM_CFG 0x6010 /* Register Addres */ 1086#define AR5K_EEPROM_CFG 0x6010 /* Register Address */
1088#define AR5K_EEPROM_CFG_SIZE 0x00000003 /* Size determination override */ 1087#define AR5K_EEPROM_CFG_SIZE 0x00000003 /* Size determination override */
1089#define AR5K_EEPROM_CFG_SIZE_AUTO 0 1088#define AR5K_EEPROM_CFG_SIZE_AUTO 0
1090#define AR5K_EEPROM_CFG_SIZE_4KBIT 1 1089#define AR5K_EEPROM_CFG_SIZE_4KBIT 1
@@ -1126,7 +1125,7 @@
1126 * Second station id register (Upper 16 bits of MAC address + PCU settings) 1125 * Second station id register (Upper 16 bits of MAC address + PCU settings)
1127 */ 1126 */
1128#define AR5K_STA_ID1 0x8004 /* Register Address */ 1127#define AR5K_STA_ID1 0x8004 /* Register Address */
1129#define AR5K_STA_ID1_ADDR_U16 0x0000ffff /* Upper 16 bits of MAC addres */ 1128#define AR5K_STA_ID1_ADDR_U16 0x0000ffff /* Upper 16 bits of MAC address */
1130#define AR5K_STA_ID1_AP 0x00010000 /* Set AP mode */ 1129#define AR5K_STA_ID1_AP 0x00010000 /* Set AP mode */
1131#define AR5K_STA_ID1_ADHOC 0x00020000 /* Set Ad-Hoc mode */ 1130#define AR5K_STA_ID1_ADHOC 0x00020000 /* Set Ad-Hoc mode */
1132#define AR5K_STA_ID1_PWR_SV 0x00040000 /* Power save reporting */ 1131#define AR5K_STA_ID1_PWR_SV 0x00040000 /* Power save reporting */
@@ -1312,7 +1311,7 @@
1312#define AR5K_IFS1_EIFS 0x03fff000 1311#define AR5K_IFS1_EIFS 0x03fff000
1313#define AR5K_IFS1_EIFS_S 12 1312#define AR5K_IFS1_EIFS_S 12
1314#define AR5K_IFS1_CS_EN 0x04000000 1313#define AR5K_IFS1_CS_EN 0x04000000
1315 1314#define AR5K_IFS1_CS_EN_S 26
1316 1315
1317/* 1316/*
1318 * CFP duration register 1317 * CFP duration register
@@ -1387,10 +1386,9 @@
1387 1386
1388 1387
1389/* 1388/*
1390 * PCU control register 1389 * PCU Diagnostic register
1391 * 1390 *
1392 * Only DIS_RX is used in the code, the rest i guess are 1391 * Used for tweaking/diagnostics.
1393 * for tweaking/diagnostics.
1394 */ 1392 */
1395#define AR5K_DIAG_SW_5210 0x8068 /* Register Address [5210] */ 1393#define AR5K_DIAG_SW_5210 0x8068 /* Register Address [5210] */
1396#define AR5K_DIAG_SW_5211 0x8048 /* Register Address [5211+] */ 1394#define AR5K_DIAG_SW_5211 0x8048 /* Register Address [5211+] */
@@ -1399,22 +1397,22 @@
1399#define AR5K_DIAG_SW_DIS_WEP_ACK 0x00000001 /* Disable ACKs if WEP key is invalid */ 1397#define AR5K_DIAG_SW_DIS_WEP_ACK 0x00000001 /* Disable ACKs if WEP key is invalid */
1400#define AR5K_DIAG_SW_DIS_ACK 0x00000002 /* Disable ACKs */ 1398#define AR5K_DIAG_SW_DIS_ACK 0x00000002 /* Disable ACKs */
1401#define AR5K_DIAG_SW_DIS_CTS 0x00000004 /* Disable CTSs */ 1399#define AR5K_DIAG_SW_DIS_CTS 0x00000004 /* Disable CTSs */
1402#define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable encryption */ 1400#define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable HW encryption */
1403#define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable decryption */ 1401#define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable HW decryption */
1404#define AR5K_DIAG_SW_DIS_TX 0x00000020 /* Disable transmit [5210] */ 1402#define AR5K_DIAG_SW_DIS_TX_5210 0x00000020 /* Disable transmit [5210] */
1405#define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable recieve */ 1403#define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable receive */
1406#define AR5K_DIAG_SW_DIS_RX_5211 0x00000020 1404#define AR5K_DIAG_SW_DIS_RX_5211 0x00000020
1407#define AR5K_DIAG_SW_DIS_RX (ah->ah_version == AR5K_AR5210 ? \ 1405#define AR5K_DIAG_SW_DIS_RX (ah->ah_version == AR5K_AR5210 ? \
1408 AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211) 1406 AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211)
1409#define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* Loopback (i guess it goes with DIS_TX) [5210] */ 1407#define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* TX Data Loopback (i guess it goes with DIS_TX) [5210] */
1410#define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040 1408#define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040
1411#define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \ 1409#define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \
1412 AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211) 1410 AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211)
1413#define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Corrupted FCS */ 1411#define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Generate invalid TX FCS */
1414#define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080 1412#define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080
1415#define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \ 1413#define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \
1416 AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211) 1414 AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211)
1417#define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Dump channel info */ 1415#define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Add 56 bytes of channel info before the frame data in the RX buffer */
1418#define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100 1416#define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100
1419#define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \ 1417#define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \
1420 AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211) 1418 AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211)
@@ -1426,17 +1424,17 @@
1426#define AR5K_DIAG_SW_SCVRAM_SEED 0x0003f800 /* [5210] */ 1424#define AR5K_DIAG_SW_SCVRAM_SEED 0x0003f800 /* [5210] */
1427#define AR5K_DIAG_SW_SCRAM_SEED_M 0x0001fc00 /* Scrambler seed mask */ 1425#define AR5K_DIAG_SW_SCRAM_SEED_M 0x0001fc00 /* Scrambler seed mask */
1428#define AR5K_DIAG_SW_SCRAM_SEED_S 10 1426#define AR5K_DIAG_SW_SCRAM_SEED_S 10
1429#define AR5K_DIAG_SW_DIS_SEQ_INC 0x00040000 /* Disable seqnum increment (?)[5210] */ 1427#define AR5K_DIAG_SW_DIS_SEQ_INC_5210 0x00040000 /* Disable seqnum increment (?)[5210] */
1430#define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000 1428#define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000
1431#define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 /* Accept frames of non-zero protocol number */ 1429#define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 /* Accept frames of non-zero protocol number */
1432#define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \ 1430#define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \
1433 AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211) 1431 AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211)
1434#define AR5K_DIAG_SW_OBSPT_M 0x000c0000 /* Observation point select (?) */ 1432#define AR5K_DIAG_SW_OBSPT_M 0x000c0000 /* Observation point select (?) */
1435#define AR5K_DIAG_SW_OBSPT_S 18 1433#define AR5K_DIAG_SW_OBSPT_S 18
1436#define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x0010000 /* Force RX Clear high */ 1434#define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x00100000 /* Ignore carrier sense */
1437#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000 /* Ignore virtual carrier sense */ 1435#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x00200000 /* Ignore virtual carrier sense */
1438#define AR5K_DIAG_SW_CHANEL_IDLE_HIGH 0x0040000 /* Force channel idle high */ 1436#define AR5K_DIAG_SW_CHANNEL_IDLE_HIGH 0x00400000 /* Force channel idle high */
1439#define AR5K_DIAG_SW_PHEAR_ME 0x0080000 /* ??? */ 1437#define AR5K_DIAG_SW_PHEAR_ME 0x00800000 /* ??? */
1440 1438
1441/* 1439/*
1442 * TSF (clock) register (lower 32 bits) 1440 * TSF (clock) register (lower 32 bits)
@@ -1822,50 +1820,8 @@
1822 1820
1823/*===5212 end===*/ 1821/*===5212 end===*/
1824 1822
1825/*
1826 * Key table (WEP) register
1827 */
1828#define AR5K_KEYTABLE_0_5210 0x9000
1829#define AR5K_KEYTABLE_0_5211 0x8800
1830#define AR5K_KEYTABLE_5210(_n) (AR5K_KEYTABLE_0_5210 + ((_n) << 5))
1831#define AR5K_KEYTABLE_5211(_n) (AR5K_KEYTABLE_0_5211 + ((_n) << 5))
1832#define AR5K_KEYTABLE(_n) (ah->ah_version == AR5K_AR5210 ? \
1833 AR5K_KEYTABLE_5210(_n) : AR5K_KEYTABLE_5211(_n))
1834#define AR5K_KEYTABLE_OFF(_n, x) (AR5K_KEYTABLE(_n) + (x << 2))
1835#define AR5K_KEYTABLE_TYPE(_n) AR5K_KEYTABLE_OFF(_n, 5)
1836#define AR5K_KEYTABLE_TYPE_40 0x00000000
1837#define AR5K_KEYTABLE_TYPE_104 0x00000001
1838#define AR5K_KEYTABLE_TYPE_128 0x00000003
1839#define AR5K_KEYTABLE_TYPE_TKIP 0x00000004 /* [5212+] */
1840#define AR5K_KEYTABLE_TYPE_AES 0x00000005 /* [5211+] */
1841#define AR5K_KEYTABLE_TYPE_CCM 0x00000006 /* [5212+] */
1842#define AR5K_KEYTABLE_TYPE_NULL 0x00000007 /* [5211+] */
1843#define AR5K_KEYTABLE_ANTENNA 0x00000008 /* [5212+] */
1844#define AR5K_KEYTABLE_MAC0(_n) AR5K_KEYTABLE_OFF(_n, 6)
1845#define AR5K_KEYTABLE_MAC1(_n) AR5K_KEYTABLE_OFF(_n, 7)
1846#define AR5K_KEYTABLE_VALID 0x00008000
1847
1848/* If key type is TKIP and MIC is enabled
1849 * MIC key goes in offset entry + 64 */
1850#define AR5K_KEYTABLE_MIC_OFFSET 64
1851
1852/* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit
1853 * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit
1854 * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit
1855 *
1856 * Some vendors have introduced bigger WEP keys to address
1857 * security vulnerabilities in WEP. This includes:
1858 *
1859 * WEP 232-bit = 232-bit entered key + 24 bit IV = 256-bit
1860 *
1861 * We can expand this if we find ar5k Atheros cards with a larger
1862 * key table size.
1863 */
1864#define AR5K_KEYTABLE_SIZE_5210 64 1823#define AR5K_KEYTABLE_SIZE_5210 64
1865#define AR5K_KEYTABLE_SIZE_5211 128 1824#define AR5K_KEYTABLE_SIZE_5211 128
1866#define AR5K_KEYTABLE_SIZE (ah->ah_version == AR5K_AR5210 ? \
1867 AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211)
1868
1869 1825
1870/*===PHY REGISTERS===*/ 1826/*===PHY REGISTERS===*/
1871 1827
@@ -1911,7 +1867,7 @@
1911#define AR5K_PHY_TURBO 0x9804 /* Register Address */ 1867#define AR5K_PHY_TURBO 0x9804 /* Register Address */
1912#define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */ 1868#define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */
1913#define AR5K_PHY_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode */ 1869#define AR5K_PHY_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode */
1914#define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo mimo */ 1870#define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo */
1915 1871
1916/* 1872/*
1917 * PHY agility command register 1873 * PHY agility command register
@@ -2102,6 +2058,7 @@
2102 2058
2103#define AR5K_PHY_SCAL 0x9878 2059#define AR5K_PHY_SCAL 0x9878
2104#define AR5K_PHY_SCAL_32MHZ 0x0000000e 2060#define AR5K_PHY_SCAL_32MHZ 0x0000000e
2061#define AR5K_PHY_SCAL_32MHZ_5311 0x00000008
2105#define AR5K_PHY_SCAL_32MHZ_2417 0x0000000a 2062#define AR5K_PHY_SCAL_32MHZ_2417 0x0000000a
2106#define AR5K_PHY_SCAL_32MHZ_HB63 0x00000032 2063#define AR5K_PHY_SCAL_32MHZ_HB63 0x00000032
2107 2064
@@ -2288,6 +2245,8 @@
2288#define AR5K_PHY_FRAME_CTL (ah->ah_version == AR5K_AR5210 ? \ 2245#define AR5K_PHY_FRAME_CTL (ah->ah_version == AR5K_AR5210 ? \
2289 AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211) 2246 AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211)
2290/*---[5111+]---*/ 2247/*---[5111+]---*/
2248#define AR5K_PHY_FRAME_CTL_WIN_LEN 0x00000003 /* Force window length (?) */
2249#define AR5K_PHY_FRAME_CTL_WIN_LEN_S 0
2291#define AR5K_PHY_FRAME_CTL_TX_CLIP 0x00000038 /* Mask for tx clip (?) */ 2250#define AR5K_PHY_FRAME_CTL_TX_CLIP 0x00000038 /* Mask for tx clip (?) */
2292#define AR5K_PHY_FRAME_CTL_TX_CLIP_S 3 2251#define AR5K_PHY_FRAME_CTL_TX_CLIP_S 3
2293#define AR5K_PHY_FRAME_CTL_PREP_CHINFO 0x00010000 /* Prepend chan info */ 2252#define AR5K_PHY_FRAME_CTL_PREP_CHINFO 0x00010000 /* Prepend chan info */
@@ -2602,3 +2561,28 @@
2602 */ 2561 */
2603#define AR5K_PHY_PDADC_TXPOWER_BASE 0xa280 2562#define AR5K_PHY_PDADC_TXPOWER_BASE 0xa280
2604#define AR5K_PHY_PDADC_TXPOWER(_n) (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2)) 2563#define AR5K_PHY_PDADC_TXPOWER(_n) (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2))
2564
2565/*
2566 * Platform registers for WiSoC
2567 */
2568#define AR5K_AR5312_RESET 0xbc003020
2569#define AR5K_AR5312_RESET_BB0_COLD 0x00000004
2570#define AR5K_AR5312_RESET_BB1_COLD 0x00000200
2571#define AR5K_AR5312_RESET_WMAC0 0x00002000
2572#define AR5K_AR5312_RESET_BB0_WARM 0x00004000
2573#define AR5K_AR5312_RESET_WMAC1 0x00020000
2574#define AR5K_AR5312_RESET_BB1_WARM 0x00040000
2575
2576#define AR5K_AR5312_ENABLE 0xbc003080
2577#define AR5K_AR5312_ENABLE_WLAN0 0x00000001
2578#define AR5K_AR5312_ENABLE_WLAN1 0x00000008
2579
2580#define AR5K_AR2315_RESET 0xb1000004
2581#define AR5K_AR2315_RESET_WMAC 0x00000001
2582#define AR5K_AR2315_RESET_BB_WARM 0x00000002
2583
2584#define AR5K_AR2315_AHB_ARB_CTL 0xb1000008
2585#define AR5K_AR2315_AHB_ARB_CTL_WLAN 0x00000002
2586
2587#define AR5K_AR2315_BYTESWAP 0xb100000c
2588#define AR5K_AR2315_BYTESWAP_WMAC 0x00000002
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 498aa28ea9e6..126a4eab35f3 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -27,11 +27,17 @@
27 27
28#include <linux/pci.h> /* To determine if a card is pci-e */ 28#include <linux/pci.h> /* To determine if a card is pci-e */
29#include <linux/log2.h> 29#include <linux/log2.h>
30#include <linux/platform_device.h>
30#include "ath5k.h" 31#include "ath5k.h"
31#include "reg.h" 32#include "reg.h"
32#include "base.h" 33#include "base.h"
33#include "debug.h" 34#include "debug.h"
34 35
36
37/******************\
38* Helper functions *
39\******************/
40
35/* 41/*
36 * Check if a register write has been completed 42 * Check if a register write has been completed
37 */ 43 */
@@ -53,146 +59,272 @@ int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
53 return (i <= 0) ? -EAGAIN : 0; 59 return (i <= 0) ? -EAGAIN : 0;
54} 60}
55 61
62
63/*************************\
64* Clock related functions *
65\*************************/
66
56/** 67/**
57 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 68 * ath5k_hw_htoclock - Translate usec to hw clock units
58 * 69 *
59 * @ah: the &struct ath5k_hw 70 * @ah: The &struct ath5k_hw
60 * @channel: the currently set channel upon reset 71 * @usec: value in microseconds
61 * 72 */
62 * Write the delta slope coefficient (used on pilot tracking ?) for OFDM 73unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
63 * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset(). 74{
75 struct ath_common *common = ath5k_hw_common(ah);
76 return usec * common->clockrate;
77}
78
79/**
80 * ath5k_hw_clocktoh - Translate hw clock units to usec
81 * @clock: value in hw clock units
82 */
83unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
84{
85 struct ath_common *common = ath5k_hw_common(ah);
86 return clock / common->clockrate;
87}
88
89/**
90 * ath5k_hw_init_core_clock - Initialize core clock
64 * 91 *
65 * Since delta slope is floating point we split it on its exponent and 92 * @ah The &struct ath5k_hw
66 * mantissa and provide these values on hw.
67 * 93 *
68 * For more infos i think this patent is related 94 * Initialize core clock parameters (usec, usec32, latencies etc).
69 * http://www.freepatentsonline.com/7184495.html
70 */ 95 */
71static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, 96static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
72 struct ieee80211_channel *channel)
73{ 97{
74 /* Get exponent and mantissa and set it */ 98 struct ieee80211_channel *channel = ah->ah_current_channel;
75 u32 coef_scaled, coef_exp, coef_man, 99 struct ath_common *common = ath5k_hw_common(ah);
76 ds_coef_exp, ds_coef_man, clock; 100 u32 usec_reg, txlat, rxlat, usec, clock, sclock, txf2txs;
77
78 BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
79 !(channel->hw_value & CHANNEL_OFDM));
80
81 /* Get coefficient
82 * ALGO: coef = (5 * clock / carrier_freq) / 2
83 * we scale coef by shifting clock value by 24 for
84 * better precision since we use integers */
85 /* TODO: Half/quarter rate */
86 clock = (channel->hw_value & CHANNEL_TURBO) ? 80 : 40;
87 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
88
89 /* Get exponent
90 * ALGO: coef_exp = 14 - highest set bit position */
91 coef_exp = ilog2(coef_scaled);
92
93 /* Doesn't make sense if it's zero*/
94 if (!coef_scaled || !coef_exp)
95 return -EINVAL;
96 101
97 /* Note: we've shifted coef_scaled by 24 */ 102 /*
98 coef_exp = 14 - (coef_exp - 24); 103 * Set core clock frequency
104 */
105 if (channel->hw_value & CHANNEL_5GHZ)
106 clock = 40; /* 802.11a */
107 else if (channel->hw_value & CHANNEL_CCK)
108 clock = 22; /* 802.11b */
109 else
110 clock = 44; /* 802.11g */
99 111
112 /* Use clock multiplier for non-default
113 * bwmode */
114 switch (ah->ah_bwmode) {
115 case AR5K_BWMODE_40MHZ:
116 clock *= 2;
117 break;
118 case AR5K_BWMODE_10MHZ:
119 clock /= 2;
120 break;
121 case AR5K_BWMODE_5MHZ:
122 clock /= 4;
123 break;
124 default:
125 break;
126 }
127
128 common->clockrate = clock;
100 129
101 /* Get mantissa (significant digits) 130 /*
102 * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */ 131 * Set USEC parameters
103 coef_man = coef_scaled + 132 */
104 (1 << (24 - coef_exp - 1)); 133 /* Set USEC counter on PCU*/
134 usec = clock - 1;
135 usec = AR5K_REG_SM(usec, AR5K_USEC_1);
105 136
106 /* Calculate delta slope coefficient exponent 137 /* Set usec duration on DCU */
107 * and mantissa (remove scaling) and set them on hw */ 138 if (ah->ah_version != AR5K_AR5210)
108 ds_coef_man = coef_man >> (24 - coef_exp); 139 AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
109 ds_coef_exp = coef_exp - 16; 140 AR5K_DCU_GBL_IFS_MISC_USEC_DUR,
141 clock);
110 142
111 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, 143 /* Set 32MHz USEC counter */
112 AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man); 144 if ((ah->ah_radio == AR5K_RF5112) ||
113 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, 145 (ah->ah_radio == AR5K_RF5413) ||
114 AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp); 146 (ah->ah_radio == AR5K_RF2316) ||
147 (ah->ah_radio == AR5K_RF2317))
148 /* Remain on 40MHz clock ? */
149 sclock = 40 - 1;
150 else
151 sclock = 32 - 1;
152 sclock = AR5K_REG_SM(sclock, AR5K_USEC_32);
115 153
116 return 0; 154 /*
117} 155 * Set tx/rx latencies
156 */
157 usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
158 txlat = AR5K_REG_MS(usec_reg, AR5K_USEC_TX_LATENCY_5211);
159 rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211);
118 160
161 /*
162 * Set default Tx frame to Tx data start delay
163 */
164 txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT;
119 165
120/* 166 /*
121 * index into rates for control rates, we can set it up like this because 167 * 5210 initvals don't include usec settings
122 * this is only used for AR5212 and we know it supports G mode 168 * so we need to use magic values here for
123 */ 169 * tx/rx latencies
124static const unsigned int control_rates[] = 170 */
125 { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 }; 171 if (ah->ah_version == AR5K_AR5210) {
172 /* same for turbo */
173 txlat = AR5K_INIT_TX_LATENCY_5210;
174 rxlat = AR5K_INIT_RX_LATENCY_5210;
175 }
126 176
127/** 177 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
128 * ath5k_hw_write_rate_duration - fill rate code to duration table 178 /* 5311 has different tx/rx latency masks
129 * 179 * from 5211, since we deal 5311 the same
130 * @ah: the &struct ath5k_hw 180 * as 5211 when setting initvals, shift
131 * @mode: one of enum ath5k_driver_mode 181 * values here to their proper locations
132 * 182 *
133 * Write the rate code to duration table upon hw reset. This is a helper for 183 * Note: Initvals indicate tx/rx/ latencies
134 * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on 184 * are the same for turbo mode */
135 * the hardware, based on current mode, for each rate. The rates which are 185 txlat = AR5K_REG_SM(txlat, AR5K_USEC_TX_LATENCY_5210);
136 * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have 186 rxlat = AR5K_REG_SM(rxlat, AR5K_USEC_RX_LATENCY_5210);
137 * different rate code so we write their value twice (one for long preample 187 } else
138 * and one for short). 188 switch (ah->ah_bwmode) {
189 case AR5K_BWMODE_10MHZ:
190 txlat = AR5K_REG_SM(txlat * 2,
191 AR5K_USEC_TX_LATENCY_5211);
192 rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX,
193 AR5K_USEC_RX_LATENCY_5211);
194 txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_10MHZ;
195 break;
196 case AR5K_BWMODE_5MHZ:
197 txlat = AR5K_REG_SM(txlat * 4,
198 AR5K_USEC_TX_LATENCY_5211);
199 rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX,
200 AR5K_USEC_RX_LATENCY_5211);
201 txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_5MHZ;
202 break;
203 case AR5K_BWMODE_40MHZ:
204 txlat = AR5K_INIT_TX_LAT_MIN;
205 rxlat = AR5K_REG_SM(rxlat / 2,
206 AR5K_USEC_RX_LATENCY_5211);
207 txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT;
208 break;
209 default:
210 break;
211 }
212
213 usec_reg = (usec | sclock | txlat | rxlat);
214 ath5k_hw_reg_write(ah, usec_reg, AR5K_USEC);
215
216 /* On 5112 set tx frane to tx data start delay */
217 if (ah->ah_radio == AR5K_RF5112) {
218 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL2,
219 AR5K_PHY_RF_CTL2_TXF2TXD_START,
220 txf2txs);
221 }
222}
223
224/*
225 * If there is an external 32KHz crystal available, use it
226 * as ref. clock instead of 32/40MHz clock and baseband clocks
227 * to save power during sleep or restore normal 32/40MHz
228 * operation.
139 * 229 *
140 * Note: Band doesn't matter here, if we set the values for OFDM it works 230 * XXX: When operating on 32KHz certain PHY registers (27 - 31,
141 * on both a and g modes. So all we have to do is set values for all g rates 231 * 123 - 127) require delay on access.
142 * that include all OFDM and CCK rates. If we operate in turbo or xr/half/
143 * quarter rate mode, we need to use another set of bitrates (that's why we
144 * need the mode parameter) but we don't handle these proprietary modes yet.
145 */ 232 */
146static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, 233static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
147 unsigned int mode)
148{ 234{
149 struct ath5k_softc *sc = ah->ah_sc; 235 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
150 struct ieee80211_rate *rate; 236 u32 scal, spending;
151 unsigned int i; 237
238 /* Only set 32KHz settings if we have an external
239 * 32KHz crystal present */
240 if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
241 AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
242 enable) {
152 243
153 /* Write rate duration table */ 244 /* 1 usec/cycle */
154 for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) { 245 AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
155 u32 reg; 246 /* Set up tsf increment on each cycle */
156 u16 tx_time; 247 AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
157 248
158 rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]]; 249 /* Set baseband sleep control registers
250 * and sleep control rate */
251 ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
159 252
160 /* Set ACK timeout */ 253 if ((ah->ah_radio == AR5K_RF5112) ||
161 reg = AR5K_RATE_DUR(rate->hw_value); 254 (ah->ah_radio == AR5K_RF5413) ||
255 (ah->ah_radio == AR5K_RF2316) ||
256 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
257 spending = 0x14;
258 else
259 spending = 0x18;
260 ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
162 261
163 /* An ACK frame consists of 10 bytes. If you add the FCS, 262 if ((ah->ah_radio == AR5K_RF5112) ||
164 * which ieee80211_generic_frame_duration() adds, 263 (ah->ah_radio == AR5K_RF5413) ||
165 * its 14 bytes. Note we use the control rate and not the 264 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
166 * actual rate for this rate. See mac80211 tx.c 265 ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
167 * ieee80211_duration() for a brief description of 266 ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
168 * what rate we should choose to TX ACKs. */ 267 ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
169 tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, 268 ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
170 sc->vif, 10, rate)); 269 AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
270 AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
271 } else {
272 ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
273 ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
274 ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
275 ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
276 AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
277 AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
278 }
171 279
172 ath5k_hw_reg_write(ah, tx_time, reg); 280 /* Enable sleep clock operation */
281 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
282 AR5K_PCICFG_SLEEP_CLOCK_EN);
173 283
174 if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) 284 } else {
175 continue;
176 285
177 /* 286 /* Disable sleep clock operation and
178 * We're not distinguishing short preamble here, 287 * restore default parameters */
179 * This is true, all we'll get is a longer value here 288 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
180 * which is not necessarilly bad. We could use 289 AR5K_PCICFG_SLEEP_CLOCK_EN);
181 * export ieee80211_frame_duration() but that needs to be 290
182 * fixed first to be properly used by mac802111 drivers: 291 AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
183 * 292 AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
184 * - remove erp stuff and let the routine figure ofdm 293
185 * erp rates 294 /* Set DAC/ADC delays */
186 * - remove passing argument ieee80211_local as 295 ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
187 * drivers don't have access to it 296 ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
188 * - move drivers using ieee80211_generic_frame_duration() 297
189 * to this 298 if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
190 */ 299 scal = AR5K_PHY_SCAL_32MHZ_2417;
191 ath5k_hw_reg_write(ah, tx_time, 300 else if (ee->ee_is_hb63)
192 reg + (AR5K_SET_SHORT_PREAMBLE << 2)); 301 scal = AR5K_PHY_SCAL_32MHZ_HB63;
302 else
303 scal = AR5K_PHY_SCAL_32MHZ;
304 ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
305
306 ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
307 ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
308
309 if ((ah->ah_radio == AR5K_RF5112) ||
310 (ah->ah_radio == AR5K_RF5413) ||
311 (ah->ah_radio == AR5K_RF2316) ||
312 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
313 spending = 0x14;
314 else
315 spending = 0x18;
316 ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
317
318 /* Set up tsf increment on each cycle */
319 AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
193 } 320 }
194} 321}
195 322
323
324/*********************\
325* Reset/Sleep control *
326\*********************/
327
196/* 328/*
197 * Reset chipset 329 * Reset chipset
198 */ 330 */
@@ -236,6 +368,64 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
236} 368}
237 369
238/* 370/*
371 * Reset AHB chipset
372 * AR5K_RESET_CTL_PCU flag resets WMAC
373 * AR5K_RESET_CTL_BASEBAND flag resets WBB
374 */
375static int ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags)
376{
377 u32 mask = flags ? flags : ~0U;
378 volatile u32 *reg;
379 u32 regval;
380 u32 val = 0;
381
382 /* ah->ah_mac_srev is not available at this point yet */
383 if (ah->ah_sc->devid >= AR5K_SREV_AR2315_R6) {
384 reg = (u32 *) AR5K_AR2315_RESET;
385 if (mask & AR5K_RESET_CTL_PCU)
386 val |= AR5K_AR2315_RESET_WMAC;
387 if (mask & AR5K_RESET_CTL_BASEBAND)
388 val |= AR5K_AR2315_RESET_BB_WARM;
389 } else {
390 reg = (u32 *) AR5K_AR5312_RESET;
391 if (to_platform_device(ah->ah_sc->dev)->id == 0) {
392 if (mask & AR5K_RESET_CTL_PCU)
393 val |= AR5K_AR5312_RESET_WMAC0;
394 if (mask & AR5K_RESET_CTL_BASEBAND)
395 val |= AR5K_AR5312_RESET_BB0_COLD |
396 AR5K_AR5312_RESET_BB0_WARM;
397 } else {
398 if (mask & AR5K_RESET_CTL_PCU)
399 val |= AR5K_AR5312_RESET_WMAC1;
400 if (mask & AR5K_RESET_CTL_BASEBAND)
401 val |= AR5K_AR5312_RESET_BB1_COLD |
402 AR5K_AR5312_RESET_BB1_WARM;
403 }
404 }
405
406 /* Put BB/MAC into reset */
407 regval = __raw_readl(reg);
408 __raw_writel(regval | val, reg);
409 regval = __raw_readl(reg);
410 udelay(100);
411
412 /* Bring BB/MAC out of reset */
413 __raw_writel(regval & ~val, reg);
414 regval = __raw_readl(reg);
415
416 /*
417 * Reset configuration register (for hw byte-swap). Note that this
418 * is only set for big endian. We do the necessary magic in
419 * AR5K_INIT_CFG.
420 */
421 if ((flags & AR5K_RESET_CTL_PCU) == 0)
422 ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
423
424 return 0;
425}
426
427
428/*
239 * Sleep control 429 * Sleep control
240 */ 430 */
241static int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, 431static int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
@@ -326,7 +516,7 @@ commit:
326 * register). After this MAC and Baseband are 516 * register). After this MAC and Baseband are
327 * disabled and a full reset is needed to come 517 * disabled and a full reset is needed to come
328 * back. This way we save as much power as possible 518 * back. This way we save as much power as possible
329 * without puting the card on full sleep. 519 * without putting the card on full sleep.
330 */ 520 */
331int ath5k_hw_on_hold(struct ath5k_hw *ah) 521int ath5k_hw_on_hold(struct ath5k_hw *ah)
332{ 522{
@@ -334,6 +524,9 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
334 u32 bus_flags; 524 u32 bus_flags;
335 int ret; 525 int ret;
336 526
527 if (ath5k_get_bus_type(ah) == ATH_AHB)
528 return 0;
529
337 /* Make sure device is awake */ 530 /* Make sure device is awake */
338 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); 531 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
339 if (ret) { 532 if (ret) {
@@ -344,12 +537,12 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
344 /* 537 /*
345 * Put chipset on warm reset... 538 * Put chipset on warm reset...
346 * 539 *
347 * Note: puting PCI core on warm reset on PCI-E cards 540 * Note: putting PCI core on warm reset on PCI-E cards
348 * results card to hang and always return 0xffff... so 541 * results card to hang and always return 0xffff... so
349 * we ingore that flag for PCI-E cards. On PCI cards 542 * we ingore that flag for PCI-E cards. On PCI cards
350 * this flag gets cleared after 64 PCI clocks. 543 * this flag gets cleared after 64 PCI clocks.
351 */ 544 */
352 bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI; 545 bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI;
353 546
354 if (ah->ah_version == AR5K_AR5210) { 547 if (ah->ah_version == AR5K_AR5210) {
355 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | 548 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
@@ -378,7 +571,6 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
378 571
379/* 572/*
380 * Bring up MAC + PHY Chips and program PLL 573 * Bring up MAC + PHY Chips and program PLL
381 * TODO: Half/Quarter rate support
382 */ 574 */
383int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) 575int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
384{ 576{
@@ -390,22 +582,24 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
390 mode = 0; 582 mode = 0;
391 clock = 0; 583 clock = 0;
392 584
393 /* Wakeup the device */ 585 if ((ath5k_get_bus_type(ah) != ATH_AHB) || !initial) {
394 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); 586 /* Wakeup the device */
395 if (ret) { 587 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
396 ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n"); 588 if (ret) {
397 return ret; 589 ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
590 return ret;
591 }
398 } 592 }
399 593
400 /* 594 /*
401 * Put chipset on warm reset... 595 * Put chipset on warm reset...
402 * 596 *
403 * Note: puting PCI core on warm reset on PCI-E cards 597 * Note: putting PCI core on warm reset on PCI-E cards
404 * results card to hang and always return 0xffff... so 598 * results card to hang and always return 0xffff... so
405 * we ingore that flag for PCI-E cards. On PCI cards 599 * we ingore that flag for PCI-E cards. On PCI cards
406 * this flag gets cleared after 64 PCI clocks. 600 * this flag gets cleared after 64 PCI clocks.
407 */ 601 */
408 bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI; 602 bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI;
409 603
410 if (ah->ah_version == AR5K_AR5210) { 604 if (ah->ah_version == AR5K_AR5210) {
411 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | 605 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
@@ -413,8 +607,12 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
413 AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI); 607 AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
414 mdelay(2); 608 mdelay(2);
415 } else { 609 } else {
416 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | 610 if (ath5k_get_bus_type(ah) == ATH_AHB)
417 AR5K_RESET_CTL_BASEBAND | bus_flags); 611 ret = ath5k_hw_wisoc_reset(ah, AR5K_RESET_CTL_PCU |
612 AR5K_RESET_CTL_BASEBAND);
613 else
614 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
615 AR5K_RESET_CTL_BASEBAND | bus_flags);
418 } 616 }
419 617
420 if (ret) { 618 if (ret) {
@@ -429,9 +627,15 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
429 return ret; 627 return ret;
430 } 628 }
431 629
432 /* ...clear reset control register and pull device out of 630 /* ...reset configuration regiter on Wisoc ...
433 * warm reset */ 631 * ...clear reset control register and pull device out of
434 if (ath5k_hw_nic_reset(ah, 0)) { 632 * warm reset on others */
633 if (ath5k_get_bus_type(ah) == ATH_AHB)
634 ret = ath5k_hw_wisoc_reset(ah, 0);
635 else
636 ret = ath5k_hw_nic_reset(ah, 0);
637
638 if (ret) {
435 ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n"); 639 ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
436 return -EIO; 640 return -EIO;
437 } 641 }
@@ -466,7 +670,8 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
466 * CCK headers) operation. We need to test 670 * CCK headers) operation. We need to test
467 * this, 5211 might support ofdm-only g after 671 * this, 5211 might support ofdm-only g after
468 * all, there are also initial register values 672 * all, there are also initial register values
469 * in the code for g mode (see initvals.c). */ 673 * in the code for g mode (see initvals.c).
674 */
470 if (ah->ah_version == AR5K_AR5211) 675 if (ah->ah_version == AR5K_AR5211)
471 mode |= AR5K_PHY_MODE_MOD_OFDM; 676 mode |= AR5K_PHY_MODE_MOD_OFDM;
472 else 677 else
@@ -479,6 +684,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
479 } else if (flags & CHANNEL_5GHZ) { 684 } else if (flags & CHANNEL_5GHZ) {
480 mode |= AR5K_PHY_MODE_FREQ_5GHZ; 685 mode |= AR5K_PHY_MODE_FREQ_5GHZ;
481 686
687 /* Different PLL setting for 5413 */
482 if (ah->ah_radio == AR5K_RF5413) 688 if (ah->ah_radio == AR5K_RF5413)
483 clock = AR5K_PHY_PLL_40MHZ_5413; 689 clock = AR5K_PHY_PLL_40MHZ_5413;
484 else 690 else
@@ -496,12 +702,29 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
496 return -EINVAL; 702 return -EINVAL;
497 } 703 }
498 704
499 if (flags & CHANNEL_TURBO) 705 /*XXX: Can bwmode be used with dynamic mode ?
500 turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT; 706 * (I don't think it supports 44MHz) */
707 /* On 2425 initvals TURBO_SHORT is not pressent */
708 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {
709 turbo = AR5K_PHY_TURBO_MODE |
710 (ah->ah_radio == AR5K_RF2425) ? 0 :
711 AR5K_PHY_TURBO_SHORT;
712 } else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) {
713 if (ah->ah_radio == AR5K_RF5413) {
714 mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ?
715 AR5K_PHY_MODE_HALF_RATE :
716 AR5K_PHY_MODE_QUARTER_RATE;
717 } else if (ah->ah_version == AR5K_AR5212) {
718 clock |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ?
719 AR5K_PHY_PLL_HALF_RATE :
720 AR5K_PHY_PLL_QUARTER_RATE;
721 }
722 }
723
501 } else { /* Reset the device */ 724 } else { /* Reset the device */
502 725
503 /* ...enable Atheros turbo mode if requested */ 726 /* ...enable Atheros turbo mode if requested */
504 if (flags & CHANNEL_TURBO) 727 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
505 ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE, 728 ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
506 AR5K_PHY_TURBO); 729 AR5K_PHY_TURBO);
507 } 730 }
@@ -522,107 +745,10 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
522 return 0; 745 return 0;
523} 746}
524 747
525/*
526 * If there is an external 32KHz crystal available, use it
527 * as ref. clock instead of 32/40MHz clock and baseband clocks
528 * to save power during sleep or restore normal 32/40MHz
529 * operation.
530 *
531 * XXX: When operating on 32KHz certain PHY registers (27 - 31,
532 * 123 - 127) require delay on access.
533 */
534static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
535{
536 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
537 u32 scal, spending, usec32;
538
539 /* Only set 32KHz settings if we have an external
540 * 32KHz crystal present */
541 if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
542 AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
543 enable) {
544
545 /* 1 usec/cycle */
546 AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
547 /* Set up tsf increment on each cycle */
548 AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
549
550 /* Set baseband sleep control registers
551 * and sleep control rate */
552 ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
553
554 if ((ah->ah_radio == AR5K_RF5112) ||
555 (ah->ah_radio == AR5K_RF5413) ||
556 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
557 spending = 0x14;
558 else
559 spending = 0x18;
560 ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
561
562 if ((ah->ah_radio == AR5K_RF5112) ||
563 (ah->ah_radio == AR5K_RF5413) ||
564 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
565 ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
566 ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
567 ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
568 ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
569 AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
570 AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
571 } else {
572 ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
573 ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
574 ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
575 ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
576 AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
577 AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
578 }
579
580 /* Enable sleep clock operation */
581 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
582 AR5K_PCICFG_SLEEP_CLOCK_EN);
583
584 } else {
585
586 /* Disable sleep clock operation and
587 * restore default parameters */
588 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
589 AR5K_PCICFG_SLEEP_CLOCK_EN);
590
591 AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
592 AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
593
594 ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
595 ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
596
597 if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
598 scal = AR5K_PHY_SCAL_32MHZ_2417;
599 else if (ee->ee_is_hb63)
600 scal = AR5K_PHY_SCAL_32MHZ_HB63;
601 else
602 scal = AR5K_PHY_SCAL_32MHZ;
603 ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
604
605 ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
606 ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
607 748
608 if ((ah->ah_radio == AR5K_RF5112) || 749/**************************************\
609 (ah->ah_radio == AR5K_RF5413) || 750* Post-initvals register modifications *
610 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) 751\**************************************/
611 spending = 0x14;
612 else
613 spending = 0x18;
614 ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
615
616 if ((ah->ah_radio == AR5K_RF5112) ||
617 (ah->ah_radio == AR5K_RF5413))
618 usec32 = 39;
619 else
620 usec32 = 31;
621 AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32);
622
623 AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
624 }
625}
626 752
627/* TODO: Half/Quarter rate */ 753/* TODO: Half/Quarter rate */
628static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, 754static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
@@ -663,22 +789,10 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
663 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG, 789 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
664 AR5K_TXCFG_DCU_DBL_BUF_DIS); 790 AR5K_TXCFG_DCU_DBL_BUF_DIS);
665 791
666 /* Set DAC/ADC delays */
667 if (ah->ah_version == AR5K_AR5212) {
668 u32 scal;
669 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
670 if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
671 scal = AR5K_PHY_SCAL_32MHZ_2417;
672 else if (ee->ee_is_hb63)
673 scal = AR5K_PHY_SCAL_32MHZ_HB63;
674 else
675 scal = AR5K_PHY_SCAL_32MHZ;
676 ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
677 }
678
679 /* Set fast ADC */ 792 /* Set fast ADC */
680 if ((ah->ah_radio == AR5K_RF5413) || 793 if ((ah->ah_radio == AR5K_RF5413) ||
681 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) { 794 (ah->ah_radio == AR5K_RF2317) ||
795 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
682 u32 fast_adc = true; 796 u32 fast_adc = true;
683 797
684 if (channel->center_freq == 2462 || 798 if (channel->center_freq == 2462 ||
@@ -706,33 +820,68 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
706 } 820 }
707 821
708 if (ah->ah_mac_srev < AR5K_SREV_AR5211) { 822 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
709 u32 usec_reg;
710 /* 5311 has different tx/rx latency masks
711 * from 5211, since we deal 5311 the same
712 * as 5211 when setting initvals, shift
713 * values here to their proper locations */
714 usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
715 ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 |
716 AR5K_USEC_32 |
717 AR5K_USEC_TX_LATENCY_5211 |
718 AR5K_REG_SM(29,
719 AR5K_USEC_RX_LATENCY_5210)),
720 AR5K_USEC_5211);
721 /* Clear QCU/DCU clock gating register */ 823 /* Clear QCU/DCU clock gating register */
722 ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT); 824 ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);
723 /* Set DAC/ADC delays */ 825 /* Set DAC/ADC delays */
724 ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL); 826 ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ_5311,
827 AR5K_PHY_SCAL);
725 /* Enable PCU FIFO corruption ECO */ 828 /* Enable PCU FIFO corruption ECO */
726 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, 829 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
727 AR5K_DIAG_SW_ECO_ENABLE); 830 AR5K_DIAG_SW_ECO_ENABLE);
728 } 831 }
832
833 if (ah->ah_bwmode) {
834 /* Increase PHY switch and AGC settling time
835 * on turbo mode (ath5k_hw_commit_eeprom_settings
836 * will override settling time if available) */
837 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {
838
839 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
840 AR5K_PHY_SETTLING_AGC,
841 AR5K_AGC_SETTLING_TURBO);
842
843 /* XXX: Initvals indicate we only increase
844 * switch time on AR5212, 5211 and 5210
845 * only change agc time (bug?) */
846 if (ah->ah_version == AR5K_AR5212)
847 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
848 AR5K_PHY_SETTLING_SWITCH,
849 AR5K_SWITCH_SETTLING_TURBO);
850
851 if (ah->ah_version == AR5K_AR5210) {
852 /* Set Frame Control Register */
853 ath5k_hw_reg_write(ah,
854 (AR5K_PHY_FRAME_CTL_INI |
855 AR5K_PHY_TURBO_MODE |
856 AR5K_PHY_TURBO_SHORT | 0x2020),
857 AR5K_PHY_FRAME_CTL_5210);
858 }
859 /* On 5413 PHY force window length for half/quarter rate*/
860 } else if ((ah->ah_mac_srev >= AR5K_SREV_AR5424) &&
861 (ah->ah_mac_srev <= AR5K_SREV_AR5414)) {
862 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL_5211,
863 AR5K_PHY_FRAME_CTL_WIN_LEN,
864 3);
865 }
866 } else if (ah->ah_version == AR5K_AR5210) {
867 /* Set Frame Control Register for normal operation */
868 ath5k_hw_reg_write(ah, (AR5K_PHY_FRAME_CTL_INI | 0x1020),
869 AR5K_PHY_FRAME_CTL_5210);
870 }
729} 871}
730 872
731static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, 873static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
732 struct ieee80211_channel *channel, u8 ee_mode) 874 struct ieee80211_channel *channel)
733{ 875{
734 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 876 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
735 s16 cck_ofdm_pwr_delta; 877 s16 cck_ofdm_pwr_delta;
878 u8 ee_mode;
879
880 /* TODO: Add support for AR5210 EEPROM */
881 if (ah->ah_version == AR5K_AR5210)
882 return;
883
884 ee_mode = ath5k_eeprom_mode_from_channel(channel);
736 885
737 /* Adjust power delta for channel 14 */ 886 /* Adjust power delta for channel 14 */
738 if (channel->center_freq == 2484) 887 if (channel->center_freq == 2484)
@@ -772,7 +921,7 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
772 AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]), 921 AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
773 AR5K_PHY_NFTHRES); 922 AR5K_PHY_NFTHRES);
774 923
775 if ((channel->hw_value & CHANNEL_TURBO) && 924 if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) &&
776 (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) { 925 (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {
777 /* Switch settling time (Turbo) */ 926 /* Switch settling time (Turbo) */
778 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, 927 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
@@ -870,143 +1019,175 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
870 ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE); 1019 ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);
871} 1020}
872 1021
873/* 1022
874 * Main reset function 1023/*********************\
875 */ 1024* Main reset function *
1025\*********************/
1026
876int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, 1027int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
877 struct ieee80211_channel *channel, bool change_channel) 1028 struct ieee80211_channel *channel, bool fast, bool skip_pcu)
878{ 1029{
879 struct ath_common *common = ath5k_hw_common(ah); 1030 u32 s_seq[10], s_led[3], tsf_up, tsf_lo;
880 u32 s_seq[10], s_led[3], staid1_flags, tsf_up, tsf_lo; 1031 u8 mode;
881 u32 phy_tst1;
882 u8 mode, freq, ee_mode;
883 int i, ret; 1032 int i, ret;
884 1033
885 ee_mode = 0;
886 staid1_flags = 0;
887 tsf_up = 0; 1034 tsf_up = 0;
888 tsf_lo = 0; 1035 tsf_lo = 0;
889 freq = 0;
890 mode = 0; 1036 mode = 0;
891 1037
892 /* 1038 /*
893 * Save some registers before a reset 1039 * Sanity check for fast flag
1040 * Fast channel change only available
1041 * on AR2413/AR5413.
894 */ 1042 */
895 /*DCU/Antenna selection not available on 5210*/ 1043 if (fast && (ah->ah_radio != AR5K_RF2413) &&
896 if (ah->ah_version != AR5K_AR5210) { 1044 (ah->ah_radio != AR5K_RF5413))
1045 fast = 0;
897 1046
898 switch (channel->hw_value & CHANNEL_MODES) { 1047 /* Disable sleep clock operation
899 case CHANNEL_A: 1048 * to avoid register access delay on certain
900 mode = AR5K_MODE_11A; 1049 * PHY registers */
901 freq = AR5K_INI_RFGAIN_5GHZ; 1050 if (ah->ah_version == AR5K_AR5212)
902 ee_mode = AR5K_EEPROM_MODE_11A; 1051 ath5k_hw_set_sleep_clock(ah, false);
903 break; 1052
904 case CHANNEL_G: 1053 /*
905 mode = AR5K_MODE_11G; 1054 * Stop PCU
906 freq = AR5K_INI_RFGAIN_2GHZ; 1055 */
907 ee_mode = AR5K_EEPROM_MODE_11G; 1056 ath5k_hw_stop_rx_pcu(ah);
908 break; 1057
909 case CHANNEL_B: 1058 /*
910 mode = AR5K_MODE_11B; 1059 * Stop DMA
911 freq = AR5K_INI_RFGAIN_2GHZ; 1060 *
912 ee_mode = AR5K_EEPROM_MODE_11B; 1061 * Note: If DMA didn't stop continue
913 break; 1062 * since only a reset will fix it.
914 case CHANNEL_T: 1063 */
915 mode = AR5K_MODE_11A_TURBO; 1064 ret = ath5k_hw_dma_stop(ah);
916 freq = AR5K_INI_RFGAIN_5GHZ; 1065
917 ee_mode = AR5K_EEPROM_MODE_11A; 1066 /* RF Bus grant won't work if we have pending
918 break; 1067 * frames */
919 case CHANNEL_TG: 1068 if (ret && fast) {
920 if (ah->ah_version == AR5K_AR5211) { 1069 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
921 ATH5K_ERR(ah->ah_sc, 1070 "DMA didn't stop, falling back to normal reset\n");
922 "TurboG mode not available on 5211"); 1071 fast = 0;
923 return -EINVAL; 1072 /* Non fatal, just continue with
924 } 1073 * normal reset */
925 mode = AR5K_MODE_11G_TURBO; 1074 ret = 0;
926 freq = AR5K_INI_RFGAIN_2GHZ; 1075 }
927 ee_mode = AR5K_EEPROM_MODE_11G; 1076
928 break; 1077 switch (channel->hw_value & CHANNEL_MODES) {
929 case CHANNEL_XR: 1078 case CHANNEL_A:
930 if (ah->ah_version == AR5K_AR5211) { 1079 mode = AR5K_MODE_11A;
931 ATH5K_ERR(ah->ah_sc, 1080 break;
932 "XR mode not available on 5211"); 1081 case CHANNEL_G:
933 return -EINVAL; 1082
934 } 1083 if (ah->ah_version <= AR5K_AR5211) {
935 mode = AR5K_MODE_XR;
936 freq = AR5K_INI_RFGAIN_5GHZ;
937 ee_mode = AR5K_EEPROM_MODE_11A;
938 break;
939 default:
940 ATH5K_ERR(ah->ah_sc, 1084 ATH5K_ERR(ah->ah_sc,
941 "invalid channel: %d\n", channel->center_freq); 1085 "G mode not available on 5210/5211");
942 return -EINVAL; 1086 return -EINVAL;
943 } 1087 }
944 1088
945 if (change_channel) { 1089 mode = AR5K_MODE_11G;
946 /* 1090 break;
947 * Save frame sequence count 1091 case CHANNEL_B:
948 * For revs. after Oahu, only save
949 * seq num for DCU 0 (Global seq num)
950 */
951 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
952 1092
953 for (i = 0; i < 10; i++) 1093 if (ah->ah_version < AR5K_AR5211) {
954 s_seq[i] = ath5k_hw_reg_read(ah, 1094 ATH5K_ERR(ah->ah_sc,
955 AR5K_QUEUE_DCU_SEQNUM(i)); 1095 "B mode not available on 5210");
1096 return -EINVAL;
1097 }
956 1098
957 } else { 1099 mode = AR5K_MODE_11B;
958 s_seq[0] = ath5k_hw_reg_read(ah, 1100 break;
959 AR5K_QUEUE_DCU_SEQNUM(0)); 1101 case CHANNEL_XR:
960 } 1102 if (ah->ah_version == AR5K_AR5211) {
1103 ATH5K_ERR(ah->ah_sc,
1104 "XR mode not available on 5211");
1105 return -EINVAL;
1106 }
1107 mode = AR5K_MODE_XR;
1108 break;
1109 default:
1110 ATH5K_ERR(ah->ah_sc,
1111 "invalid channel: %d\n", channel->center_freq);
1112 return -EINVAL;
1113 }
961 1114
962 /* TSF accelerates on AR5211 durring reset 1115 /*
963 * As a workaround save it here and restore 1116 * If driver requested fast channel change and DMA has stopped
964 * it later so that it's back in time after 1117 * go on. If it fails continue with a normal reset.
965 * reset. This way it'll get re-synced on the 1118 */
966 * next beacon without breaking ad-hoc. 1119 if (fast) {
967 * 1120 ret = ath5k_hw_phy_init(ah, channel, mode, true);
968 * On AR5212 TSF is almost preserved across a 1121 if (ret) {
969 * reset so it stays back in time anyway and 1122 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
970 * we don't have to save/restore it. 1123 "fast chan change failed, falling back to normal reset\n");
971 * 1124 /* Non fatal, can happen eg.
972 * XXX: Since this breaks power saving we have 1125 * on mode change */
973 * to disable power saving until we receive the 1126 ret = 0;
974 * next beacon, so we can resync beacon timers */ 1127 } else {
975 if (ah->ah_version == AR5K_AR5211) { 1128 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
976 tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32); 1129 "fast chan change successful\n");
977 tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32); 1130 return 0;
978 }
979 } 1131 }
1132 }
1133
1134 /*
1135 * Save some registers before a reset
1136 */
1137 if (ah->ah_version != AR5K_AR5210) {
1138 /*
1139 * Save frame sequence count
1140 * For revs. after Oahu, only save
1141 * seq num for DCU 0 (Global seq num)
1142 */
1143 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
980 1144
981 if (ah->ah_version == AR5K_AR5212) { 1145 for (i = 0; i < 10; i++)
982 /* Restore normal 32/40MHz clock operation 1146 s_seq[i] = ath5k_hw_reg_read(ah,
983 * to avoid register access delay on certain 1147 AR5K_QUEUE_DCU_SEQNUM(i));
984 * PHY registers */
985 ath5k_hw_set_sleep_clock(ah, false);
986 1148
987 /* Since we are going to write rf buffer 1149 } else {
988 * check if we have any pending gain_F 1150 s_seq[0] = ath5k_hw_reg_read(ah,
989 * optimization settings */ 1151 AR5K_QUEUE_DCU_SEQNUM(0));
990 if (change_channel && ah->ah_rf_banks != NULL) 1152 }
991 ath5k_hw_gainf_calibrate(ah); 1153
1154 /* TSF accelerates on AR5211 during reset
1155 * As a workaround save it here and restore
1156 * it later so that it's back in time after
1157 * reset. This way it'll get re-synced on the
1158 * next beacon without breaking ad-hoc.
1159 *
1160 * On AR5212 TSF is almost preserved across a
1161 * reset so it stays back in time anyway and
1162 * we don't have to save/restore it.
1163 *
1164 * XXX: Since this breaks power saving we have
1165 * to disable power saving until we receive the
1166 * next beacon, so we can resync beacon timers */
1167 if (ah->ah_version == AR5K_AR5211) {
1168 tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
1169 tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
992 } 1170 }
993 } 1171 }
994 1172
1173
995 /*GPIOs*/ 1174 /*GPIOs*/
996 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & 1175 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &
997 AR5K_PCICFG_LEDSTATE; 1176 AR5K_PCICFG_LEDSTATE;
998 s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR); 1177 s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
999 s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO); 1178 s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
1000 1179
1001 /* AR5K_STA_ID1 flags, only preserve antenna 1180
1002 * settings and ack/cts rate mode */ 1181 /*
1003 staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 1182 * Since we are going to write rf buffer
1004 (AR5K_STA_ID1_DEFAULT_ANTENNA | 1183 * check if we have any pending gain_F
1005 AR5K_STA_ID1_DESC_ANTENNA | 1184 * optimization settings
1006 AR5K_STA_ID1_RTS_DEF_ANTENNA | 1185 */
1007 AR5K_STA_ID1_ACKCTS_6MB | 1186 if (ah->ah_version == AR5K_AR5212 &&
1008 AR5K_STA_ID1_BASE_RATE_11B | 1187 (ah->ah_radio <= AR5K_RF5112)) {
1009 AR5K_STA_ID1_SELFGEN_DEF_ANT); 1188 if (!fast && ah->ah_rf_banks != NULL)
1189 ath5k_hw_gainf_calibrate(ah);
1190 }
1010 1191
1011 /* Wakeup the device */ 1192 /* Wakeup the device */
1012 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false); 1193 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
@@ -1021,121 +1202,42 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1021 AR5K_PHY(0)); 1202 AR5K_PHY(0));
1022 1203
1023 /* Write initial settings */ 1204 /* Write initial settings */
1024 ret = ath5k_hw_write_initvals(ah, mode, change_channel); 1205 ret = ath5k_hw_write_initvals(ah, mode, skip_pcu);
1025 if (ret) 1206 if (ret)
1026 return ret; 1207 return ret;
1027 1208
1209 /* Initialize core clock settings */
1210 ath5k_hw_init_core_clock(ah);
1211
1028 /* 1212 /*
1029 * 5211/5212 Specific 1213 * Tweak initval settings for revised
1214 * chipsets and add some more config
1215 * bits
1030 */ 1216 */
1031 if (ah->ah_version != AR5K_AR5210) { 1217 ath5k_hw_tweak_initval_settings(ah, channel);
1032
1033 /*
1034 * Write initial RF gain settings
1035 * This should work for both 5111/5112
1036 */
1037 ret = ath5k_hw_rfgain_init(ah, freq);
1038 if (ret)
1039 return ret;
1040
1041 mdelay(1);
1042
1043 /*
1044 * Tweak initval settings for revised
1045 * chipsets and add some more config
1046 * bits
1047 */
1048 ath5k_hw_tweak_initval_settings(ah, channel);
1049
1050 /*
1051 * Set TX power
1052 */
1053 ret = ath5k_hw_txpower(ah, channel, ee_mode,
1054 ah->ah_txpower.txp_max_pwr / 2);
1055 if (ret)
1056 return ret;
1057
1058 /* Write rate duration table only on AR5212 and if
1059 * virtual interface has already been brought up
1060 * XXX: rethink this after new mode changes to
1061 * mac80211 are integrated */
1062 if (ah->ah_version == AR5K_AR5212 &&
1063 ah->ah_sc->vif != NULL)
1064 ath5k_hw_write_rate_duration(ah, mode);
1065
1066 /*
1067 * Write RF buffer
1068 */
1069 ret = ath5k_hw_rfregs_init(ah, channel, mode);
1070 if (ret)
1071 return ret;
1072
1073
1074 /* Write OFDM timings on 5212*/
1075 if (ah->ah_version == AR5K_AR5212 &&
1076 channel->hw_value & CHANNEL_OFDM) {
1077 1218
1078 ret = ath5k_hw_write_ofdm_timings(ah, channel); 1219 /* Commit values from EEPROM */
1079 if (ret) 1220 ath5k_hw_commit_eeprom_settings(ah, channel);
1080 return ret;
1081 1221
1082 /* Spur info is available only from EEPROM versions
1083 * bigger than 5.3 but but the EEPOM routines will use
1084 * static values for older versions */
1085 if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
1086 ath5k_hw_set_spur_mitigation_filter(ah,
1087 channel);
1088 }
1089
1090 /*Enable/disable 802.11b mode on 5111
1091 (enable 2111 frequency converter + CCK)*/
1092 if (ah->ah_radio == AR5K_RF5111) {
1093 if (mode == AR5K_MODE_11B)
1094 AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
1095 AR5K_TXCFG_B_MODE);
1096 else
1097 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
1098 AR5K_TXCFG_B_MODE);
1099 }
1100
1101 /* Commit values from EEPROM */
1102 ath5k_hw_commit_eeprom_settings(ah, channel, ee_mode);
1103
1104 } else {
1105 /*
1106 * For 5210 we do all initialization using
1107 * initvals, so we don't have to modify
1108 * any settings (5210 also only supports
1109 * a/aturbo modes)
1110 */
1111 mdelay(1);
1112 /* Disable phy and wait */
1113 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
1114 mdelay(1);
1115 }
1116 1222
1117 /* 1223 /*
1118 * Restore saved values 1224 * Restore saved values
1119 */ 1225 */
1120 1226
1121 /*DCU/Antenna selection not available on 5210*/ 1227 /* Seqnum, TSF */
1122 if (ah->ah_version != AR5K_AR5210) { 1228 if (ah->ah_version != AR5K_AR5210) {
1229 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
1230 for (i = 0; i < 10; i++)
1231 ath5k_hw_reg_write(ah, s_seq[i],
1232 AR5K_QUEUE_DCU_SEQNUM(i));
1233 } else {
1234 ath5k_hw_reg_write(ah, s_seq[0],
1235 AR5K_QUEUE_DCU_SEQNUM(0));
1236 }
1123 1237
1124 if (change_channel) { 1238 if (ah->ah_version == AR5K_AR5211) {
1125 if (ah->ah_mac_srev < AR5K_SREV_AR5211) { 1239 ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
1126 for (i = 0; i < 10; i++) 1240 ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
1127 ath5k_hw_reg_write(ah, s_seq[i],
1128 AR5K_QUEUE_DCU_SEQNUM(i));
1129 } else {
1130 ath5k_hw_reg_write(ah, s_seq[0],
1131 AR5K_QUEUE_DCU_SEQNUM(0));
1132 }
1133
1134
1135 if (ah->ah_version == AR5K_AR5211) {
1136 ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
1137 ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
1138 }
1139 } 1241 }
1140 } 1242 }
1141 1243
@@ -1146,203 +1248,34 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1146 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR); 1248 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
1147 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO); 1249 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
1148 1250
1149 /* Restore sta_id flags and preserve our mac address*/
1150 ath5k_hw_reg_write(ah,
1151 get_unaligned_le32(common->macaddr),
1152 AR5K_STA_ID0);
1153 ath5k_hw_reg_write(ah,
1154 staid1_flags | get_unaligned_le16(common->macaddr + 4),
1155 AR5K_STA_ID1);
1156
1157
1158 /* 1251 /*
1159 * Configure PCU 1252 * Initialize PCU
1160 */ 1253 */
1161 1254 ath5k_hw_pcu_init(ah, op_mode, mode);
1162 /* Restore bssid and bssid mask */
1163 ath5k_hw_set_associd(ah);
1164
1165 /* Set PCU config */
1166 ath5k_hw_set_opmode(ah, op_mode);
1167
1168 /* Clear any pending interrupts
1169 * PISR/SISR Not available on 5210 */
1170 if (ah->ah_version != AR5K_AR5210)
1171 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
1172
1173 /* Set RSSI/BRSSI thresholds
1174 *
1175 * Note: If we decide to set this value
1176 * dynamicaly, have in mind that when AR5K_RSSI_THR
1177 * register is read it might return 0x40 if we haven't
1178 * wrote anything to it plus BMISS RSSI threshold is zeroed.
1179 * So doing a save/restore procedure here isn't the right
1180 * choice. Instead store it on ath5k_hw */
1181 ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
1182 AR5K_TUNE_BMISS_THRES <<
1183 AR5K_RSSI_THR_BMISS_S),
1184 AR5K_RSSI_THR);
1185
1186 /* MIC QoS support */
1187 if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
1188 ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
1189 ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
1190 }
1191
1192 /* QoS NOACK Policy */
1193 if (ah->ah_version == AR5K_AR5212) {
1194 ath5k_hw_reg_write(ah,
1195 AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
1196 AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |
1197 AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
1198 AR5K_QOS_NOACK);
1199 }
1200
1201 1255
1202 /* 1256 /*
1203 * Configure PHY 1257 * Initialize PHY
1204 */ 1258 */
1205 1259 ret = ath5k_hw_phy_init(ah, channel, mode, false);
1206 /* Set channel on PHY */ 1260 if (ret) {
1207 ret = ath5k_hw_channel(ah, channel); 1261 ATH5K_ERR(ah->ah_sc,
1208 if (ret) 1262 "failed to initialize PHY (%i) !\n", ret);
1209 return ret; 1263 return ret;
1210
1211 /*
1212 * Enable the PHY and wait until completion
1213 * This includes BaseBand and Synthesizer
1214 * activation.
1215 */
1216 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
1217
1218 /*
1219 * On 5211+ read activation -> rx delay
1220 * and use it.
1221 *
1222 * TODO: Half/quarter rate support
1223 */
1224 if (ah->ah_version != AR5K_AR5210) {
1225 u32 delay;
1226 delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
1227 AR5K_PHY_RX_DELAY_M;
1228 delay = (channel->hw_value & CHANNEL_CCK) ?
1229 ((delay << 2) / 22) : (delay / 10);
1230
1231 udelay(100 + (2 * delay));
1232 } else {
1233 mdelay(1);
1234 }
1235
1236 /*
1237 * Perform ADC test to see if baseband is ready
1238 * Set tx hold and check adc test register
1239 */
1240 phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
1241 ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
1242 for (i = 0; i <= 20; i++) {
1243 if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
1244 break;
1245 udelay(200);
1246 }
1247 ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
1248
1249 /*
1250 * Start automatic gain control calibration
1251 *
1252 * During AGC calibration RX path is re-routed to
1253 * a power detector so we don't receive anything.
1254 *
1255 * This method is used to calibrate some static offsets
1256 * used together with on-the fly I/Q calibration (the
1257 * one performed via ath5k_hw_phy_calibrate), that doesn't
1258 * interrupt rx path.
1259 *
1260 * While rx path is re-routed to the power detector we also
1261 * start a noise floor calibration, to measure the
1262 * card's noise floor (the noise we measure when we are not
1263 * transmiting or receiving anything).
1264 *
1265 * If we are in a noisy environment AGC calibration may time
1266 * out and/or noise floor calibration might timeout.
1267 */
1268 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1269 AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);
1270
1271 /* At the same time start I/Q calibration for QAM constellation
1272 * -no need for CCK- */
1273 ah->ah_calibration = false;
1274 if (!(mode == AR5K_MODE_11B)) {
1275 ah->ah_calibration = true;
1276 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
1277 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
1278 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
1279 AR5K_PHY_IQ_RUN);
1280 } 1264 }
1281 1265
1282 /* Wait for gain calibration to finish (we check for I/Q calibration
1283 * during ath5k_phy_calibrate) */
1284 if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
1285 AR5K_PHY_AGCCTL_CAL, 0, false)) {
1286 ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
1287 channel->center_freq);
1288 }
1289
1290 /* Restore antenna mode */
1291 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
1292
1293 /* Restore slot time and ACK timeouts */
1294 if (ah->ah_coverage_class > 0)
1295 ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
1296
1297 /* 1266 /*
1298 * Configure QCUs/DCUs 1267 * Configure QCUs/DCUs
1299 */ 1268 */
1300 1269 ret = ath5k_hw_init_queues(ah);
1301 /* TODO: HW Compression support for data queues */ 1270 if (ret)
1302 /* TODO: Burst prefetch for data queues */ 1271 return ret;
1303
1304 /*
1305 * Reset queues and start beacon timers at the end of the reset routine
1306 * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
1307 * Note: If we want we can assign multiple qcus on one dcu.
1308 */
1309 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
1310 ret = ath5k_hw_reset_tx_queue(ah, i);
1311 if (ret) {
1312 ATH5K_ERR(ah->ah_sc,
1313 "failed to reset TX queue #%d\n", i);
1314 return ret;
1315 }
1316 }
1317 1272
1318 1273
1319 /* 1274 /*
1320 * Configure DMA/Interrupts 1275 * Initialize DMA/Interrupts
1321 */ 1276 */
1277 ath5k_hw_dma_init(ah);
1322 1278
1323 /*
1324 * Set Rx/Tx DMA Configuration
1325 *
1326 * Set standard DMA size (128). Note that
1327 * a DMA size of 512 causes rx overruns and tx errors
1328 * on pci-e cards (tested on 5424 but since rx overruns
1329 * also occur on 5416/5418 with madwifi we set 128
1330 * for all PCI-E cards to be safe).
1331 *
1332 * XXX: need to check 5210 for this
1333 * TODO: Check out tx triger level, it's always 64 on dumps but I
1334 * guess we can tweak it and see how it goes ;-)
1335 */
1336 if (ah->ah_version != AR5K_AR5210) {
1337 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
1338 AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
1339 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
1340 AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
1341 }
1342
1343 /* Pre-enable interrupts on 5211/5212*/
1344 if (ah->ah_version != AR5K_AR5210)
1345 ath5k_hw_set_imr(ah, ah->ah_imr);
1346 1279
1347 /* Enable 32KHz clock function for AR5212+ chips 1280 /* Enable 32KHz clock function for AR5212+ chips
1348 * Set clocks to 32KHz operation and use an 1281 * Set clocks to 32KHz operation and use an
diff --git a/drivers/net/wireless/ath/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h
index e50baff66175..16b67e84906d 100644
--- a/drivers/net/wireless/ath/ath5k/rfbuffer.h
+++ b/drivers/net/wireless/ath/ath5k/rfbuffer.h
@@ -25,10 +25,10 @@
25 * 25 *
26 * We don't write on those registers directly but 26 * We don't write on those registers directly but
27 * we send a data packet on the chip, using a special register, 27 * we send a data packet on the chip, using a special register,
28 * that holds all the settings we need. After we 've sent the 28 * that holds all the settings we need. After we've sent the
29 * data packet, we write on another special register to notify hw 29 * data packet, we write on another special register to notify hw
30 * to apply the settings. This is done so that control registers 30 * to apply the settings. This is done so that control registers
31 * can be dynamicaly programmed during operation and the settings 31 * can be dynamically programmed during operation and the settings
32 * are applied faster on the hw. 32 * are applied faster on the hw.
33 * 33 *
34 * We call each data packet an "RF Bank" and all the data we write 34 * We call each data packet an "RF Bank" and all the data we write
@@ -51,7 +51,7 @@
51struct ath5k_ini_rfbuffer { 51struct ath5k_ini_rfbuffer {
52 u8 rfb_bank; /* RF Bank number */ 52 u8 rfb_bank; /* RF Bank number */
53 u16 rfb_ctrl_register; /* RF Buffer control register */ 53 u16 rfb_ctrl_register; /* RF Buffer control register */
54 u32 rfb_mode_data[5]; /* RF Buffer data for each mode */ 54 u32 rfb_mode_data[3]; /* RF Buffer data for each mode */
55}; 55};
56 56
57/* 57/*
@@ -79,8 +79,10 @@ struct ath5k_rf_reg {
79 * life easier by using an index for each register 79 * life easier by using an index for each register
80 * instead of a full rfb_field */ 80 * instead of a full rfb_field */
81enum ath5k_rf_regs_idx { 81enum ath5k_rf_regs_idx {
82 /* BANK 2 */
83 AR5K_RF_TURBO = 0,
82 /* BANK 6 */ 84 /* BANK 6 */
83 AR5K_RF_OB_2GHZ = 0, 85 AR5K_RF_OB_2GHZ,
84 AR5K_RF_OB_5GHZ, 86 AR5K_RF_OB_5GHZ,
85 AR5K_RF_DB_2GHZ, 87 AR5K_RF_DB_2GHZ,
86 AR5K_RF_DB_5GHZ, 88 AR5K_RF_DB_5GHZ,
@@ -134,6 +136,9 @@ enum ath5k_rf_regs_idx {
134* RF5111 (Sombrero) * 136* RF5111 (Sombrero) *
135\*******************/ 137\*******************/
136 138
139/* BANK 2 len pos col */
140#define AR5K_RF5111_RF_TURBO { 1, 3, 0 }
141
137/* BANK 6 len pos col */ 142/* BANK 6 len pos col */
138#define AR5K_RF5111_OB_2GHZ { 3, 119, 0 } 143#define AR5K_RF5111_OB_2GHZ { 3, 119, 0 }
139#define AR5K_RF5111_DB_2GHZ { 3, 122, 0 } 144#define AR5K_RF5111_DB_2GHZ { 3, 122, 0 }
@@ -158,6 +163,7 @@ enum ath5k_rf_regs_idx {
158#define AR5K_RF5111_MAX_TIME { 2, 49, 0 } 163#define AR5K_RF5111_MAX_TIME { 2, 49, 0 }
159 164
160static const struct ath5k_rf_reg rf_regs_5111[] = { 165static const struct ath5k_rf_reg rf_regs_5111[] = {
166 {2, AR5K_RF_TURBO, AR5K_RF5111_RF_TURBO},
161 {6, AR5K_RF_OB_2GHZ, AR5K_RF5111_OB_2GHZ}, 167 {6, AR5K_RF_OB_2GHZ, AR5K_RF5111_OB_2GHZ},
162 {6, AR5K_RF_DB_2GHZ, AR5K_RF5111_DB_2GHZ}, 168 {6, AR5K_RF_DB_2GHZ, AR5K_RF5111_DB_2GHZ},
163 {6, AR5K_RF_OB_5GHZ, AR5K_RF5111_OB_5GHZ}, 169 {6, AR5K_RF_OB_5GHZ, AR5K_RF5111_OB_5GHZ},
@@ -177,97 +183,52 @@ static const struct ath5k_rf_reg rf_regs_5111[] = {
177 183
178/* Default mode specific settings */ 184/* Default mode specific settings */
179static const struct ath5k_ini_rfbuffer rfb_5111[] = { 185static const struct ath5k_ini_rfbuffer rfb_5111[] = {
180 { 0, 0x989c, 186 /* BANK / C.R. A/XR B G */
181 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ 187 { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
182 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 188 { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
183 { 0, 0x989c, 189 { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
184 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 190 { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
185 { 0, 0x989c, 191 { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
186 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 192 { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
187 { 0, 0x989c, 193 { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
188 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 194 { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
189 { 0, 0x989c, 195 { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
190 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 196 { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
191 { 0, 0x989c, 197 { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
192 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 198 { 0, 0x989c, { 0x00380000, 0x00380000, 0x00380000 } },
193 { 0, 0x989c, 199 { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
194 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 200 { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
195 { 0, 0x989c, 201 { 0, 0x989c, { 0x00000000, 0x000000c0, 0x00000080 } },
196 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 202 { 0, 0x989c, { 0x000400f9, 0x000400ff, 0x000400fd } },
197 { 0, 0x989c, 203 { 0, 0x98d4, { 0x00000000, 0x00000004, 0x00000004 } },
198 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 204 { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
199 { 0, 0x989c, 205 { 2, 0x98d4, { 0x00000010, 0x00000010, 0x00000010 } },
200 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 206 { 3, 0x98d8, { 0x00601068, 0x00601068, 0x00601068 } },
201 { 0, 0x989c, 207 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
202 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 208 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
203 { 0, 0x989c, 209 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
204 { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } }, 210 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
205 { 0, 0x989c, 211 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
206 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 212 { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } },
207 { 0, 0x989c, 213 { 6, 0x989c, { 0x04000000, 0x04000000, 0x04000000 } },
208 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 214 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
209 { 0, 0x989c, 215 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
210 { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } }, 216 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
211 { 0, 0x989c, 217 { 6, 0x989c, { 0x00000000, 0x0a000000, 0x00000000 } },
212 { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } }, 218 { 6, 0x989c, { 0x003800c0, 0x023800c0, 0x003800c0 } },
213 { 0, 0x98d4, 219 { 6, 0x989c, { 0x00020006, 0x00000006, 0x00020006 } },
214 { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } }, 220 { 6, 0x989c, { 0x00000089, 0x00000089, 0x00000089 } },
215 { 1, 0x98d4, 221 { 6, 0x989c, { 0x000000a0, 0x000000a0, 0x000000a0 } },
216 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, 222 { 6, 0x989c, { 0x00040007, 0x00040007, 0x00040007 } },
217 { 2, 0x98d4, 223 { 6, 0x98d4, { 0x0000001a, 0x0000001a, 0x0000001a } },
218 { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } }, 224 { 7, 0x989c, { 0x00000040, 0x00000040, 0x00000040 } },
219 { 3, 0x98d8, 225 { 7, 0x989c, { 0x00000010, 0x00000010, 0x00000010 } },
220 { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } }, 226 { 7, 0x989c, { 0x00000008, 0x00000008, 0x00000008 } },
221 { 6, 0x989c, 227 { 7, 0x989c, { 0x0000004f, 0x0000004f, 0x0000004f } },
222 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 228 { 7, 0x989c, { 0x000000f1, 0x00000061, 0x000000f1 } },
223 { 6, 0x989c, 229 { 7, 0x989c, { 0x0000904f, 0x0000904c, 0x0000904f } },
224 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 230 { 7, 0x989c, { 0x0000125a, 0x0000129a, 0x0000125a } },
225 { 6, 0x989c, 231 { 7, 0x98cc, { 0x0000000e, 0x0000000f, 0x0000000e } },
226 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
227 { 6, 0x989c,
228 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
229 { 6, 0x989c,
230 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
231 { 6, 0x989c,
232 { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
233 { 6, 0x989c,
234 { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
235 { 6, 0x989c,
236 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
237 { 6, 0x989c,
238 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
239 { 6, 0x989c,
240 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
241 { 6, 0x989c,
242 { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
243 { 6, 0x989c,
244 { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
245 { 6, 0x989c,
246 { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
247 { 6, 0x989c,
248 { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
249 { 6, 0x989c,
250 { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
251 { 6, 0x989c,
252 { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
253 { 6, 0x98d4,
254 { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
255 { 7, 0x989c,
256 { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
257 { 7, 0x989c,
258 { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
259 { 7, 0x989c,
260 { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
261 { 7, 0x989c,
262 { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
263 { 7, 0x989c,
264 { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
265 { 7, 0x989c,
266 { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
267 { 7, 0x989c,
268 { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
269 { 7, 0x98cc,
270 { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
271}; 232};
272 233
273 234
@@ -276,6 +237,9 @@ static const struct ath5k_ini_rfbuffer rfb_5111[] = {
276* RF5112/RF2112 (Derby) * 237* RF5112/RF2112 (Derby) *
277\***********************/ 238\***********************/
278 239
240/* BANK 2 (Common) len pos col */
241#define AR5K_RF5112X_RF_TURBO { 1, 1, 2 }
242
279/* BANK 7 (Common) len pos col */ 243/* BANK 7 (Common) len pos col */
280#define AR5K_RF5112X_GAIN_I { 6, 14, 0 } 244#define AR5K_RF5112X_GAIN_I { 6, 14, 0 }
281#define AR5K_RF5112X_MIXVGA_OVR { 1, 36, 0 } 245#define AR5K_RF5112X_MIXVGA_OVR { 1, 36, 0 }
@@ -307,6 +271,7 @@ static const struct ath5k_ini_rfbuffer rfb_5111[] = {
307#define AR5K_RF5112_PWD(_n) { 1, (302 - _n), 3 } 271#define AR5K_RF5112_PWD(_n) { 1, (302 - _n), 3 }
308 272
309static const struct ath5k_rf_reg rf_regs_5112[] = { 273static const struct ath5k_rf_reg rf_regs_5112[] = {
274 {2, AR5K_RF_TURBO, AR5K_RF5112X_RF_TURBO},
310 {6, AR5K_RF_OB_2GHZ, AR5K_RF5112_OB_2GHZ}, 275 {6, AR5K_RF_OB_2GHZ, AR5K_RF5112_OB_2GHZ},
311 {6, AR5K_RF_DB_2GHZ, AR5K_RF5112_DB_2GHZ}, 276 {6, AR5K_RF_DB_2GHZ, AR5K_RF5112_DB_2GHZ},
312 {6, AR5K_RF_OB_5GHZ, AR5K_RF5112_OB_5GHZ}, 277 {6, AR5K_RF_OB_5GHZ, AR5K_RF5112_OB_5GHZ},
@@ -335,115 +300,61 @@ static const struct ath5k_rf_reg rf_regs_5112[] = {
335 300
336/* Default mode specific settings */ 301/* Default mode specific settings */
337static const struct ath5k_ini_rfbuffer rfb_5112[] = { 302static const struct ath5k_ini_rfbuffer rfb_5112[] = {
338 { 1, 0x98d4, 303 /* BANK / C.R. A/XR B G */
339 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ 304 { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
340 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, 305 { 2, 0x98d0, { 0x03060408, 0x03060408, 0x03060408 } },
341 { 2, 0x98d0, 306 { 3, 0x98dc, { 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
342 { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } }, 307 { 6, 0x989c, { 0x00a00000, 0x00a00000, 0x00a00000 } },
343 { 3, 0x98dc, 308 { 6, 0x989c, { 0x000a0000, 0x000a0000, 0x000a0000 } },
344 { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } }, 309 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
345 { 6, 0x989c, 310 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
346 { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } }, 311 { 6, 0x989c, { 0x00660000, 0x00660000, 0x00660000 } },
347 { 6, 0x989c, 312 { 6, 0x989c, { 0x00db0000, 0x00db0000, 0x00db0000 } },
348 { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } }, 313 { 6, 0x989c, { 0x00f10000, 0x00f10000, 0x00f10000 } },
349 { 6, 0x989c, 314 { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } },
350 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 315 { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } },
351 { 6, 0x989c, 316 { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } },
352 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 317 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
353 { 6, 0x989c, 318 { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } },
354 { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } }, 319 { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
355 { 6, 0x989c, 320 { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
356 { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } }, 321 { 6, 0x989c, { 0x008b0000, 0x008b0000, 0x008b0000 } },
357 { 6, 0x989c, 322 { 6, 0x989c, { 0x00600000, 0x00600000, 0x00600000 } },
358 { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } }, 323 { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } },
359 { 6, 0x989c, 324 { 6, 0x989c, { 0x00840000, 0x00840000, 0x00840000 } },
360 { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } }, 325 { 6, 0x989c, { 0x00640000, 0x00640000, 0x00640000 } },
361 { 6, 0x989c, 326 { 6, 0x989c, { 0x00200000, 0x00200000, 0x00200000 } },
362 { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } }, 327 { 6, 0x989c, { 0x00240000, 0x00240000, 0x00240000 } },
363 { 6, 0x989c, 328 { 6, 0x989c, { 0x00250000, 0x00250000, 0x00250000 } },
364 { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } }, 329 { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } },
365 { 6, 0x989c, 330 { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } },
366 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 331 { 6, 0x989c, { 0x00510000, 0x00510000, 0x00510000 } },
367 { 6, 0x989c, 332 { 6, 0x989c, { 0x1c040000, 0x1c040000, 0x1c040000 } },
368 { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } }, 333 { 6, 0x989c, { 0x000a0000, 0x000a0000, 0x000a0000 } },
369 { 6, 0x989c, 334 { 6, 0x989c, { 0x00a10000, 0x00a10000, 0x00a10000 } },
370 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, 335 { 6, 0x989c, { 0x00400000, 0x00400000, 0x00400000 } },
371 { 6, 0x989c, 336 { 6, 0x989c, { 0x03090000, 0x03090000, 0x03090000 } },
372 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, 337 { 6, 0x989c, { 0x06000000, 0x06000000, 0x06000000 } },
373 { 6, 0x989c, 338 { 6, 0x989c, { 0x000000b0, 0x000000a8, 0x000000a8 } },
374 { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } }, 339 { 6, 0x989c, { 0x0000002e, 0x0000002e, 0x0000002e } },
375 { 6, 0x989c, 340 { 6, 0x989c, { 0x006c4a41, 0x006c4af1, 0x006c4a61 } },
376 { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } }, 341 { 6, 0x989c, { 0x0050892a, 0x0050892b, 0x0050892b } },
377 { 6, 0x989c, 342 { 6, 0x989c, { 0x00842400, 0x00842400, 0x00842400 } },
378 { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } }, 343 { 6, 0x989c, { 0x00c69200, 0x00c69200, 0x00c69200 } },
379 { 6, 0x989c, 344 { 6, 0x98d0, { 0x0002000c, 0x0002000c, 0x0002000c } },
380 { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } }, 345 { 7, 0x989c, { 0x00000094, 0x00000094, 0x00000094 } },
381 { 6, 0x989c, 346 { 7, 0x989c, { 0x00000091, 0x00000091, 0x00000091 } },
382 { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } }, 347 { 7, 0x989c, { 0x0000000a, 0x00000012, 0x00000012 } },
383 { 6, 0x989c, 348 { 7, 0x989c, { 0x00000080, 0x00000080, 0x00000080 } },
384 { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } }, 349 { 7, 0x989c, { 0x000000c1, 0x000000c1, 0x000000c1 } },
385 { 6, 0x989c, 350 { 7, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } },
386 { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } }, 351 { 7, 0x989c, { 0x000000f0, 0x000000f0, 0x000000f0 } },
387 { 6, 0x989c, 352 { 7, 0x989c, { 0x00000022, 0x00000022, 0x00000022 } },
388 { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } }, 353 { 7, 0x989c, { 0x00000092, 0x00000092, 0x00000092 } },
389 { 6, 0x989c, 354 { 7, 0x989c, { 0x000000d4, 0x000000d4, 0x000000d4 } },
390 { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } }, 355 { 7, 0x989c, { 0x000014cc, 0x000014cc, 0x000014cc } },
391 { 6, 0x989c, 356 { 7, 0x989c, { 0x0000048c, 0x0000048c, 0x0000048c } },
392 { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } }, 357 { 7, 0x98c4, { 0x00000003, 0x00000003, 0x00000003 } },
393 { 6, 0x989c,
394 { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
395 { 6, 0x989c,
396 { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
397 { 6, 0x989c,
398 { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
399 { 6, 0x989c,
400 { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
401 { 6, 0x989c,
402 { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
403 { 6, 0x989c,
404 { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
405 { 6, 0x989c,
406 { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
407 { 6, 0x989c,
408 { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
409 { 6, 0x989c,
410 { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
411 { 6, 0x989c,
412 { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
413 { 6, 0x989c,
414 { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
415 { 6, 0x989c,
416 { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
417 { 6, 0x989c,
418 { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
419 { 6, 0x98d0,
420 { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
421 { 7, 0x989c,
422 { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
423 { 7, 0x989c,
424 { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
425 { 7, 0x989c,
426 { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
427 { 7, 0x989c,
428 { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
429 { 7, 0x989c,
430 { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
431 { 7, 0x989c,
432 { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
433 { 7, 0x989c,
434 { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
435 { 7, 0x989c,
436 { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
437 { 7, 0x989c,
438 { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
439 { 7, 0x989c,
440 { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
441 { 7, 0x989c,
442 { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
443 { 7, 0x989c,
444 { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
445 { 7, 0x98c4,
446 { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
447}; 358};
448 359
449/* RFX112A (Derby 2) */ 360/* RFX112A (Derby 2) */
@@ -477,6 +388,7 @@ static const struct ath5k_ini_rfbuffer rfb_5112[] = {
477#define AR5K_RF5112A_XB5_LVL { 2, 3, 3 } 388#define AR5K_RF5112A_XB5_LVL { 2, 3, 3 }
478 389
479static const struct ath5k_rf_reg rf_regs_5112a[] = { 390static const struct ath5k_rf_reg rf_regs_5112a[] = {
391 {2, AR5K_RF_TURBO, AR5K_RF5112X_RF_TURBO},
480 {6, AR5K_RF_OB_2GHZ, AR5K_RF5112A_OB_2GHZ}, 392 {6, AR5K_RF_OB_2GHZ, AR5K_RF5112A_OB_2GHZ},
481 {6, AR5K_RF_DB_2GHZ, AR5K_RF5112A_DB_2GHZ}, 393 {6, AR5K_RF_DB_2GHZ, AR5K_RF5112A_DB_2GHZ},
482 {6, AR5K_RF_OB_5GHZ, AR5K_RF5112A_OB_5GHZ}, 394 {6, AR5K_RF_OB_5GHZ, AR5K_RF5112A_OB_5GHZ},
@@ -515,119 +427,63 @@ static const struct ath5k_rf_reg rf_regs_5112a[] = {
515 427
516/* Default mode specific settings */ 428/* Default mode specific settings */
517static const struct ath5k_ini_rfbuffer rfb_5112a[] = { 429static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
518 { 1, 0x98d4, 430 /* BANK / C.R. A/XR B G */
519 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ 431 { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
520 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, 432 { 2, 0x98d0, { 0x03060408, 0x03060408, 0x03060408 } },
521 { 2, 0x98d0, 433 { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
522 { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } }, 434 { 6, 0x989c, { 0x0f000000, 0x0f000000, 0x0f000000 } },
523 { 3, 0x98dc, 435 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
524 { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, 436 { 6, 0x989c, { 0x00800000, 0x00800000, 0x00800000 } },
525 { 6, 0x989c, 437 { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
526 { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } }, 438 { 6, 0x989c, { 0x00010000, 0x00010000, 0x00010000 } },
527 { 6, 0x989c, 439 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
528 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 440 { 6, 0x989c, { 0x00180000, 0x00180000, 0x00180000 } },
529 { 6, 0x989c, 441 { 6, 0x989c, { 0x00600000, 0x006e0000, 0x006e0000 } },
530 { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } }, 442 { 6, 0x989c, { 0x00c70000, 0x00c70000, 0x00c70000 } },
531 { 6, 0x989c, 443 { 6, 0x989c, { 0x004b0000, 0x004b0000, 0x004b0000 } },
532 { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, 444 { 6, 0x989c, { 0x04480000, 0x04480000, 0x04480000 } },
533 { 6, 0x989c, 445 { 6, 0x989c, { 0x004c0000, 0x004c0000, 0x004c0000 } },
534 { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } }, 446 { 6, 0x989c, { 0x00e40000, 0x00e40000, 0x00e40000 } },
535 { 6, 0x989c, 447 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
536 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 448 { 6, 0x989c, { 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
537 { 6, 0x989c, 449 { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
538 { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } }, 450 { 6, 0x989c, { 0x043f0000, 0x043f0000, 0x043f0000 } },
539 { 6, 0x989c, 451 { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } },
540 { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } }, 452 { 6, 0x989c, { 0x02190000, 0x02190000, 0x02190000 } },
541 { 6, 0x989c, 453 { 6, 0x989c, { 0x00240000, 0x00240000, 0x00240000 } },
542 { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } }, 454 { 6, 0x989c, { 0x00b40000, 0x00b40000, 0x00b40000 } },
543 { 6, 0x989c, 455 { 6, 0x989c, { 0x00990000, 0x00990000, 0x00990000 } },
544 { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } }, 456 { 6, 0x989c, { 0x00500000, 0x00500000, 0x00500000 } },
545 { 6, 0x989c, 457 { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
546 { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } }, 458 { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } },
547 { 6, 0x989c, 459 { 6, 0x989c, { 0xc0320000, 0xc0320000, 0xc0320000 } },
548 { 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000 } }, 460 { 6, 0x989c, { 0x01740000, 0x01740000, 0x01740000 } },
549 { 6, 0x989c, 461 { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } },
550 { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } }, 462 { 6, 0x989c, { 0x86280000, 0x86280000, 0x86280000 } },
551 { 6, 0x989c, 463 { 6, 0x989c, { 0x31840000, 0x31840000, 0x31840000 } },
552 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 464 { 6, 0x989c, { 0x00f20080, 0x00f20080, 0x00f20080 } },
553 { 6, 0x989c, 465 { 6, 0x989c, { 0x00270019, 0x00270019, 0x00270019 } },
554 { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } }, 466 { 6, 0x989c, { 0x00000003, 0x00000003, 0x00000003 } },
555 { 6, 0x989c, 467 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
556 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, 468 { 6, 0x989c, { 0x000000b2, 0x000000b2, 0x000000b2 } },
557 { 6, 0x989c, 469 { 6, 0x989c, { 0x00b02084, 0x00b02084, 0x00b02084 } },
558 { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } }, 470 { 6, 0x989c, { 0x004125a4, 0x004125a4, 0x004125a4 } },
559 { 6, 0x989c, 471 { 6, 0x989c, { 0x00119220, 0x00119220, 0x00119220 } },
560 { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } }, 472 { 6, 0x989c, { 0x001a4800, 0x001a4800, 0x001a4800 } },
561 { 6, 0x989c, 473 { 6, 0x98d8, { 0x000b0230, 0x000b0230, 0x000b0230 } },
562 { 0x02190000, 0x02190000, 0x02190000, 0x02190000, 0x02190000 } }, 474 { 7, 0x989c, { 0x00000094, 0x00000094, 0x00000094 } },
563 { 6, 0x989c, 475 { 7, 0x989c, { 0x00000091, 0x00000091, 0x00000091 } },
564 { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } }, 476 { 7, 0x989c, { 0x00000012, 0x00000012, 0x00000012 } },
565 { 6, 0x989c, 477 { 7, 0x989c, { 0x00000080, 0x00000080, 0x00000080 } },
566 { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } }, 478 { 7, 0x989c, { 0x000000d9, 0x000000d9, 0x000000d9 } },
567 { 6, 0x989c, 479 { 7, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } },
568 { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } }, 480 { 7, 0x989c, { 0x000000f0, 0x000000f0, 0x000000f0 } },
569 { 6, 0x989c, 481 { 7, 0x989c, { 0x000000a2, 0x000000a2, 0x000000a2 } },
570 { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } }, 482 { 7, 0x989c, { 0x00000052, 0x00000052, 0x00000052 } },
571 { 6, 0x989c, 483 { 7, 0x989c, { 0x000000d4, 0x000000d4, 0x000000d4 } },
572 { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, 484 { 7, 0x989c, { 0x000014cc, 0x000014cc, 0x000014cc } },
573 { 6, 0x989c, 485 { 7, 0x989c, { 0x0000048c, 0x0000048c, 0x0000048c } },
574 { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } }, 486 { 7, 0x98c4, { 0x00000003, 0x00000003, 0x00000003 } },
575 { 6, 0x989c,
576 { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
577 { 6, 0x989c,
578 { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
579 { 6, 0x989c,
580 { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
581 { 6, 0x989c,
582 { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
583 { 6, 0x989c,
584 { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
585 { 6, 0x989c,
586 { 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080 } },
587 { 6, 0x989c,
588 { 0x00270019, 0x00270019, 0x00270019, 0x00270019, 0x00270019 } },
589 { 6, 0x989c,
590 { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
591 { 6, 0x989c,
592 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
593 { 6, 0x989c,
594 { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
595 { 6, 0x989c,
596 { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
597 { 6, 0x989c,
598 { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
599 { 6, 0x989c,
600 { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
601 { 6, 0x989c,
602 { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
603 { 6, 0x98d8,
604 { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
605 { 7, 0x989c,
606 { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
607 { 7, 0x989c,
608 { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
609 { 7, 0x989c,
610 { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
611 { 7, 0x989c,
612 { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
613 { 7, 0x989c,
614 { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
615 { 7, 0x989c,
616 { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
617 { 7, 0x989c,
618 { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
619 { 7, 0x989c,
620 { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
621 { 7, 0x989c,
622 { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
623 { 7, 0x989c,
624 { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
625 { 7, 0x989c,
626 { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
627 { 7, 0x989c,
628 { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
629 { 7, 0x98c4,
630 { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
631}; 487};
632 488
633 489
@@ -636,11 +492,15 @@ static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
636* RF2413 (Griffin) * 492* RF2413 (Griffin) *
637\******************/ 493\******************/
638 494
495/* BANK 2 len pos col */
496#define AR5K_RF2413_RF_TURBO { 1, 1, 2 }
497
639/* BANK 6 len pos col */ 498/* BANK 6 len pos col */
640#define AR5K_RF2413_OB_2GHZ { 3, 168, 0 } 499#define AR5K_RF2413_OB_2GHZ { 3, 168, 0 }
641#define AR5K_RF2413_DB_2GHZ { 3, 165, 0 } 500#define AR5K_RF2413_DB_2GHZ { 3, 165, 0 }
642 501
643static const struct ath5k_rf_reg rf_regs_2413[] = { 502static const struct ath5k_rf_reg rf_regs_2413[] = {
503 {2, AR5K_RF_TURBO, AR5K_RF2413_RF_TURBO},
644 {6, AR5K_RF_OB_2GHZ, AR5K_RF2413_OB_2GHZ}, 504 {6, AR5K_RF_OB_2GHZ, AR5K_RF2413_OB_2GHZ},
645 {6, AR5K_RF_DB_2GHZ, AR5K_RF2413_DB_2GHZ}, 505 {6, AR5K_RF_DB_2GHZ, AR5K_RF2413_DB_2GHZ},
646}; 506};
@@ -649,73 +509,40 @@ static const struct ath5k_rf_reg rf_regs_2413[] = {
649 * XXX: a/aTurbo ??? 509 * XXX: a/aTurbo ???
650 */ 510 */
651static const struct ath5k_ini_rfbuffer rfb_2413[] = { 511static const struct ath5k_ini_rfbuffer rfb_2413[] = {
652 { 1, 0x98d4, 512 /* BANK / C.R. A/XR B G */
653 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ 513 { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
654 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, 514 { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
655 { 2, 0x98d0, 515 { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
656 { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } }, 516 { 6, 0x989c, { 0xf0000000, 0xf0000000, 0xf0000000 } },
657 { 3, 0x98dc, 517 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
658 { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, 518 { 6, 0x989c, { 0x03000000, 0x03000000, 0x03000000 } },
659 { 6, 0x989c, 519 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
660 { 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000 } }, 520 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
661 { 6, 0x989c, 521 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
662 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 522 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
663 { 6, 0x989c, 523 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
664 { 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000 } }, 524 { 6, 0x989c, { 0x40400000, 0x40400000, 0x40400000 } },
665 { 6, 0x989c, 525 { 6, 0x989c, { 0x65050000, 0x65050000, 0x65050000 } },
666 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 526 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
667 { 6, 0x989c, 527 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
668 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 528 { 6, 0x989c, { 0x00420000, 0x00420000, 0x00420000 } },
669 { 6, 0x989c, 529 { 6, 0x989c, { 0x00b50000, 0x00b50000, 0x00b50000 } },
670 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 530 { 6, 0x989c, { 0x00030000, 0x00030000, 0x00030000 } },
671 { 6, 0x989c, 531 { 6, 0x989c, { 0x00f70000, 0x00f70000, 0x00f70000 } },
672 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 532 { 6, 0x989c, { 0x009d0000, 0x009d0000, 0x009d0000 } },
673 { 6, 0x989c, 533 { 6, 0x989c, { 0x00220000, 0x00220000, 0x00220000 } },
674 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 534 { 6, 0x989c, { 0x04220000, 0x04220000, 0x04220000 } },
675 { 6, 0x989c, 535 { 6, 0x989c, { 0x00230018, 0x00230018, 0x00230018 } },
676 { 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000 } }, 536 { 6, 0x989c, { 0x00280000, 0x00280060, 0x00280060 } },
677 { 6, 0x989c, 537 { 6, 0x989c, { 0x005000c0, 0x005000c3, 0x005000c3 } },
678 { 0x65050000, 0x65050000, 0x65050000, 0x65050000, 0x65050000 } }, 538 { 6, 0x989c, { 0x0004007f, 0x0004007f, 0x0004007f } },
679 { 6, 0x989c, 539 { 6, 0x989c, { 0x00000458, 0x00000458, 0x00000458 } },
680 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 540 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
681 { 6, 0x989c, 541 { 6, 0x989c, { 0x0000c000, 0x0000c000, 0x0000c000 } },
682 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 542 { 6, 0x98d8, { 0x00400230, 0x00400230, 0x00400230 } },
683 { 6, 0x989c, 543 { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
684 { 0x00420000, 0x00420000, 0x00420000, 0x00420000, 0x00420000 } }, 544 { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
685 { 6, 0x989c, 545 { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
686 { 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000 } },
687 { 6, 0x989c,
688 { 0x00030000, 0x00030000, 0x00030000, 0x00030000, 0x00030000 } },
689 { 6, 0x989c,
690 { 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000 } },
691 { 6, 0x989c,
692 { 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000 } },
693 { 6, 0x989c,
694 { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
695 { 6, 0x989c,
696 { 0x04220000, 0x04220000, 0x04220000, 0x04220000, 0x04220000 } },
697 { 6, 0x989c,
698 { 0x00230018, 0x00230018, 0x00230018, 0x00230018, 0x00230018 } },
699 { 6, 0x989c,
700 { 0x00280000, 0x00280000, 0x00280060, 0x00280060, 0x00280060 } },
701 { 6, 0x989c,
702 { 0x005000c0, 0x005000c0, 0x005000c3, 0x005000c3, 0x005000c3 } },
703 { 6, 0x989c,
704 { 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f } },
705 { 6, 0x989c,
706 { 0x00000458, 0x00000458, 0x00000458, 0x00000458, 0x00000458 } },
707 { 6, 0x989c,
708 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
709 { 6, 0x989c,
710 { 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000 } },
711 { 6, 0x98d8,
712 { 0x00400230, 0x00400230, 0x00400230, 0x00400230, 0x00400230 } },
713 { 7, 0x989c,
714 { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
715 { 7, 0x989c,
716 { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
717 { 7, 0x98cc,
718 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
719}; 546};
720 547
721 548
@@ -724,88 +551,57 @@ static const struct ath5k_ini_rfbuffer rfb_2413[] = {
724* RF2315/RF2316 (Cobra SoC) * 551* RF2315/RF2316 (Cobra SoC) *
725\***************************/ 552\***************************/
726 553
554/* BANK 2 len pos col */
555#define AR5K_RF2316_RF_TURBO { 1, 1, 2 }
556
727/* BANK 6 len pos col */ 557/* BANK 6 len pos col */
728#define AR5K_RF2316_OB_2GHZ { 3, 178, 0 } 558#define AR5K_RF2316_OB_2GHZ { 3, 178, 0 }
729#define AR5K_RF2316_DB_2GHZ { 3, 175, 0 } 559#define AR5K_RF2316_DB_2GHZ { 3, 175, 0 }
730 560
731static const struct ath5k_rf_reg rf_regs_2316[] = { 561static const struct ath5k_rf_reg rf_regs_2316[] = {
562 {2, AR5K_RF_TURBO, AR5K_RF2316_RF_TURBO},
732 {6, AR5K_RF_OB_2GHZ, AR5K_RF2316_OB_2GHZ}, 563 {6, AR5K_RF_OB_2GHZ, AR5K_RF2316_OB_2GHZ},
733 {6, AR5K_RF_DB_2GHZ, AR5K_RF2316_DB_2GHZ}, 564 {6, AR5K_RF_DB_2GHZ, AR5K_RF2316_DB_2GHZ},
734}; 565};
735 566
736/* Default mode specific settings */ 567/* Default mode specific settings */
737static const struct ath5k_ini_rfbuffer rfb_2316[] = { 568static const struct ath5k_ini_rfbuffer rfb_2316[] = {
738 { 1, 0x98d4, 569 /* BANK / C.R. A/XR B G */
739 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ 570 { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
740 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, 571 { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
741 { 2, 0x98d0, 572 { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
742 { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } }, 573 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
743 { 3, 0x98dc, 574 { 6, 0x989c, { 0xc0000000, 0xc0000000, 0xc0000000 } },
744 { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, 575 { 6, 0x989c, { 0x0f000000, 0x0f000000, 0x0f000000 } },
745 { 6, 0x989c, 576 { 6, 0x989c, { 0x02000000, 0x02000000, 0x02000000 } },
746 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 577 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
747 { 6, 0x989c, 578 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
748 { 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 } }, 579 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
749 { 6, 0x989c, 580 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
750 { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } }, 581 { 6, 0x989c, { 0xf8000000, 0xf8000000, 0xf8000000 } },
751 { 6, 0x989c, 582 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
752 { 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000 } }, 583 { 6, 0x989c, { 0x95150000, 0x95150000, 0x95150000 } },
753 { 6, 0x989c, 584 { 6, 0x989c, { 0xc1000000, 0xc1000000, 0xc1000000 } },
754 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 585 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
755 { 6, 0x989c, 586 { 6, 0x989c, { 0x00080000, 0x00080000, 0x00080000 } },
756 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 587 { 6, 0x989c, { 0x00d50000, 0x00d50000, 0x00d50000 } },
757 { 6, 0x989c, 588 { 6, 0x989c, { 0x000e0000, 0x000e0000, 0x000e0000 } },
758 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 589 { 6, 0x989c, { 0x00dc0000, 0x00dc0000, 0x00dc0000 } },
759 { 6, 0x989c, 590 { 6, 0x989c, { 0x00770000, 0x00770000, 0x00770000 } },
760 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 591 { 6, 0x989c, { 0x008a0000, 0x008a0000, 0x008a0000 } },
761 { 6, 0x989c, 592 { 6, 0x989c, { 0x10880000, 0x10880000, 0x10880000 } },
762 { 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000 } }, 593 { 6, 0x989c, { 0x008c0060, 0x008c0060, 0x008c0060 } },
763 { 6, 0x989c, 594 { 6, 0x989c, { 0x00a00000, 0x00a00080, 0x00a00080 } },
764 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 595 { 6, 0x989c, { 0x00400000, 0x0040000d, 0x0040000d } },
765 { 6, 0x989c, 596 { 6, 0x989c, { 0x00110400, 0x00110400, 0x00110400 } },
766 { 0x95150000, 0x95150000, 0x95150000, 0x95150000, 0x95150000 } }, 597 { 6, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } },
767 { 6, 0x989c, 598 { 6, 0x989c, { 0x00000001, 0x00000001, 0x00000001 } },
768 { 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000 } }, 599 { 6, 0x989c, { 0x00000b00, 0x00000b00, 0x00000b00 } },
769 { 6, 0x989c, 600 { 6, 0x989c, { 0x00000be8, 0x00000be8, 0x00000be8 } },
770 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 601 { 6, 0x98c0, { 0x00010000, 0x00010000, 0x00010000 } },
771 { 6, 0x989c, 602 { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
772 { 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000 } }, 603 { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
773 { 6, 0x989c, 604 { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
774 { 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000 } },
775 { 6, 0x989c,
776 { 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000 } },
777 { 6, 0x989c,
778 { 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000 } },
779 { 6, 0x989c,
780 { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
781 { 6, 0x989c,
782 { 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000 } },
783 { 6, 0x989c,
784 { 0x10880000, 0x10880000, 0x10880000, 0x10880000, 0x10880000 } },
785 { 6, 0x989c,
786 { 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060 } },
787 { 6, 0x989c,
788 { 0x00a00000, 0x00a00000, 0x00a00080, 0x00a00080, 0x00a00080 } },
789 { 6, 0x989c,
790 { 0x00400000, 0x00400000, 0x0040000d, 0x0040000d, 0x0040000d } },
791 { 6, 0x989c,
792 { 0x00110400, 0x00110400, 0x00110400, 0x00110400, 0x00110400 } },
793 { 6, 0x989c,
794 { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
795 { 6, 0x989c,
796 { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
797 { 6, 0x989c,
798 { 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00 } },
799 { 6, 0x989c,
800 { 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8 } },
801 { 6, 0x98c0,
802 { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
803 { 7, 0x989c,
804 { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
805 { 7, 0x989c,
806 { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
807 { 7, 0x98cc,
808 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
809}; 605};
810 606
811 607
@@ -835,93 +631,50 @@ static const struct ath5k_rf_reg rf_regs_5413[] = {
835 631
836/* Default mode specific settings */ 632/* Default mode specific settings */
837static const struct ath5k_ini_rfbuffer rfb_5413[] = { 633static const struct ath5k_ini_rfbuffer rfb_5413[] = {
838 { 1, 0x98d4, 634 /* BANK / C.R. A/XR B G */
839 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ 635 { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
840 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, 636 { 2, 0x98d0, { 0x00000008, 0x00000008, 0x00000008 } },
841 { 2, 0x98d0, 637 { 3, 0x98dc, { 0x00a000c0, 0x00e000c0, 0x00e000c0 } },
842 { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } }, 638 { 6, 0x989c, { 0x33000000, 0x33000000, 0x33000000 } },
843 { 3, 0x98dc, 639 { 6, 0x989c, { 0x01000000, 0x01000000, 0x01000000 } },
844 { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } }, 640 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
845 { 6, 0x989c, 641 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
846 { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } }, 642 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
847 { 6, 0x989c, 643 { 6, 0x989c, { 0x1f000000, 0x1f000000, 0x1f000000 } },
848 { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } }, 644 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
849 { 6, 0x989c, 645 { 6, 0x989c, { 0x00b80000, 0x00b80000, 0x00b80000 } },
850 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 646 { 6, 0x989c, { 0x00b70000, 0x00b70000, 0x00b70000 } },
851 { 6, 0x989c, 647 { 6, 0x989c, { 0x00840000, 0x00840000, 0x00840000 } },
852 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 648 { 6, 0x989c, { 0x00980000, 0x00980000, 0x00980000 } },
853 { 6, 0x989c, 649 { 6, 0x989c, { 0x00c00000, 0x00c00000, 0x00c00000 } },
854 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 650 { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
855 { 6, 0x989c, 651 { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
856 { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } }, 652 { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
857 { 6, 0x989c, 653 { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
858 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 654 { 6, 0x989c, { 0x00d70000, 0x00d70000, 0x00d70000 } },
859 { 6, 0x989c, 655 { 6, 0x989c, { 0x00610000, 0x00610000, 0x00610000 } },
860 { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } }, 656 { 6, 0x989c, { 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
861 { 6, 0x989c, 657 { 6, 0x989c, { 0x00de0000, 0x00de0000, 0x00de0000 } },
862 { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } }, 658 { 6, 0x989c, { 0x007f0000, 0x007f0000, 0x007f0000 } },
863 { 6, 0x989c, 659 { 6, 0x989c, { 0x043d0000, 0x043d0000, 0x043d0000 } },
864 { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } }, 660 { 6, 0x989c, { 0x00770000, 0x00770000, 0x00770000 } },
865 { 6, 0x989c, 661 { 6, 0x989c, { 0x00440000, 0x00440000, 0x00440000 } },
866 { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } }, 662 { 6, 0x989c, { 0x00980000, 0x00980000, 0x00980000 } },
867 { 6, 0x989c, 663 { 6, 0x989c, { 0x00100080, 0x00100080, 0x00100080 } },
868 { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } }, 664 { 6, 0x989c, { 0x0005c034, 0x0005c034, 0x0005c034 } },
869 { 6, 0x989c, 665 { 6, 0x989c, { 0x003100f0, 0x003100f0, 0x003100f0 } },
870 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, 666 { 6, 0x989c, { 0x000c011f, 0x000c011f, 0x000c011f } },
871 { 6, 0x989c, 667 { 6, 0x989c, { 0x00510040, 0x00510040, 0x00510040 } },
872 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, 668 { 6, 0x989c, { 0x005000da, 0x005000da, 0x005000da } },
873 { 6, 0x989c, 669 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
874 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, 670 { 6, 0x989c, { 0x00004044, 0x00004044, 0x00004044 } },
875 { 6, 0x989c, 671 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
876 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, 672 { 6, 0x989c, { 0x000060c0, 0x000060c0, 0x000060c0 } },
877 { 6, 0x989c, 673 { 6, 0x989c, { 0x00002c00, 0x00003600, 0x00003600 } },
878 { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } }, 674 { 6, 0x98c8, { 0x00000403, 0x00040403, 0x00040403 } },
879 { 6, 0x989c, 675 { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
880 { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } }, 676 { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
881 { 6, 0x989c, 677 { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
882 { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
883 { 6, 0x989c,
884 { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
885 { 6, 0x989c,
886 { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
887 { 6, 0x989c,
888 { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
889 { 6, 0x989c,
890 { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
891 { 6, 0x989c,
892 { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
893 { 6, 0x989c,
894 { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
895 { 6, 0x989c,
896 { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
897 { 6, 0x989c,
898 { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
899 { 6, 0x989c,
900 { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
901 { 6, 0x989c,
902 { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
903 { 6, 0x989c,
904 { 0x00510040, 0x00510040, 0x00510040, 0x00510040, 0x00510040 } },
905 { 6, 0x989c,
906 { 0x005000da, 0x005000da, 0x005000da, 0x005000da, 0x005000da } },
907 { 6, 0x989c,
908 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
909 { 6, 0x989c,
910 { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
911 { 6, 0x989c,
912 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
913 { 6, 0x989c,
914 { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
915 { 6, 0x989c,
916 { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00002c00 } },
917 { 6, 0x98c8,
918 { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
919 { 7, 0x989c,
920 { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
921 { 7, 0x989c,
922 { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
923 { 7, 0x98cc,
924 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
925}; 678};
926 679
927 680
@@ -931,92 +684,59 @@ static const struct ath5k_ini_rfbuffer rfb_5413[] = {
931* AR2317 (Spider SoC) * 684* AR2317 (Spider SoC) *
932\***************************/ 685\***************************/
933 686
687/* BANK 2 len pos col */
688#define AR5K_RF2425_RF_TURBO { 1, 1, 2 }
689
934/* BANK 6 len pos col */ 690/* BANK 6 len pos col */
935#define AR5K_RF2425_OB_2GHZ { 3, 193, 0 } 691#define AR5K_RF2425_OB_2GHZ { 3, 193, 0 }
936#define AR5K_RF2425_DB_2GHZ { 3, 190, 0 } 692#define AR5K_RF2425_DB_2GHZ { 3, 190, 0 }
937 693
938static const struct ath5k_rf_reg rf_regs_2425[] = { 694static const struct ath5k_rf_reg rf_regs_2425[] = {
695 {2, AR5K_RF_TURBO, AR5K_RF2425_RF_TURBO},
939 {6, AR5K_RF_OB_2GHZ, AR5K_RF2425_OB_2GHZ}, 696 {6, AR5K_RF_OB_2GHZ, AR5K_RF2425_OB_2GHZ},
940 {6, AR5K_RF_DB_2GHZ, AR5K_RF2425_DB_2GHZ}, 697 {6, AR5K_RF_DB_2GHZ, AR5K_RF2425_DB_2GHZ},
941}; 698};
942 699
943/* Default mode specific settings 700/* Default mode specific settings
944 * XXX: a/aTurbo ?
945 */ 701 */
946static const struct ath5k_ini_rfbuffer rfb_2425[] = { 702static const struct ath5k_ini_rfbuffer rfb_2425[] = {
947 { 1, 0x98d4, 703 /* BANK / C.R. A/XR B G */
948 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ 704 { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
949 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, 705 { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
950 { 2, 0x98d0, 706 { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
951 { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } }, 707 { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } },
952 { 3, 0x98dc, 708 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
953 { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, 709 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
954 { 6, 0x989c, 710 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
955 { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } }, 711 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
956 { 6, 0x989c, 712 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
957 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 713 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
958 { 6, 0x989c, 714 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
959 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 715 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
960 { 6, 0x989c, 716 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
961 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 717 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
962 { 6, 0x989c, 718 { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
963 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 719 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
964 { 6, 0x989c, 720 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
965 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 721 { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } },
966 { 6, 0x989c, 722 { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } },
967 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 723 { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } },
968 { 6, 0x989c, 724 { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } },
969 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 725 { 6, 0x989c, { 0x00e70000, 0x00e70000, 0x00e70000 } },
970 { 6, 0x989c, 726 { 6, 0x989c, { 0x00140000, 0x00140000, 0x00140000 } },
971 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 727 { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } },
972 { 6, 0x989c, 728 { 6, 0x989c, { 0x0007001a, 0x0007001a, 0x0007001a } },
973 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 729 { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } },
974 { 6, 0x989c, 730 { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } },
975 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 731 { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } },
976 { 6, 0x989c, 732 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
977 { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, 733 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
978 { 6, 0x989c, 734 { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } },
979 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 735 { 6, 0x989c, { 0x00001688, 0x00001688, 0x00001688 } },
980 { 6, 0x989c, 736 { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } },
981 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 737 { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
982 { 6, 0x989c, 738 { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
983 { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } }, 739 { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
984 { 6, 0x989c,
985 { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
986 { 6, 0x989c,
987 { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
988 { 6, 0x989c,
989 { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
990 { 6, 0x989c,
991 { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
992 { 6, 0x989c,
993 { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
994 { 6, 0x989c,
995 { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
996 { 6, 0x989c,
997 { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
998 { 6, 0x989c,
999 { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
1000 { 6, 0x989c,
1001 { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
1002 { 6, 0x989c,
1003 { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
1004 { 6, 0x989c,
1005 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1006 { 6, 0x989c,
1007 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1008 { 6, 0x989c,
1009 { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
1010 { 6, 0x989c,
1011 { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
1012 { 6, 0x98c4,
1013 { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
1014 { 7, 0x989c,
1015 { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
1016 { 7, 0x989c,
1017 { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
1018 { 7, 0x98cc,
1019 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
1020}; 740};
1021 741
1022/* 742/*
@@ -1024,158 +744,85 @@ static const struct ath5k_ini_rfbuffer rfb_2425[] = {
1024 * bank modification and get rid of this 744 * bank modification and get rid of this
1025 */ 745 */
1026static const struct ath5k_ini_rfbuffer rfb_2317[] = { 746static const struct ath5k_ini_rfbuffer rfb_2317[] = {
1027 { 1, 0x98d4, 747 /* BANK / C.R. A/XR B G */
1028 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ 748 { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
1029 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, 749 { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
1030 { 2, 0x98d0, 750 { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
1031 { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } }, 751 { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } },
1032 { 3, 0x98dc, 752 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1033 { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, 753 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1034 { 6, 0x989c, 754 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1035 { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } }, 755 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1036 { 6, 0x989c, 756 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1037 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 757 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1038 { 6, 0x989c, 758 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1039 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 759 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1040 { 6, 0x989c, 760 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1041 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 761 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1042 { 6, 0x989c, 762 { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
1043 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 763 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1044 { 6, 0x989c, 764 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1045 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 765 { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } },
1046 { 6, 0x989c, 766 { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } },
1047 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 767 { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } },
1048 { 6, 0x989c, 768 { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } },
1049 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 769 { 6, 0x989c, { 0x00e70000, 0x00e70000, 0x00e70000 } },
1050 { 6, 0x989c, 770 { 6, 0x989c, { 0x00140100, 0x00140100, 0x00140100 } },
1051 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 771 { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } },
1052 { 6, 0x989c, 772 { 6, 0x989c, { 0x0007001a, 0x0007001a, 0x0007001a } },
1053 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 773 { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } },
1054 { 6, 0x989c, 774 { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } },
1055 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 775 { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } },
1056 { 6, 0x989c, 776 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1057 { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, 777 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1058 { 6, 0x989c, 778 { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } },
1059 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 779 { 6, 0x989c, { 0x00009688, 0x00009688, 0x00009688 } },
1060 { 6, 0x989c, 780 { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } },
1061 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 781 { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
1062 { 6, 0x989c, 782 { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
1063 { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } }, 783 { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
1064 { 6, 0x989c,
1065 { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
1066 { 6, 0x989c,
1067 { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
1068 { 6, 0x989c,
1069 { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
1070 { 6, 0x989c,
1071 { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
1072 { 6, 0x989c,
1073 { 0x00140100, 0x00140100, 0x00140100, 0x00140100, 0x00140100 } },
1074 { 6, 0x989c,
1075 { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
1076 { 6, 0x989c,
1077 { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
1078 { 6, 0x989c,
1079 { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
1080 { 6, 0x989c,
1081 { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
1082 { 6, 0x989c,
1083 { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
1084 { 6, 0x989c,
1085 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1086 { 6, 0x989c,
1087 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1088 { 6, 0x989c,
1089 { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
1090 { 6, 0x989c,
1091 { 0x00009688, 0x00009688, 0x00009688, 0x00009688, 0x00009688 } },
1092 { 6, 0x98c4,
1093 { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
1094 { 7, 0x989c,
1095 { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
1096 { 7, 0x989c,
1097 { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
1098 { 7, 0x98cc,
1099 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
1100}; 784};
1101 785
1102/* 786/*
1103 * TODO: Handle the few differences with swan during 787 * TODO: Handle the few differences with swan during
1104 * bank modification and get rid of this 788 * bank modification and get rid of this
1105 * XXX: a/aTurbo ?
1106 */ 789 */
1107static const struct ath5k_ini_rfbuffer rfb_2417[] = { 790static const struct ath5k_ini_rfbuffer rfb_2417[] = {
1108 { 1, 0x98d4, 791 /* BANK / C.R. A/XR B G */
1109 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */ 792 { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } },
1110 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } }, 793 { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } },
1111 { 2, 0x98d0, 794 { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } },
1112 { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } }, 795 { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } },
1113 { 3, 0x98dc, 796 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1114 { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } }, 797 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1115 { 6, 0x989c, 798 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1116 { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } }, 799 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1117 { 6, 0x989c, 800 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1118 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 801 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1119 { 6, 0x989c, 802 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1120 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 803 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1121 { 6, 0x989c, 804 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1122 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 805 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1123 { 6, 0x989c, 806 { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } },
1124 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 807 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1125 { 6, 0x989c, 808 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1126 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 809 { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } },
1127 { 6, 0x989c, 810 { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } },
1128 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 811 { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } },
1129 { 6, 0x989c, 812 { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } },
1130 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 813 { 6, 0x989c, { 0x00e70000, 0x80e70000, 0x80e70000 } },
1131 { 6, 0x989c, 814 { 6, 0x989c, { 0x00140000, 0x00140000, 0x00140000 } },
1132 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 815 { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } },
1133 { 6, 0x989c, 816 { 6, 0x989c, { 0x0007001a, 0x0207001a, 0x0207001a } },
1134 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 817 { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } },
1135 { 6, 0x989c, 818 { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } },
1136 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 819 { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } },
1137 { 6, 0x989c, 820 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1138 { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } }, 821 { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } },
1139 { 6, 0x989c, 822 { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } },
1140 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 823 { 6, 0x989c, { 0x00001688, 0x00001688, 0x00001688 } },
1141 { 6, 0x989c, 824 { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } },
1142 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }, 825 { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } },
1143 { 6, 0x989c, 826 { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } },
1144 { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } }, 827 { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } },
1145 { 6, 0x989c,
1146 { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
1147 { 6, 0x989c,
1148 { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
1149 { 6, 0x989c,
1150 { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
1151 { 6, 0x989c,
1152 { 0x00e70000, 0x00e70000, 0x80e70000, 0x80e70000, 0x00e70000 } },
1153 { 6, 0x989c,
1154 { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
1155 { 6, 0x989c,
1156 { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
1157 { 6, 0x989c,
1158 { 0x0007001a, 0x0007001a, 0x0207001a, 0x0207001a, 0x0007001a } },
1159 { 6, 0x989c,
1160 { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
1161 { 6, 0x989c,
1162 { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
1163 { 6, 0x989c,
1164 { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
1165 { 6, 0x989c,
1166 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1167 { 6, 0x989c,
1168 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1169 { 6, 0x989c,
1170 { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
1171 { 6, 0x989c,
1172 { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
1173 { 6, 0x98c4,
1174 { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
1175 { 7, 0x989c,
1176 { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
1177 { 7, 0x989c,
1178 { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
1179 { 7, 0x98cc,
1180 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
1181}; 828};
diff --git a/drivers/net/wireless/ath/ath5k/sysfs.c b/drivers/net/wireless/ath/ath5k/sysfs.c
index 90757de7bf59..a073cdce1f15 100644
--- a/drivers/net/wireless/ath/ath5k/sysfs.c
+++ b/drivers/net/wireless/ath/ath5k/sysfs.c
@@ -10,7 +10,8 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \
10 struct device_attribute *attr, \ 10 struct device_attribute *attr, \
11 char *buf) \ 11 char *buf) \
12{ \ 12{ \
13 struct ath5k_softc *sc = dev_get_drvdata(dev); \ 13 struct ieee80211_hw *hw = dev_get_drvdata(dev); \
14 struct ath5k_softc *sc = hw->priv; \
14 return snprintf(buf, PAGE_SIZE, "%d\n", get); \ 15 return snprintf(buf, PAGE_SIZE, "%d\n", get); \
15} \ 16} \
16 \ 17 \
@@ -18,7 +19,8 @@ static ssize_t ath5k_attr_store_##name(struct device *dev, \
18 struct device_attribute *attr, \ 19 struct device_attribute *attr, \
19 const char *buf, size_t count) \ 20 const char *buf, size_t count) \
20{ \ 21{ \
21 struct ath5k_softc *sc = dev_get_drvdata(dev); \ 22 struct ieee80211_hw *hw = dev_get_drvdata(dev); \
23 struct ath5k_softc *sc = hw->priv; \
22 int val; \ 24 int val; \
23 \ 25 \
24 val = (int)simple_strtoul(buf, NULL, 10); \ 26 val = (int)simple_strtoul(buf, NULL, 10); \
@@ -33,7 +35,8 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \
33 struct device_attribute *attr, \ 35 struct device_attribute *attr, \
34 char *buf) \ 36 char *buf) \
35{ \ 37{ \
36 struct ath5k_softc *sc = dev_get_drvdata(dev); \ 38 struct ieee80211_hw *hw = dev_get_drvdata(dev); \
39 struct ath5k_softc *sc = hw->priv; \
37 return snprintf(buf, PAGE_SIZE, "%d\n", get); \ 40 return snprintf(buf, PAGE_SIZE, "%d\n", get); \
38} \ 41} \
39static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL) 42static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL)
@@ -95,7 +98,7 @@ static struct attribute_group ath5k_attribute_group_ani = {
95int 98int
96ath5k_sysfs_register(struct ath5k_softc *sc) 99ath5k_sysfs_register(struct ath5k_softc *sc)
97{ 100{
98 struct device *dev = &sc->pdev->dev; 101 struct device *dev = sc->dev;
99 int err; 102 int err;
100 103
101 err = sysfs_create_group(&dev->kobj, &ath5k_attribute_group_ani); 104 err = sysfs_create_group(&dev->kobj, &ath5k_attribute_group_ani);
@@ -110,7 +113,7 @@ ath5k_sysfs_register(struct ath5k_softc *sc)
110void 113void
111ath5k_sysfs_unregister(struct ath5k_softc *sc) 114ath5k_sysfs_unregister(struct ath5k_softc *sc)
112{ 115{
113 struct device *dev = &sc->pdev->dev; 116 struct device *dev = sc->dev;
114 117
115 sysfs_remove_group(&dev->kobj, &ath5k_attribute_group_ani); 118 sysfs_remove_group(&dev->kobj, &ath5k_attribute_group_ani);
116} 119}
diff --git a/drivers/net/wireless/ath/ath5k/trace.h b/drivers/net/wireless/ath/ath5k/trace.h
new file mode 100644
index 000000000000..2de68adb6240
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/trace.h
@@ -0,0 +1,107 @@
1#if !defined(__TRACE_ATH5K_H) || defined(TRACE_HEADER_MULTI_READ)
2#define __TRACE_ATH5K_H
3
4#include <linux/tracepoint.h>
5#include "base.h"
6
7#ifndef CONFIG_ATH5K_TRACER
8#undef TRACE_EVENT
9#define TRACE_EVENT(name, proto, ...) \
10static inline void trace_ ## name(proto) {}
11#endif
12
13struct sk_buff;
14
15#define PRIV_ENTRY __field(struct ath5k_softc *, priv)
16#define PRIV_ASSIGN __entry->priv = priv
17
18#undef TRACE_SYSTEM
19#define TRACE_SYSTEM ath5k
20
21TRACE_EVENT(ath5k_rx,
22 TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb),
23 TP_ARGS(priv, skb),
24 TP_STRUCT__entry(
25 PRIV_ENTRY
26 __field(unsigned long, skbaddr)
27 __dynamic_array(u8, frame, skb->len)
28 ),
29 TP_fast_assign(
30 PRIV_ASSIGN;
31 __entry->skbaddr = (unsigned long) skb;
32 memcpy(__get_dynamic_array(frame), skb->data, skb->len);
33 ),
34 TP_printk(
35 "[%p] RX skb=%lx", __entry->priv, __entry->skbaddr
36 )
37);
38
39TRACE_EVENT(ath5k_tx,
40 TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb,
41 struct ath5k_txq *q),
42
43 TP_ARGS(priv, skb, q),
44
45 TP_STRUCT__entry(
46 PRIV_ENTRY
47 __field(unsigned long, skbaddr)
48 __field(u8, qnum)
49 __dynamic_array(u8, frame, skb->len)
50 ),
51
52 TP_fast_assign(
53 PRIV_ASSIGN;
54 __entry->skbaddr = (unsigned long) skb;
55 __entry->qnum = (u8) q->qnum;
56 memcpy(__get_dynamic_array(frame), skb->data, skb->len);
57 ),
58
59 TP_printk(
60 "[%p] TX skb=%lx q=%d", __entry->priv, __entry->skbaddr,
61 __entry->qnum
62 )
63);
64
65TRACE_EVENT(ath5k_tx_complete,
66 TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb,
67 struct ath5k_txq *q, struct ath5k_tx_status *ts),
68
69 TP_ARGS(priv, skb, q, ts),
70
71 TP_STRUCT__entry(
72 PRIV_ENTRY
73 __field(unsigned long, skbaddr)
74 __field(u8, qnum)
75 __field(u8, ts_status)
76 __field(s8, ts_rssi)
77 __field(u8, ts_antenna)
78 ),
79
80 TP_fast_assign(
81 PRIV_ASSIGN;
82 __entry->skbaddr = (unsigned long) skb;
83 __entry->qnum = (u8) q->qnum;
84 __entry->ts_status = ts->ts_status;
85 __entry->ts_rssi = ts->ts_rssi;
86 __entry->ts_antenna = ts->ts_antenna;
87 ),
88
89 TP_printk(
90 "[%p] TX end skb=%lx q=%d stat=%x rssi=%d ant=%x",
91 __entry->priv, __entry->skbaddr, __entry->qnum,
92 __entry->ts_status, __entry->ts_rssi, __entry->ts_antenna
93 )
94);
95
96#endif /* __TRACE_ATH5K_H */
97
98#ifdef CONFIG_ATH5K_TRACER
99
100#undef TRACE_INCLUDE_PATH
101#define TRACE_INCLUDE_PATH ../../drivers/net/wireless/ath/ath5k
102#undef TRACE_INCLUDE_FILE
103#define TRACE_INCLUDE_FILE trace
104
105#include <trace/define_trace.h>
106
107#endif