diff options
Diffstat (limited to 'drivers/net/wireless/ath')
95 files changed, 6957 insertions, 10657 deletions
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index 92c216263ee..d1b23067619 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig | |||
@@ -24,7 +24,6 @@ config ATH_DEBUG | |||
24 | 24 | ||
25 | source "drivers/net/wireless/ath/ath5k/Kconfig" | 25 | source "drivers/net/wireless/ath/ath5k/Kconfig" |
26 | source "drivers/net/wireless/ath/ath9k/Kconfig" | 26 | source "drivers/net/wireless/ath/ath9k/Kconfig" |
27 | source "drivers/net/wireless/ath/ar9170/Kconfig" | ||
28 | source "drivers/net/wireless/ath/carl9170/Kconfig" | 27 | source "drivers/net/wireless/ath/carl9170/Kconfig" |
29 | 28 | ||
30 | endif | 29 | endif |
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile index 6d711ec97ec..0e8f528c81c 100644 --- a/drivers/net/wireless/ath/Makefile +++ b/drivers/net/wireless/ath/Makefile | |||
@@ -1,6 +1,5 @@ | |||
1 | obj-$(CONFIG_ATH5K) += ath5k/ | 1 | obj-$(CONFIG_ATH5K) += ath5k/ |
2 | obj-$(CONFIG_ATH9K_HW) += ath9k/ | 2 | obj-$(CONFIG_ATH9K_HW) += ath9k/ |
3 | obj-$(CONFIG_AR9170_USB) += ar9170/ | ||
4 | obj-$(CONFIG_CARL9170) += carl9170/ | 3 | obj-$(CONFIG_CARL9170) += carl9170/ |
5 | 4 | ||
6 | obj-$(CONFIG_ATH_COMMON) += ath.o | 5 | obj-$(CONFIG_ATH_COMMON) += ath.o |
diff --git a/drivers/net/wireless/ath/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig deleted file mode 100644 index 7b9672b0d09..00000000000 --- a/drivers/net/wireless/ath/ar9170/Kconfig +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | config AR9170_USB | ||
2 | tristate "Atheros AR9170 802.11n USB support (OBSOLETE)" | ||
3 | depends on USB && MAC80211 | ||
4 | select FW_LOADER | ||
5 | help | ||
6 | This driver is going to get replaced by carl9170. | ||
7 | |||
8 | This is a driver for the Atheros "otus" 802.11n USB devices. | ||
9 | |||
10 | These devices require additional firmware (2 files). | ||
11 | For now, these files can be downloaded from here: | ||
12 | |||
13 | http://wireless.kernel.org/en/users/Drivers/ar9170 | ||
14 | |||
15 | If you choose to build a module, it'll be called ar9170usb. | ||
16 | |||
17 | config AR9170_LEDS | ||
18 | bool | ||
19 | depends on AR9170_USB && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = AR9170_USB) | ||
20 | default y | ||
diff --git a/drivers/net/wireless/ath/ar9170/Makefile b/drivers/net/wireless/ath/ar9170/Makefile deleted file mode 100644 index 8d91c7ee321..00000000000 --- a/drivers/net/wireless/ath/ar9170/Makefile +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | ar9170usb-objs := usb.o main.o cmd.o mac.o phy.o led.o | ||
2 | |||
3 | obj-$(CONFIG_AR9170_USB) += ar9170usb.o | ||
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h deleted file mode 100644 index 371e4ce4952..00000000000 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ /dev/null | |||
@@ -1,258 +0,0 @@ | |||
1 | /* | ||
2 | * Atheros AR9170 driver | ||
3 | * | ||
4 | * Driver specific definitions | ||
5 | * | ||
6 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; see the file COPYING. If not, see | ||
20 | * http://www.gnu.org/licenses/. | ||
21 | * | ||
22 | * This file incorporates work covered by the following copyright and | ||
23 | * permission notice: | ||
24 | * Copyright (c) 2007-2008 Atheros Communications, Inc. | ||
25 | * | ||
26 | * Permission to use, copy, modify, and/or distribute this software for any | ||
27 | * purpose with or without fee is hereby granted, provided that the above | ||
28 | * copyright notice and this permission notice appear in all copies. | ||
29 | * | ||
30 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
31 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
32 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
33 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
34 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
35 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
36 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
37 | */ | ||
38 | #ifndef __AR9170_H | ||
39 | #define __AR9170_H | ||
40 | |||
41 | #include <linux/completion.h> | ||
42 | #include <linux/spinlock.h> | ||
43 | #include <net/cfg80211.h> | ||
44 | #include <net/mac80211.h> | ||
45 | #ifdef CONFIG_AR9170_LEDS | ||
46 | #include <linux/leds.h> | ||
47 | #endif /* CONFIG_AR9170_LEDS */ | ||
48 | #include "eeprom.h" | ||
49 | #include "hw.h" | ||
50 | |||
51 | #include "../regd.h" | ||
52 | |||
53 | #define PAYLOAD_MAX (AR9170_MAX_CMD_LEN/4 - 1) | ||
54 | |||
55 | enum ar9170_bw { | ||
56 | AR9170_BW_20, | ||
57 | AR9170_BW_40_BELOW, | ||
58 | AR9170_BW_40_ABOVE, | ||
59 | |||
60 | __AR9170_NUM_BW, | ||
61 | }; | ||
62 | |||
63 | static inline enum ar9170_bw nl80211_to_ar9170(enum nl80211_channel_type type) | ||
64 | { | ||
65 | switch (type) { | ||
66 | case NL80211_CHAN_NO_HT: | ||
67 | case NL80211_CHAN_HT20: | ||
68 | return AR9170_BW_20; | ||
69 | case NL80211_CHAN_HT40MINUS: | ||
70 | return AR9170_BW_40_BELOW; | ||
71 | case NL80211_CHAN_HT40PLUS: | ||
72 | return AR9170_BW_40_ABOVE; | ||
73 | default: | ||
74 | BUG(); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | enum ar9170_rf_init_mode { | ||
79 | AR9170_RFI_NONE, | ||
80 | AR9170_RFI_WARM, | ||
81 | AR9170_RFI_COLD, | ||
82 | }; | ||
83 | |||
84 | #define AR9170_MAX_RX_BUFFER_SIZE 8192 | ||
85 | |||
86 | #ifdef CONFIG_AR9170_LEDS | ||
87 | struct ar9170; | ||
88 | |||
89 | struct ar9170_led { | ||
90 | struct ar9170 *ar; | ||
91 | struct led_classdev l; | ||
92 | char name[32]; | ||
93 | unsigned int toggled; | ||
94 | bool last_state; | ||
95 | bool registered; | ||
96 | }; | ||
97 | |||
98 | #endif /* CONFIG_AR9170_LEDS */ | ||
99 | |||
100 | enum ar9170_device_state { | ||
101 | AR9170_UNKNOWN_STATE, | ||
102 | AR9170_STOPPED, | ||
103 | AR9170_IDLE, | ||
104 | AR9170_STARTED, | ||
105 | }; | ||
106 | |||
107 | struct ar9170_rxstream_mpdu_merge { | ||
108 | struct ar9170_rx_head plcp; | ||
109 | bool has_plcp; | ||
110 | }; | ||
111 | |||
112 | struct ar9170_tx_queue_stats { | ||
113 | unsigned int len; | ||
114 | unsigned int limit; | ||
115 | unsigned int count; | ||
116 | }; | ||
117 | |||
118 | #define AR9170_QUEUE_TIMEOUT 64 | ||
119 | #define AR9170_TX_TIMEOUT 8 | ||
120 | #define AR9170_JANITOR_DELAY 128 | ||
121 | #define AR9170_TX_INVALID_RATE 0xffffffff | ||
122 | |||
123 | #define AR9170_NUM_TX_LIMIT_HARD AR9170_TXQ_DEPTH | ||
124 | #define AR9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH - 10) | ||
125 | |||
126 | struct ar9170 { | ||
127 | struct ieee80211_hw *hw; | ||
128 | struct ath_common common; | ||
129 | struct mutex mutex; | ||
130 | enum ar9170_device_state state; | ||
131 | bool registered; | ||
132 | unsigned long bad_hw_nagger; | ||
133 | |||
134 | int (*open)(struct ar9170 *); | ||
135 | void (*stop)(struct ar9170 *); | ||
136 | int (*tx)(struct ar9170 *, struct sk_buff *); | ||
137 | int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 , | ||
138 | void *, u32 , void *); | ||
139 | void (*callback_cmd)(struct ar9170 *, u32 , void *); | ||
140 | int (*flush)(struct ar9170 *); | ||
141 | |||
142 | /* interface mode settings */ | ||
143 | struct ieee80211_vif *vif; | ||
144 | |||
145 | /* beaconing */ | ||
146 | struct sk_buff *beacon; | ||
147 | struct work_struct beacon_work; | ||
148 | bool enable_beacon; | ||
149 | |||
150 | /* cryptographic engine */ | ||
151 | u64 usedkeys; | ||
152 | bool rx_software_decryption; | ||
153 | bool disable_offload; | ||
154 | |||
155 | /* filter settings */ | ||
156 | u64 cur_mc_hash; | ||
157 | u32 cur_filter; | ||
158 | unsigned int filter_state; | ||
159 | bool sniffer_enabled; | ||
160 | |||
161 | /* PHY */ | ||
162 | struct ieee80211_channel *channel; | ||
163 | int noise[4]; | ||
164 | |||
165 | /* power calibration data */ | ||
166 | u8 power_5G_leg[4]; | ||
167 | u8 power_2G_cck[4]; | ||
168 | u8 power_2G_ofdm[4]; | ||
169 | u8 power_5G_ht20[8]; | ||
170 | u8 power_5G_ht40[8]; | ||
171 | u8 power_2G_ht20[8]; | ||
172 | u8 power_2G_ht40[8]; | ||
173 | |||
174 | u8 phy_heavy_clip; | ||
175 | |||
176 | #ifdef CONFIG_AR9170_LEDS | ||
177 | struct delayed_work led_work; | ||
178 | struct ar9170_led leds[AR9170_NUM_LEDS]; | ||
179 | #endif /* CONFIG_AR9170_LEDS */ | ||
180 | |||
181 | /* qos queue settings */ | ||
182 | spinlock_t tx_stats_lock; | ||
183 | struct ar9170_tx_queue_stats tx_stats[5]; | ||
184 | struct ieee80211_tx_queue_params edcf[5]; | ||
185 | |||
186 | spinlock_t cmdlock; | ||
187 | __le32 cmdbuf[PAYLOAD_MAX + 1]; | ||
188 | |||
189 | /* MAC statistics */ | ||
190 | struct ieee80211_low_level_stats stats; | ||
191 | |||
192 | /* EEPROM */ | ||
193 | struct ar9170_eeprom eeprom; | ||
194 | |||
195 | /* tx queues - as seen by hw - */ | ||
196 | struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; | ||
197 | struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; | ||
198 | struct delayed_work tx_janitor; | ||
199 | |||
200 | /* rxstream mpdu merge */ | ||
201 | struct ar9170_rxstream_mpdu_merge rx_mpdu; | ||
202 | struct sk_buff *rx_failover; | ||
203 | int rx_failover_missing; | ||
204 | |||
205 | /* (cached) HW A-MPDU settings */ | ||
206 | u8 global_ampdu_density; | ||
207 | u8 global_ampdu_factor; | ||
208 | }; | ||
209 | |||
210 | struct ar9170_tx_info { | ||
211 | unsigned long timeout; | ||
212 | }; | ||
213 | |||
214 | #define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) | ||
215 | #define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE) | ||
216 | |||
217 | /* exported interface */ | ||
218 | void *ar9170_alloc(size_t priv_size); | ||
219 | int ar9170_register(struct ar9170 *ar, struct device *pdev); | ||
220 | void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb); | ||
221 | void ar9170_unregister(struct ar9170 *ar); | ||
222 | void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb); | ||
223 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); | ||
224 | int ar9170_nag_limiter(struct ar9170 *ar); | ||
225 | |||
226 | /* MAC */ | ||
227 | void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
228 | int ar9170_init_mac(struct ar9170 *ar); | ||
229 | int ar9170_set_qos(struct ar9170 *ar); | ||
230 | int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast); | ||
231 | int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter); | ||
232 | int ar9170_set_operating_mode(struct ar9170 *ar); | ||
233 | int ar9170_set_beacon_timers(struct ar9170 *ar); | ||
234 | int ar9170_set_dyn_sifs_ack(struct ar9170 *ar); | ||
235 | int ar9170_set_slot_time(struct ar9170 *ar); | ||
236 | int ar9170_set_basic_rates(struct ar9170 *ar); | ||
237 | int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry); | ||
238 | int ar9170_update_beacon(struct ar9170 *ar); | ||
239 | void ar9170_new_beacon(struct work_struct *work); | ||
240 | int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype, | ||
241 | u8 keyidx, u8 *keydata, int keylen); | ||
242 | int ar9170_disable_key(struct ar9170 *ar, u8 id); | ||
243 | |||
244 | /* LEDs */ | ||
245 | #ifdef CONFIG_AR9170_LEDS | ||
246 | int ar9170_register_leds(struct ar9170 *ar); | ||
247 | void ar9170_unregister_leds(struct ar9170 *ar); | ||
248 | #endif /* CONFIG_AR9170_LEDS */ | ||
249 | int ar9170_init_leds(struct ar9170 *ar); | ||
250 | int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state); | ||
251 | |||
252 | /* PHY / RF */ | ||
253 | int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band); | ||
254 | int ar9170_init_rf(struct ar9170 *ar); | ||
255 | int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, | ||
256 | enum ar9170_rf_init_mode rfi, enum ar9170_bw bw); | ||
257 | |||
258 | #endif /* __AR9170_H */ | ||
diff --git a/drivers/net/wireless/ath/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c deleted file mode 100644 index 6452c5055a6..00000000000 --- a/drivers/net/wireless/ath/ar9170/cmd.c +++ /dev/null | |||
@@ -1,127 +0,0 @@ | |||
1 | /* | ||
2 | * Atheros AR9170 driver | ||
3 | * | ||
4 | * Basic HW register/memory/command access functions | ||
5 | * | ||
6 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; see the file COPYING. If not, see | ||
20 | * http://www.gnu.org/licenses/. | ||
21 | * | ||
22 | * This file incorporates work covered by the following copyright and | ||
23 | * permission notice: | ||
24 | * Copyright (c) 2007-2008 Atheros Communications, Inc. | ||
25 | * | ||
26 | * Permission to use, copy, modify, and/or distribute this software for any | ||
27 | * purpose with or without fee is hereby granted, provided that the above | ||
28 | * copyright notice and this permission notice appear in all copies. | ||
29 | * | ||
30 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
31 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
32 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
33 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
34 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
35 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
36 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
37 | */ | ||
38 | |||
39 | #include "ar9170.h" | ||
40 | #include "cmd.h" | ||
41 | |||
42 | int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len) | ||
43 | { | ||
44 | int err; | ||
45 | |||
46 | if (unlikely(!IS_ACCEPTING_CMD(ar))) | ||
47 | return 0; | ||
48 | |||
49 | err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL); | ||
50 | if (err) | ||
51 | wiphy_debug(ar->hw->wiphy, "writing memory failed\n"); | ||
52 | return err; | ||
53 | } | ||
54 | |||
55 | int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) | ||
56 | { | ||
57 | const __le32 buf[2] = { | ||
58 | cpu_to_le32(reg), | ||
59 | cpu_to_le32(val), | ||
60 | }; | ||
61 | int err; | ||
62 | |||
63 | if (unlikely(!IS_ACCEPTING_CMD(ar))) | ||
64 | return 0; | ||
65 | |||
66 | err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf), | ||
67 | (u8 *) buf, 0, NULL); | ||
68 | if (err) | ||
69 | wiphy_debug(ar->hw->wiphy, "writing reg %#x (val %#x) failed\n", | ||
70 | reg, val); | ||
71 | return err; | ||
72 | } | ||
73 | |||
74 | int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out) | ||
75 | { | ||
76 | int i, err; | ||
77 | __le32 *offs, *res; | ||
78 | |||
79 | if (unlikely(!IS_ACCEPTING_CMD(ar))) | ||
80 | return 0; | ||
81 | |||
82 | /* abuse "out" for the register offsets, must be same length */ | ||
83 | offs = (__le32 *)out; | ||
84 | for (i = 0; i < nregs; i++) | ||
85 | offs[i] = cpu_to_le32(regs[i]); | ||
86 | |||
87 | /* also use the same buffer for the input */ | ||
88 | res = (__le32 *)out; | ||
89 | |||
90 | err = ar->exec_cmd(ar, AR9170_CMD_RREG, | ||
91 | 4 * nregs, (u8 *)offs, | ||
92 | 4 * nregs, (u8 *)res); | ||
93 | if (err) | ||
94 | return err; | ||
95 | |||
96 | /* convert result to cpu endian */ | ||
97 | for (i = 0; i < nregs; i++) | ||
98 | out[i] = le32_to_cpu(res[i]); | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val) | ||
104 | { | ||
105 | return ar9170_read_mreg(ar, 1, ®, val); | ||
106 | } | ||
107 | |||
108 | int ar9170_echo_test(struct ar9170 *ar, u32 v) | ||
109 | { | ||
110 | __le32 echobuf = cpu_to_le32(v); | ||
111 | __le32 echores; | ||
112 | int err; | ||
113 | |||
114 | if (unlikely(!IS_ACCEPTING_CMD(ar))) | ||
115 | return -ENODEV; | ||
116 | |||
117 | err = ar->exec_cmd(ar, AR9170_CMD_ECHO, | ||
118 | 4, (u8 *)&echobuf, | ||
119 | 4, (u8 *)&echores); | ||
120 | if (err) | ||
121 | return err; | ||
122 | |||
123 | if (echobuf != echores) | ||
124 | return -EINVAL; | ||
125 | |||
126 | return 0; | ||
127 | } | ||
diff --git a/drivers/net/wireless/ath/ar9170/cmd.h b/drivers/net/wireless/ath/ar9170/cmd.h deleted file mode 100644 index ec8134b4b94..00000000000 --- a/drivers/net/wireless/ath/ar9170/cmd.h +++ /dev/null | |||
@@ -1,92 +0,0 @@ | |||
1 | /* | ||
2 | * Atheros AR9170 driver | ||
3 | * | ||
4 | * Basic HW register/memory/command access functions | ||
5 | * | ||
6 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; see the file COPYING. If not, see | ||
20 | * http://www.gnu.org/licenses/. | ||
21 | * | ||
22 | * This file incorporates work covered by the following copyright and | ||
23 | * permission notice: | ||
24 | * Copyright (c) 2007-2008 Atheros Communications, Inc. | ||
25 | * | ||
26 | * Permission to use, copy, modify, and/or distribute this software for any | ||
27 | * purpose with or without fee is hereby granted, provided that the above | ||
28 | * copyright notice and this permission notice appear in all copies. | ||
29 | * | ||
30 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
31 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
32 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
33 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
34 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
35 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
36 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
37 | */ | ||
38 | #ifndef __CMD_H | ||
39 | #define __CMD_H | ||
40 | |||
41 | #include "ar9170.h" | ||
42 | |||
43 | /* basic HW access */ | ||
44 | int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len); | ||
45 | int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val); | ||
46 | int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val); | ||
47 | int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out); | ||
48 | int ar9170_echo_test(struct ar9170 *ar, u32 v); | ||
49 | |||
50 | /* | ||
51 | * Macros to facilitate writing multiple registers in a single | ||
52 | * write-combining USB command. Note that when the first group | ||
53 | * fails the whole thing will fail without any others attempted, | ||
54 | * but you won't know which write in the group failed. | ||
55 | */ | ||
56 | #define ar9170_regwrite_begin(ar) \ | ||
57 | do { \ | ||
58 | int __nreg = 0, __err = 0; \ | ||
59 | struct ar9170 *__ar = ar; | ||
60 | |||
61 | #define ar9170_regwrite(r, v) do { \ | ||
62 | __ar->cmdbuf[2 * __nreg + 1] = cpu_to_le32(r); \ | ||
63 | __ar->cmdbuf[2 * __nreg + 2] = cpu_to_le32(v); \ | ||
64 | __nreg++; \ | ||
65 | if ((__nreg >= PAYLOAD_MAX/2)) { \ | ||
66 | if (IS_ACCEPTING_CMD(__ar)) \ | ||
67 | __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \ | ||
68 | 8 * __nreg, \ | ||
69 | (u8 *) &__ar->cmdbuf[1], \ | ||
70 | 0, NULL); \ | ||
71 | __nreg = 0; \ | ||
72 | if (__err) \ | ||
73 | goto __regwrite_out; \ | ||
74 | } \ | ||
75 | } while (0) | ||
76 | |||
77 | #define ar9170_regwrite_finish() \ | ||
78 | __regwrite_out : \ | ||
79 | if (__nreg) { \ | ||
80 | if (IS_ACCEPTING_CMD(__ar)) \ | ||
81 | __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \ | ||
82 | 8 * __nreg, \ | ||
83 | (u8 *) &__ar->cmdbuf[1], \ | ||
84 | 0, NULL); \ | ||
85 | __nreg = 0; \ | ||
86 | } | ||
87 | |||
88 | #define ar9170_regwrite_result() \ | ||
89 | __err; \ | ||
90 | } while (0); | ||
91 | |||
92 | #endif /* __CMD_H */ | ||
diff --git a/drivers/net/wireless/ath/ar9170/eeprom.h b/drivers/net/wireless/ath/ar9170/eeprom.h deleted file mode 100644 index 6c466388342..00000000000 --- a/drivers/net/wireless/ath/ar9170/eeprom.h +++ /dev/null | |||
@@ -1,179 +0,0 @@ | |||
1 | /* | ||
2 | * Atheros AR9170 driver | ||
3 | * | ||
4 | * EEPROM layout | ||
5 | * | ||
6 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; see the file COPYING. If not, see | ||
20 | * http://www.gnu.org/licenses/. | ||
21 | * | ||
22 | * This file incorporates work covered by the following copyright and | ||
23 | * permission notice: | ||
24 | * Copyright (c) 2007-2008 Atheros Communications, Inc. | ||
25 | * | ||
26 | * Permission to use, copy, modify, and/or distribute this software for any | ||
27 | * purpose with or without fee is hereby granted, provided that the above | ||
28 | * copyright notice and this permission notice appear in all copies. | ||
29 | * | ||
30 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
31 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
32 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
33 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
34 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
35 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
36 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
37 | */ | ||
38 | #ifndef __AR9170_EEPROM_H | ||
39 | #define __AR9170_EEPROM_H | ||
40 | |||
41 | #define AR5416_MAX_CHAINS 2 | ||
42 | #define AR5416_MODAL_SPURS 5 | ||
43 | |||
44 | struct ar9170_eeprom_modal { | ||
45 | __le32 antCtrlChain[AR5416_MAX_CHAINS]; | ||
46 | __le32 antCtrlCommon; | ||
47 | s8 antennaGainCh[AR5416_MAX_CHAINS]; | ||
48 | u8 switchSettling; | ||
49 | u8 txRxAttenCh[AR5416_MAX_CHAINS]; | ||
50 | u8 rxTxMarginCh[AR5416_MAX_CHAINS]; | ||
51 | s8 adcDesiredSize; | ||
52 | s8 pgaDesiredSize; | ||
53 | u8 xlnaGainCh[AR5416_MAX_CHAINS]; | ||
54 | u8 txEndToXpaOff; | ||
55 | u8 txEndToRxOn; | ||
56 | u8 txFrameToXpaOn; | ||
57 | u8 thresh62; | ||
58 | s8 noiseFloorThreshCh[AR5416_MAX_CHAINS]; | ||
59 | u8 xpdGain; | ||
60 | u8 xpd; | ||
61 | s8 iqCalICh[AR5416_MAX_CHAINS]; | ||
62 | s8 iqCalQCh[AR5416_MAX_CHAINS]; | ||
63 | u8 pdGainOverlap; | ||
64 | u8 ob; | ||
65 | u8 db; | ||
66 | u8 xpaBiasLvl; | ||
67 | u8 pwrDecreaseFor2Chain; | ||
68 | u8 pwrDecreaseFor3Chain; | ||
69 | u8 txFrameToDataStart; | ||
70 | u8 txFrameToPaOn; | ||
71 | u8 ht40PowerIncForPdadc; | ||
72 | u8 bswAtten[AR5416_MAX_CHAINS]; | ||
73 | u8 bswMargin[AR5416_MAX_CHAINS]; | ||
74 | u8 swSettleHt40; | ||
75 | u8 reserved[22]; | ||
76 | struct spur_channel { | ||
77 | __le16 spurChan; | ||
78 | u8 spurRangeLow; | ||
79 | u8 spurRangeHigh; | ||
80 | } __packed spur_channels[AR5416_MODAL_SPURS]; | ||
81 | } __packed; | ||
82 | |||
83 | #define AR5416_NUM_PD_GAINS 4 | ||
84 | #define AR5416_PD_GAIN_ICEPTS 5 | ||
85 | |||
86 | struct ar9170_calibration_data_per_freq { | ||
87 | u8 pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; | ||
88 | u8 vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; | ||
89 | } __packed; | ||
90 | |||
91 | #define AR5416_NUM_5G_CAL_PIERS 8 | ||
92 | #define AR5416_NUM_2G_CAL_PIERS 4 | ||
93 | |||
94 | #define AR5416_NUM_5G_TARGET_PWRS 8 | ||
95 | #define AR5416_NUM_2G_CCK_TARGET_PWRS 3 | ||
96 | #define AR5416_NUM_2G_OFDM_TARGET_PWRS 4 | ||
97 | #define AR5416_MAX_NUM_TGT_PWRS 8 | ||
98 | |||
99 | struct ar9170_calibration_target_power_legacy { | ||
100 | u8 freq; | ||
101 | u8 power[4]; | ||
102 | } __packed; | ||
103 | |||
104 | struct ar9170_calibration_target_power_ht { | ||
105 | u8 freq; | ||
106 | u8 power[8]; | ||
107 | } __packed; | ||
108 | |||
109 | #define AR5416_NUM_CTLS 24 | ||
110 | |||
111 | struct ar9170_calctl_edges { | ||
112 | u8 channel; | ||
113 | #define AR9170_CALCTL_EDGE_FLAGS 0xC0 | ||
114 | u8 power_flags; | ||
115 | } __packed; | ||
116 | |||
117 | #define AR5416_NUM_BAND_EDGES 8 | ||
118 | |||
119 | struct ar9170_calctl_data { | ||
120 | struct ar9170_calctl_edges | ||
121 | control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; | ||
122 | } __packed; | ||
123 | |||
124 | |||
125 | struct ar9170_eeprom { | ||
126 | __le16 length; | ||
127 | __le16 checksum; | ||
128 | __le16 version; | ||
129 | u8 operating_flags; | ||
130 | #define AR9170_OPFLAG_5GHZ 1 | ||
131 | #define AR9170_OPFLAG_2GHZ 2 | ||
132 | u8 misc; | ||
133 | __le16 reg_domain[2]; | ||
134 | u8 mac_address[6]; | ||
135 | u8 rx_mask; | ||
136 | u8 tx_mask; | ||
137 | __le16 rf_silent; | ||
138 | __le16 bluetooth_options; | ||
139 | __le16 device_capabilities; | ||
140 | __le32 build_number; | ||
141 | u8 deviceType; | ||
142 | u8 reserved[33]; | ||
143 | |||
144 | u8 customer_data[64]; | ||
145 | |||
146 | struct ar9170_eeprom_modal | ||
147 | modal_header[2]; | ||
148 | |||
149 | u8 cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS]; | ||
150 | u8 cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS]; | ||
151 | |||
152 | struct ar9170_calibration_data_per_freq | ||
153 | cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS], | ||
154 | cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS]; | ||
155 | |||
156 | /* power calibration data */ | ||
157 | struct ar9170_calibration_target_power_legacy | ||
158 | cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS]; | ||
159 | struct ar9170_calibration_target_power_ht | ||
160 | cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS], | ||
161 | cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS]; | ||
162 | |||
163 | struct ar9170_calibration_target_power_legacy | ||
164 | cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS], | ||
165 | cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS]; | ||
166 | struct ar9170_calibration_target_power_ht | ||
167 | cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS], | ||
168 | cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS]; | ||
169 | |||
170 | /* conformance testing limits */ | ||
171 | u8 ctl_index[AR5416_NUM_CTLS]; | ||
172 | struct ar9170_calctl_data | ||
173 | ctl_data[AR5416_NUM_CTLS]; | ||
174 | |||
175 | u8 pad; | ||
176 | __le16 subsystem_id; | ||
177 | } __packed; | ||
178 | |||
179 | #endif /* __AR9170_EEPROM_H */ | ||
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h deleted file mode 100644 index 06f1f3c951a..00000000000 --- a/drivers/net/wireless/ath/ar9170/hw.h +++ /dev/null | |||
@@ -1,430 +0,0 @@ | |||
1 | /* | ||
2 | * Atheros AR9170 driver | ||
3 | * | ||
4 | * Hardware-specific definitions | ||
5 | * | ||
6 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; see the file COPYING. If not, see | ||
20 | * http://www.gnu.org/licenses/. | ||
21 | * | ||
22 | * This file incorporates work covered by the following copyright and | ||
23 | * permission notice: | ||
24 | * Copyright (c) 2007-2008 Atheros Communications, Inc. | ||
25 | * | ||
26 | * Permission to use, copy, modify, and/or distribute this software for any | ||
27 | * purpose with or without fee is hereby granted, provided that the above | ||
28 | * copyright notice and this permission notice appear in all copies. | ||
29 | * | ||
30 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
31 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
32 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
33 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
34 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
35 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
36 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
37 | */ | ||
38 | #ifndef __AR9170_HW_H | ||
39 | #define __AR9170_HW_H | ||
40 | |||
41 | #define AR9170_MAX_CMD_LEN 64 | ||
42 | |||
43 | enum ar9170_cmd { | ||
44 | AR9170_CMD_RREG = 0x00, | ||
45 | AR9170_CMD_WREG = 0x01, | ||
46 | AR9170_CMD_RMEM = 0x02, | ||
47 | AR9170_CMD_WMEM = 0x03, | ||
48 | AR9170_CMD_BITAND = 0x04, | ||
49 | AR9170_CMD_BITOR = 0x05, | ||
50 | AR9170_CMD_EKEY = 0x28, | ||
51 | AR9170_CMD_DKEY = 0x29, | ||
52 | AR9170_CMD_FREQUENCY = 0x30, | ||
53 | AR9170_CMD_RF_INIT = 0x31, | ||
54 | AR9170_CMD_SYNTH = 0x32, | ||
55 | AR9170_CMD_FREQ_START = 0x33, | ||
56 | AR9170_CMD_ECHO = 0x80, | ||
57 | AR9170_CMD_TALLY = 0x81, | ||
58 | AR9170_CMD_TALLY_APD = 0x82, | ||
59 | AR9170_CMD_CONFIG = 0x83, | ||
60 | AR9170_CMD_RESET = 0x90, | ||
61 | AR9170_CMD_DKRESET = 0x91, | ||
62 | AR9170_CMD_DKTX_STATUS = 0x92, | ||
63 | AR9170_CMD_FDC = 0xA0, | ||
64 | AR9170_CMD_WREEPROM = 0xB0, | ||
65 | AR9170_CMD_WFLASH = 0xB0, | ||
66 | AR9170_CMD_FLASH_ERASE = 0xB1, | ||
67 | AR9170_CMD_FLASH_PROG = 0xB2, | ||
68 | AR9170_CMD_FLASH_CHKSUM = 0xB3, | ||
69 | AR9170_CMD_FLASH_READ = 0xB4, | ||
70 | AR9170_CMD_FW_DL_INIT = 0xB5, | ||
71 | AR9170_CMD_MEM_WREEPROM = 0xBB, | ||
72 | }; | ||
73 | |||
74 | /* endpoints */ | ||
75 | #define AR9170_EP_TX 1 | ||
76 | #define AR9170_EP_RX 2 | ||
77 | #define AR9170_EP_IRQ 3 | ||
78 | #define AR9170_EP_CMD 4 | ||
79 | |||
80 | #define AR9170_EEPROM_START 0x1600 | ||
81 | |||
82 | #define AR9170_GPIO_REG_BASE 0x1d0100 | ||
83 | #define AR9170_GPIO_REG_PORT_TYPE AR9170_GPIO_REG_BASE | ||
84 | #define AR9170_GPIO_REG_DATA (AR9170_GPIO_REG_BASE + 4) | ||
85 | #define AR9170_NUM_LEDS 2 | ||
86 | |||
87 | |||
88 | #define AR9170_USB_REG_BASE 0x1e1000 | ||
89 | #define AR9170_USB_REG_DMA_CTL (AR9170_USB_REG_BASE + 0x108) | ||
90 | #define AR9170_DMA_CTL_ENABLE_TO_DEVICE 0x1 | ||
91 | #define AR9170_DMA_CTL_ENABLE_FROM_DEVICE 0x2 | ||
92 | #define AR9170_DMA_CTL_HIGH_SPEED 0x4 | ||
93 | #define AR9170_DMA_CTL_PACKET_MODE 0x8 | ||
94 | |||
95 | #define AR9170_USB_REG_MAX_AGG_UPLOAD (AR9170_USB_REG_BASE + 0x110) | ||
96 | #define AR9170_USB_REG_UPLOAD_TIME_CTL (AR9170_USB_REG_BASE + 0x114) | ||
97 | |||
98 | |||
99 | |||
100 | #define AR9170_MAC_REG_BASE 0x1c3000 | ||
101 | |||
102 | #define AR9170_MAC_REG_TSF_L (AR9170_MAC_REG_BASE + 0x514) | ||
103 | #define AR9170_MAC_REG_TSF_H (AR9170_MAC_REG_BASE + 0x518) | ||
104 | |||
105 | #define AR9170_MAC_REG_ATIM_WINDOW (AR9170_MAC_REG_BASE + 0x51C) | ||
106 | #define AR9170_MAC_REG_BCN_PERIOD (AR9170_MAC_REG_BASE + 0x520) | ||
107 | #define AR9170_MAC_REG_PRETBTT (AR9170_MAC_REG_BASE + 0x524) | ||
108 | |||
109 | #define AR9170_MAC_REG_MAC_ADDR_L (AR9170_MAC_REG_BASE + 0x610) | ||
110 | #define AR9170_MAC_REG_MAC_ADDR_H (AR9170_MAC_REG_BASE + 0x614) | ||
111 | #define AR9170_MAC_REG_BSSID_L (AR9170_MAC_REG_BASE + 0x618) | ||
112 | #define AR9170_MAC_REG_BSSID_H (AR9170_MAC_REG_BASE + 0x61c) | ||
113 | |||
114 | #define AR9170_MAC_REG_GROUP_HASH_TBL_L (AR9170_MAC_REG_BASE + 0x624) | ||
115 | #define AR9170_MAC_REG_GROUP_HASH_TBL_H (AR9170_MAC_REG_BASE + 0x628) | ||
116 | |||
117 | #define AR9170_MAC_REG_RX_TIMEOUT (AR9170_MAC_REG_BASE + 0x62C) | ||
118 | |||
119 | #define AR9170_MAC_REG_BASIC_RATE (AR9170_MAC_REG_BASE + 0x630) | ||
120 | #define AR9170_MAC_REG_MANDATORY_RATE (AR9170_MAC_REG_BASE + 0x634) | ||
121 | #define AR9170_MAC_REG_RTS_CTS_RATE (AR9170_MAC_REG_BASE + 0x638) | ||
122 | #define AR9170_MAC_REG_BACKOFF_PROTECT (AR9170_MAC_REG_BASE + 0x63c) | ||
123 | #define AR9170_MAC_REG_RX_THRESHOLD (AR9170_MAC_REG_BASE + 0x640) | ||
124 | #define AR9170_MAC_REG_RX_PE_DELAY (AR9170_MAC_REG_BASE + 0x64C) | ||
125 | |||
126 | #define AR9170_MAC_REG_DYNAMIC_SIFS_ACK (AR9170_MAC_REG_BASE + 0x658) | ||
127 | #define AR9170_MAC_REG_SNIFFER (AR9170_MAC_REG_BASE + 0x674) | ||
128 | #define AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC BIT(0) | ||
129 | #define AR9170_MAC_REG_SNIFFER_DEFAULTS 0x02000000 | ||
130 | #define AR9170_MAC_REG_ENCRYPTION (AR9170_MAC_REG_BASE + 0x678) | ||
131 | #define AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE BIT(3) | ||
132 | #define AR9170_MAC_REG_ENCRYPTION_DEFAULTS 0x70 | ||
133 | |||
134 | #define AR9170_MAC_REG_MISC_680 (AR9170_MAC_REG_BASE + 0x680) | ||
135 | #define AR9170_MAC_REG_TX_UNDERRUN (AR9170_MAC_REG_BASE + 0x688) | ||
136 | |||
137 | #define AR9170_MAC_REG_FRAMETYPE_FILTER (AR9170_MAC_REG_BASE + 0x68c) | ||
138 | #define AR9170_MAC_REG_FTF_ASSOC_REQ BIT(0) | ||
139 | #define AR9170_MAC_REG_FTF_ASSOC_RESP BIT(1) | ||
140 | #define AR9170_MAC_REG_FTF_REASSOC_REQ BIT(2) | ||
141 | #define AR9170_MAC_REG_FTF_REASSOC_RESP BIT(3) | ||
142 | #define AR9170_MAC_REG_FTF_PRB_REQ BIT(4) | ||
143 | #define AR9170_MAC_REG_FTF_PRB_RESP BIT(5) | ||
144 | #define AR9170_MAC_REG_FTF_BIT6 BIT(6) | ||
145 | #define AR9170_MAC_REG_FTF_BIT7 BIT(7) | ||
146 | #define AR9170_MAC_REG_FTF_BEACON BIT(8) | ||
147 | #define AR9170_MAC_REG_FTF_ATIM BIT(9) | ||
148 | #define AR9170_MAC_REG_FTF_DEASSOC BIT(10) | ||
149 | #define AR9170_MAC_REG_FTF_AUTH BIT(11) | ||
150 | #define AR9170_MAC_REG_FTF_DEAUTH BIT(12) | ||
151 | #define AR9170_MAC_REG_FTF_BIT13 BIT(13) | ||
152 | #define AR9170_MAC_REG_FTF_BIT14 BIT(14) | ||
153 | #define AR9170_MAC_REG_FTF_BIT15 BIT(15) | ||
154 | #define AR9170_MAC_REG_FTF_BAR BIT(24) | ||
155 | #define AR9170_MAC_REG_FTF_BA BIT(25) | ||
156 | #define AR9170_MAC_REG_FTF_PSPOLL BIT(26) | ||
157 | #define AR9170_MAC_REG_FTF_RTS BIT(27) | ||
158 | #define AR9170_MAC_REG_FTF_CTS BIT(28) | ||
159 | #define AR9170_MAC_REG_FTF_ACK BIT(29) | ||
160 | #define AR9170_MAC_REG_FTF_CFE BIT(30) | ||
161 | #define AR9170_MAC_REG_FTF_CFE_ACK BIT(31) | ||
162 | #define AR9170_MAC_REG_FTF_DEFAULTS 0x0700ffff | ||
163 | #define AR9170_MAC_REG_FTF_MONITOR 0xfd00ffff | ||
164 | |||
165 | #define AR9170_MAC_REG_RX_TOTAL (AR9170_MAC_REG_BASE + 0x6A0) | ||
166 | #define AR9170_MAC_REG_RX_CRC32 (AR9170_MAC_REG_BASE + 0x6A4) | ||
167 | #define AR9170_MAC_REG_RX_CRC16 (AR9170_MAC_REG_BASE + 0x6A8) | ||
168 | #define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI (AR9170_MAC_REG_BASE + 0x6AC) | ||
169 | #define AR9170_MAC_REG_RX_OVERRUN (AR9170_MAC_REG_BASE + 0x6B0) | ||
170 | #define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL (AR9170_MAC_REG_BASE + 0x6BC) | ||
171 | #define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6CC) | ||
172 | #define AR9170_MAC_REG_TX_TOTAL (AR9170_MAC_REG_BASE + 0x6F4) | ||
173 | |||
174 | |||
175 | #define AR9170_MAC_REG_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0x690) | ||
176 | #define AR9170_MAC_REG_EIFS_AND_SIFS (AR9170_MAC_REG_BASE + 0x698) | ||
177 | |||
178 | #define AR9170_MAC_REG_SLOT_TIME (AR9170_MAC_REG_BASE + 0x6F0) | ||
179 | |||
180 | #define AR9170_MAC_REG_POWERMANAGEMENT (AR9170_MAC_REG_BASE + 0x700) | ||
181 | #define AR9170_MAC_REG_POWERMGT_IBSS 0xe0 | ||
182 | #define AR9170_MAC_REG_POWERMGT_AP 0xa1 | ||
183 | #define AR9170_MAC_REG_POWERMGT_STA 0x2 | ||
184 | #define AR9170_MAC_REG_POWERMGT_AP_WDS 0x3 | ||
185 | #define AR9170_MAC_REG_POWERMGT_DEFAULTS (0xf << 24) | ||
186 | |||
187 | #define AR9170_MAC_REG_ROLL_CALL_TBL_L (AR9170_MAC_REG_BASE + 0x704) | ||
188 | #define AR9170_MAC_REG_ROLL_CALL_TBL_H (AR9170_MAC_REG_BASE + 0x708) | ||
189 | |||
190 | #define AR9170_MAC_REG_AC0_CW (AR9170_MAC_REG_BASE + 0xB00) | ||
191 | #define AR9170_MAC_REG_AC1_CW (AR9170_MAC_REG_BASE + 0xB04) | ||
192 | #define AR9170_MAC_REG_AC2_CW (AR9170_MAC_REG_BASE + 0xB08) | ||
193 | #define AR9170_MAC_REG_AC3_CW (AR9170_MAC_REG_BASE + 0xB0C) | ||
194 | #define AR9170_MAC_REG_AC4_CW (AR9170_MAC_REG_BASE + 0xB10) | ||
195 | #define AR9170_MAC_REG_AC1_AC0_AIFS (AR9170_MAC_REG_BASE + 0xB14) | ||
196 | #define AR9170_MAC_REG_AC3_AC2_AIFS (AR9170_MAC_REG_BASE + 0xB18) | ||
197 | |||
198 | #define AR9170_MAC_REG_RETRY_MAX (AR9170_MAC_REG_BASE + 0xB28) | ||
199 | |||
200 | #define AR9170_MAC_REG_FCS_SELECT (AR9170_MAC_REG_BASE + 0xBB0) | ||
201 | #define AR9170_MAC_FCS_SWFCS 0x1 | ||
202 | #define AR9170_MAC_FCS_FIFO_PROT 0x4 | ||
203 | |||
204 | |||
205 | #define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND (AR9170_MAC_REG_BASE + 0xB30) | ||
206 | |||
207 | #define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xB44) | ||
208 | #define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xB48) | ||
209 | |||
210 | #define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xB9C) | ||
211 | #define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xBA0) | ||
212 | |||
213 | #define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xC00) | ||
214 | #define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xC50) | ||
215 | |||
216 | #define AR9170_MAC_REG_TXRX_MPI (AR9170_MAC_REG_BASE + 0xD7C) | ||
217 | #define AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f | ||
218 | #define AR9170_MAC_TXRX_MPI_TX_TO_MASK 0x0000fff0 | ||
219 | #define AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000 | ||
220 | #define AR9170_MAC_TXRX_MPI_RX_TO_MASK 0xfff00000 | ||
221 | |||
222 | #define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xD84) | ||
223 | #define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xD88) | ||
224 | #define AR9170_MAC_REG_BCN_PLCP (AR9170_MAC_REG_BASE + 0xD90) | ||
225 | #define AR9170_MAC_REG_BCN_CTRL (AR9170_MAC_REG_BASE + 0xD94) | ||
226 | #define AR9170_MAC_REG_BCN_HT1 (AR9170_MAC_REG_BASE + 0xDA0) | ||
227 | #define AR9170_MAC_REG_BCN_HT2 (AR9170_MAC_REG_BASE + 0xDA4) | ||
228 | |||
229 | |||
230 | #define AR9170_PWR_REG_BASE 0x1D4000 | ||
231 | |||
232 | #define AR9170_PWR_REG_CLOCK_SEL (AR9170_PWR_REG_BASE + 0x008) | ||
233 | #define AR9170_PWR_CLK_AHB_40MHZ 0 | ||
234 | #define AR9170_PWR_CLK_AHB_20_22MHZ 1 | ||
235 | #define AR9170_PWR_CLK_AHB_40_44MHZ 2 | ||
236 | #define AR9170_PWR_CLK_AHB_80_88MHZ 3 | ||
237 | #define AR9170_PWR_CLK_DAC_160_INV_DLY 0x70 | ||
238 | |||
239 | |||
240 | /* put beacon here in memory */ | ||
241 | #define AR9170_BEACON_BUFFER_ADDRESS 0x117900 | ||
242 | |||
243 | |||
244 | struct ar9170_tx_control { | ||
245 | __le16 length; | ||
246 | __le16 mac_control; | ||
247 | __le32 phy_control; | ||
248 | u8 frame_data[0]; | ||
249 | } __packed; | ||
250 | |||
251 | /* these are either-or */ | ||
252 | #define AR9170_TX_MAC_PROT_RTS 0x0001 | ||
253 | #define AR9170_TX_MAC_PROT_CTS 0x0002 | ||
254 | |||
255 | #define AR9170_TX_MAC_NO_ACK 0x0004 | ||
256 | /* if unset, MAC will only do SIFS space before frame */ | ||
257 | #define AR9170_TX_MAC_BACKOFF 0x0008 | ||
258 | #define AR9170_TX_MAC_BURST 0x0010 | ||
259 | #define AR9170_TX_MAC_AGGR 0x0020 | ||
260 | |||
261 | /* encryption is a two-bit field */ | ||
262 | #define AR9170_TX_MAC_ENCR_NONE 0x0000 | ||
263 | #define AR9170_TX_MAC_ENCR_RC4 0x0040 | ||
264 | #define AR9170_TX_MAC_ENCR_CENC 0x0080 | ||
265 | #define AR9170_TX_MAC_ENCR_AES 0x00c0 | ||
266 | |||
267 | #define AR9170_TX_MAC_MMIC 0x0100 | ||
268 | #define AR9170_TX_MAC_HW_DURATION 0x0200 | ||
269 | #define AR9170_TX_MAC_QOS_SHIFT 10 | ||
270 | #define AR9170_TX_MAC_QOS_MASK (3 << AR9170_TX_MAC_QOS_SHIFT) | ||
271 | #define AR9170_TX_MAC_AGGR_QOS_BIT1 0x0400 | ||
272 | #define AR9170_TX_MAC_AGGR_QOS_BIT2 0x0800 | ||
273 | #define AR9170_TX_MAC_DISABLE_TXOP 0x1000 | ||
274 | #define AR9170_TX_MAC_TXOP_RIFS 0x2000 | ||
275 | #define AR9170_TX_MAC_IMM_AMPDU 0x4000 | ||
276 | #define AR9170_TX_MAC_RATE_PROBE 0x8000 | ||
277 | |||
278 | /* either-or */ | ||
279 | #define AR9170_TX_PHY_MOD_MASK 0x00000003 | ||
280 | #define AR9170_TX_PHY_MOD_CCK 0x00000000 | ||
281 | #define AR9170_TX_PHY_MOD_OFDM 0x00000001 | ||
282 | #define AR9170_TX_PHY_MOD_HT 0x00000002 | ||
283 | |||
284 | /* depends on modulation */ | ||
285 | #define AR9170_TX_PHY_SHORT_PREAMBLE 0x00000004 | ||
286 | #define AR9170_TX_PHY_GREENFIELD 0x00000004 | ||
287 | |||
288 | #define AR9170_TX_PHY_BW_SHIFT 3 | ||
289 | #define AR9170_TX_PHY_BW_MASK (3 << AR9170_TX_PHY_BW_SHIFT) | ||
290 | #define AR9170_TX_PHY_BW_20MHZ 0 | ||
291 | #define AR9170_TX_PHY_BW_40MHZ 2 | ||
292 | #define AR9170_TX_PHY_BW_40MHZ_DUP 3 | ||
293 | |||
294 | #define AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT 6 | ||
295 | #define AR9170_TX_PHY_TX_HEAVY_CLIP_MASK (7 << AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT) | ||
296 | |||
297 | #define AR9170_TX_PHY_TX_PWR_SHIFT 9 | ||
298 | #define AR9170_TX_PHY_TX_PWR_MASK (0x3f << AR9170_TX_PHY_TX_PWR_SHIFT) | ||
299 | |||
300 | /* not part of the hw-spec */ | ||
301 | #define AR9170_TX_PHY_QOS_SHIFT 25 | ||
302 | #define AR9170_TX_PHY_QOS_MASK (3 << AR9170_TX_PHY_QOS_SHIFT) | ||
303 | |||
304 | #define AR9170_TX_PHY_TXCHAIN_SHIFT 15 | ||
305 | #define AR9170_TX_PHY_TXCHAIN_MASK (7 << AR9170_TX_PHY_TXCHAIN_SHIFT) | ||
306 | #define AR9170_TX_PHY_TXCHAIN_1 1 | ||
307 | /* use for cck, ofdm 6/9/12/18/24 and HT if capable */ | ||
308 | #define AR9170_TX_PHY_TXCHAIN_2 5 | ||
309 | |||
310 | #define AR9170_TX_PHY_MCS_SHIFT 18 | ||
311 | #define AR9170_TX_PHY_MCS_MASK (0x7f << AR9170_TX_PHY_MCS_SHIFT) | ||
312 | |||
313 | #define AR9170_TX_PHY_SHORT_GI 0x80000000 | ||
314 | |||
315 | #define AR5416_MAX_RATE_POWER 63 | ||
316 | |||
317 | struct ar9170_rx_head { | ||
318 | u8 plcp[12]; | ||
319 | } __packed; | ||
320 | |||
321 | struct ar9170_rx_phystatus { | ||
322 | union { | ||
323 | struct { | ||
324 | u8 rssi_ant0, rssi_ant1, rssi_ant2, | ||
325 | rssi_ant0x, rssi_ant1x, rssi_ant2x, | ||
326 | rssi_combined; | ||
327 | } __packed; | ||
328 | u8 rssi[7]; | ||
329 | } __packed; | ||
330 | |||
331 | u8 evm_stream0[6], evm_stream1[6]; | ||
332 | u8 phy_err; | ||
333 | } __packed; | ||
334 | |||
335 | struct ar9170_rx_macstatus { | ||
336 | u8 SAidx, DAidx; | ||
337 | u8 error; | ||
338 | u8 status; | ||
339 | } __packed; | ||
340 | |||
341 | #define AR9170_ENC_ALG_NONE 0x0 | ||
342 | #define AR9170_ENC_ALG_WEP64 0x1 | ||
343 | #define AR9170_ENC_ALG_TKIP 0x2 | ||
344 | #define AR9170_ENC_ALG_AESCCMP 0x4 | ||
345 | #define AR9170_ENC_ALG_WEP128 0x5 | ||
346 | #define AR9170_ENC_ALG_WEP256 0x6 | ||
347 | #define AR9170_ENC_ALG_CENC 0x7 | ||
348 | |||
349 | #define AR9170_RX_ENC_SOFTWARE 0x8 | ||
350 | |||
351 | static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t) | ||
352 | { | ||
353 | return (t->SAidx & 0xc0) >> 4 | | ||
354 | (t->DAidx & 0xc0) >> 6; | ||
355 | } | ||
356 | |||
357 | #define AR9170_RX_STATUS_MODULATION_MASK 0x03 | ||
358 | #define AR9170_RX_STATUS_MODULATION_CCK 0x00 | ||
359 | #define AR9170_RX_STATUS_MODULATION_OFDM 0x01 | ||
360 | #define AR9170_RX_STATUS_MODULATION_HT 0x02 | ||
361 | #define AR9170_RX_STATUS_MODULATION_DUPOFDM 0x03 | ||
362 | |||
363 | /* depends on modulation */ | ||
364 | #define AR9170_RX_STATUS_SHORT_PREAMBLE 0x08 | ||
365 | #define AR9170_RX_STATUS_GREENFIELD 0x08 | ||
366 | |||
367 | #define AR9170_RX_STATUS_MPDU_MASK 0x30 | ||
368 | #define AR9170_RX_STATUS_MPDU_SINGLE 0x00 | ||
369 | #define AR9170_RX_STATUS_MPDU_FIRST 0x20 | ||
370 | #define AR9170_RX_STATUS_MPDU_MIDDLE 0x30 | ||
371 | #define AR9170_RX_STATUS_MPDU_LAST 0x10 | ||
372 | |||
373 | #define AR9170_RX_ERROR_RXTO 0x01 | ||
374 | #define AR9170_RX_ERROR_OVERRUN 0x02 | ||
375 | #define AR9170_RX_ERROR_DECRYPT 0x04 | ||
376 | #define AR9170_RX_ERROR_FCS 0x08 | ||
377 | #define AR9170_RX_ERROR_WRONG_RA 0x10 | ||
378 | #define AR9170_RX_ERROR_PLCP 0x20 | ||
379 | #define AR9170_RX_ERROR_MMIC 0x40 | ||
380 | #define AR9170_RX_ERROR_FATAL 0x80 | ||
381 | |||
382 | struct ar9170_cmd_tx_status { | ||
383 | u8 dst[ETH_ALEN]; | ||
384 | __le32 rate; | ||
385 | __le16 status; | ||
386 | } __packed; | ||
387 | |||
388 | #define AR9170_TX_STATUS_COMPLETE 0x00 | ||
389 | #define AR9170_TX_STATUS_RETRY 0x01 | ||
390 | #define AR9170_TX_STATUS_FAILED 0x02 | ||
391 | |||
392 | struct ar9170_cmd_ba_failed_count { | ||
393 | __le16 failed; | ||
394 | __le16 rate; | ||
395 | } __packed; | ||
396 | |||
397 | struct ar9170_cmd_response { | ||
398 | u8 flag; | ||
399 | u8 type; | ||
400 | __le16 padding; | ||
401 | |||
402 | union { | ||
403 | struct ar9170_cmd_tx_status tx_status; | ||
404 | struct ar9170_cmd_ba_failed_count ba_fail_cnt; | ||
405 | u8 data[0]; | ||
406 | }; | ||
407 | } __packed; | ||
408 | |||
409 | /* QoS */ | ||
410 | |||
411 | /* mac80211 queue to HW/FW map */ | ||
412 | static const u8 ar9170_qos_hwmap[4] = { 3, 2, 0, 1 }; | ||
413 | |||
414 | /* HW/FW queue to mac80211 map */ | ||
415 | static const u8 ar9170_qos_mac80211map[4] = { 2, 3, 1, 0 }; | ||
416 | |||
417 | enum ar9170_txq { | ||
418 | AR9170_TXQ_BE, | ||
419 | AR9170_TXQ_BK, | ||
420 | AR9170_TXQ_VI, | ||
421 | AR9170_TXQ_VO, | ||
422 | |||
423 | __AR9170_NUM_TXQ, | ||
424 | }; | ||
425 | |||
426 | #define AR9170_TXQ_DEPTH 32 | ||
427 | #define AR9170_TX_MAX_PENDING 128 | ||
428 | #define AR9170_RX_STREAM_MAX_SIZE 65535 | ||
429 | |||
430 | #endif /* __AR9170_HW_H */ | ||
diff --git a/drivers/net/wireless/ath/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c deleted file mode 100644 index 832d90087f8..00000000000 --- a/drivers/net/wireless/ath/ar9170/led.c +++ /dev/null | |||
@@ -1,181 +0,0 @@ | |||
1 | /* | ||
2 | * Atheros AR9170 driver | ||
3 | * | ||
4 | * LED handling | ||
5 | * | ||
6 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; see the file COPYING. If not, see | ||
20 | * http://www.gnu.org/licenses/. | ||
21 | * | ||
22 | * This file incorporates work covered by the following copyright and | ||
23 | * permission notice: | ||
24 | * Copyright (c) 2007-2008 Atheros Communications, Inc. | ||
25 | * | ||
26 | * Permission to use, copy, modify, and/or distribute this software for any | ||
27 | * purpose with or without fee is hereby granted, provided that the above | ||
28 | * copyright notice and this permission notice appear in all copies. | ||
29 | * | ||
30 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
31 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
32 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
33 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
34 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
35 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
36 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
37 | */ | ||
38 | |||
39 | #include "ar9170.h" | ||
40 | #include "cmd.h" | ||
41 | |||
42 | int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state) | ||
43 | { | ||
44 | return ar9170_write_reg(ar, AR9170_GPIO_REG_DATA, led_state); | ||
45 | } | ||
46 | |||
47 | int ar9170_init_leds(struct ar9170 *ar) | ||
48 | { | ||
49 | int err; | ||
50 | |||
51 | /* disable LEDs */ | ||
52 | /* GPIO [0/1 mode: output, 2/3: input] */ | ||
53 | err = ar9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3); | ||
54 | if (err) | ||
55 | goto out; | ||
56 | |||
57 | /* GPIO 0/1 value: off */ | ||
58 | err = ar9170_set_leds_state(ar, 0); | ||
59 | |||
60 | out: | ||
61 | return err; | ||
62 | } | ||
63 | |||
64 | #ifdef CONFIG_AR9170_LEDS | ||
65 | static void ar9170_update_leds(struct work_struct *work) | ||
66 | { | ||
67 | struct ar9170 *ar = container_of(work, struct ar9170, led_work.work); | ||
68 | int i, tmp, blink_delay = 1000; | ||
69 | u32 led_val = 0; | ||
70 | bool rerun = false; | ||
71 | |||
72 | if (unlikely(!IS_ACCEPTING_CMD(ar))) | ||
73 | return ; | ||
74 | |||
75 | mutex_lock(&ar->mutex); | ||
76 | for (i = 0; i < AR9170_NUM_LEDS; i++) | ||
77 | if (ar->leds[i].registered && ar->leds[i].toggled) { | ||
78 | led_val |= 1 << i; | ||
79 | |||
80 | tmp = 70 + 200 / (ar->leds[i].toggled); | ||
81 | if (tmp < blink_delay) | ||
82 | blink_delay = tmp; | ||
83 | |||
84 | if (ar->leds[i].toggled > 1) | ||
85 | ar->leds[i].toggled = 0; | ||
86 | |||
87 | rerun = true; | ||
88 | } | ||
89 | |||
90 | ar9170_set_leds_state(ar, led_val); | ||
91 | mutex_unlock(&ar->mutex); | ||
92 | |||
93 | if (!rerun) | ||
94 | return; | ||
95 | |||
96 | ieee80211_queue_delayed_work(ar->hw, | ||
97 | &ar->led_work, | ||
98 | msecs_to_jiffies(blink_delay)); | ||
99 | } | ||
100 | |||
101 | static void ar9170_led_brightness_set(struct led_classdev *led, | ||
102 | enum led_brightness brightness) | ||
103 | { | ||
104 | struct ar9170_led *arl = container_of(led, struct ar9170_led, l); | ||
105 | struct ar9170 *ar = arl->ar; | ||
106 | |||
107 | if (unlikely(!arl->registered)) | ||
108 | return ; | ||
109 | |||
110 | if (arl->last_state != !!brightness) { | ||
111 | arl->toggled++; | ||
112 | arl->last_state = !!brightness; | ||
113 | } | ||
114 | |||
115 | if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled)) | ||
116 | ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10); | ||
117 | } | ||
118 | |||
119 | static int ar9170_register_led(struct ar9170 *ar, int i, char *name, | ||
120 | char *trigger) | ||
121 | { | ||
122 | int err; | ||
123 | |||
124 | snprintf(ar->leds[i].name, sizeof(ar->leds[i].name), | ||
125 | "ar9170-%s::%s", wiphy_name(ar->hw->wiphy), name); | ||
126 | |||
127 | ar->leds[i].ar = ar; | ||
128 | ar->leds[i].l.name = ar->leds[i].name; | ||
129 | ar->leds[i].l.brightness_set = ar9170_led_brightness_set; | ||
130 | ar->leds[i].l.brightness = 0; | ||
131 | ar->leds[i].l.default_trigger = trigger; | ||
132 | |||
133 | err = led_classdev_register(wiphy_dev(ar->hw->wiphy), | ||
134 | &ar->leds[i].l); | ||
135 | if (err) | ||
136 | wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n", | ||
137 | ar->leds[i].name, err); | ||
138 | else | ||
139 | ar->leds[i].registered = true; | ||
140 | |||
141 | return err; | ||
142 | } | ||
143 | |||
144 | void ar9170_unregister_leds(struct ar9170 *ar) | ||
145 | { | ||
146 | int i; | ||
147 | |||
148 | for (i = 0; i < AR9170_NUM_LEDS; i++) | ||
149 | if (ar->leds[i].registered) { | ||
150 | led_classdev_unregister(&ar->leds[i].l); | ||
151 | ar->leds[i].registered = false; | ||
152 | ar->leds[i].toggled = 0; | ||
153 | } | ||
154 | |||
155 | cancel_delayed_work_sync(&ar->led_work); | ||
156 | } | ||
157 | |||
158 | int ar9170_register_leds(struct ar9170 *ar) | ||
159 | { | ||
160 | int err; | ||
161 | |||
162 | INIT_DELAYED_WORK(&ar->led_work, ar9170_update_leds); | ||
163 | |||
164 | err = ar9170_register_led(ar, 0, "tx", | ||
165 | ieee80211_get_tx_led_name(ar->hw)); | ||
166 | if (err) | ||
167 | goto fail; | ||
168 | |||
169 | err = ar9170_register_led(ar, 1, "assoc", | ||
170 | ieee80211_get_assoc_led_name(ar->hw)); | ||
171 | if (err) | ||
172 | goto fail; | ||
173 | |||
174 | return 0; | ||
175 | |||
176 | fail: | ||
177 | ar9170_unregister_leds(ar); | ||
178 | return err; | ||
179 | } | ||
180 | |||
181 | #endif /* CONFIG_AR9170_LEDS */ | ||
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c deleted file mode 100644 index 857e8610429..00000000000 --- a/drivers/net/wireless/ath/ar9170/mac.c +++ /dev/null | |||
@@ -1,519 +0,0 @@ | |||
1 | /* | ||
2 | * Atheros AR9170 driver | ||
3 | * | ||
4 | * MAC programming | ||
5 | * | ||
6 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; see the file COPYING. If not, see | ||
20 | * http://www.gnu.org/licenses/. | ||
21 | * | ||
22 | * This file incorporates work covered by the following copyright and | ||
23 | * permission notice: | ||
24 | * Copyright (c) 2007-2008 Atheros Communications, Inc. | ||
25 | * | ||
26 | * Permission to use, copy, modify, and/or distribute this software for any | ||
27 | * purpose with or without fee is hereby granted, provided that the above | ||
28 | * copyright notice and this permission notice appear in all copies. | ||
29 | * | ||
30 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
31 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
32 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
33 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
34 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
35 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
36 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
37 | */ | ||
38 | |||
39 | #include <asm/unaligned.h> | ||
40 | |||
41 | #include "ar9170.h" | ||
42 | #include "cmd.h" | ||
43 | |||
44 | int ar9170_set_dyn_sifs_ack(struct ar9170 *ar) | ||
45 | { | ||
46 | u32 val; | ||
47 | |||
48 | if (conf_is_ht40(&ar->hw->conf)) | ||
49 | val = 0x010a; | ||
50 | else { | ||
51 | if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) | ||
52 | val = 0x105; | ||
53 | else | ||
54 | val = 0x104; | ||
55 | } | ||
56 | |||
57 | return ar9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val); | ||
58 | } | ||
59 | |||
60 | int ar9170_set_slot_time(struct ar9170 *ar) | ||
61 | { | ||
62 | u32 slottime = 20; | ||
63 | |||
64 | if (!ar->vif) | ||
65 | return 0; | ||
66 | |||
67 | if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) || | ||
68 | ar->vif->bss_conf.use_short_slot) | ||
69 | slottime = 9; | ||
70 | |||
71 | return ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, slottime << 10); | ||
72 | } | ||
73 | |||
74 | int ar9170_set_basic_rates(struct ar9170 *ar) | ||
75 | { | ||
76 | u8 cck, ofdm; | ||
77 | |||
78 | if (!ar->vif) | ||
79 | return 0; | ||
80 | |||
81 | ofdm = ar->vif->bss_conf.basic_rates >> 4; | ||
82 | |||
83 | /* FIXME: is still necessary? */ | ||
84 | if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) | ||
85 | cck = 0; | ||
86 | else | ||
87 | cck = ar->vif->bss_conf.basic_rates & 0xf; | ||
88 | |||
89 | return ar9170_write_reg(ar, AR9170_MAC_REG_BASIC_RATE, | ||
90 | ofdm << 8 | cck); | ||
91 | } | ||
92 | |||
93 | int ar9170_set_qos(struct ar9170 *ar) | ||
94 | { | ||
95 | ar9170_regwrite_begin(ar); | ||
96 | |||
97 | ar9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min | | ||
98 | (ar->edcf[0].cw_max << 16)); | ||
99 | ar9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min | | ||
100 | (ar->edcf[1].cw_max << 16)); | ||
101 | ar9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min | | ||
102 | (ar->edcf[2].cw_max << 16)); | ||
103 | ar9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min | | ||
104 | (ar->edcf[3].cw_max << 16)); | ||
105 | ar9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min | | ||
106 | (ar->edcf[4].cw_max << 16)); | ||
107 | |||
108 | ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_AIFS, | ||
109 | ((ar->edcf[0].aifs * 9 + 10)) | | ||
110 | ((ar->edcf[1].aifs * 9 + 10) << 12) | | ||
111 | ((ar->edcf[2].aifs * 9 + 10) << 24)); | ||
112 | ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_AIFS, | ||
113 | ((ar->edcf[2].aifs * 9 + 10) >> 8) | | ||
114 | ((ar->edcf[3].aifs * 9 + 10) << 4) | | ||
115 | ((ar->edcf[4].aifs * 9 + 10) << 16)); | ||
116 | |||
117 | ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP, | ||
118 | ar->edcf[0].txop | ar->edcf[1].txop << 16); | ||
119 | ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP, | ||
120 | ar->edcf[2].txop | ar->edcf[3].txop << 16); | ||
121 | |||
122 | ar9170_regwrite_finish(); | ||
123 | |||
124 | return ar9170_regwrite_result(); | ||
125 | } | ||
126 | |||
127 | static int ar9170_set_ampdu_density(struct ar9170 *ar, u8 mpdudensity) | ||
128 | { | ||
129 | u32 val; | ||
130 | |||
131 | /* don't allow AMPDU density > 8us */ | ||
132 | if (mpdudensity > 6) | ||
133 | return -EINVAL; | ||
134 | |||
135 | /* Watch out! Otus uses slightly different density values. */ | ||
136 | val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0); | ||
137 | |||
138 | ar9170_regwrite_begin(ar); | ||
139 | ar9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, val); | ||
140 | ar9170_regwrite_finish(); | ||
141 | |||
142 | return ar9170_regwrite_result(); | ||
143 | } | ||
144 | |||
145 | int ar9170_init_mac(struct ar9170 *ar) | ||
146 | { | ||
147 | ar9170_regwrite_begin(ar); | ||
148 | |||
149 | ar9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40); | ||
150 | |||
151 | ar9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0); | ||
152 | |||
153 | /* enable MMIC */ | ||
154 | ar9170_regwrite(AR9170_MAC_REG_SNIFFER, | ||
155 | AR9170_MAC_REG_SNIFFER_DEFAULTS); | ||
156 | |||
157 | ar9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80); | ||
158 | |||
159 | ar9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70); | ||
160 | ar9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000); | ||
161 | ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10); | ||
162 | |||
163 | /* CF-END mode */ | ||
164 | ar9170_regwrite(0x1c3b2c, 0x19000000); | ||
165 | |||
166 | /* NAV protects ACK only (in TXOP) */ | ||
167 | ar9170_regwrite(0x1c3b38, 0x201); | ||
168 | |||
169 | /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */ | ||
170 | /* OTUS set AM to 0x1 */ | ||
171 | ar9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170); | ||
172 | |||
173 | ar9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105); | ||
174 | |||
175 | /* AGG test code*/ | ||
176 | /* Aggregation MAX number and timeout */ | ||
177 | ar9170_regwrite(0x1c3b9c, 0x10000a); | ||
178 | |||
179 | ar9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER, | ||
180 | AR9170_MAC_REG_FTF_DEFAULTS); | ||
181 | |||
182 | /* Enable deaggregator, response in sniffer mode */ | ||
183 | ar9170_regwrite(0x1c3c40, 0x1 | 1<<30); | ||
184 | |||
185 | /* rate sets */ | ||
186 | ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f); | ||
187 | ar9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f); | ||
188 | ar9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x10b01bb); | ||
189 | |||
190 | /* MIMO response control */ | ||
191 | ar9170_regwrite(0x1c3694, 0x4003C1E);/* bit 26~28 otus-AM */ | ||
192 | |||
193 | /* switch MAC to OTUS interface */ | ||
194 | ar9170_regwrite(0x1c3600, 0x3); | ||
195 | |||
196 | ar9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff); | ||
197 | |||
198 | /* set PHY register read timeout (??) */ | ||
199 | ar9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008); | ||
200 | |||
201 | /* Disable Rx TimeOut, workaround for BB. */ | ||
202 | ar9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0); | ||
203 | |||
204 | /* Set CPU clock frequency to 88/80MHz */ | ||
205 | ar9170_regwrite(AR9170_PWR_REG_CLOCK_SEL, | ||
206 | AR9170_PWR_CLK_AHB_80_88MHZ | | ||
207 | AR9170_PWR_CLK_DAC_160_INV_DLY); | ||
208 | |||
209 | /* Set WLAN DMA interrupt mode: generate int per packet */ | ||
210 | ar9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011); | ||
211 | |||
212 | ar9170_regwrite(AR9170_MAC_REG_FCS_SELECT, | ||
213 | AR9170_MAC_FCS_FIFO_PROT); | ||
214 | |||
215 | /* Disables the CF_END frame, undocumented register */ | ||
216 | ar9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND, | ||
217 | 0x141E0F48); | ||
218 | |||
219 | ar9170_regwrite_finish(); | ||
220 | |||
221 | return ar9170_regwrite_result(); | ||
222 | } | ||
223 | |||
224 | static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac) | ||
225 | { | ||
226 | static const u8 zero[ETH_ALEN] = { 0 }; | ||
227 | |||
228 | if (!mac) | ||
229 | mac = zero; | ||
230 | |||
231 | ar9170_regwrite_begin(ar); | ||
232 | |||
233 | ar9170_regwrite(reg, get_unaligned_le32(mac)); | ||
234 | ar9170_regwrite(reg + 4, get_unaligned_le16(mac + 4)); | ||
235 | |||
236 | ar9170_regwrite_finish(); | ||
237 | |||
238 | return ar9170_regwrite_result(); | ||
239 | } | ||
240 | |||
241 | int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hash) | ||
242 | { | ||
243 | int err; | ||
244 | |||
245 | ar9170_regwrite_begin(ar); | ||
246 | ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32); | ||
247 | ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash); | ||
248 | ar9170_regwrite_finish(); | ||
249 | err = ar9170_regwrite_result(); | ||
250 | if (err) | ||
251 | return err; | ||
252 | |||
253 | ar->cur_mc_hash = mc_hash; | ||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter) | ||
258 | { | ||
259 | int err; | ||
260 | |||
261 | err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER, filter); | ||
262 | if (err) | ||
263 | return err; | ||
264 | |||
265 | ar->cur_filter = filter; | ||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static int ar9170_set_promiscouous(struct ar9170 *ar) | ||
270 | { | ||
271 | u32 encr_mode, sniffer; | ||
272 | int err; | ||
273 | |||
274 | err = ar9170_read_reg(ar, AR9170_MAC_REG_SNIFFER, &sniffer); | ||
275 | if (err) | ||
276 | return err; | ||
277 | |||
278 | err = ar9170_read_reg(ar, AR9170_MAC_REG_ENCRYPTION, &encr_mode); | ||
279 | if (err) | ||
280 | return err; | ||
281 | |||
282 | if (ar->sniffer_enabled) { | ||
283 | sniffer |= AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC; | ||
284 | |||
285 | /* | ||
286 | * Rx decryption works in place. | ||
287 | * | ||
288 | * If we don't disable it, the hardware will render all | ||
289 | * encrypted frames which are encrypted with an unknown | ||
290 | * key useless. | ||
291 | */ | ||
292 | |||
293 | encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE; | ||
294 | ar->sniffer_enabled = true; | ||
295 | } else { | ||
296 | sniffer &= ~AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC; | ||
297 | |||
298 | if (ar->rx_software_decryption) | ||
299 | encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE; | ||
300 | else | ||
301 | encr_mode &= ~AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE; | ||
302 | } | ||
303 | |||
304 | ar9170_regwrite_begin(ar); | ||
305 | ar9170_regwrite(AR9170_MAC_REG_ENCRYPTION, encr_mode); | ||
306 | ar9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer); | ||
307 | ar9170_regwrite_finish(); | ||
308 | |||
309 | return ar9170_regwrite_result(); | ||
310 | } | ||
311 | |||
312 | int ar9170_set_operating_mode(struct ar9170 *ar) | ||
313 | { | ||
314 | struct ath_common *common = &ar->common; | ||
315 | u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS; | ||
316 | u8 *mac_addr, *bssid; | ||
317 | int err; | ||
318 | |||
319 | if (ar->vif) { | ||
320 | mac_addr = common->macaddr; | ||
321 | bssid = common->curbssid; | ||
322 | |||
323 | switch (ar->vif->type) { | ||
324 | case NL80211_IFTYPE_MESH_POINT: | ||
325 | case NL80211_IFTYPE_ADHOC: | ||
326 | pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS; | ||
327 | break; | ||
328 | case NL80211_IFTYPE_AP: | ||
329 | pm_mode |= AR9170_MAC_REG_POWERMGT_AP; | ||
330 | break; | ||
331 | case NL80211_IFTYPE_WDS: | ||
332 | pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS; | ||
333 | break; | ||
334 | case NL80211_IFTYPE_MONITOR: | ||
335 | ar->sniffer_enabled = true; | ||
336 | ar->rx_software_decryption = true; | ||
337 | break; | ||
338 | default: | ||
339 | pm_mode |= AR9170_MAC_REG_POWERMGT_STA; | ||
340 | break; | ||
341 | } | ||
342 | } else { | ||
343 | mac_addr = NULL; | ||
344 | bssid = NULL; | ||
345 | } | ||
346 | |||
347 | err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr); | ||
348 | if (err) | ||
349 | return err; | ||
350 | |||
351 | err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid); | ||
352 | if (err) | ||
353 | return err; | ||
354 | |||
355 | err = ar9170_set_promiscouous(ar); | ||
356 | if (err) | ||
357 | return err; | ||
358 | |||
359 | /* set AMPDU density to 8us. */ | ||
360 | err = ar9170_set_ampdu_density(ar, 6); | ||
361 | if (err) | ||
362 | return err; | ||
363 | |||
364 | ar9170_regwrite_begin(ar); | ||
365 | |||
366 | ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode); | ||
367 | ar9170_regwrite_finish(); | ||
368 | |||
369 | return ar9170_regwrite_result(); | ||
370 | } | ||
371 | |||
372 | int ar9170_set_hwretry_limit(struct ar9170 *ar, unsigned int max_retry) | ||
373 | { | ||
374 | u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111); | ||
375 | |||
376 | return ar9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp); | ||
377 | } | ||
378 | |||
379 | int ar9170_set_beacon_timers(struct ar9170 *ar) | ||
380 | { | ||
381 | u32 v = 0; | ||
382 | u32 pretbtt = 0; | ||
383 | |||
384 | if (ar->vif) { | ||
385 | v |= ar->vif->bss_conf.beacon_int; | ||
386 | |||
387 | if (ar->enable_beacon) { | ||
388 | switch (ar->vif->type) { | ||
389 | case NL80211_IFTYPE_MESH_POINT: | ||
390 | case NL80211_IFTYPE_ADHOC: | ||
391 | v |= BIT(25); | ||
392 | break; | ||
393 | case NL80211_IFTYPE_AP: | ||
394 | v |= BIT(24); | ||
395 | pretbtt = (ar->vif->bss_conf.beacon_int - 6) << | ||
396 | 16; | ||
397 | break; | ||
398 | default: | ||
399 | break; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | v |= ar->vif->bss_conf.dtim_period << 16; | ||
404 | } | ||
405 | |||
406 | ar9170_regwrite_begin(ar); | ||
407 | ar9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt); | ||
408 | ar9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v); | ||
409 | ar9170_regwrite_finish(); | ||
410 | return ar9170_regwrite_result(); | ||
411 | } | ||
412 | |||
413 | int ar9170_update_beacon(struct ar9170 *ar) | ||
414 | { | ||
415 | struct sk_buff *skb; | ||
416 | __le32 *data, *old = NULL; | ||
417 | u32 word; | ||
418 | int i; | ||
419 | |||
420 | skb = ieee80211_beacon_get(ar->hw, ar->vif); | ||
421 | if (!skb) | ||
422 | return -ENOMEM; | ||
423 | |||
424 | data = (__le32 *)skb->data; | ||
425 | if (ar->beacon) | ||
426 | old = (__le32 *)ar->beacon->data; | ||
427 | |||
428 | ar9170_regwrite_begin(ar); | ||
429 | for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) { | ||
430 | /* | ||
431 | * XXX: This accesses beyond skb data for up | ||
432 | * to the last 3 bytes!! | ||
433 | */ | ||
434 | |||
435 | if (old && (data[i] == old[i])) | ||
436 | continue; | ||
437 | |||
438 | word = le32_to_cpu(data[i]); | ||
439 | ar9170_regwrite(AR9170_BEACON_BUFFER_ADDRESS + 4 * i, word); | ||
440 | } | ||
441 | |||
442 | /* XXX: use skb->cb info */ | ||
443 | if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) | ||
444 | ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP, | ||
445 | ((skb->len + 4) << (3 + 16)) + 0x0400); | ||
446 | else | ||
447 | ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP, | ||
448 | ((skb->len + 4) << 16) + 0x001b); | ||
449 | |||
450 | ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4); | ||
451 | ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS); | ||
452 | ar9170_regwrite(AR9170_MAC_REG_BCN_CTRL, 1); | ||
453 | |||
454 | ar9170_regwrite_finish(); | ||
455 | |||
456 | dev_kfree_skb(ar->beacon); | ||
457 | ar->beacon = skb; | ||
458 | |||
459 | return ar9170_regwrite_result(); | ||
460 | } | ||
461 | |||
462 | void ar9170_new_beacon(struct work_struct *work) | ||
463 | { | ||
464 | struct ar9170 *ar = container_of(work, struct ar9170, | ||
465 | beacon_work); | ||
466 | struct sk_buff *skb; | ||
467 | |||
468 | if (unlikely(!IS_STARTED(ar))) | ||
469 | return ; | ||
470 | |||
471 | mutex_lock(&ar->mutex); | ||
472 | |||
473 | if (!ar->vif) | ||
474 | goto out; | ||
475 | |||
476 | ar9170_update_beacon(ar); | ||
477 | |||
478 | rcu_read_lock(); | ||
479 | while ((skb = ieee80211_get_buffered_bc(ar->hw, ar->vif))) | ||
480 | ar9170_op_tx(ar->hw, skb); | ||
481 | |||
482 | rcu_read_unlock(); | ||
483 | |||
484 | out: | ||
485 | mutex_unlock(&ar->mutex); | ||
486 | } | ||
487 | |||
488 | int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype, | ||
489 | u8 keyidx, u8 *keydata, int keylen) | ||
490 | { | ||
491 | __le32 vals[7]; | ||
492 | static const u8 bcast[ETH_ALEN] = | ||
493 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | ||
494 | u8 dummy; | ||
495 | |||
496 | mac = mac ? : bcast; | ||
497 | |||
498 | vals[0] = cpu_to_le32((keyidx << 16) + id); | ||
499 | vals[1] = cpu_to_le32(mac[1] << 24 | mac[0] << 16 | ktype); | ||
500 | vals[2] = cpu_to_le32(mac[5] << 24 | mac[4] << 16 | | ||
501 | mac[3] << 8 | mac[2]); | ||
502 | memset(&vals[3], 0, 16); | ||
503 | if (keydata) | ||
504 | memcpy(&vals[3], keydata, keylen); | ||
505 | |||
506 | return ar->exec_cmd(ar, AR9170_CMD_EKEY, | ||
507 | sizeof(vals), (u8 *)vals, | ||
508 | 1, &dummy); | ||
509 | } | ||
510 | |||
511 | int ar9170_disable_key(struct ar9170 *ar, u8 id) | ||
512 | { | ||
513 | __le32 val = cpu_to_le32(id); | ||
514 | u8 dummy; | ||
515 | |||
516 | return ar->exec_cmd(ar, AR9170_CMD_EKEY, | ||
517 | sizeof(val), (u8 *)&val, | ||
518 | 1, &dummy); | ||
519 | } | ||
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c deleted file mode 100644 index ccc2edaaeda..00000000000 --- a/drivers/net/wireless/ath/ar9170/main.c +++ /dev/null | |||
@@ -1,2190 +0,0 @@ | |||
1 | /* | ||
2 | * Atheros AR9170 driver | ||
3 | * | ||
4 | * mac80211 interaction code | ||
5 | * | ||
6 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | ||
7 | * Copyright 2009, Christian Lamparter <chunkeey@web.de> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; see the file COPYING. If not, see | ||
21 | * http://www.gnu.org/licenses/. | ||
22 | * | ||
23 | * This file incorporates work covered by the following copyright and | ||
24 | * permission notice: | ||
25 | * Copyright (c) 2007-2008 Atheros Communications, Inc. | ||
26 | * | ||
27 | * Permission to use, copy, modify, and/or distribute this software for any | ||
28 | * purpose with or without fee is hereby granted, provided that the above | ||
29 | * copyright notice and this permission notice appear in all copies. | ||
30 | * | ||
31 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
32 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
33 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
34 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
35 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
36 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
37 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
38 | */ | ||
39 | |||
40 | #include <linux/init.h> | ||
41 | #include <linux/slab.h> | ||
42 | #include <linux/module.h> | ||
43 | #include <linux/etherdevice.h> | ||
44 | #include <net/mac80211.h> | ||
45 | #include "ar9170.h" | ||
46 | #include "hw.h" | ||
47 | #include "cmd.h" | ||
48 | |||
49 | static int modparam_nohwcrypt; | ||
50 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | ||
51 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | ||
52 | |||
53 | #define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \ | ||
54 | .bitrate = (_bitrate), \ | ||
55 | .flags = (_flags), \ | ||
56 | .hw_value = (_hw_rate) | (_txpidx) << 4, \ | ||
57 | } | ||
58 | |||
59 | static struct ieee80211_rate __ar9170_ratetable[] = { | ||
60 | RATE(10, 0, 0, 0), | ||
61 | RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE), | ||
62 | RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE), | ||
63 | RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE), | ||
64 | RATE(60, 0xb, 0, 0), | ||
65 | RATE(90, 0xf, 0, 0), | ||
66 | RATE(120, 0xa, 0, 0), | ||
67 | RATE(180, 0xe, 0, 0), | ||
68 | RATE(240, 0x9, 0, 0), | ||
69 | RATE(360, 0xd, 1, 0), | ||
70 | RATE(480, 0x8, 2, 0), | ||
71 | RATE(540, 0xc, 3, 0), | ||
72 | }; | ||
73 | #undef RATE | ||
74 | |||
75 | #define ar9170_g_ratetable (__ar9170_ratetable + 0) | ||
76 | #define ar9170_g_ratetable_size 12 | ||
77 | #define ar9170_a_ratetable (__ar9170_ratetable + 4) | ||
78 | #define ar9170_a_ratetable_size 8 | ||
79 | |||
80 | /* | ||
81 | * NB: The hw_value is used as an index into the ar9170_phy_freq_params | ||
82 | * array in phy.c so that we don't have to do frequency lookups! | ||
83 | */ | ||
84 | #define CHAN(_freq, _idx) { \ | ||
85 | .center_freq = (_freq), \ | ||
86 | .hw_value = (_idx), \ | ||
87 | .max_power = 18, /* XXX */ \ | ||
88 | } | ||
89 | |||
90 | static struct ieee80211_channel ar9170_2ghz_chantable[] = { | ||
91 | CHAN(2412, 0), | ||
92 | CHAN(2417, 1), | ||
93 | CHAN(2422, 2), | ||
94 | CHAN(2427, 3), | ||
95 | CHAN(2432, 4), | ||
96 | CHAN(2437, 5), | ||
97 | CHAN(2442, 6), | ||
98 | CHAN(2447, 7), | ||
99 | CHAN(2452, 8), | ||
100 | CHAN(2457, 9), | ||
101 | CHAN(2462, 10), | ||
102 | CHAN(2467, 11), | ||
103 | CHAN(2472, 12), | ||
104 | CHAN(2484, 13), | ||
105 | }; | ||
106 | |||
107 | static struct ieee80211_channel ar9170_5ghz_chantable[] = { | ||
108 | CHAN(4920, 14), | ||
109 | CHAN(4940, 15), | ||
110 | CHAN(4960, 16), | ||
111 | CHAN(4980, 17), | ||
112 | CHAN(5040, 18), | ||
113 | CHAN(5060, 19), | ||
114 | CHAN(5080, 20), | ||
115 | CHAN(5180, 21), | ||
116 | CHAN(5200, 22), | ||
117 | CHAN(5220, 23), | ||
118 | CHAN(5240, 24), | ||
119 | CHAN(5260, 25), | ||
120 | CHAN(5280, 26), | ||
121 | CHAN(5300, 27), | ||
122 | CHAN(5320, 28), | ||
123 | CHAN(5500, 29), | ||
124 | CHAN(5520, 30), | ||
125 | CHAN(5540, 31), | ||
126 | CHAN(5560, 32), | ||
127 | CHAN(5580, 33), | ||
128 | CHAN(5600, 34), | ||
129 | CHAN(5620, 35), | ||
130 | CHAN(5640, 36), | ||
131 | CHAN(5660, 37), | ||
132 | CHAN(5680, 38), | ||
133 | CHAN(5700, 39), | ||
134 | CHAN(5745, 40), | ||
135 | CHAN(5765, 41), | ||
136 | CHAN(5785, 42), | ||
137 | CHAN(5805, 43), | ||
138 | CHAN(5825, 44), | ||
139 | CHAN(5170, 45), | ||
140 | CHAN(5190, 46), | ||
141 | CHAN(5210, 47), | ||
142 | CHAN(5230, 48), | ||
143 | }; | ||
144 | #undef CHAN | ||
145 | |||
146 | #define AR9170_HT_CAP \ | ||
147 | { \ | ||
148 | .ht_supported = true, \ | ||
149 | .cap = IEEE80211_HT_CAP_MAX_AMSDU | \ | ||
150 | IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \ | ||
151 | IEEE80211_HT_CAP_SGI_40 | \ | ||
152 | IEEE80211_HT_CAP_GRN_FLD | \ | ||
153 | IEEE80211_HT_CAP_DSSSCCK40 | \ | ||
154 | IEEE80211_HT_CAP_SM_PS, \ | ||
155 | .ampdu_factor = 3, \ | ||
156 | .ampdu_density = 6, \ | ||
157 | .mcs = { \ | ||
158 | .rx_mask = { 0xff, 0xff, 0, 0, 0x1, 0, 0, 0, 0, 0, }, \ | ||
159 | .rx_highest = cpu_to_le16(300), \ | ||
160 | .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ | ||
161 | }, \ | ||
162 | } | ||
163 | |||
164 | static struct ieee80211_supported_band ar9170_band_2GHz = { | ||
165 | .channels = ar9170_2ghz_chantable, | ||
166 | .n_channels = ARRAY_SIZE(ar9170_2ghz_chantable), | ||
167 | .bitrates = ar9170_g_ratetable, | ||
168 | .n_bitrates = ar9170_g_ratetable_size, | ||
169 | .ht_cap = AR9170_HT_CAP, | ||
170 | }; | ||
171 | |||
172 | static struct ieee80211_supported_band ar9170_band_5GHz = { | ||
173 | .channels = ar9170_5ghz_chantable, | ||
174 | .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable), | ||
175 | .bitrates = ar9170_a_ratetable, | ||
176 | .n_bitrates = ar9170_a_ratetable_size, | ||
177 | .ht_cap = AR9170_HT_CAP, | ||
178 | }; | ||
179 | |||
180 | static void ar9170_tx(struct ar9170 *ar); | ||
181 | |||
182 | static inline u16 ar9170_get_seq_h(struct ieee80211_hdr *hdr) | ||
183 | { | ||
184 | return le16_to_cpu(hdr->seq_ctrl) >> 4; | ||
185 | } | ||
186 | |||
187 | static inline u16 ar9170_get_seq(struct sk_buff *skb) | ||
188 | { | ||
189 | struct ar9170_tx_control *txc = (void *) skb->data; | ||
190 | return ar9170_get_seq_h((void *) txc->frame_data); | ||
191 | } | ||
192 | |||
193 | #ifdef AR9170_QUEUE_DEBUG | ||
194 | static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) | ||
195 | { | ||
196 | struct ar9170_tx_control *txc = (void *) skb->data; | ||
197 | struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); | ||
198 | struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; | ||
199 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; | ||
200 | |||
201 | wiphy_debug(ar->hw->wiphy, | ||
202 | "=> FRAME [skb:%p, q:%d, DA:[%pM] s:%d " | ||
203 | "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", | ||
204 | skb, skb_get_queue_mapping(skb), | ||
205 | ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr), | ||
206 | le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), | ||
207 | jiffies_to_msecs(arinfo->timeout - jiffies)); | ||
208 | } | ||
209 | |||
210 | static void __ar9170_dump_txqueue(struct ar9170 *ar, | ||
211 | struct sk_buff_head *queue) | ||
212 | { | ||
213 | struct sk_buff *skb; | ||
214 | int i = 0; | ||
215 | |||
216 | printk(KERN_DEBUG "---[ cut here ]---\n"); | ||
217 | wiphy_debug(ar->hw->wiphy, "%d entries in queue.\n", | ||
218 | skb_queue_len(queue)); | ||
219 | |||
220 | skb_queue_walk(queue, skb) { | ||
221 | printk(KERN_DEBUG "index:%d =>\n", i++); | ||
222 | ar9170_print_txheader(ar, skb); | ||
223 | } | ||
224 | if (i != skb_queue_len(queue)) | ||
225 | printk(KERN_DEBUG "WARNING: queue frame counter " | ||
226 | "mismatch %d != %d\n", skb_queue_len(queue), i); | ||
227 | printk(KERN_DEBUG "---[ end ]---\n"); | ||
228 | } | ||
229 | #endif /* AR9170_QUEUE_DEBUG */ | ||
230 | |||
231 | #ifdef AR9170_QUEUE_DEBUG | ||
232 | static void ar9170_dump_txqueue(struct ar9170 *ar, | ||
233 | struct sk_buff_head *queue) | ||
234 | { | ||
235 | unsigned long flags; | ||
236 | |||
237 | spin_lock_irqsave(&queue->lock, flags); | ||
238 | __ar9170_dump_txqueue(ar, queue); | ||
239 | spin_unlock_irqrestore(&queue->lock, flags); | ||
240 | } | ||
241 | #endif /* AR9170_QUEUE_DEBUG */ | ||
242 | |||
243 | #ifdef AR9170_QUEUE_STOP_DEBUG | ||
244 | static void __ar9170_dump_txstats(struct ar9170 *ar) | ||
245 | { | ||
246 | int i; | ||
247 | |||
248 | wiphy_debug(ar->hw->wiphy, "QoS queue stats\n"); | ||
249 | |||
250 | for (i = 0; i < __AR9170_NUM_TXQ; i++) | ||
251 | wiphy_debug(ar->hw->wiphy, | ||
252 | "queue:%d limit:%d len:%d waitack:%d stopped:%d\n", | ||
253 | i, ar->tx_stats[i].limit, ar->tx_stats[i].len, | ||
254 | skb_queue_len(&ar->tx_status[i]), | ||
255 | ieee80211_queue_stopped(ar->hw, i)); | ||
256 | } | ||
257 | #endif /* AR9170_QUEUE_STOP_DEBUG */ | ||
258 | |||
259 | /* caller must guarantee exclusive access for _bin_ queue. */ | ||
260 | static void ar9170_recycle_expired(struct ar9170 *ar, | ||
261 | struct sk_buff_head *queue, | ||
262 | struct sk_buff_head *bin) | ||
263 | { | ||
264 | struct sk_buff *skb, *old = NULL; | ||
265 | unsigned long flags; | ||
266 | |||
267 | spin_lock_irqsave(&queue->lock, flags); | ||
268 | while ((skb = skb_peek(queue))) { | ||
269 | struct ieee80211_tx_info *txinfo; | ||
270 | struct ar9170_tx_info *arinfo; | ||
271 | |||
272 | txinfo = IEEE80211_SKB_CB(skb); | ||
273 | arinfo = (void *) txinfo->rate_driver_data; | ||
274 | |||
275 | if (time_is_before_jiffies(arinfo->timeout)) { | ||
276 | #ifdef AR9170_QUEUE_DEBUG | ||
277 | wiphy_debug(ar->hw->wiphy, | ||
278 | "[%ld > %ld] frame expired => recycle\n", | ||
279 | jiffies, arinfo->timeout); | ||
280 | ar9170_print_txheader(ar, skb); | ||
281 | #endif /* AR9170_QUEUE_DEBUG */ | ||
282 | __skb_unlink(skb, queue); | ||
283 | __skb_queue_tail(bin, skb); | ||
284 | } else { | ||
285 | break; | ||
286 | } | ||
287 | |||
288 | if (unlikely(old == skb)) { | ||
289 | /* bail out - queue is shot. */ | ||
290 | |||
291 | WARN_ON(1); | ||
292 | break; | ||
293 | } | ||
294 | old = skb; | ||
295 | } | ||
296 | spin_unlock_irqrestore(&queue->lock, flags); | ||
297 | } | ||
298 | |||
299 | static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, | ||
300 | u16 tx_status) | ||
301 | { | ||
302 | struct ieee80211_tx_info *txinfo; | ||
303 | unsigned int retries = 0; | ||
304 | |||
305 | txinfo = IEEE80211_SKB_CB(skb); | ||
306 | ieee80211_tx_info_clear_status(txinfo); | ||
307 | |||
308 | switch (tx_status) { | ||
309 | case AR9170_TX_STATUS_RETRY: | ||
310 | retries = 2; | ||
311 | case AR9170_TX_STATUS_COMPLETE: | ||
312 | txinfo->flags |= IEEE80211_TX_STAT_ACK; | ||
313 | break; | ||
314 | |||
315 | case AR9170_TX_STATUS_FAILED: | ||
316 | retries = ar->hw->conf.long_frame_max_tx_count; | ||
317 | break; | ||
318 | |||
319 | default: | ||
320 | wiphy_err(ar->hw->wiphy, | ||
321 | "invalid tx_status response (%x)\n", tx_status); | ||
322 | break; | ||
323 | } | ||
324 | |||
325 | txinfo->status.rates[0].count = retries + 1; | ||
326 | skb_pull(skb, sizeof(struct ar9170_tx_control)); | ||
327 | ieee80211_tx_status_irqsafe(ar->hw, skb); | ||
328 | } | ||
329 | |||
330 | void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) | ||
331 | { | ||
332 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
333 | struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data; | ||
334 | unsigned int queue = skb_get_queue_mapping(skb); | ||
335 | unsigned long flags; | ||
336 | |||
337 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | ||
338 | ar->tx_stats[queue].len--; | ||
339 | |||
340 | if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) { | ||
341 | #ifdef AR9170_QUEUE_STOP_DEBUG | ||
342 | wiphy_debug(ar->hw->wiphy, "wake queue %d\n", queue); | ||
343 | __ar9170_dump_txstats(ar); | ||
344 | #endif /* AR9170_QUEUE_STOP_DEBUG */ | ||
345 | ieee80211_wake_queue(ar->hw, queue); | ||
346 | } | ||
347 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
348 | |||
349 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) { | ||
350 | ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); | ||
351 | } else { | ||
352 | arinfo->timeout = jiffies + | ||
353 | msecs_to_jiffies(AR9170_TX_TIMEOUT); | ||
354 | |||
355 | skb_queue_tail(&ar->tx_status[queue], skb); | ||
356 | } | ||
357 | |||
358 | if (!ar->tx_stats[queue].len && | ||
359 | !skb_queue_empty(&ar->tx_pending[queue])) { | ||
360 | ar9170_tx(ar); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, | ||
365 | const u8 *mac, | ||
366 | struct sk_buff_head *queue, | ||
367 | const u32 rate) | ||
368 | { | ||
369 | unsigned long flags; | ||
370 | struct sk_buff *skb; | ||
371 | |||
372 | /* | ||
373 | * Unfortunately, the firmware does not tell to which (queued) frame | ||
374 | * this transmission status report belongs to. | ||
375 | * | ||
376 | * So we have to make risky guesses - with the scarce information | ||
377 | * the firmware provided (-> destination MAC, and phy_control) - | ||
378 | * and hope that we picked the right one... | ||
379 | */ | ||
380 | |||
381 | spin_lock_irqsave(&queue->lock, flags); | ||
382 | skb_queue_walk(queue, skb) { | ||
383 | struct ar9170_tx_control *txc = (void *) skb->data; | ||
384 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; | ||
385 | u32 r; | ||
386 | |||
387 | if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) { | ||
388 | #ifdef AR9170_QUEUE_DEBUG | ||
389 | wiphy_debug(ar->hw->wiphy, | ||
390 | "skip frame => DA %pM != %pM\n", | ||
391 | mac, ieee80211_get_DA(hdr)); | ||
392 | ar9170_print_txheader(ar, skb); | ||
393 | #endif /* AR9170_QUEUE_DEBUG */ | ||
394 | continue; | ||
395 | } | ||
396 | |||
397 | r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >> | ||
398 | AR9170_TX_PHY_MCS_SHIFT; | ||
399 | |||
400 | if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) { | ||
401 | #ifdef AR9170_QUEUE_DEBUG | ||
402 | wiphy_debug(ar->hw->wiphy, | ||
403 | "skip frame => rate %d != %d\n", rate, r); | ||
404 | ar9170_print_txheader(ar, skb); | ||
405 | #endif /* AR9170_QUEUE_DEBUG */ | ||
406 | continue; | ||
407 | } | ||
408 | |||
409 | __skb_unlink(skb, queue); | ||
410 | spin_unlock_irqrestore(&queue->lock, flags); | ||
411 | return skb; | ||
412 | } | ||
413 | |||
414 | #ifdef AR9170_QUEUE_DEBUG | ||
415 | wiphy_err(ar->hw->wiphy, | ||
416 | "ESS:[%pM] does not have any outstanding frames in queue.\n", | ||
417 | mac); | ||
418 | __ar9170_dump_txqueue(ar, queue); | ||
419 | #endif /* AR9170_QUEUE_DEBUG */ | ||
420 | spin_unlock_irqrestore(&queue->lock, flags); | ||
421 | |||
422 | return NULL; | ||
423 | } | ||
424 | |||
425 | /* | ||
426 | * This worker tries to keeps an maintain tx_status queues. | ||
427 | * So we can guarantee that incoming tx_status reports are | ||
428 | * actually for a pending frame. | ||
429 | */ | ||
430 | |||
431 | static void ar9170_tx_janitor(struct work_struct *work) | ||
432 | { | ||
433 | struct ar9170 *ar = container_of(work, struct ar9170, | ||
434 | tx_janitor.work); | ||
435 | struct sk_buff_head waste; | ||
436 | unsigned int i; | ||
437 | bool resched = false; | ||
438 | |||
439 | if (unlikely(!IS_STARTED(ar))) | ||
440 | return ; | ||
441 | |||
442 | skb_queue_head_init(&waste); | ||
443 | |||
444 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { | ||
445 | #ifdef AR9170_QUEUE_DEBUG | ||
446 | wiphy_debug(ar->hw->wiphy, "garbage collector scans queue:%d\n", | ||
447 | i); | ||
448 | ar9170_dump_txqueue(ar, &ar->tx_pending[i]); | ||
449 | ar9170_dump_txqueue(ar, &ar->tx_status[i]); | ||
450 | #endif /* AR9170_QUEUE_DEBUG */ | ||
451 | |||
452 | ar9170_recycle_expired(ar, &ar->tx_status[i], &waste); | ||
453 | ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste); | ||
454 | skb_queue_purge(&waste); | ||
455 | |||
456 | if (!skb_queue_empty(&ar->tx_status[i]) || | ||
457 | !skb_queue_empty(&ar->tx_pending[i])) | ||
458 | resched = true; | ||
459 | } | ||
460 | |||
461 | if (!resched) | ||
462 | return; | ||
463 | |||
464 | ieee80211_queue_delayed_work(ar->hw, | ||
465 | &ar->tx_janitor, | ||
466 | msecs_to_jiffies(AR9170_JANITOR_DELAY)); | ||
467 | } | ||
468 | |||
469 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | ||
470 | { | ||
471 | struct ar9170_cmd_response *cmd = (void *) buf; | ||
472 | |||
473 | if ((cmd->type & 0xc0) != 0xc0) { | ||
474 | ar->callback_cmd(ar, len, buf); | ||
475 | return; | ||
476 | } | ||
477 | |||
478 | /* hardware event handlers */ | ||
479 | switch (cmd->type) { | ||
480 | case 0xc1: { | ||
481 | /* | ||
482 | * TX status notification: | ||
483 | * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1 | ||
484 | * | ||
485 | * XX always 81 | ||
486 | * YY always 00 | ||
487 | * M1-M6 is the MAC address | ||
488 | * R1-R4 is the transmit rate | ||
489 | * S1-S2 is the transmit status | ||
490 | */ | ||
491 | |||
492 | struct sk_buff *skb; | ||
493 | u32 phy = le32_to_cpu(cmd->tx_status.rate); | ||
494 | u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >> | ||
495 | AR9170_TX_PHY_QOS_SHIFT; | ||
496 | #ifdef AR9170_QUEUE_DEBUG | ||
497 | wiphy_debug(ar->hw->wiphy, | ||
498 | "recv tx_status for %pm, p:%08x, q:%d\n", | ||
499 | cmd->tx_status.dst, phy, q); | ||
500 | #endif /* AR9170_QUEUE_DEBUG */ | ||
501 | |||
502 | skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst, | ||
503 | &ar->tx_status[q], | ||
504 | AR9170_TX_INVALID_RATE); | ||
505 | if (unlikely(!skb)) | ||
506 | return ; | ||
507 | |||
508 | ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status)); | ||
509 | break; | ||
510 | } | ||
511 | |||
512 | case 0xc0: | ||
513 | /* | ||
514 | * pre-TBTT event | ||
515 | */ | ||
516 | if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP) | ||
517 | ieee80211_queue_work(ar->hw, &ar->beacon_work); | ||
518 | break; | ||
519 | |||
520 | case 0xc2: | ||
521 | /* | ||
522 | * (IBSS) beacon send notification | ||
523 | * bytes: 04 c2 XX YY B4 B3 B2 B1 | ||
524 | * | ||
525 | * XX always 80 | ||
526 | * YY always 00 | ||
527 | * B1-B4 "should" be the number of send out beacons. | ||
528 | */ | ||
529 | break; | ||
530 | |||
531 | case 0xc3: | ||
532 | /* End of Atim Window */ | ||
533 | break; | ||
534 | |||
535 | case 0xc4: | ||
536 | /* BlockACK bitmap */ | ||
537 | break; | ||
538 | |||
539 | case 0xc5: | ||
540 | /* BlockACK events */ | ||
541 | break; | ||
542 | |||
543 | case 0xc6: | ||
544 | /* Watchdog Interrupt */ | ||
545 | break; | ||
546 | |||
547 | case 0xc9: | ||
548 | /* retransmission issue / SIFS/EIFS collision ?! */ | ||
549 | break; | ||
550 | |||
551 | /* firmware debug */ | ||
552 | case 0xca: | ||
553 | printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, | ||
554 | (char *)buf + 4); | ||
555 | break; | ||
556 | case 0xcb: | ||
557 | len -= 4; | ||
558 | |||
559 | switch (len) { | ||
560 | case 1: | ||
561 | printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n", | ||
562 | *((char *)buf + 4)); | ||
563 | break; | ||
564 | case 2: | ||
565 | printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n", | ||
566 | le16_to_cpup((__le16 *)((char *)buf + 4))); | ||
567 | break; | ||
568 | case 4: | ||
569 | printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n", | ||
570 | le32_to_cpup((__le32 *)((char *)buf + 4))); | ||
571 | break; | ||
572 | case 8: | ||
573 | printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n", | ||
574 | (unsigned long)le64_to_cpup( | ||
575 | (__le64 *)((char *)buf + 4))); | ||
576 | break; | ||
577 | } | ||
578 | break; | ||
579 | case 0xcc: | ||
580 | print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE, | ||
581 | (char *)buf + 4, len - 4); | ||
582 | break; | ||
583 | |||
584 | default: | ||
585 | pr_info("received unhandled event %x\n", cmd->type); | ||
586 | print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); | ||
587 | break; | ||
588 | } | ||
589 | } | ||
590 | |||
591 | static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar) | ||
592 | { | ||
593 | memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head)); | ||
594 | ar->rx_mpdu.has_plcp = false; | ||
595 | } | ||
596 | |||
597 | int ar9170_nag_limiter(struct ar9170 *ar) | ||
598 | { | ||
599 | bool print_message; | ||
600 | |||
601 | /* | ||
602 | * we expect all sorts of errors in promiscuous mode. | ||
603 | * don't bother with it, it's OK! | ||
604 | */ | ||
605 | if (ar->sniffer_enabled) | ||
606 | return false; | ||
607 | |||
608 | /* | ||
609 | * only go for frequent errors! The hardware tends to | ||
610 | * do some stupid thing once in a while under load, in | ||
611 | * noisy environments or just for fun! | ||
612 | */ | ||
613 | if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit()) | ||
614 | print_message = true; | ||
615 | else | ||
616 | print_message = false; | ||
617 | |||
618 | /* reset threshold for "once in a while" */ | ||
619 | ar->bad_hw_nagger = jiffies + HZ / 4; | ||
620 | return print_message; | ||
621 | } | ||
622 | |||
623 | static int ar9170_rx_mac_status(struct ar9170 *ar, | ||
624 | struct ar9170_rx_head *head, | ||
625 | struct ar9170_rx_macstatus *mac, | ||
626 | struct ieee80211_rx_status *status) | ||
627 | { | ||
628 | u8 error, decrypt; | ||
629 | |||
630 | BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12); | ||
631 | BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4); | ||
632 | |||
633 | error = mac->error; | ||
634 | if (error & AR9170_RX_ERROR_MMIC) { | ||
635 | status->flag |= RX_FLAG_MMIC_ERROR; | ||
636 | error &= ~AR9170_RX_ERROR_MMIC; | ||
637 | } | ||
638 | |||
639 | if (error & AR9170_RX_ERROR_PLCP) { | ||
640 | status->flag |= RX_FLAG_FAILED_PLCP_CRC; | ||
641 | error &= ~AR9170_RX_ERROR_PLCP; | ||
642 | |||
643 | if (!(ar->filter_state & FIF_PLCPFAIL)) | ||
644 | return -EINVAL; | ||
645 | } | ||
646 | |||
647 | if (error & AR9170_RX_ERROR_FCS) { | ||
648 | status->flag |= RX_FLAG_FAILED_FCS_CRC; | ||
649 | error &= ~AR9170_RX_ERROR_FCS; | ||
650 | |||
651 | if (!(ar->filter_state & FIF_FCSFAIL)) | ||
652 | return -EINVAL; | ||
653 | } | ||
654 | |||
655 | decrypt = ar9170_get_decrypt_type(mac); | ||
656 | if (!(decrypt & AR9170_RX_ENC_SOFTWARE) && | ||
657 | decrypt != AR9170_ENC_ALG_NONE) | ||
658 | status->flag |= RX_FLAG_DECRYPTED; | ||
659 | |||
660 | /* ignore wrong RA errors */ | ||
661 | error &= ~AR9170_RX_ERROR_WRONG_RA; | ||
662 | |||
663 | if (error & AR9170_RX_ERROR_DECRYPT) { | ||
664 | error &= ~AR9170_RX_ERROR_DECRYPT; | ||
665 | /* | ||
666 | * Rx decryption is done in place, | ||
667 | * the original data is lost anyway. | ||
668 | */ | ||
669 | |||
670 | return -EINVAL; | ||
671 | } | ||
672 | |||
673 | /* drop any other error frames */ | ||
674 | if (unlikely(error)) { | ||
675 | /* TODO: update netdevice's RX dropped/errors statistics */ | ||
676 | |||
677 | if (ar9170_nag_limiter(ar)) | ||
678 | wiphy_debug(ar->hw->wiphy, | ||
679 | "received frame with suspicious error code (%#x).\n", | ||
680 | error); | ||
681 | |||
682 | return -EINVAL; | ||
683 | } | ||
684 | |||
685 | status->band = ar->channel->band; | ||
686 | status->freq = ar->channel->center_freq; | ||
687 | |||
688 | switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) { | ||
689 | case AR9170_RX_STATUS_MODULATION_CCK: | ||
690 | if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE) | ||
691 | status->flag |= RX_FLAG_SHORTPRE; | ||
692 | switch (head->plcp[0]) { | ||
693 | case 0x0a: | ||
694 | status->rate_idx = 0; | ||
695 | break; | ||
696 | case 0x14: | ||
697 | status->rate_idx = 1; | ||
698 | break; | ||
699 | case 0x37: | ||
700 | status->rate_idx = 2; | ||
701 | break; | ||
702 | case 0x6e: | ||
703 | status->rate_idx = 3; | ||
704 | break; | ||
705 | default: | ||
706 | if (ar9170_nag_limiter(ar)) | ||
707 | wiphy_err(ar->hw->wiphy, | ||
708 | "invalid plcp cck rate (%x).\n", | ||
709 | head->plcp[0]); | ||
710 | return -EINVAL; | ||
711 | } | ||
712 | break; | ||
713 | |||
714 | case AR9170_RX_STATUS_MODULATION_DUPOFDM: | ||
715 | case AR9170_RX_STATUS_MODULATION_OFDM: | ||
716 | switch (head->plcp[0] & 0xf) { | ||
717 | case 0xb: | ||
718 | status->rate_idx = 0; | ||
719 | break; | ||
720 | case 0xf: | ||
721 | status->rate_idx = 1; | ||
722 | break; | ||
723 | case 0xa: | ||
724 | status->rate_idx = 2; | ||
725 | break; | ||
726 | case 0xe: | ||
727 | status->rate_idx = 3; | ||
728 | break; | ||
729 | case 0x9: | ||
730 | status->rate_idx = 4; | ||
731 | break; | ||
732 | case 0xd: | ||
733 | status->rate_idx = 5; | ||
734 | break; | ||
735 | case 0x8: | ||
736 | status->rate_idx = 6; | ||
737 | break; | ||
738 | case 0xc: | ||
739 | status->rate_idx = 7; | ||
740 | break; | ||
741 | default: | ||
742 | if (ar9170_nag_limiter(ar)) | ||
743 | wiphy_err(ar->hw->wiphy, | ||
744 | "invalid plcp ofdm rate (%x).\n", | ||
745 | head->plcp[0]); | ||
746 | return -EINVAL; | ||
747 | } | ||
748 | if (status->band == IEEE80211_BAND_2GHZ) | ||
749 | status->rate_idx += 4; | ||
750 | break; | ||
751 | |||
752 | case AR9170_RX_STATUS_MODULATION_HT: | ||
753 | if (head->plcp[3] & 0x80) | ||
754 | status->flag |= RX_FLAG_40MHZ; | ||
755 | if (head->plcp[6] & 0x80) | ||
756 | status->flag |= RX_FLAG_SHORT_GI; | ||
757 | |||
758 | status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f); | ||
759 | status->flag |= RX_FLAG_HT; | ||
760 | break; | ||
761 | |||
762 | default: | ||
763 | if (ar9170_nag_limiter(ar)) | ||
764 | wiphy_err(ar->hw->wiphy, "invalid modulation\n"); | ||
765 | return -EINVAL; | ||
766 | } | ||
767 | |||
768 | return 0; | ||
769 | } | ||
770 | |||
771 | static void ar9170_rx_phy_status(struct ar9170 *ar, | ||
772 | struct ar9170_rx_phystatus *phy, | ||
773 | struct ieee80211_rx_status *status) | ||
774 | { | ||
775 | int i; | ||
776 | |||
777 | BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20); | ||
778 | |||
779 | for (i = 0; i < 3; i++) | ||
780 | if (phy->rssi[i] != 0x80) | ||
781 | status->antenna |= BIT(i); | ||
782 | |||
783 | /* post-process RSSI */ | ||
784 | for (i = 0; i < 7; i++) | ||
785 | if (phy->rssi[i] & 0x80) | ||
786 | phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f; | ||
787 | |||
788 | /* TODO: we could do something with phy_errors */ | ||
789 | status->signal = ar->noise[0] + phy->rssi_combined; | ||
790 | } | ||
791 | |||
792 | static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len) | ||
793 | { | ||
794 | struct sk_buff *skb; | ||
795 | int reserved = 0; | ||
796 | struct ieee80211_hdr *hdr = (void *) buf; | ||
797 | |||
798 | if (ieee80211_is_data_qos(hdr->frame_control)) { | ||
799 | u8 *qc = ieee80211_get_qos_ctl(hdr); | ||
800 | reserved += NET_IP_ALIGN; | ||
801 | |||
802 | if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) | ||
803 | reserved += NET_IP_ALIGN; | ||
804 | } | ||
805 | |||
806 | if (ieee80211_has_a4(hdr->frame_control)) | ||
807 | reserved += NET_IP_ALIGN; | ||
808 | |||
809 | reserved = 32 + (reserved & NET_IP_ALIGN); | ||
810 | |||
811 | skb = dev_alloc_skb(len + reserved); | ||
812 | if (likely(skb)) { | ||
813 | skb_reserve(skb, reserved); | ||
814 | memcpy(skb_put(skb, len), buf, len); | ||
815 | } | ||
816 | |||
817 | return skb; | ||
818 | } | ||
819 | |||
820 | /* | ||
821 | * If the frame alignment is right (or the kernel has | ||
822 | * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there | ||
823 | * is only a single MPDU in the USB frame, then we could | ||
824 | * submit to mac80211 the SKB directly. However, since | ||
825 | * there may be multiple packets in one SKB in stream | ||
826 | * mode, and we need to observe the proper ordering, | ||
827 | * this is non-trivial. | ||
828 | */ | ||
829 | |||
830 | static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) | ||
831 | { | ||
832 | struct ar9170_rx_head *head; | ||
833 | struct ar9170_rx_macstatus *mac; | ||
834 | struct ar9170_rx_phystatus *phy = NULL; | ||
835 | struct ieee80211_rx_status status; | ||
836 | struct sk_buff *skb; | ||
837 | int mpdu_len; | ||
838 | |||
839 | if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac)))) | ||
840 | return ; | ||
841 | |||
842 | /* Received MPDU */ | ||
843 | mpdu_len = len - sizeof(*mac); | ||
844 | |||
845 | mac = (void *)(buf + mpdu_len); | ||
846 | if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) { | ||
847 | /* this frame is too damaged and can't be used - drop it */ | ||
848 | |||
849 | return ; | ||
850 | } | ||
851 | |||
852 | switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) { | ||
853 | case AR9170_RX_STATUS_MPDU_FIRST: | ||
854 | /* first mpdu packet has the plcp header */ | ||
855 | if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) { | ||
856 | head = (void *) buf; | ||
857 | memcpy(&ar->rx_mpdu.plcp, (void *) buf, | ||
858 | sizeof(struct ar9170_rx_head)); | ||
859 | |||
860 | mpdu_len -= sizeof(struct ar9170_rx_head); | ||
861 | buf += sizeof(struct ar9170_rx_head); | ||
862 | ar->rx_mpdu.has_plcp = true; | ||
863 | } else { | ||
864 | if (ar9170_nag_limiter(ar)) | ||
865 | wiphy_err(ar->hw->wiphy, | ||
866 | "plcp info is clipped.\n"); | ||
867 | return ; | ||
868 | } | ||
869 | break; | ||
870 | |||
871 | case AR9170_RX_STATUS_MPDU_LAST: | ||
872 | /* last mpdu has a extra tail with phy status information */ | ||
873 | |||
874 | if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) { | ||
875 | mpdu_len -= sizeof(struct ar9170_rx_phystatus); | ||
876 | phy = (void *)(buf + mpdu_len); | ||
877 | } else { | ||
878 | if (ar9170_nag_limiter(ar)) | ||
879 | wiphy_err(ar->hw->wiphy, | ||
880 | "frame tail is clipped.\n"); | ||
881 | return ; | ||
882 | } | ||
883 | |||
884 | case AR9170_RX_STATUS_MPDU_MIDDLE: | ||
885 | /* middle mpdus are just data */ | ||
886 | if (unlikely(!ar->rx_mpdu.has_plcp)) { | ||
887 | if (!ar9170_nag_limiter(ar)) | ||
888 | return ; | ||
889 | |||
890 | wiphy_err(ar->hw->wiphy, | ||
891 | "rx stream did not start with a first_mpdu frame tag.\n"); | ||
892 | |||
893 | return ; | ||
894 | } | ||
895 | |||
896 | head = &ar->rx_mpdu.plcp; | ||
897 | break; | ||
898 | |||
899 | case AR9170_RX_STATUS_MPDU_SINGLE: | ||
900 | /* single mpdu - has plcp (head) and phy status (tail) */ | ||
901 | head = (void *) buf; | ||
902 | |||
903 | mpdu_len -= sizeof(struct ar9170_rx_head); | ||
904 | mpdu_len -= sizeof(struct ar9170_rx_phystatus); | ||
905 | |||
906 | buf += sizeof(struct ar9170_rx_head); | ||
907 | phy = (void *)(buf + mpdu_len); | ||
908 | break; | ||
909 | |||
910 | default: | ||
911 | BUG_ON(1); | ||
912 | break; | ||
913 | } | ||
914 | |||
915 | if (unlikely(mpdu_len < FCS_LEN)) | ||
916 | return ; | ||
917 | |||
918 | memset(&status, 0, sizeof(status)); | ||
919 | if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status))) | ||
920 | return ; | ||
921 | |||
922 | if (phy) | ||
923 | ar9170_rx_phy_status(ar, phy, &status); | ||
924 | |||
925 | skb = ar9170_rx_copy_data(buf, mpdu_len); | ||
926 | if (likely(skb)) { | ||
927 | memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); | ||
928 | ieee80211_rx_irqsafe(ar->hw, skb); | ||
929 | } | ||
930 | } | ||
931 | |||
932 | void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) | ||
933 | { | ||
934 | unsigned int i, tlen, resplen, wlen = 0, clen = 0; | ||
935 | u8 *tbuf, *respbuf; | ||
936 | |||
937 | tbuf = skb->data; | ||
938 | tlen = skb->len; | ||
939 | |||
940 | while (tlen >= 4) { | ||
941 | clen = tbuf[1] << 8 | tbuf[0]; | ||
942 | wlen = ALIGN(clen, 4); | ||
943 | |||
944 | /* check if this is stream has a valid tag.*/ | ||
945 | if (tbuf[2] != 0 || tbuf[3] != 0x4e) { | ||
946 | /* | ||
947 | * TODO: handle the highly unlikely event that the | ||
948 | * corrupted stream has the TAG at the right position. | ||
949 | */ | ||
950 | |||
951 | /* check if the frame can be repaired. */ | ||
952 | if (!ar->rx_failover_missing) { | ||
953 | /* this is no "short read". */ | ||
954 | if (ar9170_nag_limiter(ar)) { | ||
955 | wiphy_err(ar->hw->wiphy, | ||
956 | "missing tag!\n"); | ||
957 | goto err_telluser; | ||
958 | } else | ||
959 | goto err_silent; | ||
960 | } | ||
961 | |||
962 | if (ar->rx_failover_missing > tlen) { | ||
963 | if (ar9170_nag_limiter(ar)) { | ||
964 | wiphy_err(ar->hw->wiphy, | ||
965 | "possible multi stream corruption!\n"); | ||
966 | goto err_telluser; | ||
967 | } else | ||
968 | goto err_silent; | ||
969 | } | ||
970 | |||
971 | memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); | ||
972 | ar->rx_failover_missing -= tlen; | ||
973 | |||
974 | if (ar->rx_failover_missing <= 0) { | ||
975 | /* | ||
976 | * nested ar9170_rx call! | ||
977 | * termination is guaranteed, even when the | ||
978 | * combined frame also have a element with | ||
979 | * a bad tag. | ||
980 | */ | ||
981 | |||
982 | ar->rx_failover_missing = 0; | ||
983 | ar9170_rx(ar, ar->rx_failover); | ||
984 | |||
985 | skb_reset_tail_pointer(ar->rx_failover); | ||
986 | skb_trim(ar->rx_failover, 0); | ||
987 | } | ||
988 | |||
989 | return ; | ||
990 | } | ||
991 | |||
992 | /* check if stream is clipped */ | ||
993 | if (wlen > tlen - 4) { | ||
994 | if (ar->rx_failover_missing) { | ||
995 | /* TODO: handle double stream corruption. */ | ||
996 | if (ar9170_nag_limiter(ar)) { | ||
997 | wiphy_err(ar->hw->wiphy, | ||
998 | "double rx stream corruption!\n"); | ||
999 | goto err_telluser; | ||
1000 | } else | ||
1001 | goto err_silent; | ||
1002 | } | ||
1003 | |||
1004 | /* | ||
1005 | * save incomplete data set. | ||
1006 | * the firmware will resend the missing bits when | ||
1007 | * the rx - descriptor comes round again. | ||
1008 | */ | ||
1009 | |||
1010 | memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); | ||
1011 | ar->rx_failover_missing = clen - tlen; | ||
1012 | return ; | ||
1013 | } | ||
1014 | resplen = clen; | ||
1015 | respbuf = tbuf + 4; | ||
1016 | tbuf += wlen + 4; | ||
1017 | tlen -= wlen + 4; | ||
1018 | |||
1019 | i = 0; | ||
1020 | |||
1021 | /* weird thing, but this is the same in the original driver */ | ||
1022 | while (resplen > 2 && i < 12 && | ||
1023 | respbuf[0] == 0xff && respbuf[1] == 0xff) { | ||
1024 | i += 2; | ||
1025 | resplen -= 2; | ||
1026 | respbuf += 2; | ||
1027 | } | ||
1028 | |||
1029 | if (resplen < 4) | ||
1030 | continue; | ||
1031 | |||
1032 | /* found the 6 * 0xffff marker? */ | ||
1033 | if (i == 12) | ||
1034 | ar9170_handle_command_response(ar, respbuf, resplen); | ||
1035 | else | ||
1036 | ar9170_handle_mpdu(ar, respbuf, clen); | ||
1037 | } | ||
1038 | |||
1039 | if (tlen) { | ||
1040 | if (net_ratelimit()) | ||
1041 | wiphy_err(ar->hw->wiphy, | ||
1042 | "%d bytes of unprocessed data left in rx stream!\n", | ||
1043 | tlen); | ||
1044 | |||
1045 | goto err_telluser; | ||
1046 | } | ||
1047 | |||
1048 | return ; | ||
1049 | |||
1050 | err_telluser: | ||
1051 | wiphy_err(ar->hw->wiphy, | ||
1052 | "damaged RX stream data [want:%d, data:%d, rx:%d, pending:%d ]\n", | ||
1053 | clen, wlen, tlen, ar->rx_failover_missing); | ||
1054 | |||
1055 | if (ar->rx_failover_missing) | ||
1056 | print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET, | ||
1057 | ar->rx_failover->data, | ||
1058 | ar->rx_failover->len); | ||
1059 | |||
1060 | print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET, | ||
1061 | skb->data, skb->len); | ||
1062 | |||
1063 | wiphy_err(ar->hw->wiphy, | ||
1064 | "If you see this message frequently, please check your hardware and cables.\n"); | ||
1065 | |||
1066 | err_silent: | ||
1067 | if (ar->rx_failover_missing) { | ||
1068 | skb_reset_tail_pointer(ar->rx_failover); | ||
1069 | skb_trim(ar->rx_failover, 0); | ||
1070 | ar->rx_failover_missing = 0; | ||
1071 | } | ||
1072 | } | ||
1073 | |||
1074 | #define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \ | ||
1075 | do { \ | ||
1076 | queue.aifs = ai_fs; \ | ||
1077 | queue.cw_min = cwmin; \ | ||
1078 | queue.cw_max = cwmax; \ | ||
1079 | queue.txop = _txop; \ | ||
1080 | } while (0) | ||
1081 | |||
1082 | static int ar9170_op_start(struct ieee80211_hw *hw) | ||
1083 | { | ||
1084 | struct ar9170 *ar = hw->priv; | ||
1085 | int err, i; | ||
1086 | |||
1087 | mutex_lock(&ar->mutex); | ||
1088 | |||
1089 | /* reinitialize queues statistics */ | ||
1090 | memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); | ||
1091 | for (i = 0; i < __AR9170_NUM_TXQ; i++) | ||
1092 | ar->tx_stats[i].limit = AR9170_TXQ_DEPTH; | ||
1093 | |||
1094 | /* reset QoS defaults */ | ||
1095 | AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/ | ||
1096 | AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023, 0); /* BACKGROUND */ | ||
1097 | AR9170_FILL_QUEUE(ar->edcf[2], 2, 7, 15, 94); /* VIDEO */ | ||
1098 | AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */ | ||
1099 | AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */ | ||
1100 | |||
1101 | /* set sane AMPDU defaults */ | ||
1102 | ar->global_ampdu_density = 6; | ||
1103 | ar->global_ampdu_factor = 3; | ||
1104 | |||
1105 | ar->bad_hw_nagger = jiffies; | ||
1106 | |||
1107 | err = ar->open(ar); | ||
1108 | if (err) | ||
1109 | goto out; | ||
1110 | |||
1111 | err = ar9170_init_mac(ar); | ||
1112 | if (err) | ||
1113 | goto out; | ||
1114 | |||
1115 | err = ar9170_set_qos(ar); | ||
1116 | if (err) | ||
1117 | goto out; | ||
1118 | |||
1119 | err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ); | ||
1120 | if (err) | ||
1121 | goto out; | ||
1122 | |||
1123 | err = ar9170_init_rf(ar); | ||
1124 | if (err) | ||
1125 | goto out; | ||
1126 | |||
1127 | /* start DMA */ | ||
1128 | err = ar9170_write_reg(ar, 0x1c3d30, 0x100); | ||
1129 | if (err) | ||
1130 | goto out; | ||
1131 | |||
1132 | ar->state = AR9170_STARTED; | ||
1133 | |||
1134 | out: | ||
1135 | mutex_unlock(&ar->mutex); | ||
1136 | return err; | ||
1137 | } | ||
1138 | |||
1139 | static void ar9170_op_stop(struct ieee80211_hw *hw) | ||
1140 | { | ||
1141 | struct ar9170 *ar = hw->priv; | ||
1142 | unsigned int i; | ||
1143 | |||
1144 | if (IS_STARTED(ar)) | ||
1145 | ar->state = AR9170_IDLE; | ||
1146 | |||
1147 | cancel_delayed_work_sync(&ar->tx_janitor); | ||
1148 | #ifdef CONFIG_AR9170_LEDS | ||
1149 | cancel_delayed_work_sync(&ar->led_work); | ||
1150 | #endif | ||
1151 | cancel_work_sync(&ar->beacon_work); | ||
1152 | |||
1153 | mutex_lock(&ar->mutex); | ||
1154 | |||
1155 | if (IS_ACCEPTING_CMD(ar)) { | ||
1156 | ar9170_set_leds_state(ar, 0); | ||
1157 | |||
1158 | /* stop DMA */ | ||
1159 | ar9170_write_reg(ar, 0x1c3d30, 0); | ||
1160 | ar->stop(ar); | ||
1161 | } | ||
1162 | |||
1163 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { | ||
1164 | skb_queue_purge(&ar->tx_pending[i]); | ||
1165 | skb_queue_purge(&ar->tx_status[i]); | ||
1166 | } | ||
1167 | |||
1168 | mutex_unlock(&ar->mutex); | ||
1169 | } | ||
1170 | |||
1171 | static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) | ||
1172 | { | ||
1173 | struct ieee80211_hdr *hdr; | ||
1174 | struct ar9170_tx_control *txc; | ||
1175 | struct ieee80211_tx_info *info; | ||
1176 | struct ieee80211_tx_rate *txrate; | ||
1177 | struct ar9170_tx_info *arinfo; | ||
1178 | unsigned int queue = skb_get_queue_mapping(skb); | ||
1179 | u16 keytype = 0; | ||
1180 | u16 len, icv = 0; | ||
1181 | |||
1182 | BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); | ||
1183 | |||
1184 | hdr = (void *)skb->data; | ||
1185 | info = IEEE80211_SKB_CB(skb); | ||
1186 | len = skb->len; | ||
1187 | |||
1188 | txc = (void *)skb_push(skb, sizeof(*txc)); | ||
1189 | |||
1190 | if (info->control.hw_key) { | ||
1191 | icv = info->control.hw_key->icv_len; | ||
1192 | |||
1193 | switch (info->control.hw_key->cipher) { | ||
1194 | case WLAN_CIPHER_SUITE_WEP40: | ||
1195 | case WLAN_CIPHER_SUITE_WEP104: | ||
1196 | case WLAN_CIPHER_SUITE_TKIP: | ||
1197 | keytype = AR9170_TX_MAC_ENCR_RC4; | ||
1198 | break; | ||
1199 | case WLAN_CIPHER_SUITE_CCMP: | ||
1200 | keytype = AR9170_TX_MAC_ENCR_AES; | ||
1201 | break; | ||
1202 | default: | ||
1203 | WARN_ON(1); | ||
1204 | goto err_out; | ||
1205 | } | ||
1206 | } | ||
1207 | |||
1208 | /* Length */ | ||
1209 | txc->length = cpu_to_le16(len + icv + 4); | ||
1210 | |||
1211 | txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | | ||
1212 | AR9170_TX_MAC_BACKOFF); | ||
1213 | txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] << | ||
1214 | AR9170_TX_MAC_QOS_SHIFT); | ||
1215 | txc->mac_control |= cpu_to_le16(keytype); | ||
1216 | txc->phy_control = cpu_to_le32(0); | ||
1217 | |||
1218 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) | ||
1219 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); | ||
1220 | |||
1221 | txrate = &info->control.rates[0]; | ||
1222 | if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) | ||
1223 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); | ||
1224 | else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS) | ||
1225 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); | ||
1226 | |||
1227 | arinfo = (void *)info->rate_driver_data; | ||
1228 | arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT); | ||
1229 | |||
1230 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && | ||
1231 | (is_valid_ether_addr(ieee80211_get_DA(hdr)))) { | ||
1232 | /* | ||
1233 | * WARNING: | ||
1234 | * Putting the QoS queue bits into an unexplored territory is | ||
1235 | * certainly not elegant. | ||
1236 | * | ||
1237 | * In my defense: This idea provides a reasonable way to | ||
1238 | * smuggle valuable information to the tx_status callback. | ||
1239 | * Also, the idea behind this bit-abuse came straight from | ||
1240 | * the original driver code. | ||
1241 | */ | ||
1242 | |||
1243 | txc->phy_control |= | ||
1244 | cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); | ||
1245 | |||
1246 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); | ||
1247 | } | ||
1248 | |||
1249 | return 0; | ||
1250 | |||
1251 | err_out: | ||
1252 | skb_pull(skb, sizeof(*txc)); | ||
1253 | return -EINVAL; | ||
1254 | } | ||
1255 | |||
1256 | static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb) | ||
1257 | { | ||
1258 | struct ar9170_tx_control *txc; | ||
1259 | struct ieee80211_tx_info *info; | ||
1260 | struct ieee80211_rate *rate = NULL; | ||
1261 | struct ieee80211_tx_rate *txrate; | ||
1262 | u32 power, chains; | ||
1263 | |||
1264 | txc = (void *) skb->data; | ||
1265 | info = IEEE80211_SKB_CB(skb); | ||
1266 | txrate = &info->control.rates[0]; | ||
1267 | |||
1268 | if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) | ||
1269 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); | ||
1270 | |||
1271 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | ||
1272 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE); | ||
1273 | |||
1274 | if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | ||
1275 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ); | ||
1276 | /* this works because 40 MHz is 2 and dup is 3 */ | ||
1277 | if (txrate->flags & IEEE80211_TX_RC_DUP_DATA) | ||
1278 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP); | ||
1279 | |||
1280 | if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) | ||
1281 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI); | ||
1282 | |||
1283 | if (txrate->flags & IEEE80211_TX_RC_MCS) { | ||
1284 | u32 r = txrate->idx; | ||
1285 | u8 *txpower; | ||
1286 | |||
1287 | /* heavy clip control */ | ||
1288 | txc->phy_control |= cpu_to_le32((r & 0x7) << 7); | ||
1289 | |||
1290 | r <<= AR9170_TX_PHY_MCS_SHIFT; | ||
1291 | BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK); | ||
1292 | |||
1293 | txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK); | ||
1294 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT); | ||
1295 | |||
1296 | if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { | ||
1297 | if (info->band == IEEE80211_BAND_5GHZ) | ||
1298 | txpower = ar->power_5G_ht40; | ||
1299 | else | ||
1300 | txpower = ar->power_2G_ht40; | ||
1301 | } else { | ||
1302 | if (info->band == IEEE80211_BAND_5GHZ) | ||
1303 | txpower = ar->power_5G_ht20; | ||
1304 | else | ||
1305 | txpower = ar->power_2G_ht20; | ||
1306 | } | ||
1307 | |||
1308 | power = txpower[(txrate->idx) & 7]; | ||
1309 | } else { | ||
1310 | u8 *txpower; | ||
1311 | u32 mod; | ||
1312 | u32 phyrate; | ||
1313 | u8 idx = txrate->idx; | ||
1314 | |||
1315 | if (info->band != IEEE80211_BAND_2GHZ) { | ||
1316 | idx += 4; | ||
1317 | txpower = ar->power_5G_leg; | ||
1318 | mod = AR9170_TX_PHY_MOD_OFDM; | ||
1319 | } else { | ||
1320 | if (idx < 4) { | ||
1321 | txpower = ar->power_2G_cck; | ||
1322 | mod = AR9170_TX_PHY_MOD_CCK; | ||
1323 | } else { | ||
1324 | mod = AR9170_TX_PHY_MOD_OFDM; | ||
1325 | txpower = ar->power_2G_ofdm; | ||
1326 | } | ||
1327 | } | ||
1328 | |||
1329 | rate = &__ar9170_ratetable[idx]; | ||
1330 | |||
1331 | phyrate = rate->hw_value & 0xF; | ||
1332 | power = txpower[(rate->hw_value & 0x30) >> 4]; | ||
1333 | phyrate <<= AR9170_TX_PHY_MCS_SHIFT; | ||
1334 | |||
1335 | txc->phy_control |= cpu_to_le32(mod); | ||
1336 | txc->phy_control |= cpu_to_le32(phyrate); | ||
1337 | } | ||
1338 | |||
1339 | power <<= AR9170_TX_PHY_TX_PWR_SHIFT; | ||
1340 | power &= AR9170_TX_PHY_TX_PWR_MASK; | ||
1341 | txc->phy_control |= cpu_to_le32(power); | ||
1342 | |||
1343 | /* set TX chains */ | ||
1344 | if (ar->eeprom.tx_mask == 1) { | ||
1345 | chains = AR9170_TX_PHY_TXCHAIN_1; | ||
1346 | } else { | ||
1347 | chains = AR9170_TX_PHY_TXCHAIN_2; | ||
1348 | |||
1349 | /* >= 36M legacy OFDM - use only one chain */ | ||
1350 | if (rate && rate->bitrate >= 360) | ||
1351 | chains = AR9170_TX_PHY_TXCHAIN_1; | ||
1352 | } | ||
1353 | txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT); | ||
1354 | } | ||
1355 | |||
1356 | static void ar9170_tx(struct ar9170 *ar) | ||
1357 | { | ||
1358 | struct sk_buff *skb; | ||
1359 | unsigned long flags; | ||
1360 | struct ieee80211_tx_info *info; | ||
1361 | struct ar9170_tx_info *arinfo; | ||
1362 | unsigned int i, frames, frames_failed, remaining_space; | ||
1363 | int err; | ||
1364 | bool schedule_garbagecollector = false; | ||
1365 | |||
1366 | BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); | ||
1367 | |||
1368 | if (unlikely(!IS_STARTED(ar))) | ||
1369 | return ; | ||
1370 | |||
1371 | remaining_space = AR9170_TX_MAX_PENDING; | ||
1372 | |||
1373 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { | ||
1374 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | ||
1375 | frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len, | ||
1376 | skb_queue_len(&ar->tx_pending[i])); | ||
1377 | |||
1378 | if (remaining_space < frames) { | ||
1379 | #ifdef AR9170_QUEUE_DEBUG | ||
1380 | wiphy_debug(ar->hw->wiphy, | ||
1381 | "tx quota reached queue:%d, " | ||
1382 | "remaining slots:%d, needed:%d\n", | ||
1383 | i, remaining_space, frames); | ||
1384 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1385 | frames = remaining_space; | ||
1386 | } | ||
1387 | |||
1388 | ar->tx_stats[i].len += frames; | ||
1389 | ar->tx_stats[i].count += frames; | ||
1390 | if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { | ||
1391 | #ifdef AR9170_QUEUE_DEBUG | ||
1392 | wiphy_debug(ar->hw->wiphy, "queue %d full\n", i); | ||
1393 | wiphy_debug(ar->hw->wiphy, "stuck frames: ===>\n"); | ||
1394 | ar9170_dump_txqueue(ar, &ar->tx_pending[i]); | ||
1395 | ar9170_dump_txqueue(ar, &ar->tx_status[i]); | ||
1396 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1397 | |||
1398 | #ifdef AR9170_QUEUE_STOP_DEBUG | ||
1399 | wiphy_debug(ar->hw->wiphy, "stop queue %d\n", i); | ||
1400 | __ar9170_dump_txstats(ar); | ||
1401 | #endif /* AR9170_QUEUE_STOP_DEBUG */ | ||
1402 | ieee80211_stop_queue(ar->hw, i); | ||
1403 | } | ||
1404 | |||
1405 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1406 | |||
1407 | if (!frames) | ||
1408 | continue; | ||
1409 | |||
1410 | frames_failed = 0; | ||
1411 | while (frames) { | ||
1412 | skb = skb_dequeue(&ar->tx_pending[i]); | ||
1413 | if (unlikely(!skb)) { | ||
1414 | frames_failed += frames; | ||
1415 | frames = 0; | ||
1416 | break; | ||
1417 | } | ||
1418 | |||
1419 | info = IEEE80211_SKB_CB(skb); | ||
1420 | arinfo = (void *) info->rate_driver_data; | ||
1421 | |||
1422 | /* TODO: cancel stuck frames */ | ||
1423 | arinfo->timeout = jiffies + | ||
1424 | msecs_to_jiffies(AR9170_TX_TIMEOUT); | ||
1425 | |||
1426 | #ifdef AR9170_QUEUE_DEBUG | ||
1427 | wiphy_debug(ar->hw->wiphy, "send frame q:%d =>\n", i); | ||
1428 | ar9170_print_txheader(ar, skb); | ||
1429 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1430 | |||
1431 | err = ar->tx(ar, skb); | ||
1432 | if (unlikely(err)) { | ||
1433 | frames_failed++; | ||
1434 | dev_kfree_skb_any(skb); | ||
1435 | } else { | ||
1436 | remaining_space--; | ||
1437 | schedule_garbagecollector = true; | ||
1438 | } | ||
1439 | |||
1440 | frames--; | ||
1441 | } | ||
1442 | |||
1443 | #ifdef AR9170_QUEUE_DEBUG | ||
1444 | wiphy_debug(ar->hw->wiphy, | ||
1445 | "ar9170_tx report for queue %d\n", i); | ||
1446 | |||
1447 | wiphy_debug(ar->hw->wiphy, | ||
1448 | "unprocessed pending frames left:\n"); | ||
1449 | ar9170_dump_txqueue(ar, &ar->tx_pending[i]); | ||
1450 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1451 | |||
1452 | if (unlikely(frames_failed)) { | ||
1453 | #ifdef AR9170_QUEUE_DEBUG | ||
1454 | wiphy_debug(ar->hw->wiphy, | ||
1455 | "frames failed %d =>\n", frames_failed); | ||
1456 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1457 | |||
1458 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | ||
1459 | ar->tx_stats[i].len -= frames_failed; | ||
1460 | ar->tx_stats[i].count -= frames_failed; | ||
1461 | #ifdef AR9170_QUEUE_STOP_DEBUG | ||
1462 | wiphy_debug(ar->hw->wiphy, "wake queue %d\n", i); | ||
1463 | __ar9170_dump_txstats(ar); | ||
1464 | #endif /* AR9170_QUEUE_STOP_DEBUG */ | ||
1465 | ieee80211_wake_queue(ar->hw, i); | ||
1466 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1467 | } | ||
1468 | } | ||
1469 | |||
1470 | if (!schedule_garbagecollector) | ||
1471 | return; | ||
1472 | |||
1473 | ieee80211_queue_delayed_work(ar->hw, | ||
1474 | &ar->tx_janitor, | ||
1475 | msecs_to_jiffies(AR9170_JANITOR_DELAY)); | ||
1476 | } | ||
1477 | |||
1478 | void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1479 | { | ||
1480 | struct ar9170 *ar = hw->priv; | ||
1481 | struct ieee80211_tx_info *info; | ||
1482 | unsigned int queue; | ||
1483 | |||
1484 | if (unlikely(!IS_STARTED(ar))) | ||
1485 | goto err_free; | ||
1486 | |||
1487 | if (unlikely(ar9170_tx_prepare(ar, skb))) | ||
1488 | goto err_free; | ||
1489 | |||
1490 | queue = skb_get_queue_mapping(skb); | ||
1491 | info = IEEE80211_SKB_CB(skb); | ||
1492 | ar9170_tx_prepare_phy(ar, skb); | ||
1493 | skb_queue_tail(&ar->tx_pending[queue], skb); | ||
1494 | |||
1495 | ar9170_tx(ar); | ||
1496 | return; | ||
1497 | |||
1498 | err_free: | ||
1499 | dev_kfree_skb_any(skb); | ||
1500 | } | ||
1501 | |||
1502 | static int ar9170_op_add_interface(struct ieee80211_hw *hw, | ||
1503 | struct ieee80211_vif *vif) | ||
1504 | { | ||
1505 | struct ar9170 *ar = hw->priv; | ||
1506 | struct ath_common *common = &ar->common; | ||
1507 | int err = 0; | ||
1508 | |||
1509 | mutex_lock(&ar->mutex); | ||
1510 | |||
1511 | if (ar->vif) { | ||
1512 | err = -EBUSY; | ||
1513 | goto unlock; | ||
1514 | } | ||
1515 | |||
1516 | ar->vif = vif; | ||
1517 | memcpy(common->macaddr, vif->addr, ETH_ALEN); | ||
1518 | |||
1519 | if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) { | ||
1520 | ar->rx_software_decryption = true; | ||
1521 | ar->disable_offload = true; | ||
1522 | } | ||
1523 | |||
1524 | ar->cur_filter = 0; | ||
1525 | err = ar9170_update_frame_filter(ar, AR9170_MAC_REG_FTF_DEFAULTS); | ||
1526 | if (err) | ||
1527 | goto unlock; | ||
1528 | |||
1529 | err = ar9170_set_operating_mode(ar); | ||
1530 | |||
1531 | unlock: | ||
1532 | mutex_unlock(&ar->mutex); | ||
1533 | return err; | ||
1534 | } | ||
1535 | |||
1536 | static void ar9170_op_remove_interface(struct ieee80211_hw *hw, | ||
1537 | struct ieee80211_vif *vif) | ||
1538 | { | ||
1539 | struct ar9170 *ar = hw->priv; | ||
1540 | |||
1541 | mutex_lock(&ar->mutex); | ||
1542 | ar->vif = NULL; | ||
1543 | ar9170_update_frame_filter(ar, 0); | ||
1544 | ar9170_set_beacon_timers(ar); | ||
1545 | dev_kfree_skb(ar->beacon); | ||
1546 | ar->beacon = NULL; | ||
1547 | ar->sniffer_enabled = false; | ||
1548 | ar->rx_software_decryption = false; | ||
1549 | ar9170_set_operating_mode(ar); | ||
1550 | mutex_unlock(&ar->mutex); | ||
1551 | } | ||
1552 | |||
1553 | static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed) | ||
1554 | { | ||
1555 | struct ar9170 *ar = hw->priv; | ||
1556 | int err = 0; | ||
1557 | |||
1558 | mutex_lock(&ar->mutex); | ||
1559 | |||
1560 | if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { | ||
1561 | /* TODO */ | ||
1562 | err = 0; | ||
1563 | } | ||
1564 | |||
1565 | if (changed & IEEE80211_CONF_CHANGE_PS) { | ||
1566 | /* TODO */ | ||
1567 | err = 0; | ||
1568 | } | ||
1569 | |||
1570 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | ||
1571 | /* TODO */ | ||
1572 | err = 0; | ||
1573 | } | ||
1574 | |||
1575 | if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { | ||
1576 | /* | ||
1577 | * is it long_frame_max_tx_count or short_frame_max_tx_count? | ||
1578 | */ | ||
1579 | |||
1580 | err = ar9170_set_hwretry_limit(ar, | ||
1581 | ar->hw->conf.long_frame_max_tx_count); | ||
1582 | if (err) | ||
1583 | goto out; | ||
1584 | } | ||
1585 | |||
1586 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | ||
1587 | |||
1588 | /* adjust slot time for 5 GHz */ | ||
1589 | err = ar9170_set_slot_time(ar); | ||
1590 | if (err) | ||
1591 | goto out; | ||
1592 | |||
1593 | err = ar9170_set_dyn_sifs_ack(ar); | ||
1594 | if (err) | ||
1595 | goto out; | ||
1596 | |||
1597 | err = ar9170_set_channel(ar, hw->conf.channel, | ||
1598 | AR9170_RFI_NONE, | ||
1599 | nl80211_to_ar9170(hw->conf.channel_type)); | ||
1600 | if (err) | ||
1601 | goto out; | ||
1602 | } | ||
1603 | |||
1604 | out: | ||
1605 | mutex_unlock(&ar->mutex); | ||
1606 | return err; | ||
1607 | } | ||
1608 | |||
1609 | static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, | ||
1610 | struct netdev_hw_addr_list *mc_list) | ||
1611 | { | ||
1612 | u64 mchash; | ||
1613 | struct netdev_hw_addr *ha; | ||
1614 | |||
1615 | /* always get broadcast frames */ | ||
1616 | mchash = 1ULL << (0xff >> 2); | ||
1617 | |||
1618 | netdev_hw_addr_list_for_each(ha, mc_list) | ||
1619 | mchash |= 1ULL << (ha->addr[5] >> 2); | ||
1620 | |||
1621 | return mchash; | ||
1622 | } | ||
1623 | |||
1624 | static void ar9170_op_configure_filter(struct ieee80211_hw *hw, | ||
1625 | unsigned int changed_flags, | ||
1626 | unsigned int *new_flags, | ||
1627 | u64 multicast) | ||
1628 | { | ||
1629 | struct ar9170 *ar = hw->priv; | ||
1630 | |||
1631 | if (unlikely(!IS_ACCEPTING_CMD(ar))) | ||
1632 | return ; | ||
1633 | |||
1634 | mutex_lock(&ar->mutex); | ||
1635 | |||
1636 | /* mask supported flags */ | ||
1637 | *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC | | ||
1638 | FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL; | ||
1639 | ar->filter_state = *new_flags; | ||
1640 | /* | ||
1641 | * We can support more by setting the sniffer bit and | ||
1642 | * then checking the error flags, later. | ||
1643 | */ | ||
1644 | |||
1645 | if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI) | ||
1646 | multicast = ~0ULL; | ||
1647 | |||
1648 | if (multicast != ar->cur_mc_hash) | ||
1649 | ar9170_update_multicast(ar, multicast); | ||
1650 | |||
1651 | if (changed_flags & FIF_CONTROL) { | ||
1652 | u32 filter = AR9170_MAC_REG_FTF_PSPOLL | | ||
1653 | AR9170_MAC_REG_FTF_RTS | | ||
1654 | AR9170_MAC_REG_FTF_CTS | | ||
1655 | AR9170_MAC_REG_FTF_ACK | | ||
1656 | AR9170_MAC_REG_FTF_CFE | | ||
1657 | AR9170_MAC_REG_FTF_CFE_ACK; | ||
1658 | |||
1659 | if (*new_flags & FIF_CONTROL) | ||
1660 | filter |= ar->cur_filter; | ||
1661 | else | ||
1662 | filter &= (~ar->cur_filter); | ||
1663 | |||
1664 | ar9170_update_frame_filter(ar, filter); | ||
1665 | } | ||
1666 | |||
1667 | if (changed_flags & FIF_PROMISC_IN_BSS) { | ||
1668 | ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0; | ||
1669 | ar9170_set_operating_mode(ar); | ||
1670 | } | ||
1671 | |||
1672 | mutex_unlock(&ar->mutex); | ||
1673 | } | ||
1674 | |||
1675 | |||
1676 | static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, | ||
1677 | struct ieee80211_vif *vif, | ||
1678 | struct ieee80211_bss_conf *bss_conf, | ||
1679 | u32 changed) | ||
1680 | { | ||
1681 | struct ar9170 *ar = hw->priv; | ||
1682 | struct ath_common *common = &ar->common; | ||
1683 | int err = 0; | ||
1684 | |||
1685 | mutex_lock(&ar->mutex); | ||
1686 | |||
1687 | if (changed & BSS_CHANGED_BSSID) { | ||
1688 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | ||
1689 | err = ar9170_set_operating_mode(ar); | ||
1690 | if (err) | ||
1691 | goto out; | ||
1692 | } | ||
1693 | |||
1694 | if (changed & BSS_CHANGED_BEACON_ENABLED) | ||
1695 | ar->enable_beacon = bss_conf->enable_beacon; | ||
1696 | |||
1697 | if (changed & BSS_CHANGED_BEACON) { | ||
1698 | err = ar9170_update_beacon(ar); | ||
1699 | if (err) | ||
1700 | goto out; | ||
1701 | } | ||
1702 | |||
1703 | if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON | | ||
1704 | BSS_CHANGED_BEACON_INT)) { | ||
1705 | err = ar9170_set_beacon_timers(ar); | ||
1706 | if (err) | ||
1707 | goto out; | ||
1708 | } | ||
1709 | |||
1710 | if (changed & BSS_CHANGED_ASSOC) { | ||
1711 | #ifndef CONFIG_AR9170_LEDS | ||
1712 | /* enable assoc LED. */ | ||
1713 | err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0); | ||
1714 | #endif /* CONFIG_AR9170_LEDS */ | ||
1715 | } | ||
1716 | |||
1717 | if (changed & BSS_CHANGED_HT) { | ||
1718 | /* TODO */ | ||
1719 | err = 0; | ||
1720 | } | ||
1721 | |||
1722 | if (changed & BSS_CHANGED_ERP_SLOT) { | ||
1723 | err = ar9170_set_slot_time(ar); | ||
1724 | if (err) | ||
1725 | goto out; | ||
1726 | } | ||
1727 | |||
1728 | if (changed & BSS_CHANGED_BASIC_RATES) { | ||
1729 | err = ar9170_set_basic_rates(ar); | ||
1730 | if (err) | ||
1731 | goto out; | ||
1732 | } | ||
1733 | |||
1734 | out: | ||
1735 | mutex_unlock(&ar->mutex); | ||
1736 | } | ||
1737 | |||
1738 | static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw) | ||
1739 | { | ||
1740 | struct ar9170 *ar = hw->priv; | ||
1741 | int err; | ||
1742 | u64 tsf; | ||
1743 | #define NR 3 | ||
1744 | static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H, | ||
1745 | AR9170_MAC_REG_TSF_L, | ||
1746 | AR9170_MAC_REG_TSF_H }; | ||
1747 | u32 val[NR]; | ||
1748 | int loops = 0; | ||
1749 | |||
1750 | mutex_lock(&ar->mutex); | ||
1751 | |||
1752 | while (loops++ < 10) { | ||
1753 | err = ar9170_read_mreg(ar, NR, addr, val); | ||
1754 | if (err || val[0] == val[2]) | ||
1755 | break; | ||
1756 | } | ||
1757 | |||
1758 | mutex_unlock(&ar->mutex); | ||
1759 | |||
1760 | if (WARN_ON(err)) | ||
1761 | return 0; | ||
1762 | tsf = val[0]; | ||
1763 | tsf = (tsf << 32) | val[1]; | ||
1764 | return tsf; | ||
1765 | #undef NR | ||
1766 | } | ||
1767 | |||
1768 | static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | ||
1769 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, | ||
1770 | struct ieee80211_key_conf *key) | ||
1771 | { | ||
1772 | struct ar9170 *ar = hw->priv; | ||
1773 | int err = 0, i; | ||
1774 | u8 ktype; | ||
1775 | |||
1776 | if ((!ar->vif) || (ar->disable_offload)) | ||
1777 | return -EOPNOTSUPP; | ||
1778 | |||
1779 | switch (key->cipher) { | ||
1780 | case WLAN_CIPHER_SUITE_WEP40: | ||
1781 | ktype = AR9170_ENC_ALG_WEP64; | ||
1782 | break; | ||
1783 | case WLAN_CIPHER_SUITE_WEP104: | ||
1784 | ktype = AR9170_ENC_ALG_WEP128; | ||
1785 | break; | ||
1786 | case WLAN_CIPHER_SUITE_TKIP: | ||
1787 | ktype = AR9170_ENC_ALG_TKIP; | ||
1788 | break; | ||
1789 | case WLAN_CIPHER_SUITE_CCMP: | ||
1790 | ktype = AR9170_ENC_ALG_AESCCMP; | ||
1791 | break; | ||
1792 | default: | ||
1793 | return -EOPNOTSUPP; | ||
1794 | } | ||
1795 | |||
1796 | mutex_lock(&ar->mutex); | ||
1797 | if (cmd == SET_KEY) { | ||
1798 | if (unlikely(!IS_STARTED(ar))) { | ||
1799 | err = -EOPNOTSUPP; | ||
1800 | goto out; | ||
1801 | } | ||
1802 | |||
1803 | /* group keys need all-zeroes address */ | ||
1804 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) | ||
1805 | sta = NULL; | ||
1806 | |||
1807 | if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { | ||
1808 | for (i = 0; i < 64; i++) | ||
1809 | if (!(ar->usedkeys & BIT(i))) | ||
1810 | break; | ||
1811 | if (i == 64) { | ||
1812 | ar->rx_software_decryption = true; | ||
1813 | ar9170_set_operating_mode(ar); | ||
1814 | err = -ENOSPC; | ||
1815 | goto out; | ||
1816 | } | ||
1817 | } else { | ||
1818 | i = 64 + key->keyidx; | ||
1819 | } | ||
1820 | |||
1821 | key->hw_key_idx = i; | ||
1822 | |||
1823 | err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0, | ||
1824 | key->key, min_t(u8, 16, key->keylen)); | ||
1825 | if (err) | ||
1826 | goto out; | ||
1827 | |||
1828 | if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { | ||
1829 | err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, | ||
1830 | ktype, 1, key->key + 16, 16); | ||
1831 | if (err) | ||
1832 | goto out; | ||
1833 | |||
1834 | /* | ||
1835 | * hardware is not capable generating the MMIC | ||
1836 | * for fragmented frames! | ||
1837 | */ | ||
1838 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
1839 | } | ||
1840 | |||
1841 | if (i < 64) | ||
1842 | ar->usedkeys |= BIT(i); | ||
1843 | |||
1844 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
1845 | } else { | ||
1846 | if (unlikely(!IS_STARTED(ar))) { | ||
1847 | /* The device is gone... together with the key ;-) */ | ||
1848 | err = 0; | ||
1849 | goto out; | ||
1850 | } | ||
1851 | |||
1852 | err = ar9170_disable_key(ar, key->hw_key_idx); | ||
1853 | if (err) | ||
1854 | goto out; | ||
1855 | |||
1856 | if (key->hw_key_idx < 64) { | ||
1857 | ar->usedkeys &= ~BIT(key->hw_key_idx); | ||
1858 | } else { | ||
1859 | err = ar9170_upload_key(ar, key->hw_key_idx, NULL, | ||
1860 | AR9170_ENC_ALG_NONE, 0, | ||
1861 | NULL, 0); | ||
1862 | if (err) | ||
1863 | goto out; | ||
1864 | |||
1865 | if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { | ||
1866 | err = ar9170_upload_key(ar, key->hw_key_idx, | ||
1867 | NULL, | ||
1868 | AR9170_ENC_ALG_NONE, 1, | ||
1869 | NULL, 0); | ||
1870 | if (err) | ||
1871 | goto out; | ||
1872 | } | ||
1873 | |||
1874 | } | ||
1875 | } | ||
1876 | |||
1877 | ar9170_regwrite_begin(ar); | ||
1878 | ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys); | ||
1879 | ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32); | ||
1880 | ar9170_regwrite_finish(); | ||
1881 | err = ar9170_regwrite_result(); | ||
1882 | |||
1883 | out: | ||
1884 | mutex_unlock(&ar->mutex); | ||
1885 | |||
1886 | return err; | ||
1887 | } | ||
1888 | |||
1889 | static int ar9170_get_stats(struct ieee80211_hw *hw, | ||
1890 | struct ieee80211_low_level_stats *stats) | ||
1891 | { | ||
1892 | struct ar9170 *ar = hw->priv; | ||
1893 | u32 val; | ||
1894 | int err; | ||
1895 | |||
1896 | mutex_lock(&ar->mutex); | ||
1897 | err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val); | ||
1898 | ar->stats.dot11ACKFailureCount += val; | ||
1899 | |||
1900 | memcpy(stats, &ar->stats, sizeof(*stats)); | ||
1901 | mutex_unlock(&ar->mutex); | ||
1902 | |||
1903 | return 0; | ||
1904 | } | ||
1905 | |||
1906 | static int ar9170_get_survey(struct ieee80211_hw *hw, int idx, | ||
1907 | struct survey_info *survey) | ||
1908 | { | ||
1909 | struct ar9170 *ar = hw->priv; | ||
1910 | struct ieee80211_conf *conf = &hw->conf; | ||
1911 | |||
1912 | if (idx != 0) | ||
1913 | return -ENOENT; | ||
1914 | |||
1915 | /* TODO: update noise value, e.g. call ar9170_set_channel */ | ||
1916 | |||
1917 | survey->channel = conf->channel; | ||
1918 | survey->filled = SURVEY_INFO_NOISE_DBM; | ||
1919 | survey->noise = ar->noise[0]; | ||
1920 | |||
1921 | return 0; | ||
1922 | } | ||
1923 | |||
1924 | static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, | ||
1925 | const struct ieee80211_tx_queue_params *param) | ||
1926 | { | ||
1927 | struct ar9170 *ar = hw->priv; | ||
1928 | int ret; | ||
1929 | |||
1930 | mutex_lock(&ar->mutex); | ||
1931 | if (queue < __AR9170_NUM_TXQ) { | ||
1932 | memcpy(&ar->edcf[ar9170_qos_hwmap[queue]], | ||
1933 | param, sizeof(*param)); | ||
1934 | |||
1935 | ret = ar9170_set_qos(ar); | ||
1936 | } else { | ||
1937 | ret = -EINVAL; | ||
1938 | } | ||
1939 | |||
1940 | mutex_unlock(&ar->mutex); | ||
1941 | return ret; | ||
1942 | } | ||
1943 | |||
1944 | static int ar9170_ampdu_action(struct ieee80211_hw *hw, | ||
1945 | struct ieee80211_vif *vif, | ||
1946 | enum ieee80211_ampdu_mlme_action action, | ||
1947 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, | ||
1948 | u8 buf_size) | ||
1949 | { | ||
1950 | switch (action) { | ||
1951 | case IEEE80211_AMPDU_RX_START: | ||
1952 | case IEEE80211_AMPDU_RX_STOP: | ||
1953 | /* Handled by firmware */ | ||
1954 | break; | ||
1955 | |||
1956 | default: | ||
1957 | return -EOPNOTSUPP; | ||
1958 | } | ||
1959 | |||
1960 | return 0; | ||
1961 | } | ||
1962 | |||
1963 | static const struct ieee80211_ops ar9170_ops = { | ||
1964 | .start = ar9170_op_start, | ||
1965 | .stop = ar9170_op_stop, | ||
1966 | .tx = ar9170_op_tx, | ||
1967 | .add_interface = ar9170_op_add_interface, | ||
1968 | .remove_interface = ar9170_op_remove_interface, | ||
1969 | .config = ar9170_op_config, | ||
1970 | .prepare_multicast = ar9170_op_prepare_multicast, | ||
1971 | .configure_filter = ar9170_op_configure_filter, | ||
1972 | .conf_tx = ar9170_conf_tx, | ||
1973 | .bss_info_changed = ar9170_op_bss_info_changed, | ||
1974 | .get_tsf = ar9170_op_get_tsf, | ||
1975 | .set_key = ar9170_set_key, | ||
1976 | .get_stats = ar9170_get_stats, | ||
1977 | .get_survey = ar9170_get_survey, | ||
1978 | .ampdu_action = ar9170_ampdu_action, | ||
1979 | }; | ||
1980 | |||
1981 | void *ar9170_alloc(size_t priv_size) | ||
1982 | { | ||
1983 | struct ieee80211_hw *hw; | ||
1984 | struct ar9170 *ar; | ||
1985 | struct sk_buff *skb; | ||
1986 | int i; | ||
1987 | |||
1988 | /* | ||
1989 | * this buffer is used for rx stream reconstruction. | ||
1990 | * Under heavy load this device (or the transport layer?) | ||
1991 | * tends to split the streams into separate rx descriptors. | ||
1992 | */ | ||
1993 | |||
1994 | skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL); | ||
1995 | if (!skb) | ||
1996 | goto err_nomem; | ||
1997 | |||
1998 | hw = ieee80211_alloc_hw(priv_size, &ar9170_ops); | ||
1999 | if (!hw) | ||
2000 | goto err_nomem; | ||
2001 | |||
2002 | ar = hw->priv; | ||
2003 | ar->hw = hw; | ||
2004 | ar->rx_failover = skb; | ||
2005 | |||
2006 | mutex_init(&ar->mutex); | ||
2007 | spin_lock_init(&ar->cmdlock); | ||
2008 | spin_lock_init(&ar->tx_stats_lock); | ||
2009 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { | ||
2010 | skb_queue_head_init(&ar->tx_status[i]); | ||
2011 | skb_queue_head_init(&ar->tx_pending[i]); | ||
2012 | } | ||
2013 | ar9170_rx_reset_rx_mpdu(ar); | ||
2014 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); | ||
2015 | INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); | ||
2016 | |||
2017 | /* all hw supports 2.4 GHz, so set channel to 1 by default */ | ||
2018 | ar->channel = &ar9170_2ghz_chantable[0]; | ||
2019 | |||
2020 | /* first part of wiphy init */ | ||
2021 | ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | ||
2022 | BIT(NL80211_IFTYPE_WDS) | | ||
2023 | BIT(NL80211_IFTYPE_ADHOC); | ||
2024 | ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | | ||
2025 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
2026 | IEEE80211_HW_SIGNAL_DBM; | ||
2027 | |||
2028 | ar->hw->queues = __AR9170_NUM_TXQ; | ||
2029 | ar->hw->extra_tx_headroom = 8; | ||
2030 | |||
2031 | ar->hw->max_rates = 1; | ||
2032 | ar->hw->max_rate_tries = 3; | ||
2033 | |||
2034 | for (i = 0; i < ARRAY_SIZE(ar->noise); i++) | ||
2035 | ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ | ||
2036 | |||
2037 | return ar; | ||
2038 | |||
2039 | err_nomem: | ||
2040 | kfree_skb(skb); | ||
2041 | return ERR_PTR(-ENOMEM); | ||
2042 | } | ||
2043 | |||
2044 | static int ar9170_read_eeprom(struct ar9170 *ar) | ||
2045 | { | ||
2046 | #define RW 8 /* number of words to read at once */ | ||
2047 | #define RB (sizeof(u32) * RW) | ||
2048 | struct ath_regulatory *regulatory = &ar->common.regulatory; | ||
2049 | u8 *eeprom = (void *)&ar->eeprom; | ||
2050 | u8 *addr = ar->eeprom.mac_address; | ||
2051 | __le32 offsets[RW]; | ||
2052 | unsigned int rx_streams, tx_streams, tx_params = 0; | ||
2053 | int i, j, err, bands = 0; | ||
2054 | |||
2055 | BUILD_BUG_ON(sizeof(ar->eeprom) & 3); | ||
2056 | |||
2057 | BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4); | ||
2058 | #ifndef __CHECKER__ | ||
2059 | /* don't want to handle trailing remains */ | ||
2060 | BUILD_BUG_ON(sizeof(ar->eeprom) % RB); | ||
2061 | #endif | ||
2062 | |||
2063 | for (i = 0; i < sizeof(ar->eeprom)/RB; i++) { | ||
2064 | for (j = 0; j < RW; j++) | ||
2065 | offsets[j] = cpu_to_le32(AR9170_EEPROM_START + | ||
2066 | RB * i + 4 * j); | ||
2067 | |||
2068 | err = ar->exec_cmd(ar, AR9170_CMD_RREG, | ||
2069 | RB, (u8 *) &offsets, | ||
2070 | RB, eeprom + RB * i); | ||
2071 | if (err) | ||
2072 | return err; | ||
2073 | } | ||
2074 | |||
2075 | #undef RW | ||
2076 | #undef RB | ||
2077 | |||
2078 | if (ar->eeprom.length == cpu_to_le16(0xFFFF)) | ||
2079 | return -ENODATA; | ||
2080 | |||
2081 | if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) { | ||
2082 | ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz; | ||
2083 | bands++; | ||
2084 | } | ||
2085 | if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) { | ||
2086 | ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz; | ||
2087 | bands++; | ||
2088 | } | ||
2089 | |||
2090 | rx_streams = hweight8(ar->eeprom.rx_mask); | ||
2091 | tx_streams = hweight8(ar->eeprom.tx_mask); | ||
2092 | |||
2093 | if (rx_streams != tx_streams) | ||
2094 | tx_params = IEEE80211_HT_MCS_TX_RX_DIFF; | ||
2095 | |||
2096 | if (tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS) | ||
2097 | tx_params = (tx_streams - 1) << | ||
2098 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; | ||
2099 | |||
2100 | ar9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params; | ||
2101 | ar9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params; | ||
2102 | |||
2103 | /* | ||
2104 | * I measured this, a bandswitch takes roughly | ||
2105 | * 135 ms and a frequency switch about 80. | ||
2106 | * | ||
2107 | * FIXME: measure these values again once EEPROM settings | ||
2108 | * are used, that will influence them! | ||
2109 | */ | ||
2110 | if (bands == 2) | ||
2111 | ar->hw->channel_change_time = 135 * 1000; | ||
2112 | else | ||
2113 | ar->hw->channel_change_time = 80 * 1000; | ||
2114 | |||
2115 | regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]); | ||
2116 | regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]); | ||
2117 | |||
2118 | /* second part of wiphy init */ | ||
2119 | SET_IEEE80211_PERM_ADDR(ar->hw, addr); | ||
2120 | |||
2121 | return bands ? 0 : -EINVAL; | ||
2122 | } | ||
2123 | |||
2124 | static int ar9170_reg_notifier(struct wiphy *wiphy, | ||
2125 | struct regulatory_request *request) | ||
2126 | { | ||
2127 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | ||
2128 | struct ar9170 *ar = hw->priv; | ||
2129 | |||
2130 | return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory); | ||
2131 | } | ||
2132 | |||
2133 | int ar9170_register(struct ar9170 *ar, struct device *pdev) | ||
2134 | { | ||
2135 | struct ath_regulatory *regulatory = &ar->common.regulatory; | ||
2136 | int err; | ||
2137 | |||
2138 | /* try to read EEPROM, init MAC addr */ | ||
2139 | err = ar9170_read_eeprom(ar); | ||
2140 | if (err) | ||
2141 | goto err_out; | ||
2142 | |||
2143 | err = ath_regd_init(regulatory, ar->hw->wiphy, | ||
2144 | ar9170_reg_notifier); | ||
2145 | if (err) | ||
2146 | goto err_out; | ||
2147 | |||
2148 | err = ieee80211_register_hw(ar->hw); | ||
2149 | if (err) | ||
2150 | goto err_out; | ||
2151 | |||
2152 | if (!ath_is_world_regd(regulatory)) | ||
2153 | regulatory_hint(ar->hw->wiphy, regulatory->alpha2); | ||
2154 | |||
2155 | err = ar9170_init_leds(ar); | ||
2156 | if (err) | ||
2157 | goto err_unreg; | ||
2158 | |||
2159 | #ifdef CONFIG_AR9170_LEDS | ||
2160 | err = ar9170_register_leds(ar); | ||
2161 | if (err) | ||
2162 | goto err_unreg; | ||
2163 | #endif /* CONFIG_AR9170_LEDS */ | ||
2164 | |||
2165 | dev_info(pdev, "Atheros AR9170 is registered as '%s'\n", | ||
2166 | wiphy_name(ar->hw->wiphy)); | ||
2167 | |||
2168 | ar->registered = true; | ||
2169 | return 0; | ||
2170 | |||
2171 | err_unreg: | ||
2172 | ieee80211_unregister_hw(ar->hw); | ||
2173 | |||
2174 | err_out: | ||
2175 | return err; | ||
2176 | } | ||
2177 | |||
2178 | void ar9170_unregister(struct ar9170 *ar) | ||
2179 | { | ||
2180 | if (ar->registered) { | ||
2181 | #ifdef CONFIG_AR9170_LEDS | ||
2182 | ar9170_unregister_leds(ar); | ||
2183 | #endif /* CONFIG_AR9170_LEDS */ | ||
2184 | |||
2185 | ieee80211_unregister_hw(ar->hw); | ||
2186 | } | ||
2187 | |||
2188 | kfree_skb(ar->rx_failover); | ||
2189 | mutex_destroy(&ar->mutex); | ||
2190 | } | ||
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c deleted file mode 100644 index aa8d06ba1ee..00000000000 --- a/drivers/net/wireless/ath/ar9170/phy.c +++ /dev/null | |||
@@ -1,1719 +0,0 @@ | |||
1 | /* | ||
2 | * Atheros AR9170 driver | ||
3 | * | ||
4 | * PHY and RF code | ||
5 | * | ||
6 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; see the file COPYING. If not, see | ||
20 | * http://www.gnu.org/licenses/. | ||
21 | * | ||
22 | * This file incorporates work covered by the following copyright and | ||
23 | * permission notice: | ||
24 | * Copyright (c) 2007-2008 Atheros Communications, Inc. | ||
25 | * | ||
26 | * Permission to use, copy, modify, and/or distribute this software for any | ||
27 | * purpose with or without fee is hereby granted, provided that the above | ||
28 | * copyright notice and this permission notice appear in all copies. | ||
29 | * | ||
30 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
31 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
32 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
33 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
34 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
35 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
36 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
37 | */ | ||
38 | |||
39 | #include <linux/bitrev.h> | ||
40 | #include "ar9170.h" | ||
41 | #include "cmd.h" | ||
42 | |||
43 | static int ar9170_init_power_cal(struct ar9170 *ar) | ||
44 | { | ||
45 | ar9170_regwrite_begin(ar); | ||
46 | |||
47 | ar9170_regwrite(0x1bc000 + 0x993c, 0x7f); | ||
48 | ar9170_regwrite(0x1bc000 + 0x9934, 0x3f3f3f3f); | ||
49 | ar9170_regwrite(0x1bc000 + 0x9938, 0x3f3f3f3f); | ||
50 | ar9170_regwrite(0x1bc000 + 0xa234, 0x3f3f3f3f); | ||
51 | ar9170_regwrite(0x1bc000 + 0xa238, 0x3f3f3f3f); | ||
52 | ar9170_regwrite(0x1bc000 + 0xa38c, 0x3f3f3f3f); | ||
53 | ar9170_regwrite(0x1bc000 + 0xa390, 0x3f3f3f3f); | ||
54 | ar9170_regwrite(0x1bc000 + 0xa3cc, 0x3f3f3f3f); | ||
55 | ar9170_regwrite(0x1bc000 + 0xa3d0, 0x3f3f3f3f); | ||
56 | ar9170_regwrite(0x1bc000 + 0xa3d4, 0x3f3f3f3f); | ||
57 | |||
58 | ar9170_regwrite_finish(); | ||
59 | return ar9170_regwrite_result(); | ||
60 | } | ||
61 | |||
62 | struct ar9170_phy_init { | ||
63 | u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20; | ||
64 | }; | ||
65 | |||
66 | static struct ar9170_phy_init ar5416_phy_init[] = { | ||
67 | { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, | ||
68 | { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, }, | ||
69 | { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
70 | { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, }, | ||
71 | { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, }, | ||
72 | { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, }, | ||
73 | { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, }, | ||
74 | { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
75 | { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, }, | ||
76 | { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, }, | ||
77 | { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, }, | ||
78 | { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, }, | ||
79 | { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
80 | { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, }, | ||
81 | { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, | ||
82 | { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, }, | ||
83 | { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, }, | ||
84 | { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, }, | ||
85 | { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, }, | ||
86 | { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, }, | ||
87 | { 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, }, | ||
88 | { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, }, | ||
89 | { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, }, | ||
90 | { 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, }, | ||
91 | { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, }, | ||
92 | { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, }, | ||
93 | { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, }, | ||
94 | { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
95 | { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
96 | { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
97 | { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
98 | { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, }, | ||
99 | { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, }, | ||
100 | { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, }, | ||
101 | { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, }, | ||
102 | { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, }, | ||
103 | { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, | ||
104 | { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, }, | ||
105 | { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, | ||
106 | { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, | ||
107 | { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, }, | ||
108 | { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, }, | ||
109 | { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, }, | ||
110 | { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, }, | ||
111 | { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, }, | ||
112 | { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, }, | ||
113 | { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, | ||
114 | { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, }, | ||
115 | { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, }, | ||
116 | { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
117 | { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, | ||
118 | { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
119 | { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
120 | { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
121 | { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
122 | { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
123 | { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
124 | { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
125 | { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
126 | { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
127 | { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
128 | { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, | ||
129 | { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, }, | ||
130 | { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, }, | ||
131 | { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, }, | ||
132 | { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, }, | ||
133 | { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, }, | ||
134 | { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, }, | ||
135 | { 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, }, | ||
136 | { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, }, | ||
137 | { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, }, | ||
138 | { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
139 | { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
140 | { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
141 | { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, }, | ||
142 | { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, }, | ||
143 | { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, }, | ||
144 | { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, }, | ||
145 | { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
146 | { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, }, | ||
147 | { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
148 | { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, }, | ||
149 | { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, }, | ||
150 | { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, }, | ||
151 | { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, }, | ||
152 | { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, }, | ||
153 | { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, }, | ||
154 | { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, }, | ||
155 | { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, }, | ||
156 | { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, }, | ||
157 | { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, }, | ||
158 | { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, }, | ||
159 | { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, }, | ||
160 | { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, }, | ||
161 | { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, }, | ||
162 | { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, }, | ||
163 | { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, }, | ||
164 | { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, }, | ||
165 | { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, }, | ||
166 | { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, }, | ||
167 | { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, }, | ||
168 | { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, }, | ||
169 | { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, }, | ||
170 | { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, }, | ||
171 | { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, }, | ||
172 | { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, }, | ||
173 | { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, }, | ||
174 | { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, }, | ||
175 | { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, }, | ||
176 | { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, }, | ||
177 | { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, }, | ||
178 | { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, }, | ||
179 | { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, }, | ||
180 | { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, }, | ||
181 | { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, }, | ||
182 | { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, }, | ||
183 | { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, }, | ||
184 | { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, }, | ||
185 | { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, }, | ||
186 | { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, }, | ||
187 | { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
188 | { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
189 | { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
190 | { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
191 | { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
192 | { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
193 | { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
194 | { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
195 | { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
196 | { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
197 | { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
198 | { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
199 | { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
200 | { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
201 | { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
202 | { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
203 | { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
204 | { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
205 | { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
206 | { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
207 | { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
208 | { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
209 | { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
210 | { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, | ||
211 | { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
212 | { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, | ||
213 | { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, }, | ||
214 | { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, }, | ||
215 | { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, }, | ||
216 | { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, }, | ||
217 | { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, }, | ||
218 | { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, }, | ||
219 | { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, }, | ||
220 | { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, }, | ||
221 | { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, }, | ||
222 | { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, }, | ||
223 | { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, }, | ||
224 | { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, }, | ||
225 | { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, }, | ||
226 | { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, }, | ||
227 | { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, }, | ||
228 | { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, }, | ||
229 | { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, }, | ||
230 | { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, }, | ||
231 | { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, }, | ||
232 | { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, }, | ||
233 | { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, }, | ||
234 | { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, }, | ||
235 | { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, }, | ||
236 | { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, }, | ||
237 | { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, }, | ||
238 | { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, }, | ||
239 | { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, }, | ||
240 | { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, }, | ||
241 | { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, }, | ||
242 | { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, }, | ||
243 | { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, }, | ||
244 | { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, }, | ||
245 | { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, }, | ||
246 | { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, }, | ||
247 | { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, }, | ||
248 | { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, }, | ||
249 | { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, }, | ||
250 | { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, }, | ||
251 | { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, }, | ||
252 | { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
253 | { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
254 | { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
255 | { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
256 | { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
257 | { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
258 | { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
259 | { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
260 | { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
261 | { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
262 | { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
263 | { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
264 | { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
265 | { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
266 | { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
267 | { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
268 | { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
269 | { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
270 | { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
271 | { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
272 | { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, | ||
273 | { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, }, | ||
274 | { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, }, | ||
275 | { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
276 | { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
277 | { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
278 | { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
279 | { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
280 | { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
281 | { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
282 | { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
283 | { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
284 | { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
285 | { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
286 | { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
287 | { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
288 | { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
289 | { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
290 | { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
291 | { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
292 | { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
293 | { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, }, | ||
294 | { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, }, | ||
295 | { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, }, | ||
296 | { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, | ||
297 | { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, }, | ||
298 | { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, }, | ||
299 | { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, }, | ||
300 | { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, }, | ||
301 | { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, }, | ||
302 | { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, }, | ||
303 | { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, }, | ||
304 | { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
305 | { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, }, | ||
306 | { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, | ||
307 | { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, | ||
308 | { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, }, | ||
309 | { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, }, | ||
310 | { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, }, | ||
311 | { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, }, | ||
312 | { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, | ||
313 | { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, }, | ||
314 | { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
315 | { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, }, | ||
316 | { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, }, | ||
317 | { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, }, | ||
318 | { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, }, | ||
319 | { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
320 | { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, | ||
321 | { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, }, | ||
322 | { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, | ||
323 | { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, }, | ||
324 | { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, }, | ||
325 | { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, }, | ||
326 | { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, }, | ||
327 | { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, }, | ||
328 | { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, }, | ||
329 | { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, }, | ||
330 | { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, }, | ||
331 | { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, }, | ||
332 | { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, }, | ||
333 | { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, }, | ||
334 | { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, }, | ||
335 | { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
336 | { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
337 | { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
338 | { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
339 | { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
340 | { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
341 | { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
342 | { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, | ||
343 | { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, | ||
344 | { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, | ||
345 | { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, }, | ||
346 | { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, }, | ||
347 | { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, }, | ||
348 | { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, | ||
349 | { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, | ||
350 | { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, | ||
351 | { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, }, | ||
352 | { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, | ||
353 | { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
354 | { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
355 | { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
356 | { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
357 | { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
358 | { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
359 | { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
360 | { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
361 | { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
362 | { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
363 | { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
364 | { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, | ||
365 | { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, | ||
366 | { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, | ||
367 | { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, | ||
368 | { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, | ||
369 | { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, }, | ||
370 | { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, }, | ||
371 | { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, }, | ||
372 | { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, | ||
373 | { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, | ||
374 | { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, | ||
375 | { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, }, | ||
376 | { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, }, | ||
377 | { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, | ||
378 | { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, | ||
379 | { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, | ||
380 | /* { 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */ | ||
381 | { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, }, | ||
382 | { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, }, | ||
383 | { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, }, | ||
384 | { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, }, | ||
385 | { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, }, | ||
386 | { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, }, | ||
387 | { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, }, | ||
388 | { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, }, | ||
389 | { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, }, | ||
390 | { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, }, | ||
391 | { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, }, | ||
392 | { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, }, | ||
393 | { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, }, | ||
394 | { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, }, | ||
395 | { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, }, | ||
396 | { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, } | ||
397 | }; | ||
398 | |||
399 | /* | ||
400 | * look up a certain register in ar5416_phy_init[] and return the init. value | ||
401 | * for the band and bandwidth given. Return 0 if register address not found. | ||
402 | */ | ||
403 | static u32 ar9170_get_default_phy_reg_val(u32 reg, bool is_2ghz, bool is_40mhz) | ||
404 | { | ||
405 | unsigned int i; | ||
406 | for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) { | ||
407 | if (ar5416_phy_init[i].reg != reg) | ||
408 | continue; | ||
409 | |||
410 | if (is_2ghz) { | ||
411 | if (is_40mhz) | ||
412 | return ar5416_phy_init[i]._2ghz_40; | ||
413 | else | ||
414 | return ar5416_phy_init[i]._2ghz_20; | ||
415 | } else { | ||
416 | if (is_40mhz) | ||
417 | return ar5416_phy_init[i]._5ghz_40; | ||
418 | else | ||
419 | return ar5416_phy_init[i]._5ghz_20; | ||
420 | } | ||
421 | } | ||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | /* | ||
426 | * initialize some phy regs from eeprom values in modal_header[] | ||
427 | * acc. to band and bandwidth | ||
428 | */ | ||
429 | static int ar9170_init_phy_from_eeprom(struct ar9170 *ar, | ||
430 | bool is_2ghz, bool is_40mhz) | ||
431 | { | ||
432 | static const u8 xpd2pd[16] = { | ||
433 | 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2, | ||
434 | 0x2, 0x3, 0x7, 0x2, 0xB, 0x2, 0x2, 0x2 | ||
435 | }; | ||
436 | u32 defval, newval; | ||
437 | /* pointer to the modal_header acc. to band */ | ||
438 | struct ar9170_eeprom_modal *m = &ar->eeprom.modal_header[is_2ghz]; | ||
439 | |||
440 | ar9170_regwrite_begin(ar); | ||
441 | |||
442 | /* ant common control (index 0) */ | ||
443 | newval = le32_to_cpu(m->antCtrlCommon); | ||
444 | ar9170_regwrite(0x1c5964, newval); | ||
445 | |||
446 | /* ant control chain 0 (index 1) */ | ||
447 | newval = le32_to_cpu(m->antCtrlChain[0]); | ||
448 | ar9170_regwrite(0x1c5960, newval); | ||
449 | |||
450 | /* ant control chain 2 (index 2) */ | ||
451 | newval = le32_to_cpu(m->antCtrlChain[1]); | ||
452 | ar9170_regwrite(0x1c7960, newval); | ||
453 | |||
454 | /* SwSettle (index 3) */ | ||
455 | if (!is_40mhz) { | ||
456 | defval = ar9170_get_default_phy_reg_val(0x1c5844, | ||
457 | is_2ghz, is_40mhz); | ||
458 | newval = (defval & ~0x3f80) | | ||
459 | ((m->switchSettling & 0x7f) << 7); | ||
460 | ar9170_regwrite(0x1c5844, newval); | ||
461 | } | ||
462 | |||
463 | /* adcDesired, pdaDesired (index 4) */ | ||
464 | defval = ar9170_get_default_phy_reg_val(0x1c5850, is_2ghz, is_40mhz); | ||
465 | newval = (defval & ~0xffff) | ((u8)m->pgaDesiredSize << 8) | | ||
466 | ((u8)m->adcDesiredSize); | ||
467 | ar9170_regwrite(0x1c5850, newval); | ||
468 | |||
469 | /* TxEndToXpaOff, TxFrameToXpaOn (index 5) */ | ||
470 | defval = ar9170_get_default_phy_reg_val(0x1c5834, is_2ghz, is_40mhz); | ||
471 | newval = (m->txEndToXpaOff << 24) | (m->txEndToXpaOff << 16) | | ||
472 | (m->txFrameToXpaOn << 8) | m->txFrameToXpaOn; | ||
473 | ar9170_regwrite(0x1c5834, newval); | ||
474 | |||
475 | /* TxEndToRxOn (index 6) */ | ||
476 | defval = ar9170_get_default_phy_reg_val(0x1c5828, is_2ghz, is_40mhz); | ||
477 | newval = (defval & ~0xff0000) | (m->txEndToRxOn << 16); | ||
478 | ar9170_regwrite(0x1c5828, newval); | ||
479 | |||
480 | /* thresh62 (index 7) */ | ||
481 | defval = ar9170_get_default_phy_reg_val(0x1c8864, is_2ghz, is_40mhz); | ||
482 | newval = (defval & ~0x7f000) | (m->thresh62 << 12); | ||
483 | ar9170_regwrite(0x1c8864, newval); | ||
484 | |||
485 | /* tx/rx attenuation chain 0 (index 8) */ | ||
486 | defval = ar9170_get_default_phy_reg_val(0x1c5848, is_2ghz, is_40mhz); | ||
487 | newval = (defval & ~0x3f000) | ((m->txRxAttenCh[0] & 0x3f) << 12); | ||
488 | ar9170_regwrite(0x1c5848, newval); | ||
489 | |||
490 | /* tx/rx attenuation chain 2 (index 9) */ | ||
491 | defval = ar9170_get_default_phy_reg_val(0x1c7848, is_2ghz, is_40mhz); | ||
492 | newval = (defval & ~0x3f000) | ((m->txRxAttenCh[1] & 0x3f) << 12); | ||
493 | ar9170_regwrite(0x1c7848, newval); | ||
494 | |||
495 | /* tx/rx margin chain 0 (index 10) */ | ||
496 | defval = ar9170_get_default_phy_reg_val(0x1c620c, is_2ghz, is_40mhz); | ||
497 | newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[0] & 0x3f) << 18); | ||
498 | /* bsw margin chain 0 for 5GHz only */ | ||
499 | if (!is_2ghz) | ||
500 | newval = (newval & ~0x3c00) | ((m->bswMargin[0] & 0xf) << 10); | ||
501 | ar9170_regwrite(0x1c620c, newval); | ||
502 | |||
503 | /* tx/rx margin chain 2 (index 11) */ | ||
504 | defval = ar9170_get_default_phy_reg_val(0x1c820c, is_2ghz, is_40mhz); | ||
505 | newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[1] & 0x3f) << 18); | ||
506 | ar9170_regwrite(0x1c820c, newval); | ||
507 | |||
508 | /* iqCall, iqCallq chain 0 (index 12) */ | ||
509 | defval = ar9170_get_default_phy_reg_val(0x1c5920, is_2ghz, is_40mhz); | ||
510 | newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[0] & 0x3f) << 5) | | ||
511 | ((u8)m->iqCalQCh[0] & 0x1f); | ||
512 | ar9170_regwrite(0x1c5920, newval); | ||
513 | |||
514 | /* iqCall, iqCallq chain 2 (index 13) */ | ||
515 | defval = ar9170_get_default_phy_reg_val(0x1c7920, is_2ghz, is_40mhz); | ||
516 | newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[1] & 0x3f) << 5) | | ||
517 | ((u8)m->iqCalQCh[1] & 0x1f); | ||
518 | ar9170_regwrite(0x1c7920, newval); | ||
519 | |||
520 | /* xpd gain mask (index 14) */ | ||
521 | defval = ar9170_get_default_phy_reg_val(0x1c6258, is_2ghz, is_40mhz); | ||
522 | newval = (defval & ~0xf0000) | (xpd2pd[m->xpdGain & 0xf] << 16); | ||
523 | ar9170_regwrite(0x1c6258, newval); | ||
524 | ar9170_regwrite_finish(); | ||
525 | |||
526 | return ar9170_regwrite_result(); | ||
527 | } | ||
528 | |||
529 | int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band) | ||
530 | { | ||
531 | int i, err; | ||
532 | u32 val; | ||
533 | bool is_2ghz = band == IEEE80211_BAND_2GHZ; | ||
534 | bool is_40mhz = conf_is_ht40(&ar->hw->conf); | ||
535 | |||
536 | ar9170_regwrite_begin(ar); | ||
537 | |||
538 | for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) { | ||
539 | if (is_40mhz) { | ||
540 | if (is_2ghz) | ||
541 | val = ar5416_phy_init[i]._2ghz_40; | ||
542 | else | ||
543 | val = ar5416_phy_init[i]._5ghz_40; | ||
544 | } else { | ||
545 | if (is_2ghz) | ||
546 | val = ar5416_phy_init[i]._2ghz_20; | ||
547 | else | ||
548 | val = ar5416_phy_init[i]._5ghz_20; | ||
549 | } | ||
550 | |||
551 | ar9170_regwrite(ar5416_phy_init[i].reg, val); | ||
552 | } | ||
553 | |||
554 | ar9170_regwrite_finish(); | ||
555 | err = ar9170_regwrite_result(); | ||
556 | if (err) | ||
557 | return err; | ||
558 | |||
559 | err = ar9170_init_phy_from_eeprom(ar, is_2ghz, is_40mhz); | ||
560 | if (err) | ||
561 | return err; | ||
562 | |||
563 | err = ar9170_init_power_cal(ar); | ||
564 | if (err) | ||
565 | return err; | ||
566 | |||
567 | /* XXX: remove magic! */ | ||
568 | if (is_2ghz) | ||
569 | err = ar9170_write_reg(ar, 0x1d4014, 0x5163); | ||
570 | else | ||
571 | err = ar9170_write_reg(ar, 0x1d4014, 0x5143); | ||
572 | |||
573 | return err; | ||
574 | } | ||
575 | |||
576 | struct ar9170_rf_init { | ||
577 | u32 reg, _5ghz, _2ghz; | ||
578 | }; | ||
579 | |||
580 | static struct ar9170_rf_init ar9170_rf_init[] = { | ||
581 | /* bank 0 */ | ||
582 | { 0x1c58b0, 0x1e5795e5, 0x1e5795e5}, | ||
583 | { 0x1c58e0, 0x02008020, 0x02008020}, | ||
584 | /* bank 1 */ | ||
585 | { 0x1c58b0, 0x02108421, 0x02108421}, | ||
586 | { 0x1c58ec, 0x00000008, 0x00000008}, | ||
587 | /* bank 2 */ | ||
588 | { 0x1c58b0, 0x0e73ff17, 0x0e73ff17}, | ||
589 | { 0x1c58e0, 0x00000420, 0x00000420}, | ||
590 | /* bank 3 */ | ||
591 | { 0x1c58f0, 0x01400018, 0x01c00018}, | ||
592 | /* bank 4 */ | ||
593 | { 0x1c58b0, 0x000001a1, 0x000001a1}, | ||
594 | { 0x1c58e8, 0x00000001, 0x00000001}, | ||
595 | /* bank 5 */ | ||
596 | { 0x1c58b0, 0x00000013, 0x00000013}, | ||
597 | { 0x1c58e4, 0x00000002, 0x00000002}, | ||
598 | /* bank 6 */ | ||
599 | { 0x1c58b0, 0x00000000, 0x00000000}, | ||
600 | { 0x1c58b0, 0x00000000, 0x00000000}, | ||
601 | { 0x1c58b0, 0x00000000, 0x00000000}, | ||
602 | { 0x1c58b0, 0x00000000, 0x00000000}, | ||
603 | { 0x1c58b0, 0x00000000, 0x00000000}, | ||
604 | { 0x1c58b0, 0x00004000, 0x00004000}, | ||
605 | { 0x1c58b0, 0x00006c00, 0x00006c00}, | ||
606 | { 0x1c58b0, 0x00002c00, 0x00002c00}, | ||
607 | { 0x1c58b0, 0x00004800, 0x00004800}, | ||
608 | { 0x1c58b0, 0x00004000, 0x00004000}, | ||
609 | { 0x1c58b0, 0x00006000, 0x00006000}, | ||
610 | { 0x1c58b0, 0x00001000, 0x00001000}, | ||
611 | { 0x1c58b0, 0x00004000, 0x00004000}, | ||
612 | { 0x1c58b0, 0x00007c00, 0x00007c00}, | ||
613 | { 0x1c58b0, 0x00007c00, 0x00007c00}, | ||
614 | { 0x1c58b0, 0x00007c00, 0x00007c00}, | ||
615 | { 0x1c58b0, 0x00007c00, 0x00007c00}, | ||
616 | { 0x1c58b0, 0x00007c00, 0x00007c00}, | ||
617 | { 0x1c58b0, 0x00087c00, 0x00087c00}, | ||
618 | { 0x1c58b0, 0x00007c00, 0x00007c00}, | ||
619 | { 0x1c58b0, 0x00005400, 0x00005400}, | ||
620 | { 0x1c58b0, 0x00000c00, 0x00000c00}, | ||
621 | { 0x1c58b0, 0x00001800, 0x00001800}, | ||
622 | { 0x1c58b0, 0x00007c00, 0x00007c00}, | ||
623 | { 0x1c58b0, 0x00006c00, 0x00006c00}, | ||
624 | { 0x1c58b0, 0x00006c00, 0x00006c00}, | ||
625 | { 0x1c58b0, 0x00007c00, 0x00007c00}, | ||
626 | { 0x1c58b0, 0x00002c00, 0x00002c00}, | ||
627 | { 0x1c58b0, 0x00003c00, 0x00003c00}, | ||
628 | { 0x1c58b0, 0x00003800, 0x00003800}, | ||
629 | { 0x1c58b0, 0x00001c00, 0x00001c00}, | ||
630 | { 0x1c58b0, 0x00000800, 0x00000800}, | ||
631 | { 0x1c58b0, 0x00000408, 0x00000408}, | ||
632 | { 0x1c58b0, 0x00004c15, 0x00004c15}, | ||
633 | { 0x1c58b0, 0x00004188, 0x00004188}, | ||
634 | { 0x1c58b0, 0x0000201e, 0x0000201e}, | ||
635 | { 0x1c58b0, 0x00010408, 0x00010408}, | ||
636 | { 0x1c58b0, 0x00000801, 0x00000801}, | ||
637 | { 0x1c58b0, 0x00000c08, 0x00000c08}, | ||
638 | { 0x1c58b0, 0x0000181e, 0x0000181e}, | ||
639 | { 0x1c58b0, 0x00001016, 0x00001016}, | ||
640 | { 0x1c58b0, 0x00002800, 0x00002800}, | ||
641 | { 0x1c58b0, 0x00004010, 0x00004010}, | ||
642 | { 0x1c58b0, 0x0000081c, 0x0000081c}, | ||
643 | { 0x1c58b0, 0x00000115, 0x00000115}, | ||
644 | { 0x1c58b0, 0x00000015, 0x00000015}, | ||
645 | { 0x1c58b0, 0x00000066, 0x00000066}, | ||
646 | { 0x1c58b0, 0x0000001c, 0x0000001c}, | ||
647 | { 0x1c58b0, 0x00000000, 0x00000000}, | ||
648 | { 0x1c58b0, 0x00000004, 0x00000004}, | ||
649 | { 0x1c58b0, 0x00000015, 0x00000015}, | ||
650 | { 0x1c58b0, 0x0000001f, 0x0000001f}, | ||
651 | { 0x1c58e0, 0x00000000, 0x00000400}, | ||
652 | /* bank 7 */ | ||
653 | { 0x1c58b0, 0x000000a0, 0x000000a0}, | ||
654 | { 0x1c58b0, 0x00000000, 0x00000000}, | ||
655 | { 0x1c58b0, 0x00000040, 0x00000040}, | ||
656 | { 0x1c58f0, 0x0000001c, 0x0000001c}, | ||
657 | }; | ||
658 | |||
659 | static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz) | ||
660 | { | ||
661 | int err, i; | ||
662 | |||
663 | ar9170_regwrite_begin(ar); | ||
664 | |||
665 | for (i = 0; i < ARRAY_SIZE(ar9170_rf_init); i++) | ||
666 | ar9170_regwrite(ar9170_rf_init[i].reg, | ||
667 | band5ghz ? ar9170_rf_init[i]._5ghz | ||
668 | : ar9170_rf_init[i]._2ghz); | ||
669 | |||
670 | ar9170_regwrite_finish(); | ||
671 | err = ar9170_regwrite_result(); | ||
672 | if (err) | ||
673 | wiphy_err(ar->hw->wiphy, "rf init failed\n"); | ||
674 | return err; | ||
675 | } | ||
676 | |||
677 | static int ar9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz, | ||
678 | u32 freq, enum ar9170_bw bw) | ||
679 | { | ||
680 | int err; | ||
681 | u32 d0, d1, td0, td1, fd0, fd1; | ||
682 | u8 chansel; | ||
683 | u8 refsel0 = 1, refsel1 = 0; | ||
684 | u8 lf_synth = 0; | ||
685 | |||
686 | switch (bw) { | ||
687 | case AR9170_BW_40_ABOVE: | ||
688 | freq += 10; | ||
689 | break; | ||
690 | case AR9170_BW_40_BELOW: | ||
691 | freq -= 10; | ||
692 | break; | ||
693 | case AR9170_BW_20: | ||
694 | break; | ||
695 | case __AR9170_NUM_BW: | ||
696 | BUG(); | ||
697 | } | ||
698 | |||
699 | if (band5ghz) { | ||
700 | if (freq % 10) { | ||
701 | chansel = (freq - 4800) / 5; | ||
702 | } else { | ||
703 | chansel = ((freq - 4800) / 10) * 2; | ||
704 | refsel0 = 0; | ||
705 | refsel1 = 1; | ||
706 | } | ||
707 | chansel = byte_rev_table[chansel]; | ||
708 | } else { | ||
709 | if (freq == 2484) { | ||
710 | chansel = 10 + (freq - 2274) / 5; | ||
711 | lf_synth = 1; | ||
712 | } else | ||
713 | chansel = 16 + (freq - 2272) / 5; | ||
714 | chansel *= 4; | ||
715 | chansel = byte_rev_table[chansel]; | ||
716 | } | ||
717 | |||
718 | d1 = chansel; | ||
719 | d0 = 0x21 | | ||
720 | refsel0 << 3 | | ||
721 | refsel1 << 2 | | ||
722 | lf_synth << 1; | ||
723 | td0 = d0 & 0x1f; | ||
724 | td1 = d1 & 0x1f; | ||
725 | fd0 = td1 << 5 | td0; | ||
726 | |||
727 | td0 = (d0 >> 5) & 0x7; | ||
728 | td1 = (d1 >> 5) & 0x7; | ||
729 | fd1 = td1 << 5 | td0; | ||
730 | |||
731 | ar9170_regwrite_begin(ar); | ||
732 | |||
733 | ar9170_regwrite(0x1c58b0, fd0); | ||
734 | ar9170_regwrite(0x1c58e8, fd1); | ||
735 | |||
736 | ar9170_regwrite_finish(); | ||
737 | err = ar9170_regwrite_result(); | ||
738 | if (err) | ||
739 | return err; | ||
740 | |||
741 | msleep(10); | ||
742 | |||
743 | return 0; | ||
744 | } | ||
745 | |||
746 | struct ar9170_phy_freq_params { | ||
747 | u8 coeff_exp; | ||
748 | u16 coeff_man; | ||
749 | u8 coeff_exp_shgi; | ||
750 | u16 coeff_man_shgi; | ||
751 | }; | ||
752 | |||
753 | struct ar9170_phy_freq_entry { | ||
754 | u16 freq; | ||
755 | struct ar9170_phy_freq_params params[__AR9170_NUM_BW]; | ||
756 | }; | ||
757 | |||
758 | /* NB: must be in sync with channel tables in main! */ | ||
759 | static const struct ar9170_phy_freq_entry ar9170_phy_freq_params[] = { | ||
760 | /* | ||
761 | * freq, | ||
762 | * 20MHz, | ||
763 | * 40MHz (below), | ||
764 | * 40Mhz (above), | ||
765 | */ | ||
766 | { 2412, { | ||
767 | { 3, 21737, 3, 19563, }, | ||
768 | { 3, 21827, 3, 19644, }, | ||
769 | { 3, 21647, 3, 19482, }, | ||
770 | } }, | ||
771 | { 2417, { | ||
772 | { 3, 21692, 3, 19523, }, | ||
773 | { 3, 21782, 3, 19604, }, | ||
774 | { 3, 21602, 3, 19442, }, | ||
775 | } }, | ||
776 | { 2422, { | ||
777 | { 3, 21647, 3, 19482, }, | ||
778 | { 3, 21737, 3, 19563, }, | ||
779 | { 3, 21558, 3, 19402, }, | ||
780 | } }, | ||
781 | { 2427, { | ||
782 | { 3, 21602, 3, 19442, }, | ||
783 | { 3, 21692, 3, 19523, }, | ||
784 | { 3, 21514, 3, 19362, }, | ||
785 | } }, | ||
786 | { 2432, { | ||
787 | { 3, 21558, 3, 19402, }, | ||
788 | { 3, 21647, 3, 19482, }, | ||
789 | { 3, 21470, 3, 19323, }, | ||
790 | } }, | ||
791 | { 2437, { | ||
792 | { 3, 21514, 3, 19362, }, | ||
793 | { 3, 21602, 3, 19442, }, | ||
794 | { 3, 21426, 3, 19283, }, | ||
795 | } }, | ||
796 | { 2442, { | ||
797 | { 3, 21470, 3, 19323, }, | ||
798 | { 3, 21558, 3, 19402, }, | ||
799 | { 3, 21382, 3, 19244, }, | ||
800 | } }, | ||
801 | { 2447, { | ||
802 | { 3, 21426, 3, 19283, }, | ||
803 | { 3, 21514, 3, 19362, }, | ||
804 | { 3, 21339, 3, 19205, }, | ||
805 | } }, | ||
806 | { 2452, { | ||
807 | { 3, 21382, 3, 19244, }, | ||
808 | { 3, 21470, 3, 19323, }, | ||
809 | { 3, 21295, 3, 19166, }, | ||
810 | } }, | ||
811 | { 2457, { | ||
812 | { 3, 21339, 3, 19205, }, | ||
813 | { 3, 21426, 3, 19283, }, | ||
814 | { 3, 21252, 3, 19127, }, | ||
815 | } }, | ||
816 | { 2462, { | ||
817 | { 3, 21295, 3, 19166, }, | ||
818 | { 3, 21382, 3, 19244, }, | ||
819 | { 3, 21209, 3, 19088, }, | ||
820 | } }, | ||
821 | { 2467, { | ||
822 | { 3, 21252, 3, 19127, }, | ||
823 | { 3, 21339, 3, 19205, }, | ||
824 | { 3, 21166, 3, 19050, }, | ||
825 | } }, | ||
826 | { 2472, { | ||
827 | { 3, 21209, 3, 19088, }, | ||
828 | { 3, 21295, 3, 19166, }, | ||
829 | { 3, 21124, 3, 19011, }, | ||
830 | } }, | ||
831 | { 2484, { | ||
832 | { 3, 21107, 3, 18996, }, | ||
833 | { 3, 21192, 3, 19073, }, | ||
834 | { 3, 21022, 3, 18920, }, | ||
835 | } }, | ||
836 | { 4920, { | ||
837 | { 4, 21313, 4, 19181, }, | ||
838 | { 4, 21356, 4, 19220, }, | ||
839 | { 4, 21269, 4, 19142, }, | ||
840 | } }, | ||
841 | { 4940, { | ||
842 | { 4, 21226, 4, 19104, }, | ||
843 | { 4, 21269, 4, 19142, }, | ||
844 | { 4, 21183, 4, 19065, }, | ||
845 | } }, | ||
846 | { 4960, { | ||
847 | { 4, 21141, 4, 19027, }, | ||
848 | { 4, 21183, 4, 19065, }, | ||
849 | { 4, 21098, 4, 18988, }, | ||
850 | } }, | ||
851 | { 4980, { | ||
852 | { 4, 21056, 4, 18950, }, | ||
853 | { 4, 21098, 4, 18988, }, | ||
854 | { 4, 21014, 4, 18912, }, | ||
855 | } }, | ||
856 | { 5040, { | ||
857 | { 4, 20805, 4, 18725, }, | ||
858 | { 4, 20846, 4, 18762, }, | ||
859 | { 4, 20764, 4, 18687, }, | ||
860 | } }, | ||
861 | { 5060, { | ||
862 | { 4, 20723, 4, 18651, }, | ||
863 | { 4, 20764, 4, 18687, }, | ||
864 | { 4, 20682, 4, 18614, }, | ||
865 | } }, | ||
866 | { 5080, { | ||
867 | { 4, 20641, 4, 18577, }, | ||
868 | { 4, 20682, 4, 18614, }, | ||
869 | { 4, 20601, 4, 18541, }, | ||
870 | } }, | ||
871 | { 5180, { | ||
872 | { 4, 20243, 4, 18219, }, | ||
873 | { 4, 20282, 4, 18254, }, | ||
874 | { 4, 20204, 4, 18183, }, | ||
875 | } }, | ||
876 | { 5200, { | ||
877 | { 4, 20165, 4, 18148, }, | ||
878 | { 4, 20204, 4, 18183, }, | ||
879 | { 4, 20126, 4, 18114, }, | ||
880 | } }, | ||
881 | { 5220, { | ||
882 | { 4, 20088, 4, 18079, }, | ||
883 | { 4, 20126, 4, 18114, }, | ||
884 | { 4, 20049, 4, 18044, }, | ||
885 | } }, | ||
886 | { 5240, { | ||
887 | { 4, 20011, 4, 18010, }, | ||
888 | { 4, 20049, 4, 18044, }, | ||
889 | { 4, 19973, 4, 17976, }, | ||
890 | } }, | ||
891 | { 5260, { | ||
892 | { 4, 19935, 4, 17941, }, | ||
893 | { 4, 19973, 4, 17976, }, | ||
894 | { 4, 19897, 4, 17907, }, | ||
895 | } }, | ||
896 | { 5280, { | ||
897 | { 4, 19859, 4, 17873, }, | ||
898 | { 4, 19897, 4, 17907, }, | ||
899 | { 4, 19822, 4, 17840, }, | ||
900 | } }, | ||
901 | { 5300, { | ||
902 | { 4, 19784, 4, 17806, }, | ||
903 | { 4, 19822, 4, 17840, }, | ||
904 | { 4, 19747, 4, 17772, }, | ||
905 | } }, | ||
906 | { 5320, { | ||
907 | { 4, 19710, 4, 17739, }, | ||
908 | { 4, 19747, 4, 17772, }, | ||
909 | { 4, 19673, 4, 17706, }, | ||
910 | } }, | ||
911 | { 5500, { | ||
912 | { 4, 19065, 4, 17159, }, | ||
913 | { 4, 19100, 4, 17190, }, | ||
914 | { 4, 19030, 4, 17127, }, | ||
915 | } }, | ||
916 | { 5520, { | ||
917 | { 4, 18996, 4, 17096, }, | ||
918 | { 4, 19030, 4, 17127, }, | ||
919 | { 4, 18962, 4, 17065, }, | ||
920 | } }, | ||
921 | { 5540, { | ||
922 | { 4, 18927, 4, 17035, }, | ||
923 | { 4, 18962, 4, 17065, }, | ||
924 | { 4, 18893, 4, 17004, }, | ||
925 | } }, | ||
926 | { 5560, { | ||
927 | { 4, 18859, 4, 16973, }, | ||
928 | { 4, 18893, 4, 17004, }, | ||
929 | { 4, 18825, 4, 16943, }, | ||
930 | } }, | ||
931 | { 5580, { | ||
932 | { 4, 18792, 4, 16913, }, | ||
933 | { 4, 18825, 4, 16943, }, | ||
934 | { 4, 18758, 4, 16882, }, | ||
935 | } }, | ||
936 | { 5600, { | ||
937 | { 4, 18725, 4, 16852, }, | ||
938 | { 4, 18758, 4, 16882, }, | ||
939 | { 4, 18691, 4, 16822, }, | ||
940 | } }, | ||
941 | { 5620, { | ||
942 | { 4, 18658, 4, 16792, }, | ||
943 | { 4, 18691, 4, 16822, }, | ||
944 | { 4, 18625, 4, 16762, }, | ||
945 | } }, | ||
946 | { 5640, { | ||
947 | { 4, 18592, 4, 16733, }, | ||
948 | { 4, 18625, 4, 16762, }, | ||
949 | { 4, 18559, 4, 16703, }, | ||
950 | } }, | ||
951 | { 5660, { | ||
952 | { 4, 18526, 4, 16673, }, | ||
953 | { 4, 18559, 4, 16703, }, | ||
954 | { 4, 18493, 4, 16644, }, | ||
955 | } }, | ||
956 | { 5680, { | ||
957 | { 4, 18461, 4, 16615, }, | ||
958 | { 4, 18493, 4, 16644, }, | ||
959 | { 4, 18428, 4, 16586, }, | ||
960 | } }, | ||
961 | { 5700, { | ||
962 | { 4, 18396, 4, 16556, }, | ||
963 | { 4, 18428, 4, 16586, }, | ||
964 | { 4, 18364, 4, 16527, }, | ||
965 | } }, | ||
966 | { 5745, { | ||
967 | { 4, 18252, 4, 16427, }, | ||
968 | { 4, 18284, 4, 16455, }, | ||
969 | { 4, 18220, 4, 16398, }, | ||
970 | } }, | ||
971 | { 5765, { | ||
972 | { 4, 18189, 5, 32740, }, | ||
973 | { 4, 18220, 4, 16398, }, | ||
974 | { 4, 18157, 5, 32683, }, | ||
975 | } }, | ||
976 | { 5785, { | ||
977 | { 4, 18126, 5, 32626, }, | ||
978 | { 4, 18157, 5, 32683, }, | ||
979 | { 4, 18094, 5, 32570, }, | ||
980 | } }, | ||
981 | { 5805, { | ||
982 | { 4, 18063, 5, 32514, }, | ||
983 | { 4, 18094, 5, 32570, }, | ||
984 | { 4, 18032, 5, 32458, }, | ||
985 | } }, | ||
986 | { 5825, { | ||
987 | { 4, 18001, 5, 32402, }, | ||
988 | { 4, 18032, 5, 32458, }, | ||
989 | { 4, 17970, 5, 32347, }, | ||
990 | } }, | ||
991 | { 5170, { | ||
992 | { 4, 20282, 4, 18254, }, | ||
993 | { 4, 20321, 4, 18289, }, | ||
994 | { 4, 20243, 4, 18219, }, | ||
995 | } }, | ||
996 | { 5190, { | ||
997 | { 4, 20204, 4, 18183, }, | ||
998 | { 4, 20243, 4, 18219, }, | ||
999 | { 4, 20165, 4, 18148, }, | ||
1000 | } }, | ||
1001 | { 5210, { | ||
1002 | { 4, 20126, 4, 18114, }, | ||
1003 | { 4, 20165, 4, 18148, }, | ||
1004 | { 4, 20088, 4, 18079, }, | ||
1005 | } }, | ||
1006 | { 5230, { | ||
1007 | { 4, 20049, 4, 18044, }, | ||
1008 | { 4, 20088, 4, 18079, }, | ||
1009 | { 4, 20011, 4, 18010, }, | ||
1010 | } }, | ||
1011 | }; | ||
1012 | |||
1013 | static const struct ar9170_phy_freq_params * | ||
1014 | ar9170_get_hw_dyn_params(struct ieee80211_channel *channel, | ||
1015 | enum ar9170_bw bw) | ||
1016 | { | ||
1017 | unsigned int chanidx = 0; | ||
1018 | u16 freq = 2412; | ||
1019 | |||
1020 | if (channel) { | ||
1021 | chanidx = channel->hw_value; | ||
1022 | freq = channel->center_freq; | ||
1023 | } | ||
1024 | |||
1025 | BUG_ON(chanidx >= ARRAY_SIZE(ar9170_phy_freq_params)); | ||
1026 | |||
1027 | BUILD_BUG_ON(__AR9170_NUM_BW != 3); | ||
1028 | |||
1029 | WARN_ON(ar9170_phy_freq_params[chanidx].freq != freq); | ||
1030 | |||
1031 | return &ar9170_phy_freq_params[chanidx].params[bw]; | ||
1032 | } | ||
1033 | |||
1034 | |||
1035 | int ar9170_init_rf(struct ar9170 *ar) | ||
1036 | { | ||
1037 | const struct ar9170_phy_freq_params *freqpar; | ||
1038 | __le32 cmd[7]; | ||
1039 | int err; | ||
1040 | |||
1041 | err = ar9170_init_rf_banks_0_7(ar, false); | ||
1042 | if (err) | ||
1043 | return err; | ||
1044 | |||
1045 | err = ar9170_init_rf_bank4_pwr(ar, false, 2412, AR9170_BW_20); | ||
1046 | if (err) | ||
1047 | return err; | ||
1048 | |||
1049 | freqpar = ar9170_get_hw_dyn_params(NULL, AR9170_BW_20); | ||
1050 | |||
1051 | cmd[0] = cpu_to_le32(2412 * 1000); | ||
1052 | cmd[1] = cpu_to_le32(0); | ||
1053 | cmd[2] = cpu_to_le32(1); | ||
1054 | cmd[3] = cpu_to_le32(freqpar->coeff_exp); | ||
1055 | cmd[4] = cpu_to_le32(freqpar->coeff_man); | ||
1056 | cmd[5] = cpu_to_le32(freqpar->coeff_exp_shgi); | ||
1057 | cmd[6] = cpu_to_le32(freqpar->coeff_man_shgi); | ||
1058 | |||
1059 | /* RF_INIT echoes the command back to us */ | ||
1060 | err = ar->exec_cmd(ar, AR9170_CMD_RF_INIT, | ||
1061 | sizeof(cmd), (u8 *)cmd, | ||
1062 | sizeof(cmd), (u8 *)cmd); | ||
1063 | if (err) | ||
1064 | return err; | ||
1065 | |||
1066 | msleep(1000); | ||
1067 | |||
1068 | return ar9170_echo_test(ar, 0xaabbccdd); | ||
1069 | } | ||
1070 | |||
1071 | static int ar9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f) | ||
1072 | { | ||
1073 | int idx = nfreqs - 2; | ||
1074 | |||
1075 | while (idx >= 0) { | ||
1076 | if (f >= freqs[idx]) | ||
1077 | return idx; | ||
1078 | idx--; | ||
1079 | } | ||
1080 | |||
1081 | return 0; | ||
1082 | } | ||
1083 | |||
1084 | static s32 ar9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2) | ||
1085 | { | ||
1086 | /* nothing to interpolate, it's horizontal */ | ||
1087 | if (y2 == y1) | ||
1088 | return y1; | ||
1089 | |||
1090 | /* check if we hit one of the edges */ | ||
1091 | if (x == x1) | ||
1092 | return y1; | ||
1093 | if (x == x2) | ||
1094 | return y2; | ||
1095 | |||
1096 | /* x1 == x2 is bad, hopefully == x */ | ||
1097 | if (x2 == x1) | ||
1098 | return y1; | ||
1099 | |||
1100 | return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1)); | ||
1101 | } | ||
1102 | |||
1103 | static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2) | ||
1104 | { | ||
1105 | #define SHIFT 8 | ||
1106 | s32 y; | ||
1107 | |||
1108 | y = ar9170_interpolate_s32(x << SHIFT, | ||
1109 | x1 << SHIFT, y1 << SHIFT, | ||
1110 | x2 << SHIFT, y2 << SHIFT); | ||
1111 | |||
1112 | /* | ||
1113 | * XXX: unwrap this expression | ||
1114 | * Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)? | ||
1115 | * Can we rely on the compiler to optimise away the div? | ||
1116 | */ | ||
1117 | return (y >> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1)); | ||
1118 | #undef SHIFT | ||
1119 | } | ||
1120 | |||
1121 | static u8 ar9170_interpolate_val(u8 x, u8 *x_array, u8 *y_array) | ||
1122 | { | ||
1123 | int i; | ||
1124 | |||
1125 | for (i = 0; i < 3; i++) | ||
1126 | if (x <= x_array[i + 1]) | ||
1127 | break; | ||
1128 | |||
1129 | return ar9170_interpolate_u8(x, | ||
1130 | x_array[i], | ||
1131 | y_array[i], | ||
1132 | x_array[i + 1], | ||
1133 | y_array[i + 1]); | ||
1134 | } | ||
1135 | |||
1136 | static int ar9170_set_freq_cal_data(struct ar9170 *ar, | ||
1137 | struct ieee80211_channel *channel) | ||
1138 | { | ||
1139 | u8 *cal_freq_pier; | ||
1140 | u8 vpds[2][AR5416_PD_GAIN_ICEPTS]; | ||
1141 | u8 pwrs[2][AR5416_PD_GAIN_ICEPTS]; | ||
1142 | int chain, idx, i; | ||
1143 | u32 phy_data = 0; | ||
1144 | u8 f, tmp; | ||
1145 | |||
1146 | switch (channel->band) { | ||
1147 | case IEEE80211_BAND_2GHZ: | ||
1148 | f = channel->center_freq - 2300; | ||
1149 | cal_freq_pier = ar->eeprom.cal_freq_pier_2G; | ||
1150 | i = AR5416_NUM_2G_CAL_PIERS - 1; | ||
1151 | break; | ||
1152 | |||
1153 | case IEEE80211_BAND_5GHZ: | ||
1154 | f = (channel->center_freq - 4800) / 5; | ||
1155 | cal_freq_pier = ar->eeprom.cal_freq_pier_5G; | ||
1156 | i = AR5416_NUM_5G_CAL_PIERS - 1; | ||
1157 | break; | ||
1158 | |||
1159 | default: | ||
1160 | return -EINVAL; | ||
1161 | break; | ||
1162 | } | ||
1163 | |||
1164 | for (; i >= 0; i--) { | ||
1165 | if (cal_freq_pier[i] != 0xff) | ||
1166 | break; | ||
1167 | } | ||
1168 | if (i < 0) | ||
1169 | return -EINVAL; | ||
1170 | |||
1171 | idx = ar9170_find_freq_idx(i, cal_freq_pier, f); | ||
1172 | |||
1173 | ar9170_regwrite_begin(ar); | ||
1174 | |||
1175 | for (chain = 0; chain < AR5416_MAX_CHAINS; chain++) { | ||
1176 | for (i = 0; i < AR5416_PD_GAIN_ICEPTS; i++) { | ||
1177 | struct ar9170_calibration_data_per_freq *cal_pier_data; | ||
1178 | int j; | ||
1179 | |||
1180 | switch (channel->band) { | ||
1181 | case IEEE80211_BAND_2GHZ: | ||
1182 | cal_pier_data = &ar->eeprom. | ||
1183 | cal_pier_data_2G[chain][idx]; | ||
1184 | break; | ||
1185 | |||
1186 | case IEEE80211_BAND_5GHZ: | ||
1187 | cal_pier_data = &ar->eeprom. | ||
1188 | cal_pier_data_5G[chain][idx]; | ||
1189 | break; | ||
1190 | |||
1191 | default: | ||
1192 | return -EINVAL; | ||
1193 | } | ||
1194 | |||
1195 | for (j = 0; j < 2; j++) { | ||
1196 | vpds[j][i] = ar9170_interpolate_u8(f, | ||
1197 | cal_freq_pier[idx], | ||
1198 | cal_pier_data->vpd_pdg[j][i], | ||
1199 | cal_freq_pier[idx + 1], | ||
1200 | cal_pier_data[1].vpd_pdg[j][i]); | ||
1201 | |||
1202 | pwrs[j][i] = ar9170_interpolate_u8(f, | ||
1203 | cal_freq_pier[idx], | ||
1204 | cal_pier_data->pwr_pdg[j][i], | ||
1205 | cal_freq_pier[idx + 1], | ||
1206 | cal_pier_data[1].pwr_pdg[j][i]) / 2; | ||
1207 | } | ||
1208 | } | ||
1209 | |||
1210 | for (i = 0; i < 76; i++) { | ||
1211 | if (i < 25) { | ||
1212 | tmp = ar9170_interpolate_val(i, &pwrs[0][0], | ||
1213 | &vpds[0][0]); | ||
1214 | } else { | ||
1215 | tmp = ar9170_interpolate_val(i - 12, | ||
1216 | &pwrs[1][0], | ||
1217 | &vpds[1][0]); | ||
1218 | } | ||
1219 | |||
1220 | phy_data |= tmp << ((i & 3) << 3); | ||
1221 | if ((i & 3) == 3) { | ||
1222 | ar9170_regwrite(0x1c6280 + chain * 0x1000 + | ||
1223 | (i & ~3), phy_data); | ||
1224 | phy_data = 0; | ||
1225 | } | ||
1226 | } | ||
1227 | |||
1228 | for (i = 19; i < 32; i++) | ||
1229 | ar9170_regwrite(0x1c6280 + chain * 0x1000 + (i << 2), | ||
1230 | 0x0); | ||
1231 | } | ||
1232 | |||
1233 | ar9170_regwrite_finish(); | ||
1234 | return ar9170_regwrite_result(); | ||
1235 | } | ||
1236 | |||
1237 | static u8 ar9170_get_max_edge_power(struct ar9170 *ar, | ||
1238 | struct ar9170_calctl_edges edges[], | ||
1239 | u32 freq) | ||
1240 | { | ||
1241 | int i; | ||
1242 | u8 rc = AR5416_MAX_RATE_POWER; | ||
1243 | u8 f; | ||
1244 | if (freq < 3000) | ||
1245 | f = freq - 2300; | ||
1246 | else | ||
1247 | f = (freq - 4800) / 5; | ||
1248 | |||
1249 | for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) { | ||
1250 | if (edges[i].channel == 0xff) | ||
1251 | break; | ||
1252 | if (f == edges[i].channel) { | ||
1253 | /* exact freq match */ | ||
1254 | rc = edges[i].power_flags & ~AR9170_CALCTL_EDGE_FLAGS; | ||
1255 | break; | ||
1256 | } | ||
1257 | if (i > 0 && f < edges[i].channel) { | ||
1258 | if (f > edges[i - 1].channel && | ||
1259 | edges[i - 1].power_flags & | ||
1260 | AR9170_CALCTL_EDGE_FLAGS) { | ||
1261 | /* lower channel has the inband flag set */ | ||
1262 | rc = edges[i - 1].power_flags & | ||
1263 | ~AR9170_CALCTL_EDGE_FLAGS; | ||
1264 | } | ||
1265 | break; | ||
1266 | } | ||
1267 | } | ||
1268 | |||
1269 | if (i == AR5416_NUM_BAND_EDGES) { | ||
1270 | if (f > edges[i - 1].channel && | ||
1271 | edges[i - 1].power_flags & AR9170_CALCTL_EDGE_FLAGS) { | ||
1272 | /* lower channel has the inband flag set */ | ||
1273 | rc = edges[i - 1].power_flags & | ||
1274 | ~AR9170_CALCTL_EDGE_FLAGS; | ||
1275 | } | ||
1276 | } | ||
1277 | return rc; | ||
1278 | } | ||
1279 | |||
1280 | static u8 ar9170_get_heavy_clip(struct ar9170 *ar, | ||
1281 | struct ar9170_calctl_edges edges[], | ||
1282 | u32 freq, enum ar9170_bw bw) | ||
1283 | { | ||
1284 | u8 f; | ||
1285 | int i; | ||
1286 | u8 rc = 0; | ||
1287 | |||
1288 | if (freq < 3000) | ||
1289 | f = freq - 2300; | ||
1290 | else | ||
1291 | f = (freq - 4800) / 5; | ||
1292 | |||
1293 | if (bw == AR9170_BW_40_BELOW || bw == AR9170_BW_40_ABOVE) | ||
1294 | rc |= 0xf0; | ||
1295 | |||
1296 | for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) { | ||
1297 | if (edges[i].channel == 0xff) | ||
1298 | break; | ||
1299 | if (f == edges[i].channel) { | ||
1300 | if (!(edges[i].power_flags & AR9170_CALCTL_EDGE_FLAGS)) | ||
1301 | rc |= 0x0f; | ||
1302 | break; | ||
1303 | } | ||
1304 | } | ||
1305 | |||
1306 | return rc; | ||
1307 | } | ||
1308 | |||
1309 | /* | ||
1310 | * calculate the conformance test limits and the heavy clip parameter | ||
1311 | * and apply them to ar->power* (derived from otus hal/hpmain.c, line 3706) | ||
1312 | */ | ||
1313 | static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) | ||
1314 | { | ||
1315 | u8 ctl_grp; /* CTL group */ | ||
1316 | u8 ctl_idx; /* CTL index */ | ||
1317 | int i, j; | ||
1318 | struct ctl_modes { | ||
1319 | u8 ctl_mode; | ||
1320 | u8 max_power; | ||
1321 | u8 *pwr_cal_data; | ||
1322 | int pwr_cal_len; | ||
1323 | } *modes; | ||
1324 | |||
1325 | /* | ||
1326 | * order is relevant in the mode_list_*: we fall back to the | ||
1327 | * lower indices if any mode is missed in the EEPROM. | ||
1328 | */ | ||
1329 | struct ctl_modes mode_list_2ghz[] = { | ||
1330 | { CTL_11B, 0, ar->power_2G_cck, 4 }, | ||
1331 | { CTL_11G, 0, ar->power_2G_ofdm, 4 }, | ||
1332 | { CTL_2GHT20, 0, ar->power_2G_ht20, 8 }, | ||
1333 | { CTL_2GHT40, 0, ar->power_2G_ht40, 8 }, | ||
1334 | }; | ||
1335 | struct ctl_modes mode_list_5ghz[] = { | ||
1336 | { CTL_11A, 0, ar->power_5G_leg, 4 }, | ||
1337 | { CTL_5GHT20, 0, ar->power_5G_ht20, 8 }, | ||
1338 | { CTL_5GHT40, 0, ar->power_5G_ht40, 8 }, | ||
1339 | }; | ||
1340 | int nr_modes; | ||
1341 | |||
1342 | #define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n]) | ||
1343 | |||
1344 | ar->phy_heavy_clip = 0; | ||
1345 | |||
1346 | /* | ||
1347 | * TODO: investigate the differences between OTUS' | ||
1348 | * hpreg.c::zfHpGetRegulatoryDomain() and | ||
1349 | * ath/regd.c::ath_regd_get_band_ctl() - | ||
1350 | * e.g. for FCC3_WORLD the OTUS procedure | ||
1351 | * always returns CTL_FCC, while the one in ath/ delivers | ||
1352 | * CTL_ETSI for 2GHz and CTL_FCC for 5GHz. | ||
1353 | */ | ||
1354 | ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory, | ||
1355 | ar->hw->conf.channel->band); | ||
1356 | |||
1357 | /* ctl group not found - either invalid band (NO_CTL) or ww roaming */ | ||
1358 | if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL) | ||
1359 | ctl_grp = CTL_FCC; | ||
1360 | |||
1361 | if (ctl_grp != CTL_FCC) | ||
1362 | /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */ | ||
1363 | return; | ||
1364 | |||
1365 | if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { | ||
1366 | modes = mode_list_2ghz; | ||
1367 | nr_modes = ARRAY_SIZE(mode_list_2ghz); | ||
1368 | } else { | ||
1369 | modes = mode_list_5ghz; | ||
1370 | nr_modes = ARRAY_SIZE(mode_list_5ghz); | ||
1371 | } | ||
1372 | |||
1373 | for (i = 0; i < nr_modes; i++) { | ||
1374 | u8 c = ctl_grp | modes[i].ctl_mode; | ||
1375 | for (ctl_idx = 0; ctl_idx < AR5416_NUM_CTLS; ctl_idx++) | ||
1376 | if (c == ar->eeprom.ctl_index[ctl_idx]) | ||
1377 | break; | ||
1378 | if (ctl_idx < AR5416_NUM_CTLS) { | ||
1379 | int f_off = 0; | ||
1380 | |||
1381 | /* determine heav clip parameter from | ||
1382 | the 11G edges array */ | ||
1383 | if (modes[i].ctl_mode == CTL_11G) { | ||
1384 | ar->phy_heavy_clip = | ||
1385 | ar9170_get_heavy_clip(ar, | ||
1386 | EDGES(ctl_idx, 1), | ||
1387 | freq, bw); | ||
1388 | } | ||
1389 | |||
1390 | /* adjust freq for 40MHz */ | ||
1391 | if (modes[i].ctl_mode == CTL_2GHT40 || | ||
1392 | modes[i].ctl_mode == CTL_5GHT40) { | ||
1393 | if (bw == AR9170_BW_40_BELOW) | ||
1394 | f_off = -10; | ||
1395 | else | ||
1396 | f_off = 10; | ||
1397 | } | ||
1398 | |||
1399 | modes[i].max_power = | ||
1400 | ar9170_get_max_edge_power(ar, EDGES(ctl_idx, 1), | ||
1401 | freq+f_off); | ||
1402 | |||
1403 | /* | ||
1404 | * TODO: check if the regulatory max. power is | ||
1405 | * controlled by cfg80211 for DFS | ||
1406 | * (hpmain applies it to max_power itself for DFS freq) | ||
1407 | */ | ||
1408 | |||
1409 | } else { | ||
1410 | /* | ||
1411 | * Workaround in otus driver, hpmain.c, line 3906: | ||
1412 | * if no data for 5GHT20 are found, take the | ||
1413 | * legacy 5G value. | ||
1414 | * We extend this here to fallback from any other *HT or | ||
1415 | * 11G, too. | ||
1416 | */ | ||
1417 | int k = i; | ||
1418 | |||
1419 | modes[i].max_power = AR5416_MAX_RATE_POWER; | ||
1420 | while (k-- > 0) { | ||
1421 | if (modes[k].max_power != | ||
1422 | AR5416_MAX_RATE_POWER) { | ||
1423 | modes[i].max_power = modes[k].max_power; | ||
1424 | break; | ||
1425 | } | ||
1426 | } | ||
1427 | } | ||
1428 | |||
1429 | /* apply max power to pwr_cal_data (ar->power_*) */ | ||
1430 | for (j = 0; j < modes[i].pwr_cal_len; j++) { | ||
1431 | modes[i].pwr_cal_data[j] = min(modes[i].pwr_cal_data[j], | ||
1432 | modes[i].max_power); | ||
1433 | } | ||
1434 | } | ||
1435 | |||
1436 | if (ar->phy_heavy_clip & 0xf0) { | ||
1437 | ar->power_2G_ht40[0]--; | ||
1438 | ar->power_2G_ht40[1]--; | ||
1439 | ar->power_2G_ht40[2]--; | ||
1440 | } | ||
1441 | if (ar->phy_heavy_clip & 0xf) { | ||
1442 | ar->power_2G_ht20[0]++; | ||
1443 | ar->power_2G_ht20[1]++; | ||
1444 | ar->power_2G_ht20[2]++; | ||
1445 | } | ||
1446 | |||
1447 | |||
1448 | #undef EDGES | ||
1449 | } | ||
1450 | |||
1451 | static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) | ||
1452 | { | ||
1453 | struct ar9170_calibration_target_power_legacy *ctpl; | ||
1454 | struct ar9170_calibration_target_power_ht *ctph; | ||
1455 | u8 *ctpres; | ||
1456 | int ntargets; | ||
1457 | int idx, i, n; | ||
1458 | u8 ackpower, ackchains, f; | ||
1459 | u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS]; | ||
1460 | |||
1461 | if (freq < 3000) | ||
1462 | f = freq - 2300; | ||
1463 | else | ||
1464 | f = (freq - 4800)/5; | ||
1465 | |||
1466 | /* | ||
1467 | * cycle through the various modes | ||
1468 | * | ||
1469 | * legacy modes first: 5G, 2G CCK, 2G OFDM | ||
1470 | */ | ||
1471 | for (i = 0; i < 3; i++) { | ||
1472 | switch (i) { | ||
1473 | case 0: /* 5 GHz legacy */ | ||
1474 | ctpl = &ar->eeprom.cal_tgt_pwr_5G[0]; | ||
1475 | ntargets = AR5416_NUM_5G_TARGET_PWRS; | ||
1476 | ctpres = ar->power_5G_leg; | ||
1477 | break; | ||
1478 | case 1: /* 2.4 GHz CCK */ | ||
1479 | ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0]; | ||
1480 | ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS; | ||
1481 | ctpres = ar->power_2G_cck; | ||
1482 | break; | ||
1483 | case 2: /* 2.4 GHz OFDM */ | ||
1484 | ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0]; | ||
1485 | ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; | ||
1486 | ctpres = ar->power_2G_ofdm; | ||
1487 | break; | ||
1488 | default: | ||
1489 | BUG(); | ||
1490 | } | ||
1491 | |||
1492 | for (n = 0; n < ntargets; n++) { | ||
1493 | if (ctpl[n].freq == 0xff) | ||
1494 | break; | ||
1495 | pwr_freqs[n] = ctpl[n].freq; | ||
1496 | } | ||
1497 | ntargets = n; | ||
1498 | idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f); | ||
1499 | for (n = 0; n < 4; n++) | ||
1500 | ctpres[n] = ar9170_interpolate_u8( | ||
1501 | f, | ||
1502 | ctpl[idx + 0].freq, | ||
1503 | ctpl[idx + 0].power[n], | ||
1504 | ctpl[idx + 1].freq, | ||
1505 | ctpl[idx + 1].power[n]); | ||
1506 | } | ||
1507 | |||
1508 | /* | ||
1509 | * HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40 | ||
1510 | */ | ||
1511 | for (i = 0; i < 4; i++) { | ||
1512 | switch (i) { | ||
1513 | case 0: /* 5 GHz HT 20 */ | ||
1514 | ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0]; | ||
1515 | ntargets = AR5416_NUM_5G_TARGET_PWRS; | ||
1516 | ctpres = ar->power_5G_ht20; | ||
1517 | break; | ||
1518 | case 1: /* 5 GHz HT 40 */ | ||
1519 | ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0]; | ||
1520 | ntargets = AR5416_NUM_5G_TARGET_PWRS; | ||
1521 | ctpres = ar->power_5G_ht40; | ||
1522 | break; | ||
1523 | case 2: /* 2.4 GHz HT 20 */ | ||
1524 | ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0]; | ||
1525 | ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; | ||
1526 | ctpres = ar->power_2G_ht20; | ||
1527 | break; | ||
1528 | case 3: /* 2.4 GHz HT 40 */ | ||
1529 | ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0]; | ||
1530 | ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; | ||
1531 | ctpres = ar->power_2G_ht40; | ||
1532 | break; | ||
1533 | default: | ||
1534 | BUG(); | ||
1535 | } | ||
1536 | |||
1537 | for (n = 0; n < ntargets; n++) { | ||
1538 | if (ctph[n].freq == 0xff) | ||
1539 | break; | ||
1540 | pwr_freqs[n] = ctph[n].freq; | ||
1541 | } | ||
1542 | ntargets = n; | ||
1543 | idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f); | ||
1544 | for (n = 0; n < 8; n++) | ||
1545 | ctpres[n] = ar9170_interpolate_u8( | ||
1546 | f, | ||
1547 | ctph[idx + 0].freq, | ||
1548 | ctph[idx + 0].power[n], | ||
1549 | ctph[idx + 1].freq, | ||
1550 | ctph[idx + 1].power[n]); | ||
1551 | } | ||
1552 | |||
1553 | |||
1554 | /* calc. conformance test limits and apply to ar->power*[] */ | ||
1555 | ar9170_calc_ctl(ar, freq, bw); | ||
1556 | |||
1557 | /* set ACK/CTS TX power */ | ||
1558 | ar9170_regwrite_begin(ar); | ||
1559 | |||
1560 | if (ar->eeprom.tx_mask != 1) | ||
1561 | ackchains = AR9170_TX_PHY_TXCHAIN_2; | ||
1562 | else | ||
1563 | ackchains = AR9170_TX_PHY_TXCHAIN_1; | ||
1564 | |||
1565 | if (freq < 3000) | ||
1566 | ackpower = ar->power_2G_ofdm[0] & 0x3f; | ||
1567 | else | ||
1568 | ackpower = ar->power_5G_leg[0] & 0x3f; | ||
1569 | |||
1570 | ar9170_regwrite(0x1c3694, ackpower << 20 | ackchains << 26); | ||
1571 | ar9170_regwrite(0x1c3bb4, ackpower << 5 | ackchains << 11 | | ||
1572 | ackpower << 21 | ackchains << 27); | ||
1573 | |||
1574 | ar9170_regwrite_finish(); | ||
1575 | return ar9170_regwrite_result(); | ||
1576 | } | ||
1577 | |||
1578 | static int ar9170_calc_noise_dbm(u32 raw_noise) | ||
1579 | { | ||
1580 | if (raw_noise & 0x100) | ||
1581 | return ~((raw_noise & 0x0ff) >> 1); | ||
1582 | else | ||
1583 | return (raw_noise & 0xff) >> 1; | ||
1584 | } | ||
1585 | |||
1586 | int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, | ||
1587 | enum ar9170_rf_init_mode rfi, enum ar9170_bw bw) | ||
1588 | { | ||
1589 | const struct ar9170_phy_freq_params *freqpar; | ||
1590 | u32 cmd, tmp, offs; | ||
1591 | __le32 vals[8]; | ||
1592 | int i, err; | ||
1593 | bool bandswitch; | ||
1594 | |||
1595 | /* clear BB heavy clip enable */ | ||
1596 | err = ar9170_write_reg(ar, 0x1c59e0, 0x200); | ||
1597 | if (err) | ||
1598 | return err; | ||
1599 | |||
1600 | /* may be NULL at first setup */ | ||
1601 | if (ar->channel) | ||
1602 | bandswitch = ar->channel->band != channel->band; | ||
1603 | else | ||
1604 | bandswitch = true; | ||
1605 | |||
1606 | /* HW workaround */ | ||
1607 | if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] && | ||
1608 | channel->center_freq <= 2417) | ||
1609 | bandswitch = true; | ||
1610 | |||
1611 | err = ar->exec_cmd(ar, AR9170_CMD_FREQ_START, 0, NULL, 0, NULL); | ||
1612 | if (err) | ||
1613 | return err; | ||
1614 | |||
1615 | if (rfi != AR9170_RFI_NONE || bandswitch) { | ||
1616 | u32 val = 0x400; | ||
1617 | |||
1618 | if (rfi == AR9170_RFI_COLD) | ||
1619 | val = 0x800; | ||
1620 | |||
1621 | /* warm/cold reset BB/ADDA */ | ||
1622 | err = ar9170_write_reg(ar, 0x1d4004, val); | ||
1623 | if (err) | ||
1624 | return err; | ||
1625 | |||
1626 | err = ar9170_write_reg(ar, 0x1d4004, 0x0); | ||
1627 | if (err) | ||
1628 | return err; | ||
1629 | |||
1630 | err = ar9170_init_phy(ar, channel->band); | ||
1631 | if (err) | ||
1632 | return err; | ||
1633 | |||
1634 | err = ar9170_init_rf_banks_0_7(ar, | ||
1635 | channel->band == IEEE80211_BAND_5GHZ); | ||
1636 | if (err) | ||
1637 | return err; | ||
1638 | |||
1639 | cmd = AR9170_CMD_RF_INIT; | ||
1640 | } else { | ||
1641 | cmd = AR9170_CMD_FREQUENCY; | ||
1642 | } | ||
1643 | |||
1644 | err = ar9170_init_rf_bank4_pwr(ar, | ||
1645 | channel->band == IEEE80211_BAND_5GHZ, | ||
1646 | channel->center_freq, bw); | ||
1647 | if (err) | ||
1648 | return err; | ||
1649 | |||
1650 | switch (bw) { | ||
1651 | case AR9170_BW_20: | ||
1652 | tmp = 0x240; | ||
1653 | offs = 0; | ||
1654 | break; | ||
1655 | case AR9170_BW_40_BELOW: | ||
1656 | tmp = 0x2c4; | ||
1657 | offs = 3; | ||
1658 | break; | ||
1659 | case AR9170_BW_40_ABOVE: | ||
1660 | tmp = 0x2d4; | ||
1661 | offs = 1; | ||
1662 | break; | ||
1663 | default: | ||
1664 | BUG(); | ||
1665 | return -ENOSYS; | ||
1666 | } | ||
1667 | |||
1668 | if (ar->eeprom.tx_mask != 1) | ||
1669 | tmp |= 0x100; | ||
1670 | |||
1671 | err = ar9170_write_reg(ar, 0x1c5804, tmp); | ||
1672 | if (err) | ||
1673 | return err; | ||
1674 | |||
1675 | err = ar9170_set_freq_cal_data(ar, channel); | ||
1676 | if (err) | ||
1677 | return err; | ||
1678 | |||
1679 | err = ar9170_set_power_cal(ar, channel->center_freq, bw); | ||
1680 | if (err) | ||
1681 | return err; | ||
1682 | |||
1683 | freqpar = ar9170_get_hw_dyn_params(channel, bw); | ||
1684 | |||
1685 | vals[0] = cpu_to_le32(channel->center_freq * 1000); | ||
1686 | vals[1] = cpu_to_le32(conf_is_ht40(&ar->hw->conf)); | ||
1687 | vals[2] = cpu_to_le32(offs << 2 | 1); | ||
1688 | vals[3] = cpu_to_le32(freqpar->coeff_exp); | ||
1689 | vals[4] = cpu_to_le32(freqpar->coeff_man); | ||
1690 | vals[5] = cpu_to_le32(freqpar->coeff_exp_shgi); | ||
1691 | vals[6] = cpu_to_le32(freqpar->coeff_man_shgi); | ||
1692 | vals[7] = cpu_to_le32(1000); | ||
1693 | |||
1694 | err = ar->exec_cmd(ar, cmd, sizeof(vals), (u8 *)vals, | ||
1695 | sizeof(vals), (u8 *)vals); | ||
1696 | if (err) | ||
1697 | return err; | ||
1698 | |||
1699 | if (ar->phy_heavy_clip) { | ||
1700 | err = ar9170_write_reg(ar, 0x1c59e0, | ||
1701 | 0x200 | ar->phy_heavy_clip); | ||
1702 | if (err) { | ||
1703 | if (ar9170_nag_limiter(ar)) | ||
1704 | wiphy_err(ar->hw->wiphy, | ||
1705 | "failed to set heavy clip\n"); | ||
1706 | } | ||
1707 | } | ||
1708 | |||
1709 | for (i = 0; i < 2; i++) { | ||
1710 | ar->noise[i] = ar9170_calc_noise_dbm( | ||
1711 | (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff); | ||
1712 | |||
1713 | ar->noise[i + 2] = ar9170_calc_noise_dbm( | ||
1714 | (le32_to_cpu(vals[5 + i]) >> 23) & 0x1ff); | ||
1715 | } | ||
1716 | |||
1717 | ar->channel = channel; | ||
1718 | return 0; | ||
1719 | } | ||
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c deleted file mode 100644 index d3be6f9816b..00000000000 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ /dev/null | |||
@@ -1,1008 +0,0 @@ | |||
1 | /* | ||
2 | * Atheros AR9170 driver | ||
3 | * | ||
4 | * USB - frontend | ||
5 | * | ||
6 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | ||
7 | * Copyright 2009, Christian Lamparter <chunkeey@web.de> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; see the file COPYING. If not, see | ||
21 | * http://www.gnu.org/licenses/. | ||
22 | * | ||
23 | * This file incorporates work covered by the following copyright and | ||
24 | * permission notice: | ||
25 | * Copyright (c) 2007-2008 Atheros Communications, Inc. | ||
26 | * | ||
27 | * Permission to use, copy, modify, and/or distribute this software for any | ||
28 | * purpose with or without fee is hereby granted, provided that the above | ||
29 | * copyright notice and this permission notice appear in all copies. | ||
30 | * | ||
31 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
32 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
33 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
34 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
35 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
36 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
37 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
38 | */ | ||
39 | |||
40 | #include <linux/module.h> | ||
41 | #include <linux/slab.h> | ||
42 | #include <linux/usb.h> | ||
43 | #include <linux/firmware.h> | ||
44 | #include <linux/etherdevice.h> | ||
45 | #include <linux/device.h> | ||
46 | #include <net/mac80211.h> | ||
47 | #include "ar9170.h" | ||
48 | #include "cmd.h" | ||
49 | #include "hw.h" | ||
50 | #include "usb.h" | ||
51 | |||
52 | MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); | ||
53 | MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>"); | ||
54 | MODULE_LICENSE("GPL"); | ||
55 | MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless"); | ||
56 | MODULE_FIRMWARE("ar9170.fw"); | ||
57 | |||
58 | enum ar9170_requirements { | ||
59 | AR9170_REQ_FW1_ONLY = 1, | ||
60 | }; | ||
61 | |||
62 | static struct usb_device_id ar9170_usb_ids[] = { | ||
63 | /* Atheros 9170 */ | ||
64 | { USB_DEVICE(0x0cf3, 0x9170) }, | ||
65 | /* Atheros TG121N */ | ||
66 | { USB_DEVICE(0x0cf3, 0x1001) }, | ||
67 | /* TP-Link TL-WN821N v2 */ | ||
68 | { USB_DEVICE(0x0cf3, 0x1002) }, | ||
69 | /* 3Com Dual Band 802.11n USB Adapter */ | ||
70 | { USB_DEVICE(0x0cf3, 0x1010) }, | ||
71 | /* H3C Dual Band 802.11n USB Adapter */ | ||
72 | { USB_DEVICE(0x0cf3, 0x1011) }, | ||
73 | /* Cace Airpcap NX */ | ||
74 | { USB_DEVICE(0xcace, 0x0300) }, | ||
75 | /* D-Link DWA 160 A1 */ | ||
76 | { USB_DEVICE(0x07d1, 0x3c10) }, | ||
77 | /* D-Link DWA 160 A2 */ | ||
78 | { USB_DEVICE(0x07d1, 0x3a09) }, | ||
79 | /* Netgear WNA1000 */ | ||
80 | { USB_DEVICE(0x0846, 0x9040) }, | ||
81 | /* Netgear WNDA3100 */ | ||
82 | { USB_DEVICE(0x0846, 0x9010) }, | ||
83 | /* Netgear WN111 v2 */ | ||
84 | { USB_DEVICE(0x0846, 0x9001) }, | ||
85 | /* Zydas ZD1221 */ | ||
86 | { USB_DEVICE(0x0ace, 0x1221) }, | ||
87 | /* Proxim ORiNOCO 802.11n USB */ | ||
88 | { USB_DEVICE(0x1435, 0x0804) }, | ||
89 | /* WNC Generic 11n USB Dongle */ | ||
90 | { USB_DEVICE(0x1435, 0x0326) }, | ||
91 | /* ZyXEL NWD271N */ | ||
92 | { USB_DEVICE(0x0586, 0x3417) }, | ||
93 | /* Z-Com UB81 BG */ | ||
94 | { USB_DEVICE(0x0cde, 0x0023) }, | ||
95 | /* Z-Com UB82 ABG */ | ||
96 | { USB_DEVICE(0x0cde, 0x0026) }, | ||
97 | /* Sphairon Homelink 1202 */ | ||
98 | { USB_DEVICE(0x0cde, 0x0027) }, | ||
99 | /* Arcadyan WN7512 */ | ||
100 | { USB_DEVICE(0x083a, 0xf522) }, | ||
101 | /* Planex GWUS300 */ | ||
102 | { USB_DEVICE(0x2019, 0x5304) }, | ||
103 | /* IO-Data WNGDNUS2 */ | ||
104 | { USB_DEVICE(0x04bb, 0x093f) }, | ||
105 | /* AVM FRITZ!WLAN USB Stick N */ | ||
106 | { USB_DEVICE(0x057C, 0x8401) }, | ||
107 | /* NEC WL300NU-G */ | ||
108 | { USB_DEVICE(0x0409, 0x0249) }, | ||
109 | /* AVM FRITZ!WLAN USB Stick N 2.4 */ | ||
110 | { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY }, | ||
111 | /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */ | ||
112 | { USB_DEVICE(0x1668, 0x1200) }, | ||
113 | |||
114 | /* terminate */ | ||
115 | {} | ||
116 | }; | ||
117 | MODULE_DEVICE_TABLE(usb, ar9170_usb_ids); | ||
118 | |||
119 | static void ar9170_usb_submit_urb(struct ar9170_usb *aru) | ||
120 | { | ||
121 | struct urb *urb; | ||
122 | unsigned long flags; | ||
123 | int err; | ||
124 | |||
125 | if (unlikely(!IS_STARTED(&aru->common))) | ||
126 | return ; | ||
127 | |||
128 | spin_lock_irqsave(&aru->tx_urb_lock, flags); | ||
129 | if (atomic_read(&aru->tx_submitted_urbs) >= AR9170_NUM_TX_URBS) { | ||
130 | spin_unlock_irqrestore(&aru->tx_urb_lock, flags); | ||
131 | return ; | ||
132 | } | ||
133 | atomic_inc(&aru->tx_submitted_urbs); | ||
134 | |||
135 | urb = usb_get_from_anchor(&aru->tx_pending); | ||
136 | if (!urb) { | ||
137 | atomic_dec(&aru->tx_submitted_urbs); | ||
138 | spin_unlock_irqrestore(&aru->tx_urb_lock, flags); | ||
139 | |||
140 | return ; | ||
141 | } | ||
142 | spin_unlock_irqrestore(&aru->tx_urb_lock, flags); | ||
143 | |||
144 | aru->tx_pending_urbs--; | ||
145 | usb_anchor_urb(urb, &aru->tx_submitted); | ||
146 | |||
147 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
148 | if (unlikely(err)) { | ||
149 | if (ar9170_nag_limiter(&aru->common)) | ||
150 | dev_err(&aru->udev->dev, "submit_urb failed (%d).\n", | ||
151 | err); | ||
152 | |||
153 | usb_unanchor_urb(urb); | ||
154 | atomic_dec(&aru->tx_submitted_urbs); | ||
155 | ar9170_tx_callback(&aru->common, urb->context); | ||
156 | } | ||
157 | |||
158 | usb_free_urb(urb); | ||
159 | } | ||
160 | |||
161 | static void ar9170_usb_tx_urb_complete_frame(struct urb *urb) | ||
162 | { | ||
163 | struct sk_buff *skb = urb->context; | ||
164 | struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); | ||
165 | |||
166 | if (unlikely(!aru)) { | ||
167 | dev_kfree_skb_irq(skb); | ||
168 | return ; | ||
169 | } | ||
170 | |||
171 | atomic_dec(&aru->tx_submitted_urbs); | ||
172 | |||
173 | ar9170_tx_callback(&aru->common, skb); | ||
174 | |||
175 | ar9170_usb_submit_urb(aru); | ||
176 | } | ||
177 | |||
178 | static void ar9170_usb_tx_urb_complete(struct urb *urb) | ||
179 | { | ||
180 | } | ||
181 | |||
182 | static void ar9170_usb_irq_completed(struct urb *urb) | ||
183 | { | ||
184 | struct ar9170_usb *aru = urb->context; | ||
185 | |||
186 | switch (urb->status) { | ||
187 | /* everything is fine */ | ||
188 | case 0: | ||
189 | break; | ||
190 | |||
191 | /* disconnect */ | ||
192 | case -ENOENT: | ||
193 | case -ECONNRESET: | ||
194 | case -ENODEV: | ||
195 | case -ESHUTDOWN: | ||
196 | goto free; | ||
197 | |||
198 | default: | ||
199 | goto resubmit; | ||
200 | } | ||
201 | |||
202 | ar9170_handle_command_response(&aru->common, urb->transfer_buffer, | ||
203 | urb->actual_length); | ||
204 | |||
205 | resubmit: | ||
206 | usb_anchor_urb(urb, &aru->rx_submitted); | ||
207 | if (usb_submit_urb(urb, GFP_ATOMIC)) { | ||
208 | usb_unanchor_urb(urb); | ||
209 | goto free; | ||
210 | } | ||
211 | |||
212 | return; | ||
213 | |||
214 | free: | ||
215 | usb_free_coherent(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma); | ||
216 | } | ||
217 | |||
218 | static void ar9170_usb_rx_completed(struct urb *urb) | ||
219 | { | ||
220 | struct sk_buff *skb = urb->context; | ||
221 | struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); | ||
222 | int err; | ||
223 | |||
224 | if (!aru) | ||
225 | goto free; | ||
226 | |||
227 | switch (urb->status) { | ||
228 | /* everything is fine */ | ||
229 | case 0: | ||
230 | break; | ||
231 | |||
232 | /* disconnect */ | ||
233 | case -ENOENT: | ||
234 | case -ECONNRESET: | ||
235 | case -ENODEV: | ||
236 | case -ESHUTDOWN: | ||
237 | goto free; | ||
238 | |||
239 | default: | ||
240 | goto resubmit; | ||
241 | } | ||
242 | |||
243 | skb_put(skb, urb->actual_length); | ||
244 | ar9170_rx(&aru->common, skb); | ||
245 | |||
246 | resubmit: | ||
247 | skb_reset_tail_pointer(skb); | ||
248 | skb_trim(skb, 0); | ||
249 | |||
250 | usb_anchor_urb(urb, &aru->rx_submitted); | ||
251 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
252 | if (unlikely(err)) { | ||
253 | usb_unanchor_urb(urb); | ||
254 | goto free; | ||
255 | } | ||
256 | |||
257 | return ; | ||
258 | |||
259 | free: | ||
260 | dev_kfree_skb_irq(skb); | ||
261 | } | ||
262 | |||
263 | static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru, | ||
264 | struct urb *urb, gfp_t gfp) | ||
265 | { | ||
266 | struct sk_buff *skb; | ||
267 | |||
268 | skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp); | ||
269 | if (!skb) | ||
270 | return -ENOMEM; | ||
271 | |||
272 | /* reserve some space for mac80211's radiotap */ | ||
273 | skb_reserve(skb, 32); | ||
274 | |||
275 | usb_fill_bulk_urb(urb, aru->udev, | ||
276 | usb_rcvbulkpipe(aru->udev, AR9170_EP_RX), | ||
277 | skb->data, min(skb_tailroom(skb), | ||
278 | AR9170_MAX_RX_BUFFER_SIZE), | ||
279 | ar9170_usb_rx_completed, skb); | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru) | ||
285 | { | ||
286 | struct urb *urb = NULL; | ||
287 | void *ibuf; | ||
288 | int err = -ENOMEM; | ||
289 | |||
290 | /* initialize interrupt endpoint */ | ||
291 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
292 | if (!urb) | ||
293 | goto out; | ||
294 | |||
295 | ibuf = usb_alloc_coherent(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma); | ||
296 | if (!ibuf) | ||
297 | goto out; | ||
298 | |||
299 | usb_fill_int_urb(urb, aru->udev, | ||
300 | usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf, | ||
301 | 64, ar9170_usb_irq_completed, aru, 1); | ||
302 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
303 | |||
304 | usb_anchor_urb(urb, &aru->rx_submitted); | ||
305 | err = usb_submit_urb(urb, GFP_KERNEL); | ||
306 | if (err) { | ||
307 | usb_unanchor_urb(urb); | ||
308 | usb_free_coherent(aru->udev, 64, urb->transfer_buffer, | ||
309 | urb->transfer_dma); | ||
310 | } | ||
311 | |||
312 | out: | ||
313 | usb_free_urb(urb); | ||
314 | return err; | ||
315 | } | ||
316 | |||
317 | static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru) | ||
318 | { | ||
319 | struct urb *urb; | ||
320 | int i; | ||
321 | int err = -EINVAL; | ||
322 | |||
323 | for (i = 0; i < AR9170_NUM_RX_URBS; i++) { | ||
324 | err = -ENOMEM; | ||
325 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
326 | if (!urb) | ||
327 | goto err_out; | ||
328 | |||
329 | err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL); | ||
330 | if (err) { | ||
331 | usb_free_urb(urb); | ||
332 | goto err_out; | ||
333 | } | ||
334 | |||
335 | usb_anchor_urb(urb, &aru->rx_submitted); | ||
336 | err = usb_submit_urb(urb, GFP_KERNEL); | ||
337 | if (err) { | ||
338 | usb_unanchor_urb(urb); | ||
339 | dev_kfree_skb_any((void *) urb->transfer_buffer); | ||
340 | usb_free_urb(urb); | ||
341 | goto err_out; | ||
342 | } | ||
343 | usb_free_urb(urb); | ||
344 | } | ||
345 | |||
346 | /* the device now waiting for a firmware. */ | ||
347 | aru->common.state = AR9170_IDLE; | ||
348 | return 0; | ||
349 | |||
350 | err_out: | ||
351 | |||
352 | usb_kill_anchored_urbs(&aru->rx_submitted); | ||
353 | return err; | ||
354 | } | ||
355 | |||
356 | static int ar9170_usb_flush(struct ar9170 *ar) | ||
357 | { | ||
358 | struct ar9170_usb *aru = (void *) ar; | ||
359 | struct urb *urb; | ||
360 | int ret, err = 0; | ||
361 | |||
362 | if (IS_STARTED(ar)) | ||
363 | aru->common.state = AR9170_IDLE; | ||
364 | |||
365 | usb_wait_anchor_empty_timeout(&aru->tx_pending, | ||
366 | msecs_to_jiffies(800)); | ||
367 | while ((urb = usb_get_from_anchor(&aru->tx_pending))) { | ||
368 | ar9170_tx_callback(&aru->common, (void *) urb->context); | ||
369 | usb_free_urb(urb); | ||
370 | } | ||
371 | |||
372 | /* lets wait a while until the tx - queues are dried out */ | ||
373 | ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, | ||
374 | msecs_to_jiffies(100)); | ||
375 | if (ret == 0) | ||
376 | err = -ETIMEDOUT; | ||
377 | |||
378 | usb_kill_anchored_urbs(&aru->tx_submitted); | ||
379 | |||
380 | if (IS_ACCEPTING_CMD(ar)) | ||
381 | aru->common.state = AR9170_STARTED; | ||
382 | |||
383 | return err; | ||
384 | } | ||
385 | |||
386 | static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) | ||
387 | { | ||
388 | int err; | ||
389 | |||
390 | aru->common.state = AR9170_UNKNOWN_STATE; | ||
391 | |||
392 | err = ar9170_usb_flush(&aru->common); | ||
393 | if (err) | ||
394 | dev_err(&aru->udev->dev, "stuck tx urbs!\n"); | ||
395 | |||
396 | usb_poison_anchored_urbs(&aru->tx_submitted); | ||
397 | usb_poison_anchored_urbs(&aru->rx_submitted); | ||
398 | } | ||
399 | |||
400 | static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd, | ||
401 | unsigned int plen, void *payload, | ||
402 | unsigned int outlen, void *out) | ||
403 | { | ||
404 | struct ar9170_usb *aru = (void *) ar; | ||
405 | struct urb *urb = NULL; | ||
406 | unsigned long flags; | ||
407 | int err = -ENOMEM; | ||
408 | |||
409 | if (unlikely(!IS_ACCEPTING_CMD(ar))) | ||
410 | return -EPERM; | ||
411 | |||
412 | if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4)) | ||
413 | return -EINVAL; | ||
414 | |||
415 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
416 | if (unlikely(!urb)) | ||
417 | goto err_free; | ||
418 | |||
419 | ar->cmdbuf[0] = cpu_to_le32(plen); | ||
420 | ar->cmdbuf[0] |= cpu_to_le32(cmd << 8); | ||
421 | /* writing multiple regs fills this buffer already */ | ||
422 | if (plen && payload != (u8 *)(&ar->cmdbuf[1])) | ||
423 | memcpy(&ar->cmdbuf[1], payload, plen); | ||
424 | |||
425 | spin_lock_irqsave(&aru->common.cmdlock, flags); | ||
426 | aru->readbuf = (u8 *)out; | ||
427 | aru->readlen = outlen; | ||
428 | spin_unlock_irqrestore(&aru->common.cmdlock, flags); | ||
429 | |||
430 | usb_fill_int_urb(urb, aru->udev, | ||
431 | usb_sndintpipe(aru->udev, AR9170_EP_CMD), | ||
432 | aru->common.cmdbuf, plen + 4, | ||
433 | ar9170_usb_tx_urb_complete, NULL, 1); | ||
434 | |||
435 | usb_anchor_urb(urb, &aru->tx_submitted); | ||
436 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
437 | if (unlikely(err)) { | ||
438 | usb_unanchor_urb(urb); | ||
439 | usb_free_urb(urb); | ||
440 | goto err_unbuf; | ||
441 | } | ||
442 | usb_free_urb(urb); | ||
443 | |||
444 | err = wait_for_completion_timeout(&aru->cmd_wait, HZ); | ||
445 | if (err == 0) { | ||
446 | err = -ETIMEDOUT; | ||
447 | goto err_unbuf; | ||
448 | } | ||
449 | |||
450 | if (aru->readlen != outlen) { | ||
451 | err = -EMSGSIZE; | ||
452 | goto err_unbuf; | ||
453 | } | ||
454 | |||
455 | return 0; | ||
456 | |||
457 | err_unbuf: | ||
458 | /* Maybe the device was removed in the second we were waiting? */ | ||
459 | if (IS_STARTED(ar)) { | ||
460 | dev_err(&aru->udev->dev, "no command feedback " | ||
461 | "received (%d).\n", err); | ||
462 | |||
463 | /* provide some maybe useful debug information */ | ||
464 | print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE, | ||
465 | aru->common.cmdbuf, plen + 4); | ||
466 | dump_stack(); | ||
467 | } | ||
468 | |||
469 | /* invalidate to avoid completing the next prematurely */ | ||
470 | spin_lock_irqsave(&aru->common.cmdlock, flags); | ||
471 | aru->readbuf = NULL; | ||
472 | aru->readlen = 0; | ||
473 | spin_unlock_irqrestore(&aru->common.cmdlock, flags); | ||
474 | |||
475 | err_free: | ||
476 | |||
477 | return err; | ||
478 | } | ||
479 | |||
480 | static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb) | ||
481 | { | ||
482 | struct ar9170_usb *aru = (struct ar9170_usb *) ar; | ||
483 | struct urb *urb; | ||
484 | |||
485 | if (unlikely(!IS_STARTED(ar))) { | ||
486 | /* Seriously, what were you drink... err... thinking!? */ | ||
487 | return -EPERM; | ||
488 | } | ||
489 | |||
490 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
491 | if (unlikely(!urb)) | ||
492 | return -ENOMEM; | ||
493 | |||
494 | usb_fill_bulk_urb(urb, aru->udev, | ||
495 | usb_sndbulkpipe(aru->udev, AR9170_EP_TX), | ||
496 | skb->data, skb->len, | ||
497 | ar9170_usb_tx_urb_complete_frame, skb); | ||
498 | urb->transfer_flags |= URB_ZERO_PACKET; | ||
499 | |||
500 | usb_anchor_urb(urb, &aru->tx_pending); | ||
501 | aru->tx_pending_urbs++; | ||
502 | |||
503 | usb_free_urb(urb); | ||
504 | |||
505 | ar9170_usb_submit_urb(aru); | ||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer) | ||
510 | { | ||
511 | struct ar9170_usb *aru = (void *) ar; | ||
512 | unsigned long flags; | ||
513 | u32 in, out; | ||
514 | |||
515 | if (unlikely(!buffer)) | ||
516 | return ; | ||
517 | |||
518 | in = le32_to_cpup((__le32 *)buffer); | ||
519 | out = le32_to_cpu(ar->cmdbuf[0]); | ||
520 | |||
521 | /* mask off length byte */ | ||
522 | out &= ~0xFF; | ||
523 | |||
524 | if (aru->readlen >= 0) { | ||
525 | /* add expected length */ | ||
526 | out |= aru->readlen; | ||
527 | } else { | ||
528 | /* add obtained length */ | ||
529 | out |= in & 0xFF; | ||
530 | } | ||
531 | |||
532 | /* | ||
533 | * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response | ||
534 | * length and we cannot predict the correct length in advance. | ||
535 | * So we only check if we provided enough space for the data. | ||
536 | */ | ||
537 | if (unlikely(out < in)) { | ||
538 | dev_warn(&aru->udev->dev, "received invalid command response " | ||
539 | "got %d bytes, instead of %d bytes " | ||
540 | "and the resp length is %d bytes\n", | ||
541 | in, out, len); | ||
542 | print_hex_dump_bytes("ar9170 invalid resp: ", | ||
543 | DUMP_PREFIX_OFFSET, buffer, len); | ||
544 | /* | ||
545 | * Do not complete, then the command times out, | ||
546 | * and we get a stack trace from there. | ||
547 | */ | ||
548 | return ; | ||
549 | } | ||
550 | |||
551 | spin_lock_irqsave(&aru->common.cmdlock, flags); | ||
552 | if (aru->readbuf && len > 0) { | ||
553 | memcpy(aru->readbuf, buffer + 4, len - 4); | ||
554 | aru->readbuf = NULL; | ||
555 | } | ||
556 | complete(&aru->cmd_wait); | ||
557 | spin_unlock_irqrestore(&aru->common.cmdlock, flags); | ||
558 | } | ||
559 | |||
560 | static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data, | ||
561 | size_t len, u32 addr, bool complete) | ||
562 | { | ||
563 | int transfer, err; | ||
564 | u8 *buf = kmalloc(4096, GFP_KERNEL); | ||
565 | |||
566 | if (!buf) | ||
567 | return -ENOMEM; | ||
568 | |||
569 | while (len) { | ||
570 | transfer = min_t(int, len, 4096); | ||
571 | memcpy(buf, data, transfer); | ||
572 | |||
573 | err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0), | ||
574 | 0x30 /* FW DL */, 0x40 | USB_DIR_OUT, | ||
575 | addr >> 8, 0, buf, transfer, 1000); | ||
576 | |||
577 | if (err < 0) { | ||
578 | kfree(buf); | ||
579 | return err; | ||
580 | } | ||
581 | |||
582 | len -= transfer; | ||
583 | data += transfer; | ||
584 | addr += transfer; | ||
585 | } | ||
586 | kfree(buf); | ||
587 | |||
588 | if (complete) { | ||
589 | err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0), | ||
590 | 0x31 /* FW DL COMPLETE */, | ||
591 | 0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000); | ||
592 | } | ||
593 | |||
594 | return 0; | ||
595 | } | ||
596 | |||
597 | static int ar9170_usb_reset(struct ar9170_usb *aru) | ||
598 | { | ||
599 | int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING); | ||
600 | |||
601 | if (lock) { | ||
602 | ret = usb_lock_device_for_reset(aru->udev, aru->intf); | ||
603 | if (ret < 0) { | ||
604 | dev_err(&aru->udev->dev, "unable to lock device " | ||
605 | "for reset (%d).\n", ret); | ||
606 | return ret; | ||
607 | } | ||
608 | } | ||
609 | |||
610 | ret = usb_reset_device(aru->udev); | ||
611 | if (lock) | ||
612 | usb_unlock_device(aru->udev); | ||
613 | |||
614 | /* let it rest - for a second - */ | ||
615 | msleep(1000); | ||
616 | |||
617 | return ret; | ||
618 | } | ||
619 | |||
620 | static int ar9170_usb_upload_firmware(struct ar9170_usb *aru) | ||
621 | { | ||
622 | int err; | ||
623 | |||
624 | if (!aru->init_values) | ||
625 | goto upload_fw_start; | ||
626 | |||
627 | /* First, upload initial values to device RAM */ | ||
628 | err = ar9170_usb_upload(aru, aru->init_values->data, | ||
629 | aru->init_values->size, 0x102800, false); | ||
630 | if (err) { | ||
631 | dev_err(&aru->udev->dev, "firmware part 1 " | ||
632 | "upload failed (%d).\n", err); | ||
633 | return err; | ||
634 | } | ||
635 | |||
636 | upload_fw_start: | ||
637 | |||
638 | /* Then, upload the firmware itself and start it */ | ||
639 | return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size, | ||
640 | 0x200000, true); | ||
641 | } | ||
642 | |||
643 | static int ar9170_usb_init_transport(struct ar9170_usb *aru) | ||
644 | { | ||
645 | struct ar9170 *ar = (void *) &aru->common; | ||
646 | int err; | ||
647 | |||
648 | ar9170_regwrite_begin(ar); | ||
649 | |||
650 | /* Set USB Rx stream mode MAX packet number to 2 */ | ||
651 | ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4); | ||
652 | |||
653 | /* Set USB Rx stream mode timeout to 10us */ | ||
654 | ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80); | ||
655 | |||
656 | ar9170_regwrite_finish(); | ||
657 | |||
658 | err = ar9170_regwrite_result(); | ||
659 | if (err) | ||
660 | dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err); | ||
661 | |||
662 | return err; | ||
663 | } | ||
664 | |||
665 | static void ar9170_usb_stop(struct ar9170 *ar) | ||
666 | { | ||
667 | struct ar9170_usb *aru = (void *) ar; | ||
668 | int ret; | ||
669 | |||
670 | if (IS_ACCEPTING_CMD(ar)) | ||
671 | aru->common.state = AR9170_STOPPED; | ||
672 | |||
673 | ret = ar9170_usb_flush(ar); | ||
674 | if (ret) | ||
675 | dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); | ||
676 | |||
677 | usb_poison_anchored_urbs(&aru->tx_submitted); | ||
678 | |||
679 | /* | ||
680 | * Note: | ||
681 | * So far we freed all tx urbs, but we won't dare to touch any rx urbs. | ||
682 | * Else we would end up with a unresponsive device... | ||
683 | */ | ||
684 | } | ||
685 | |||
686 | static int ar9170_usb_open(struct ar9170 *ar) | ||
687 | { | ||
688 | struct ar9170_usb *aru = (void *) ar; | ||
689 | int err; | ||
690 | |||
691 | usb_unpoison_anchored_urbs(&aru->tx_submitted); | ||
692 | err = ar9170_usb_init_transport(aru); | ||
693 | if (err) { | ||
694 | usb_poison_anchored_urbs(&aru->tx_submitted); | ||
695 | return err; | ||
696 | } | ||
697 | |||
698 | aru->common.state = AR9170_IDLE; | ||
699 | return 0; | ||
700 | } | ||
701 | |||
702 | static int ar9170_usb_init_device(struct ar9170_usb *aru) | ||
703 | { | ||
704 | int err; | ||
705 | |||
706 | err = ar9170_usb_alloc_rx_irq_urb(aru); | ||
707 | if (err) | ||
708 | goto err_out; | ||
709 | |||
710 | err = ar9170_usb_alloc_rx_bulk_urbs(aru); | ||
711 | if (err) | ||
712 | goto err_unrx; | ||
713 | |||
714 | err = ar9170_usb_upload_firmware(aru); | ||
715 | if (err) { | ||
716 | err = ar9170_echo_test(&aru->common, 0x60d43110); | ||
717 | if (err) { | ||
718 | /* force user invention, by disabling the device */ | ||
719 | err = usb_driver_set_configuration(aru->udev, -1); | ||
720 | dev_err(&aru->udev->dev, "device is in a bad state. " | ||
721 | "please reconnect it!\n"); | ||
722 | goto err_unrx; | ||
723 | } | ||
724 | } | ||
725 | |||
726 | return 0; | ||
727 | |||
728 | err_unrx: | ||
729 | ar9170_usb_cancel_urbs(aru); | ||
730 | |||
731 | err_out: | ||
732 | return err; | ||
733 | } | ||
734 | |||
735 | static void ar9170_usb_firmware_failed(struct ar9170_usb *aru) | ||
736 | { | ||
737 | struct device *parent = aru->udev->dev.parent; | ||
738 | struct usb_device *udev; | ||
739 | |||
740 | /* | ||
741 | * Store a copy of the usb_device pointer locally. | ||
742 | * This is because device_release_driver initiates | ||
743 | * ar9170_usb_disconnect, which in turn frees our | ||
744 | * driver context (aru). | ||
745 | */ | ||
746 | udev = aru->udev; | ||
747 | |||
748 | complete(&aru->firmware_loading_complete); | ||
749 | |||
750 | /* unbind anything failed */ | ||
751 | if (parent) | ||
752 | device_lock(parent); | ||
753 | |||
754 | device_release_driver(&udev->dev); | ||
755 | if (parent) | ||
756 | device_unlock(parent); | ||
757 | |||
758 | usb_put_dev(udev); | ||
759 | } | ||
760 | |||
761 | static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context) | ||
762 | { | ||
763 | struct ar9170_usb *aru = context; | ||
764 | int err; | ||
765 | |||
766 | aru->firmware = fw; | ||
767 | |||
768 | if (!fw) { | ||
769 | dev_err(&aru->udev->dev, "firmware file not found.\n"); | ||
770 | goto err_freefw; | ||
771 | } | ||
772 | |||
773 | err = ar9170_usb_init_device(aru); | ||
774 | if (err) | ||
775 | goto err_freefw; | ||
776 | |||
777 | err = ar9170_usb_open(&aru->common); | ||
778 | if (err) | ||
779 | goto err_unrx; | ||
780 | |||
781 | err = ar9170_register(&aru->common, &aru->udev->dev); | ||
782 | |||
783 | ar9170_usb_stop(&aru->common); | ||
784 | if (err) | ||
785 | goto err_unrx; | ||
786 | |||
787 | complete(&aru->firmware_loading_complete); | ||
788 | usb_put_dev(aru->udev); | ||
789 | return; | ||
790 | |||
791 | err_unrx: | ||
792 | ar9170_usb_cancel_urbs(aru); | ||
793 | |||
794 | err_freefw: | ||
795 | ar9170_usb_firmware_failed(aru); | ||
796 | } | ||
797 | |||
798 | static void ar9170_usb_firmware_inits(const struct firmware *fw, | ||
799 | void *context) | ||
800 | { | ||
801 | struct ar9170_usb *aru = context; | ||
802 | int err; | ||
803 | |||
804 | if (!fw) { | ||
805 | dev_err(&aru->udev->dev, "file with init values not found.\n"); | ||
806 | ar9170_usb_firmware_failed(aru); | ||
807 | return; | ||
808 | } | ||
809 | |||
810 | aru->init_values = fw; | ||
811 | |||
812 | /* ok so we have the init values -- get code for two-stage */ | ||
813 | |||
814 | err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-2.fw", | ||
815 | &aru->udev->dev, GFP_KERNEL, aru, | ||
816 | ar9170_usb_firmware_finish); | ||
817 | if (err) | ||
818 | ar9170_usb_firmware_failed(aru); | ||
819 | } | ||
820 | |||
821 | static void ar9170_usb_firmware_step2(const struct firmware *fw, void *context) | ||
822 | { | ||
823 | struct ar9170_usb *aru = context; | ||
824 | int err; | ||
825 | |||
826 | if (fw) { | ||
827 | ar9170_usb_firmware_finish(fw, context); | ||
828 | return; | ||
829 | } | ||
830 | |||
831 | if (aru->req_one_stage_fw) { | ||
832 | dev_err(&aru->udev->dev, "ar9170.fw firmware file " | ||
833 | "not found and is required for this device\n"); | ||
834 | ar9170_usb_firmware_failed(aru); | ||
835 | return; | ||
836 | } | ||
837 | |||
838 | dev_err(&aru->udev->dev, "ar9170.fw firmware file " | ||
839 | "not found, trying old firmware...\n"); | ||
840 | |||
841 | err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-1.fw", | ||
842 | &aru->udev->dev, GFP_KERNEL, aru, | ||
843 | ar9170_usb_firmware_inits); | ||
844 | if (err) | ||
845 | ar9170_usb_firmware_failed(aru); | ||
846 | } | ||
847 | |||
848 | static bool ar9170_requires_one_stage(const struct usb_device_id *id) | ||
849 | { | ||
850 | if (!id->driver_info) | ||
851 | return false; | ||
852 | if (id->driver_info == AR9170_REQ_FW1_ONLY) | ||
853 | return true; | ||
854 | return false; | ||
855 | } | ||
856 | |||
857 | static int ar9170_usb_probe(struct usb_interface *intf, | ||
858 | const struct usb_device_id *id) | ||
859 | { | ||
860 | struct ar9170_usb *aru; | ||
861 | struct ar9170 *ar; | ||
862 | struct usb_device *udev; | ||
863 | int err; | ||
864 | |||
865 | aru = ar9170_alloc(sizeof(*aru)); | ||
866 | if (IS_ERR(aru)) { | ||
867 | err = PTR_ERR(aru); | ||
868 | goto out; | ||
869 | } | ||
870 | |||
871 | udev = interface_to_usbdev(intf); | ||
872 | usb_get_dev(udev); | ||
873 | aru->udev = udev; | ||
874 | aru->intf = intf; | ||
875 | ar = &aru->common; | ||
876 | |||
877 | aru->req_one_stage_fw = ar9170_requires_one_stage(id); | ||
878 | |||
879 | usb_set_intfdata(intf, aru); | ||
880 | SET_IEEE80211_DEV(ar->hw, &intf->dev); | ||
881 | |||
882 | init_usb_anchor(&aru->rx_submitted); | ||
883 | init_usb_anchor(&aru->tx_pending); | ||
884 | init_usb_anchor(&aru->tx_submitted); | ||
885 | init_completion(&aru->cmd_wait); | ||
886 | init_completion(&aru->firmware_loading_complete); | ||
887 | spin_lock_init(&aru->tx_urb_lock); | ||
888 | |||
889 | aru->tx_pending_urbs = 0; | ||
890 | atomic_set(&aru->tx_submitted_urbs, 0); | ||
891 | |||
892 | aru->common.stop = ar9170_usb_stop; | ||
893 | aru->common.flush = ar9170_usb_flush; | ||
894 | aru->common.open = ar9170_usb_open; | ||
895 | aru->common.tx = ar9170_usb_tx; | ||
896 | aru->common.exec_cmd = ar9170_usb_exec_cmd; | ||
897 | aru->common.callback_cmd = ar9170_usb_callback_cmd; | ||
898 | |||
899 | #ifdef CONFIG_PM | ||
900 | udev->reset_resume = 1; | ||
901 | #endif /* CONFIG_PM */ | ||
902 | err = ar9170_usb_reset(aru); | ||
903 | if (err) | ||
904 | goto err_freehw; | ||
905 | |||
906 | usb_get_dev(aru->udev); | ||
907 | return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw", | ||
908 | &aru->udev->dev, GFP_KERNEL, aru, | ||
909 | ar9170_usb_firmware_step2); | ||
910 | err_freehw: | ||
911 | usb_set_intfdata(intf, NULL); | ||
912 | usb_put_dev(udev); | ||
913 | ieee80211_free_hw(ar->hw); | ||
914 | out: | ||
915 | return err; | ||
916 | } | ||
917 | |||
918 | static void ar9170_usb_disconnect(struct usb_interface *intf) | ||
919 | { | ||
920 | struct ar9170_usb *aru = usb_get_intfdata(intf); | ||
921 | |||
922 | if (!aru) | ||
923 | return; | ||
924 | |||
925 | aru->common.state = AR9170_IDLE; | ||
926 | |||
927 | wait_for_completion(&aru->firmware_loading_complete); | ||
928 | |||
929 | ar9170_unregister(&aru->common); | ||
930 | ar9170_usb_cancel_urbs(aru); | ||
931 | |||
932 | usb_put_dev(aru->udev); | ||
933 | usb_set_intfdata(intf, NULL); | ||
934 | ieee80211_free_hw(aru->common.hw); | ||
935 | |||
936 | release_firmware(aru->init_values); | ||
937 | release_firmware(aru->firmware); | ||
938 | } | ||
939 | |||
940 | #ifdef CONFIG_PM | ||
941 | static int ar9170_suspend(struct usb_interface *intf, | ||
942 | pm_message_t message) | ||
943 | { | ||
944 | struct ar9170_usb *aru = usb_get_intfdata(intf); | ||
945 | |||
946 | if (!aru) | ||
947 | return -ENODEV; | ||
948 | |||
949 | aru->common.state = AR9170_IDLE; | ||
950 | ar9170_usb_cancel_urbs(aru); | ||
951 | |||
952 | return 0; | ||
953 | } | ||
954 | |||
955 | static int ar9170_resume(struct usb_interface *intf) | ||
956 | { | ||
957 | struct ar9170_usb *aru = usb_get_intfdata(intf); | ||
958 | int err; | ||
959 | |||
960 | if (!aru) | ||
961 | return -ENODEV; | ||
962 | |||
963 | usb_unpoison_anchored_urbs(&aru->rx_submitted); | ||
964 | usb_unpoison_anchored_urbs(&aru->tx_submitted); | ||
965 | |||
966 | err = ar9170_usb_init_device(aru); | ||
967 | if (err) | ||
968 | goto err_unrx; | ||
969 | |||
970 | err = ar9170_usb_open(&aru->common); | ||
971 | if (err) | ||
972 | goto err_unrx; | ||
973 | |||
974 | return 0; | ||
975 | |||
976 | err_unrx: | ||
977 | aru->common.state = AR9170_IDLE; | ||
978 | ar9170_usb_cancel_urbs(aru); | ||
979 | |||
980 | return err; | ||
981 | } | ||
982 | #endif /* CONFIG_PM */ | ||
983 | |||
984 | static struct usb_driver ar9170_driver = { | ||
985 | .name = "ar9170usb", | ||
986 | .probe = ar9170_usb_probe, | ||
987 | .disconnect = ar9170_usb_disconnect, | ||
988 | .id_table = ar9170_usb_ids, | ||
989 | .soft_unbind = 1, | ||
990 | #ifdef CONFIG_PM | ||
991 | .suspend = ar9170_suspend, | ||
992 | .resume = ar9170_resume, | ||
993 | .reset_resume = ar9170_resume, | ||
994 | #endif /* CONFIG_PM */ | ||
995 | }; | ||
996 | |||
997 | static int __init ar9170_init(void) | ||
998 | { | ||
999 | return usb_register(&ar9170_driver); | ||
1000 | } | ||
1001 | |||
1002 | static void __exit ar9170_exit(void) | ||
1003 | { | ||
1004 | usb_deregister(&ar9170_driver); | ||
1005 | } | ||
1006 | |||
1007 | module_init(ar9170_init); | ||
1008 | module_exit(ar9170_exit); | ||
diff --git a/drivers/net/wireless/ath/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h deleted file mode 100644 index 919b06046eb..00000000000 --- a/drivers/net/wireless/ath/ar9170/usb.h +++ /dev/null | |||
@@ -1,82 +0,0 @@ | |||
1 | /* | ||
2 | * Atheros AR9170 USB driver | ||
3 | * | ||
4 | * Driver specific definitions | ||
5 | * | ||
6 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | ||
7 | * Copyright 2009, Christian Lamparter <chunkeey@web.de> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; see the file COPYING. If not, see | ||
21 | * http://www.gnu.org/licenses/. | ||
22 | * | ||
23 | * This file incorporates work covered by the following copyright and | ||
24 | * permission notice: | ||
25 | * Copyright (c) 2007-2008 Atheros Communications, Inc. | ||
26 | * | ||
27 | * Permission to use, copy, modify, and/or distribute this software for any | ||
28 | * purpose with or without fee is hereby granted, provided that the above | ||
29 | * copyright notice and this permission notice appear in all copies. | ||
30 | * | ||
31 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
32 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
33 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
34 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
35 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
36 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
37 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
38 | */ | ||
39 | #ifndef __USB_H | ||
40 | #define __USB_H | ||
41 | |||
42 | #include <linux/usb.h> | ||
43 | #include <linux/completion.h> | ||
44 | #include <linux/spinlock.h> | ||
45 | #include <linux/leds.h> | ||
46 | #include <net/cfg80211.h> | ||
47 | #include <net/mac80211.h> | ||
48 | #include <linux/firmware.h> | ||
49 | #include "eeprom.h" | ||
50 | #include "hw.h" | ||
51 | #include "ar9170.h" | ||
52 | |||
53 | #define AR9170_NUM_RX_URBS 16 | ||
54 | #define AR9170_NUM_TX_URBS 8 | ||
55 | |||
56 | struct firmware; | ||
57 | |||
58 | struct ar9170_usb { | ||
59 | struct ar9170 common; | ||
60 | struct usb_device *udev; | ||
61 | struct usb_interface *intf; | ||
62 | |||
63 | struct usb_anchor rx_submitted; | ||
64 | struct usb_anchor tx_pending; | ||
65 | struct usb_anchor tx_submitted; | ||
66 | |||
67 | bool req_one_stage_fw; | ||
68 | |||
69 | spinlock_t tx_urb_lock; | ||
70 | atomic_t tx_submitted_urbs; | ||
71 | unsigned int tx_pending_urbs; | ||
72 | |||
73 | struct completion cmd_wait; | ||
74 | struct completion firmware_loading_complete; | ||
75 | int readlen; | ||
76 | u8 *readbuf; | ||
77 | |||
78 | const struct firmware *init_values; | ||
79 | const struct firmware *firmware; | ||
80 | }; | ||
81 | |||
82 | #endif /* __USB_H */ | ||
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index a6c6a466000..7cf4317a2a8 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -119,17 +119,11 @@ struct ath_ops { | |||
119 | void (*write)(void *, u32 val, u32 reg_offset); | 119 | void (*write)(void *, u32 val, u32 reg_offset); |
120 | void (*enable_write_buffer)(void *); | 120 | void (*enable_write_buffer)(void *); |
121 | void (*write_flush) (void *); | 121 | void (*write_flush) (void *); |
122 | u32 (*rmw)(void *, u32 reg_offset, u32 set, u32 clr); | ||
122 | }; | 123 | }; |
123 | 124 | ||
124 | struct ath_common; | 125 | struct ath_common; |
125 | 126 | struct ath_bus_ops; | |
126 | struct ath_bus_ops { | ||
127 | enum ath_bus_type ath_bus_type; | ||
128 | void (*read_cachesize)(struct ath_common *common, int *csz); | ||
129 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); | ||
130 | void (*bt_coex_prep)(struct ath_common *common); | ||
131 | void (*extn_synch_en)(struct ath_common *common); | ||
132 | }; | ||
133 | 127 | ||
134 | struct ath_common { | 128 | struct ath_common { |
135 | void *ah; | 129 | void *ah; |
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 82324e98efe..ea998278155 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/nl80211.h> | 19 | #include <linux/nl80211.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/etherdevice.h> | ||
21 | #include <ar231x_platform.h> | 22 | #include <ar231x_platform.h> |
22 | #include "ath5k.h" | 23 | #include "ath5k.h" |
23 | #include "debug.h" | 24 | #include "debug.h" |
@@ -62,10 +63,27 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah) | |||
62 | return 0; | 63 | return 0; |
63 | } | 64 | } |
64 | 65 | ||
66 | static 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 | |||
65 | static const struct ath_bus_ops ath_ahb_bus_ops = { | 82 | static const struct ath_bus_ops ath_ahb_bus_ops = { |
66 | .ath_bus_type = ATH_AHB, | 83 | .ath_bus_type = ATH_AHB, |
67 | .read_cachesize = ath5k_ahb_read_cachesize, | 84 | .read_cachesize = ath5k_ahb_read_cachesize, |
68 | .eeprom_read = ath5k_ahb_eeprom_read, | 85 | .eeprom_read = ath5k_ahb_eeprom_read, |
86 | .eeprom_read_mac = ath5k_ahb_eeprom_read_mac, | ||
69 | }; | 87 | }; |
70 | 88 | ||
71 | /*Initialization*/ | 89 | /*Initialization*/ |
@@ -142,6 +160,16 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
142 | else | 160 | else |
143 | reg |= AR5K_AR5312_ENABLE_WLAN1; | 161 | reg |= AR5K_AR5312_ENABLE_WLAN1; |
144 | __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); | 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); | ||
145 | } | 173 | } |
146 | 174 | ||
147 | ret = ath5k_init_softc(sc, &ath_ahb_bus_ops); | 175 | ret = ath5k_init_softc(sc, &ath_ahb_bus_ops); |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 8a06dbd3962..bb50700436f 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -224,8 +224,7 @@ | |||
224 | 224 | ||
225 | /* SIFS */ | 225 | /* SIFS */ |
226 | #define AR5K_INIT_SIFS_TURBO 6 | 226 | #define AR5K_INIT_SIFS_TURBO 6 |
227 | /* XXX: 8 from initvals 10 from standard */ | 227 | #define AR5K_INIT_SIFS_DEFAULT_BG 10 |
228 | #define AR5K_INIT_SIFS_DEFAULT_BG 8 | ||
229 | #define AR5K_INIT_SIFS_DEFAULT_A 16 | 228 | #define AR5K_INIT_SIFS_DEFAULT_A 16 |
230 | #define AR5K_INIT_SIFS_HALF_RATE 32 | 229 | #define AR5K_INIT_SIFS_HALF_RATE 32 |
231 | #define AR5K_INIT_SIFS_QUARTER_RATE 64 | 230 | #define AR5K_INIT_SIFS_QUARTER_RATE 64 |
@@ -453,12 +452,10 @@ struct ath5k_tx_status { | |||
453 | u16 ts_seqnum; | 452 | u16 ts_seqnum; |
454 | u16 ts_tstamp; | 453 | u16 ts_tstamp; |
455 | u8 ts_status; | 454 | u8 ts_status; |
456 | u8 ts_rate[4]; | ||
457 | u8 ts_retry[4]; | ||
458 | u8 ts_final_idx; | 455 | u8 ts_final_idx; |
456 | u8 ts_final_retry; | ||
459 | s8 ts_rssi; | 457 | s8 ts_rssi; |
460 | u8 ts_shortretry; | 458 | u8 ts_shortretry; |
461 | u8 ts_longretry; | ||
462 | u8 ts_virtcol; | 459 | u8 ts_virtcol; |
463 | u8 ts_antenna; | 460 | u8 ts_antenna; |
464 | }; | 461 | }; |
@@ -875,6 +872,19 @@ enum ath5k_int { | |||
875 | AR5K_INT_QTRIG = 0x40000000, /* Non common */ | 872 | AR5K_INT_QTRIG = 0x40000000, /* Non common */ |
876 | AR5K_INT_GLOBAL = 0x80000000, | 873 | AR5K_INT_GLOBAL = 0x80000000, |
877 | 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 | |||
878 | AR5K_INT_COMMON = AR5K_INT_RXOK | 888 | AR5K_INT_COMMON = AR5K_INT_RXOK |
879 | | AR5K_INT_RXDESC | 889 | | AR5K_INT_RXDESC |
880 | | AR5K_INT_RXERR | 890 | | AR5K_INT_RXERR |
@@ -1058,6 +1068,7 @@ struct ath5k_hw { | |||
1058 | u8 ah_coverage_class; | 1068 | u8 ah_coverage_class; |
1059 | bool ah_ack_bitrate_high; | 1069 | bool ah_ack_bitrate_high; |
1060 | u8 ah_bwmode; | 1070 | u8 ah_bwmode; |
1071 | bool ah_short_slot; | ||
1061 | 1072 | ||
1062 | /* Antenna Control */ | 1073 | /* Antenna Control */ |
1063 | u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; | 1074 | u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; |
@@ -1144,6 +1155,13 @@ struct ath5k_hw { | |||
1144 | struct ath5k_rx_status *); | 1155 | struct ath5k_rx_status *); |
1145 | }; | 1156 | }; |
1146 | 1157 | ||
1158 | struct 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 | |||
1147 | /* | 1165 | /* |
1148 | * Prototypes | 1166 | * Prototypes |
1149 | */ | 1167 | */ |
@@ -1227,13 +1245,12 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah); | |||
1227 | /* EEPROM access functions */ | 1245 | /* EEPROM access functions */ |
1228 | int ath5k_eeprom_init(struct ath5k_hw *ah); | 1246 | int ath5k_eeprom_init(struct ath5k_hw *ah); |
1229 | void ath5k_eeprom_detach(struct ath5k_hw *ah); | 1247 | void ath5k_eeprom_detach(struct ath5k_hw *ah); |
1230 | int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); | ||
1231 | 1248 | ||
1232 | 1249 | ||
1233 | /* Protocol Control Unit Functions */ | 1250 | /* Protocol Control Unit Functions */ |
1234 | /* Helpers */ | 1251 | /* Helpers */ |
1235 | int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | 1252 | int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, |
1236 | int len, struct ieee80211_rate *rate); | 1253 | int len, struct ieee80211_rate *rate, bool shortpre); |
1237 | unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); | 1254 | unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); |
1238 | unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); | 1255 | unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); |
1239 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); | 1256 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); |
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index bc824056048..1588401de3c 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
@@ -313,12 +313,17 @@ int ath5k_hw_init(struct ath5k_softc *sc) | |||
313 | goto err; | 313 | goto err; |
314 | } | 314 | } |
315 | 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); | ||
319 | } | ||
320 | |||
316 | /* Crypto settings */ | 321 | /* Crypto settings */ |
317 | common->keymax = (sc->ah->ah_version == AR5K_AR5210 ? | 322 | common->keymax = (sc->ah->ah_version == AR5K_AR5210 ? |
318 | AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); | 323 | AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); |
319 | 324 | ||
320 | if (srev >= AR5K_SREV_AR5212_V4 && | 325 | if (srev >= AR5K_SREV_AR5212_V4 && |
321 | (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && | 326 | (ee->ee_version < AR5K_EEPROM_VERSION_5_0 || |
322 | !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) | 327 | !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) |
323 | common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; | 328 | common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; |
324 | 329 | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 349a5963931..22047628ccf 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1444,6 +1444,21 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) | |||
1444 | } | 1444 | } |
1445 | 1445 | ||
1446 | static void | 1446 | static void |
1447 | ath5k_set_current_imask(struct ath5k_softc *sc) | ||
1448 | { | ||
1449 | enum ath5k_int imask = sc->imask; | ||
1450 | unsigned long flags; | ||
1451 | |||
1452 | spin_lock_irqsave(&sc->irqlock, flags); | ||
1453 | if (sc->rx_pending) | ||
1454 | imask &= ~AR5K_INT_RX_ALL; | ||
1455 | if (sc->tx_pending) | ||
1456 | imask &= ~AR5K_INT_TX_ALL; | ||
1457 | ath5k_hw_set_imr(sc->ah, imask); | ||
1458 | spin_unlock_irqrestore(&sc->irqlock, flags); | ||
1459 | } | ||
1460 | |||
1461 | static void | ||
1447 | ath5k_tasklet_rx(unsigned long data) | 1462 | ath5k_tasklet_rx(unsigned long data) |
1448 | { | 1463 | { |
1449 | struct ath5k_rx_status rs = {}; | 1464 | struct ath5k_rx_status rs = {}; |
@@ -1506,6 +1521,8 @@ next: | |||
1506 | } while (ath5k_rxbuf_setup(sc, bf) == 0); | 1521 | } while (ath5k_rxbuf_setup(sc, bf) == 0); |
1507 | unlock: | 1522 | unlock: |
1508 | spin_unlock(&sc->rxbuflock); | 1523 | spin_unlock(&sc->rxbuflock); |
1524 | sc->rx_pending = false; | ||
1525 | ath5k_set_current_imask(sc); | ||
1509 | } | 1526 | } |
1510 | 1527 | ||
1511 | 1528 | ||
@@ -1573,28 +1590,28 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1573 | struct ath5k_txq *txq, struct ath5k_tx_status *ts) | 1590 | struct ath5k_txq *txq, struct ath5k_tx_status *ts) |
1574 | { | 1591 | { |
1575 | struct ieee80211_tx_info *info; | 1592 | struct ieee80211_tx_info *info; |
1593 | u8 tries[3]; | ||
1576 | int i; | 1594 | int i; |
1577 | 1595 | ||
1578 | sc->stats.tx_all_count++; | 1596 | sc->stats.tx_all_count++; |
1579 | sc->stats.tx_bytes_count += skb->len; | 1597 | sc->stats.tx_bytes_count += skb->len; |
1580 | info = IEEE80211_SKB_CB(skb); | 1598 | info = IEEE80211_SKB_CB(skb); |
1581 | 1599 | ||
1600 | tries[0] = info->status.rates[0].count; | ||
1601 | tries[1] = info->status.rates[1].count; | ||
1602 | tries[2] = info->status.rates[2].count; | ||
1603 | |||
1582 | ieee80211_tx_info_clear_status(info); | 1604 | ieee80211_tx_info_clear_status(info); |
1583 | for (i = 0; i < 4; i++) { | 1605 | |
1606 | for (i = 0; i < ts->ts_final_idx; i++) { | ||
1584 | struct ieee80211_tx_rate *r = | 1607 | struct ieee80211_tx_rate *r = |
1585 | &info->status.rates[i]; | 1608 | &info->status.rates[i]; |
1586 | 1609 | ||
1587 | if (ts->ts_rate[i]) { | 1610 | r->count = tries[i]; |
1588 | r->idx = ath5k_hw_to_driver_rix(sc, ts->ts_rate[i]); | ||
1589 | r->count = ts->ts_retry[i]; | ||
1590 | } else { | ||
1591 | r->idx = -1; | ||
1592 | r->count = 0; | ||
1593 | } | ||
1594 | } | 1611 | } |
1595 | 1612 | ||
1596 | /* count the successful attempt as well */ | 1613 | info->status.rates[ts->ts_final_idx].count = ts->ts_final_retry; |
1597 | info->status.rates[ts->ts_final_idx].count++; | 1614 | info->status.rates[ts->ts_final_idx + 1].idx = -1; |
1598 | 1615 | ||
1599 | if (unlikely(ts->ts_status)) { | 1616 | if (unlikely(ts->ts_status)) { |
1600 | sc->stats.ack_fail++; | 1617 | sc->stats.ack_fail++; |
@@ -1609,6 +1626,9 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1609 | } else { | 1626 | } else { |
1610 | info->flags |= IEEE80211_TX_STAT_ACK; | 1627 | info->flags |= IEEE80211_TX_STAT_ACK; |
1611 | info->status.ack_signal = ts->ts_rssi; | 1628 | info->status.ack_signal = ts->ts_rssi; |
1629 | |||
1630 | /* count the successful attempt as well */ | ||
1631 | info->status.rates[ts->ts_final_idx].count++; | ||
1612 | } | 1632 | } |
1613 | 1633 | ||
1614 | /* | 1634 | /* |
@@ -1690,6 +1710,9 @@ ath5k_tasklet_tx(unsigned long data) | |||
1690 | for (i=0; i < AR5K_NUM_TX_QUEUES; i++) | 1710 | for (i=0; i < AR5K_NUM_TX_QUEUES; i++) |
1691 | if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i))) | 1711 | if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i))) |
1692 | ath5k_tx_processq(sc, &sc->txqs[i]); | 1712 | ath5k_tx_processq(sc, &sc->txqs[i]); |
1713 | |||
1714 | sc->tx_pending = false; | ||
1715 | ath5k_set_current_imask(sc); | ||
1693 | } | 1716 | } |
1694 | 1717 | ||
1695 | 1718 | ||
@@ -2119,6 +2142,20 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah) | |||
2119 | * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ | 2142 | * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ |
2120 | } | 2143 | } |
2121 | 2144 | ||
2145 | static void | ||
2146 | ath5k_schedule_rx(struct ath5k_softc *sc) | ||
2147 | { | ||
2148 | sc->rx_pending = true; | ||
2149 | tasklet_schedule(&sc->rxtq); | ||
2150 | } | ||
2151 | |||
2152 | static void | ||
2153 | ath5k_schedule_tx(struct ath5k_softc *sc) | ||
2154 | { | ||
2155 | sc->tx_pending = true; | ||
2156 | tasklet_schedule(&sc->txtq); | ||
2157 | } | ||
2158 | |||
2122 | irqreturn_t | 2159 | irqreturn_t |
2123 | ath5k_intr(int irq, void *dev_id) | 2160 | ath5k_intr(int irq, void *dev_id) |
2124 | { | 2161 | { |
@@ -2161,7 +2198,7 @@ ath5k_intr(int irq, void *dev_id) | |||
2161 | ieee80211_queue_work(sc->hw, &sc->reset_work); | 2198 | ieee80211_queue_work(sc->hw, &sc->reset_work); |
2162 | } | 2199 | } |
2163 | else | 2200 | else |
2164 | tasklet_schedule(&sc->rxtq); | 2201 | ath5k_schedule_rx(sc); |
2165 | } else { | 2202 | } else { |
2166 | if (status & AR5K_INT_SWBA) { | 2203 | if (status & AR5K_INT_SWBA) { |
2167 | tasklet_hi_schedule(&sc->beacontq); | 2204 | tasklet_hi_schedule(&sc->beacontq); |
@@ -2179,10 +2216,10 @@ ath5k_intr(int irq, void *dev_id) | |||
2179 | ath5k_hw_update_tx_triglevel(ah, true); | 2216 | ath5k_hw_update_tx_triglevel(ah, true); |
2180 | } | 2217 | } |
2181 | if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) | 2218 | if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) |
2182 | tasklet_schedule(&sc->rxtq); | 2219 | ath5k_schedule_rx(sc); |
2183 | if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC | 2220 | if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC |
2184 | | AR5K_INT_TXERR | AR5K_INT_TXEOL)) | 2221 | | AR5K_INT_TXERR | AR5K_INT_TXEOL)) |
2185 | tasklet_schedule(&sc->txtq); | 2222 | ath5k_schedule_tx(sc); |
2186 | if (status & AR5K_INT_BMISS) { | 2223 | if (status & AR5K_INT_BMISS) { |
2187 | /* TODO */ | 2224 | /* TODO */ |
2188 | } | 2225 | } |
@@ -2201,6 +2238,9 @@ ath5k_intr(int irq, void *dev_id) | |||
2201 | 2238 | ||
2202 | } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); | 2239 | } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); |
2203 | 2240 | ||
2241 | if (sc->rx_pending || sc->tx_pending) | ||
2242 | ath5k_set_current_imask(sc); | ||
2243 | |||
2204 | if (unlikely(!counter)) | 2244 | if (unlikely(!counter)) |
2205 | ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); | 2245 | ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); |
2206 | 2246 | ||
@@ -2354,7 +2394,7 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops) | |||
2354 | spin_lock_init(&sc->rxbuflock); | 2394 | spin_lock_init(&sc->rxbuflock); |
2355 | spin_lock_init(&sc->txbuflock); | 2395 | spin_lock_init(&sc->txbuflock); |
2356 | spin_lock_init(&sc->block); | 2396 | spin_lock_init(&sc->block); |
2357 | 2397 | spin_lock_init(&sc->irqlock); | |
2358 | 2398 | ||
2359 | /* Setup interrupt handler */ | 2399 | /* Setup interrupt handler */ |
2360 | ret = request_irq(sc->irq, ath5k_intr, IRQF_SHARED, "ath", sc); | 2400 | ret = request_irq(sc->irq, ath5k_intr, IRQF_SHARED, "ath", sc); |
@@ -2572,6 +2612,8 @@ done: | |||
2572 | 2612 | ||
2573 | static void stop_tasklets(struct ath5k_softc *sc) | 2613 | static void stop_tasklets(struct ath5k_softc *sc) |
2574 | { | 2614 | { |
2615 | sc->rx_pending = false; | ||
2616 | sc->tx_pending = false; | ||
2575 | tasklet_kill(&sc->rxtq); | 2617 | tasklet_kill(&sc->rxtq); |
2576 | tasklet_kill(&sc->txtq); | 2618 | tasklet_kill(&sc->txtq); |
2577 | tasklet_kill(&sc->calib); | 2619 | tasklet_kill(&sc->calib); |
@@ -2838,7 +2880,7 @@ ath5k_init(struct ieee80211_hw *hw) | |||
2838 | INIT_WORK(&sc->reset_work, ath5k_reset_work); | 2880 | INIT_WORK(&sc->reset_work, ath5k_reset_work); |
2839 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work); | 2881 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work); |
2840 | 2882 | ||
2841 | ret = ath5k_eeprom_read_mac(ah, mac); | 2883 | ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac); |
2842 | if (ret) { | 2884 | if (ret) { |
2843 | ATH5K_ERR(sc, "unable to read address from EEPROM\n"); | 2885 | ATH5K_ERR(sc, "unable to read address from EEPROM\n"); |
2844 | goto err_queues; | 2886 | goto err_queues; |
@@ -2898,7 +2940,6 @@ ath5k_deinit_softc(struct ath5k_softc *sc) | |||
2898 | * XXX: ??? detach ath5k_hw ??? | 2940 | * XXX: ??? detach ath5k_hw ??? |
2899 | * Other than that, it's straightforward... | 2941 | * Other than that, it's straightforward... |
2900 | */ | 2942 | */ |
2901 | ath5k_debug_finish_device(sc); | ||
2902 | ieee80211_unregister_hw(hw); | 2943 | ieee80211_unregister_hw(hw); |
2903 | ath5k_desc_free(sc); | 2944 | ath5k_desc_free(sc); |
2904 | ath5k_txq_release(sc); | 2945 | ath5k_txq_release(sc); |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 978f1f4ac2f..b294f330501 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -193,12 +193,13 @@ struct ath5k_softc { | |||
193 | dma_addr_t desc_daddr; /* DMA (physical) address */ | 193 | dma_addr_t desc_daddr; /* DMA (physical) address */ |
194 | size_t desc_len; /* size of TX/RX descriptors */ | 194 | size_t desc_len; /* size of TX/RX descriptors */ |
195 | 195 | ||
196 | DECLARE_BITMAP(status, 5); | 196 | DECLARE_BITMAP(status, 6); |
197 | #define ATH_STAT_INVALID 0 /* disable hardware accesses */ | 197 | #define ATH_STAT_INVALID 0 /* disable hardware accesses */ |
198 | #define ATH_STAT_MRRETRY 1 /* multi-rate retry support */ | 198 | #define ATH_STAT_MRRETRY 1 /* multi-rate retry support */ |
199 | #define ATH_STAT_PROMISC 2 | 199 | #define ATH_STAT_PROMISC 2 |
200 | #define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */ | 200 | #define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */ |
201 | #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 */ | ||
202 | 203 | ||
203 | unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ | 204 | unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ |
204 | struct ieee80211_channel *curchan; /* current h/w channel */ | 205 | struct ieee80211_channel *curchan; /* current h/w channel */ |
@@ -207,6 +208,10 @@ struct ath5k_softc { | |||
207 | 208 | ||
208 | enum ath5k_int imask; /* interrupt mask copy */ | 209 | enum ath5k_int imask; /* interrupt mask copy */ |
209 | 210 | ||
211 | spinlock_t irqlock; | ||
212 | bool rx_pending; /* rx tasklet pending */ | ||
213 | bool tx_pending; /* tx tasklet pending */ | ||
214 | |||
210 | u8 lladdr[ETH_ALEN]; | 215 | u8 lladdr[ETH_ALEN]; |
211 | u8 bssidmask[ETH_ALEN]; | 216 | u8 bssidmask[ETH_ALEN]; |
212 | 217 | ||
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c index f77e8a703c5..7dd88e1c3ff 100644 --- a/drivers/net/wireless/ath/ath5k/caps.c +++ b/drivers/net/wireless/ath/ath5k/caps.c | |||
@@ -94,6 +94,9 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) | |||
94 | } | 94 | } |
95 | } | 95 | } |
96 | 96 | ||
97 | if ((ah->ah_radio_5ghz_revision & 0xf0) == AR5K_SREV_RAD_2112) | ||
98 | __clear_bit(AR5K_MODE_11A, caps->cap_mode); | ||
99 | |||
97 | /* Set number of supported TX queues */ | 100 | /* Set number of supported TX queues */ |
98 | if (ah->ah_version == AR5K_AR5210) | 101 | if (ah->ah_version == AR5K_AR5210) |
99 | caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU; | 102 | caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU; |
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 0230f30e9e9..0bf7313b8a1 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c | |||
@@ -888,65 +888,38 @@ static const struct file_operations fops_queue = { | |||
888 | void | 888 | void |
889 | ath5k_debug_init_device(struct ath5k_softc *sc) | 889 | ath5k_debug_init_device(struct ath5k_softc *sc) |
890 | { | 890 | { |
891 | sc->debug.level = ath5k_debug; | 891 | struct dentry *phydir; |
892 | 892 | ||
893 | sc->debug.debugfs_phydir = debugfs_create_dir("ath5k", | 893 | sc->debug.level = ath5k_debug; |
894 | sc->hw->wiphy->debugfsdir); | ||
895 | 894 | ||
896 | sc->debug.debugfs_debug = debugfs_create_file("debug", | 895 | phydir = debugfs_create_dir("ath5k", sc->hw->wiphy->debugfsdir); |
897 | S_IWUSR | S_IRUSR, | 896 | if (!phydir) |
898 | sc->debug.debugfs_phydir, sc, &fops_debug); | 897 | return; |
899 | 898 | ||
900 | sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUSR, | 899 | debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, sc, |
901 | sc->debug.debugfs_phydir, sc, &fops_registers); | 900 | &fops_debug); |
902 | 901 | ||
903 | sc->debug.debugfs_beacon = debugfs_create_file("beacon", | 902 | debugfs_create_file("registers", S_IRUSR, phydir, sc, &fops_registers); |
904 | S_IWUSR | S_IRUSR, | ||
905 | sc->debug.debugfs_phydir, sc, &fops_beacon); | ||
906 | 903 | ||
907 | sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, | 904 | debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, sc, |
908 | sc->debug.debugfs_phydir, sc, &fops_reset); | 905 | &fops_beacon); |
909 | 906 | ||
910 | sc->debug.debugfs_antenna = debugfs_create_file("antenna", | 907 | debugfs_create_file("reset", S_IWUSR, phydir, sc, &fops_reset); |
911 | S_IWUSR | S_IRUSR, | ||
912 | sc->debug.debugfs_phydir, sc, &fops_antenna); | ||
913 | 908 | ||
914 | sc->debug.debugfs_misc = debugfs_create_file("misc", | 909 | debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, sc, |
915 | S_IRUSR, | 910 | &fops_antenna); |
916 | sc->debug.debugfs_phydir, sc, &fops_misc); | ||
917 | 911 | ||
918 | sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors", | 912 | debugfs_create_file("misc", S_IRUSR, phydir, sc, &fops_misc); |
919 | S_IWUSR | S_IRUSR, | ||
920 | sc->debug.debugfs_phydir, sc, | ||
921 | &fops_frameerrors); | ||
922 | 913 | ||
923 | sc->debug.debugfs_ani = debugfs_create_file("ani", | 914 | debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, sc, |
924 | S_IWUSR | S_IRUSR, | 915 | &fops_frameerrors); |
925 | sc->debug.debugfs_phydir, sc, | ||
926 | &fops_ani); | ||
927 | 916 | ||
928 | sc->debug.debugfs_queue = debugfs_create_file("queue", | 917 | debugfs_create_file("ani", S_IWUSR | S_IRUSR, phydir, sc, &fops_ani); |
929 | S_IWUSR | S_IRUSR, | ||
930 | sc->debug.debugfs_phydir, sc, | ||
931 | &fops_queue); | ||
932 | } | ||
933 | 918 | ||
934 | void | 919 | debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, sc, |
935 | ath5k_debug_finish_device(struct ath5k_softc *sc) | 920 | &fops_queue); |
936 | { | ||
937 | debugfs_remove(sc->debug.debugfs_debug); | ||
938 | debugfs_remove(sc->debug.debugfs_registers); | ||
939 | debugfs_remove(sc->debug.debugfs_beacon); | ||
940 | debugfs_remove(sc->debug.debugfs_reset); | ||
941 | debugfs_remove(sc->debug.debugfs_antenna); | ||
942 | debugfs_remove(sc->debug.debugfs_misc); | ||
943 | debugfs_remove(sc->debug.debugfs_frameerrors); | ||
944 | debugfs_remove(sc->debug.debugfs_ani); | ||
945 | debugfs_remove(sc->debug.debugfs_queue); | ||
946 | debugfs_remove(sc->debug.debugfs_phydir); | ||
947 | } | 921 | } |
948 | 922 | ||
949 | |||
950 | /* functions used in other places */ | 923 | /* functions used in other places */ |
951 | 924 | ||
952 | void | 925 | void |
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index b0355aef68d..193dd2d4ea3 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h | |||
@@ -68,17 +68,6 @@ struct ath5k_buf; | |||
68 | 68 | ||
69 | struct ath5k_dbg_info { | 69 | struct 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_misc; | ||
79 | struct dentry *debugfs_frameerrors; | ||
80 | struct dentry *debugfs_ani; | ||
81 | struct dentry *debugfs_queue; | ||
82 | }; | 71 | }; |
83 | 72 | ||
84 | /** | 73 | /** |
@@ -141,9 +130,6 @@ void | |||
141 | ath5k_debug_init_device(struct ath5k_softc *sc); | 130 | ath5k_debug_init_device(struct ath5k_softc *sc); |
142 | 131 | ||
143 | void | 132 | void |
144 | ath5k_debug_finish_device(struct ath5k_softc *sc); | ||
145 | |||
146 | void | ||
147 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); | 133 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); |
148 | 134 | ||
149 | void | 135 | void |
@@ -167,9 +153,6 @@ static inline void | |||
167 | ath5k_debug_init_device(struct ath5k_softc *sc) {} | 153 | ath5k_debug_init_device(struct ath5k_softc *sc) {} |
168 | 154 | ||
169 | static inline void | 155 | static inline void |
170 | ath5k_debug_finish_device(struct ath5k_softc *sc) {} | ||
171 | |||
172 | static inline void | ||
173 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} | 156 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} |
174 | 157 | ||
175 | static inline void | 158 | static inline void |
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index a8fcc94269f..62172d58572 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c | |||
@@ -185,6 +185,12 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
185 | struct ath5k_hw_4w_tx_ctl *tx_ctl; | 185 | struct ath5k_hw_4w_tx_ctl *tx_ctl; |
186 | unsigned int frame_len; | 186 | unsigned int frame_len; |
187 | 187 | ||
188 | /* | ||
189 | * Use local variables for these to reduce load/store access on | ||
190 | * uncached memory | ||
191 | */ | ||
192 | u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0; | ||
193 | |||
188 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; | 194 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; |
189 | 195 | ||
190 | /* | 196 | /* |
@@ -208,8 +214,9 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
208 | if (tx_power > AR5K_TUNE_MAX_TXPOWER) | 214 | if (tx_power > AR5K_TUNE_MAX_TXPOWER) |
209 | tx_power = AR5K_TUNE_MAX_TXPOWER; | 215 | tx_power = AR5K_TUNE_MAX_TXPOWER; |
210 | 216 | ||
211 | /* Clear descriptor */ | 217 | /* Clear descriptor status area */ |
212 | memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc)); | 218 | memset(&desc->ud.ds_tx5212.tx_stat, 0, |
219 | sizeof(desc->ud.ds_tx5212.tx_stat)); | ||
213 | 220 | ||
214 | /* Setup control descriptor */ | 221 | /* Setup control descriptor */ |
215 | 222 | ||
@@ -221,7 +228,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
221 | if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) | 228 | if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) |
222 | return -EINVAL; | 229 | return -EINVAL; |
223 | 230 | ||
224 | tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; | 231 | txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; |
225 | 232 | ||
226 | /* Verify and set buffer length */ | 233 | /* Verify and set buffer length */ |
227 | 234 | ||
@@ -232,21 +239,17 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
232 | if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) | 239 | if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) |
233 | return -EINVAL; | 240 | return -EINVAL; |
234 | 241 | ||
235 | tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; | 242 | txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; |
236 | 243 | ||
237 | tx_ctl->tx_control_0 |= | 244 | txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | |
238 | AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | | 245 | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); |
239 | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); | 246 | txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); |
240 | tx_ctl->tx_control_1 |= AR5K_REG_SM(type, | 247 | txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); |
241 | AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); | 248 | txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; |
242 | tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0, | ||
243 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); | ||
244 | tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | ||
245 | 249 | ||
246 | #define _TX_FLAGS(_c, _flag) \ | 250 | #define _TX_FLAGS(_c, _flag) \ |
247 | if (flags & AR5K_TXDESC_##_flag) { \ | 251 | if (flags & AR5K_TXDESC_##_flag) { \ |
248 | tx_ctl->tx_control_##_c |= \ | 252 | txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ |
249 | AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ | ||
250 | } | 253 | } |
251 | 254 | ||
252 | _TX_FLAGS(0, CLRDMASK); | 255 | _TX_FLAGS(0, CLRDMASK); |
@@ -262,8 +265,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
262 | * WEP crap | 265 | * WEP crap |
263 | */ | 266 | */ |
264 | if (key_index != AR5K_TXKEYIX_INVALID) { | 267 | if (key_index != AR5K_TXKEYIX_INVALID) { |
265 | tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; | 268 | txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; |
266 | tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, | 269 | txctl1 |= AR5K_REG_SM(key_index, |
267 | AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); | 270 | AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); |
268 | } | 271 | } |
269 | 272 | ||
@@ -274,12 +277,16 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
274 | if ((flags & AR5K_TXDESC_RTSENA) && | 277 | if ((flags & AR5K_TXDESC_RTSENA) && |
275 | (flags & AR5K_TXDESC_CTSENA)) | 278 | (flags & AR5K_TXDESC_CTSENA)) |
276 | return -EINVAL; | 279 | return -EINVAL; |
277 | tx_ctl->tx_control_2 |= rtscts_duration & | 280 | txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION; |
278 | AR5K_4W_TX_DESC_CTL2_RTS_DURATION; | 281 | txctl3 |= AR5K_REG_SM(rtscts_rate, |
279 | tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate, | ||
280 | AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); | 282 | AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); |
281 | } | 283 | } |
282 | 284 | ||
285 | tx_ctl->tx_control_0 = txctl0; | ||
286 | tx_ctl->tx_control_1 = txctl1; | ||
287 | tx_ctl->tx_control_2 = txctl2; | ||
288 | tx_ctl->tx_control_3 = txctl3; | ||
289 | |||
283 | return 0; | 290 | return 0; |
284 | } | 291 | } |
285 | 292 | ||
@@ -364,7 +371,7 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, | |||
364 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); | 371 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); |
365 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, | 372 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, |
366 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); | 373 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); |
367 | ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, | 374 | ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0, |
368 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); | 375 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); |
369 | /*TODO: ts->ts_virtcol + test*/ | 376 | /*TODO: ts->ts_virtcol + test*/ |
370 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, | 377 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, |
@@ -373,9 +380,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, | |||
373 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); | 380 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); |
374 | ts->ts_antenna = 1; | 381 | ts->ts_antenna = 1; |
375 | ts->ts_status = 0; | 382 | ts->ts_status = 0; |
376 | ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0, | ||
377 | AR5K_2W_TX_DESC_CTL0_XMIT_RATE); | ||
378 | ts->ts_retry[0] = ts->ts_longretry; | ||
379 | ts->ts_final_idx = 0; | 383 | ts->ts_final_idx = 0; |
380 | 384 | ||
381 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { | 385 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { |
@@ -401,81 +405,48 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, | |||
401 | { | 405 | { |
402 | struct ath5k_hw_4w_tx_ctl *tx_ctl; | 406 | struct ath5k_hw_4w_tx_ctl *tx_ctl; |
403 | struct ath5k_hw_tx_status *tx_status; | 407 | struct ath5k_hw_tx_status *tx_status; |
408 | u32 txstat0, txstat1; | ||
404 | 409 | ||
405 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; | 410 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; |
406 | tx_status = &desc->ud.ds_tx5212.tx_stat; | 411 | tx_status = &desc->ud.ds_tx5212.tx_stat; |
407 | 412 | ||
413 | txstat1 = ACCESS_ONCE(tx_status->tx_status_1); | ||
414 | |||
408 | /* No frame has been send or error */ | 415 | /* No frame has been send or error */ |
409 | if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE))) | 416 | if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE))) |
410 | return -EINPROGRESS; | 417 | return -EINPROGRESS; |
411 | 418 | ||
419 | txstat0 = ACCESS_ONCE(tx_status->tx_status_0); | ||
420 | |||
412 | /* | 421 | /* |
413 | * Get descriptor status | 422 | * Get descriptor status |
414 | */ | 423 | */ |
415 | ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, | 424 | ts->ts_tstamp = AR5K_REG_MS(txstat0, |
416 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); | 425 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); |
417 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, | 426 | ts->ts_shortretry = AR5K_REG_MS(txstat0, |
418 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); | 427 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); |
419 | ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, | 428 | ts->ts_final_retry = AR5K_REG_MS(txstat0, |
420 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); | 429 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); |
421 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, | 430 | ts->ts_seqnum = AR5K_REG_MS(txstat1, |
422 | AR5K_DESC_TX_STATUS1_SEQ_NUM); | 431 | AR5K_DESC_TX_STATUS1_SEQ_NUM); |
423 | ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, | 432 | ts->ts_rssi = AR5K_REG_MS(txstat1, |
424 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); | 433 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); |
425 | ts->ts_antenna = (tx_status->tx_status_1 & | 434 | ts->ts_antenna = (txstat1 & |
426 | AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; | 435 | AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; |
427 | ts->ts_status = 0; | 436 | ts->ts_status = 0; |
428 | 437 | ||
429 | ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, | 438 | ts->ts_final_idx = AR5K_REG_MS(txstat1, |
430 | AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); | 439 | AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); |
431 | 440 | ||
432 | /* The longretry counter has the number of un-acked retries | ||
433 | * for the final rate. To get the total number of retries | ||
434 | * we have to add the retry counters for the other rates | ||
435 | * as well | ||
436 | */ | ||
437 | ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry; | ||
438 | switch (ts->ts_final_idx) { | ||
439 | case 3: | ||
440 | ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
441 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE3); | ||
442 | |||
443 | ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
444 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); | ||
445 | ts->ts_longretry += ts->ts_retry[2]; | ||
446 | /* fall through */ | ||
447 | case 2: | ||
448 | ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
449 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); | ||
450 | |||
451 | ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
452 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); | ||
453 | ts->ts_longretry += ts->ts_retry[1]; | ||
454 | /* fall through */ | ||
455 | case 1: | ||
456 | ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
457 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); | ||
458 | |||
459 | ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
460 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); | ||
461 | ts->ts_longretry += ts->ts_retry[0]; | ||
462 | /* fall through */ | ||
463 | case 0: | ||
464 | ts->ts_rate[0] = tx_ctl->tx_control_3 & | ||
465 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | ||
466 | break; | ||
467 | } | ||
468 | |||
469 | /* TX error */ | 441 | /* TX error */ |
470 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { | 442 | if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { |
471 | if (tx_status->tx_status_0 & | 443 | if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) |
472 | AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) | ||
473 | ts->ts_status |= AR5K_TXERR_XRETRY; | 444 | ts->ts_status |= AR5K_TXERR_XRETRY; |
474 | 445 | ||
475 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) | 446 | if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) |
476 | ts->ts_status |= AR5K_TXERR_FIFO; | 447 | ts->ts_status |= AR5K_TXERR_FIFO; |
477 | 448 | ||
478 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) | 449 | if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED) |
479 | ts->ts_status |= AR5K_TXERR_FILT; | 450 | ts->ts_status |= AR5K_TXERR_FILT; |
480 | } | 451 | } |
481 | 452 | ||
@@ -609,37 +580,37 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
609 | struct ath5k_rx_status *rs) | 580 | struct ath5k_rx_status *rs) |
610 | { | 581 | { |
611 | struct ath5k_hw_rx_status *rx_status; | 582 | struct ath5k_hw_rx_status *rx_status; |
583 | u32 rxstat0, rxstat1; | ||
612 | 584 | ||
613 | rx_status = &desc->ud.ds_rx.rx_stat; | 585 | rx_status = &desc->ud.ds_rx.rx_stat; |
586 | rxstat1 = ACCESS_ONCE(rx_status->rx_status_1); | ||
614 | 587 | ||
615 | /* No frame received / not ready */ | 588 | /* No frame received / not ready */ |
616 | if (unlikely(!(rx_status->rx_status_1 & | 589 | if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE))) |
617 | AR5K_5212_RX_DESC_STATUS1_DONE))) | ||
618 | return -EINPROGRESS; | 590 | return -EINPROGRESS; |
619 | 591 | ||
620 | memset(rs, 0, sizeof(struct ath5k_rx_status)); | 592 | memset(rs, 0, sizeof(struct ath5k_rx_status)); |
593 | rxstat0 = ACCESS_ONCE(rx_status->rx_status_0); | ||
621 | 594 | ||
622 | /* | 595 | /* |
623 | * Frame receive status | 596 | * Frame receive status |
624 | */ | 597 | */ |
625 | rs->rs_datalen = rx_status->rx_status_0 & | 598 | rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN; |
626 | AR5K_5212_RX_DESC_STATUS0_DATA_LEN; | 599 | rs->rs_rssi = AR5K_REG_MS(rxstat0, |
627 | rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, | ||
628 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); | 600 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); |
629 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, | 601 | rs->rs_rate = AR5K_REG_MS(rxstat0, |
630 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); | 602 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); |
631 | rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, | 603 | rs->rs_antenna = AR5K_REG_MS(rxstat0, |
632 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); | 604 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); |
633 | rs->rs_more = !!(rx_status->rx_status_0 & | 605 | rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE); |
634 | AR5K_5212_RX_DESC_STATUS0_MORE); | 606 | rs->rs_tstamp = AR5K_REG_MS(rxstat1, |
635 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | ||
636 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | 607 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); |
637 | 608 | ||
638 | /* | 609 | /* |
639 | * Key table status | 610 | * Key table status |
640 | */ | 611 | */ |
641 | if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) | 612 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) |
642 | rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, | 613 | rs->rs_keyix = AR5K_REG_MS(rxstat1, |
643 | AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); | 614 | AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); |
644 | else | 615 | else |
645 | rs->rs_keyix = AR5K_RXKEYIX_INVALID; | 616 | rs->rs_keyix = AR5K_RXKEYIX_INVALID; |
@@ -647,27 +618,22 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
647 | /* | 618 | /* |
648 | * Receive/descriptor errors | 619 | * Receive/descriptor errors |
649 | */ | 620 | */ |
650 | if (!(rx_status->rx_status_1 & | 621 | if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { |
651 | AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { | 622 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) |
652 | if (rx_status->rx_status_1 & | ||
653 | AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) | ||
654 | rs->rs_status |= AR5K_RXERR_CRC; | 623 | rs->rs_status |= AR5K_RXERR_CRC; |
655 | 624 | ||
656 | if (rx_status->rx_status_1 & | 625 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { |
657 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { | ||
658 | rs->rs_status |= AR5K_RXERR_PHY; | 626 | rs->rs_status |= AR5K_RXERR_PHY; |
659 | rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, | 627 | rs->rs_phyerr = AR5K_REG_MS(rxstat1, |
660 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); | 628 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); |
661 | if (!ah->ah_capabilities.cap_has_phyerr_counters) | 629 | if (!ah->ah_capabilities.cap_has_phyerr_counters) |
662 | ath5k_ani_phy_error_report(ah, rs->rs_phyerr); | 630 | ath5k_ani_phy_error_report(ah, rs->rs_phyerr); |
663 | } | 631 | } |
664 | 632 | ||
665 | if (rx_status->rx_status_1 & | 633 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) |
666 | AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) | ||
667 | rs->rs_status |= AR5K_RXERR_DECRYPT; | 634 | rs->rs_status |= AR5K_RXERR_DECRYPT; |
668 | 635 | ||
669 | if (rx_status->rx_status_1 & | 636 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) |
670 | AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) | ||
671 | rs->rs_status |= AR5K_RXERR_MIC; | 637 | rs->rs_status |= AR5K_RXERR_MIC; |
672 | } | 638 | } |
673 | return 0; | 639 | return 0; |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index efb672cb31e..1fef84f87c7 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | |||
@@ -660,6 +660,53 @@ ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) | |||
660 | vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; | 660 | vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; |
661 | } | 661 | } |
662 | 662 | ||
663 | static int | ||
664 | ath5k_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 < ee->ee_pd_gains[mode]; pdg++) { | ||
695 | struct ath5k_pdgain_info *pd = | ||
696 | &chinfo[pier].pd_curves[pdg]; | ||
697 | |||
698 | if (pd != NULL) { | ||
699 | kfree(pd->pd_step); | ||
700 | kfree(pd->pd_pwr); | ||
701 | } | ||
702 | } | ||
703 | |||
704 | kfree(chinfo[pier].pd_curves); | ||
705 | } | ||
706 | |||
707 | return 0; | ||
708 | } | ||
709 | |||
663 | /* Convert RF5111 specific data to generic raw data | 710 | /* Convert RF5111 specific data to generic raw data |
664 | * used by interpolation code */ | 711 | * used by interpolation code */ |
665 | static int | 712 | static int |
@@ -684,7 +731,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, | |||
684 | GFP_KERNEL); | 731 | GFP_KERNEL); |
685 | 732 | ||
686 | if (!chinfo[pier].pd_curves) | 733 | if (!chinfo[pier].pd_curves) |
687 | return -ENOMEM; | 734 | goto err_out; |
688 | 735 | ||
689 | /* Only one curve for RF5111 | 736 | /* Only one curve for RF5111 |
690 | * find out which one and place | 737 | * find out which one and place |
@@ -708,12 +755,12 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, | |||
708 | pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, | 755 | pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, |
709 | sizeof(u8), GFP_KERNEL); | 756 | sizeof(u8), GFP_KERNEL); |
710 | if (!pd->pd_step) | 757 | if (!pd->pd_step) |
711 | return -ENOMEM; | 758 | goto err_out; |
712 | 759 | ||
713 | pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, | 760 | pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, |
714 | sizeof(s16), GFP_KERNEL); | 761 | sizeof(s16), GFP_KERNEL); |
715 | if (!pd->pd_pwr) | 762 | if (!pd->pd_pwr) |
716 | return -ENOMEM; | 763 | goto err_out; |
717 | 764 | ||
718 | /* Fill raw dataset | 765 | /* Fill raw dataset |
719 | * (convert power to 0.25dB units | 766 | * (convert power to 0.25dB units |
@@ -734,6 +781,10 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, | |||
734 | } | 781 | } |
735 | 782 | ||
736 | return 0; | 783 | return 0; |
784 | |||
785 | err_out: | ||
786 | ath5k_eeprom_free_pcal_info(ah, mode); | ||
787 | return -ENOMEM; | ||
737 | } | 788 | } |
738 | 789 | ||
739 | /* Parse EEPROM data */ | 790 | /* Parse EEPROM data */ |
@@ -867,7 +918,7 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
867 | GFP_KERNEL); | 918 | GFP_KERNEL); |
868 | 919 | ||
869 | if (!chinfo[pier].pd_curves) | 920 | if (!chinfo[pier].pd_curves) |
870 | return -ENOMEM; | 921 | goto err_out; |
871 | 922 | ||
872 | /* Fill pd_curves */ | 923 | /* Fill pd_curves */ |
873 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | 924 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { |
@@ -886,14 +937,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
886 | sizeof(u8), GFP_KERNEL); | 937 | sizeof(u8), GFP_KERNEL); |
887 | 938 | ||
888 | if (!pd->pd_step) | 939 | if (!pd->pd_step) |
889 | return -ENOMEM; | 940 | goto err_out; |
890 | 941 | ||
891 | pd->pd_pwr = kcalloc(pd->pd_points, | 942 | pd->pd_pwr = kcalloc(pd->pd_points, |
892 | sizeof(s16), GFP_KERNEL); | 943 | sizeof(s16), GFP_KERNEL); |
893 | 944 | ||
894 | if (!pd->pd_pwr) | 945 | if (!pd->pd_pwr) |
895 | return -ENOMEM; | 946 | goto err_out; |
896 | |||
897 | 947 | ||
898 | /* Fill raw dataset | 948 | /* Fill raw dataset |
899 | * (all power levels are in 0.25dB units) */ | 949 | * (all power levels are in 0.25dB units) */ |
@@ -925,13 +975,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
925 | sizeof(u8), GFP_KERNEL); | 975 | sizeof(u8), GFP_KERNEL); |
926 | 976 | ||
927 | if (!pd->pd_step) | 977 | if (!pd->pd_step) |
928 | return -ENOMEM; | 978 | goto err_out; |
929 | 979 | ||
930 | pd->pd_pwr = kcalloc(pd->pd_points, | 980 | pd->pd_pwr = kcalloc(pd->pd_points, |
931 | sizeof(s16), GFP_KERNEL); | 981 | sizeof(s16), GFP_KERNEL); |
932 | 982 | ||
933 | if (!pd->pd_pwr) | 983 | if (!pd->pd_pwr) |
934 | return -ENOMEM; | 984 | goto err_out; |
935 | 985 | ||
936 | /* Fill raw dataset | 986 | /* Fill raw dataset |
937 | * (all power levels are in 0.25dB units) */ | 987 | * (all power levels are in 0.25dB units) */ |
@@ -954,6 +1004,10 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
954 | } | 1004 | } |
955 | 1005 | ||
956 | return 0; | 1006 | return 0; |
1007 | |||
1008 | err_out: | ||
1009 | ath5k_eeprom_free_pcal_info(ah, mode); | ||
1010 | return -ENOMEM; | ||
957 | } | 1011 | } |
958 | 1012 | ||
959 | /* Parse EEPROM data */ | 1013 | /* Parse EEPROM data */ |
@@ -1156,7 +1210,7 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, | |||
1156 | GFP_KERNEL); | 1210 | GFP_KERNEL); |
1157 | 1211 | ||
1158 | if (!chinfo[pier].pd_curves) | 1212 | if (!chinfo[pier].pd_curves) |
1159 | return -ENOMEM; | 1213 | goto err_out; |
1160 | 1214 | ||
1161 | /* Fill pd_curves */ | 1215 | /* Fill pd_curves */ |
1162 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | 1216 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { |
@@ -1177,13 +1231,13 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, | |||
1177 | sizeof(u8), GFP_KERNEL); | 1231 | sizeof(u8), GFP_KERNEL); |
1178 | 1232 | ||
1179 | if (!pd->pd_step) | 1233 | if (!pd->pd_step) |
1180 | return -ENOMEM; | 1234 | goto err_out; |
1181 | 1235 | ||
1182 | pd->pd_pwr = kcalloc(pd->pd_points, | 1236 | pd->pd_pwr = kcalloc(pd->pd_points, |
1183 | sizeof(s16), GFP_KERNEL); | 1237 | sizeof(s16), GFP_KERNEL); |
1184 | 1238 | ||
1185 | if (!pd->pd_pwr) | 1239 | if (!pd->pd_pwr) |
1186 | return -ENOMEM; | 1240 | goto err_out; |
1187 | 1241 | ||
1188 | /* Fill raw dataset | 1242 | /* Fill raw dataset |
1189 | * convert all pwr levels to | 1243 | * convert all pwr levels to |
@@ -1213,6 +1267,10 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, | |||
1213 | } | 1267 | } |
1214 | 1268 | ||
1215 | return 0; | 1269 | return 0; |
1270 | |||
1271 | err_out: | ||
1272 | ath5k_eeprom_free_pcal_info(ah, mode); | ||
1273 | return -ENOMEM; | ||
1216 | } | 1274 | } |
1217 | 1275 | ||
1218 | /* Parse EEPROM data */ | 1276 | /* Parse EEPROM data */ |
@@ -1534,53 +1592,6 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah) | |||
1534 | return 0; | 1592 | return 0; |
1535 | } | 1593 | } |
1536 | 1594 | ||
1537 | static int | ||
1538 | ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) | ||
1539 | { | ||
1540 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
1541 | struct ath5k_chan_pcal_info *chinfo; | ||
1542 | u8 pier, pdg; | ||
1543 | |||
1544 | switch (mode) { | ||
1545 | case AR5K_EEPROM_MODE_11A: | ||
1546 | if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) | ||
1547 | return 0; | ||
1548 | chinfo = ee->ee_pwr_cal_a; | ||
1549 | break; | ||
1550 | case AR5K_EEPROM_MODE_11B: | ||
1551 | if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) | ||
1552 | return 0; | ||
1553 | chinfo = ee->ee_pwr_cal_b; | ||
1554 | break; | ||
1555 | case AR5K_EEPROM_MODE_11G: | ||
1556 | if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) | ||
1557 | return 0; | ||
1558 | chinfo = ee->ee_pwr_cal_g; | ||
1559 | break; | ||
1560 | default: | ||
1561 | return -EINVAL; | ||
1562 | } | ||
1563 | |||
1564 | for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { | ||
1565 | if (!chinfo[pier].pd_curves) | ||
1566 | continue; | ||
1567 | |||
1568 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | ||
1569 | struct ath5k_pdgain_info *pd = | ||
1570 | &chinfo[pier].pd_curves[pdg]; | ||
1571 | |||
1572 | if (pd != NULL) { | ||
1573 | kfree(pd->pd_step); | ||
1574 | kfree(pd->pd_pwr); | ||
1575 | } | ||
1576 | } | ||
1577 | |||
1578 | kfree(chinfo[pier].pd_curves); | ||
1579 | } | ||
1580 | |||
1581 | return 0; | ||
1582 | } | ||
1583 | |||
1584 | /* Read conformance test limits used for regulatory control */ | 1595 | /* Read conformance test limits used for regulatory control */ |
1585 | static int | 1596 | static int |
1586 | ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) | 1597 | ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) |
@@ -1721,35 +1732,6 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah) | |||
1721 | return ret; | 1732 | return ret; |
1722 | } | 1733 | } |
1723 | 1734 | ||
1724 | /* | ||
1725 | * Read the MAC address from eeprom | ||
1726 | */ | ||
1727 | int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | ||
1728 | { | ||
1729 | u8 mac_d[ETH_ALEN] = {}; | ||
1730 | u32 total, offset; | ||
1731 | u16 data; | ||
1732 | int octet; | ||
1733 | |||
1734 | AR5K_EEPROM_READ(0x20, data); | ||
1735 | |||
1736 | for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { | ||
1737 | AR5K_EEPROM_READ(offset, data); | ||
1738 | |||
1739 | total += data; | ||
1740 | mac_d[octet + 1] = data & 0xff; | ||
1741 | mac_d[octet] = data >> 8; | ||
1742 | octet += 2; | ||
1743 | } | ||
1744 | |||
1745 | if (!total || total == 3 * 0xffff) | ||
1746 | return -EINVAL; | ||
1747 | |||
1748 | memcpy(mac, mac_d, ETH_ALEN); | ||
1749 | |||
1750 | return 0; | ||
1751 | } | ||
1752 | |||
1753 | 1735 | ||
1754 | /***********************\ | 1736 | /***********************\ |
1755 | * Init/Detach functions * | 1737 | * Init/Detach functions * |
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 9be29b728b1..807bd644016 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -282,6 +282,15 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
282 | if (changes & BSS_CHANGED_BEACON_INT) | 282 | if (changes & BSS_CHANGED_BEACON_INT) |
283 | sc->bintval = bss_conf->beacon_int; | 283 | sc->bintval = bss_conf->beacon_int; |
284 | 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 | |||
285 | if (changes & BSS_CHANGED_ASSOC) { | 294 | if (changes & BSS_CHANGED_ASSOC) { |
286 | avf->assoc = bss_conf->assoc; | 295 | avf->assoc = bss_conf->assoc; |
287 | if (bss_conf->assoc) | 296 | if (bss_conf->assoc) |
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index 3c44689a700..296c316a834 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/nl80211.h> | 17 | #include <linux/nl80211.h> |
18 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
19 | #include <linux/pci-aspm.h> | 19 | #include <linux/pci-aspm.h> |
20 | #include <linux/etherdevice.h> | ||
20 | #include "../ath.h" | 21 | #include "../ath.h" |
21 | #include "ath5k.h" | 22 | #include "ath5k.h" |
22 | #include "debug.h" | 23 | #include "debug.h" |
@@ -108,11 +109,42 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah) | |||
108 | return 0; | 109 | return 0; |
109 | } | 110 | } |
110 | 111 | ||
112 | /* | ||
113 | * Read the MAC address from eeprom or platform_data | ||
114 | */ | ||
115 | static 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 | |||
111 | /* Common ath_bus_opts structure */ | 142 | /* Common ath_bus_opts structure */ |
112 | static const struct ath_bus_ops ath_pci_bus_ops = { | 143 | static const struct ath_bus_ops ath_pci_bus_ops = { |
113 | .ath_bus_type = ATH_PCI, | 144 | .ath_bus_type = ATH_PCI, |
114 | .read_cachesize = ath5k_pci_read_cachesize, | 145 | .read_cachesize = ath5k_pci_read_cachesize, |
115 | .eeprom_read = ath5k_pci_eeprom_read, | 146 | .eeprom_read = ath5k_pci_eeprom_read, |
147 | .eeprom_read_mac = ath5k_pci_eeprom_read_mac, | ||
116 | }; | 148 | }; |
117 | 149 | ||
118 | /********************\ | 150 | /********************\ |
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index d9b3f828455..712a9ac4000 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c | |||
@@ -75,7 +75,7 @@ static const unsigned int ack_rates_high[] = | |||
75 | * bwmodes. | 75 | * bwmodes. |
76 | */ | 76 | */ |
77 | int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | 77 | int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, |
78 | int len, struct ieee80211_rate *rate) | 78 | int len, struct ieee80211_rate *rate, bool shortpre) |
79 | { | 79 | { |
80 | struct ath5k_softc *sc = ah->ah_sc; | 80 | struct ath5k_softc *sc = ah->ah_sc; |
81 | int sifs, preamble, plcp_bits, sym_time; | 81 | int sifs, preamble, plcp_bits, sym_time; |
@@ -84,9 +84,15 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | |||
84 | 84 | ||
85 | /* Fallback */ | 85 | /* Fallback */ |
86 | if (!ah->ah_bwmode) { | 86 | if (!ah->ah_bwmode) { |
87 | dur = ieee80211_generic_frame_duration(sc->hw, | 87 | __le16 raw_dur = ieee80211_generic_frame_duration(sc->hw, |
88 | NULL, len, rate); | 88 | NULL, len, rate); |
89 | return le16_to_cpu(dur); | 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; | ||
90 | } | 96 | } |
91 | 97 | ||
92 | bitrate = rate->bitrate; | 98 | bitrate = rate->bitrate; |
@@ -145,9 +151,9 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) | |||
145 | slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE; | 151 | slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE; |
146 | break; | 152 | break; |
147 | case AR5K_BWMODE_DEFAULT: | 153 | case AR5K_BWMODE_DEFAULT: |
148 | slot_time = AR5K_INIT_SLOT_TIME_DEFAULT; | ||
149 | default: | 154 | default: |
150 | if (channel->hw_value & CHANNEL_CCK) | 155 | slot_time = AR5K_INIT_SLOT_TIME_DEFAULT; |
156 | if ((channel->hw_value & CHANNEL_CCK) && !ah->ah_short_slot) | ||
151 | slot_time = AR5K_INIT_SLOT_TIME_B; | 157 | slot_time = AR5K_INIT_SLOT_TIME_B; |
152 | break; | 158 | break; |
153 | } | 159 | } |
@@ -263,27 +269,14 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah) | |||
263 | * actual rate for this rate. See mac80211 tx.c | 269 | * actual rate for this rate. See mac80211 tx.c |
264 | * ieee80211_duration() for a brief description of | 270 | * ieee80211_duration() for a brief description of |
265 | * what rate we should choose to TX ACKs. */ | 271 | * what rate we should choose to TX ACKs. */ |
266 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); | 272 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); |
267 | 273 | ||
268 | ath5k_hw_reg_write(ah, tx_time, reg); | 274 | ath5k_hw_reg_write(ah, tx_time, reg); |
269 | 275 | ||
270 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) | 276 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) |
271 | continue; | 277 | continue; |
272 | 278 | ||
273 | /* | 279 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, true); |
274 | * We're not distinguishing short preamble here, | ||
275 | * This is true, all we'll get is a longer value here | ||
276 | * which is not necessarilly bad. We could use | ||
277 | * export ieee80211_frame_duration() but that needs to be | ||
278 | * fixed first to be properly used by mac802111 drivers: | ||
279 | * | ||
280 | * - remove erp stuff and let the routine figure ofdm | ||
281 | * erp rates | ||
282 | * - remove passing argument ieee80211_local as | ||
283 | * drivers don't have access to it | ||
284 | * - move drivers using ieee80211_generic_frame_duration() | ||
285 | * to this | ||
286 | */ | ||
287 | ath5k_hw_reg_write(ah, tx_time, | 280 | ath5k_hw_reg_write(ah, tx_time, |
288 | reg + (AR5K_SET_SHORT_PREAMBLE << 2)); | 281 | reg + (AR5K_SET_SHORT_PREAMBLE << 2)); |
289 | } | 282 | } |
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 3343fb9e494..b18c5021aac 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c | |||
@@ -519,7 +519,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) | |||
519 | return -EINVAL; | 519 | return -EINVAL; |
520 | 520 | ||
521 | sifs = ath5k_hw_get_default_sifs(ah); | 521 | sifs = ath5k_hw_get_default_sifs(ah); |
522 | sifs_clock = ath5k_hw_htoclock(ah, sifs); | 522 | sifs_clock = ath5k_hw_htoclock(ah, sifs - 2); |
523 | 523 | ||
524 | /* EIFS | 524 | /* EIFS |
525 | * Txtime of ack at lowest rate + SIFS + DIFS | 525 | * Txtime of ack at lowest rate + SIFS + DIFS |
@@ -550,7 +550,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) | |||
550 | else | 550 | else |
551 | rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; | 551 | rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; |
552 | 552 | ||
553 | ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); | 553 | ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); |
554 | 554 | ||
555 | /* ack_tx_time includes an SIFS already */ | 555 | /* ack_tx_time includes an SIFS already */ |
556 | eifs = ack_tx_time + sifs + 2 * slot_time; | 556 | eifs = ack_tx_time + sifs + 2 * slot_time; |
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 84206898f77..3510de2cf62 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c | |||
@@ -159,6 +159,11 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah) | |||
159 | rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211); | 159 | rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211); |
160 | 160 | ||
161 | /* | 161 | /* |
162 | * Set default Tx frame to Tx data start delay | ||
163 | */ | ||
164 | txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT; | ||
165 | |||
166 | /* | ||
162 | * 5210 initvals don't include usec settings | 167 | * 5210 initvals don't include usec settings |
163 | * so we need to use magic values here for | 168 | * so we need to use magic values here for |
164 | * tx/rx latencies | 169 | * tx/rx latencies |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index ad57a6d2311..d9ff8413ab9 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -5,7 +5,7 @@ config ATH9K_COMMON | |||
5 | 5 | ||
6 | config ATH9K | 6 | config ATH9K |
7 | tristate "Atheros 802.11n wireless cards support" | 7 | tristate "Atheros 802.11n wireless cards support" |
8 | depends on PCI && MAC80211 | 8 | depends on MAC80211 |
9 | select ATH9K_HW | 9 | select ATH9K_HW |
10 | select MAC80211_LEDS | 10 | select MAC80211_LEDS |
11 | select LEDS_CLASS | 11 | select LEDS_CLASS |
@@ -23,6 +23,25 @@ config ATH9K | |||
23 | 23 | ||
24 | If you choose to build a module, it'll be called ath9k. | 24 | If you choose to build a module, it'll be called ath9k. |
25 | 25 | ||
26 | config ATH9K_PCI | ||
27 | bool "Atheros ath9k PCI/PCIe bus support" | ||
28 | depends on ATH9K && PCI | ||
29 | default PCI | ||
30 | ---help--- | ||
31 | This option enables the PCI bus support in ath9k. | ||
32 | |||
33 | Say Y, if you have a compatible PCI/PCIe wireless card. | ||
34 | |||
35 | config ATH9K_AHB | ||
36 | bool "Atheros ath9k AHB bus support" | ||
37 | depends on ATH9K | ||
38 | default n | ||
39 | ---help--- | ||
40 | This option enables the AHB bus support in ath9k. | ||
41 | |||
42 | Say Y, if you have a SoC with a compatible built-in | ||
43 | wireless MAC. Say N if unsure. | ||
44 | |||
26 | config ATH9K_DEBUGFS | 45 | config ATH9K_DEBUGFS |
27 | bool "Atheros ath9k debugging" | 46 | bool "Atheros ath9k debugging" |
28 | depends on ATH9K && DEBUG_FS | 47 | depends on ATH9K && DEBUG_FS |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 4d66ca8042e..05a6fade7b1 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -6,8 +6,8 @@ ath9k-y += beacon.o \ | |||
6 | xmit.o \ | 6 | xmit.o \ |
7 | 7 | ||
8 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o | 8 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o |
9 | ath9k-$(CONFIG_PCI) += pci.o | 9 | ath9k-$(CONFIG_ATH9K_PCI) += pci.o |
10 | ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o | 10 | ath9k-$(CONFIG_ATH9K_AHB) += ahb.o |
11 | ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o | 11 | ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o |
12 | 12 | ||
13 | obj-$(CONFIG_ATH9K) += ath9k.o | 13 | obj-$(CONFIG_ATH9K) += ath9k.o |
@@ -48,4 +48,6 @@ ath9k_htc-y += htc_hst.o \ | |||
48 | htc_drv_init.o \ | 48 | htc_drv_init.o \ |
49 | htc_drv_gpio.o | 49 | htc_drv_gpio.o |
50 | 50 | ||
51 | ath9k_htc-$(CONFIG_ATH9K_HTC_DEBUGFS) += htc_drv_debug.o | ||
52 | |||
51 | obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o | 53 | obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o |
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 9cb0efa9b4c..61956392f2d 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -21,6 +21,18 @@ | |||
21 | #include <linux/ath9k_platform.h> | 21 | #include <linux/ath9k_platform.h> |
22 | #include "ath9k.h" | 22 | #include "ath9k.h" |
23 | 23 | ||
24 | static const struct platform_device_id ath9k_platform_id_table[] = { | ||
25 | { | ||
26 | .name = "ath9k", | ||
27 | .driver_data = AR5416_AR9100_DEVID, | ||
28 | }, | ||
29 | { | ||
30 | .name = "ar934x_wmac", | ||
31 | .driver_data = AR9300_DEVID_AR9340, | ||
32 | }, | ||
33 | {}, | ||
34 | }; | ||
35 | |||
24 | /* return bus cachesize in 4B word units */ | 36 | /* return bus cachesize in 4B word units */ |
25 | static void ath_ahb_read_cachesize(struct ath_common *common, int *csz) | 37 | static void ath_ahb_read_cachesize(struct ath_common *common, int *csz) |
26 | { | 38 | { |
@@ -57,6 +69,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
57 | struct ath_softc *sc; | 69 | struct ath_softc *sc; |
58 | struct ieee80211_hw *hw; | 70 | struct ieee80211_hw *hw; |
59 | struct resource *res; | 71 | struct resource *res; |
72 | const struct platform_device_id *id = platform_get_device_id(pdev); | ||
60 | int irq; | 73 | int irq; |
61 | int ret = 0; | 74 | int ret = 0; |
62 | struct ath_hw *ah; | 75 | struct ath_hw *ah; |
@@ -116,7 +129,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
116 | goto err_free_hw; | 129 | goto err_free_hw; |
117 | } | 130 | } |
118 | 131 | ||
119 | ret = ath9k_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops); | 132 | ret = ath9k_init_device(id->driver_data, sc, 0x0, &ath_ahb_bus_ops); |
120 | if (ret) { | 133 | if (ret) { |
121 | dev_err(&pdev->dev, "failed to initialize device\n"); | 134 | dev_err(&pdev->dev, "failed to initialize device\n"); |
122 | goto err_irq; | 135 | goto err_irq; |
@@ -165,8 +178,11 @@ static struct platform_driver ath_ahb_driver = { | |||
165 | .name = "ath9k", | 178 | .name = "ath9k", |
166 | .owner = THIS_MODULE, | 179 | .owner = THIS_MODULE, |
167 | }, | 180 | }, |
181 | .id_table = ath9k_platform_id_table, | ||
168 | }; | 182 | }; |
169 | 183 | ||
184 | MODULE_DEVICE_TABLE(platform, ath9k_platform_id_table); | ||
185 | |||
170 | int ath_ahb_init(void) | 186 | int ath_ahb_init(void) |
171 | { | 187 | { |
172 | return platform_driver_register(&ath_ahb_driver); | 188 | return platform_driver_register(&ath_ahb_driver); |
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 2e31c775351..5a1f4f511bc 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c | |||
@@ -899,12 +899,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah) | |||
899 | * check here default level should not modify INI setting. | 899 | * check here default level should not modify INI setting. |
900 | */ | 900 | */ |
901 | if (use_new_ani(ah)) { | 901 | if (use_new_ani(ah)) { |
902 | const struct ani_ofdm_level_entry *entry_ofdm; | ||
903 | const struct ani_cck_level_entry *entry_cck; | ||
904 | |||
905 | entry_ofdm = &ofdm_level_table[ATH9K_ANI_OFDM_DEF_LEVEL]; | ||
906 | entry_cck = &cck_level_table[ATH9K_ANI_CCK_DEF_LEVEL]; | ||
907 | |||
908 | ah->aniperiod = ATH9K_ANI_PERIOD_NEW; | 902 | ah->aniperiod = ATH9K_ANI_PERIOD_NEW; |
909 | ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW; | 903 | ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW; |
910 | } else { | 904 | } else { |
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 106c0b06cf5..4bf9dab4f2b 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | |||
@@ -44,6 +44,34 @@ static const int m1ThreshExt_off = 127; | |||
44 | static const int m2ThreshExt_off = 127; | 44 | static const int m2ThreshExt_off = 127; |
45 | 45 | ||
46 | 46 | ||
47 | static void ar5008_rf_bank_setup(u32 *bank, struct ar5416IniArray *array, | ||
48 | int col) | ||
49 | { | ||
50 | int i; | ||
51 | |||
52 | for (i = 0; i < array->ia_rows; i++) | ||
53 | bank[i] = INI_RA(array, i, col); | ||
54 | } | ||
55 | |||
56 | |||
57 | #define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) \ | ||
58 | ar5008_write_rf_array(ah, iniarray, regData, &(regWr)) | ||
59 | |||
60 | static void ar5008_write_rf_array(struct ath_hw *ah, struct ar5416IniArray *array, | ||
61 | u32 *data, unsigned int *writecnt) | ||
62 | { | ||
63 | int r; | ||
64 | |||
65 | ENABLE_REGWRITE_BUFFER(ah); | ||
66 | |||
67 | for (r = 0; r < array->ia_rows; r++) { | ||
68 | REG_WRITE(ah, INI_RA(array, r, 0), data[r]); | ||
69 | DO_DELAY(*writecnt); | ||
70 | } | ||
71 | |||
72 | REGWRITE_BUFFER_FLUSH(ah); | ||
73 | } | ||
74 | |||
47 | /** | 75 | /** |
48 | * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters | 76 | * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters |
49 | * @rfbuf: | 77 | * @rfbuf: |
@@ -530,16 +558,16 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, | |||
530 | eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); | 558 | eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); |
531 | 559 | ||
532 | /* Setup Bank 0 Write */ | 560 | /* Setup Bank 0 Write */ |
533 | RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1); | 561 | ar5008_rf_bank_setup(ah->analogBank0Data, &ah->iniBank0, 1); |
534 | 562 | ||
535 | /* Setup Bank 1 Write */ | 563 | /* Setup Bank 1 Write */ |
536 | RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1); | 564 | ar5008_rf_bank_setup(ah->analogBank1Data, &ah->iniBank1, 1); |
537 | 565 | ||
538 | /* Setup Bank 2 Write */ | 566 | /* Setup Bank 2 Write */ |
539 | RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1); | 567 | ar5008_rf_bank_setup(ah->analogBank2Data, &ah->iniBank2, 1); |
540 | 568 | ||
541 | /* Setup Bank 6 Write */ | 569 | /* Setup Bank 6 Write */ |
542 | RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3, | 570 | ar5008_rf_bank_setup(ah->analogBank3Data, &ah->iniBank3, |
543 | modesIndex); | 571 | modesIndex); |
544 | { | 572 | { |
545 | int i; | 573 | int i; |
@@ -569,7 +597,7 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, | |||
569 | } | 597 | } |
570 | 598 | ||
571 | /* Setup Bank 7 Setup */ | 599 | /* Setup Bank 7 Setup */ |
572 | RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1); | 600 | ar5008_rf_bank_setup(ah->analogBank7Data, &ah->iniBank7, 1); |
573 | 601 | ||
574 | /* Write Analog registers */ | 602 | /* Write Analog registers */ |
575 | REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data, | 603 | REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data, |
@@ -729,6 +757,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, | |||
729 | struct ath9k_channel *chan) | 757 | struct ath9k_channel *chan) |
730 | { | 758 | { |
731 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | 759 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); |
760 | struct ath_common *common = ath9k_hw_common(ah); | ||
732 | int i, regWrites = 0; | 761 | int i, regWrites = 0; |
733 | struct ieee80211_channel *channel = chan->chan; | 762 | struct ieee80211_channel *channel = chan->chan; |
734 | u32 modesIndex, freqIndex; | 763 | u32 modesIndex, freqIndex; |
@@ -805,7 +834,8 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, | |||
805 | REG_WRITE(ah, reg, val); | 834 | REG_WRITE(ah, reg, val); |
806 | 835 | ||
807 | if (reg >= 0x7800 && reg < 0x78a0 | 836 | if (reg >= 0x7800 && reg < 0x78a0 |
808 | && ah->config.analog_shiftreg) { | 837 | && ah->config.analog_shiftreg |
838 | && (common->bus_ops->ath_bus_type != ATH_USB)) { | ||
809 | udelay(100); | 839 | udelay(100); |
810 | } | 840 | } |
811 | 841 | ||
@@ -835,7 +865,8 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, | |||
835 | REG_WRITE(ah, reg, val); | 865 | REG_WRITE(ah, reg, val); |
836 | 866 | ||
837 | if (reg >= 0x7800 && reg < 0x78a0 | 867 | if (reg >= 0x7800 && reg < 0x78a0 |
838 | && ah->config.analog_shiftreg) { | 868 | && ah->config.analog_shiftreg |
869 | && (common->bus_ops->ath_bus_type != ATH_USB)) { | ||
839 | udelay(100); | 870 | udelay(100); |
840 | } | 871 | } |
841 | 872 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 76388c6d669..cb611b287b3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c | |||
@@ -26,6 +26,27 @@ enum ar9002_cal_types { | |||
26 | IQ_MISMATCH_CAL = BIT(2), | 26 | IQ_MISMATCH_CAL = BIT(2), |
27 | }; | 27 | }; |
28 | 28 | ||
29 | static bool ar9002_hw_is_cal_supported(struct ath_hw *ah, | ||
30 | struct ath9k_channel *chan, | ||
31 | enum ar9002_cal_types cal_type) | ||
32 | { | ||
33 | bool supported = false; | ||
34 | switch (ah->supp_cals & cal_type) { | ||
35 | case IQ_MISMATCH_CAL: | ||
36 | /* Run IQ Mismatch for non-CCK only */ | ||
37 | if (!IS_CHAN_B(chan)) | ||
38 | supported = true; | ||
39 | break; | ||
40 | case ADC_GAIN_CAL: | ||
41 | case ADC_DC_CAL: | ||
42 | /* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */ | ||
43 | if (!IS_CHAN_B(chan) && | ||
44 | !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) | ||
45 | supported = true; | ||
46 | break; | ||
47 | } | ||
48 | return supported; | ||
49 | } | ||
29 | 50 | ||
30 | static void ar9002_hw_setup_calibration(struct ath_hw *ah, | 51 | static void ar9002_hw_setup_calibration(struct ath_hw *ah, |
31 | struct ath9k_cal_list *currCal) | 52 | struct ath9k_cal_list *currCal) |
@@ -858,26 +879,32 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) | |||
858 | if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { | 879 | if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { |
859 | ah->supp_cals = IQ_MISMATCH_CAL; | 880 | ah->supp_cals = IQ_MISMATCH_CAL; |
860 | 881 | ||
861 | if (AR_SREV_9160_10_OR_LATER(ah) && | 882 | if (AR_SREV_9160_10_OR_LATER(ah)) |
862 | !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) { | ||
863 | ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL; | 883 | ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL; |
864 | 884 | ||
885 | if (AR_SREV_9287(ah)) | ||
886 | ah->supp_cals &= ~ADC_GAIN_CAL; | ||
865 | 887 | ||
888 | if (ar9002_hw_is_cal_supported(ah, chan, ADC_GAIN_CAL)) { | ||
866 | INIT_CAL(&ah->adcgain_caldata); | 889 | INIT_CAL(&ah->adcgain_caldata); |
867 | INSERT_CAL(ah, &ah->adcgain_caldata); | 890 | INSERT_CAL(ah, &ah->adcgain_caldata); |
868 | ath_dbg(common, ATH_DBG_CALIBRATE, | 891 | ath_dbg(common, ATH_DBG_CALIBRATE, |
869 | "enabling ADC Gain Calibration.\n"); | 892 | "enabling ADC Gain Calibration.\n"); |
893 | } | ||
870 | 894 | ||
895 | if (ar9002_hw_is_cal_supported(ah, chan, ADC_DC_CAL)) { | ||
871 | INIT_CAL(&ah->adcdc_caldata); | 896 | INIT_CAL(&ah->adcdc_caldata); |
872 | INSERT_CAL(ah, &ah->adcdc_caldata); | 897 | INSERT_CAL(ah, &ah->adcdc_caldata); |
873 | ath_dbg(common, ATH_DBG_CALIBRATE, | 898 | ath_dbg(common, ATH_DBG_CALIBRATE, |
874 | "enabling ADC DC Calibration.\n"); | 899 | "enabling ADC DC Calibration.\n"); |
875 | } | 900 | } |
876 | 901 | ||
877 | INIT_CAL(&ah->iq_caldata); | 902 | if (ar9002_hw_is_cal_supported(ah, chan, IQ_MISMATCH_CAL)) { |
878 | INSERT_CAL(ah, &ah->iq_caldata); | 903 | INIT_CAL(&ah->iq_caldata); |
879 | ath_dbg(common, ATH_DBG_CALIBRATE, | 904 | INSERT_CAL(ah, &ah->iq_caldata); |
880 | "enabling IQ Calibration.\n"); | 905 | ath_dbg(common, ATH_DBG_CALIBRATE, |
906 | "enabling IQ Calibration.\n"); | ||
907 | } | ||
881 | 908 | ||
882 | ah->cal_list_curr = ah->cal_list; | 909 | ah->cal_list_curr = ah->cal_list; |
883 | 910 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 399ab3bb299..7a332f16b79 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c | |||
@@ -290,7 +290,6 @@ static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds, | |||
290 | | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) | 290 | | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) |
291 | | SM(txPower, AR_XmitPower) | 291 | | SM(txPower, AR_XmitPower) |
292 | | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) | 292 | | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) |
293 | | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) | ||
294 | | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) | 293 | | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) |
295 | | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0); | 294 | | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0); |
296 | 295 | ||
@@ -311,6 +310,16 @@ static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds, | |||
311 | } | 310 | } |
312 | } | 311 | } |
313 | 312 | ||
313 | static void ar9002_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) | ||
314 | { | ||
315 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
316 | |||
317 | if (val) | ||
318 | ads->ds_ctl0 |= AR_ClrDestMask; | ||
319 | else | ||
320 | ads->ds_ctl0 &= ~AR_ClrDestMask; | ||
321 | } | ||
322 | |||
314 | static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, | 323 | static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, |
315 | void *lastds, | 324 | void *lastds, |
316 | u32 durUpdateEn, u32 rtsctsRate, | 325 | u32 durUpdateEn, u32 rtsctsRate, |
@@ -406,26 +415,6 @@ static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *ds) | |||
406 | ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr); | 415 | ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr); |
407 | } | 416 | } |
408 | 417 | ||
409 | static void ar9002_hw_set11n_burstduration(struct ath_hw *ah, void *ds, | ||
410 | u32 burstDuration) | ||
411 | { | ||
412 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
413 | |||
414 | ads->ds_ctl2 &= ~AR_BurstDur; | ||
415 | ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur); | ||
416 | } | ||
417 | |||
418 | static void ar9002_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, | ||
419 | u32 vmf) | ||
420 | { | ||
421 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
422 | |||
423 | if (vmf) | ||
424 | ads->ds_ctl0 |= AR_VirtMoreFrag; | ||
425 | else | ||
426 | ads->ds_ctl0 &= ~AR_VirtMoreFrag; | ||
427 | } | ||
428 | |||
429 | void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, | 418 | void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, |
430 | u32 size, u32 flags) | 419 | u32 size, u32 flags) |
431 | { | 420 | { |
@@ -458,6 +447,5 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah) | |||
458 | ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle; | 447 | ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle; |
459 | ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last; | 448 | ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last; |
460 | ops->clr11n_aggr = ar9002_hw_clr11n_aggr; | 449 | ops->clr11n_aggr = ar9002_hw_clr11n_aggr; |
461 | ops->set11n_burstduration = ar9002_hw_set11n_burstduration; | 450 | ops->set_clrdmask = ar9002_hw_set_clrdmask; |
462 | ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag; | ||
463 | } | 451 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index 7d68d61e406..a57e963cf0d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c | |||
@@ -517,23 +517,7 @@ static void ar9002_hw_set_nf_limits(struct ath_hw *ah) | |||
517 | } | 517 | } |
518 | } | 518 | } |
519 | 519 | ||
520 | void ar9002_hw_attach_phy_ops(struct ath_hw *ah) | 520 | static void ar9002_hw_antdiv_comb_conf_get(struct ath_hw *ah, |
521 | { | ||
522 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | ||
523 | |||
524 | priv_ops->set_rf_regs = NULL; | ||
525 | priv_ops->rf_alloc_ext_banks = NULL; | ||
526 | priv_ops->rf_free_ext_banks = NULL; | ||
527 | priv_ops->rf_set_freq = ar9002_hw_set_channel; | ||
528 | priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate; | ||
529 | priv_ops->olc_init = ar9002_olc_init; | ||
530 | priv_ops->compute_pll_control = ar9002_hw_compute_pll_control; | ||
531 | priv_ops->do_getnf = ar9002_hw_do_getnf; | ||
532 | |||
533 | ar9002_hw_set_nf_limits(ah); | ||
534 | } | ||
535 | |||
536 | void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, | ||
537 | struct ath_hw_antcomb_conf *antconf) | 521 | struct ath_hw_antcomb_conf *antconf) |
538 | { | 522 | { |
539 | u32 regval; | 523 | u32 regval; |
@@ -545,10 +529,11 @@ void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, | |||
545 | AR_PHY_9285_ANT_DIV_ALT_LNACONF_S; | 529 | AR_PHY_9285_ANT_DIV_ALT_LNACONF_S; |
546 | antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >> | 530 | antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >> |
547 | AR_PHY_9285_FAST_DIV_BIAS_S; | 531 | AR_PHY_9285_FAST_DIV_BIAS_S; |
532 | antconf->lna1_lna2_delta = -3; | ||
533 | antconf->div_group = 0; | ||
548 | } | 534 | } |
549 | EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_get); | ||
550 | 535 | ||
551 | void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah, | 536 | static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah, |
552 | struct ath_hw_antcomb_conf *antconf) | 537 | struct ath_hw_antcomb_conf *antconf) |
553 | { | 538 | { |
554 | u32 regval; | 539 | u32 regval; |
@@ -566,4 +551,23 @@ void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah, | |||
566 | 551 | ||
567 | REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval); | 552 | REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval); |
568 | } | 553 | } |
569 | EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_set); | 554 | |
555 | void ar9002_hw_attach_phy_ops(struct ath_hw *ah) | ||
556 | { | ||
557 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | ||
558 | struct ath_hw_ops *ops = ath9k_hw_ops(ah); | ||
559 | |||
560 | priv_ops->set_rf_regs = NULL; | ||
561 | priv_ops->rf_alloc_ext_banks = NULL; | ||
562 | priv_ops->rf_free_ext_banks = NULL; | ||
563 | priv_ops->rf_set_freq = ar9002_hw_set_channel; | ||
564 | priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate; | ||
565 | priv_ops->olc_init = ar9002_olc_init; | ||
566 | priv_ops->compute_pll_control = ar9002_hw_compute_pll_control; | ||
567 | priv_ops->do_getnf = ar9002_hw_do_getnf; | ||
568 | |||
569 | ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get; | ||
570 | ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set; | ||
571 | |||
572 | ar9002_hw_set_nf_limits(ah); | ||
573 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index 37663dbbcf5..47780ef1c89 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h | |||
@@ -483,7 +483,11 @@ | |||
483 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000 | 483 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000 |
484 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 | 484 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 |
485 | 485 | ||
486 | #define AR_PHY_TX_PWRCTRL8 0xa278 | ||
487 | |||
486 | #define AR_PHY_TX_PWRCTRL9 0xa27C | 488 | #define AR_PHY_TX_PWRCTRL9 0xa27C |
489 | |||
490 | #define AR_PHY_TX_PWRCTRL10 0xa394 | ||
487 | #define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00 | 491 | #define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00 |
488 | #define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 | 492 | #define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 |
489 | #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 | 493 | #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 |
@@ -495,6 +499,8 @@ | |||
495 | 499 | ||
496 | #define AR_PHY_CH0_TX_PWRCTRL11 0xa398 | 500 | #define AR_PHY_CH0_TX_PWRCTRL11 0xa398 |
497 | #define AR_PHY_CH1_TX_PWRCTRL11 0xb398 | 501 | #define AR_PHY_CH1_TX_PWRCTRL11 0xb398 |
502 | #define AR_PHY_CH0_TX_PWRCTRL12 0xa3dc | ||
503 | #define AR_PHY_CH0_TX_PWRCTRL13 0xa3e0 | ||
498 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00 | 504 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00 |
499 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10 | 505 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10 |
500 | 506 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 9ecca93392e..f915a3dbfca 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | |||
@@ -34,10 +34,10 @@ static const u32 ar9300_2p2_radio_postamble[][5] = { | |||
34 | 34 | ||
35 | static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { | 35 | static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { |
36 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 36 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
37 | {0x0000a2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, | 37 | {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
38 | {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, | 38 | {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
39 | {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, | 39 | {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
40 | {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 40 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
41 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | 41 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, |
42 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 42 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
43 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | 43 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, |
@@ -119,14 +119,14 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { | |||
119 | {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, | 119 | {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
120 | {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, | 120 | {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
121 | {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, | 121 | {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
122 | {0x0000b2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, | 122 | {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
123 | {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, | 123 | {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
124 | {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, | 124 | {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
125 | {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 125 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
126 | {0x0000c2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, | 126 | {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
127 | {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, | 127 | {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
128 | {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, | 128 | {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
129 | {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 129 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
130 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | 130 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, |
131 | {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, | 131 | {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, |
132 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 132 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
@@ -835,10 +835,10 @@ static const u32 ar9300_2p2_baseband_core[][2] = { | |||
835 | 835 | ||
836 | static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { | 836 | static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { |
837 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 837 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
838 | {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 838 | {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, |
839 | {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 839 | {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, |
840 | {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 840 | {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, |
841 | {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 841 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
842 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, | 842 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, |
843 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | 843 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, |
844 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, | 844 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, |
@@ -920,14 +920,14 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { | |||
920 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 920 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
921 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 921 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
922 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 922 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
923 | {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 923 | {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, |
924 | {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 924 | {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, |
925 | {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 925 | {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, |
926 | {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 926 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
927 | {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 927 | {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, |
928 | {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 928 | {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, |
929 | {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 929 | {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, |
930 | {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 930 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
931 | {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, | 931 | {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, |
932 | {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, | 932 | {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, |
933 | {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, | 933 | {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, |
@@ -941,10 +941,10 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { | |||
941 | 941 | ||
942 | static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { | 942 | static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { |
943 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 943 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
944 | {0x0000a2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, | 944 | {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, |
945 | {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, | 945 | {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, |
946 | {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, | 946 | {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, |
947 | {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 947 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
948 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, | 948 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, |
949 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | 949 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, |
950 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, | 950 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, |
@@ -1026,14 +1026,14 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { | |||
1026 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 1026 | {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
1027 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 1027 | {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
1028 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, | 1028 | {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, |
1029 | {0x0000b2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, | 1029 | {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, |
1030 | {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, | 1030 | {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, |
1031 | {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, | 1031 | {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, |
1032 | {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1032 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1033 | {0x0000c2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, | 1033 | {0x0000c2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, |
1034 | {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, | 1034 | {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, |
1035 | {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, | 1035 | {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, |
1036 | {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1036 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1037 | {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, | 1037 | {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, |
1038 | {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, | 1038 | {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, |
1039 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 1039 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
@@ -1307,10 +1307,10 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = { | |||
1307 | 1307 | ||
1308 | static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { | 1308 | static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { |
1309 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 1309 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
1310 | {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 1310 | {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
1311 | {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 1311 | {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
1312 | {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 1312 | {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
1313 | {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1313 | {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1314 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | 1314 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, |
1315 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1315 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1316 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | 1316 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, |
@@ -1329,21 +1329,21 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { | |||
1329 | {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, | 1329 | {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, |
1330 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, | 1330 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, |
1331 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, | 1331 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, |
1332 | {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, | 1332 | {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861}, |
1333 | {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, | 1333 | {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81}, |
1334 | {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83}, | 1334 | {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83}, |
1335 | {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84}, | 1335 | {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84}, |
1336 | {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3}, | 1336 | {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3}, |
1337 | {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5}, | 1337 | {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5}, |
1338 | {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9}, | 1338 | {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9}, |
1339 | {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb}, | 1339 | {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb}, |
1340 | {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1340 | {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1341 | {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1341 | {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1342 | {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1342 | {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1343 | {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1343 | {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1344 | {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1344 | {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1345 | {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1345 | {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1346 | {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, | 1346 | {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, |
1347 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | 1347 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, |
1348 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, | 1348 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, |
1349 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, | 1349 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, |
@@ -1361,45 +1361,45 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { | |||
1361 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, | 1361 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, |
1362 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, | 1362 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, |
1363 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, | 1363 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, |
1364 | {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, | 1364 | {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861}, |
1365 | {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, | 1365 | {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81}, |
1366 | {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83}, | 1366 | {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83}, |
1367 | {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84}, | 1367 | {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84}, |
1368 | {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3}, | 1368 | {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3}, |
1369 | {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5}, | 1369 | {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5}, |
1370 | {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9}, | 1370 | {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9}, |
1371 | {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb}, | 1371 | {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb}, |
1372 | {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1372 | {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1373 | {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1373 | {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1374 | {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1374 | {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1375 | {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1375 | {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1376 | {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1376 | {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1377 | {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1377 | {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1378 | {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, | 1378 | {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, |
1379 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1379 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1380 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1380 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1381 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1381 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1382 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1382 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1383 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1383 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1384 | {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, | 1384 | {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000}, |
1385 | {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, | 1385 | {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501}, |
1386 | {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, | 1386 | {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501}, |
1387 | {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, | 1387 | {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03}, |
1388 | {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, | 1388 | {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04}, |
1389 | {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, | 1389 | {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04}, |
1390 | {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, | 1390 | {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1391 | {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | 1391 | {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1392 | {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | 1392 | {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1393 | {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | 1393 | {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1394 | {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, | 1394 | {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, |
1395 | {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 1395 | {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
1396 | {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 1396 | {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
1397 | {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 1397 | {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
1398 | {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1398 | {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1399 | {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, | 1399 | {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, |
1400 | {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, | 1400 | {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, |
1401 | {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, | 1401 | {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, |
1402 | {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1402 | {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, |
1403 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | 1403 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, |
1404 | {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, | 1404 | {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, |
1405 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 1405 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 4a4cd88429c..f276cb922b4 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -18,13 +18,13 @@ | |||
18 | #include "hw-ops.h" | 18 | #include "hw-ops.h" |
19 | #include "ar9003_phy.h" | 19 | #include "ar9003_phy.h" |
20 | 20 | ||
21 | #define MPASS 3 | ||
22 | #define MAX_MEASUREMENT 8 | 21 | #define MAX_MEASUREMENT 8 |
23 | #define MAX_DIFFERENCE 10 | 22 | #define MAX_MAG_DELTA 11 |
23 | #define MAX_PHS_DELTA 10 | ||
24 | 24 | ||
25 | struct coeff { | 25 | struct coeff { |
26 | int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS]; | 26 | int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT]; |
27 | int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS]; | 27 | int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT]; |
28 | int iqc_coeff[2]; | 28 | int iqc_coeff[2]; |
29 | }; | 29 | }; |
30 | 30 | ||
@@ -185,17 +185,19 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah) | |||
185 | 185 | ||
186 | /* Accumulate IQ cal measures for active chains */ | 186 | /* Accumulate IQ cal measures for active chains */ |
187 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | 187 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { |
188 | ah->totalPowerMeasI[i] += | 188 | if (ah->txchainmask & BIT(i)) { |
189 | REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | 189 | ah->totalPowerMeasI[i] += |
190 | ah->totalPowerMeasQ[i] += | 190 | REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); |
191 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | 191 | ah->totalPowerMeasQ[i] += |
192 | ah->totalIqCorrMeas[i] += | 192 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); |
193 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | 193 | ah->totalIqCorrMeas[i] += |
194 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | 194 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); |
195 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", | 195 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, |
196 | ah->cal_samples, i, ah->totalPowerMeasI[i], | 196 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", |
197 | ah->totalPowerMeasQ[i], | 197 | ah->cal_samples, i, ah->totalPowerMeasI[i], |
198 | ah->totalIqCorrMeas[i]); | 198 | ah->totalPowerMeasQ[i], |
199 | ah->totalIqCorrMeas[i]); | ||
200 | } | ||
199 | } | 201 | } |
200 | } | 202 | } |
201 | 203 | ||
@@ -608,36 +610,48 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
608 | return true; | 610 | return true; |
609 | } | 611 | } |
610 | 612 | ||
611 | static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg) | 613 | static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, |
614 | int max_delta) | ||
612 | { | 615 | { |
613 | int diff[MPASS]; | 616 | int mp_max = -64, max_idx = 0; |
614 | 617 | int mp_min = 63, min_idx = 0; | |
615 | diff[0] = abs(mp_coeff[0] - mp_coeff[1]); | 618 | int mp_avg = 0, i, outlier_idx = 0; |
616 | diff[1] = abs(mp_coeff[1] - mp_coeff[2]); | 619 | |
617 | diff[2] = abs(mp_coeff[2] - mp_coeff[0]); | 620 | /* find min/max mismatch across all calibrated gains */ |
618 | 621 | for (i = 0; i < nmeasurement; i++) { | |
619 | if (diff[0] > MAX_DIFFERENCE && | 622 | mp_avg += mp_coeff[i]; |
620 | diff[1] > MAX_DIFFERENCE && | 623 | if (mp_coeff[i] > mp_max) { |
621 | diff[2] > MAX_DIFFERENCE) | 624 | mp_max = mp_coeff[i]; |
622 | return false; | 625 | max_idx = i; |
626 | } else if (mp_coeff[i] < mp_min) { | ||
627 | mp_min = mp_coeff[i]; | ||
628 | min_idx = i; | ||
629 | } | ||
630 | } | ||
623 | 631 | ||
624 | if (diff[0] <= diff[1] && diff[0] <= diff[2]) | 632 | /* find average (exclude max abs value) */ |
625 | *mp_avg = (mp_coeff[0] + mp_coeff[1]) / 2; | 633 | for (i = 0; i < nmeasurement; i++) { |
626 | else if (diff[1] <= diff[2]) | 634 | if ((abs(mp_coeff[i]) < abs(mp_max)) || |
627 | *mp_avg = (mp_coeff[1] + mp_coeff[2]) / 2; | 635 | (abs(mp_coeff[i]) < abs(mp_min))) |
628 | else | 636 | mp_avg += mp_coeff[i]; |
629 | *mp_avg = (mp_coeff[2] + mp_coeff[0]) / 2; | 637 | } |
638 | mp_avg /= (nmeasurement - 1); | ||
630 | 639 | ||
631 | return true; | 640 | /* detect outlier */ |
641 | if (abs(mp_max - mp_min) > max_delta) { | ||
642 | if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg)) | ||
643 | outlier_idx = max_idx; | ||
644 | else | ||
645 | outlier_idx = min_idx; | ||
646 | } | ||
647 | mp_coeff[outlier_idx] = mp_avg; | ||
632 | } | 648 | } |
633 | 649 | ||
634 | static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | 650 | static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, |
635 | u8 num_chains, | 651 | u8 num_chains, |
636 | struct coeff *coeff) | 652 | struct coeff *coeff) |
637 | { | 653 | { |
638 | struct ath_common *common = ath9k_hw_common(ah); | ||
639 | int i, im, nmeasurement; | 654 | int i, im, nmeasurement; |
640 | int magnitude, phase; | ||
641 | u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; | 655 | u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; |
642 | 656 | ||
643 | memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff)); | 657 | memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff)); |
@@ -657,37 +671,28 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | |||
657 | 671 | ||
658 | /* Load the average of 2 passes */ | 672 | /* Load the average of 2 passes */ |
659 | for (i = 0; i < num_chains; i++) { | 673 | for (i = 0; i < num_chains; i++) { |
660 | if (AR_SREV_9485(ah)) | 674 | nmeasurement = REG_READ_FIELD(ah, |
661 | nmeasurement = REG_READ_FIELD(ah, | 675 | AR_PHY_TX_IQCAL_STATUS_B0, |
662 | AR_PHY_TX_IQCAL_STATUS_B0_9485, | 676 | AR_PHY_CALIBRATED_GAINS_0); |
663 | AR_PHY_CALIBRATED_GAINS_0); | ||
664 | else | ||
665 | nmeasurement = REG_READ_FIELD(ah, | ||
666 | AR_PHY_TX_IQCAL_STATUS_B0, | ||
667 | AR_PHY_CALIBRATED_GAINS_0); | ||
668 | 677 | ||
669 | if (nmeasurement > MAX_MEASUREMENT) | 678 | if (nmeasurement > MAX_MEASUREMENT) |
670 | nmeasurement = MAX_MEASUREMENT; | 679 | nmeasurement = MAX_MEASUREMENT; |
671 | 680 | ||
672 | for (im = 0; im < nmeasurement; im++) { | 681 | /* detect outlier only if nmeasurement > 1 */ |
673 | /* | 682 | if (nmeasurement > 1) { |
674 | * Determine which 2 passes are closest and compute avg | 683 | /* Detect magnitude outlier */ |
675 | * magnitude | 684 | ar9003_hw_detect_outlier(coeff->mag_coeff[i], |
676 | */ | 685 | nmeasurement, MAX_MAG_DELTA); |
677 | if (!ar9003_hw_compute_closest_pass_and_avg(coeff->mag_coeff[i][im], | ||
678 | &magnitude)) | ||
679 | goto disable_txiqcal; | ||
680 | 686 | ||
681 | /* | 687 | /* Detect phase outlier */ |
682 | * Determine which 2 passes are closest and compute avg | 688 | ar9003_hw_detect_outlier(coeff->phs_coeff[i], |
683 | * phase | 689 | nmeasurement, MAX_PHS_DELTA); |
684 | */ | 690 | } |
685 | if (!ar9003_hw_compute_closest_pass_and_avg(coeff->phs_coeff[i][im], | 691 | |
686 | &phase)) | 692 | for (im = 0; im < nmeasurement; im++) { |
687 | goto disable_txiqcal; | ||
688 | 693 | ||
689 | coeff->iqc_coeff[0] = (magnitude & 0x7f) | | 694 | coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) | |
690 | ((phase & 0x7f) << 7); | 695 | ((coeff->phs_coeff[i][im] & 0x7f) << 7); |
691 | 696 | ||
692 | if ((im % 2) == 0) | 697 | if ((im % 2) == 0) |
693 | REG_RMW_FIELD(ah, tx_corr_coeff[im][i], | 698 | REG_RMW_FIELD(ah, tx_corr_coeff[im][i], |
@@ -707,141 +712,37 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | |||
707 | 712 | ||
708 | return; | 713 | return; |
709 | 714 | ||
710 | disable_txiqcal: | ||
711 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, | ||
712 | AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x0); | ||
713 | REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, | ||
714 | AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x0); | ||
715 | |||
716 | ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n"); | ||
717 | } | 715 | } |
718 | 716 | ||
719 | static void ar9003_hw_tx_iq_cal(struct ath_hw *ah) | 717 | static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah) |
720 | { | 718 | { |
721 | struct ath_common *common = ath9k_hw_common(ah); | 719 | struct ath_common *common = ath9k_hw_common(ah); |
722 | static const u32 txiqcal_status[AR9300_MAX_CHAINS] = { | ||
723 | AR_PHY_TX_IQCAL_STATUS_B0, | ||
724 | AR_PHY_TX_IQCAL_STATUS_B1, | ||
725 | AR_PHY_TX_IQCAL_STATUS_B2, | ||
726 | }; | ||
727 | static const u32 chan_info_tab[] = { | ||
728 | AR_PHY_CHAN_INFO_TAB_0, | ||
729 | AR_PHY_CHAN_INFO_TAB_1, | ||
730 | AR_PHY_CHAN_INFO_TAB_2, | ||
731 | }; | ||
732 | struct coeff coeff; | ||
733 | s32 iq_res[6]; | ||
734 | s32 i, j, ip, im, nmeasurement; | ||
735 | u8 nchains = get_streams(common->tx_chainmask); | ||
736 | |||
737 | for (ip = 0; ip < MPASS; ip++) { | ||
738 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, | ||
739 | AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, | ||
740 | DELPT); | ||
741 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START, | ||
742 | AR_PHY_TX_IQCAL_START_DO_CAL, | ||
743 | AR_PHY_TX_IQCAL_START_DO_CAL); | ||
744 | |||
745 | if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START, | ||
746 | AR_PHY_TX_IQCAL_START_DO_CAL, | ||
747 | 0, AH_WAIT_TIMEOUT)) { | ||
748 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
749 | "Tx IQ Cal not complete.\n"); | ||
750 | goto TX_IQ_CAL_FAILED; | ||
751 | } | ||
752 | |||
753 | nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0, | ||
754 | AR_PHY_CALIBRATED_GAINS_0); | ||
755 | if (nmeasurement > MAX_MEASUREMENT) | ||
756 | nmeasurement = MAX_MEASUREMENT; | ||
757 | |||
758 | for (i = 0; i < nchains; i++) { | ||
759 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
760 | "Doing Tx IQ Cal for chain %d.\n", i); | ||
761 | for (im = 0; im < nmeasurement; im++) { | ||
762 | if (REG_READ(ah, txiqcal_status[i]) & | ||
763 | AR_PHY_TX_IQCAL_STATUS_FAILED) { | ||
764 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
765 | "Tx IQ Cal failed for chain %d.\n", i); | ||
766 | goto TX_IQ_CAL_FAILED; | ||
767 | } | ||
768 | |||
769 | for (j = 0; j < 3; j++) { | ||
770 | u8 idx = 2 * j, | ||
771 | offset = 4 * (3 * im + j); | ||
772 | |||
773 | REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, | ||
774 | AR_PHY_CHAN_INFO_TAB_S2_READ, | ||
775 | 0); | ||
776 | |||
777 | /* 32 bits */ | ||
778 | iq_res[idx] = REG_READ(ah, | ||
779 | chan_info_tab[i] + | ||
780 | offset); | ||
781 | |||
782 | REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, | ||
783 | AR_PHY_CHAN_INFO_TAB_S2_READ, | ||
784 | 1); | ||
785 | |||
786 | /* 16 bits */ | ||
787 | iq_res[idx+1] = 0xffff & REG_READ(ah, | ||
788 | chan_info_tab[i] + | ||
789 | offset); | ||
790 | |||
791 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
792 | "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n", | ||
793 | idx, iq_res[idx], idx+1, iq_res[idx+1]); | ||
794 | } | ||
795 | |||
796 | if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, | ||
797 | coeff.iqc_coeff)) { | ||
798 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
799 | "Failed in calculation of IQ correction.\n"); | ||
800 | goto TX_IQ_CAL_FAILED; | ||
801 | } | ||
802 | coeff.mag_coeff[i][im][ip] = | ||
803 | coeff.iqc_coeff[0] & 0x7f; | ||
804 | coeff.phs_coeff[i][im][ip] = | ||
805 | (coeff.iqc_coeff[0] >> 7) & 0x7f; | ||
806 | |||
807 | if (coeff.mag_coeff[i][im][ip] > 63) | ||
808 | coeff.mag_coeff[i][im][ip] -= 128; | ||
809 | if (coeff.phs_coeff[i][im][ip] > 63) | ||
810 | coeff.phs_coeff[i][im][ip] -= 128; | ||
811 | |||
812 | } | ||
813 | } | ||
814 | } | ||
815 | |||
816 | ar9003_hw_tx_iqcal_load_avg_2_passes(ah, nchains, &coeff); | ||
817 | |||
818 | return; | ||
819 | |||
820 | TX_IQ_CAL_FAILED: | ||
821 | ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n"); | ||
822 | } | ||
823 | |||
824 | static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah) | ||
825 | { | ||
826 | u8 tx_gain_forced; | 720 | u8 tx_gain_forced; |
827 | 721 | ||
828 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1_9485, | ||
829 | AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT); | ||
830 | tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN, | 722 | tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN, |
831 | AR_PHY_TXGAIN_FORCE); | 723 | AR_PHY_TXGAIN_FORCE); |
832 | if (tx_gain_forced) | 724 | if (tx_gain_forced) |
833 | REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, | 725 | REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, |
834 | AR_PHY_TXGAIN_FORCE, 0); | 726 | AR_PHY_TXGAIN_FORCE, 0); |
835 | 727 | ||
836 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START_9485, | 728 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START, |
837 | AR_PHY_TX_IQCAL_START_DO_CAL_9485, 1); | 729 | AR_PHY_TX_IQCAL_START_DO_CAL, 1); |
730 | |||
731 | if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START, | ||
732 | AR_PHY_TX_IQCAL_START_DO_CAL, 0, | ||
733 | AH_WAIT_TIMEOUT)) { | ||
734 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
735 | "Tx IQ Cal is not completed.\n"); | ||
736 | return false; | ||
737 | } | ||
738 | return true; | ||
838 | } | 739 | } |
839 | 740 | ||
840 | static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) | 741 | static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) |
841 | { | 742 | { |
842 | struct ath_common *common = ath9k_hw_common(ah); | 743 | struct ath_common *common = ath9k_hw_common(ah); |
843 | const u32 txiqcal_status[AR9300_MAX_CHAINS] = { | 744 | const u32 txiqcal_status[AR9300_MAX_CHAINS] = { |
844 | AR_PHY_TX_IQCAL_STATUS_B0_9485, | 745 | AR_PHY_TX_IQCAL_STATUS_B0, |
845 | AR_PHY_TX_IQCAL_STATUS_B1, | 746 | AR_PHY_TX_IQCAL_STATUS_B1, |
846 | AR_PHY_TX_IQCAL_STATUS_B2, | 747 | AR_PHY_TX_IQCAL_STATUS_B2, |
847 | }; | 748 | }; |
@@ -853,7 +754,7 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) | |||
853 | struct coeff coeff; | 754 | struct coeff coeff; |
854 | s32 iq_res[6]; | 755 | s32 iq_res[6]; |
855 | u8 num_chains = 0; | 756 | u8 num_chains = 0; |
856 | int i, ip, im, j; | 757 | int i, im, j; |
857 | int nmeasurement; | 758 | int nmeasurement; |
858 | 759 | ||
859 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | 760 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { |
@@ -861,71 +762,69 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) | |||
861 | num_chains++; | 762 | num_chains++; |
862 | } | 763 | } |
863 | 764 | ||
864 | for (ip = 0; ip < MPASS; ip++) { | 765 | for (i = 0; i < num_chains; i++) { |
865 | for (i = 0; i < num_chains; i++) { | 766 | nmeasurement = REG_READ_FIELD(ah, |
866 | nmeasurement = REG_READ_FIELD(ah, | 767 | AR_PHY_TX_IQCAL_STATUS_B0, |
867 | AR_PHY_TX_IQCAL_STATUS_B0_9485, | 768 | AR_PHY_CALIBRATED_GAINS_0); |
868 | AR_PHY_CALIBRATED_GAINS_0); | 769 | if (nmeasurement > MAX_MEASUREMENT) |
869 | if (nmeasurement > MAX_MEASUREMENT) | 770 | nmeasurement = MAX_MEASUREMENT; |
870 | nmeasurement = MAX_MEASUREMENT; | ||
871 | 771 | ||
872 | for (im = 0; im < nmeasurement; im++) { | 772 | for (im = 0; im < nmeasurement; im++) { |
873 | ath_dbg(common, ATH_DBG_CALIBRATE, | 773 | ath_dbg(common, ATH_DBG_CALIBRATE, |
874 | "Doing Tx IQ Cal for chain %d.\n", i); | 774 | "Doing Tx IQ Cal for chain %d.\n", i); |
875 | 775 | ||
876 | if (REG_READ(ah, txiqcal_status[i]) & | 776 | if (REG_READ(ah, txiqcal_status[i]) & |
877 | AR_PHY_TX_IQCAL_STATUS_FAILED) { | 777 | AR_PHY_TX_IQCAL_STATUS_FAILED) { |
878 | ath_dbg(common, ATH_DBG_CALIBRATE, | 778 | ath_dbg(common, ATH_DBG_CALIBRATE, |
879 | "Tx IQ Cal failed for chain %d.\n", i); | 779 | "Tx IQ Cal failed for chain %d.\n", i); |
880 | goto tx_iqcal_fail; | 780 | goto tx_iqcal_fail; |
881 | } | 781 | } |
882 | 782 | ||
883 | for (j = 0; j < 3; j++) { | 783 | for (j = 0; j < 3; j++) { |
884 | u32 idx = 2 * j, offset = 4 * (3 * im + j); | 784 | u32 idx = 2 * j, offset = 4 * (3 * im + j); |
885 | 785 | ||
886 | REG_RMW_FIELD(ah, | 786 | REG_RMW_FIELD(ah, |
887 | AR_PHY_CHAN_INFO_MEMORY, | 787 | AR_PHY_CHAN_INFO_MEMORY, |
888 | AR_PHY_CHAN_INFO_TAB_S2_READ, | 788 | AR_PHY_CHAN_INFO_TAB_S2_READ, |
889 | 0); | 789 | 0); |
890 | 790 | ||
891 | /* 32 bits */ | 791 | /* 32 bits */ |
892 | iq_res[idx] = REG_READ(ah, | 792 | iq_res[idx] = REG_READ(ah, |
893 | chan_info_tab[i] + | 793 | chan_info_tab[i] + |
894 | offset); | 794 | offset); |
895 | 795 | ||
896 | REG_RMW_FIELD(ah, | 796 | REG_RMW_FIELD(ah, |
897 | AR_PHY_CHAN_INFO_MEMORY, | 797 | AR_PHY_CHAN_INFO_MEMORY, |
898 | AR_PHY_CHAN_INFO_TAB_S2_READ, | 798 | AR_PHY_CHAN_INFO_TAB_S2_READ, |
899 | 1); | 799 | 1); |
900 | 800 | ||
901 | /* 16 bits */ | 801 | /* 16 bits */ |
902 | iq_res[idx + 1] = 0xffff & REG_READ(ah, | 802 | iq_res[idx + 1] = 0xffff & REG_READ(ah, |
903 | chan_info_tab[i] + offset); | 803 | chan_info_tab[i] + offset); |
904 | 804 | ||
905 | ath_dbg(common, ATH_DBG_CALIBRATE, | 805 | ath_dbg(common, ATH_DBG_CALIBRATE, |
906 | "IQ RES[%d]=0x%x" | 806 | "IQ RES[%d]=0x%x" |
907 | "IQ_RES[%d]=0x%x\n", | 807 | "IQ_RES[%d]=0x%x\n", |
908 | idx, iq_res[idx], idx + 1, | 808 | idx, iq_res[idx], idx + 1, |
909 | iq_res[idx + 1]); | 809 | iq_res[idx + 1]); |
910 | } | 810 | } |
911 | 811 | ||
912 | if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, | 812 | if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, |
913 | coeff.iqc_coeff)) { | 813 | coeff.iqc_coeff)) { |
914 | ath_dbg(common, ATH_DBG_CALIBRATE, | 814 | ath_dbg(common, ATH_DBG_CALIBRATE, |
915 | "Failed in calculation of IQ correction.\n"); | 815 | "Failed in calculation of \ |
916 | goto tx_iqcal_fail; | 816 | IQ correction.\n"); |
917 | } | 817 | goto tx_iqcal_fail; |
818 | } | ||
918 | 819 | ||
919 | coeff.mag_coeff[i][im][ip] = | 820 | coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f; |
920 | coeff.iqc_coeff[0] & 0x7f; | 821 | coeff.phs_coeff[i][im] = |
921 | coeff.phs_coeff[i][im][ip] = | 822 | (coeff.iqc_coeff[0] >> 7) & 0x7f; |
922 | (coeff.iqc_coeff[0] >> 7) & 0x7f; | ||
923 | 823 | ||
924 | if (coeff.mag_coeff[i][im][ip] > 63) | 824 | if (coeff.mag_coeff[i][im] > 63) |
925 | coeff.mag_coeff[i][im][ip] -= 128; | 825 | coeff.mag_coeff[i][im] -= 128; |
926 | if (coeff.phs_coeff[i][im][ip] > 63) | 826 | if (coeff.phs_coeff[i][im] > 63) |
927 | coeff.phs_coeff[i][im][ip] -= 128; | 827 | coeff.phs_coeff[i][im] -= 128; |
928 | } | ||
929 | } | 828 | } |
930 | } | 829 | } |
931 | ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff); | 830 | ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff); |
@@ -940,31 +839,37 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
940 | struct ath9k_channel *chan) | 839 | struct ath9k_channel *chan) |
941 | { | 840 | { |
942 | struct ath_common *common = ath9k_hw_common(ah); | 841 | struct ath_common *common = ath9k_hw_common(ah); |
842 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
943 | int val; | 843 | int val; |
844 | bool txiqcal_done = false; | ||
944 | 845 | ||
945 | val = REG_READ(ah, AR_ENT_OTP); | 846 | val = REG_READ(ah, AR_ENT_OTP); |
946 | ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val); | 847 | ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val); |
947 | 848 | ||
948 | if (AR_SREV_9485(ah)) | 849 | /* Configure rx/tx chains before running AGC/TxiQ cals */ |
949 | ar9003_hw_set_chain_masks(ah, 0x1, 0x1); | 850 | if (val & AR_ENT_OTP_CHAIN2_DISABLE) |
950 | else if (val & AR_ENT_OTP_CHAIN2_DISABLE) | ||
951 | ar9003_hw_set_chain_masks(ah, 0x3, 0x3); | 851 | ar9003_hw_set_chain_masks(ah, 0x3, 0x3); |
952 | else | 852 | else |
953 | /* | 853 | ar9003_hw_set_chain_masks(ah, pCap->rx_chainmask, |
954 | * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain | 854 | pCap->tx_chainmask); |
955 | * mode before running AGC/TxIQ cals | ||
956 | */ | ||
957 | ar9003_hw_set_chain_masks(ah, 0x7, 0x7); | ||
958 | 855 | ||
959 | /* Do Tx IQ Calibration */ | 856 | /* Do Tx IQ Calibration */ |
960 | if (AR_SREV_9485(ah)) | 857 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, |
961 | ar9003_hw_tx_iq_cal_run(ah); | 858 | AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, |
962 | else | 859 | DELPT); |
963 | ar9003_hw_tx_iq_cal(ah); | ||
964 | 860 | ||
965 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); | 861 | /* |
966 | udelay(5); | 862 | * For AR9485 or later chips, TxIQ cal runs as part of |
967 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | 863 | * AGC calibration |
864 | */ | ||
865 | if (AR_SREV_9485_OR_LATER(ah)) | ||
866 | txiqcal_done = true; | ||
867 | else { | ||
868 | txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); | ||
869 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); | ||
870 | udelay(5); | ||
871 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | ||
872 | } | ||
968 | 873 | ||
969 | /* Calibrate the AGC */ | 874 | /* Calibrate the AGC */ |
970 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | 875 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, |
@@ -979,7 +884,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
979 | return false; | 884 | return false; |
980 | } | 885 | } |
981 | 886 | ||
982 | if (AR_SREV_9485(ah)) | 887 | if (txiqcal_done) |
983 | ar9003_hw_tx_iq_cal_post_proc(ah); | 888 | ar9003_hw_tx_iq_cal_post_proc(ah); |
984 | 889 | ||
985 | /* Revert chainmasks to their original values before NF cal */ | 890 | /* Revert chainmasks to their original values before NF cal */ |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 6eadf975ae4..d985841ff40 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -652,7 +652,7 @@ static const struct ar9300_eeprom ar9300_x113 = { | |||
652 | .regDmn = { LE16(0), LE16(0x1f) }, | 652 | .regDmn = { LE16(0), LE16(0x1f) }, |
653 | .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ | 653 | .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ |
654 | .opCapFlags = { | 654 | .opCapFlags = { |
655 | .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A, | 655 | .opFlags = AR5416_OPFLAGS_11A, |
656 | .eepMisc = 0, | 656 | .eepMisc = 0, |
657 | }, | 657 | }, |
658 | .rfSilent = 0, | 658 | .rfSilent = 0, |
@@ -922,7 +922,7 @@ static const struct ar9300_eeprom ar9300_x113 = { | |||
922 | .db_stage2 = {3, 3, 3}, /* 3 chain */ | 922 | .db_stage2 = {3, 3, 3}, /* 3 chain */ |
923 | .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ | 923 | .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ |
924 | .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ | 924 | .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ |
925 | .xpaBiasLvl = 0, | 925 | .xpaBiasLvl = 0xf, |
926 | .txFrameToDataStart = 0x0e, | 926 | .txFrameToDataStart = 0x0e, |
927 | .txFrameToPaOn = 0x0e, | 927 | .txFrameToPaOn = 0x0e, |
928 | .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ | 928 | .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ |
@@ -3217,7 +3217,6 @@ static int ar9300_compress_decision(struct ath_hw *ah, | |||
3217 | u8 *word, int length, int mdata_size) | 3217 | u8 *word, int length, int mdata_size) |
3218 | { | 3218 | { |
3219 | struct ath_common *common = ath9k_hw_common(ah); | 3219 | struct ath_common *common = ath9k_hw_common(ah); |
3220 | u8 *dptr; | ||
3221 | const struct ar9300_eeprom *eep = NULL; | 3220 | const struct ar9300_eeprom *eep = NULL; |
3222 | 3221 | ||
3223 | switch (code) { | 3222 | switch (code) { |
@@ -3235,7 +3234,6 @@ static int ar9300_compress_decision(struct ath_hw *ah, | |||
3235 | break; | 3234 | break; |
3236 | case _CompressBlock: | 3235 | case _CompressBlock: |
3237 | if (reference == 0) { | 3236 | if (reference == 0) { |
3238 | dptr = mptr; | ||
3239 | } else { | 3237 | } else { |
3240 | eep = ar9003_eeprom_struct_find_by_id(reference); | 3238 | eep = ar9003_eeprom_struct_find_by_id(reference); |
3241 | if (eep == NULL) { | 3239 | if (eep == NULL) { |
@@ -3329,26 +3327,26 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, | |||
3329 | else | 3327 | else |
3330 | cptr = AR9300_BASE_ADDR; | 3328 | cptr = AR9300_BASE_ADDR; |
3331 | ath_dbg(common, ATH_DBG_EEPROM, | 3329 | ath_dbg(common, ATH_DBG_EEPROM, |
3332 | "Trying EEPROM accesss at Address 0x%04x\n", cptr); | 3330 | "Trying EEPROM access at Address 0x%04x\n", cptr); |
3333 | if (ar9300_check_eeprom_header(ah, read, cptr)) | 3331 | if (ar9300_check_eeprom_header(ah, read, cptr)) |
3334 | goto found; | 3332 | goto found; |
3335 | 3333 | ||
3336 | cptr = AR9300_BASE_ADDR_512; | 3334 | cptr = AR9300_BASE_ADDR_512; |
3337 | ath_dbg(common, ATH_DBG_EEPROM, | 3335 | ath_dbg(common, ATH_DBG_EEPROM, |
3338 | "Trying EEPROM accesss at Address 0x%04x\n", cptr); | 3336 | "Trying EEPROM access at Address 0x%04x\n", cptr); |
3339 | if (ar9300_check_eeprom_header(ah, read, cptr)) | 3337 | if (ar9300_check_eeprom_header(ah, read, cptr)) |
3340 | goto found; | 3338 | goto found; |
3341 | 3339 | ||
3342 | read = ar9300_read_otp; | 3340 | read = ar9300_read_otp; |
3343 | cptr = AR9300_BASE_ADDR; | 3341 | cptr = AR9300_BASE_ADDR; |
3344 | ath_dbg(common, ATH_DBG_EEPROM, | 3342 | ath_dbg(common, ATH_DBG_EEPROM, |
3345 | "Trying OTP accesss at Address 0x%04x\n", cptr); | 3343 | "Trying OTP access at Address 0x%04x\n", cptr); |
3346 | if (ar9300_check_eeprom_header(ah, read, cptr)) | 3344 | if (ar9300_check_eeprom_header(ah, read, cptr)) |
3347 | goto found; | 3345 | goto found; |
3348 | 3346 | ||
3349 | cptr = AR9300_BASE_ADDR_512; | 3347 | cptr = AR9300_BASE_ADDR_512; |
3350 | ath_dbg(common, ATH_DBG_EEPROM, | 3348 | ath_dbg(common, ATH_DBG_EEPROM, |
3351 | "Trying OTP accesss at Address 0x%04x\n", cptr); | 3349 | "Trying OTP access at Address 0x%04x\n", cptr); |
3352 | if (ar9300_check_eeprom_header(ah, read, cptr)) | 3350 | if (ar9300_check_eeprom_header(ah, read, cptr)) |
3353 | goto found; | 3351 | goto found; |
3354 | 3352 | ||
@@ -3444,13 +3442,15 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) | |||
3444 | { | 3442 | { |
3445 | int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz); | 3443 | int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz); |
3446 | 3444 | ||
3447 | if (AR_SREV_9485(ah)) | 3445 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) |
3448 | REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); | 3446 | REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); |
3449 | else { | 3447 | else { |
3450 | REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); | 3448 | REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); |
3451 | REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB, | 3449 | REG_RMW_FIELD(ah, AR_CH0_THERM, |
3452 | bias >> 2); | 3450 | AR_CH0_THERM_XPABIASLVL_MSB, |
3453 | REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1); | 3451 | bias >> 2); |
3452 | REG_RMW_FIELD(ah, AR_CH0_THERM, | ||
3453 | AR_CH0_THERM_XPASHORT2GND, 1); | ||
3454 | } | 3454 | } |
3455 | } | 3455 | } |
3456 | 3456 | ||
@@ -3497,34 +3497,77 @@ static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, | |||
3497 | 3497 | ||
3498 | static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) | 3498 | static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) |
3499 | { | 3499 | { |
3500 | int chain; | ||
3501 | u32 regval; | ||
3502 | u32 ant_div_ctl1; | ||
3503 | static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = { | ||
3504 | AR_PHY_SWITCH_CHAIN_0, | ||
3505 | AR_PHY_SWITCH_CHAIN_1, | ||
3506 | AR_PHY_SWITCH_CHAIN_2, | ||
3507 | }; | ||
3508 | |||
3500 | u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz); | 3509 | u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz); |
3510 | |||
3501 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value); | 3511 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value); |
3502 | 3512 | ||
3503 | value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); | 3513 | value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); |
3504 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); | 3514 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); |
3505 | 3515 | ||
3506 | value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz); | 3516 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { |
3507 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value); | 3517 | if ((ah->rxchainmask & BIT(chain)) || |
3508 | 3518 | (ah->txchainmask & BIT(chain))) { | |
3509 | if (!AR_SREV_9485(ah)) { | 3519 | value = ar9003_hw_ant_ctrl_chain_get(ah, chain, |
3510 | value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz); | 3520 | is2ghz); |
3511 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, | 3521 | REG_RMW_FIELD(ah, switch_chain_reg[chain], |
3512 | value); | 3522 | AR_SWITCH_TABLE_ALL, value); |
3513 | 3523 | } | |
3514 | value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz); | ||
3515 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, | ||
3516 | value); | ||
3517 | } | 3524 | } |
3518 | 3525 | ||
3519 | if (AR_SREV_9485(ah)) { | 3526 | if (AR_SREV_9485(ah)) { |
3520 | value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1); | 3527 | value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1); |
3521 | REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_CTRL_ALL, | 3528 | /* |
3522 | value); | 3529 | * main_lnaconf, alt_lnaconf, main_tb, alt_tb |
3523 | REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_ENABLE, | 3530 | * are the fields present |
3524 | value >> 6); | 3531 | */ |
3525 | REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, AR_FAST_DIV_ENABLE, | 3532 | regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); |
3526 | value >> 7); | 3533 | regval &= (~AR_ANT_DIV_CTRL_ALL); |
3534 | regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S; | ||
3535 | /* enable_lnadiv */ | ||
3536 | regval &= (~AR_PHY_9485_ANT_DIV_LNADIV); | ||
3537 | regval |= ((value >> 6) & 0x1) << | ||
3538 | AR_PHY_9485_ANT_DIV_LNADIV_S; | ||
3539 | REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); | ||
3540 | |||
3541 | /*enable fast_div */ | ||
3542 | regval = REG_READ(ah, AR_PHY_CCK_DETECT); | ||
3543 | regval &= (~AR_FAST_DIV_ENABLE); | ||
3544 | regval |= ((value >> 7) & 0x1) << | ||
3545 | AR_FAST_DIV_ENABLE_S; | ||
3546 | REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); | ||
3547 | ant_div_ctl1 = | ||
3548 | ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); | ||
3549 | /* check whether antenna diversity is enabled */ | ||
3550 | if ((ant_div_ctl1 >> 0x6) == 0x3) { | ||
3551 | regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); | ||
3552 | /* | ||
3553 | * clear bits 25-30 main_lnaconf, alt_lnaconf, | ||
3554 | * main_tb, alt_tb | ||
3555 | */ | ||
3556 | regval &= (~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF | | ||
3557 | AR_PHY_9485_ANT_DIV_ALT_LNACONF | | ||
3558 | AR_PHY_9485_ANT_DIV_ALT_GAINTB | | ||
3559 | AR_PHY_9485_ANT_DIV_MAIN_GAINTB)); | ||
3560 | /* by default use LNA1 for the main antenna */ | ||
3561 | regval |= (AR_PHY_9485_ANT_DIV_LNA1 << | ||
3562 | AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S); | ||
3563 | regval |= (AR_PHY_9485_ANT_DIV_LNA2 << | ||
3564 | AR_PHY_9485_ANT_DIV_ALT_LNACONF_S); | ||
3565 | REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); | ||
3566 | } | ||
3567 | |||
3568 | |||
3527 | } | 3569 | } |
3570 | |||
3528 | } | 3571 | } |
3529 | 3572 | ||
3530 | static void ar9003_hw_drive_strength_apply(struct ath_hw *ah) | 3573 | static void ar9003_hw_drive_strength_apply(struct ath_hw *ah) |
@@ -3634,13 +3677,16 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan) | |||
3634 | 3677 | ||
3635 | /* Test value. if 0 then attenuation is unused. Don't load anything. */ | 3678 | /* Test value. if 0 then attenuation is unused. Don't load anything. */ |
3636 | for (i = 0; i < 3; i++) { | 3679 | for (i = 0; i < 3; i++) { |
3637 | value = ar9003_hw_atten_chain_get(ah, i, chan); | 3680 | if (ah->txchainmask & BIT(i)) { |
3638 | REG_RMW_FIELD(ah, ext_atten_reg[i], | 3681 | value = ar9003_hw_atten_chain_get(ah, i, chan); |
3639 | AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); | 3682 | REG_RMW_FIELD(ah, ext_atten_reg[i], |
3640 | 3683 | AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); | |
3641 | value = ar9003_hw_atten_chain_get_margin(ah, i, chan); | 3684 | |
3642 | REG_RMW_FIELD(ah, ext_atten_reg[i], | 3685 | value = ar9003_hw_atten_chain_get_margin(ah, i, chan); |
3643 | AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value); | 3686 | REG_RMW_FIELD(ah, ext_atten_reg[i], |
3687 | AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, | ||
3688 | value); | ||
3689 | } | ||
3644 | } | 3690 | } |
3645 | } | 3691 | } |
3646 | 3692 | ||
@@ -3749,8 +3795,9 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, | |||
3749 | ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); | 3795 | ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); |
3750 | ar9003_hw_drive_strength_apply(ah); | 3796 | ar9003_hw_drive_strength_apply(ah); |
3751 | ar9003_hw_atten_apply(ah, chan); | 3797 | ar9003_hw_atten_apply(ah, chan); |
3752 | ar9003_hw_internal_regulator_apply(ah); | 3798 | if (!AR_SREV_9340(ah)) |
3753 | if (AR_SREV_9485(ah)) | 3799 | ar9003_hw_internal_regulator_apply(ah); |
3800 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) | ||
3754 | ar9003_hw_apply_tuning_caps(ah); | 3801 | ar9003_hw_apply_tuning_caps(ah); |
3755 | } | 3802 | } |
3756 | 3803 | ||
@@ -3994,6 +4041,16 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) | |||
3994 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0) | 4041 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0) |
3995 | ); | 4042 | ); |
3996 | 4043 | ||
4044 | /* Write the power for duplicated frames - HT40 */ | ||
4045 | |||
4046 | /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */ | ||
4047 | REG_WRITE(ah, 0xa3e0, | ||
4048 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) | | ||
4049 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) | | ||
4050 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) | | ||
4051 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0) | ||
4052 | ); | ||
4053 | |||
3997 | /* Write the HT20 power per rate set */ | 4054 | /* Write the HT20 power per rate set */ |
3998 | 4055 | ||
3999 | /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */ | 4056 | /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */ |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 7f5de6e4448..a55eddbb258 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "ar9003_mac.h" | 18 | #include "ar9003_mac.h" |
19 | #include "ar9003_2p2_initvals.h" | 19 | #include "ar9003_2p2_initvals.h" |
20 | #include "ar9485_initvals.h" | 20 | #include "ar9485_initvals.h" |
21 | #include "ar9340_initvals.h" | ||
21 | 22 | ||
22 | /* General hardware code for the AR9003 hadware family */ | 23 | /* General hardware code for the AR9003 hadware family */ |
23 | 24 | ||
@@ -28,109 +29,105 @@ | |||
28 | */ | 29 | */ |
29 | static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | 30 | static void ar9003_hw_init_mode_regs(struct ath_hw *ah) |
30 | { | 31 | { |
31 | if (AR_SREV_9485_11(ah)) { | 32 | if (AR_SREV_9340(ah)) { |
32 | /* mac */ | 33 | /* mac */ |
33 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | 34 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); |
34 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 35 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
35 | ar9485_1_1_mac_core, | 36 | ar9340_1p0_mac_core, |
36 | ARRAY_SIZE(ar9485_1_1_mac_core), 2); | 37 | ARRAY_SIZE(ar9340_1p0_mac_core), 2); |
37 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | 38 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], |
38 | ar9485_1_1_mac_postamble, | 39 | ar9340_1p0_mac_postamble, |
39 | ARRAY_SIZE(ar9485_1_1_mac_postamble), 5); | 40 | ARRAY_SIZE(ar9340_1p0_mac_postamble), 5); |
40 | 41 | ||
41 | /* bb */ | 42 | /* bb */ |
42 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1, | 43 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); |
43 | ARRAY_SIZE(ar9485_1_1), 2); | ||
44 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | 44 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], |
45 | ar9485_1_1_baseband_core, | 45 | ar9340_1p0_baseband_core, |
46 | ARRAY_SIZE(ar9485_1_1_baseband_core), 2); | 46 | ARRAY_SIZE(ar9340_1p0_baseband_core), 2); |
47 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | 47 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], |
48 | ar9485_1_1_baseband_postamble, | 48 | ar9340_1p0_baseband_postamble, |
49 | ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5); | 49 | ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5); |
50 | 50 | ||
51 | /* radio */ | 51 | /* radio */ |
52 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | 52 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); |
53 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | 53 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], |
54 | ar9485_1_1_radio_core, | 54 | ar9340_1p0_radio_core, |
55 | ARRAY_SIZE(ar9485_1_1_radio_core), 2); | 55 | ARRAY_SIZE(ar9340_1p0_radio_core), 2); |
56 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | 56 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], |
57 | ar9485_1_1_radio_postamble, | 57 | ar9340_1p0_radio_postamble, |
58 | ARRAY_SIZE(ar9485_1_1_radio_postamble), 2); | 58 | ARRAY_SIZE(ar9340_1p0_radio_postamble), 5); |
59 | 59 | ||
60 | /* soc */ | 60 | /* soc */ |
61 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | 61 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], |
62 | ar9485_1_1_soc_preamble, | 62 | ar9340_1p0_soc_preamble, |
63 | ARRAY_SIZE(ar9485_1_1_soc_preamble), 2); | 63 | ARRAY_SIZE(ar9340_1p0_soc_preamble), 2); |
64 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | 64 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); |
65 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0); | 65 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], |
66 | ar9340_1p0_soc_postamble, | ||
67 | ARRAY_SIZE(ar9340_1p0_soc_postamble), 5); | ||
66 | 68 | ||
67 | /* rx/tx gain */ | 69 | /* rx/tx gain */ |
68 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 70 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
69 | ar9485_common_rx_gain_1_1, | 71 | ar9340Common_wo_xlna_rx_gain_table_1p0, |
70 | ARRAY_SIZE(ar9485_common_rx_gain_1_1), 2); | 72 | ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0), |
73 | 5); | ||
71 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 74 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
72 | ar9485_modes_lowest_ob_db_tx_gain_1_1, | 75 | ar9340Modes_high_ob_db_tx_gain_table_1p0, |
73 | ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), | 76 | ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0), |
74 | 5); | 77 | 5); |
75 | 78 | ||
76 | /* Load PCIE SERDES settings from INI */ | 79 | INIT_INI_ARRAY(&ah->iniModesAdditional, |
77 | 80 | ar9340Modes_fast_clock_1p0, | |
78 | /* Awake Setting */ | 81 | ARRAY_SIZE(ar9340Modes_fast_clock_1p0), |
79 | 82 | 3); | |
80 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
81 | ar9485_1_1_pcie_phy_clkreq_disable_L1, | ||
82 | ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), | ||
83 | 2); | ||
84 | |||
85 | /* Sleep Setting */ | ||
86 | 83 | ||
87 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, | 84 | INIT_INI_ARRAY(&ah->iniModesAdditional_40M, |
88 | ar9485_1_1_pcie_phy_clkreq_disable_L1, | 85 | ar9340_1p0_radio_core_40M, |
89 | ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), | 86 | ARRAY_SIZE(ar9340_1p0_radio_core_40M), |
90 | 2); | 87 | 2); |
91 | } else if (AR_SREV_9485(ah)) { | 88 | } else if (AR_SREV_9485_11(ah)) { |
92 | /* mac */ | 89 | /* mac */ |
93 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | 90 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); |
94 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 91 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
95 | ar9485_1_0_mac_core, | 92 | ar9485_1_1_mac_core, |
96 | ARRAY_SIZE(ar9485_1_0_mac_core), 2); | 93 | ARRAY_SIZE(ar9485_1_1_mac_core), 2); |
97 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | 94 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], |
98 | ar9485_1_0_mac_postamble, | 95 | ar9485_1_1_mac_postamble, |
99 | ARRAY_SIZE(ar9485_1_0_mac_postamble), 5); | 96 | ARRAY_SIZE(ar9485_1_1_mac_postamble), 5); |
100 | 97 | ||
101 | /* bb */ | 98 | /* bb */ |
102 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_0, | 99 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1, |
103 | ARRAY_SIZE(ar9485_1_0), 2); | 100 | ARRAY_SIZE(ar9485_1_1), 2); |
104 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | 101 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], |
105 | ar9485_1_0_baseband_core, | 102 | ar9485_1_1_baseband_core, |
106 | ARRAY_SIZE(ar9485_1_0_baseband_core), 2); | 103 | ARRAY_SIZE(ar9485_1_1_baseband_core), 2); |
107 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | 104 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], |
108 | ar9485_1_0_baseband_postamble, | 105 | ar9485_1_1_baseband_postamble, |
109 | ARRAY_SIZE(ar9485_1_0_baseband_postamble), 5); | 106 | ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5); |
110 | 107 | ||
111 | /* radio */ | 108 | /* radio */ |
112 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | 109 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); |
113 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | 110 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], |
114 | ar9485_1_0_radio_core, | 111 | ar9485_1_1_radio_core, |
115 | ARRAY_SIZE(ar9485_1_0_radio_core), 2); | 112 | ARRAY_SIZE(ar9485_1_1_radio_core), 2); |
116 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | 113 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], |
117 | ar9485_1_0_radio_postamble, | 114 | ar9485_1_1_radio_postamble, |
118 | ARRAY_SIZE(ar9485_1_0_radio_postamble), 2); | 115 | ARRAY_SIZE(ar9485_1_1_radio_postamble), 2); |
119 | 116 | ||
120 | /* soc */ | 117 | /* soc */ |
121 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | 118 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], |
122 | ar9485_1_0_soc_preamble, | 119 | ar9485_1_1_soc_preamble, |
123 | ARRAY_SIZE(ar9485_1_0_soc_preamble), 2); | 120 | ARRAY_SIZE(ar9485_1_1_soc_preamble), 2); |
124 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | 121 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); |
125 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0); | 122 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0); |
126 | 123 | ||
127 | /* rx/tx gain */ | 124 | /* rx/tx gain */ |
128 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 125 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
129 | ar9485Common_rx_gain_1_0, | 126 | ar9485Common_wo_xlna_rx_gain_1_1, |
130 | ARRAY_SIZE(ar9485Common_rx_gain_1_0), 2); | 127 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2); |
131 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 128 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
132 | ar9485Modes_lowest_ob_db_tx_gain_1_0, | 129 | ar9485_modes_lowest_ob_db_tx_gain_1_1, |
133 | ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0), | 130 | ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), |
134 | 5); | 131 | 5); |
135 | 132 | ||
136 | /* Load PCIE SERDES settings from INI */ | 133 | /* Load PCIE SERDES settings from INI */ |
@@ -138,15 +135,15 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
138 | /* Awake Setting */ | 135 | /* Awake Setting */ |
139 | 136 | ||
140 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | 137 | INIT_INI_ARRAY(&ah->iniPcieSerdes, |
141 | ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1, | 138 | ar9485_1_1_pcie_phy_clkreq_disable_L1, |
142 | ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1), | 139 | ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), |
143 | 2); | 140 | 2); |
144 | 141 | ||
145 | /* Sleep Setting */ | 142 | /* Sleep Setting */ |
146 | 143 | ||
147 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, | 144 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, |
148 | ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1, | 145 | ar9485_1_1_pcie_phy_clkreq_disable_L1, |
149 | ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1), | 146 | ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), |
150 | 2); | 147 | 2); |
151 | } else { | 148 | } else { |
152 | /* mac */ | 149 | /* mac */ |
@@ -223,15 +220,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
223 | switch (ar9003_hw_get_tx_gain_idx(ah)) { | 220 | switch (ar9003_hw_get_tx_gain_idx(ah)) { |
224 | case 0: | 221 | case 0: |
225 | default: | 222 | default: |
226 | if (AR_SREV_9485_11(ah)) | 223 | if (AR_SREV_9340(ah)) |
227 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 224 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
228 | ar9485_modes_lowest_ob_db_tx_gain_1_1, | 225 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, |
229 | ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), | 226 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), |
230 | 5); | 227 | 5); |
231 | else if (AR_SREV_9485(ah)) | 228 | else if (AR_SREV_9485_11(ah)) |
232 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 229 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
233 | ar9485Modes_lowest_ob_db_tx_gain_1_0, | 230 | ar9485_modes_lowest_ob_db_tx_gain_1_1, |
234 | ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0), | 231 | ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), |
235 | 5); | 232 | 5); |
236 | else | 233 | else |
237 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 234 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
@@ -240,15 +237,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
240 | 5); | 237 | 5); |
241 | break; | 238 | break; |
242 | case 1: | 239 | case 1: |
243 | if (AR_SREV_9485_11(ah)) | 240 | if (AR_SREV_9340(ah)) |
244 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 241 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
245 | ar9485Modes_high_ob_db_tx_gain_1_1, | 242 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, |
246 | ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1), | 243 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), |
247 | 5); | 244 | 5); |
248 | else if (AR_SREV_9485(ah)) | 245 | else if (AR_SREV_9485_11(ah)) |
249 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 246 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
250 | ar9485Modes_high_ob_db_tx_gain_1_0, | 247 | ar9485Modes_high_ob_db_tx_gain_1_1, |
251 | ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_0), | 248 | ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1), |
252 | 5); | 249 | 5); |
253 | else | 250 | else |
254 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 251 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
@@ -257,15 +254,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
257 | 5); | 254 | 5); |
258 | break; | 255 | break; |
259 | case 2: | 256 | case 2: |
260 | if (AR_SREV_9485_11(ah)) | 257 | if (AR_SREV_9340(ah)) |
261 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 258 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
262 | ar9485Modes_low_ob_db_tx_gain_1_1, | 259 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, |
263 | ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1), | 260 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), |
264 | 5); | 261 | 5); |
265 | else if (AR_SREV_9485(ah)) | 262 | else if (AR_SREV_9485_11(ah)) |
266 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 263 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
267 | ar9485Modes_low_ob_db_tx_gain_1_0, | 264 | ar9485Modes_low_ob_db_tx_gain_1_1, |
268 | ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_0), | 265 | ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1), |
269 | 5); | 266 | 5); |
270 | else | 267 | else |
271 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 268 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
@@ -274,15 +271,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
274 | 5); | 271 | 5); |
275 | break; | 272 | break; |
276 | case 3: | 273 | case 3: |
277 | if (AR_SREV_9485_11(ah)) | 274 | if (AR_SREV_9340(ah)) |
278 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 275 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
279 | ar9485Modes_high_power_tx_gain_1_1, | 276 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, |
280 | ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1), | 277 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), |
281 | 5); | 278 | 5); |
282 | else if (AR_SREV_9485(ah)) | 279 | else if (AR_SREV_9485_11(ah)) |
283 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 280 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
284 | ar9485Modes_high_power_tx_gain_1_0, | 281 | ar9485Modes_high_power_tx_gain_1_1, |
285 | ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_0), | 282 | ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1), |
286 | 5); | 283 | 5); |
287 | else | 284 | else |
288 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 285 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
@@ -298,15 +295,15 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) | |||
298 | switch (ar9003_hw_get_rx_gain_idx(ah)) { | 295 | switch (ar9003_hw_get_rx_gain_idx(ah)) { |
299 | case 0: | 296 | case 0: |
300 | default: | 297 | default: |
301 | if (AR_SREV_9485_11(ah)) | 298 | if (AR_SREV_9340(ah)) |
302 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 299 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
303 | ar9485_common_rx_gain_1_1, | 300 | ar9340Common_rx_gain_table_1p0, |
304 | ARRAY_SIZE(ar9485_common_rx_gain_1_1), | 301 | ARRAY_SIZE(ar9340Common_rx_gain_table_1p0), |
305 | 2); | 302 | 2); |
306 | else if (AR_SREV_9485(ah)) | 303 | else if (AR_SREV_9485_11(ah)) |
307 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 304 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
308 | ar9485Common_rx_gain_1_0, | 305 | ar9485Common_wo_xlna_rx_gain_1_1, |
309 | ARRAY_SIZE(ar9485Common_rx_gain_1_0), | 306 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), |
310 | 2); | 307 | 2); |
311 | else | 308 | else |
312 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 309 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
@@ -315,15 +312,15 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) | |||
315 | 2); | 312 | 2); |
316 | break; | 313 | break; |
317 | case 1: | 314 | case 1: |
318 | if (AR_SREV_9485_11(ah)) | 315 | if (AR_SREV_9340(ah)) |
319 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 316 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
320 | ar9485Common_wo_xlna_rx_gain_1_1, | 317 | ar9340Common_wo_xlna_rx_gain_table_1p0, |
321 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), | 318 | ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0), |
322 | 2); | 319 | 2); |
323 | else if (AR_SREV_9485(ah)) | 320 | else if (AR_SREV_9485_11(ah)) |
324 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 321 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
325 | ar9485Common_wo_xlna_rx_gain_1_0, | 322 | ar9485Common_wo_xlna_rx_gain_1_1, |
326 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_0), | 323 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), |
327 | 2); | 324 | 2); |
328 | else | 325 | else |
329 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 326 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 038a0cbfc6e..be6adec33dd 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
@@ -329,7 +329,6 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds, | |||
329 | | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) | 329 | | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) |
330 | | SM(txpower, AR_XmitPower) | 330 | | SM(txpower, AR_XmitPower) |
331 | | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) | 331 | | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) |
332 | | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) | ||
333 | | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) | 332 | | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) |
334 | | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0); | 333 | | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0); |
335 | 334 | ||
@@ -350,6 +349,16 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds, | |||
350 | ads->ctl22 = 0; | 349 | ads->ctl22 = 0; |
351 | } | 350 | } |
352 | 351 | ||
352 | static void ar9003_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) | ||
353 | { | ||
354 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; | ||
355 | |||
356 | if (val) | ||
357 | ads->ctl11 |= AR_ClrDestMask; | ||
358 | else | ||
359 | ads->ctl11 &= ~AR_ClrDestMask; | ||
360 | } | ||
361 | |||
353 | static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, | 362 | static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, |
354 | void *lastds, | 363 | void *lastds, |
355 | u32 durUpdateEn, u32 rtsctsRate, | 364 | u32 durUpdateEn, u32 rtsctsRate, |
@@ -475,27 +484,6 @@ static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds) | |||
475 | ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr); | 484 | ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr); |
476 | } | 485 | } |
477 | 486 | ||
478 | static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds, | ||
479 | u32 burstDuration) | ||
480 | { | ||
481 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; | ||
482 | |||
483 | ads->ctl13 &= ~AR_BurstDur; | ||
484 | ads->ctl13 |= SM(burstDuration, AR_BurstDur); | ||
485 | |||
486 | } | ||
487 | |||
488 | static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, | ||
489 | u32 vmf) | ||
490 | { | ||
491 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; | ||
492 | |||
493 | if (vmf) | ||
494 | ads->ctl11 |= AR_VirtMoreFrag; | ||
495 | else | ||
496 | ads->ctl11 &= ~AR_VirtMoreFrag; | ||
497 | } | ||
498 | |||
499 | void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains) | 487 | void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains) |
500 | { | 488 | { |
501 | struct ar9003_txc *ads = ds; | 489 | struct ar9003_txc *ads = ds; |
@@ -520,8 +508,7 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw) | |||
520 | ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle; | 508 | ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle; |
521 | ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last; | 509 | ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last; |
522 | ops->clr11n_aggr = ar9003_hw_clr11n_aggr; | 510 | ops->clr11n_aggr = ar9003_hw_clr11n_aggr; |
523 | ops->set11n_burstduration = ar9003_hw_set11n_burstduration; | 511 | ops->set_clrdmask = ar9003_hw_set_clrdmask; |
524 | ops->set11n_virtualmorefrag = ar9003_hw_set11n_virtualmorefrag; | ||
525 | } | 512 | } |
526 | 513 | ||
527 | void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) | 514 | void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index eb250d6b803..25f3c2fdf2b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -75,16 +75,42 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
75 | freq = centers.synth_center; | 75 | freq = centers.synth_center; |
76 | 76 | ||
77 | if (freq < 4800) { /* 2 GHz, fractional mode */ | 77 | if (freq < 4800) { /* 2 GHz, fractional mode */ |
78 | if (AR_SREV_9485(ah)) | 78 | if (AR_SREV_9485(ah)) { |
79 | channelSel = CHANSEL_2G_9485(freq); | 79 | u32 chan_frac; |
80 | else | 80 | |
81 | /* | ||
82 | * freq_ref = 40 / (refdiva >> amoderefsel); where refdiva=1 and amoderefsel=0 | ||
83 | * ndiv = ((chan_mhz * 4) / 3) / freq_ref; | ||
84 | * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000 | ||
85 | */ | ||
86 | channelSel = (freq * 4) / 120; | ||
87 | chan_frac = (((freq * 4) % 120) * 0x20000) / 120; | ||
88 | channelSel = (channelSel << 17) | chan_frac; | ||
89 | } else if (AR_SREV_9340(ah)) { | ||
90 | if (ah->is_clk_25mhz) { | ||
91 | u32 chan_frac; | ||
92 | |||
93 | channelSel = (freq * 2) / 75; | ||
94 | chan_frac = (((freq * 2) % 75) * 0x20000) / 75; | ||
95 | channelSel = (channelSel << 17) | chan_frac; | ||
96 | } else | ||
97 | channelSel = CHANSEL_2G(freq) >> 1; | ||
98 | } else | ||
81 | channelSel = CHANSEL_2G(freq); | 99 | channelSel = CHANSEL_2G(freq); |
82 | /* Set to 2G mode */ | 100 | /* Set to 2G mode */ |
83 | bMode = 1; | 101 | bMode = 1; |
84 | } else { | 102 | } else { |
85 | channelSel = CHANSEL_5G(freq); | 103 | if (AR_SREV_9340(ah) && ah->is_clk_25mhz) { |
86 | /* Doubler is ON, so, divide channelSel by 2. */ | 104 | u32 chan_frac; |
87 | channelSel >>= 1; | 105 | |
106 | channelSel = (freq * 2) / 75; | ||
107 | chan_frac = ((freq % 75) * 0x20000) / 75; | ||
108 | channelSel = (channelSel << 17) | chan_frac; | ||
109 | } else { | ||
110 | channelSel = CHANSEL_5G(freq); | ||
111 | /* Doubler is ON, so, divide channelSel by 2. */ | ||
112 | channelSel >>= 1; | ||
113 | } | ||
88 | /* Set to 5G mode */ | 114 | /* Set to 5G mode */ |
89 | bMode = 0; | 115 | bMode = 0; |
90 | } | 116 | } |
@@ -142,7 +168,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, | |||
142 | * is out-of-band and can be ignored. | 168 | * is out-of-band and can be ignored. |
143 | */ | 169 | */ |
144 | 170 | ||
145 | if (AR_SREV_9485(ah)) { | 171 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) { |
146 | spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, | 172 | spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, |
147 | IS_CHAN_2GHZ(chan)); | 173 | IS_CHAN_2GHZ(chan)); |
148 | if (spur_fbin_ptr[0] == 0) /* No spur */ | 174 | if (spur_fbin_ptr[0] == 0) /* No spur */ |
@@ -167,7 +193,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, | |||
167 | 193 | ||
168 | for (i = 0; i < max_spur_cnts; i++) { | 194 | for (i = 0; i < max_spur_cnts; i++) { |
169 | negative = 0; | 195 | negative = 0; |
170 | if (AR_SREV_9485(ah)) | 196 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) |
171 | cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], | 197 | cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], |
172 | IS_CHAN_2GHZ(chan)) - synth_freq; | 198 | IS_CHAN_2GHZ(chan)) - synth_freq; |
173 | else | 199 | else |
@@ -401,7 +427,7 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah, | |||
401 | 427 | ||
402 | ar9003_hw_spur_ofdm_clear(ah); | 428 | ar9003_hw_spur_ofdm_clear(ah); |
403 | 429 | ||
404 | for (i = 0; spurChansPtr[i] && i < 5; i++) { | 430 | for (i = 0; i < AR_EEPROM_MODAL_SPURS && spurChansPtr[i]; i++) { |
405 | freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq; | 431 | freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq; |
406 | if (abs(freq_offset) < range) { | 432 | if (abs(freq_offset) < range) { |
407 | ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); | 433 | ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); |
@@ -590,29 +616,25 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
590 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | 616 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); |
591 | unsigned int regWrites = 0, i; | 617 | unsigned int regWrites = 0, i; |
592 | struct ieee80211_channel *channel = chan->chan; | 618 | struct ieee80211_channel *channel = chan->chan; |
593 | u32 modesIndex, freqIndex; | 619 | u32 modesIndex; |
594 | 620 | ||
595 | switch (chan->chanmode) { | 621 | switch (chan->chanmode) { |
596 | case CHANNEL_A: | 622 | case CHANNEL_A: |
597 | case CHANNEL_A_HT20: | 623 | case CHANNEL_A_HT20: |
598 | modesIndex = 1; | 624 | modesIndex = 1; |
599 | freqIndex = 1; | ||
600 | break; | 625 | break; |
601 | case CHANNEL_A_HT40PLUS: | 626 | case CHANNEL_A_HT40PLUS: |
602 | case CHANNEL_A_HT40MINUS: | 627 | case CHANNEL_A_HT40MINUS: |
603 | modesIndex = 2; | 628 | modesIndex = 2; |
604 | freqIndex = 1; | ||
605 | break; | 629 | break; |
606 | case CHANNEL_G: | 630 | case CHANNEL_G: |
607 | case CHANNEL_G_HT20: | 631 | case CHANNEL_G_HT20: |
608 | case CHANNEL_B: | 632 | case CHANNEL_B: |
609 | modesIndex = 4; | 633 | modesIndex = 4; |
610 | freqIndex = 2; | ||
611 | break; | 634 | break; |
612 | case CHANNEL_G_HT40PLUS: | 635 | case CHANNEL_G_HT40PLUS: |
613 | case CHANNEL_G_HT40MINUS: | 636 | case CHANNEL_G_HT40MINUS: |
614 | modesIndex = 3; | 637 | modesIndex = 3; |
615 | freqIndex = 2; | ||
616 | break; | 638 | break; |
617 | 639 | ||
618 | default: | 640 | default: |
@@ -637,6 +659,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
637 | REG_WRITE_ARRAY(&ah->iniModesAdditional, | 659 | REG_WRITE_ARRAY(&ah->iniModesAdditional, |
638 | modesIndex, regWrites); | 660 | modesIndex, regWrites); |
639 | 661 | ||
662 | if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) | ||
663 | REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); | ||
664 | |||
640 | ar9003_hw_override_ini(ah); | 665 | ar9003_hw_override_ini(ah); |
641 | ar9003_hw_set_channel_regs(ah, chan); | 666 | ar9003_hw_set_channel_regs(ah, chan); |
642 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); | 667 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); |
@@ -1159,9 +1184,52 @@ static void ar9003_hw_set_radar_conf(struct ath_hw *ah) | |||
1159 | conf->radar_inband = 8; | 1184 | conf->radar_inband = 8; |
1160 | } | 1185 | } |
1161 | 1186 | ||
1187 | static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah, | ||
1188 | struct ath_hw_antcomb_conf *antconf) | ||
1189 | { | ||
1190 | u32 regval; | ||
1191 | |||
1192 | regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); | ||
1193 | antconf->main_lna_conf = (regval & AR_PHY_9485_ANT_DIV_MAIN_LNACONF) >> | ||
1194 | AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S; | ||
1195 | antconf->alt_lna_conf = (regval & AR_PHY_9485_ANT_DIV_ALT_LNACONF) >> | ||
1196 | AR_PHY_9485_ANT_DIV_ALT_LNACONF_S; | ||
1197 | antconf->fast_div_bias = (regval & AR_PHY_9485_ANT_FAST_DIV_BIAS) >> | ||
1198 | AR_PHY_9485_ANT_FAST_DIV_BIAS_S; | ||
1199 | antconf->lna1_lna2_delta = -9; | ||
1200 | antconf->div_group = 2; | ||
1201 | } | ||
1202 | |||
1203 | static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah, | ||
1204 | struct ath_hw_antcomb_conf *antconf) | ||
1205 | { | ||
1206 | u32 regval; | ||
1207 | |||
1208 | regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); | ||
1209 | regval &= ~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF | | ||
1210 | AR_PHY_9485_ANT_DIV_ALT_LNACONF | | ||
1211 | AR_PHY_9485_ANT_FAST_DIV_BIAS | | ||
1212 | AR_PHY_9485_ANT_DIV_MAIN_GAINTB | | ||
1213 | AR_PHY_9485_ANT_DIV_ALT_GAINTB); | ||
1214 | regval |= ((antconf->main_lna_conf << | ||
1215 | AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S) | ||
1216 | & AR_PHY_9485_ANT_DIV_MAIN_LNACONF); | ||
1217 | regval |= ((antconf->alt_lna_conf << AR_PHY_9485_ANT_DIV_ALT_LNACONF_S) | ||
1218 | & AR_PHY_9485_ANT_DIV_ALT_LNACONF); | ||
1219 | regval |= ((antconf->fast_div_bias << AR_PHY_9485_ANT_FAST_DIV_BIAS_S) | ||
1220 | & AR_PHY_9485_ANT_FAST_DIV_BIAS); | ||
1221 | regval |= ((antconf->main_gaintb << AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S) | ||
1222 | & AR_PHY_9485_ANT_DIV_MAIN_GAINTB); | ||
1223 | regval |= ((antconf->alt_gaintb << AR_PHY_9485_ANT_DIV_ALT_GAINTB_S) | ||
1224 | & AR_PHY_9485_ANT_DIV_ALT_GAINTB); | ||
1225 | |||
1226 | REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); | ||
1227 | } | ||
1228 | |||
1162 | void ar9003_hw_attach_phy_ops(struct ath_hw *ah) | 1229 | void ar9003_hw_attach_phy_ops(struct ath_hw *ah) |
1163 | { | 1230 | { |
1164 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | 1231 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); |
1232 | struct ath_hw_ops *ops = ath9k_hw_ops(ah); | ||
1165 | static const u32 ar9300_cca_regs[6] = { | 1233 | static const u32 ar9300_cca_regs[6] = { |
1166 | AR_PHY_CCA_0, | 1234 | AR_PHY_CCA_0, |
1167 | AR_PHY_CCA_1, | 1235 | AR_PHY_CCA_1, |
@@ -1188,6 +1256,9 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) | |||
1188 | priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs; | 1256 | priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs; |
1189 | priv_ops->set_radar_params = ar9003_hw_set_radar_params; | 1257 | priv_ops->set_radar_params = ar9003_hw_set_radar_params; |
1190 | 1258 | ||
1259 | ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get; | ||
1260 | ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set; | ||
1261 | |||
1191 | ar9003_hw_set_nf_limits(ah); | 1262 | ar9003_hw_set_nf_limits(ah); |
1192 | ar9003_hw_set_radar_conf(ah); | 1263 | ar9003_hw_set_radar_conf(ah); |
1193 | memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs)); | 1264 | memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs)); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 8bdda2cf9dd..c7505b48e5c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -261,12 +261,34 @@ | |||
261 | #define AR_PHY_EXT_CCA0 (AR_AGC_BASE + 0x20) | 261 | #define AR_PHY_EXT_CCA0 (AR_AGC_BASE + 0x20) |
262 | #define AR_PHY_RESTART (AR_AGC_BASE + 0x24) | 262 | #define AR_PHY_RESTART (AR_AGC_BASE + 0x24) |
263 | 263 | ||
264 | /* | ||
265 | * Antenna Diversity settings | ||
266 | */ | ||
264 | #define AR_PHY_MC_GAIN_CTRL (AR_AGC_BASE + 0x28) | 267 | #define AR_PHY_MC_GAIN_CTRL (AR_AGC_BASE + 0x28) |
265 | #define AR_ANT_DIV_CTRL_ALL 0x7e000000 | 268 | #define AR_ANT_DIV_CTRL_ALL 0x7e000000 |
266 | #define AR_ANT_DIV_CTRL_ALL_S 25 | 269 | #define AR_ANT_DIV_CTRL_ALL_S 25 |
267 | #define AR_ANT_DIV_ENABLE 0x1000000 | 270 | #define AR_ANT_DIV_ENABLE 0x1000000 |
268 | #define AR_ANT_DIV_ENABLE_S 24 | 271 | #define AR_ANT_DIV_ENABLE_S 24 |
269 | 272 | ||
273 | |||
274 | #define AR_PHY_9485_ANT_FAST_DIV_BIAS 0x00007e00 | ||
275 | #define AR_PHY_9485_ANT_FAST_DIV_BIAS_S 9 | ||
276 | #define AR_PHY_9485_ANT_DIV_LNADIV 0x01000000 | ||
277 | #define AR_PHY_9485_ANT_DIV_LNADIV_S 24 | ||
278 | #define AR_PHY_9485_ANT_DIV_ALT_LNACONF 0x06000000 | ||
279 | #define AR_PHY_9485_ANT_DIV_ALT_LNACONF_S 25 | ||
280 | #define AR_PHY_9485_ANT_DIV_MAIN_LNACONF 0x18000000 | ||
281 | #define AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S 27 | ||
282 | #define AR_PHY_9485_ANT_DIV_ALT_GAINTB 0x20000000 | ||
283 | #define AR_PHY_9485_ANT_DIV_ALT_GAINTB_S 29 | ||
284 | #define AR_PHY_9485_ANT_DIV_MAIN_GAINTB 0x40000000 | ||
285 | #define AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S 30 | ||
286 | |||
287 | #define AR_PHY_9485_ANT_DIV_LNA1_MINUS_LNA2 0x0 | ||
288 | #define AR_PHY_9485_ANT_DIV_LNA2 0x1 | ||
289 | #define AR_PHY_9485_ANT_DIV_LNA1 0x2 | ||
290 | #define AR_PHY_9485_ANT_DIV_LNA1_PLUS_LNA2 0x3 | ||
291 | |||
270 | #define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c) | 292 | #define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c) |
271 | #define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30) | 293 | #define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30) |
272 | #define AR_PHY_20_40_DET_THR (AR_AGC_BASE + 0x34) | 294 | #define AR_PHY_20_40_DET_THR (AR_AGC_BASE + 0x34) |
@@ -548,15 +570,12 @@ | |||
548 | 570 | ||
549 | #define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300) | 571 | #define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300) |
550 | 572 | ||
551 | #define AR_PHY_TX_IQCAL_START_9485 (AR_SM_BASE + 0x3c4) | 573 | #define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + AR_SREV_9485(ah) ? \ |
552 | #define AR_PHY_TX_IQCAL_START_DO_CAL_9485 0x80000000 | 574 | 0x3c8 : 0x448) |
553 | #define AR_PHY_TX_IQCAL_START_DO_CAL_9485_S 31 | 575 | #define AR_PHY_TX_IQCAL_START (AR_SM_BASE + AR_SREV_9485(ah) ? \ |
554 | #define AR_PHY_TX_IQCAL_CONTROL_1_9485 (AR_SM_BASE + 0x3c8) | 576 | 0x3c4 : 0x440) |
555 | #define AR_PHY_TX_IQCAL_STATUS_B0_9485 (AR_SM_BASE + 0x3f0) | 577 | #define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + AR_SREV_9485(ah) ? \ |
556 | 578 | 0x3f0 : 0x48c) | |
557 | #define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448) | ||
558 | #define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440) | ||
559 | #define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c) | ||
560 | #define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \ | 579 | #define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \ |
561 | (AR_SREV_9485(ah) ? \ | 580 | (AR_SREV_9485(ah) ? \ |
562 | 0x3d0 : 0x450) + ((_i) << 2)) | 581 | 0x3d0 : 0x450) + ((_i) << 2)) |
@@ -588,7 +607,7 @@ | |||
588 | #define AR_PHY_65NM_CH0_BIAS2 0x160c4 | 607 | #define AR_PHY_65NM_CH0_BIAS2 0x160c4 |
589 | #define AR_PHY_65NM_CH0_BIAS4 0x160cc | 608 | #define AR_PHY_65NM_CH0_BIAS4 0x160cc |
590 | #define AR_PHY_65NM_CH0_RXTX4 0x1610c | 609 | #define AR_PHY_65NM_CH0_RXTX4 0x1610c |
591 | #define AR_PHY_65NM_CH0_THERM (AR_SREV_9485(ah) ? 0x1628c : 0x16290) | 610 | #define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 : 0x1628c) |
592 | 611 | ||
593 | #define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000 | 612 | #define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000 |
594 | #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31 | 613 | #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31 |
@@ -758,10 +777,10 @@ | |||
758 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 | 777 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 |
759 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 | 778 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 |
760 | #define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004 | 779 | #define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004 |
761 | #define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000 | 780 | #define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000 |
762 | #define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18 | 781 | #define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18 |
763 | #define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001 | 782 | #define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001 |
764 | #define AR_PHY_TX_IQCAL_START_DO_CAL_S 0 | 783 | #define AR_PHY_TX_IQCAL_START_DO_CAL_S 0 |
765 | 784 | ||
766 | #define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001 | 785 | #define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001 |
767 | #define AR_PHY_CALIBRATED_GAINS_0 0x3e | 786 | #define AR_PHY_CALIBRATED_GAINS_0 0x3e |
diff --git a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h new file mode 100644 index 00000000000..815a8af1bee --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h | |||
@@ -0,0 +1,1525 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef INITVALS_9340_H | ||
18 | #define INITVALS_9340_H | ||
19 | |||
20 | static const u32 ar9340_1p0_radio_postamble[][5] = { | ||
21 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
22 | {0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800}, | ||
23 | {0x0001610c, 0x08000000, 0x08000000, 0x00000000, 0x00000000}, | ||
24 | {0x00016140, 0x10804000, 0x10804000, 0x50804000, 0x50804000}, | ||
25 | {0x0001650c, 0x08000000, 0x08000000, 0x00000000, 0x00000000}, | ||
26 | {0x00016540, 0x10804000, 0x10804000, 0x50804000, 0x50804000}, | ||
27 | }; | ||
28 | |||
29 | static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = { | ||
30 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
31 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
32 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
33 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | ||
34 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | ||
35 | {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, | ||
36 | {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, | ||
37 | {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, | ||
38 | {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, | ||
39 | {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, | ||
40 | {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, | ||
41 | {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, | ||
42 | {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, | ||
43 | {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, | ||
44 | {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, | ||
45 | {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, | ||
46 | {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, | ||
47 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, | ||
48 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, | ||
49 | {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, | ||
50 | {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, | ||
51 | {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, | ||
52 | {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, | ||
53 | {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, | ||
54 | {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, | ||
55 | {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, | ||
56 | {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, | ||
57 | {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
58 | {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
59 | {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
60 | {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
61 | {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
62 | {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
63 | {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
64 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | ||
65 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, | ||
66 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, | ||
67 | {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, | ||
68 | {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, | ||
69 | {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, | ||
70 | {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402}, | ||
71 | {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404}, | ||
72 | {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, | ||
73 | {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, | ||
74 | {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, | ||
75 | {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, | ||
76 | {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, | ||
77 | {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, | ||
78 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, | ||
79 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, | ||
80 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, | ||
81 | {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, | ||
82 | {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, | ||
83 | {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83}, | ||
84 | {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84}, | ||
85 | {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3}, | ||
86 | {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5}, | ||
87 | {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9}, | ||
88 | {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb}, | ||
89 | {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
90 | {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
91 | {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
92 | {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
93 | {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
94 | {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
95 | {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
96 | {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, | ||
97 | {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, | ||
98 | {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, | ||
99 | {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, | ||
100 | }; | ||
101 | |||
102 | static const u32 ar9340Modes_fast_clock_1p0[][3] = { | ||
103 | /* Addr 5G_HT20 5G_HT40 */ | ||
104 | {0x00001030, 0x00000268, 0x000004d0}, | ||
105 | {0x00001070, 0x0000018c, 0x00000318}, | ||
106 | {0x000010b0, 0x00000fd0, 0x00001fa0}, | ||
107 | {0x00008014, 0x044c044c, 0x08980898}, | ||
108 | {0x0000801c, 0x148ec02b, 0x148ec057}, | ||
109 | {0x00008318, 0x000044c0, 0x00008980}, | ||
110 | {0x00009e00, 0x03721821, 0x03721821}, | ||
111 | {0x0000a230, 0x0000000b, 0x00000016}, | ||
112 | {0x0000a254, 0x00000898, 0x00001130}, | ||
113 | }; | ||
114 | |||
115 | static const u32 ar9340_1p0_radio_core[][2] = { | ||
116 | /* Addr allmodes */ | ||
117 | {0x00016000, 0x36db6db6}, | ||
118 | {0x00016004, 0x6db6db40}, | ||
119 | {0x00016008, 0x73f00000}, | ||
120 | {0x0001600c, 0x00000000}, | ||
121 | {0x00016040, 0x7f80fff8}, | ||
122 | {0x00016044, 0x03b6d2db}, | ||
123 | {0x00016048, 0x24925266}, | ||
124 | {0x0001604c, 0x000f0278}, | ||
125 | {0x00016050, 0x6db6db6c}, | ||
126 | {0x00016054, 0x6db60000}, | ||
127 | {0x00016080, 0x00080000}, | ||
128 | {0x00016084, 0x0e48048c}, | ||
129 | {0x00016088, 0x14214514}, | ||
130 | {0x0001608c, 0x119f081c}, | ||
131 | {0x00016090, 0x24926490}, | ||
132 | {0x00016094, 0x00000000}, | ||
133 | {0x00016098, 0xd411eb84}, | ||
134 | {0x0001609c, 0x03e47f32}, | ||
135 | {0x000160a0, 0xc2108ffe}, | ||
136 | {0x000160a4, 0x812fc370}, | ||
137 | {0x000160a8, 0x423c8000}, | ||
138 | {0x000160ac, 0xa4646800}, | ||
139 | {0x000160b0, 0x00fe7f46}, | ||
140 | {0x000160b4, 0x92480000}, | ||
141 | {0x000160c0, 0x006db6db}, | ||
142 | {0x000160c4, 0x6db6db60}, | ||
143 | {0x000160c8, 0x6db6db6c}, | ||
144 | {0x000160cc, 0x6de6db6c}, | ||
145 | {0x000160d0, 0xb6da4924}, | ||
146 | {0x00016100, 0x04cb0001}, | ||
147 | {0x00016104, 0xfff80000}, | ||
148 | {0x00016108, 0x00080010}, | ||
149 | {0x0001610c, 0x00000000}, | ||
150 | {0x00016140, 0x50804008}, | ||
151 | {0x00016144, 0x01884080}, | ||
152 | {0x00016148, 0x000080c0}, | ||
153 | {0x00016280, 0x01000015}, | ||
154 | {0x00016284, 0x05530000}, | ||
155 | {0x00016288, 0x00318000}, | ||
156 | {0x0001628c, 0x50000000}, | ||
157 | {0x00016290, 0x4080294f}, | ||
158 | {0x00016380, 0x00000000}, | ||
159 | {0x00016384, 0x00000000}, | ||
160 | {0x00016388, 0x00800700}, | ||
161 | {0x0001638c, 0x00800700}, | ||
162 | {0x00016390, 0x00800700}, | ||
163 | {0x00016394, 0x00000000}, | ||
164 | {0x00016398, 0x00000000}, | ||
165 | {0x0001639c, 0x00000000}, | ||
166 | {0x000163a0, 0x00000001}, | ||
167 | {0x000163a4, 0x00000001}, | ||
168 | {0x000163a8, 0x00000000}, | ||
169 | {0x000163ac, 0x00000000}, | ||
170 | {0x000163b0, 0x00000000}, | ||
171 | {0x000163b4, 0x00000000}, | ||
172 | {0x000163b8, 0x00000000}, | ||
173 | {0x000163bc, 0x00000000}, | ||
174 | {0x000163c0, 0x000000a0}, | ||
175 | {0x000163c4, 0x000c0000}, | ||
176 | {0x000163c8, 0x14021402}, | ||
177 | {0x000163cc, 0x00001402}, | ||
178 | {0x000163d0, 0x00000000}, | ||
179 | {0x000163d4, 0x00000000}, | ||
180 | {0x00016400, 0x36db6db6}, | ||
181 | {0x00016404, 0x6db6db40}, | ||
182 | {0x00016408, 0x73f00000}, | ||
183 | {0x0001640c, 0x00000000}, | ||
184 | {0x00016440, 0x7f80fff8}, | ||
185 | {0x00016444, 0x03b6d2db}, | ||
186 | {0x00016448, 0x24927266}, | ||
187 | {0x0001644c, 0x000f0278}, | ||
188 | {0x00016450, 0x6db6db6c}, | ||
189 | {0x00016454, 0x6db60000}, | ||
190 | {0x00016500, 0x04cb0001}, | ||
191 | {0x00016504, 0xfff80000}, | ||
192 | {0x00016508, 0x00080010}, | ||
193 | {0x0001650c, 0x00000000}, | ||
194 | {0x00016540, 0x50804008}, | ||
195 | {0x00016544, 0x01884080}, | ||
196 | {0x00016548, 0x000080c0}, | ||
197 | {0x00016780, 0x00000000}, | ||
198 | {0x00016784, 0x00000000}, | ||
199 | {0x00016788, 0x00800700}, | ||
200 | {0x0001678c, 0x00800700}, | ||
201 | {0x00016790, 0x00800700}, | ||
202 | {0x00016794, 0x00000000}, | ||
203 | {0x00016798, 0x00000000}, | ||
204 | {0x0001679c, 0x00000000}, | ||
205 | {0x000167a0, 0x00000001}, | ||
206 | {0x000167a4, 0x00000001}, | ||
207 | {0x000167a8, 0x00000000}, | ||
208 | {0x000167ac, 0x00000000}, | ||
209 | {0x000167b0, 0x00000000}, | ||
210 | {0x000167b4, 0x00000000}, | ||
211 | {0x000167b8, 0x00000000}, | ||
212 | {0x000167bc, 0x00000000}, | ||
213 | {0x000167c0, 0x000000a0}, | ||
214 | {0x000167c4, 0x000c0000}, | ||
215 | {0x000167c8, 0x14021402}, | ||
216 | {0x000167cc, 0x00001402}, | ||
217 | {0x000167d0, 0x00000000}, | ||
218 | {0x000167d4, 0x00000000}, | ||
219 | }; | ||
220 | |||
221 | static const u32 ar9340_1p0_radio_core_40M[][2] = { | ||
222 | {0x0001609c, 0x02566f3a}, | ||
223 | {0x000160ac, 0xa4647c00}, | ||
224 | {0x000160b0, 0x01885f5a}, | ||
225 | }; | ||
226 | |||
227 | static const u32 ar9340_1p0_mac_postamble[][5] = { | ||
228 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
229 | {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, | ||
230 | {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, | ||
231 | {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, | ||
232 | {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, | ||
233 | {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, | ||
234 | {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, | ||
235 | {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, | ||
236 | {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, | ||
237 | }; | ||
238 | |||
239 | static const u32 ar9340_1p0_soc_postamble[][5] = { | ||
240 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
241 | {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, | ||
242 | }; | ||
243 | |||
244 | static const u32 ar9340_1p0_baseband_postamble[][5] = { | ||
245 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
246 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, | ||
247 | {0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e}, | ||
248 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, | ||
249 | {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, | ||
250 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, | ||
251 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, | ||
252 | {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044}, | ||
253 | {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, | ||
254 | {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, | ||
255 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, | ||
256 | {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e}, | ||
257 | {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, | ||
258 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
259 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | ||
260 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | ||
261 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, | ||
262 | {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27}, | ||
263 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, | ||
264 | {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, | ||
265 | {0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0}, | ||
266 | {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, | ||
267 | {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, | ||
268 | {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, | ||
269 | {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, | ||
270 | {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, | ||
271 | {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, | ||
272 | {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, | ||
273 | {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501}, | ||
274 | {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, | ||
275 | {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, | ||
276 | {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, | ||
277 | {0x0000a288, 0x00000220, 0x00000220, 0x00000110, 0x00000110}, | ||
278 | {0x0000a28c, 0x00011111, 0x00011111, 0x00022222, 0x00022222}, | ||
279 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, | ||
280 | {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982}, | ||
281 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, | ||
282 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
283 | {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | ||
284 | {0x0000ae04, 0x00180000, 0x00180000, 0x00180000, 0x00180000}, | ||
285 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
286 | {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | ||
287 | {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, | ||
288 | {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, | ||
289 | }; | ||
290 | |||
291 | static const u32 ar9340_1p0_baseband_core[][2] = { | ||
292 | /* Addr allmodes */ | ||
293 | {0x00009800, 0xafe68e30}, | ||
294 | {0x00009804, 0xfd14e000}, | ||
295 | {0x00009808, 0x9c0a9f6b}, | ||
296 | {0x0000980c, 0x04900000}, | ||
297 | {0x00009814, 0xb280c00a}, | ||
298 | {0x00009818, 0x00000000}, | ||
299 | {0x0000981c, 0x00020028}, | ||
300 | {0x00009834, 0x5f3ca3de}, | ||
301 | {0x00009838, 0x0108ecff}, | ||
302 | {0x0000983c, 0x14750600}, | ||
303 | {0x00009880, 0x201fff00}, | ||
304 | {0x00009884, 0x00001042}, | ||
305 | {0x000098a4, 0x00200400}, | ||
306 | {0x000098b0, 0x52440bbe}, | ||
307 | {0x000098d0, 0x004b6a8e}, | ||
308 | {0x000098d4, 0x00000820}, | ||
309 | {0x000098dc, 0x00000000}, | ||
310 | {0x000098f0, 0x00000000}, | ||
311 | {0x000098f4, 0x00000000}, | ||
312 | {0x00009c04, 0xff55ff55}, | ||
313 | {0x00009c08, 0x0320ff55}, | ||
314 | {0x00009c0c, 0x00000000}, | ||
315 | {0x00009c10, 0x00000000}, | ||
316 | {0x00009c14, 0x00046384}, | ||
317 | {0x00009c18, 0x05b6b440}, | ||
318 | {0x00009c1c, 0x00b6b440}, | ||
319 | {0x00009d00, 0xc080a333}, | ||
320 | {0x00009d04, 0x40206c10}, | ||
321 | {0x00009d08, 0x009c4060}, | ||
322 | {0x00009d0c, 0x9883800a}, | ||
323 | {0x00009d10, 0x01834061}, | ||
324 | {0x00009d14, 0x00c0040b}, | ||
325 | {0x00009d18, 0x00000000}, | ||
326 | {0x00009e08, 0x0038230c}, | ||
327 | {0x00009e24, 0x990bb515}, | ||
328 | {0x00009e28, 0x0c6f0000}, | ||
329 | {0x00009e30, 0x06336f77}, | ||
330 | {0x00009e34, 0x6af6532f}, | ||
331 | {0x00009e38, 0x0cc80c00}, | ||
332 | {0x00009e3c, 0xcf946222}, | ||
333 | {0x00009e40, 0x0d261820}, | ||
334 | {0x00009e4c, 0x00001004}, | ||
335 | {0x00009e50, 0x00ff03f1}, | ||
336 | {0x00009e54, 0x00000000}, | ||
337 | {0x00009fc0, 0x803e4788}, | ||
338 | {0x00009fc4, 0x0001efb5}, | ||
339 | {0x00009fcc, 0x40000014}, | ||
340 | {0x00009fd0, 0x01193b93}, | ||
341 | {0x0000a20c, 0x00000000}, | ||
342 | {0x0000a220, 0x00000000}, | ||
343 | {0x0000a224, 0x00000000}, | ||
344 | {0x0000a228, 0x10002310}, | ||
345 | {0x0000a22c, 0x01036a1e}, | ||
346 | {0x0000a234, 0x10000fff}, | ||
347 | {0x0000a23c, 0x00000000}, | ||
348 | {0x0000a244, 0x0c000000}, | ||
349 | {0x0000a2a0, 0x00000001}, | ||
350 | {0x0000a2c0, 0x00000001}, | ||
351 | {0x0000a2c8, 0x00000000}, | ||
352 | {0x0000a2cc, 0x18c43433}, | ||
353 | {0x0000a2d4, 0x00000000}, | ||
354 | {0x0000a2dc, 0x00000000}, | ||
355 | {0x0000a2e0, 0x00000000}, | ||
356 | {0x0000a2e4, 0x00000000}, | ||
357 | {0x0000a2e8, 0x00000000}, | ||
358 | {0x0000a2ec, 0x00000000}, | ||
359 | {0x0000a2f0, 0x00000000}, | ||
360 | {0x0000a2f4, 0x00000000}, | ||
361 | {0x0000a2f8, 0x00000000}, | ||
362 | {0x0000a344, 0x00000000}, | ||
363 | {0x0000a34c, 0x00000000}, | ||
364 | {0x0000a350, 0x0000a000}, | ||
365 | {0x0000a364, 0x00000000}, | ||
366 | {0x0000a370, 0x00000000}, | ||
367 | {0x0000a390, 0x00000001}, | ||
368 | {0x0000a394, 0x00000444}, | ||
369 | {0x0000a398, 0x001f0e0f}, | ||
370 | {0x0000a39c, 0x0075393f}, | ||
371 | {0x0000a3a0, 0xb79f6427}, | ||
372 | {0x0000a3a4, 0x00000000}, | ||
373 | {0x0000a3a8, 0xaaaaaaaa}, | ||
374 | {0x0000a3ac, 0x3c466478}, | ||
375 | {0x0000a3c0, 0x20202020}, | ||
376 | {0x0000a3c4, 0x22222220}, | ||
377 | {0x0000a3c8, 0x20200020}, | ||
378 | {0x0000a3cc, 0x20202020}, | ||
379 | {0x0000a3d0, 0x20202020}, | ||
380 | {0x0000a3d4, 0x20202020}, | ||
381 | {0x0000a3d8, 0x20202020}, | ||
382 | {0x0000a3dc, 0x20202020}, | ||
383 | {0x0000a3e0, 0x20202020}, | ||
384 | {0x0000a3e4, 0x20202020}, | ||
385 | {0x0000a3e8, 0x20202020}, | ||
386 | {0x0000a3ec, 0x20202020}, | ||
387 | {0x0000a3f0, 0x00000000}, | ||
388 | {0x0000a3f4, 0x00000246}, | ||
389 | {0x0000a3f8, 0x0cdbd380}, | ||
390 | {0x0000a3fc, 0x000f0f01}, | ||
391 | {0x0000a400, 0x8fa91f01}, | ||
392 | {0x0000a404, 0x00000000}, | ||
393 | {0x0000a408, 0x0e79e5c6}, | ||
394 | {0x0000a40c, 0x00820820}, | ||
395 | {0x0000a414, 0x1ce739ce}, | ||
396 | {0x0000a418, 0x2d001dce}, | ||
397 | {0x0000a41c, 0x1ce739ce}, | ||
398 | {0x0000a420, 0x000001ce}, | ||
399 | {0x0000a424, 0x1ce739ce}, | ||
400 | {0x0000a428, 0x000001ce}, | ||
401 | {0x0000a42c, 0x1ce739ce}, | ||
402 | {0x0000a430, 0x1ce739ce}, | ||
403 | {0x0000a434, 0x00000000}, | ||
404 | {0x0000a438, 0x00001801}, | ||
405 | {0x0000a43c, 0x00000000}, | ||
406 | {0x0000a440, 0x00000000}, | ||
407 | {0x0000a444, 0x00000000}, | ||
408 | {0x0000a448, 0x04000080}, | ||
409 | {0x0000a44c, 0x00000001}, | ||
410 | {0x0000a450, 0x00010000}, | ||
411 | {0x0000a458, 0x00000000}, | ||
412 | {0x0000a600, 0x00000000}, | ||
413 | {0x0000a604, 0x00000000}, | ||
414 | {0x0000a608, 0x00000000}, | ||
415 | {0x0000a60c, 0x00000000}, | ||
416 | {0x0000a610, 0x00000000}, | ||
417 | {0x0000a614, 0x00000000}, | ||
418 | {0x0000a618, 0x00000000}, | ||
419 | {0x0000a61c, 0x00000000}, | ||
420 | {0x0000a620, 0x00000000}, | ||
421 | {0x0000a624, 0x00000000}, | ||
422 | {0x0000a628, 0x00000000}, | ||
423 | {0x0000a62c, 0x00000000}, | ||
424 | {0x0000a630, 0x00000000}, | ||
425 | {0x0000a634, 0x00000000}, | ||
426 | {0x0000a638, 0x00000000}, | ||
427 | {0x0000a63c, 0x00000000}, | ||
428 | {0x0000a640, 0x00000000}, | ||
429 | {0x0000a644, 0x3fad9d74}, | ||
430 | {0x0000a648, 0x0048060a}, | ||
431 | {0x0000a64c, 0x00000637}, | ||
432 | {0x0000a670, 0x03020100}, | ||
433 | {0x0000a674, 0x09080504}, | ||
434 | {0x0000a678, 0x0d0c0b0a}, | ||
435 | {0x0000a67c, 0x13121110}, | ||
436 | {0x0000a680, 0x31301514}, | ||
437 | {0x0000a684, 0x35343332}, | ||
438 | {0x0000a688, 0x00000036}, | ||
439 | {0x0000a690, 0x00000838}, | ||
440 | {0x0000a7c0, 0x00000000}, | ||
441 | {0x0000a7c4, 0xfffffffc}, | ||
442 | {0x0000a7c8, 0x00000000}, | ||
443 | {0x0000a7cc, 0x00000000}, | ||
444 | {0x0000a7d0, 0x00000000}, | ||
445 | {0x0000a7d4, 0x00000004}, | ||
446 | {0x0000a7dc, 0x00000000}, | ||
447 | {0x0000a8d0, 0x004b6a8e}, | ||
448 | {0x0000a8d4, 0x00000820}, | ||
449 | {0x0000a8dc, 0x00000000}, | ||
450 | {0x0000a8f0, 0x00000000}, | ||
451 | {0x0000a8f4, 0x00000000}, | ||
452 | {0x0000b2d0, 0x00000080}, | ||
453 | {0x0000b2d4, 0x00000000}, | ||
454 | {0x0000b2dc, 0x00000000}, | ||
455 | {0x0000b2e0, 0x00000000}, | ||
456 | {0x0000b2e4, 0x00000000}, | ||
457 | {0x0000b2e8, 0x00000000}, | ||
458 | {0x0000b2ec, 0x00000000}, | ||
459 | {0x0000b2f0, 0x00000000}, | ||
460 | {0x0000b2f4, 0x00000000}, | ||
461 | {0x0000b2f8, 0x00000000}, | ||
462 | {0x0000b408, 0x0e79e5c0}, | ||
463 | {0x0000b40c, 0x00820820}, | ||
464 | {0x0000b420, 0x00000000}, | ||
465 | }; | ||
466 | |||
467 | static const u32 ar9340Modes_high_power_tx_gain_table_1p0[][5] = { | ||
468 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
469 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, | ||
470 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | ||
471 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, | ||
472 | {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, | ||
473 | {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, | ||
474 | {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, | ||
475 | {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, | ||
476 | {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, | ||
477 | {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, | ||
478 | {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, | ||
479 | {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, | ||
480 | {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, | ||
481 | {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, | ||
482 | {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, | ||
483 | {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, | ||
484 | {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, | ||
485 | {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, | ||
486 | {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, | ||
487 | {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, | ||
488 | {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, | ||
489 | {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, | ||
490 | {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, | ||
491 | {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, | ||
492 | {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, | ||
493 | {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, | ||
494 | {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, | ||
495 | {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
496 | {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
497 | {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
498 | {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
499 | {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
500 | {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
501 | {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
502 | {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, | ||
503 | {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, | ||
504 | {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, | ||
505 | {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, | ||
506 | {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, | ||
507 | {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, | ||
508 | {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, | ||
509 | {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, | ||
510 | {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, | ||
511 | {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, | ||
512 | {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, | ||
513 | {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, | ||
514 | {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, | ||
515 | {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, | ||
516 | {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, | ||
517 | {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, | ||
518 | {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, | ||
519 | {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, | ||
520 | {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, | ||
521 | {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, | ||
522 | {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, | ||
523 | {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, | ||
524 | {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, | ||
525 | {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, | ||
526 | {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, | ||
527 | {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
528 | {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
529 | {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
530 | {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
531 | {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
532 | {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
533 | {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
534 | {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, | ||
535 | {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, | ||
536 | {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, | ||
537 | {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, | ||
538 | }; | ||
539 | |||
540 | static const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = { | ||
541 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
542 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, | ||
543 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | ||
544 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, | ||
545 | {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, | ||
546 | {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, | ||
547 | {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, | ||
548 | {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, | ||
549 | {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, | ||
550 | {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, | ||
551 | {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, | ||
552 | {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, | ||
553 | {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, | ||
554 | {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, | ||
555 | {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, | ||
556 | {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, | ||
557 | {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, | ||
558 | {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, | ||
559 | {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, | ||
560 | {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, | ||
561 | {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, | ||
562 | {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, | ||
563 | {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, | ||
564 | {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, | ||
565 | {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, | ||
566 | {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, | ||
567 | {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, | ||
568 | {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
569 | {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
570 | {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
571 | {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
572 | {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
573 | {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
574 | {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
575 | {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, | ||
576 | {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, | ||
577 | {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, | ||
578 | {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, | ||
579 | {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, | ||
580 | {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, | ||
581 | {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, | ||
582 | {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, | ||
583 | {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, | ||
584 | {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, | ||
585 | {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, | ||
586 | {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, | ||
587 | {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, | ||
588 | {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, | ||
589 | {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, | ||
590 | {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, | ||
591 | {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, | ||
592 | {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, | ||
593 | {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, | ||
594 | {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, | ||
595 | {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, | ||
596 | {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, | ||
597 | {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, | ||
598 | {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, | ||
599 | {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, | ||
600 | {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
601 | {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
602 | {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
603 | {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
604 | {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
605 | {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
606 | {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
607 | {0x00016044, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4}, | ||
608 | {0x00016048, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266}, | ||
609 | {0x00016444, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4}, | ||
610 | {0x00016448, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266}, | ||
611 | }; | ||
612 | static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = { | ||
613 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
614 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, | ||
615 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | ||
616 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, | ||
617 | {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, | ||
618 | {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, | ||
619 | {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, | ||
620 | {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, | ||
621 | {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, | ||
622 | {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, | ||
623 | {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, | ||
624 | {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, | ||
625 | {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, | ||
626 | {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, | ||
627 | {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, | ||
628 | {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, | ||
629 | {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, | ||
630 | {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, | ||
631 | {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, | ||
632 | {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, | ||
633 | {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, | ||
634 | {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, | ||
635 | {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, | ||
636 | {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, | ||
637 | {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, | ||
638 | {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, | ||
639 | {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, | ||
640 | {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
641 | {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
642 | {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
643 | {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
644 | {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
645 | {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
646 | {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
647 | {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, | ||
648 | {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, | ||
649 | {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, | ||
650 | {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, | ||
651 | {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, | ||
652 | {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, | ||
653 | {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, | ||
654 | {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, | ||
655 | {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, | ||
656 | {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, | ||
657 | {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, | ||
658 | {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, | ||
659 | {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, | ||
660 | {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, | ||
661 | {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, | ||
662 | {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, | ||
663 | {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, | ||
664 | {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, | ||
665 | {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, | ||
666 | {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, | ||
667 | {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, | ||
668 | {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, | ||
669 | {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, | ||
670 | {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, | ||
671 | {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, | ||
672 | {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
673 | {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
674 | {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
675 | {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
676 | {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
677 | {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
678 | {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
679 | {0x00016044, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db}, | ||
680 | {0x00016048, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266}, | ||
681 | {0x00016444, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db}, | ||
682 | {0x00016448, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266}, | ||
683 | }; | ||
684 | |||
685 | |||
686 | static const u32 ar9340Common_rx_gain_table_1p0[][2] = { | ||
687 | /* Addr allmodes */ | ||
688 | {0x0000a000, 0x00010000}, | ||
689 | {0x0000a004, 0x00030002}, | ||
690 | {0x0000a008, 0x00050004}, | ||
691 | {0x0000a00c, 0x00810080}, | ||
692 | {0x0000a010, 0x00830082}, | ||
693 | {0x0000a014, 0x01810180}, | ||
694 | {0x0000a018, 0x01830182}, | ||
695 | {0x0000a01c, 0x01850184}, | ||
696 | {0x0000a020, 0x01890188}, | ||
697 | {0x0000a024, 0x018b018a}, | ||
698 | {0x0000a028, 0x018d018c}, | ||
699 | {0x0000a02c, 0x01910190}, | ||
700 | {0x0000a030, 0x01930192}, | ||
701 | {0x0000a034, 0x01950194}, | ||
702 | {0x0000a038, 0x038a0196}, | ||
703 | {0x0000a03c, 0x038c038b}, | ||
704 | {0x0000a040, 0x0390038d}, | ||
705 | {0x0000a044, 0x03920391}, | ||
706 | {0x0000a048, 0x03940393}, | ||
707 | {0x0000a04c, 0x03960395}, | ||
708 | {0x0000a050, 0x00000000}, | ||
709 | {0x0000a054, 0x00000000}, | ||
710 | {0x0000a058, 0x00000000}, | ||
711 | {0x0000a05c, 0x00000000}, | ||
712 | {0x0000a060, 0x00000000}, | ||
713 | {0x0000a064, 0x00000000}, | ||
714 | {0x0000a068, 0x00000000}, | ||
715 | {0x0000a06c, 0x00000000}, | ||
716 | {0x0000a070, 0x00000000}, | ||
717 | {0x0000a074, 0x00000000}, | ||
718 | {0x0000a078, 0x00000000}, | ||
719 | {0x0000a07c, 0x00000000}, | ||
720 | {0x0000a080, 0x22222229}, | ||
721 | {0x0000a084, 0x1d1d1d1d}, | ||
722 | {0x0000a088, 0x1d1d1d1d}, | ||
723 | {0x0000a08c, 0x1d1d1d1d}, | ||
724 | {0x0000a090, 0x171d1d1d}, | ||
725 | {0x0000a094, 0x11111717}, | ||
726 | {0x0000a098, 0x00030311}, | ||
727 | {0x0000a09c, 0x00000000}, | ||
728 | {0x0000a0a0, 0x00000000}, | ||
729 | {0x0000a0a4, 0x00000000}, | ||
730 | {0x0000a0a8, 0x00000000}, | ||
731 | {0x0000a0ac, 0x00000000}, | ||
732 | {0x0000a0b0, 0x00000000}, | ||
733 | {0x0000a0b4, 0x00000000}, | ||
734 | {0x0000a0b8, 0x00000000}, | ||
735 | {0x0000a0bc, 0x00000000}, | ||
736 | {0x0000a0c0, 0x001f0000}, | ||
737 | {0x0000a0c4, 0x01000101}, | ||
738 | {0x0000a0c8, 0x011e011f}, | ||
739 | {0x0000a0cc, 0x011c011d}, | ||
740 | {0x0000a0d0, 0x02030204}, | ||
741 | {0x0000a0d4, 0x02010202}, | ||
742 | {0x0000a0d8, 0x021f0200}, | ||
743 | {0x0000a0dc, 0x0302021e}, | ||
744 | {0x0000a0e0, 0x03000301}, | ||
745 | {0x0000a0e4, 0x031e031f}, | ||
746 | {0x0000a0e8, 0x0402031d}, | ||
747 | {0x0000a0ec, 0x04000401}, | ||
748 | {0x0000a0f0, 0x041e041f}, | ||
749 | {0x0000a0f4, 0x0502041d}, | ||
750 | {0x0000a0f8, 0x05000501}, | ||
751 | {0x0000a0fc, 0x051e051f}, | ||
752 | {0x0000a100, 0x06010602}, | ||
753 | {0x0000a104, 0x061f0600}, | ||
754 | {0x0000a108, 0x061d061e}, | ||
755 | {0x0000a10c, 0x07020703}, | ||
756 | {0x0000a110, 0x07000701}, | ||
757 | {0x0000a114, 0x00000000}, | ||
758 | {0x0000a118, 0x00000000}, | ||
759 | {0x0000a11c, 0x00000000}, | ||
760 | {0x0000a120, 0x00000000}, | ||
761 | {0x0000a124, 0x00000000}, | ||
762 | {0x0000a128, 0x00000000}, | ||
763 | {0x0000a12c, 0x00000000}, | ||
764 | {0x0000a130, 0x00000000}, | ||
765 | {0x0000a134, 0x00000000}, | ||
766 | {0x0000a138, 0x00000000}, | ||
767 | {0x0000a13c, 0x00000000}, | ||
768 | {0x0000a140, 0x001f0000}, | ||
769 | {0x0000a144, 0x01000101}, | ||
770 | {0x0000a148, 0x011e011f}, | ||
771 | {0x0000a14c, 0x011c011d}, | ||
772 | {0x0000a150, 0x02030204}, | ||
773 | {0x0000a154, 0x02010202}, | ||
774 | {0x0000a158, 0x021f0200}, | ||
775 | {0x0000a15c, 0x0302021e}, | ||
776 | {0x0000a160, 0x03000301}, | ||
777 | {0x0000a164, 0x031e031f}, | ||
778 | {0x0000a168, 0x0402031d}, | ||
779 | {0x0000a16c, 0x04000401}, | ||
780 | {0x0000a170, 0x041e041f}, | ||
781 | {0x0000a174, 0x0502041d}, | ||
782 | {0x0000a178, 0x05000501}, | ||
783 | {0x0000a17c, 0x051e051f}, | ||
784 | {0x0000a180, 0x06010602}, | ||
785 | {0x0000a184, 0x061f0600}, | ||
786 | {0x0000a188, 0x061d061e}, | ||
787 | {0x0000a18c, 0x07020703}, | ||
788 | {0x0000a190, 0x07000701}, | ||
789 | {0x0000a194, 0x00000000}, | ||
790 | {0x0000a198, 0x00000000}, | ||
791 | {0x0000a19c, 0x00000000}, | ||
792 | {0x0000a1a0, 0x00000000}, | ||
793 | {0x0000a1a4, 0x00000000}, | ||
794 | {0x0000a1a8, 0x00000000}, | ||
795 | {0x0000a1ac, 0x00000000}, | ||
796 | {0x0000a1b0, 0x00000000}, | ||
797 | {0x0000a1b4, 0x00000000}, | ||
798 | {0x0000a1b8, 0x00000000}, | ||
799 | {0x0000a1bc, 0x00000000}, | ||
800 | {0x0000a1c0, 0x00000000}, | ||
801 | {0x0000a1c4, 0x00000000}, | ||
802 | {0x0000a1c8, 0x00000000}, | ||
803 | {0x0000a1cc, 0x00000000}, | ||
804 | {0x0000a1d0, 0x00000000}, | ||
805 | {0x0000a1d4, 0x00000000}, | ||
806 | {0x0000a1d8, 0x00000000}, | ||
807 | {0x0000a1dc, 0x00000000}, | ||
808 | {0x0000a1e0, 0x00000000}, | ||
809 | {0x0000a1e4, 0x00000000}, | ||
810 | {0x0000a1e8, 0x00000000}, | ||
811 | {0x0000a1ec, 0x00000000}, | ||
812 | {0x0000a1f0, 0x00000396}, | ||
813 | {0x0000a1f4, 0x00000396}, | ||
814 | {0x0000a1f8, 0x00000396}, | ||
815 | {0x0000a1fc, 0x00000196}, | ||
816 | {0x0000b000, 0x00010000}, | ||
817 | {0x0000b004, 0x00030002}, | ||
818 | {0x0000b008, 0x00050004}, | ||
819 | {0x0000b00c, 0x00810080}, | ||
820 | {0x0000b010, 0x00830082}, | ||
821 | {0x0000b014, 0x01810180}, | ||
822 | {0x0000b018, 0x01830182}, | ||
823 | {0x0000b01c, 0x01850184}, | ||
824 | {0x0000b020, 0x02810280}, | ||
825 | {0x0000b024, 0x02830282}, | ||
826 | {0x0000b028, 0x02850284}, | ||
827 | {0x0000b02c, 0x02890288}, | ||
828 | {0x0000b030, 0x028b028a}, | ||
829 | {0x0000b034, 0x0388028c}, | ||
830 | {0x0000b038, 0x038a0389}, | ||
831 | {0x0000b03c, 0x038c038b}, | ||
832 | {0x0000b040, 0x0390038d}, | ||
833 | {0x0000b044, 0x03920391}, | ||
834 | {0x0000b048, 0x03940393}, | ||
835 | {0x0000b04c, 0x03960395}, | ||
836 | {0x0000b050, 0x00000000}, | ||
837 | {0x0000b054, 0x00000000}, | ||
838 | {0x0000b058, 0x00000000}, | ||
839 | {0x0000b05c, 0x00000000}, | ||
840 | {0x0000b060, 0x00000000}, | ||
841 | {0x0000b064, 0x00000000}, | ||
842 | {0x0000b068, 0x00000000}, | ||
843 | {0x0000b06c, 0x00000000}, | ||
844 | {0x0000b070, 0x00000000}, | ||
845 | {0x0000b074, 0x00000000}, | ||
846 | {0x0000b078, 0x00000000}, | ||
847 | {0x0000b07c, 0x00000000}, | ||
848 | {0x0000b080, 0x32323232}, | ||
849 | {0x0000b084, 0x2f2f3232}, | ||
850 | {0x0000b088, 0x23282a2d}, | ||
851 | {0x0000b08c, 0x1c1e2123}, | ||
852 | {0x0000b090, 0x14171919}, | ||
853 | {0x0000b094, 0x0e0e1214}, | ||
854 | {0x0000b098, 0x03050707}, | ||
855 | {0x0000b09c, 0x00030303}, | ||
856 | {0x0000b0a0, 0x00000000}, | ||
857 | {0x0000b0a4, 0x00000000}, | ||
858 | {0x0000b0a8, 0x00000000}, | ||
859 | {0x0000b0ac, 0x00000000}, | ||
860 | {0x0000b0b0, 0x00000000}, | ||
861 | {0x0000b0b4, 0x00000000}, | ||
862 | {0x0000b0b8, 0x00000000}, | ||
863 | {0x0000b0bc, 0x00000000}, | ||
864 | {0x0000b0c0, 0x003f0020}, | ||
865 | {0x0000b0c4, 0x00400041}, | ||
866 | {0x0000b0c8, 0x0140005f}, | ||
867 | {0x0000b0cc, 0x0160015f}, | ||
868 | {0x0000b0d0, 0x017e017f}, | ||
869 | {0x0000b0d4, 0x02410242}, | ||
870 | {0x0000b0d8, 0x025f0240}, | ||
871 | {0x0000b0dc, 0x027f0260}, | ||
872 | {0x0000b0e0, 0x0341027e}, | ||
873 | {0x0000b0e4, 0x035f0340}, | ||
874 | {0x0000b0e8, 0x037f0360}, | ||
875 | {0x0000b0ec, 0x04400441}, | ||
876 | {0x0000b0f0, 0x0460045f}, | ||
877 | {0x0000b0f4, 0x0541047f}, | ||
878 | {0x0000b0f8, 0x055f0540}, | ||
879 | {0x0000b0fc, 0x057f0560}, | ||
880 | {0x0000b100, 0x06400641}, | ||
881 | {0x0000b104, 0x0660065f}, | ||
882 | {0x0000b108, 0x067e067f}, | ||
883 | {0x0000b10c, 0x07410742}, | ||
884 | {0x0000b110, 0x075f0740}, | ||
885 | {0x0000b114, 0x077f0760}, | ||
886 | {0x0000b118, 0x07800781}, | ||
887 | {0x0000b11c, 0x07a0079f}, | ||
888 | {0x0000b120, 0x07c107bf}, | ||
889 | {0x0000b124, 0x000007c0}, | ||
890 | {0x0000b128, 0x00000000}, | ||
891 | {0x0000b12c, 0x00000000}, | ||
892 | {0x0000b130, 0x00000000}, | ||
893 | {0x0000b134, 0x00000000}, | ||
894 | {0x0000b138, 0x00000000}, | ||
895 | {0x0000b13c, 0x00000000}, | ||
896 | {0x0000b140, 0x003f0020}, | ||
897 | {0x0000b144, 0x00400041}, | ||
898 | {0x0000b148, 0x0140005f}, | ||
899 | {0x0000b14c, 0x0160015f}, | ||
900 | {0x0000b150, 0x017e017f}, | ||
901 | {0x0000b154, 0x02410242}, | ||
902 | {0x0000b158, 0x025f0240}, | ||
903 | {0x0000b15c, 0x027f0260}, | ||
904 | {0x0000b160, 0x0341027e}, | ||
905 | {0x0000b164, 0x035f0340}, | ||
906 | {0x0000b168, 0x037f0360}, | ||
907 | {0x0000b16c, 0x04400441}, | ||
908 | {0x0000b170, 0x0460045f}, | ||
909 | {0x0000b174, 0x0541047f}, | ||
910 | {0x0000b178, 0x055f0540}, | ||
911 | {0x0000b17c, 0x057f0560}, | ||
912 | {0x0000b180, 0x06400641}, | ||
913 | {0x0000b184, 0x0660065f}, | ||
914 | {0x0000b188, 0x067e067f}, | ||
915 | {0x0000b18c, 0x07410742}, | ||
916 | {0x0000b190, 0x075f0740}, | ||
917 | {0x0000b194, 0x077f0760}, | ||
918 | {0x0000b198, 0x07800781}, | ||
919 | {0x0000b19c, 0x07a0079f}, | ||
920 | {0x0000b1a0, 0x07c107bf}, | ||
921 | {0x0000b1a4, 0x000007c0}, | ||
922 | {0x0000b1a8, 0x00000000}, | ||
923 | {0x0000b1ac, 0x00000000}, | ||
924 | {0x0000b1b0, 0x00000000}, | ||
925 | {0x0000b1b4, 0x00000000}, | ||
926 | {0x0000b1b8, 0x00000000}, | ||
927 | {0x0000b1bc, 0x00000000}, | ||
928 | {0x0000b1c0, 0x00000000}, | ||
929 | {0x0000b1c4, 0x00000000}, | ||
930 | {0x0000b1c8, 0x00000000}, | ||
931 | {0x0000b1cc, 0x00000000}, | ||
932 | {0x0000b1d0, 0x00000000}, | ||
933 | {0x0000b1d4, 0x00000000}, | ||
934 | {0x0000b1d8, 0x00000000}, | ||
935 | {0x0000b1dc, 0x00000000}, | ||
936 | {0x0000b1e0, 0x00000000}, | ||
937 | {0x0000b1e4, 0x00000000}, | ||
938 | {0x0000b1e8, 0x00000000}, | ||
939 | {0x0000b1ec, 0x00000000}, | ||
940 | {0x0000b1f0, 0x00000396}, | ||
941 | {0x0000b1f4, 0x00000396}, | ||
942 | {0x0000b1f8, 0x00000396}, | ||
943 | {0x0000b1fc, 0x00000196}, | ||
944 | }; | ||
945 | |||
946 | static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = { | ||
947 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
948 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
949 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
950 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | ||
951 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | ||
952 | {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, | ||
953 | {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, | ||
954 | {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, | ||
955 | {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, | ||
956 | {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, | ||
957 | {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, | ||
958 | {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, | ||
959 | {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, | ||
960 | {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, | ||
961 | {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, | ||
962 | {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, | ||
963 | {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, | ||
964 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, | ||
965 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, | ||
966 | {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, | ||
967 | {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, | ||
968 | {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, | ||
969 | {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, | ||
970 | {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, | ||
971 | {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, | ||
972 | {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, | ||
973 | {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, | ||
974 | {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
975 | {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
976 | {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
977 | {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
978 | {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
979 | {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
980 | {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
981 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | ||
982 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, | ||
983 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, | ||
984 | {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, | ||
985 | {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, | ||
986 | {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, | ||
987 | {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402}, | ||
988 | {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404}, | ||
989 | {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, | ||
990 | {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, | ||
991 | {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, | ||
992 | {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, | ||
993 | {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, | ||
994 | {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, | ||
995 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, | ||
996 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, | ||
997 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, | ||
998 | {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, | ||
999 | {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, | ||
1000 | {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83}, | ||
1001 | {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84}, | ||
1002 | {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3}, | ||
1003 | {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5}, | ||
1004 | {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9}, | ||
1005 | {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb}, | ||
1006 | {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1007 | {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1008 | {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1009 | {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1010 | {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1011 | {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1012 | {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1013 | {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, | ||
1014 | {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, | ||
1015 | {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, | ||
1016 | {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, | ||
1017 | }; | ||
1018 | |||
1019 | static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = { | ||
1020 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1021 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
1022 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1023 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | ||
1024 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | ||
1025 | {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, | ||
1026 | {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, | ||
1027 | {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400}, | ||
1028 | {0x0000a518, 0x21020220, 0x21020220, 0x15000402, 0x15000402}, | ||
1029 | {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, | ||
1030 | {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000603, 0x1b000603}, | ||
1031 | {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000a02, 0x1f000a02}, | ||
1032 | {0x0000a528, 0x34022225, 0x34022225, 0x23000a04, 0x23000a04}, | ||
1033 | {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x26000a20, 0x26000a20}, | ||
1034 | {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2a000e20, 0x2a000e20}, | ||
1035 | {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22}, | ||
1036 | {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24}, | ||
1037 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640}, | ||
1038 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660}, | ||
1039 | {0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861}, | ||
1040 | {0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81}, | ||
1041 | {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x42001a83, 0x42001a83}, | ||
1042 | {0x0000a550, 0x61042a6c, 0x61042a6c, 0x44001c84, 0x44001c84}, | ||
1043 | {0x0000a554, 0x66062a6c, 0x66062a6c, 0x48001ce3, 0x48001ce3}, | ||
1044 | {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x4c001ce5, 0x4c001ce5}, | ||
1045 | {0x0000a55c, 0x7006308c, 0x7006308c, 0x50001ce9, 0x50001ce9}, | ||
1046 | {0x0000a560, 0x730a308a, 0x730a308a, 0x54001ceb, 0x54001ceb}, | ||
1047 | {0x0000a564, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, | ||
1048 | {0x0000a568, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, | ||
1049 | {0x0000a56c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, | ||
1050 | {0x0000a570, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, | ||
1051 | {0x0000a574, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, | ||
1052 | {0x0000a578, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, | ||
1053 | {0x0000a57c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, | ||
1054 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | ||
1055 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, | ||
1056 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, | ||
1057 | {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, | ||
1058 | {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, | ||
1059 | {0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400}, | ||
1060 | {0x0000a598, 0x21820220, 0x21820220, 0x15800402, 0x15800402}, | ||
1061 | {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404}, | ||
1062 | {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603}, | ||
1063 | {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02}, | ||
1064 | {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04}, | ||
1065 | {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20}, | ||
1066 | {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20}, | ||
1067 | {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22}, | ||
1068 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24}, | ||
1069 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640}, | ||
1070 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660}, | ||
1071 | {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b801861, 0x3b801861}, | ||
1072 | {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e801a81, 0x3e801a81}, | ||
1073 | {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42801a83, 0x42801a83}, | ||
1074 | {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x44801c84, 0x44801c84}, | ||
1075 | {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x48801ce3, 0x48801ce3}, | ||
1076 | {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c801ce5, 0x4c801ce5}, | ||
1077 | {0x0000a5dc, 0x7086308c, 0x7086308c, 0x50801ce9, 0x50801ce9}, | ||
1078 | {0x0000a5e0, 0x738a308a, 0x738a308a, 0x54801ceb, 0x54801ceb}, | ||
1079 | {0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, | ||
1080 | {0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, | ||
1081 | {0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, | ||
1082 | {0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, | ||
1083 | {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, | ||
1084 | {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, | ||
1085 | {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, | ||
1086 | {0x00016044, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4}, | ||
1087 | {0x00016048, 0x24927266, 0x24927266, 0x8e483266, 0x8e483266}, | ||
1088 | {0x00016444, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4}, | ||
1089 | {0x00016448, 0x24927266, 0x24927266, 0x8e482266, 0x8e482266}, | ||
1090 | }; | ||
1091 | |||
1092 | static const u32 ar9340_1p0_mac_core[][2] = { | ||
1093 | /* Addr allmodes */ | ||
1094 | {0x00000008, 0x00000000}, | ||
1095 | {0x00000030, 0x00020085}, | ||
1096 | {0x00000034, 0x00000005}, | ||
1097 | {0x00000040, 0x00000000}, | ||
1098 | {0x00000044, 0x00000000}, | ||
1099 | {0x00000048, 0x00000008}, | ||
1100 | {0x0000004c, 0x00000010}, | ||
1101 | {0x00000050, 0x00000000}, | ||
1102 | {0x00001040, 0x002ffc0f}, | ||
1103 | {0x00001044, 0x002ffc0f}, | ||
1104 | {0x00001048, 0x002ffc0f}, | ||
1105 | {0x0000104c, 0x002ffc0f}, | ||
1106 | {0x00001050, 0x002ffc0f}, | ||
1107 | {0x00001054, 0x002ffc0f}, | ||
1108 | {0x00001058, 0x002ffc0f}, | ||
1109 | {0x0000105c, 0x002ffc0f}, | ||
1110 | {0x00001060, 0x002ffc0f}, | ||
1111 | {0x00001064, 0x002ffc0f}, | ||
1112 | {0x000010f0, 0x00000100}, | ||
1113 | {0x00001270, 0x00000000}, | ||
1114 | {0x000012b0, 0x00000000}, | ||
1115 | {0x000012f0, 0x00000000}, | ||
1116 | {0x0000143c, 0x00000000}, | ||
1117 | {0x0000147c, 0x00000000}, | ||
1118 | {0x00008000, 0x00000000}, | ||
1119 | {0x00008004, 0x00000000}, | ||
1120 | {0x00008008, 0x00000000}, | ||
1121 | {0x0000800c, 0x00000000}, | ||
1122 | {0x00008018, 0x00000000}, | ||
1123 | {0x00008020, 0x00000000}, | ||
1124 | {0x00008038, 0x00000000}, | ||
1125 | {0x0000803c, 0x00000000}, | ||
1126 | {0x00008040, 0x00000000}, | ||
1127 | {0x00008044, 0x00000000}, | ||
1128 | {0x00008048, 0x00000000}, | ||
1129 | {0x0000804c, 0xffffffff}, | ||
1130 | {0x00008054, 0x00000000}, | ||
1131 | {0x00008058, 0x00000000}, | ||
1132 | {0x0000805c, 0x000fc78f}, | ||
1133 | {0x00008060, 0x0000000f}, | ||
1134 | {0x00008064, 0x00000000}, | ||
1135 | {0x00008070, 0x00000310}, | ||
1136 | {0x00008074, 0x00000020}, | ||
1137 | {0x00008078, 0x00000000}, | ||
1138 | {0x0000809c, 0x0000000f}, | ||
1139 | {0x000080a0, 0x00000000}, | ||
1140 | {0x000080a4, 0x02ff0000}, | ||
1141 | {0x000080a8, 0x0e070605}, | ||
1142 | {0x000080ac, 0x0000000d}, | ||
1143 | {0x000080b0, 0x00000000}, | ||
1144 | {0x000080b4, 0x00000000}, | ||
1145 | {0x000080b8, 0x00000000}, | ||
1146 | {0x000080bc, 0x00000000}, | ||
1147 | {0x000080c0, 0x2a800000}, | ||
1148 | {0x000080c4, 0x06900168}, | ||
1149 | {0x000080c8, 0x13881c20}, | ||
1150 | {0x000080cc, 0x01f40000}, | ||
1151 | {0x000080d0, 0x00252500}, | ||
1152 | {0x000080d4, 0x00a00000}, | ||
1153 | {0x000080d8, 0x00400000}, | ||
1154 | {0x000080dc, 0x00000000}, | ||
1155 | {0x000080e0, 0xffffffff}, | ||
1156 | {0x000080e4, 0x0000ffff}, | ||
1157 | {0x000080e8, 0x3f3f3f3f}, | ||
1158 | {0x000080ec, 0x00000000}, | ||
1159 | {0x000080f0, 0x00000000}, | ||
1160 | {0x000080f4, 0x00000000}, | ||
1161 | {0x000080fc, 0x00020000}, | ||
1162 | {0x00008100, 0x00000000}, | ||
1163 | {0x00008108, 0x00000052}, | ||
1164 | {0x0000810c, 0x00000000}, | ||
1165 | {0x00008110, 0x00000000}, | ||
1166 | {0x00008114, 0x000007ff}, | ||
1167 | {0x00008118, 0x000000aa}, | ||
1168 | {0x0000811c, 0x00003210}, | ||
1169 | {0x00008124, 0x00000000}, | ||
1170 | {0x00008128, 0x00000000}, | ||
1171 | {0x0000812c, 0x00000000}, | ||
1172 | {0x00008130, 0x00000000}, | ||
1173 | {0x00008134, 0x00000000}, | ||
1174 | {0x00008138, 0x00000000}, | ||
1175 | {0x0000813c, 0x0000ffff}, | ||
1176 | {0x00008144, 0xffffffff}, | ||
1177 | {0x00008168, 0x00000000}, | ||
1178 | {0x0000816c, 0x00000000}, | ||
1179 | {0x00008170, 0x18486200}, | ||
1180 | {0x00008174, 0x33332210}, | ||
1181 | {0x00008178, 0x00000000}, | ||
1182 | {0x0000817c, 0x00020000}, | ||
1183 | {0x000081c0, 0x00000000}, | ||
1184 | {0x000081c4, 0x33332210}, | ||
1185 | {0x000081c8, 0x00000000}, | ||
1186 | {0x000081cc, 0x00000000}, | ||
1187 | {0x000081d4, 0x00000000}, | ||
1188 | {0x000081ec, 0x00000000}, | ||
1189 | {0x000081f0, 0x00000000}, | ||
1190 | {0x000081f4, 0x00000000}, | ||
1191 | {0x000081f8, 0x00000000}, | ||
1192 | {0x000081fc, 0x00000000}, | ||
1193 | {0x00008240, 0x00100000}, | ||
1194 | {0x00008244, 0x0010f424}, | ||
1195 | {0x00008248, 0x00000800}, | ||
1196 | {0x0000824c, 0x0001e848}, | ||
1197 | {0x00008250, 0x00000000}, | ||
1198 | {0x00008254, 0x00000000}, | ||
1199 | {0x00008258, 0x00000000}, | ||
1200 | {0x0000825c, 0x40000000}, | ||
1201 | {0x00008260, 0x00080922}, | ||
1202 | {0x00008264, 0x9d400010}, | ||
1203 | {0x00008268, 0xffffffff}, | ||
1204 | {0x0000826c, 0x0000ffff}, | ||
1205 | {0x00008270, 0x00000000}, | ||
1206 | {0x00008274, 0x40000000}, | ||
1207 | {0x00008278, 0x003e4180}, | ||
1208 | {0x0000827c, 0x00000004}, | ||
1209 | {0x00008284, 0x0000002c}, | ||
1210 | {0x00008288, 0x0000002c}, | ||
1211 | {0x0000828c, 0x000000ff}, | ||
1212 | {0x00008294, 0x00000000}, | ||
1213 | {0x00008298, 0x00000000}, | ||
1214 | {0x0000829c, 0x00000000}, | ||
1215 | {0x00008300, 0x00000140}, | ||
1216 | {0x00008314, 0x00000000}, | ||
1217 | {0x0000831c, 0x0000010d}, | ||
1218 | {0x00008328, 0x00000000}, | ||
1219 | {0x0000832c, 0x00000007}, | ||
1220 | {0x00008330, 0x00000302}, | ||
1221 | {0x00008334, 0x00000700}, | ||
1222 | {0x00008338, 0x00ff0000}, | ||
1223 | {0x0000833c, 0x02400000}, | ||
1224 | {0x00008340, 0x000107ff}, | ||
1225 | {0x00008344, 0xaa48105b}, | ||
1226 | {0x00008348, 0x008f0000}, | ||
1227 | {0x0000835c, 0x00000000}, | ||
1228 | {0x00008360, 0xffffffff}, | ||
1229 | {0x00008364, 0xffffffff}, | ||
1230 | {0x00008368, 0x00000000}, | ||
1231 | {0x00008370, 0x00000000}, | ||
1232 | {0x00008374, 0x000000ff}, | ||
1233 | {0x00008378, 0x00000000}, | ||
1234 | {0x0000837c, 0x00000000}, | ||
1235 | {0x00008380, 0xffffffff}, | ||
1236 | {0x00008384, 0xffffffff}, | ||
1237 | {0x00008390, 0xffffffff}, | ||
1238 | {0x00008394, 0xffffffff}, | ||
1239 | {0x00008398, 0x00000000}, | ||
1240 | {0x0000839c, 0x00000000}, | ||
1241 | {0x000083a0, 0x00000000}, | ||
1242 | {0x000083a4, 0x0000fa14}, | ||
1243 | {0x000083a8, 0x000f0c00}, | ||
1244 | {0x000083ac, 0x33332210}, | ||
1245 | {0x000083b0, 0x33332210}, | ||
1246 | {0x000083b4, 0x33332210}, | ||
1247 | {0x000083b8, 0x33332210}, | ||
1248 | {0x000083bc, 0x00000000}, | ||
1249 | {0x000083c0, 0x00000000}, | ||
1250 | {0x000083c4, 0x00000000}, | ||
1251 | {0x000083c8, 0x00000000}, | ||
1252 | {0x000083cc, 0x00000200}, | ||
1253 | {0x000083d0, 0x000301ff}, | ||
1254 | }; | ||
1255 | |||
1256 | static const u32 ar9340Common_wo_xlna_rx_gain_table_1p0[][2] = { | ||
1257 | /* Addr allmodes */ | ||
1258 | {0x0000a000, 0x00010000}, | ||
1259 | {0x0000a004, 0x00030002}, | ||
1260 | {0x0000a008, 0x00050004}, | ||
1261 | {0x0000a00c, 0x00810080}, | ||
1262 | {0x0000a010, 0x00830082}, | ||
1263 | {0x0000a014, 0x01810180}, | ||
1264 | {0x0000a018, 0x01830182}, | ||
1265 | {0x0000a01c, 0x01850184}, | ||
1266 | {0x0000a020, 0x01890188}, | ||
1267 | {0x0000a024, 0x018b018a}, | ||
1268 | {0x0000a028, 0x018d018c}, | ||
1269 | {0x0000a02c, 0x03820190}, | ||
1270 | {0x0000a030, 0x03840383}, | ||
1271 | {0x0000a034, 0x03880385}, | ||
1272 | {0x0000a038, 0x038a0389}, | ||
1273 | {0x0000a03c, 0x038c038b}, | ||
1274 | {0x0000a040, 0x0390038d}, | ||
1275 | {0x0000a044, 0x03920391}, | ||
1276 | {0x0000a048, 0x03940393}, | ||
1277 | {0x0000a04c, 0x03960395}, | ||
1278 | {0x0000a050, 0x00000000}, | ||
1279 | {0x0000a054, 0x00000000}, | ||
1280 | {0x0000a058, 0x00000000}, | ||
1281 | {0x0000a05c, 0x00000000}, | ||
1282 | {0x0000a060, 0x00000000}, | ||
1283 | {0x0000a064, 0x00000000}, | ||
1284 | {0x0000a068, 0x00000000}, | ||
1285 | {0x0000a06c, 0x00000000}, | ||
1286 | {0x0000a070, 0x00000000}, | ||
1287 | {0x0000a074, 0x00000000}, | ||
1288 | {0x0000a078, 0x00000000}, | ||
1289 | {0x0000a07c, 0x00000000}, | ||
1290 | {0x0000a080, 0x29292929}, | ||
1291 | {0x0000a084, 0x29292929}, | ||
1292 | {0x0000a088, 0x29292929}, | ||
1293 | {0x0000a08c, 0x29292929}, | ||
1294 | {0x0000a090, 0x22292929}, | ||
1295 | {0x0000a094, 0x1d1d2222}, | ||
1296 | {0x0000a098, 0x0c111117}, | ||
1297 | {0x0000a09c, 0x00030303}, | ||
1298 | {0x0000a0a0, 0x00000000}, | ||
1299 | {0x0000a0a4, 0x00000000}, | ||
1300 | {0x0000a0a8, 0x00000000}, | ||
1301 | {0x0000a0ac, 0x00000000}, | ||
1302 | {0x0000a0b0, 0x00000000}, | ||
1303 | {0x0000a0b4, 0x00000000}, | ||
1304 | {0x0000a0b8, 0x00000000}, | ||
1305 | {0x0000a0bc, 0x00000000}, | ||
1306 | {0x0000a0c0, 0x001f0000}, | ||
1307 | {0x0000a0c4, 0x01000101}, | ||
1308 | {0x0000a0c8, 0x011e011f}, | ||
1309 | {0x0000a0cc, 0x011c011d}, | ||
1310 | {0x0000a0d0, 0x02030204}, | ||
1311 | {0x0000a0d4, 0x02010202}, | ||
1312 | {0x0000a0d8, 0x021f0200}, | ||
1313 | {0x0000a0dc, 0x0302021e}, | ||
1314 | {0x0000a0e0, 0x03000301}, | ||
1315 | {0x0000a0e4, 0x031e031f}, | ||
1316 | {0x0000a0e8, 0x0402031d}, | ||
1317 | {0x0000a0ec, 0x04000401}, | ||
1318 | {0x0000a0f0, 0x041e041f}, | ||
1319 | {0x0000a0f4, 0x0502041d}, | ||
1320 | {0x0000a0f8, 0x05000501}, | ||
1321 | {0x0000a0fc, 0x051e051f}, | ||
1322 | {0x0000a100, 0x06010602}, | ||
1323 | {0x0000a104, 0x061f0600}, | ||
1324 | {0x0000a108, 0x061d061e}, | ||
1325 | {0x0000a10c, 0x07020703}, | ||
1326 | {0x0000a110, 0x07000701}, | ||
1327 | {0x0000a114, 0x00000000}, | ||
1328 | {0x0000a118, 0x00000000}, | ||
1329 | {0x0000a11c, 0x00000000}, | ||
1330 | {0x0000a120, 0x00000000}, | ||
1331 | {0x0000a124, 0x00000000}, | ||
1332 | {0x0000a128, 0x00000000}, | ||
1333 | {0x0000a12c, 0x00000000}, | ||
1334 | {0x0000a130, 0x00000000}, | ||
1335 | {0x0000a134, 0x00000000}, | ||
1336 | {0x0000a138, 0x00000000}, | ||
1337 | {0x0000a13c, 0x00000000}, | ||
1338 | {0x0000a140, 0x001f0000}, | ||
1339 | {0x0000a144, 0x01000101}, | ||
1340 | {0x0000a148, 0x011e011f}, | ||
1341 | {0x0000a14c, 0x011c011d}, | ||
1342 | {0x0000a150, 0x02030204}, | ||
1343 | {0x0000a154, 0x02010202}, | ||
1344 | {0x0000a158, 0x021f0200}, | ||
1345 | {0x0000a15c, 0x0302021e}, | ||
1346 | {0x0000a160, 0x03000301}, | ||
1347 | {0x0000a164, 0x031e031f}, | ||
1348 | {0x0000a168, 0x0402031d}, | ||
1349 | {0x0000a16c, 0x04000401}, | ||
1350 | {0x0000a170, 0x041e041f}, | ||
1351 | {0x0000a174, 0x0502041d}, | ||
1352 | {0x0000a178, 0x05000501}, | ||
1353 | {0x0000a17c, 0x051e051f}, | ||
1354 | {0x0000a180, 0x06010602}, | ||
1355 | {0x0000a184, 0x061f0600}, | ||
1356 | {0x0000a188, 0x061d061e}, | ||
1357 | {0x0000a18c, 0x07020703}, | ||
1358 | {0x0000a190, 0x07000701}, | ||
1359 | {0x0000a194, 0x00000000}, | ||
1360 | {0x0000a198, 0x00000000}, | ||
1361 | {0x0000a19c, 0x00000000}, | ||
1362 | {0x0000a1a0, 0x00000000}, | ||
1363 | {0x0000a1a4, 0x00000000}, | ||
1364 | {0x0000a1a8, 0x00000000}, | ||
1365 | {0x0000a1ac, 0x00000000}, | ||
1366 | {0x0000a1b0, 0x00000000}, | ||
1367 | {0x0000a1b4, 0x00000000}, | ||
1368 | {0x0000a1b8, 0x00000000}, | ||
1369 | {0x0000a1bc, 0x00000000}, | ||
1370 | {0x0000a1c0, 0x00000000}, | ||
1371 | {0x0000a1c4, 0x00000000}, | ||
1372 | {0x0000a1c8, 0x00000000}, | ||
1373 | {0x0000a1cc, 0x00000000}, | ||
1374 | {0x0000a1d0, 0x00000000}, | ||
1375 | {0x0000a1d4, 0x00000000}, | ||
1376 | {0x0000a1d8, 0x00000000}, | ||
1377 | {0x0000a1dc, 0x00000000}, | ||
1378 | {0x0000a1e0, 0x00000000}, | ||
1379 | {0x0000a1e4, 0x00000000}, | ||
1380 | {0x0000a1e8, 0x00000000}, | ||
1381 | {0x0000a1ec, 0x00000000}, | ||
1382 | {0x0000a1f0, 0x00000396}, | ||
1383 | {0x0000a1f4, 0x00000396}, | ||
1384 | {0x0000a1f8, 0x00000396}, | ||
1385 | {0x0000a1fc, 0x00000196}, | ||
1386 | {0x0000b000, 0x00010000}, | ||
1387 | {0x0000b004, 0x00030002}, | ||
1388 | {0x0000b008, 0x00050004}, | ||
1389 | {0x0000b00c, 0x00810080}, | ||
1390 | {0x0000b010, 0x00830082}, | ||
1391 | {0x0000b014, 0x01810180}, | ||
1392 | {0x0000b018, 0x01830182}, | ||
1393 | {0x0000b01c, 0x01850184}, | ||
1394 | {0x0000b020, 0x02810280}, | ||
1395 | {0x0000b024, 0x02830282}, | ||
1396 | {0x0000b028, 0x02850284}, | ||
1397 | {0x0000b02c, 0x02890288}, | ||
1398 | {0x0000b030, 0x028b028a}, | ||
1399 | {0x0000b034, 0x0388028c}, | ||
1400 | {0x0000b038, 0x038a0389}, | ||
1401 | {0x0000b03c, 0x038c038b}, | ||
1402 | {0x0000b040, 0x0390038d}, | ||
1403 | {0x0000b044, 0x03920391}, | ||
1404 | {0x0000b048, 0x03940393}, | ||
1405 | {0x0000b04c, 0x03960395}, | ||
1406 | {0x0000b050, 0x00000000}, | ||
1407 | {0x0000b054, 0x00000000}, | ||
1408 | {0x0000b058, 0x00000000}, | ||
1409 | {0x0000b05c, 0x00000000}, | ||
1410 | {0x0000b060, 0x00000000}, | ||
1411 | {0x0000b064, 0x00000000}, | ||
1412 | {0x0000b068, 0x00000000}, | ||
1413 | {0x0000b06c, 0x00000000}, | ||
1414 | {0x0000b070, 0x00000000}, | ||
1415 | {0x0000b074, 0x00000000}, | ||
1416 | {0x0000b078, 0x00000000}, | ||
1417 | {0x0000b07c, 0x00000000}, | ||
1418 | {0x0000b080, 0x32323232}, | ||
1419 | {0x0000b084, 0x2f2f3232}, | ||
1420 | {0x0000b088, 0x23282a2d}, | ||
1421 | {0x0000b08c, 0x1c1e2123}, | ||
1422 | {0x0000b090, 0x14171919}, | ||
1423 | {0x0000b094, 0x0e0e1214}, | ||
1424 | {0x0000b098, 0x03050707}, | ||
1425 | {0x0000b09c, 0x00030303}, | ||
1426 | {0x0000b0a0, 0x00000000}, | ||
1427 | {0x0000b0a4, 0x00000000}, | ||
1428 | {0x0000b0a8, 0x00000000}, | ||
1429 | {0x0000b0ac, 0x00000000}, | ||
1430 | {0x0000b0b0, 0x00000000}, | ||
1431 | {0x0000b0b4, 0x00000000}, | ||
1432 | {0x0000b0b8, 0x00000000}, | ||
1433 | {0x0000b0bc, 0x00000000}, | ||
1434 | {0x0000b0c0, 0x003f0020}, | ||
1435 | {0x0000b0c4, 0x00400041}, | ||
1436 | {0x0000b0c8, 0x0140005f}, | ||
1437 | {0x0000b0cc, 0x0160015f}, | ||
1438 | {0x0000b0d0, 0x017e017f}, | ||
1439 | {0x0000b0d4, 0x02410242}, | ||
1440 | {0x0000b0d8, 0x025f0240}, | ||
1441 | {0x0000b0dc, 0x027f0260}, | ||
1442 | {0x0000b0e0, 0x0341027e}, | ||
1443 | {0x0000b0e4, 0x035f0340}, | ||
1444 | {0x0000b0e8, 0x037f0360}, | ||
1445 | {0x0000b0ec, 0x04400441}, | ||
1446 | {0x0000b0f0, 0x0460045f}, | ||
1447 | {0x0000b0f4, 0x0541047f}, | ||
1448 | {0x0000b0f8, 0x055f0540}, | ||
1449 | {0x0000b0fc, 0x057f0560}, | ||
1450 | {0x0000b100, 0x06400641}, | ||
1451 | {0x0000b104, 0x0660065f}, | ||
1452 | {0x0000b108, 0x067e067f}, | ||
1453 | {0x0000b10c, 0x07410742}, | ||
1454 | {0x0000b110, 0x075f0740}, | ||
1455 | {0x0000b114, 0x077f0760}, | ||
1456 | {0x0000b118, 0x07800781}, | ||
1457 | {0x0000b11c, 0x07a0079f}, | ||
1458 | {0x0000b120, 0x07c107bf}, | ||
1459 | {0x0000b124, 0x000007c0}, | ||
1460 | {0x0000b128, 0x00000000}, | ||
1461 | {0x0000b12c, 0x00000000}, | ||
1462 | {0x0000b130, 0x00000000}, | ||
1463 | {0x0000b134, 0x00000000}, | ||
1464 | {0x0000b138, 0x00000000}, | ||
1465 | {0x0000b13c, 0x00000000}, | ||
1466 | {0x0000b140, 0x003f0020}, | ||
1467 | {0x0000b144, 0x00400041}, | ||
1468 | {0x0000b148, 0x0140005f}, | ||
1469 | {0x0000b14c, 0x0160015f}, | ||
1470 | {0x0000b150, 0x017e017f}, | ||
1471 | {0x0000b154, 0x02410242}, | ||
1472 | {0x0000b158, 0x025f0240}, | ||
1473 | {0x0000b15c, 0x027f0260}, | ||
1474 | {0x0000b160, 0x0341027e}, | ||
1475 | {0x0000b164, 0x035f0340}, | ||
1476 | {0x0000b168, 0x037f0360}, | ||
1477 | {0x0000b16c, 0x04400441}, | ||
1478 | {0x0000b170, 0x0460045f}, | ||
1479 | {0x0000b174, 0x0541047f}, | ||
1480 | {0x0000b178, 0x055f0540}, | ||
1481 | {0x0000b17c, 0x057f0560}, | ||
1482 | {0x0000b180, 0x06400641}, | ||
1483 | {0x0000b184, 0x0660065f}, | ||
1484 | {0x0000b188, 0x067e067f}, | ||
1485 | {0x0000b18c, 0x07410742}, | ||
1486 | {0x0000b190, 0x075f0740}, | ||
1487 | {0x0000b194, 0x077f0760}, | ||
1488 | {0x0000b198, 0x07800781}, | ||
1489 | {0x0000b19c, 0x07a0079f}, | ||
1490 | {0x0000b1a0, 0x07c107bf}, | ||
1491 | {0x0000b1a4, 0x000007c0}, | ||
1492 | {0x0000b1a8, 0x00000000}, | ||
1493 | {0x0000b1ac, 0x00000000}, | ||
1494 | {0x0000b1b0, 0x00000000}, | ||
1495 | {0x0000b1b4, 0x00000000}, | ||
1496 | {0x0000b1b8, 0x00000000}, | ||
1497 | {0x0000b1bc, 0x00000000}, | ||
1498 | {0x0000b1c0, 0x00000000}, | ||
1499 | {0x0000b1c4, 0x00000000}, | ||
1500 | {0x0000b1c8, 0x00000000}, | ||
1501 | {0x0000b1cc, 0x00000000}, | ||
1502 | {0x0000b1d0, 0x00000000}, | ||
1503 | {0x0000b1d4, 0x00000000}, | ||
1504 | {0x0000b1d8, 0x00000000}, | ||
1505 | {0x0000b1dc, 0x00000000}, | ||
1506 | {0x0000b1e0, 0x00000000}, | ||
1507 | {0x0000b1e4, 0x00000000}, | ||
1508 | {0x0000b1e8, 0x00000000}, | ||
1509 | {0x0000b1ec, 0x00000000}, | ||
1510 | {0x0000b1f0, 0x00000396}, | ||
1511 | {0x0000b1f4, 0x00000396}, | ||
1512 | {0x0000b1f8, 0x00000396}, | ||
1513 | {0x0000b1fc, 0x00000196}, | ||
1514 | }; | ||
1515 | |||
1516 | static const u32 ar9340_1p0_soc_preamble[][2] = { | ||
1517 | /* Addr allmodes */ | ||
1518 | {0x000040a4, 0x00a0c1c9}, | ||
1519 | {0x00007008, 0x00000000}, | ||
1520 | {0x00007020, 0x00000000}, | ||
1521 | {0x00007034, 0x00000002}, | ||
1522 | {0x00007038, 0x000004c2}, | ||
1523 | }; | ||
1524 | |||
1525 | #endif | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index 71cc0a3a29f..fbdde29f0ab 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h | |||
@@ -17,931 +17,6 @@ | |||
17 | #ifndef INITVALS_9485_H | 17 | #ifndef INITVALS_9485_H |
18 | #define INITVALS_9485_H | 18 | #define INITVALS_9485_H |
19 | 19 | ||
20 | static const u32 ar9485Common_1_0[][2] = { | ||
21 | /* Addr allmodes */ | ||
22 | {0x00007010, 0x00000022}, | ||
23 | {0x00007020, 0x00000000}, | ||
24 | {0x00007034, 0x00000002}, | ||
25 | {0x00007038, 0x000004c2}, | ||
26 | }; | ||
27 | |||
28 | static const u32 ar9485_1_0_mac_postamble[][5] = { | ||
29 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
30 | {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, | ||
31 | {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, | ||
32 | {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, | ||
33 | {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, | ||
34 | {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, | ||
35 | {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, | ||
36 | {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, | ||
37 | {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, | ||
38 | }; | ||
39 | |||
40 | static const u32 ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1[][2] = { | ||
41 | /* Addr allmodes */ | ||
42 | {0x00018c00, 0x10212e5e}, | ||
43 | {0x00018c04, 0x000801d8}, | ||
44 | {0x00018c08, 0x0000580c}, | ||
45 | }; | ||
46 | |||
47 | static const u32 ar9485Common_wo_xlna_rx_gain_1_0[][2] = { | ||
48 | /* Addr allmodes */ | ||
49 | {0x0000a000, 0x00010000}, | ||
50 | {0x0000a004, 0x00030002}, | ||
51 | {0x0000a008, 0x00050004}, | ||
52 | {0x0000a00c, 0x00810080}, | ||
53 | {0x0000a010, 0x01800082}, | ||
54 | {0x0000a014, 0x01820181}, | ||
55 | {0x0000a018, 0x01840183}, | ||
56 | {0x0000a01c, 0x01880185}, | ||
57 | {0x0000a020, 0x018a0189}, | ||
58 | {0x0000a024, 0x02850284}, | ||
59 | {0x0000a028, 0x02890288}, | ||
60 | {0x0000a02c, 0x03850384}, | ||
61 | {0x0000a030, 0x03890388}, | ||
62 | {0x0000a034, 0x038b038a}, | ||
63 | {0x0000a038, 0x038d038c}, | ||
64 | {0x0000a03c, 0x03910390}, | ||
65 | {0x0000a040, 0x03930392}, | ||
66 | {0x0000a044, 0x03950394}, | ||
67 | {0x0000a048, 0x00000396}, | ||
68 | {0x0000a04c, 0x00000000}, | ||
69 | {0x0000a050, 0x00000000}, | ||
70 | {0x0000a054, 0x00000000}, | ||
71 | {0x0000a058, 0x00000000}, | ||
72 | {0x0000a05c, 0x00000000}, | ||
73 | {0x0000a060, 0x00000000}, | ||
74 | {0x0000a064, 0x00000000}, | ||
75 | {0x0000a068, 0x00000000}, | ||
76 | {0x0000a06c, 0x00000000}, | ||
77 | {0x0000a070, 0x00000000}, | ||
78 | {0x0000a074, 0x00000000}, | ||
79 | {0x0000a078, 0x00000000}, | ||
80 | {0x0000a07c, 0x00000000}, | ||
81 | {0x0000a080, 0x28282828}, | ||
82 | {0x0000a084, 0x28282828}, | ||
83 | {0x0000a088, 0x28282828}, | ||
84 | {0x0000a08c, 0x28282828}, | ||
85 | {0x0000a090, 0x28282828}, | ||
86 | {0x0000a094, 0x21212128}, | ||
87 | {0x0000a098, 0x171c1c1c}, | ||
88 | {0x0000a09c, 0x02020212}, | ||
89 | {0x0000a0a0, 0x00000202}, | ||
90 | {0x0000a0a4, 0x00000000}, | ||
91 | {0x0000a0a8, 0x00000000}, | ||
92 | {0x0000a0ac, 0x00000000}, | ||
93 | {0x0000a0b0, 0x00000000}, | ||
94 | {0x0000a0b4, 0x00000000}, | ||
95 | {0x0000a0b8, 0x00000000}, | ||
96 | {0x0000a0bc, 0x00000000}, | ||
97 | {0x0000a0c0, 0x001f0000}, | ||
98 | {0x0000a0c4, 0x111f1100}, | ||
99 | {0x0000a0c8, 0x111d111e}, | ||
100 | {0x0000a0cc, 0x111b111c}, | ||
101 | {0x0000a0d0, 0x22032204}, | ||
102 | {0x0000a0d4, 0x22012202}, | ||
103 | {0x0000a0d8, 0x221f2200}, | ||
104 | {0x0000a0dc, 0x221d221e}, | ||
105 | {0x0000a0e0, 0x33013302}, | ||
106 | {0x0000a0e4, 0x331f3300}, | ||
107 | {0x0000a0e8, 0x4402331e}, | ||
108 | {0x0000a0ec, 0x44004401}, | ||
109 | {0x0000a0f0, 0x441e441f}, | ||
110 | {0x0000a0f4, 0x55015502}, | ||
111 | {0x0000a0f8, 0x551f5500}, | ||
112 | {0x0000a0fc, 0x6602551e}, | ||
113 | {0x0000a100, 0x66006601}, | ||
114 | {0x0000a104, 0x661e661f}, | ||
115 | {0x0000a108, 0x7703661d}, | ||
116 | {0x0000a10c, 0x77017702}, | ||
117 | {0x0000a110, 0x00007700}, | ||
118 | {0x0000a114, 0x00000000}, | ||
119 | {0x0000a118, 0x00000000}, | ||
120 | {0x0000a11c, 0x00000000}, | ||
121 | {0x0000a120, 0x00000000}, | ||
122 | {0x0000a124, 0x00000000}, | ||
123 | {0x0000a128, 0x00000000}, | ||
124 | {0x0000a12c, 0x00000000}, | ||
125 | {0x0000a130, 0x00000000}, | ||
126 | {0x0000a134, 0x00000000}, | ||
127 | {0x0000a138, 0x00000000}, | ||
128 | {0x0000a13c, 0x00000000}, | ||
129 | {0x0000a140, 0x001f0000}, | ||
130 | {0x0000a144, 0x111f1100}, | ||
131 | {0x0000a148, 0x111d111e}, | ||
132 | {0x0000a14c, 0x111b111c}, | ||
133 | {0x0000a150, 0x22032204}, | ||
134 | {0x0000a154, 0x22012202}, | ||
135 | {0x0000a158, 0x221f2200}, | ||
136 | {0x0000a15c, 0x221d221e}, | ||
137 | {0x0000a160, 0x33013302}, | ||
138 | {0x0000a164, 0x331f3300}, | ||
139 | {0x0000a168, 0x4402331e}, | ||
140 | {0x0000a16c, 0x44004401}, | ||
141 | {0x0000a170, 0x441e441f}, | ||
142 | {0x0000a174, 0x55015502}, | ||
143 | {0x0000a178, 0x551f5500}, | ||
144 | {0x0000a17c, 0x6602551e}, | ||
145 | {0x0000a180, 0x66006601}, | ||
146 | {0x0000a184, 0x661e661f}, | ||
147 | {0x0000a188, 0x7703661d}, | ||
148 | {0x0000a18c, 0x77017702}, | ||
149 | {0x0000a190, 0x00007700}, | ||
150 | {0x0000a194, 0x00000000}, | ||
151 | {0x0000a198, 0x00000000}, | ||
152 | {0x0000a19c, 0x00000000}, | ||
153 | {0x0000a1a0, 0x00000000}, | ||
154 | {0x0000a1a4, 0x00000000}, | ||
155 | {0x0000a1a8, 0x00000000}, | ||
156 | {0x0000a1ac, 0x00000000}, | ||
157 | {0x0000a1b0, 0x00000000}, | ||
158 | {0x0000a1b4, 0x00000000}, | ||
159 | {0x0000a1b8, 0x00000000}, | ||
160 | {0x0000a1bc, 0x00000000}, | ||
161 | {0x0000a1c0, 0x00000000}, | ||
162 | {0x0000a1c4, 0x00000000}, | ||
163 | {0x0000a1c8, 0x00000000}, | ||
164 | {0x0000a1cc, 0x00000000}, | ||
165 | {0x0000a1d0, 0x00000000}, | ||
166 | {0x0000a1d4, 0x00000000}, | ||
167 | {0x0000a1d8, 0x00000000}, | ||
168 | {0x0000a1dc, 0x00000000}, | ||
169 | {0x0000a1e0, 0x00000000}, | ||
170 | {0x0000a1e4, 0x00000000}, | ||
171 | {0x0000a1e8, 0x00000000}, | ||
172 | {0x0000a1ec, 0x00000000}, | ||
173 | {0x0000a1f0, 0x00000396}, | ||
174 | {0x0000a1f4, 0x00000396}, | ||
175 | {0x0000a1f8, 0x00000396}, | ||
176 | {0x0000a1fc, 0x00000296}, | ||
177 | }; | ||
178 | |||
179 | static const u32 ar9485Modes_high_power_tx_gain_1_0[][5] = { | ||
180 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
181 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, | ||
182 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
183 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
184 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
185 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
186 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
187 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
188 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
189 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
190 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, | ||
191 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, | ||
192 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, | ||
193 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, | ||
194 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20}, | ||
195 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20}, | ||
196 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22}, | ||
197 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24}, | ||
198 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26}, | ||
199 | {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640}, | ||
200 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660}, | ||
201 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861}, | ||
202 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81}, | ||
203 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83}, | ||
204 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85}, | ||
205 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5}, | ||
206 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9}, | ||
207 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb}, | ||
208 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
209 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
210 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
211 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
212 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
213 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
214 | {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db}, | ||
215 | }; | ||
216 | |||
217 | static const u32 ar9485_1_0[][2] = { | ||
218 | /* Addr allmodes */ | ||
219 | {0x0000a580, 0x00000000}, | ||
220 | {0x0000a584, 0x00000000}, | ||
221 | {0x0000a588, 0x00000000}, | ||
222 | {0x0000a58c, 0x00000000}, | ||
223 | {0x0000a590, 0x00000000}, | ||
224 | {0x0000a594, 0x00000000}, | ||
225 | {0x0000a598, 0x00000000}, | ||
226 | {0x0000a59c, 0x00000000}, | ||
227 | {0x0000a5a0, 0x00000000}, | ||
228 | {0x0000a5a4, 0x00000000}, | ||
229 | {0x0000a5a8, 0x00000000}, | ||
230 | {0x0000a5ac, 0x00000000}, | ||
231 | {0x0000a5b0, 0x00000000}, | ||
232 | {0x0000a5b4, 0x00000000}, | ||
233 | {0x0000a5b8, 0x00000000}, | ||
234 | {0x0000a5bc, 0x00000000}, | ||
235 | }; | ||
236 | |||
237 | static const u32 ar9485_1_0_radio_core[][2] = { | ||
238 | /* Addr allmodes */ | ||
239 | {0x00016000, 0x36db6db6}, | ||
240 | {0x00016004, 0x6db6db40}, | ||
241 | {0x00016008, 0x73800000}, | ||
242 | {0x0001600c, 0x00000000}, | ||
243 | {0x00016040, 0x7f80fff8}, | ||
244 | {0x00016048, 0x6c92426e}, | ||
245 | {0x0001604c, 0x000f0278}, | ||
246 | {0x00016050, 0x6db6db6c}, | ||
247 | {0x00016054, 0x6db60000}, | ||
248 | {0x00016080, 0x00080000}, | ||
249 | {0x00016084, 0x0e48048c}, | ||
250 | {0x00016088, 0x14214514}, | ||
251 | {0x0001608c, 0x119f081e}, | ||
252 | {0x00016090, 0x24926490}, | ||
253 | {0x00016098, 0xd28b3330}, | ||
254 | {0x000160a0, 0xc2108ffe}, | ||
255 | {0x000160a4, 0x812fc370}, | ||
256 | {0x000160a8, 0x423c8000}, | ||
257 | {0x000160b4, 0x92480040}, | ||
258 | {0x000160c0, 0x006db6db}, | ||
259 | {0x000160c4, 0x0186db60}, | ||
260 | {0x000160c8, 0x6db6db6c}, | ||
261 | {0x000160cc, 0x6de6fbe0}, | ||
262 | {0x000160d0, 0xf7dfcf3c}, | ||
263 | {0x00016100, 0x04cb0001}, | ||
264 | {0x00016104, 0xfff80015}, | ||
265 | {0x00016108, 0x00080010}, | ||
266 | {0x00016144, 0x01884080}, | ||
267 | {0x00016148, 0x00008040}, | ||
268 | {0x00016180, 0x08453333}, | ||
269 | {0x00016184, 0x18e82f01}, | ||
270 | {0x00016188, 0x00000000}, | ||
271 | {0x0001618c, 0x00000000}, | ||
272 | {0x00016240, 0x08400000}, | ||
273 | {0x00016244, 0x1bf90f00}, | ||
274 | {0x00016248, 0x00000000}, | ||
275 | {0x0001624c, 0x00000000}, | ||
276 | {0x00016280, 0x01000015}, | ||
277 | {0x00016284, 0x00d30000}, | ||
278 | {0x00016288, 0x00318000}, | ||
279 | {0x0001628c, 0x50000000}, | ||
280 | {0x00016290, 0x4b96210f}, | ||
281 | {0x00016380, 0x00000000}, | ||
282 | {0x00016384, 0x00000000}, | ||
283 | {0x00016388, 0x00800700}, | ||
284 | {0x0001638c, 0x00800700}, | ||
285 | {0x00016390, 0x00800700}, | ||
286 | {0x00016394, 0x00000000}, | ||
287 | {0x00016398, 0x00000000}, | ||
288 | {0x0001639c, 0x00000000}, | ||
289 | {0x000163a0, 0x00000001}, | ||
290 | {0x000163a4, 0x00000001}, | ||
291 | {0x000163a8, 0x00000000}, | ||
292 | {0x000163ac, 0x00000000}, | ||
293 | {0x000163b0, 0x00000000}, | ||
294 | {0x000163b4, 0x00000000}, | ||
295 | {0x000163b8, 0x00000000}, | ||
296 | {0x000163bc, 0x00000000}, | ||
297 | {0x000163c0, 0x000000a0}, | ||
298 | {0x000163c4, 0x000c0000}, | ||
299 | {0x000163c8, 0x14021402}, | ||
300 | {0x000163cc, 0x00001402}, | ||
301 | {0x000163d0, 0x00000000}, | ||
302 | {0x000163d4, 0x00000000}, | ||
303 | {0x00016c40, 0x1319c178}, | ||
304 | {0x00016c44, 0x10000000}, | ||
305 | }; | ||
306 | |||
307 | static const u32 ar9485Modes_lowest_ob_db_tx_gain_1_0[][5] = { | ||
308 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
309 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, | ||
310 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
311 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
312 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
313 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
314 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
315 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
316 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
317 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
318 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, | ||
319 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, | ||
320 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, | ||
321 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, | ||
322 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20}, | ||
323 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20}, | ||
324 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22}, | ||
325 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24}, | ||
326 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26}, | ||
327 | {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640}, | ||
328 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660}, | ||
329 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861}, | ||
330 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81}, | ||
331 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83}, | ||
332 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85}, | ||
333 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5}, | ||
334 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9}, | ||
335 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb}, | ||
336 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
337 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
338 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
339 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
340 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
341 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
342 | {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db}, | ||
343 | }; | ||
344 | |||
345 | static const u32 ar9485_1_0_baseband_core[][2] = { | ||
346 | /* Addr allmodes */ | ||
347 | {0x00009800, 0xafe68e30}, | ||
348 | {0x00009804, 0xfd14e000}, | ||
349 | {0x00009808, 0x9c0a8f6b}, | ||
350 | {0x0000980c, 0x04800000}, | ||
351 | {0x00009814, 0x9280c00a}, | ||
352 | {0x00009818, 0x00000000}, | ||
353 | {0x0000981c, 0x00020028}, | ||
354 | {0x00009834, 0x5f3ca3de}, | ||
355 | {0x00009838, 0x0108ecff}, | ||
356 | {0x0000983c, 0x14750600}, | ||
357 | {0x00009880, 0x201fff00}, | ||
358 | {0x00009884, 0x00001042}, | ||
359 | {0x000098a4, 0x00200400}, | ||
360 | {0x000098b0, 0x52440bbe}, | ||
361 | {0x000098bc, 0x00000002}, | ||
362 | {0x000098d0, 0x004b6a8e}, | ||
363 | {0x000098d4, 0x00000820}, | ||
364 | {0x000098dc, 0x00000000}, | ||
365 | {0x000098f0, 0x00000000}, | ||
366 | {0x000098f4, 0x00000000}, | ||
367 | {0x00009c04, 0x00000000}, | ||
368 | {0x00009c08, 0x03200000}, | ||
369 | {0x00009c0c, 0x00000000}, | ||
370 | {0x00009c10, 0x00000000}, | ||
371 | {0x00009c14, 0x00046384}, | ||
372 | {0x00009c18, 0x05b6b440}, | ||
373 | {0x00009c1c, 0x00b6b440}, | ||
374 | {0x00009d00, 0xc080a333}, | ||
375 | {0x00009d04, 0x40206c10}, | ||
376 | {0x00009d08, 0x009c4060}, | ||
377 | {0x00009d0c, 0x1883800a}, | ||
378 | {0x00009d10, 0x01834061}, | ||
379 | {0x00009d14, 0x00c00400}, | ||
380 | {0x00009d18, 0x00000000}, | ||
381 | {0x00009d1c, 0x00000000}, | ||
382 | {0x00009e08, 0x0038233c}, | ||
383 | {0x00009e24, 0x990bb515}, | ||
384 | {0x00009e28, 0x0a6f0000}, | ||
385 | {0x00009e30, 0x06336f77}, | ||
386 | {0x00009e34, 0x6af6532f}, | ||
387 | {0x00009e38, 0x0cc80c00}, | ||
388 | {0x00009e40, 0x0d261820}, | ||
389 | {0x00009e4c, 0x00001004}, | ||
390 | {0x00009e50, 0x00ff03f1}, | ||
391 | {0x00009fc0, 0x80be4788}, | ||
392 | {0x00009fc4, 0x0001efb5}, | ||
393 | {0x00009fcc, 0x40000014}, | ||
394 | {0x0000a20c, 0x00000000}, | ||
395 | {0x0000a210, 0x00000000}, | ||
396 | {0x0000a220, 0x00000000}, | ||
397 | {0x0000a224, 0x00000000}, | ||
398 | {0x0000a228, 0x10002310}, | ||
399 | {0x0000a23c, 0x00000000}, | ||
400 | {0x0000a244, 0x0c000000}, | ||
401 | {0x0000a2a0, 0x00000001}, | ||
402 | {0x0000a2c0, 0x00000001}, | ||
403 | {0x0000a2c8, 0x00000000}, | ||
404 | {0x0000a2cc, 0x18c43433}, | ||
405 | {0x0000a2d4, 0x00000000}, | ||
406 | {0x0000a2dc, 0x00000000}, | ||
407 | {0x0000a2e0, 0x00000000}, | ||
408 | {0x0000a2e4, 0x00000000}, | ||
409 | {0x0000a2e8, 0x00000000}, | ||
410 | {0x0000a2ec, 0x00000000}, | ||
411 | {0x0000a2f0, 0x00000000}, | ||
412 | {0x0000a2f4, 0x00000000}, | ||
413 | {0x0000a2f8, 0x00000000}, | ||
414 | {0x0000a344, 0x00000000}, | ||
415 | {0x0000a34c, 0x00000000}, | ||
416 | {0x0000a350, 0x0000a000}, | ||
417 | {0x0000a364, 0x00000000}, | ||
418 | {0x0000a370, 0x00000000}, | ||
419 | {0x0000a390, 0x00000001}, | ||
420 | {0x0000a394, 0x00000444}, | ||
421 | {0x0000a398, 0x001f0e0f}, | ||
422 | {0x0000a39c, 0x0075393f}, | ||
423 | {0x0000a3a0, 0xb79f6427}, | ||
424 | {0x0000a3a4, 0x00000000}, | ||
425 | {0x0000a3a8, 0xaaaaaaaa}, | ||
426 | {0x0000a3ac, 0x3c466478}, | ||
427 | {0x0000a3c0, 0x20202020}, | ||
428 | {0x0000a3c4, 0x22222220}, | ||
429 | {0x0000a3c8, 0x20200020}, | ||
430 | {0x0000a3cc, 0x20202020}, | ||
431 | {0x0000a3d0, 0x20202020}, | ||
432 | {0x0000a3d4, 0x20202020}, | ||
433 | {0x0000a3d8, 0x20202020}, | ||
434 | {0x0000a3dc, 0x20202020}, | ||
435 | {0x0000a3e0, 0x20202020}, | ||
436 | {0x0000a3e4, 0x20202020}, | ||
437 | {0x0000a3e8, 0x20202020}, | ||
438 | {0x0000a3ec, 0x20202020}, | ||
439 | {0x0000a3f0, 0x00000000}, | ||
440 | {0x0000a3f4, 0x00000006}, | ||
441 | {0x0000a3f8, 0x0cdbd380}, | ||
442 | {0x0000a3fc, 0x000f0f01}, | ||
443 | {0x0000a400, 0x8fa91f01}, | ||
444 | {0x0000a404, 0x00000000}, | ||
445 | {0x0000a408, 0x0e79e5c6}, | ||
446 | {0x0000a40c, 0x00820820}, | ||
447 | {0x0000a414, 0x1ce739ce}, | ||
448 | {0x0000a418, 0x2d0011ce}, | ||
449 | {0x0000a41c, 0x1ce739ce}, | ||
450 | {0x0000a420, 0x000001ce}, | ||
451 | {0x0000a424, 0x1ce739ce}, | ||
452 | {0x0000a428, 0x000001ce}, | ||
453 | {0x0000a42c, 0x1ce739ce}, | ||
454 | {0x0000a430, 0x1ce739ce}, | ||
455 | {0x0000a434, 0x00000000}, | ||
456 | {0x0000a438, 0x00001801}, | ||
457 | {0x0000a43c, 0x00000000}, | ||
458 | {0x0000a440, 0x00000000}, | ||
459 | {0x0000a444, 0x00000000}, | ||
460 | {0x0000a448, 0x04000000}, | ||
461 | {0x0000a44c, 0x00000001}, | ||
462 | {0x0000a450, 0x00010000}, | ||
463 | {0x0000a458, 0x00000000}, | ||
464 | {0x0000a5c4, 0x3fad9d74}, | ||
465 | {0x0000a5c8, 0x0048060a}, | ||
466 | {0x0000a5cc, 0x00000637}, | ||
467 | {0x0000a760, 0x03020100}, | ||
468 | {0x0000a764, 0x09080504}, | ||
469 | {0x0000a768, 0x0d0c0b0a}, | ||
470 | {0x0000a76c, 0x13121110}, | ||
471 | {0x0000a770, 0x31301514}, | ||
472 | {0x0000a774, 0x35343332}, | ||
473 | {0x0000a778, 0x00000036}, | ||
474 | {0x0000a780, 0x00000838}, | ||
475 | {0x0000a7c0, 0x00000000}, | ||
476 | {0x0000a7c4, 0xfffffffc}, | ||
477 | {0x0000a7c8, 0x00000000}, | ||
478 | {0x0000a7cc, 0x00000000}, | ||
479 | {0x0000a7d0, 0x00000000}, | ||
480 | {0x0000a7d4, 0x00000004}, | ||
481 | {0x0000a7dc, 0x00000001}, | ||
482 | }; | ||
483 | |||
484 | static const u32 ar9485Modes_high_ob_db_tx_gain_1_0[][5] = { | ||
485 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
486 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, | ||
487 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
488 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
489 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
490 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
491 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
492 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
493 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
494 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
495 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, | ||
496 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, | ||
497 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, | ||
498 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, | ||
499 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20}, | ||
500 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20}, | ||
501 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22}, | ||
502 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24}, | ||
503 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26}, | ||
504 | {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640}, | ||
505 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660}, | ||
506 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861}, | ||
507 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81}, | ||
508 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83}, | ||
509 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85}, | ||
510 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5}, | ||
511 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9}, | ||
512 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb}, | ||
513 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
514 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
515 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
516 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
517 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
518 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
519 | {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db}, | ||
520 | }; | ||
521 | |||
522 | static const u32 ar9485Common_rx_gain_1_0[][2] = { | ||
523 | /* Addr allmodes */ | ||
524 | {0x0000a000, 0x00010000}, | ||
525 | {0x0000a004, 0x00030002}, | ||
526 | {0x0000a008, 0x00050004}, | ||
527 | {0x0000a00c, 0x00810080}, | ||
528 | {0x0000a010, 0x01800082}, | ||
529 | {0x0000a014, 0x01820181}, | ||
530 | {0x0000a018, 0x01840183}, | ||
531 | {0x0000a01c, 0x01880185}, | ||
532 | {0x0000a020, 0x018a0189}, | ||
533 | {0x0000a024, 0x02850284}, | ||
534 | {0x0000a028, 0x02890288}, | ||
535 | {0x0000a02c, 0x03850384}, | ||
536 | {0x0000a030, 0x03890388}, | ||
537 | {0x0000a034, 0x038b038a}, | ||
538 | {0x0000a038, 0x038d038c}, | ||
539 | {0x0000a03c, 0x03910390}, | ||
540 | {0x0000a040, 0x03930392}, | ||
541 | {0x0000a044, 0x03950394}, | ||
542 | {0x0000a048, 0x00000396}, | ||
543 | {0x0000a04c, 0x00000000}, | ||
544 | {0x0000a050, 0x00000000}, | ||
545 | {0x0000a054, 0x00000000}, | ||
546 | {0x0000a058, 0x00000000}, | ||
547 | {0x0000a05c, 0x00000000}, | ||
548 | {0x0000a060, 0x00000000}, | ||
549 | {0x0000a064, 0x00000000}, | ||
550 | {0x0000a068, 0x00000000}, | ||
551 | {0x0000a06c, 0x00000000}, | ||
552 | {0x0000a070, 0x00000000}, | ||
553 | {0x0000a074, 0x00000000}, | ||
554 | {0x0000a078, 0x00000000}, | ||
555 | {0x0000a07c, 0x00000000}, | ||
556 | {0x0000a080, 0x28282828}, | ||
557 | {0x0000a084, 0x28282828}, | ||
558 | {0x0000a088, 0x28282828}, | ||
559 | {0x0000a08c, 0x28282828}, | ||
560 | {0x0000a090, 0x28282828}, | ||
561 | {0x0000a094, 0x21212128}, | ||
562 | {0x0000a098, 0x171c1c1c}, | ||
563 | {0x0000a09c, 0x02020212}, | ||
564 | {0x0000a0a0, 0x00000202}, | ||
565 | {0x0000a0a4, 0x00000000}, | ||
566 | {0x0000a0a8, 0x00000000}, | ||
567 | {0x0000a0ac, 0x00000000}, | ||
568 | {0x0000a0b0, 0x00000000}, | ||
569 | {0x0000a0b4, 0x00000000}, | ||
570 | {0x0000a0b8, 0x00000000}, | ||
571 | {0x0000a0bc, 0x00000000}, | ||
572 | {0x0000a0c0, 0x001f0000}, | ||
573 | {0x0000a0c4, 0x111f1100}, | ||
574 | {0x0000a0c8, 0x111d111e}, | ||
575 | {0x0000a0cc, 0x111b111c}, | ||
576 | {0x0000a0d0, 0x22032204}, | ||
577 | {0x0000a0d4, 0x22012202}, | ||
578 | {0x0000a0d8, 0x221f2200}, | ||
579 | {0x0000a0dc, 0x221d221e}, | ||
580 | {0x0000a0e0, 0x33013302}, | ||
581 | {0x0000a0e4, 0x331f3300}, | ||
582 | {0x0000a0e8, 0x4402331e}, | ||
583 | {0x0000a0ec, 0x44004401}, | ||
584 | {0x0000a0f0, 0x441e441f}, | ||
585 | {0x0000a0f4, 0x55015502}, | ||
586 | {0x0000a0f8, 0x551f5500}, | ||
587 | {0x0000a0fc, 0x6602551e}, | ||
588 | {0x0000a100, 0x66006601}, | ||
589 | {0x0000a104, 0x661e661f}, | ||
590 | {0x0000a108, 0x7703661d}, | ||
591 | {0x0000a10c, 0x77017702}, | ||
592 | {0x0000a110, 0x00007700}, | ||
593 | {0x0000a114, 0x00000000}, | ||
594 | {0x0000a118, 0x00000000}, | ||
595 | {0x0000a11c, 0x00000000}, | ||
596 | {0x0000a120, 0x00000000}, | ||
597 | {0x0000a124, 0x00000000}, | ||
598 | {0x0000a128, 0x00000000}, | ||
599 | {0x0000a12c, 0x00000000}, | ||
600 | {0x0000a130, 0x00000000}, | ||
601 | {0x0000a134, 0x00000000}, | ||
602 | {0x0000a138, 0x00000000}, | ||
603 | {0x0000a13c, 0x00000000}, | ||
604 | {0x0000a140, 0x001f0000}, | ||
605 | {0x0000a144, 0x111f1100}, | ||
606 | {0x0000a148, 0x111d111e}, | ||
607 | {0x0000a14c, 0x111b111c}, | ||
608 | {0x0000a150, 0x22032204}, | ||
609 | {0x0000a154, 0x22012202}, | ||
610 | {0x0000a158, 0x221f2200}, | ||
611 | {0x0000a15c, 0x221d221e}, | ||
612 | {0x0000a160, 0x33013302}, | ||
613 | {0x0000a164, 0x331f3300}, | ||
614 | {0x0000a168, 0x4402331e}, | ||
615 | {0x0000a16c, 0x44004401}, | ||
616 | {0x0000a170, 0x441e441f}, | ||
617 | {0x0000a174, 0x55015502}, | ||
618 | {0x0000a178, 0x551f5500}, | ||
619 | {0x0000a17c, 0x6602551e}, | ||
620 | {0x0000a180, 0x66006601}, | ||
621 | {0x0000a184, 0x661e661f}, | ||
622 | {0x0000a188, 0x7703661d}, | ||
623 | {0x0000a18c, 0x77017702}, | ||
624 | {0x0000a190, 0x00007700}, | ||
625 | {0x0000a194, 0x00000000}, | ||
626 | {0x0000a198, 0x00000000}, | ||
627 | {0x0000a19c, 0x00000000}, | ||
628 | {0x0000a1a0, 0x00000000}, | ||
629 | {0x0000a1a4, 0x00000000}, | ||
630 | {0x0000a1a8, 0x00000000}, | ||
631 | {0x0000a1ac, 0x00000000}, | ||
632 | {0x0000a1b0, 0x00000000}, | ||
633 | {0x0000a1b4, 0x00000000}, | ||
634 | {0x0000a1b8, 0x00000000}, | ||
635 | {0x0000a1bc, 0x00000000}, | ||
636 | {0x0000a1c0, 0x00000000}, | ||
637 | {0x0000a1c4, 0x00000000}, | ||
638 | {0x0000a1c8, 0x00000000}, | ||
639 | {0x0000a1cc, 0x00000000}, | ||
640 | {0x0000a1d0, 0x00000000}, | ||
641 | {0x0000a1d4, 0x00000000}, | ||
642 | {0x0000a1d8, 0x00000000}, | ||
643 | {0x0000a1dc, 0x00000000}, | ||
644 | {0x0000a1e0, 0x00000000}, | ||
645 | {0x0000a1e4, 0x00000000}, | ||
646 | {0x0000a1e8, 0x00000000}, | ||
647 | {0x0000a1ec, 0x00000000}, | ||
648 | {0x0000a1f0, 0x00000396}, | ||
649 | {0x0000a1f4, 0x00000396}, | ||
650 | {0x0000a1f8, 0x00000396}, | ||
651 | {0x0000a1fc, 0x00000296}, | ||
652 | }; | ||
653 | |||
654 | static const u32 ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1[][2] = { | ||
655 | /* Addr allmodes */ | ||
656 | {0x00018c00, 0x10252e5e}, | ||
657 | {0x00018c04, 0x000801d8}, | ||
658 | {0x00018c08, 0x0000580c}, | ||
659 | }; | ||
660 | |||
661 | static const u32 ar9485_1_0_pcie_phy_clkreq_enable_L1[][2] = { | ||
662 | /* Addr allmodes */ | ||
663 | {0x00018c00, 0x10253e5e}, | ||
664 | {0x00018c04, 0x000801d8}, | ||
665 | {0x00018c08, 0x0000580c}, | ||
666 | }; | ||
667 | |||
668 | static const u32 ar9485_1_0_soc_preamble[][2] = { | ||
669 | /* Addr allmodes */ | ||
670 | {0x00004090, 0x00aa10aa}, | ||
671 | {0x000040a4, 0x00a0c9c9}, | ||
672 | {0x00007048, 0x00000004}, | ||
673 | }; | ||
674 | |||
675 | static const u32 ar9485_fast_clock_1_0_baseband_postamble[][3] = { | ||
676 | /* Addr 5G_HT20 5G_HT40 */ | ||
677 | {0x00009e00, 0x03721821, 0x03721821}, | ||
678 | {0x0000a230, 0x0000400b, 0x00004016}, | ||
679 | {0x0000a254, 0x00000898, 0x00001130}, | ||
680 | }; | ||
681 | |||
682 | static const u32 ar9485_1_0_baseband_postamble[][5] = { | ||
683 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
684 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, | ||
685 | {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, | ||
686 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, | ||
687 | {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, | ||
688 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, | ||
689 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, | ||
690 | {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, | ||
691 | {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, | ||
692 | {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, | ||
693 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, | ||
694 | {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e}, | ||
695 | {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, | ||
696 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
697 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | ||
698 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | ||
699 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, | ||
700 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222}, | ||
701 | {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324}, | ||
702 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, | ||
703 | {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, | ||
704 | {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0}, | ||
705 | {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, | ||
706 | {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, | ||
707 | {0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff}, | ||
708 | {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, | ||
709 | {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, | ||
710 | {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, | ||
711 | {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, | ||
712 | {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, | ||
713 | {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501}, | ||
714 | {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, | ||
715 | {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, | ||
716 | {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0}, | ||
717 | {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
718 | {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
719 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, | ||
720 | {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982}, | ||
721 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, | ||
722 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
723 | {0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, | ||
724 | {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
725 | }; | ||
726 | |||
727 | static const u32 ar9485Modes_low_ob_db_tx_gain_1_0[][5] = { | ||
728 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
729 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, | ||
730 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
731 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
732 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
733 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
734 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
735 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
736 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
737 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
738 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, | ||
739 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, | ||
740 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, | ||
741 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, | ||
742 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20}, | ||
743 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20}, | ||
744 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22}, | ||
745 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24}, | ||
746 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26}, | ||
747 | {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640}, | ||
748 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660}, | ||
749 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861}, | ||
750 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81}, | ||
751 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83}, | ||
752 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85}, | ||
753 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5}, | ||
754 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9}, | ||
755 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb}, | ||
756 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
757 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
758 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
759 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
760 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
761 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb}, | ||
762 | {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db}, | ||
763 | }; | ||
764 | |||
765 | static const u32 ar9485_1_0_pcie_phy_clkreq_disable_L1[][2] = { | ||
766 | /* Addr allmodes */ | ||
767 | {0x00018c00, 0x10213e5e}, | ||
768 | {0x00018c04, 0x000801d8}, | ||
769 | {0x00018c08, 0x0000580c}, | ||
770 | }; | ||
771 | |||
772 | static const u32 ar9485_1_0_radio_postamble[][2] = { | ||
773 | /* Addr allmodes */ | ||
774 | {0x0001609c, 0x0b283f31}, | ||
775 | {0x000160ac, 0x24611800}, | ||
776 | {0x000160b0, 0x03284f3e}, | ||
777 | {0x0001610c, 0x00170000}, | ||
778 | {0x00016140, 0x10804008}, | ||
779 | }; | ||
780 | |||
781 | static const u32 ar9485_1_0_mac_core[][2] = { | ||
782 | /* Addr allmodes */ | ||
783 | {0x00000008, 0x00000000}, | ||
784 | {0x00000030, 0x00020085}, | ||
785 | {0x00000034, 0x00000005}, | ||
786 | {0x00000040, 0x00000000}, | ||
787 | {0x00000044, 0x00000000}, | ||
788 | {0x00000048, 0x00000008}, | ||
789 | {0x0000004c, 0x00000010}, | ||
790 | {0x00000050, 0x00000000}, | ||
791 | {0x00001040, 0x002ffc0f}, | ||
792 | {0x00001044, 0x002ffc0f}, | ||
793 | {0x00001048, 0x002ffc0f}, | ||
794 | {0x0000104c, 0x002ffc0f}, | ||
795 | {0x00001050, 0x002ffc0f}, | ||
796 | {0x00001054, 0x002ffc0f}, | ||
797 | {0x00001058, 0x002ffc0f}, | ||
798 | {0x0000105c, 0x002ffc0f}, | ||
799 | {0x00001060, 0x002ffc0f}, | ||
800 | {0x00001064, 0x002ffc0f}, | ||
801 | {0x000010f0, 0x00000100}, | ||
802 | {0x00001270, 0x00000000}, | ||
803 | {0x000012b0, 0x00000000}, | ||
804 | {0x000012f0, 0x00000000}, | ||
805 | {0x0000143c, 0x00000000}, | ||
806 | {0x0000147c, 0x00000000}, | ||
807 | {0x00008000, 0x00000000}, | ||
808 | {0x00008004, 0x00000000}, | ||
809 | {0x00008008, 0x00000000}, | ||
810 | {0x0000800c, 0x00000000}, | ||
811 | {0x00008018, 0x00000000}, | ||
812 | {0x00008020, 0x00000000}, | ||
813 | {0x00008038, 0x00000000}, | ||
814 | {0x0000803c, 0x00000000}, | ||
815 | {0x00008040, 0x00000000}, | ||
816 | {0x00008044, 0x00000000}, | ||
817 | {0x00008048, 0x00000000}, | ||
818 | {0x0000804c, 0xffffffff}, | ||
819 | {0x00008054, 0x00000000}, | ||
820 | {0x00008058, 0x00000000}, | ||
821 | {0x0000805c, 0x000fc78f}, | ||
822 | {0x00008060, 0x0000000f}, | ||
823 | {0x00008064, 0x00000000}, | ||
824 | {0x00008070, 0x00000310}, | ||
825 | {0x00008074, 0x00000020}, | ||
826 | {0x00008078, 0x00000000}, | ||
827 | {0x0000809c, 0x0000000f}, | ||
828 | {0x000080a0, 0x00000000}, | ||
829 | {0x000080a4, 0x02ff0000}, | ||
830 | {0x000080a8, 0x0e070605}, | ||
831 | {0x000080ac, 0x0000000d}, | ||
832 | {0x000080b0, 0x00000000}, | ||
833 | {0x000080b4, 0x00000000}, | ||
834 | {0x000080b8, 0x00000000}, | ||
835 | {0x000080bc, 0x00000000}, | ||
836 | {0x000080c0, 0x2a800000}, | ||
837 | {0x000080c4, 0x06900168}, | ||
838 | {0x000080c8, 0x13881c20}, | ||
839 | {0x000080cc, 0x01f40000}, | ||
840 | {0x000080d0, 0x00252500}, | ||
841 | {0x000080d4, 0x00a00000}, | ||
842 | {0x000080d8, 0x00400000}, | ||
843 | {0x000080dc, 0x00000000}, | ||
844 | {0x000080e0, 0xffffffff}, | ||
845 | {0x000080e4, 0x0000ffff}, | ||
846 | {0x000080e8, 0x3f3f3f3f}, | ||
847 | {0x000080ec, 0x00000000}, | ||
848 | {0x000080f0, 0x00000000}, | ||
849 | {0x000080f4, 0x00000000}, | ||
850 | {0x000080fc, 0x00020000}, | ||
851 | {0x00008100, 0x00000000}, | ||
852 | {0x00008108, 0x00000052}, | ||
853 | {0x0000810c, 0x00000000}, | ||
854 | {0x00008110, 0x00000000}, | ||
855 | {0x00008114, 0x000007ff}, | ||
856 | {0x00008118, 0x000000aa}, | ||
857 | {0x0000811c, 0x00003210}, | ||
858 | {0x00008124, 0x00000000}, | ||
859 | {0x00008128, 0x00000000}, | ||
860 | {0x0000812c, 0x00000000}, | ||
861 | {0x00008130, 0x00000000}, | ||
862 | {0x00008134, 0x00000000}, | ||
863 | {0x00008138, 0x00000000}, | ||
864 | {0x0000813c, 0x0000ffff}, | ||
865 | {0x00008144, 0xffffffff}, | ||
866 | {0x00008168, 0x00000000}, | ||
867 | {0x0000816c, 0x00000000}, | ||
868 | {0x00008170, 0x18486200}, | ||
869 | {0x00008174, 0x33332210}, | ||
870 | {0x00008178, 0x00000000}, | ||
871 | {0x0000817c, 0x00020000}, | ||
872 | {0x000081c0, 0x00000000}, | ||
873 | {0x000081c4, 0x33332210}, | ||
874 | {0x000081c8, 0x00000000}, | ||
875 | {0x000081cc, 0x00000000}, | ||
876 | {0x000081d4, 0x00000000}, | ||
877 | {0x000081ec, 0x00000000}, | ||
878 | {0x000081f0, 0x00000000}, | ||
879 | {0x000081f4, 0x00000000}, | ||
880 | {0x000081f8, 0x00000000}, | ||
881 | {0x000081fc, 0x00000000}, | ||
882 | {0x00008240, 0x00100000}, | ||
883 | {0x00008244, 0x0010f400}, | ||
884 | {0x00008248, 0x00000800}, | ||
885 | {0x0000824c, 0x0001e800}, | ||
886 | {0x00008250, 0x00000000}, | ||
887 | {0x00008254, 0x00000000}, | ||
888 | {0x00008258, 0x00000000}, | ||
889 | {0x0000825c, 0x40000000}, | ||
890 | {0x00008260, 0x00080922}, | ||
891 | {0x00008264, 0x9ca00010}, | ||
892 | {0x00008268, 0xffffffff}, | ||
893 | {0x0000826c, 0x0000ffff}, | ||
894 | {0x00008270, 0x00000000}, | ||
895 | {0x00008274, 0x40000000}, | ||
896 | {0x00008278, 0x003e4180}, | ||
897 | {0x0000827c, 0x00000004}, | ||
898 | {0x00008284, 0x0000002c}, | ||
899 | {0x00008288, 0x0000002c}, | ||
900 | {0x0000828c, 0x000000ff}, | ||
901 | {0x00008294, 0x00000000}, | ||
902 | {0x00008298, 0x00000000}, | ||
903 | {0x0000829c, 0x00000000}, | ||
904 | {0x00008300, 0x00000140}, | ||
905 | {0x00008314, 0x00000000}, | ||
906 | {0x0000831c, 0x0000010d}, | ||
907 | {0x00008328, 0x00000000}, | ||
908 | {0x0000832c, 0x00000007}, | ||
909 | {0x00008330, 0x00000302}, | ||
910 | {0x00008334, 0x00000700}, | ||
911 | {0x00008338, 0x00ff0000}, | ||
912 | {0x0000833c, 0x02400000}, | ||
913 | {0x00008340, 0x000107ff}, | ||
914 | {0x00008344, 0xa248105b}, | ||
915 | {0x00008348, 0x008f0000}, | ||
916 | {0x0000835c, 0x00000000}, | ||
917 | {0x00008360, 0xffffffff}, | ||
918 | {0x00008364, 0xffffffff}, | ||
919 | {0x00008368, 0x00000000}, | ||
920 | {0x00008370, 0x00000000}, | ||
921 | {0x00008374, 0x000000ff}, | ||
922 | {0x00008378, 0x00000000}, | ||
923 | {0x0000837c, 0x00000000}, | ||
924 | {0x00008380, 0xffffffff}, | ||
925 | {0x00008384, 0xffffffff}, | ||
926 | {0x00008390, 0xffffffff}, | ||
927 | {0x00008394, 0xffffffff}, | ||
928 | {0x00008398, 0x00000000}, | ||
929 | {0x0000839c, 0x00000000}, | ||
930 | {0x000083a0, 0x00000000}, | ||
931 | {0x000083a4, 0x0000fa14}, | ||
932 | {0x000083a8, 0x000f0c00}, | ||
933 | {0x000083ac, 0x33332210}, | ||
934 | {0x000083b0, 0x33332210}, | ||
935 | {0x000083b4, 0x33332210}, | ||
936 | {0x000083b8, 0x33332210}, | ||
937 | {0x000083bc, 0x00000000}, | ||
938 | {0x000083c0, 0x00000000}, | ||
939 | {0x000083c4, 0x00000000}, | ||
940 | {0x000083c8, 0x00000000}, | ||
941 | {0x000083cc, 0x00000200}, | ||
942 | {0x000083d0, 0x000301ff}, | ||
943 | }; | ||
944 | |||
945 | static const u32 ar9485_1_1_mac_core[][2] = { | 20 | static const u32 ar9485_1_1_mac_core[][2] = { |
946 | /* Addr allmodes */ | 21 | /* Addr allmodes */ |
947 | {0x00000008, 0x00000000}, | 22 | {0x00000008, 0x00000000}, |
@@ -1321,7 +396,7 @@ static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = { | |||
1321 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 396 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
1322 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 397 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
1323 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 398 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
1324 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 399 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
1325 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 400 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
1326 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 401 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
1327 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 402 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
@@ -1394,7 +469,7 @@ static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = { | |||
1394 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 469 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
1395 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 470 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
1396 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 471 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
1397 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 472 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
1398 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 473 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
1399 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 474 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
1400 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 475 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
@@ -1560,7 +635,7 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { | |||
1560 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 635 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
1561 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 636 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
1562 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 637 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
1563 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 638 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
1564 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 639 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
1565 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 640 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
1566 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 641 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
@@ -1653,7 +728,7 @@ static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = { | |||
1653 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 728 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
1654 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 729 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
1655 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 730 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
1656 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 731 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
1657 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 732 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
1658 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 733 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
1659 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 734 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
@@ -1752,7 +827,7 @@ static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { | |||
1752 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | 827 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, |
1753 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | 828 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, |
1754 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | 829 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, |
1755 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | 830 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, |
1756 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | 831 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, |
1757 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | 832 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, |
1758 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | 833 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 099bd4183ad..03b37d7be1c 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -62,7 +62,6 @@ struct ath_node; | |||
62 | #define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i)) | 62 | #define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i)) |
63 | 63 | ||
64 | struct ath_config { | 64 | struct ath_config { |
65 | u32 ath_aggr_prot; | ||
66 | u16 txpowlimit; | 65 | u16 txpowlimit; |
67 | u8 cabqReadytime; | 66 | u8 cabqReadytime; |
68 | }; | 67 | }; |
@@ -120,13 +119,11 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, | |||
120 | /* RX / TX */ | 119 | /* RX / TX */ |
121 | /***********/ | 120 | /***********/ |
122 | 121 | ||
123 | #define ATH_MAX_ANTENNA 3 | ||
124 | #define ATH_RXBUF 512 | 122 | #define ATH_RXBUF 512 |
125 | #define ATH_TXBUF 512 | 123 | #define ATH_TXBUF 512 |
126 | #define ATH_TXBUF_RESERVE 5 | 124 | #define ATH_TXBUF_RESERVE 5 |
127 | #define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE) | 125 | #define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE) |
128 | #define ATH_TXMAXTRY 13 | 126 | #define ATH_TXMAXTRY 13 |
129 | #define ATH_MGT_TXMAXTRY 4 | ||
130 | 127 | ||
131 | #define TID_TO_WME_AC(_tid) \ | 128 | #define TID_TO_WME_AC(_tid) \ |
132 | ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ | 129 | ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ |
@@ -202,6 +199,7 @@ struct ath_atx_ac { | |||
202 | int sched; | 199 | int sched; |
203 | struct list_head list; | 200 | struct list_head list; |
204 | struct list_head tid_q; | 201 | struct list_head tid_q; |
202 | bool clear_ps_filter; | ||
205 | }; | 203 | }; |
206 | 204 | ||
207 | struct ath_frame_info { | 205 | struct ath_frame_info { |
@@ -257,8 +255,12 @@ struct ath_node { | |||
257 | #endif | 255 | #endif |
258 | struct ath_atx_tid tid[WME_NUM_TID]; | 256 | struct ath_atx_tid tid[WME_NUM_TID]; |
259 | struct ath_atx_ac ac[WME_NUM_AC]; | 257 | struct ath_atx_ac ac[WME_NUM_AC]; |
258 | int ps_key; | ||
259 | |||
260 | u16 maxampdu; | 260 | u16 maxampdu; |
261 | u8 mpdudensity; | 261 | u8 mpdudensity; |
262 | |||
263 | bool sleeping; | ||
262 | }; | 264 | }; |
263 | 265 | ||
264 | #define AGGR_CLEANUP BIT(1) | 266 | #define AGGR_CLEANUP BIT(1) |
@@ -340,17 +342,18 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
340 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 342 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
341 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 343 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
342 | 344 | ||
345 | void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); | ||
346 | bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an); | ||
347 | |||
343 | /********/ | 348 | /********/ |
344 | /* VIFs */ | 349 | /* VIFs */ |
345 | /********/ | 350 | /********/ |
346 | 351 | ||
347 | struct ath_vif { | 352 | struct ath_vif { |
348 | int av_bslot; | 353 | int av_bslot; |
349 | bool is_bslot_active; | 354 | bool is_bslot_active, primary_sta_vif; |
350 | __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ | 355 | __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ |
351 | enum nl80211_iftype av_opmode; | ||
352 | struct ath_buf *av_bcbuf; | 356 | struct ath_buf *av_bcbuf; |
353 | u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */ | ||
354 | }; | 357 | }; |
355 | 358 | ||
356 | /*******************/ | 359 | /*******************/ |
@@ -362,7 +365,7 @@ struct ath_vif { | |||
362 | * number of BSSIDs) if a given beacon does not go out even after waiting this | 365 | * number of BSSIDs) if a given beacon does not go out even after waiting this |
363 | * number of beacon intervals, the game's up. | 366 | * number of beacon intervals, the game's up. |
364 | */ | 367 | */ |
365 | #define BSTUCK_THRESH (9 * ATH_BCBUF) | 368 | #define BSTUCK_THRESH 9 |
366 | #define ATH_BCBUF 4 | 369 | #define ATH_BCBUF 4 |
367 | #define ATH_DEFAULT_BINTVAL 100 /* TU */ | 370 | #define ATH_DEFAULT_BINTVAL 100 /* TU */ |
368 | #define ATH_DEFAULT_BMISS_LIMIT 10 | 371 | #define ATH_DEFAULT_BMISS_LIMIT 10 |
@@ -386,7 +389,7 @@ struct ath_beacon { | |||
386 | u32 beaconq; | 389 | u32 beaconq; |
387 | u32 bmisscnt; | 390 | u32 bmisscnt; |
388 | u32 ast_be_xmit; | 391 | u32 ast_be_xmit; |
389 | u64 bc_tstamp; | 392 | u32 bc_tstamp; |
390 | struct ieee80211_vif *bslot[ATH_BCBUF]; | 393 | struct ieee80211_vif *bslot[ATH_BCBUF]; |
391 | int slottime; | 394 | int slottime; |
392 | int slotupdate; | 395 | int slotupdate; |
@@ -401,6 +404,7 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif); | |||
401 | int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif); | 404 | int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif); |
402 | void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); | 405 | void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); |
403 | int ath_beaconq_config(struct ath_softc *sc); | 406 | int ath_beaconq_config(struct ath_softc *sc); |
407 | void ath_set_beacon(struct ath_softc *sc); | ||
404 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); | 408 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); |
405 | 409 | ||
406 | /*******/ | 410 | /*******/ |
@@ -418,6 +422,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); | |||
418 | #define ATH_PAPRD_TIMEOUT 100 /* msecs */ | 422 | #define ATH_PAPRD_TIMEOUT 100 /* msecs */ |
419 | 423 | ||
420 | void ath_hw_check(struct work_struct *work); | 424 | void ath_hw_check(struct work_struct *work); |
425 | void ath_hw_pll_work(struct work_struct *work); | ||
421 | void ath_paprd_calibrate(struct work_struct *work); | 426 | void ath_paprd_calibrate(struct work_struct *work); |
422 | void ath_ani_calibrate(unsigned long data); | 427 | void ath_ani_calibrate(unsigned long data); |
423 | 428 | ||
@@ -448,6 +453,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc); | |||
448 | 453 | ||
449 | #define ATH_LED_PIN_DEF 1 | 454 | #define ATH_LED_PIN_DEF 1 |
450 | #define ATH_LED_PIN_9287 8 | 455 | #define ATH_LED_PIN_9287 8 |
456 | #define ATH_LED_PIN_9300 10 | ||
451 | #define ATH_LED_PIN_9485 6 | 457 | #define ATH_LED_PIN_9485 6 |
452 | 458 | ||
453 | #ifdef CONFIG_MAC80211_LEDS | 459 | #ifdef CONFIG_MAC80211_LEDS |
@@ -477,7 +483,6 @@ static inline void ath_deinit_leds(struct ath_softc *sc) | |||
477 | #define ATH_ANT_DIV_COMB_ALT_ANT_RATIO 30 | 483 | #define ATH_ANT_DIV_COMB_ALT_ANT_RATIO 30 |
478 | #define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2 20 | 484 | #define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2 20 |
479 | 485 | ||
480 | #define ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA -3 | ||
481 | #define ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA -1 | 486 | #define ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA -1 |
482 | #define ATH_ANT_DIV_COMB_LNA1_DELTA_HI -4 | 487 | #define ATH_ANT_DIV_COMB_LNA1_DELTA_HI -4 |
483 | #define ATH_ANT_DIV_COMB_LNA1_DELTA_MID -2 | 488 | #define ATH_ANT_DIV_COMB_LNA1_DELTA_MID -2 |
@@ -550,6 +555,7 @@ struct ath_ant_comb { | |||
550 | #define SC_OP_BT_SCAN BIT(13) | 555 | #define SC_OP_BT_SCAN BIT(13) |
551 | #define SC_OP_ANI_RUN BIT(14) | 556 | #define SC_OP_ANI_RUN BIT(14) |
552 | #define SC_OP_ENABLE_APM BIT(15) | 557 | #define SC_OP_ENABLE_APM BIT(15) |
558 | #define SC_OP_PRIM_STA_VIF BIT(16) | ||
553 | 559 | ||
554 | /* Powersave flags */ | 560 | /* Powersave flags */ |
555 | #define PS_WAIT_FOR_BEACON BIT(0) | 561 | #define PS_WAIT_FOR_BEACON BIT(0) |
@@ -557,6 +563,7 @@ struct ath_ant_comb { | |||
557 | #define PS_WAIT_FOR_PSPOLL_DATA BIT(2) | 563 | #define PS_WAIT_FOR_PSPOLL_DATA BIT(2) |
558 | #define PS_WAIT_FOR_TX_ACK BIT(3) | 564 | #define PS_WAIT_FOR_TX_ACK BIT(3) |
559 | #define PS_BEACON_SYNC BIT(4) | 565 | #define PS_BEACON_SYNC BIT(4) |
566 | #define PS_TSFOOR_SYNC BIT(5) | ||
560 | 567 | ||
561 | struct ath_rate_table; | 568 | struct ath_rate_table; |
562 | 569 | ||
@@ -667,7 +674,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); | |||
667 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode); | 674 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode); |
668 | bool ath9k_uses_beacons(int type); | 675 | bool ath9k_uses_beacons(int type); |
669 | 676 | ||
670 | #ifdef CONFIG_PCI | 677 | #ifdef CONFIG_ATH9K_PCI |
671 | int ath_pci_init(void); | 678 | int ath_pci_init(void); |
672 | void ath_pci_exit(void); | 679 | void ath_pci_exit(void); |
673 | #else | 680 | #else |
@@ -675,7 +682,7 @@ static inline int ath_pci_init(void) { return 0; }; | |||
675 | static inline void ath_pci_exit(void) {}; | 682 | static inline void ath_pci_exit(void) {}; |
676 | #endif | 683 | #endif |
677 | 684 | ||
678 | #ifdef CONFIG_ATHEROS_AR71XX | 685 | #ifdef CONFIG_ATH9K_AHB |
679 | int ath_ahb_init(void); | 686 | int ath_ahb_init(void); |
680 | void ath_ahb_exit(void); | 687 | void ath_ahb_exit(void); |
681 | #else | 688 | #else |
@@ -688,8 +695,6 @@ void ath9k_ps_restore(struct ath_softc *sc); | |||
688 | 695 | ||
689 | u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate); | 696 | u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate); |
690 | 697 | ||
691 | void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif); | ||
692 | |||
693 | void ath_start_rfkill_poll(struct ath_softc *sc); | 698 | void ath_start_rfkill_poll(struct ath_softc *sc); |
694 | extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); | 699 | extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); |
695 | void ath9k_calculate_iter_data(struct ieee80211_hw *hw, | 700 | void ath9k_calculate_iter_data(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 6d2a545fc35..637dbc5f7b6 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -57,8 +57,8 @@ int ath_beaconq_config(struct ath_softc *sc) | |||
57 | 57 | ||
58 | /* | 58 | /* |
59 | * Associates the beacon frame buffer with a transmit descriptor. Will set | 59 | * Associates the beacon frame buffer with a transmit descriptor. Will set |
60 | * up all required antenna switch parameters, rate codes, and channel flags. | 60 | * up rate codes, and channel flags. Beacons are always sent out at the |
61 | * Beacons are always sent out at the lowest rate, and are not retried. | 61 | * lowest rate, and are not retried. |
62 | */ | 62 | */ |
63 | static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | 63 | static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, |
64 | struct ath_buf *bf, int rateidx) | 64 | struct ath_buf *bf, int rateidx) |
@@ -68,7 +68,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | |||
68 | struct ath_common *common = ath9k_hw_common(ah); | 68 | struct ath_common *common = ath9k_hw_common(ah); |
69 | struct ath_desc *ds; | 69 | struct ath_desc *ds; |
70 | struct ath9k_11n_rate_series series[4]; | 70 | struct ath9k_11n_rate_series series[4]; |
71 | int flags, antenna, ctsrate = 0, ctsduration = 0; | 71 | int flags, ctsrate = 0, ctsduration = 0; |
72 | struct ieee80211_supported_band *sband; | 72 | struct ieee80211_supported_band *sband; |
73 | u8 rate = 0; | 73 | u8 rate = 0; |
74 | 74 | ||
@@ -76,12 +76,6 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | |||
76 | flags = ATH9K_TXDESC_NOACK; | 76 | flags = ATH9K_TXDESC_NOACK; |
77 | 77 | ||
78 | ds->ds_link = 0; | 78 | ds->ds_link = 0; |
79 | /* | ||
80 | * Switch antenna every beacon. | ||
81 | * Should only switch every beacon period, not for every SWBA | ||
82 | * XXX assumes two antennae | ||
83 | */ | ||
84 | antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1); | ||
85 | 79 | ||
86 | sband = &sc->sbands[common->hw->conf.channel->band]; | 80 | sband = &sc->sbands[common->hw->conf.channel->band]; |
87 | rate = sband->bitrates[rateidx].hw_value; | 81 | rate = sband->bitrates[rateidx].hw_value; |
@@ -278,7 +272,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
278 | return -ENOMEM; | 272 | return -ENOMEM; |
279 | 273 | ||
280 | tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; | 274 | tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; |
281 | sc->beacon.bc_tstamp = le64_to_cpu(tstamp); | 275 | sc->beacon.bc_tstamp = (u32) le64_to_cpu(tstamp); |
282 | /* Calculate a TSF adjustment factor required for staggered beacons. */ | 276 | /* Calculate a TSF adjustment factor required for staggered beacons. */ |
283 | if (avp->av_bslot > 0) { | 277 | if (avp->av_bslot > 0) { |
284 | u64 tsfadjust; | 278 | u64 tsfadjust; |
@@ -294,8 +288,8 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
294 | * adjustment. Other slots are adjusted to get the timestamp | 288 | * adjustment. Other slots are adjusted to get the timestamp |
295 | * close to the TBTT for the BSS. | 289 | * close to the TBTT for the BSS. |
296 | */ | 290 | */ |
297 | tsfadjust = intval * avp->av_bslot / ATH_BCBUF; | 291 | tsfadjust = TU_TO_USEC(intval * avp->av_bslot) / ATH_BCBUF; |
298 | avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); | 292 | avp->tsf_adjust = cpu_to_le64(tsfadjust); |
299 | 293 | ||
300 | ath_dbg(common, ATH_DBG_BEACON, | 294 | ath_dbg(common, ATH_DBG_BEACON, |
301 | "stagger beacons, bslot %d intval %u tsfadjust %llu\n", | 295 | "stagger beacons, bslot %d intval %u tsfadjust %llu\n", |
@@ -326,9 +320,11 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) | |||
326 | if (avp->av_bcbuf != NULL) { | 320 | if (avp->av_bcbuf != NULL) { |
327 | struct ath_buf *bf; | 321 | struct ath_buf *bf; |
328 | 322 | ||
323 | avp->is_bslot_active = false; | ||
329 | if (avp->av_bslot != -1) { | 324 | if (avp->av_bslot != -1) { |
330 | sc->beacon.bslot[avp->av_bslot] = NULL; | 325 | sc->beacon.bslot[avp->av_bslot] = NULL; |
331 | sc->nbcnvifs--; | 326 | sc->nbcnvifs--; |
327 | avp->av_bslot = -1; | ||
332 | } | 328 | } |
333 | 329 | ||
334 | bf = avp->av_bcbuf; | 330 | bf = avp->av_bcbuf; |
@@ -369,12 +365,13 @@ void ath_beacon_tasklet(unsigned long data) | |||
369 | if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) { | 365 | if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) { |
370 | sc->beacon.bmisscnt++; | 366 | sc->beacon.bmisscnt++; |
371 | 367 | ||
372 | if (sc->beacon.bmisscnt < BSTUCK_THRESH) { | 368 | if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) { |
373 | ath_dbg(common, ATH_DBG_BSTUCK, | 369 | ath_dbg(common, ATH_DBG_BSTUCK, |
374 | "missed %u consecutive beacons\n", | 370 | "missed %u consecutive beacons\n", |
375 | sc->beacon.bmisscnt); | 371 | sc->beacon.bmisscnt); |
376 | ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); | 372 | ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); |
377 | ath9k_hw_bstuck_nfcal(ah); | 373 | if (sc->beacon.bmisscnt > 3) |
374 | ath9k_hw_bstuck_nfcal(ah); | ||
378 | } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { | 375 | } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { |
379 | ath_dbg(common, ATH_DBG_BSTUCK, | 376 | ath_dbg(common, ATH_DBG_BSTUCK, |
380 | "beacon is officially stuck\n"); | 377 | "beacon is officially stuck\n"); |
@@ -385,13 +382,6 @@ void ath_beacon_tasklet(unsigned long data) | |||
385 | return; | 382 | return; |
386 | } | 383 | } |
387 | 384 | ||
388 | if (sc->beacon.bmisscnt != 0) { | ||
389 | ath_dbg(common, ATH_DBG_BSTUCK, | ||
390 | "resume beacon xmit after %u misses\n", | ||
391 | sc->beacon.bmisscnt); | ||
392 | sc->beacon.bmisscnt = 0; | ||
393 | } | ||
394 | |||
395 | /* | 385 | /* |
396 | * Generate beacon frames. we are sending frames | 386 | * Generate beacon frames. we are sending frames |
397 | * staggered so calculate the slot for this frame based | 387 | * staggered so calculate the slot for this frame based |
@@ -401,21 +391,14 @@ void ath_beacon_tasklet(unsigned long data) | |||
401 | intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; | 391 | intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; |
402 | 392 | ||
403 | tsf = ath9k_hw_gettsf64(ah); | 393 | tsf = ath9k_hw_gettsf64(ah); |
404 | tsftu = TSF_TO_TU(tsf>>32, tsf); | 394 | tsf += TU_TO_USEC(ah->config.sw_beacon_response_time); |
405 | slot = ((tsftu % intval) * ATH_BCBUF) / intval; | 395 | tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF); |
406 | /* | 396 | slot = (tsftu % (intval * ATH_BCBUF)) / intval; |
407 | * Reverse the slot order to get slot 0 on the TBTT offset that does | ||
408 | * not require TSF adjustment and other slots adding | ||
409 | * slot/ATH_BCBUF * beacon_int to timestamp. For example, with | ||
410 | * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 .. | ||
411 | * and slot 0 is at correct offset to TBTT. | ||
412 | */ | ||
413 | slot = ATH_BCBUF - slot - 1; | ||
414 | vif = sc->beacon.bslot[slot]; | 397 | vif = sc->beacon.bslot[slot]; |
415 | 398 | ||
416 | ath_dbg(common, ATH_DBG_BEACON, | 399 | ath_dbg(common, ATH_DBG_BEACON, |
417 | "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", | 400 | "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", |
418 | slot, tsf, tsftu, intval, vif); | 401 | slot, tsf, tsftu / ATH_BCBUF, intval, vif); |
419 | 402 | ||
420 | bfaddr = 0; | 403 | bfaddr = 0; |
421 | if (vif) { | 404 | if (vif) { |
@@ -424,6 +407,13 @@ void ath_beacon_tasklet(unsigned long data) | |||
424 | bfaddr = bf->bf_daddr; | 407 | bfaddr = bf->bf_daddr; |
425 | bc = 1; | 408 | bc = 1; |
426 | } | 409 | } |
410 | |||
411 | if (sc->beacon.bmisscnt != 0) { | ||
412 | ath_dbg(common, ATH_DBG_BSTUCK, | ||
413 | "resume beacon xmit after %u misses\n", | ||
414 | sc->beacon.bmisscnt); | ||
415 | sc->beacon.bmisscnt = 0; | ||
416 | } | ||
427 | } | 417 | } |
428 | 418 | ||
429 | /* | 419 | /* |
@@ -463,13 +453,17 @@ static void ath9k_beacon_init(struct ath_softc *sc, | |||
463 | u32 next_beacon, | 453 | u32 next_beacon, |
464 | u32 beacon_period) | 454 | u32 beacon_period) |
465 | { | 455 | { |
466 | if (beacon_period & ATH9K_BEACON_RESET_TSF) | 456 | if (sc->sc_flags & SC_OP_TSF_RESET) { |
467 | ath9k_ps_wakeup(sc); | 457 | ath9k_ps_wakeup(sc); |
458 | ath9k_hw_reset_tsf(sc->sc_ah); | ||
459 | } | ||
468 | 460 | ||
469 | ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period); | 461 | ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period); |
470 | 462 | ||
471 | if (beacon_period & ATH9K_BEACON_RESET_TSF) | 463 | if (sc->sc_flags & SC_OP_TSF_RESET) { |
472 | ath9k_ps_restore(sc); | 464 | ath9k_ps_restore(sc); |
465 | sc->sc_flags &= ~SC_OP_TSF_RESET; | ||
466 | } | ||
473 | } | 467 | } |
474 | 468 | ||
475 | /* | 469 | /* |
@@ -484,18 +478,14 @@ static void ath_beacon_config_ap(struct ath_softc *sc, | |||
484 | u32 nexttbtt, intval; | 478 | u32 nexttbtt, intval; |
485 | 479 | ||
486 | /* NB: the beacon interval is kept internally in TU's */ | 480 | /* NB: the beacon interval is kept internally in TU's */ |
487 | intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; | 481 | intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); |
488 | intval /= ATH_BCBUF; /* for staggered beacons */ | 482 | intval /= ATH_BCBUF; /* for staggered beacons */ |
489 | nexttbtt = intval; | 483 | nexttbtt = intval; |
490 | 484 | ||
491 | if (sc->sc_flags & SC_OP_TSF_RESET) | ||
492 | intval |= ATH9K_BEACON_RESET_TSF; | ||
493 | |||
494 | /* | 485 | /* |
495 | * In AP mode we enable the beacon timers and SWBA interrupts to | 486 | * In AP mode we enable the beacon timers and SWBA interrupts to |
496 | * prepare beacon frames. | 487 | * prepare beacon frames. |
497 | */ | 488 | */ |
498 | intval |= ATH9K_BEACON_ENA; | ||
499 | ah->imask |= ATH9K_INT_SWBA; | 489 | ah->imask |= ATH9K_INT_SWBA; |
500 | ath_beaconq_config(sc); | 490 | ath_beaconq_config(sc); |
501 | 491 | ||
@@ -505,11 +495,6 @@ static void ath_beacon_config_ap(struct ath_softc *sc, | |||
505 | ath9k_beacon_init(sc, nexttbtt, intval); | 495 | ath9k_beacon_init(sc, nexttbtt, intval); |
506 | sc->beacon.bmisscnt = 0; | 496 | sc->beacon.bmisscnt = 0; |
507 | ath9k_hw_set_interrupts(ah, ah->imask); | 497 | ath9k_hw_set_interrupts(ah, ah->imask); |
508 | |||
509 | /* Clear the reset TSF flag, so that subsequent beacon updation | ||
510 | will not reset the HW TSF. */ | ||
511 | |||
512 | sc->sc_flags &= ~SC_OP_TSF_RESET; | ||
513 | } | 498 | } |
514 | 499 | ||
515 | /* | 500 | /* |
@@ -635,7 +620,13 @@ static void ath_beacon_config_sta(struct ath_softc *sc, | |||
635 | ath9k_hw_disable_interrupts(ah); | 620 | ath9k_hw_disable_interrupts(ah); |
636 | ath9k_hw_set_sta_beacon_timers(ah, &bs); | 621 | ath9k_hw_set_sta_beacon_timers(ah, &bs); |
637 | ah->imask |= ATH9K_INT_BMISS; | 622 | ah->imask |= ATH9K_INT_BMISS; |
638 | ath9k_hw_set_interrupts(ah, ah->imask); | 623 | |
624 | /* | ||
625 | * If the beacon config is called beacause of TSFOOR, | ||
626 | * Interrupts will be enabled back at the end of ath9k_tasklet | ||
627 | */ | ||
628 | if (!(sc->ps_flags & PS_TSFOOR_SYNC)) | ||
629 | ath9k_hw_set_interrupts(ah, ah->imask); | ||
639 | } | 630 | } |
640 | 631 | ||
641 | static void ath_beacon_config_adhoc(struct ath_softc *sc, | 632 | static void ath_beacon_config_adhoc(struct ath_softc *sc, |
@@ -643,25 +634,20 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, | |||
643 | { | 634 | { |
644 | struct ath_hw *ah = sc->sc_ah; | 635 | struct ath_hw *ah = sc->sc_ah; |
645 | struct ath_common *common = ath9k_hw_common(ah); | 636 | struct ath_common *common = ath9k_hw_common(ah); |
646 | u64 tsf; | 637 | u32 tsf, delta, intval, nexttbtt; |
647 | u32 tsftu, intval, nexttbtt; | 638 | |
648 | 639 | tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE); | |
649 | intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; | 640 | intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); |
650 | 641 | ||
651 | 642 | if (!sc->beacon.bc_tstamp) | |
652 | /* Pull nexttbtt forward to reflect the current TSF */ | 643 | nexttbtt = tsf + intval; |
653 | 644 | else { | |
654 | nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp); | 645 | if (tsf > sc->beacon.bc_tstamp) |
655 | if (nexttbtt == 0) | 646 | delta = (tsf - sc->beacon.bc_tstamp); |
656 | nexttbtt = intval; | 647 | else |
657 | else if (intval) | 648 | delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp)); |
658 | nexttbtt = roundup(nexttbtt, intval); | 649 | nexttbtt = tsf + roundup(delta, intval); |
659 | 650 | } | |
660 | tsf = ath9k_hw_gettsf64(ah); | ||
661 | tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE; | ||
662 | do { | ||
663 | nexttbtt += intval; | ||
664 | } while (nexttbtt < tsftu); | ||
665 | 651 | ||
666 | ath_dbg(common, ATH_DBG_BEACON, | 652 | ath_dbg(common, ATH_DBG_BEACON, |
667 | "IBSS nexttbtt %u intval %u (%u)\n", | 653 | "IBSS nexttbtt %u intval %u (%u)\n", |
@@ -672,7 +658,6 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, | |||
672 | * if we need to manually prepare beacon frames. Otherwise we use a | 658 | * if we need to manually prepare beacon frames. Otherwise we use a |
673 | * self-linked tx descriptor and let the hardware deal with things. | 659 | * self-linked tx descriptor and let the hardware deal with things. |
674 | */ | 660 | */ |
675 | intval |= ATH9K_BEACON_ENA; | ||
676 | ah->imask |= ATH9K_INT_SWBA; | 661 | ah->imask |= ATH9K_INT_SWBA; |
677 | 662 | ||
678 | ath_beaconq_config(sc); | 663 | ath_beaconq_config(sc); |
@@ -682,25 +667,71 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, | |||
682 | ath9k_hw_disable_interrupts(ah); | 667 | ath9k_hw_disable_interrupts(ah); |
683 | ath9k_beacon_init(sc, nexttbtt, intval); | 668 | ath9k_beacon_init(sc, nexttbtt, intval); |
684 | sc->beacon.bmisscnt = 0; | 669 | sc->beacon.bmisscnt = 0; |
685 | ath9k_hw_set_interrupts(ah, ah->imask); | 670 | /* |
671 | * If the beacon config is called beacause of TSFOOR, | ||
672 | * Interrupts will be enabled back at the end of ath9k_tasklet | ||
673 | */ | ||
674 | if (!(sc->ps_flags & PS_TSFOOR_SYNC)) | ||
675 | ath9k_hw_set_interrupts(ah, ah->imask); | ||
686 | } | 676 | } |
687 | 677 | ||
688 | void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) | 678 | static bool ath9k_allow_beacon_config(struct ath_softc *sc, |
679 | struct ieee80211_vif *vif) | ||
689 | { | 680 | { |
690 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | 681 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; |
691 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 682 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
692 | enum nl80211_iftype iftype; | 683 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
684 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
693 | 685 | ||
694 | /* Setup the beacon configuration parameters */ | 686 | /* |
695 | if (vif) { | 687 | * Can not have different beacon interval on multiple |
696 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 688 | * AP interface case |
697 | iftype = vif->type; | 689 | */ |
698 | cur_conf->beacon_interval = bss_conf->beacon_int; | 690 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) && |
699 | cur_conf->dtim_period = bss_conf->dtim_period; | 691 | (sc->nbcnvifs > 1) && |
700 | } else { | 692 | (vif->type == NL80211_IFTYPE_AP) && |
701 | iftype = sc->sc_ah->opmode; | 693 | (cur_conf->beacon_interval != bss_conf->beacon_int)) { |
694 | ath_dbg(common, ATH_DBG_CONFIG, | ||
695 | "Changing beacon interval of multiple \ | ||
696 | AP interfaces !\n"); | ||
697 | return false; | ||
702 | } | 698 | } |
699 | /* | ||
700 | * Can not configure station vif's beacon config | ||
701 | * while on AP opmode | ||
702 | */ | ||
703 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) && | ||
704 | (vif->type != NL80211_IFTYPE_AP)) { | ||
705 | ath_dbg(common, ATH_DBG_CONFIG, | ||
706 | "STA vif's beacon not allowed on AP mode\n"); | ||
707 | return false; | ||
708 | } | ||
709 | /* | ||
710 | * Do not allow beacon config if HW was already configured | ||
711 | * with another STA vif | ||
712 | */ | ||
713 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && | ||
714 | (vif->type == NL80211_IFTYPE_STATION) && | ||
715 | (sc->sc_flags & SC_OP_BEACONS) && | ||
716 | !avp->primary_sta_vif) { | ||
717 | ath_dbg(common, ATH_DBG_CONFIG, | ||
718 | "Beacon already configured for a station interface\n"); | ||
719 | return false; | ||
720 | } | ||
721 | return true; | ||
722 | } | ||
703 | 723 | ||
724 | void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) | ||
725 | { | ||
726 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | ||
727 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | ||
728 | |||
729 | if (!ath9k_allow_beacon_config(sc, vif)) | ||
730 | return; | ||
731 | |||
732 | /* Setup the beacon configuration parameters */ | ||
733 | cur_conf->beacon_interval = bss_conf->beacon_int; | ||
734 | cur_conf->dtim_period = bss_conf->dtim_period; | ||
704 | cur_conf->listen_interval = 1; | 735 | cur_conf->listen_interval = 1; |
705 | cur_conf->dtim_count = 1; | 736 | cur_conf->dtim_count = 1; |
706 | cur_conf->bmiss_timeout = | 737 | cur_conf->bmiss_timeout = |
@@ -723,9 +754,37 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
723 | if (cur_conf->dtim_period == 0) | 754 | if (cur_conf->dtim_period == 0) |
724 | cur_conf->dtim_period = 1; | 755 | cur_conf->dtim_period = 1; |
725 | 756 | ||
726 | switch (iftype) { | 757 | ath_set_beacon(sc); |
758 | } | ||
759 | |||
760 | static bool ath_has_valid_bslot(struct ath_softc *sc) | ||
761 | { | ||
762 | struct ath_vif *avp; | ||
763 | int slot; | ||
764 | bool found = false; | ||
765 | |||
766 | for (slot = 0; slot < ATH_BCBUF; slot++) { | ||
767 | if (sc->beacon.bslot[slot]) { | ||
768 | avp = (void *)sc->beacon.bslot[slot]->drv_priv; | ||
769 | if (avp->is_bslot_active) { | ||
770 | found = true; | ||
771 | break; | ||
772 | } | ||
773 | } | ||
774 | } | ||
775 | return found; | ||
776 | } | ||
777 | |||
778 | |||
779 | void ath_set_beacon(struct ath_softc *sc) | ||
780 | { | ||
781 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
782 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | ||
783 | |||
784 | switch (sc->sc_ah->opmode) { | ||
727 | case NL80211_IFTYPE_AP: | 785 | case NL80211_IFTYPE_AP: |
728 | ath_beacon_config_ap(sc, cur_conf); | 786 | if (ath_has_valid_bslot(sc)) |
787 | ath_beacon_config_ap(sc, cur_conf); | ||
729 | break; | 788 | break; |
730 | case NL80211_IFTYPE_ADHOC: | 789 | case NL80211_IFTYPE_ADHOC: |
731 | case NL80211_IFTYPE_MESH_POINT: | 790 | case NL80211_IFTYPE_MESH_POINT: |
@@ -746,26 +805,15 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
746 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) | 805 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) |
747 | { | 806 | { |
748 | struct ath_hw *ah = sc->sc_ah; | 807 | struct ath_hw *ah = sc->sc_ah; |
749 | struct ath_vif *avp; | 808 | |
750 | int slot; | 809 | if (!ath_has_valid_bslot(sc)) |
751 | bool found = false; | 810 | return; |
752 | 811 | ||
753 | ath9k_ps_wakeup(sc); | 812 | ath9k_ps_wakeup(sc); |
754 | if (status) { | 813 | if (status) { |
755 | for (slot = 0; slot < ATH_BCBUF; slot++) { | 814 | /* Re-enable beaconing */ |
756 | if (sc->beacon.bslot[slot]) { | 815 | ah->imask |= ATH9K_INT_SWBA; |
757 | avp = (void *)sc->beacon.bslot[slot]->drv_priv; | 816 | ath9k_hw_set_interrupts(ah, ah->imask); |
758 | if (avp->is_bslot_active) { | ||
759 | found = true; | ||
760 | break; | ||
761 | } | ||
762 | } | ||
763 | } | ||
764 | if (found) { | ||
765 | /* Re-enable beaconing */ | ||
766 | ah->imask |= ATH9K_INT_SWBA; | ||
767 | ath9k_hw_set_interrupts(ah, ah->imask); | ||
768 | } | ||
769 | } else { | 817 | } else { |
770 | /* Disable SWBA interrupt */ | 818 | /* Disable SWBA interrupt */ |
771 | ah->imask &= ~ATH9K_INT_SWBA; | 819 | ah->imask &= ~ATH9K_INT_SWBA; |
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index d33bf204c99..23f15a7ca7f 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c | |||
@@ -51,6 +51,10 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) | |||
51 | .bt_hold_rx_clear = true, | 51 | .bt_hold_rx_clear = true, |
52 | }; | 52 | }; |
53 | u32 i; | 53 | u32 i; |
54 | bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity; | ||
55 | |||
56 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
57 | rxclear_polarity = !ath_bt_config.bt_rxclear_polarity; | ||
54 | 58 | ||
55 | btcoex_hw->bt_coex_mode = | 59 | btcoex_hw->bt_coex_mode = |
56 | (btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) | | 60 | (btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) | |
@@ -59,7 +63,7 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) | |||
59 | SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) | | 63 | SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) | |
60 | SM(ath_bt_config.bt_mode, AR_BT_MODE) | | 64 | SM(ath_bt_config.bt_mode, AR_BT_MODE) | |
61 | SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) | | 65 | SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) | |
62 | SM(ath_bt_config.bt_rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) | | 66 | SM(rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) | |
63 | SM(ath_bt_config.bt_priority_time, AR_BT_PRIORITY_TIME) | | 67 | SM(ath_bt_config.bt_priority_time, AR_BT_PRIORITY_TIME) | |
64 | SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) | | 68 | SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) | |
65 | SM(qnum, AR_BT_QCU_THRESH); | 69 | SM(qnum, AR_BT_QCU_THRESH); |
@@ -142,6 +146,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, | |||
142 | } | 146 | } |
143 | EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); | 147 | EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); |
144 | 148 | ||
149 | |||
145 | static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) | 150 | static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) |
146 | { | 151 | { |
147 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | 152 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; |
@@ -152,9 +157,22 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) | |||
152 | * enable coex 3-wire | 157 | * enable coex 3-wire |
153 | */ | 158 | */ |
154 | REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_hw->bt_coex_mode); | 159 | REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_hw->bt_coex_mode); |
155 | REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights); | ||
156 | REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2); | 160 | REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2); |
157 | 161 | ||
162 | |||
163 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
164 | REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, ah->bt_coex_wlan_weight[0]); | ||
165 | REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, ah->bt_coex_wlan_weight[1]); | ||
166 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, ah->bt_coex_bt_weight[0]); | ||
167 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, ah->bt_coex_bt_weight[1]); | ||
168 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, ah->bt_coex_bt_weight[2]); | ||
169 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, ah->bt_coex_bt_weight[3]); | ||
170 | |||
171 | } else | ||
172 | REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights); | ||
173 | |||
174 | |||
175 | |||
158 | if (AR_SREV_9271(ah)) { | 176 | if (AR_SREV_9271(ah)) { |
159 | val = REG_READ(ah, 0x50040); | 177 | val = REG_READ(ah, 0x50040); |
160 | val &= 0xFFFFFEFF; | 178 | val &= 0xFFFFFEFF; |
@@ -202,10 +220,86 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah) | |||
202 | 220 | ||
203 | if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) { | 221 | if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) { |
204 | REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE); | 222 | REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE); |
205 | REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0); | ||
206 | REG_WRITE(ah, AR_BT_COEX_MODE2, 0); | 223 | REG_WRITE(ah, AR_BT_COEX_MODE2, 0); |
224 | |||
225 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
226 | REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, 0); | ||
227 | REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, 0); | ||
228 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, 0); | ||
229 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, 0); | ||
230 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, 0); | ||
231 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, 0); | ||
232 | } else | ||
233 | REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0); | ||
234 | |||
207 | } | 235 | } |
208 | 236 | ||
209 | ah->btcoex_hw.enabled = false; | 237 | ah->btcoex_hw.enabled = false; |
210 | } | 238 | } |
211 | EXPORT_SYMBOL(ath9k_hw_btcoex_disable); | 239 | EXPORT_SYMBOL(ath9k_hw_btcoex_disable); |
240 | |||
241 | static void ar9003_btcoex_bt_stomp(struct ath_hw *ah, | ||
242 | enum ath_stomp_type stomp_type) | ||
243 | { | ||
244 | ah->bt_coex_bt_weight[0] = AR9300_BT_WGHT; | ||
245 | ah->bt_coex_bt_weight[1] = AR9300_BT_WGHT; | ||
246 | ah->bt_coex_bt_weight[2] = AR9300_BT_WGHT; | ||
247 | ah->bt_coex_bt_weight[3] = AR9300_BT_WGHT; | ||
248 | |||
249 | |||
250 | switch (stomp_type) { | ||
251 | case ATH_BTCOEX_STOMP_ALL: | ||
252 | ah->bt_coex_wlan_weight[0] = AR9300_STOMP_ALL_WLAN_WGHT0; | ||
253 | ah->bt_coex_wlan_weight[1] = AR9300_STOMP_ALL_WLAN_WGHT1; | ||
254 | break; | ||
255 | case ATH_BTCOEX_STOMP_LOW: | ||
256 | ah->bt_coex_wlan_weight[0] = AR9300_STOMP_LOW_WLAN_WGHT0; | ||
257 | ah->bt_coex_wlan_weight[1] = AR9300_STOMP_LOW_WLAN_WGHT1; | ||
258 | break; | ||
259 | case ATH_BTCOEX_STOMP_NONE: | ||
260 | ah->bt_coex_wlan_weight[0] = AR9300_STOMP_NONE_WLAN_WGHT0; | ||
261 | ah->bt_coex_wlan_weight[1] = AR9300_STOMP_NONE_WLAN_WGHT1; | ||
262 | break; | ||
263 | |||
264 | default: | ||
265 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
266 | "Invalid Stomptype\n"); | ||
267 | break; | ||
268 | } | ||
269 | |||
270 | ath9k_hw_btcoex_enable(ah); | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * Configures appropriate weight based on stomp type. | ||
275 | */ | ||
276 | void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, | ||
277 | enum ath_stomp_type stomp_type) | ||
278 | { | ||
279 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
280 | ar9003_btcoex_bt_stomp(ah, stomp_type); | ||
281 | return; | ||
282 | } | ||
283 | |||
284 | switch (stomp_type) { | ||
285 | case ATH_BTCOEX_STOMP_ALL: | ||
286 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
287 | AR_STOMP_ALL_WLAN_WGHT); | ||
288 | break; | ||
289 | case ATH_BTCOEX_STOMP_LOW: | ||
290 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
291 | AR_STOMP_LOW_WLAN_WGHT); | ||
292 | break; | ||
293 | case ATH_BTCOEX_STOMP_NONE: | ||
294 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
295 | AR_STOMP_NONE_WLAN_WGHT); | ||
296 | break; | ||
297 | default: | ||
298 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
299 | "Invalid Stomptype\n"); | ||
300 | break; | ||
301 | } | ||
302 | |||
303 | ath9k_hw_btcoex_enable(ah); | ||
304 | } | ||
305 | EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp); | ||
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h index 588dfd464dd..a9efca83d67 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/drivers/net/wireless/ath/ath9k/btcoex.h | |||
@@ -19,9 +19,13 @@ | |||
19 | 19 | ||
20 | #include "hw.h" | 20 | #include "hw.h" |
21 | 21 | ||
22 | #define ATH_WLANACTIVE_GPIO 5 | 22 | #define ATH_WLANACTIVE_GPIO_9280 5 |
23 | #define ATH_BTACTIVE_GPIO 6 | 23 | #define ATH_BTACTIVE_GPIO_9280 6 |
24 | #define ATH_BTPRIORITY_GPIO 7 | 24 | #define ATH_BTPRIORITY_GPIO_9285 7 |
25 | |||
26 | #define ATH_WLANACTIVE_GPIO_9300 5 | ||
27 | #define ATH_BTACTIVE_GPIO_9300 4 | ||
28 | #define ATH_BTPRIORITY_GPIO_9300 8 | ||
25 | 29 | ||
26 | #define ATH_BTCOEX_DEF_BT_PERIOD 45 | 30 | #define ATH_BTCOEX_DEF_BT_PERIOD 45 |
27 | #define ATH_BTCOEX_DEF_DUTY_CYCLE 55 | 31 | #define ATH_BTCOEX_DEF_DUTY_CYCLE 55 |
@@ -32,6 +36,14 @@ | |||
32 | #define ATH_BT_CNT_THRESHOLD 3 | 36 | #define ATH_BT_CNT_THRESHOLD 3 |
33 | #define ATH_BT_CNT_SCAN_THRESHOLD 15 | 37 | #define ATH_BT_CNT_SCAN_THRESHOLD 15 |
34 | 38 | ||
39 | /* Defines the BT AR_BT_COEX_WGHT used */ | ||
40 | enum ath_stomp_type { | ||
41 | ATH_BTCOEX_NO_STOMP, | ||
42 | ATH_BTCOEX_STOMP_ALL, | ||
43 | ATH_BTCOEX_STOMP_LOW, | ||
44 | ATH_BTCOEX_STOMP_NONE | ||
45 | }; | ||
46 | |||
35 | enum ath_btcoex_scheme { | 47 | enum ath_btcoex_scheme { |
36 | ATH_BTCOEX_CFG_NONE, | 48 | ATH_BTCOEX_CFG_NONE, |
37 | ATH_BTCOEX_CFG_2WIRE, | 49 | ATH_BTCOEX_CFG_2WIRE, |
@@ -57,5 +69,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, | |||
57 | u32 wlan_weight); | 69 | u32 wlan_weight); |
58 | void ath9k_hw_btcoex_enable(struct ath_hw *ah); | 70 | void ath9k_hw_btcoex_enable(struct ath_hw *ah); |
59 | void ath9k_hw_btcoex_disable(struct ath_hw *ah); | 71 | void ath9k_hw_btcoex_disable(struct ath_hw *ah); |
72 | void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, | ||
73 | enum ath_stomp_type stomp_type); | ||
60 | 74 | ||
61 | #endif | 75 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 8649581fa4d..558b228a717 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c | |||
@@ -69,15 +69,21 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah, | |||
69 | int16_t *nfarray) | 69 | int16_t *nfarray) |
70 | { | 70 | { |
71 | struct ath_common *common = ath9k_hw_common(ah); | 71 | struct ath_common *common = ath9k_hw_common(ah); |
72 | struct ieee80211_conf *conf = &common->hw->conf; | ||
72 | struct ath_nf_limits *limit; | 73 | struct ath_nf_limits *limit; |
73 | struct ath9k_nfcal_hist *h; | 74 | struct ath9k_nfcal_hist *h; |
74 | bool high_nf_mid = false; | 75 | bool high_nf_mid = false; |
76 | u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; | ||
75 | int i; | 77 | int i; |
76 | 78 | ||
77 | h = cal->nfCalHist; | 79 | h = cal->nfCalHist; |
78 | limit = ath9k_hw_get_nf_limits(ah, ah->curchan); | 80 | limit = ath9k_hw_get_nf_limits(ah, ah->curchan); |
79 | 81 | ||
80 | for (i = 0; i < NUM_NF_READINGS; i++) { | 82 | for (i = 0; i < NUM_NF_READINGS; i++) { |
83 | if (!(chainmask & (1 << i)) || | ||
84 | ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))) | ||
85 | continue; | ||
86 | |||
81 | h[i].nfCalBuffer[h[i].currIndex] = nfarray[i]; | 87 | h[i].nfCalBuffer[h[i].currIndex] = nfarray[i]; |
82 | 88 | ||
83 | if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX) | 89 | if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX) |
@@ -225,6 +231,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) | |||
225 | int32_t val; | 231 | int32_t val; |
226 | u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; | 232 | u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; |
227 | struct ath_common *common = ath9k_hw_common(ah); | 233 | struct ath_common *common = ath9k_hw_common(ah); |
234 | struct ieee80211_conf *conf = &common->hw->conf; | ||
228 | s16 default_nf = ath9k_hw_get_default_nf(ah, chan); | 235 | s16 default_nf = ath9k_hw_get_default_nf(ah, chan); |
229 | 236 | ||
230 | if (ah->caldata) | 237 | if (ah->caldata) |
@@ -234,6 +241,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) | |||
234 | if (chainmask & (1 << i)) { | 241 | if (chainmask & (1 << i)) { |
235 | s16 nfval; | 242 | s16 nfval; |
236 | 243 | ||
244 | if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)) | ||
245 | continue; | ||
246 | |||
237 | if (h) | 247 | if (h) |
238 | nfval = h[i].privNF; | 248 | nfval = h[i].privNF; |
239 | else | 249 | else |
@@ -293,6 +303,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) | |||
293 | ENABLE_REGWRITE_BUFFER(ah); | 303 | ENABLE_REGWRITE_BUFFER(ah); |
294 | for (i = 0; i < NUM_NF_READINGS; i++) { | 304 | for (i = 0; i < NUM_NF_READINGS; i++) { |
295 | if (chainmask & (1 << i)) { | 305 | if (chainmask & (1 << i)) { |
306 | if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)) | ||
307 | continue; | ||
308 | |||
296 | val = REG_READ(ah, ah->nf_regs[i]); | 309 | val = REG_READ(ah, ah->nf_regs[i]); |
297 | val &= 0xFFFFFE00; | 310 | val &= 0xFFFFFE00; |
298 | val |= (((u32) (-50) << 1) & 0x1ff); | 311 | val |= (((u32) (-50) << 1) & 0x1ff); |
@@ -396,14 +409,6 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, | |||
396 | } | 409 | } |
397 | } | 410 | } |
398 | 411 | ||
399 | s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) | ||
400 | { | ||
401 | if (!ah->curchan || !ah->curchan->noisefloor) | ||
402 | return ath9k_hw_get_default_nf(ah, chan); | ||
403 | |||
404 | return ah->curchan->noisefloor; | ||
405 | } | ||
406 | EXPORT_SYMBOL(ath9k_hw_getchan_noise); | ||
407 | 412 | ||
408 | void ath9k_hw_bstuck_nfcal(struct ath_hw *ah) | 413 | void ath9k_hw_bstuck_nfcal(struct ath_hw *ah) |
409 | { | 414 | { |
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index b8973eb8d85..4420780fa3b 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h | |||
@@ -106,7 +106,6 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan); | |||
106 | void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, | 106 | void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, |
107 | struct ath9k_channel *chan); | 107 | struct ath9k_channel *chan); |
108 | void ath9k_hw_bstuck_nfcal(struct ath_hw *ah); | 108 | void ath9k_hw_bstuck_nfcal(struct ath_hw *ah); |
109 | s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan); | ||
110 | void ath9k_hw_reset_calibration(struct ath_hw *ah, | 109 | void ath9k_hw_reset_calibration(struct ath_hw *ah, |
111 | struct ath9k_cal_list *currCal); | 110 | struct ath9k_cal_list *currCal); |
112 | 111 | ||
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 615e68276e7..74535e6dfb8 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c | |||
@@ -116,7 +116,7 @@ void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, | |||
116 | 116 | ||
117 | if (chan->band == IEEE80211_BAND_2GHZ) { | 117 | if (chan->band == IEEE80211_BAND_2GHZ) { |
118 | ichan->chanmode = CHANNEL_G; | 118 | ichan->chanmode = CHANNEL_G; |
119 | ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G; | 119 | ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM; |
120 | } else { | 120 | } else { |
121 | ichan->chanmode = CHANNEL_A; | 121 | ichan->chanmode = CHANNEL_A; |
122 | ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; | 122 | ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; |
@@ -158,37 +158,6 @@ int ath9k_cmn_count_streams(unsigned int chainmask, int max) | |||
158 | } | 158 | } |
159 | EXPORT_SYMBOL(ath9k_cmn_count_streams); | 159 | EXPORT_SYMBOL(ath9k_cmn_count_streams); |
160 | 160 | ||
161 | /* | ||
162 | * Configures appropriate weight based on stomp type. | ||
163 | */ | ||
164 | void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common, | ||
165 | enum ath_stomp_type stomp_type) | ||
166 | { | ||
167 | struct ath_hw *ah = common->ah; | ||
168 | |||
169 | switch (stomp_type) { | ||
170 | case ATH_BTCOEX_STOMP_ALL: | ||
171 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
172 | AR_STOMP_ALL_WLAN_WGHT); | ||
173 | break; | ||
174 | case ATH_BTCOEX_STOMP_LOW: | ||
175 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
176 | AR_STOMP_LOW_WLAN_WGHT); | ||
177 | break; | ||
178 | case ATH_BTCOEX_STOMP_NONE: | ||
179 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
180 | AR_STOMP_NONE_WLAN_WGHT); | ||
181 | break; | ||
182 | default: | ||
183 | ath_dbg(common, ATH_DBG_BTCOEX, | ||
184 | "Invalid Stomptype\n"); | ||
185 | break; | ||
186 | } | ||
187 | |||
188 | ath9k_hw_btcoex_enable(ah); | ||
189 | } | ||
190 | EXPORT_SYMBOL(ath9k_cmn_btcoex_bt_stomp); | ||
191 | |||
192 | void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, | 161 | void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, |
193 | u16 new_txpow, u16 *txpower) | 162 | u16 new_txpow, u16 *txpower) |
194 | { | 163 | { |
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index b2f7b5f8909..5124f1420b3 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -50,14 +50,6 @@ | |||
50 | #define ATH_EP_RND(x, mul) \ | 50 | #define ATH_EP_RND(x, mul) \ |
51 | ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) | 51 | ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) |
52 | 52 | ||
53 | /* Defines the BT AR_BT_COEX_WGHT used */ | ||
54 | enum ath_stomp_type { | ||
55 | ATH_BTCOEX_NO_STOMP, | ||
56 | ATH_BTCOEX_STOMP_ALL, | ||
57 | ATH_BTCOEX_STOMP_LOW, | ||
58 | ATH_BTCOEX_STOMP_NONE | ||
59 | }; | ||
60 | |||
61 | int ath9k_cmn_padpos(__le16 frame_control); | 53 | int ath9k_cmn_padpos(__le16 frame_control); |
62 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); | 54 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); |
63 | void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, | 55 | void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 8df5a92a20f..bad1a87249b 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -326,6 +326,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) | |||
326 | sc->debug.stats.istats.dtimsync++; | 326 | sc->debug.stats.istats.dtimsync++; |
327 | if (status & ATH9K_INT_DTIM) | 327 | if (status & ATH9K_INT_DTIM) |
328 | sc->debug.stats.istats.dtim++; | 328 | sc->debug.stats.istats.dtim++; |
329 | if (status & ATH9K_INT_TSFOOR) | ||
330 | sc->debug.stats.istats.tsfoor++; | ||
329 | } | 331 | } |
330 | 332 | ||
331 | static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, | 333 | static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, |
@@ -380,8 +382,11 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, | |||
380 | len += snprintf(buf + len, sizeof(buf) - len, | 382 | len += snprintf(buf + len, sizeof(buf) - len, |
381 | "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim); | 383 | "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim); |
382 | len += snprintf(buf + len, sizeof(buf) - len, | 384 | len += snprintf(buf + len, sizeof(buf) - len, |
385 | "%8s: %10u\n", "TSFOOR", sc->debug.stats.istats.tsfoor); | ||
386 | len += snprintf(buf + len, sizeof(buf) - len, | ||
383 | "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total); | 387 | "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total); |
384 | 388 | ||
389 | |||
385 | if (len > sizeof(buf)) | 390 | if (len > sizeof(buf)) |
386 | len = sizeof(buf); | 391 | len = sizeof(buf); |
387 | 392 | ||
@@ -845,7 +850,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
845 | 850 | ||
846 | struct ath_softc *sc = file->private_data; | 851 | struct ath_softc *sc = file->private_data; |
847 | char *buf; | 852 | char *buf; |
848 | unsigned int len = 0, size = 1152; | 853 | unsigned int len = 0, size = 1400; |
849 | ssize_t retval = 0; | 854 | ssize_t retval = 0; |
850 | 855 | ||
851 | buf = kzalloc(size, GFP_KERNEL); | 856 | buf = kzalloc(size, GFP_KERNEL); |
@@ -874,6 +879,34 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
874 | "%18s : %10u\n", "DECRYPT BUSY ERR", | 879 | "%18s : %10u\n", "DECRYPT BUSY ERR", |
875 | sc->debug.stats.rxstats.decrypt_busy_err); | 880 | sc->debug.stats.rxstats.decrypt_busy_err); |
876 | 881 | ||
882 | len += snprintf(buf + len, size - len, | ||
883 | "%18s : %10d\n", "RSSI-CTL0", | ||
884 | sc->debug.stats.rxstats.rs_rssi_ctl0); | ||
885 | |||
886 | len += snprintf(buf + len, size - len, | ||
887 | "%18s : %10d\n", "RSSI-CTL1", | ||
888 | sc->debug.stats.rxstats.rs_rssi_ctl1); | ||
889 | |||
890 | len += snprintf(buf + len, size - len, | ||
891 | "%18s : %10d\n", "RSSI-CTL2", | ||
892 | sc->debug.stats.rxstats.rs_rssi_ctl2); | ||
893 | |||
894 | len += snprintf(buf + len, size - len, | ||
895 | "%18s : %10d\n", "RSSI-EXT0", | ||
896 | sc->debug.stats.rxstats.rs_rssi_ext0); | ||
897 | |||
898 | len += snprintf(buf + len, size - len, | ||
899 | "%18s : %10d\n", "RSSI-EXT1", | ||
900 | sc->debug.stats.rxstats.rs_rssi_ext1); | ||
901 | |||
902 | len += snprintf(buf + len, size - len, | ||
903 | "%18s : %10d\n", "RSSI-EXT2", | ||
904 | sc->debug.stats.rxstats.rs_rssi_ext2); | ||
905 | |||
906 | len += snprintf(buf + len, size - len, | ||
907 | "%18s : %10d\n", "Rx Antenna", | ||
908 | sc->debug.stats.rxstats.rs_antenna); | ||
909 | |||
877 | PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); | 910 | PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); |
878 | PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); | 911 | PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); |
879 | PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); | 912 | PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); |
@@ -948,6 +981,16 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) | |||
948 | RX_PHY_ERR_INC(phyerr); | 981 | RX_PHY_ERR_INC(phyerr); |
949 | } | 982 | } |
950 | 983 | ||
984 | sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0; | ||
985 | sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1; | ||
986 | sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2; | ||
987 | |||
988 | sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0; | ||
989 | sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1; | ||
990 | sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2; | ||
991 | |||
992 | sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; | ||
993 | |||
951 | #undef RX_STAT_INC | 994 | #undef RX_STAT_INC |
952 | #undef RX_PHY_ERR_INC | 995 | #undef RX_PHY_ERR_INC |
953 | } | 996 | } |
@@ -1088,67 +1131,43 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1088 | return -ENOMEM; | 1131 | return -ENOMEM; |
1089 | 1132 | ||
1090 | #ifdef CONFIG_ATH_DEBUG | 1133 | #ifdef CONFIG_ATH_DEBUG |
1091 | if (!debugfs_create_file("debug", S_IRUSR | S_IWUSR, | 1134 | debugfs_create_file("debug", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, |
1092 | sc->debug.debugfs_phy, sc, &fops_debug)) | 1135 | sc, &fops_debug); |
1093 | goto err; | ||
1094 | #endif | 1136 | #endif |
1095 | 1137 | debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, | |
1096 | if (!debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, | 1138 | &fops_dma); |
1097 | sc, &fops_dma)) | 1139 | debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc, |
1098 | goto err; | 1140 | &fops_interrupt); |
1099 | 1141 | debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | |
1100 | if (!debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, | 1142 | sc, &fops_wiphy); |
1101 | sc, &fops_interrupt)) | 1143 | debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, |
1102 | goto err; | 1144 | &fops_xmit); |
1103 | 1145 | debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc, | |
1104 | if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, | 1146 | &fops_stations); |
1105 | sc->debug.debugfs_phy, sc, &fops_wiphy)) | 1147 | debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, |
1106 | goto err; | 1148 | &fops_misc); |
1107 | 1149 | debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc, | |
1108 | if (!debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, | 1150 | &fops_recv); |
1109 | sc, &fops_xmit)) | 1151 | debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR, |
1110 | goto err; | 1152 | sc->debug.debugfs_phy, sc, &fops_rx_chainmask); |
1111 | 1153 | debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR, | |
1112 | if (!debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, | 1154 | sc->debug.debugfs_phy, sc, &fops_tx_chainmask); |
1113 | sc, &fops_stations)) | 1155 | debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, |
1114 | goto err; | 1156 | sc, &fops_regidx); |
1115 | 1157 | debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | |
1116 | if (!debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, | 1158 | sc, &fops_regval); |
1117 | sc, &fops_misc)) | 1159 | debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR, |
1118 | goto err; | 1160 | sc->debug.debugfs_phy, |
1119 | 1161 | &ah->config.cwm_ignore_extcca); | |
1120 | if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, | 1162 | debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc, |
1121 | sc, &fops_recv)) | 1163 | &fops_regdump); |
1122 | goto err; | 1164 | |
1123 | 1165 | debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, | |
1124 | if (!debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR, | 1166 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); |
1125 | sc->debug.debugfs_phy, sc, &fops_rx_chainmask)) | 1167 | |
1126 | goto err; | 1168 | debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, |
1127 | 1169 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); | |
1128 | if (!debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR, | ||
1129 | sc->debug.debugfs_phy, sc, &fops_tx_chainmask)) | ||
1130 | goto err; | ||
1131 | |||
1132 | if (!debugfs_create_file("regidx", S_IRUSR | S_IWUSR, | ||
1133 | sc->debug.debugfs_phy, sc, &fops_regidx)) | ||
1134 | goto err; | ||
1135 | |||
1136 | if (!debugfs_create_file("regval", S_IRUSR | S_IWUSR, | ||
1137 | sc->debug.debugfs_phy, sc, &fops_regval)) | ||
1138 | goto err; | ||
1139 | |||
1140 | if (!debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR, | ||
1141 | sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca)) | ||
1142 | goto err; | ||
1143 | |||
1144 | if (!debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, | ||
1145 | sc, &fops_regdump)) | ||
1146 | goto err; | ||
1147 | 1170 | ||
1148 | sc->debug.regidx = 0; | 1171 | sc->debug.regidx = 0; |
1149 | return 0; | 1172 | return 0; |
1150 | err: | ||
1151 | debugfs_remove_recursive(sc->debug.debugfs_phy); | ||
1152 | sc->debug.debugfs_phy = NULL; | ||
1153 | return -ENOMEM; | ||
1154 | } | 1173 | } |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 59338de0ce1..5488a324cc1 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -54,6 +54,9 @@ struct ath_buf; | |||
54 | * @dtimsync: DTIM sync lossage | 54 | * @dtimsync: DTIM sync lossage |
55 | * @dtim: RX Beacon with DTIM | 55 | * @dtim: RX Beacon with DTIM |
56 | * @bb_watchdog: Baseband watchdog | 56 | * @bb_watchdog: Baseband watchdog |
57 | * @tsfoor: TSF out of range, indicates that the corrected TSF received | ||
58 | * from a beacon differs from the PCU's internal TSF by more than a | ||
59 | * (programmable) threshold | ||
57 | */ | 60 | */ |
58 | struct ath_interrupt_stats { | 61 | struct ath_interrupt_stats { |
59 | u32 total; | 62 | u32 total; |
@@ -78,6 +81,7 @@ struct ath_interrupt_stats { | |||
78 | u32 dtimsync; | 81 | u32 dtimsync; |
79 | u32 dtim; | 82 | u32 dtim; |
80 | u32 bb_watchdog; | 83 | u32 bb_watchdog; |
84 | u32 tsfoor; | ||
81 | }; | 85 | }; |
82 | 86 | ||
83 | /** | 87 | /** |
@@ -157,6 +161,13 @@ struct ath_rx_stats { | |||
157 | u32 post_delim_crc_err; | 161 | u32 post_delim_crc_err; |
158 | u32 decrypt_busy_err; | 162 | u32 decrypt_busy_err; |
159 | u32 phy_err_stats[ATH9K_PHYERR_MAX]; | 163 | u32 phy_err_stats[ATH9K_PHYERR_MAX]; |
164 | int8_t rs_rssi_ctl0; | ||
165 | int8_t rs_rssi_ctl1; | ||
166 | int8_t rs_rssi_ctl2; | ||
167 | int8_t rs_rssi_ext0; | ||
168 | int8_t rs_rssi_ext1; | ||
169 | int8_t rs_rssi_ext2; | ||
170 | u8 rs_antenna; | ||
160 | }; | 171 | }; |
161 | 172 | ||
162 | struct ath_stats { | 173 | struct ath_stats { |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index bd82447f5b7..3e316133f11 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -436,7 +436,11 @@ struct modal_eep_4k_header { | |||
436 | u8 db2_2:4, db2_3:4; | 436 | u8 db2_2:4, db2_3:4; |
437 | u8 db2_4:4, reserved:4; | 437 | u8 db2_4:4, reserved:4; |
438 | #endif | 438 | #endif |
439 | u8 futureModal[4]; | 439 | u8 tx_diversity; |
440 | u8 flc_pwr_thresh; | ||
441 | u8 bb_scale_smrt_antenna; | ||
442 | #define EEP_4K_BB_DESIRED_SCALE_MASK 0x1f | ||
443 | u8 futureModal[1]; | ||
440 | struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; | 444 | struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; |
441 | } __packed; | 445 | } __packed; |
442 | 446 | ||
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index bc77a308c90..6f714dd7236 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c | |||
@@ -781,6 +781,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, | |||
781 | { | 781 | { |
782 | struct modal_eep_4k_header *pModal; | 782 | struct modal_eep_4k_header *pModal; |
783 | struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; | 783 | struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; |
784 | struct base_eep_header_4k *pBase = &eep->baseEepHeader; | ||
784 | u8 txRxAttenLocal; | 785 | u8 txRxAttenLocal; |
785 | u8 ob[5], db1[5], db2[5]; | 786 | u8 ob[5], db1[5], db2[5]; |
786 | u8 ant_div_control1, ant_div_control2; | 787 | u8 ant_div_control1, ant_div_control2; |
@@ -1003,6 +1004,31 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, | |||
1003 | AR_PHY_SETTLING_SWITCH, | 1004 | AR_PHY_SETTLING_SWITCH, |
1004 | pModal->swSettleHt40); | 1005 | pModal->swSettleHt40); |
1005 | } | 1006 | } |
1007 | if (AR_SREV_9271(ah) || AR_SREV_9285(ah)) { | ||
1008 | u8 bb_desired_scale = (pModal->bb_scale_smrt_antenna & | ||
1009 | EEP_4K_BB_DESIRED_SCALE_MASK); | ||
1010 | if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) { | ||
1011 | u32 pwrctrl, mask, clr; | ||
1012 | |||
1013 | mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25); | ||
1014 | pwrctrl = mask * bb_desired_scale; | ||
1015 | clr = mask * 0x1f; | ||
1016 | REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr); | ||
1017 | REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr); | ||
1018 | REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr); | ||
1019 | |||
1020 | mask = BIT(0)|BIT(5)|BIT(15); | ||
1021 | pwrctrl = mask * bb_desired_scale; | ||
1022 | clr = mask * 0x1f; | ||
1023 | REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr); | ||
1024 | |||
1025 | mask = BIT(0)|BIT(5); | ||
1026 | pwrctrl = mask * bb_desired_scale; | ||
1027 | clr = mask * 0x1f; | ||
1028 | REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr); | ||
1029 | REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr); | ||
1030 | } | ||
1031 | } | ||
1006 | } | 1032 | } |
1007 | 1033 | ||
1008 | static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) | 1034 | static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 8cd8333cc08..b87db476309 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c | |||
@@ -319,10 +319,9 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, | |||
319 | u16 numXpdGain, xpdMask; | 319 | u16 numXpdGain, xpdMask; |
320 | u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0}; | 320 | u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0}; |
321 | u32 reg32, regOffset, regChainOffset, regval; | 321 | u32 reg32, regOffset, regChainOffset, regval; |
322 | int16_t modalIdx, diff = 0; | 322 | int16_t diff = 0; |
323 | struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; | 323 | struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; |
324 | 324 | ||
325 | modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; | ||
326 | xpdMask = pEepData->modalHeader.xpdGain; | 325 | xpdMask = pEepData->modalHeader.xpdGain; |
327 | 326 | ||
328 | if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= | 327 | if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= |
@@ -392,6 +391,8 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, | |||
392 | numXpdGain); | 391 | numXpdGain); |
393 | } | 392 | } |
394 | 393 | ||
394 | ENABLE_REGWRITE_BUFFER(ah); | ||
395 | |||
395 | if (i == 0) { | 396 | if (i == 0) { |
396 | if (!ath9k_hw_ar9287_get_eeprom(ah, | 397 | if (!ath9k_hw_ar9287_get_eeprom(ah, |
397 | EEP_OL_PWRCTRL)) { | 398 | EEP_OL_PWRCTRL)) { |
@@ -442,6 +443,7 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, | |||
442 | regOffset += 4; | 443 | regOffset += 4; |
443 | } | 444 | } |
444 | } | 445 | } |
446 | REGWRITE_BUFFER_FLUSH(ah); | ||
445 | } | 447 | } |
446 | } | 448 | } |
447 | 449 | ||
@@ -757,6 +759,8 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, | |||
757 | ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; | 759 | ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; |
758 | } | 760 | } |
759 | 761 | ||
762 | ENABLE_REGWRITE_BUFFER(ah); | ||
763 | |||
760 | /* OFDM power per rate */ | 764 | /* OFDM power per rate */ |
761 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, | 765 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, |
762 | ATH9K_POW_SM(ratesArray[rate18mb], 24) | 766 | ATH9K_POW_SM(ratesArray[rate18mb], 24) |
@@ -840,6 +844,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, | |||
840 | | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) | 844 | | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) |
841 | | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); | 845 | | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); |
842 | } | 846 | } |
847 | REGWRITE_BUFFER_FLUSH(ah); | ||
843 | } | 848 | } |
844 | 849 | ||
845 | static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah, | 850 | static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah, |
@@ -852,35 +857,12 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah, | |||
852 | { | 857 | { |
853 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; | 858 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; |
854 | struct modal_eep_ar9287_header *pModal = &eep->modalHeader; | 859 | struct modal_eep_ar9287_header *pModal = &eep->modalHeader; |
855 | u16 antWrites[AR9287_ANT_16S]; | ||
856 | u32 regChainOffset, regval; | 860 | u32 regChainOffset, regval; |
857 | u8 txRxAttenLocal; | 861 | u8 txRxAttenLocal; |
858 | int i, j, offset_num; | 862 | int i; |
859 | 863 | ||
860 | pModal = &eep->modalHeader; | 864 | pModal = &eep->modalHeader; |
861 | 865 | ||
862 | antWrites[0] = (u16)((pModal->antCtrlCommon >> 28) & 0xF); | ||
863 | antWrites[1] = (u16)((pModal->antCtrlCommon >> 24) & 0xF); | ||
864 | antWrites[2] = (u16)((pModal->antCtrlCommon >> 20) & 0xF); | ||
865 | antWrites[3] = (u16)((pModal->antCtrlCommon >> 16) & 0xF); | ||
866 | antWrites[4] = (u16)((pModal->antCtrlCommon >> 12) & 0xF); | ||
867 | antWrites[5] = (u16)((pModal->antCtrlCommon >> 8) & 0xF); | ||
868 | antWrites[6] = (u16)((pModal->antCtrlCommon >> 4) & 0xF); | ||
869 | antWrites[7] = (u16)(pModal->antCtrlCommon & 0xF); | ||
870 | |||
871 | offset_num = 8; | ||
872 | |||
873 | for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) { | ||
874 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 28) & 0xf); | ||
875 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 10) & 0x3); | ||
876 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 8) & 0x3); | ||
877 | antWrites[j++] = 0; | ||
878 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 6) & 0x3); | ||
879 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 4) & 0x3); | ||
880 | antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 2) & 0x3); | ||
881 | antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3); | ||
882 | } | ||
883 | |||
884 | REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); | 866 | REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); |
885 | 867 | ||
886 | for (i = 0; i < AR9287_MAX_CHAINS; i++) { | 868 | for (i = 0; i < AR9287_MAX_CHAINS; i++) { |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index fccd87df730..c031854b569 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
@@ -231,6 +231,10 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) | |||
231 | integer = swab32(pModal->antCtrlChain[i]); | 231 | integer = swab32(pModal->antCtrlChain[i]); |
232 | pModal->antCtrlChain[i] = integer; | 232 | pModal->antCtrlChain[i] = integer; |
233 | } | 233 | } |
234 | for (i = 0; i < 3; i++) { | ||
235 | word = swab16(pModal->xpaBiasLvlFreq[i]); | ||
236 | pModal->xpaBiasLvlFreq[i] = word; | ||
237 | } | ||
234 | 238 | ||
235 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | 239 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { |
236 | word = swab16(pModal->spurChans[i].spurChan); | 240 | word = swab16(pModal->spurChans[i].spurChan); |
@@ -799,6 +803,8 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, | |||
799 | pwr_table_offset, | 803 | pwr_table_offset, |
800 | &diff); | 804 | &diff); |
801 | 805 | ||
806 | ENABLE_REGWRITE_BUFFER(ah); | ||
807 | |||
802 | if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { | 808 | if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { |
803 | if (OLC_FOR_AR9280_20_LATER) { | 809 | if (OLC_FOR_AR9280_20_LATER) { |
804 | REG_WRITE(ah, | 810 | REG_WRITE(ah, |
@@ -847,6 +853,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, | |||
847 | 853 | ||
848 | regOffset += 4; | 854 | regOffset += 4; |
849 | } | 855 | } |
856 | REGWRITE_BUFFER_FLUSH(ah); | ||
850 | } | 857 | } |
851 | } | 858 | } |
852 | 859 | ||
@@ -1205,6 +1212,8 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, | |||
1205 | } | 1212 | } |
1206 | } | 1213 | } |
1207 | 1214 | ||
1215 | ENABLE_REGWRITE_BUFFER(ah); | ||
1216 | |||
1208 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, | 1217 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, |
1209 | ATH9K_POW_SM(ratesArray[rate18mb], 24) | 1218 | ATH9K_POW_SM(ratesArray[rate18mb], 24) |
1210 | | ATH9K_POW_SM(ratesArray[rate12mb], 16) | 1219 | | ATH9K_POW_SM(ratesArray[rate12mb], 16) |
@@ -1291,6 +1300,8 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, | |||
1291 | REG_WRITE(ah, AR_PHY_POWER_TX_SUB, | 1300 | REG_WRITE(ah, AR_PHY_POWER_TX_SUB, |
1292 | ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) | 1301 | ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) |
1293 | | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)); | 1302 | | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)); |
1303 | |||
1304 | REGWRITE_BUFFER_FLUSH(ah); | ||
1294 | } | 1305 | } |
1295 | 1306 | ||
1296 | static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) | 1307 | static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 0fb8f8ac275..0349b3a1cc5 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -41,12 +41,16 @@ void ath_init_leds(struct ath_softc *sc) | |||
41 | { | 41 | { |
42 | int ret; | 42 | int ret; |
43 | 43 | ||
44 | if (AR_SREV_9287(sc->sc_ah)) | 44 | if (sc->sc_ah->led_pin < 0) { |
45 | sc->sc_ah->led_pin = ATH_LED_PIN_9287; | 45 | if (AR_SREV_9287(sc->sc_ah)) |
46 | else if (AR_SREV_9485(sc->sc_ah)) | 46 | sc->sc_ah->led_pin = ATH_LED_PIN_9287; |
47 | sc->sc_ah->led_pin = ATH_LED_PIN_9485; | 47 | else if (AR_SREV_9485(sc->sc_ah)) |
48 | else | 48 | sc->sc_ah->led_pin = ATH_LED_PIN_9485; |
49 | sc->sc_ah->led_pin = ATH_LED_PIN_DEF; | 49 | else if (AR_SREV_9300(sc->sc_ah)) |
50 | sc->sc_ah->led_pin = ATH_LED_PIN_9300; | ||
51 | else | ||
52 | sc->sc_ah->led_pin = ATH_LED_PIN_DEF; | ||
53 | } | ||
50 | 54 | ||
51 | /* Configure gpio 1 for output */ | 55 | /* Configure gpio 1 for output */ |
52 | ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, | 56 | ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, |
@@ -136,10 +140,10 @@ static void ath_detect_bt_priority(struct ath_softc *sc) | |||
136 | 140 | ||
137 | static void ath9k_gen_timer_start(struct ath_hw *ah, | 141 | static void ath9k_gen_timer_start(struct ath_hw *ah, |
138 | struct ath_gen_timer *timer, | 142 | struct ath_gen_timer *timer, |
139 | u32 timer_next, | 143 | u32 trig_timeout, |
140 | u32 timer_period) | 144 | u32 timer_period) |
141 | { | 145 | { |
142 | ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period); | 146 | ath9k_hw_gen_timer_start(ah, timer, trig_timeout, timer_period); |
143 | 147 | ||
144 | if ((ah->imask & ATH9K_INT_GENTIMER) == 0) { | 148 | if ((ah->imask & ATH9K_INT_GENTIMER) == 0) { |
145 | ath9k_hw_disable_interrupts(ah); | 149 | ath9k_hw_disable_interrupts(ah); |
@@ -172,17 +176,17 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
172 | struct ath_softc *sc = (struct ath_softc *) data; | 176 | struct ath_softc *sc = (struct ath_softc *) data; |
173 | struct ath_hw *ah = sc->sc_ah; | 177 | struct ath_hw *ah = sc->sc_ah; |
174 | struct ath_btcoex *btcoex = &sc->btcoex; | 178 | struct ath_btcoex *btcoex = &sc->btcoex; |
175 | struct ath_common *common = ath9k_hw_common(ah); | ||
176 | u32 timer_period; | 179 | u32 timer_period; |
177 | bool is_btscan; | 180 | bool is_btscan; |
178 | 181 | ||
182 | ath9k_ps_wakeup(sc); | ||
179 | ath_detect_bt_priority(sc); | 183 | ath_detect_bt_priority(sc); |
180 | 184 | ||
181 | is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | 185 | is_btscan = sc->sc_flags & SC_OP_BT_SCAN; |
182 | 186 | ||
183 | spin_lock_bh(&btcoex->btcoex_lock); | 187 | spin_lock_bh(&btcoex->btcoex_lock); |
184 | 188 | ||
185 | ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL : | 189 | ath9k_hw_btcoex_bt_stomp(ah, is_btscan ? ATH_BTCOEX_STOMP_ALL : |
186 | btcoex->bt_stomp_type); | 190 | btcoex->bt_stomp_type); |
187 | 191 | ||
188 | spin_unlock_bh(&btcoex->btcoex_lock); | 192 | spin_unlock_bh(&btcoex->btcoex_lock); |
@@ -193,11 +197,12 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
193 | 197 | ||
194 | timer_period = is_btscan ? btcoex->btscan_no_stomp : | 198 | timer_period = is_btscan ? btcoex->btscan_no_stomp : |
195 | btcoex->btcoex_no_stomp; | 199 | btcoex->btcoex_no_stomp; |
196 | ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, 0, | 200 | ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, timer_period, |
197 | timer_period * 10); | 201 | timer_period * 10); |
198 | btcoex->hw_timer_enabled = true; | 202 | btcoex->hw_timer_enabled = true; |
199 | } | 203 | } |
200 | 204 | ||
205 | ath9k_ps_restore(sc); | ||
201 | mod_timer(&btcoex->period_timer, jiffies + | 206 | mod_timer(&btcoex->period_timer, jiffies + |
202 | msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); | 207 | msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); |
203 | } | 208 | } |
@@ -217,14 +222,16 @@ static void ath_btcoex_no_stomp_timer(void *arg) | |||
217 | ath_dbg(common, ATH_DBG_BTCOEX, | 222 | ath_dbg(common, ATH_DBG_BTCOEX, |
218 | "no stomp timer running\n"); | 223 | "no stomp timer running\n"); |
219 | 224 | ||
225 | ath9k_ps_wakeup(sc); | ||
220 | spin_lock_bh(&btcoex->btcoex_lock); | 226 | spin_lock_bh(&btcoex->btcoex_lock); |
221 | 227 | ||
222 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) | 228 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) |
223 | ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE); | 229 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); |
224 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | 230 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) |
225 | ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW); | 231 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); |
226 | 232 | ||
227 | spin_unlock_bh(&btcoex->btcoex_lock); | 233 | spin_unlock_bh(&btcoex->btcoex_lock); |
234 | ath9k_ps_restore(sc); | ||
228 | } | 235 | } |
229 | 236 | ||
230 | int ath_init_btcoex_timer(struct ath_softc *sc) | 237 | int ath_init_btcoex_timer(struct ath_softc *sc) |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 2d10239ce82..2e3a33a5340 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -17,11 +17,9 @@ | |||
17 | #include "htc.h" | 17 | #include "htc.h" |
18 | 18 | ||
19 | /* identify firmware images */ | 19 | /* identify firmware images */ |
20 | #define FIRMWARE_AR7010 "ar7010.fw" | 20 | #define FIRMWARE_AR7010_1_1 "htc_7010.fw" |
21 | #define FIRMWARE_AR7010_1_1 "ar7010_1_1.fw" | 21 | #define FIRMWARE_AR9271 "htc_9271.fw" |
22 | #define FIRMWARE_AR9271 "ar9271.fw" | ||
23 | 22 | ||
24 | MODULE_FIRMWARE(FIRMWARE_AR7010); | ||
25 | MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); | 23 | MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); |
26 | MODULE_FIRMWARE(FIRMWARE_AR9271); | 24 | MODULE_FIRMWARE(FIRMWARE_AR9271); |
27 | 25 | ||
@@ -80,7 +78,7 @@ static void hif_usb_regout_cb(struct urb *urb) | |||
80 | 78 | ||
81 | if (cmd) { | 79 | if (cmd) { |
82 | ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, | 80 | ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, |
83 | cmd->skb, 1); | 81 | cmd->skb, true); |
84 | kfree(cmd); | 82 | kfree(cmd); |
85 | } | 83 | } |
86 | 84 | ||
@@ -126,6 +124,90 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, | |||
126 | return ret; | 124 | return ret; |
127 | } | 125 | } |
128 | 126 | ||
127 | static void hif_usb_mgmt_cb(struct urb *urb) | ||
128 | { | ||
129 | struct cmd_buf *cmd = (struct cmd_buf *)urb->context; | ||
130 | struct hif_device_usb *hif_dev = cmd->hif_dev; | ||
131 | bool txok = true; | ||
132 | |||
133 | if (!cmd || !cmd->skb || !cmd->hif_dev) | ||
134 | return; | ||
135 | |||
136 | switch (urb->status) { | ||
137 | case 0: | ||
138 | break; | ||
139 | case -ENOENT: | ||
140 | case -ECONNRESET: | ||
141 | case -ENODEV: | ||
142 | case -ESHUTDOWN: | ||
143 | txok = false; | ||
144 | |||
145 | /* | ||
146 | * If the URBs are being flushed, no need to complete | ||
147 | * this packet. | ||
148 | */ | ||
149 | spin_lock(&hif_dev->tx.tx_lock); | ||
150 | if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { | ||
151 | spin_unlock(&hif_dev->tx.tx_lock); | ||
152 | dev_kfree_skb_any(cmd->skb); | ||
153 | kfree(cmd); | ||
154 | return; | ||
155 | } | ||
156 | spin_unlock(&hif_dev->tx.tx_lock); | ||
157 | |||
158 | break; | ||
159 | default: | ||
160 | txok = false; | ||
161 | break; | ||
162 | } | ||
163 | |||
164 | skb_pull(cmd->skb, 4); | ||
165 | ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, | ||
166 | cmd->skb, txok); | ||
167 | kfree(cmd); | ||
168 | } | ||
169 | |||
170 | static int hif_usb_send_mgmt(struct hif_device_usb *hif_dev, | ||
171 | struct sk_buff *skb) | ||
172 | { | ||
173 | struct urb *urb; | ||
174 | struct cmd_buf *cmd; | ||
175 | int ret = 0; | ||
176 | __le16 *hdr; | ||
177 | |||
178 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
179 | if (urb == NULL) | ||
180 | return -ENOMEM; | ||
181 | |||
182 | cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); | ||
183 | if (cmd == NULL) { | ||
184 | usb_free_urb(urb); | ||
185 | return -ENOMEM; | ||
186 | } | ||
187 | |||
188 | cmd->skb = skb; | ||
189 | cmd->hif_dev = hif_dev; | ||
190 | |||
191 | hdr = (__le16 *) skb_push(skb, 4); | ||
192 | *hdr++ = cpu_to_le16(skb->len - 4); | ||
193 | *hdr++ = cpu_to_le16(ATH_USB_TX_STREAM_MODE_TAG); | ||
194 | |||
195 | usb_fill_bulk_urb(urb, hif_dev->udev, | ||
196 | usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE), | ||
197 | skb->data, skb->len, | ||
198 | hif_usb_mgmt_cb, cmd); | ||
199 | |||
200 | usb_anchor_urb(urb, &hif_dev->mgmt_submitted); | ||
201 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
202 | if (ret) { | ||
203 | usb_unanchor_urb(urb); | ||
204 | kfree(cmd); | ||
205 | } | ||
206 | usb_free_urb(urb); | ||
207 | |||
208 | return ret; | ||
209 | } | ||
210 | |||
129 | static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, | 211 | static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, |
130 | struct sk_buff_head *list) | 212 | struct sk_buff_head *list) |
131 | { | 213 | { |
@@ -133,7 +215,22 @@ static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, | |||
133 | 215 | ||
134 | while ((skb = __skb_dequeue(list)) != NULL) { | 216 | while ((skb = __skb_dequeue(list)) != NULL) { |
135 | dev_kfree_skb_any(skb); | 217 | dev_kfree_skb_any(skb); |
136 | TX_STAT_INC(skb_dropped); | 218 | } |
219 | } | ||
220 | |||
221 | static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev, | ||
222 | struct sk_buff_head *queue, | ||
223 | bool txok) | ||
224 | { | ||
225 | struct sk_buff *skb; | ||
226 | |||
227 | while ((skb = __skb_dequeue(queue)) != NULL) { | ||
228 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | ||
229 | skb, txok); | ||
230 | if (txok) | ||
231 | TX_STAT_INC(skb_success); | ||
232 | else | ||
233 | TX_STAT_INC(skb_failed); | ||
137 | } | 234 | } |
138 | } | 235 | } |
139 | 236 | ||
@@ -141,7 +238,7 @@ static void hif_usb_tx_cb(struct urb *urb) | |||
141 | { | 238 | { |
142 | struct tx_buf *tx_buf = (struct tx_buf *) urb->context; | 239 | struct tx_buf *tx_buf = (struct tx_buf *) urb->context; |
143 | struct hif_device_usb *hif_dev; | 240 | struct hif_device_usb *hif_dev; |
144 | struct sk_buff *skb; | 241 | bool txok = true; |
145 | 242 | ||
146 | if (!tx_buf || !tx_buf->hif_dev) | 243 | if (!tx_buf || !tx_buf->hif_dev) |
147 | return; | 244 | return; |
@@ -155,10 +252,7 @@ static void hif_usb_tx_cb(struct urb *urb) | |||
155 | case -ECONNRESET: | 252 | case -ECONNRESET: |
156 | case -ENODEV: | 253 | case -ENODEV: |
157 | case -ESHUTDOWN: | 254 | case -ESHUTDOWN: |
158 | /* | 255 | txok = false; |
159 | * The URB has been killed, free the SKBs. | ||
160 | */ | ||
161 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
162 | 256 | ||
163 | /* | 257 | /* |
164 | * If the URBs are being flushed, no need to add this | 258 | * If the URBs are being flushed, no need to add this |
@@ -167,41 +261,19 @@ static void hif_usb_tx_cb(struct urb *urb) | |||
167 | spin_lock(&hif_dev->tx.tx_lock); | 261 | spin_lock(&hif_dev->tx.tx_lock); |
168 | if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { | 262 | if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { |
169 | spin_unlock(&hif_dev->tx.tx_lock); | 263 | spin_unlock(&hif_dev->tx.tx_lock); |
264 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
170 | return; | 265 | return; |
171 | } | 266 | } |
172 | spin_unlock(&hif_dev->tx.tx_lock); | 267 | spin_unlock(&hif_dev->tx.tx_lock); |
173 | 268 | ||
174 | /* | 269 | break; |
175 | * In the stop() case, this URB has to be added to | ||
176 | * the free list. | ||
177 | */ | ||
178 | goto add_free; | ||
179 | default: | 270 | default: |
271 | txok = false; | ||
180 | break; | 272 | break; |
181 | } | 273 | } |
182 | 274 | ||
183 | /* | 275 | ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, txok); |
184 | * Check if TX has been stopped, this is needed because | ||
185 | * this CB could have been invoked just after the TX lock | ||
186 | * was released in hif_stop() and kill_urb() hasn't been | ||
187 | * called yet. | ||
188 | */ | ||
189 | spin_lock(&hif_dev->tx.tx_lock); | ||
190 | if (hif_dev->tx.flags & HIF_USB_TX_STOP) { | ||
191 | spin_unlock(&hif_dev->tx.tx_lock); | ||
192 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
193 | goto add_free; | ||
194 | } | ||
195 | spin_unlock(&hif_dev->tx.tx_lock); | ||
196 | |||
197 | /* Complete the queued SKBs. */ | ||
198 | while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) { | ||
199 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | ||
200 | skb, 1); | ||
201 | TX_STAT_INC(skb_completed); | ||
202 | } | ||
203 | 276 | ||
204 | add_free: | ||
205 | /* Re-initialize the SKB queue */ | 277 | /* Re-initialize the SKB queue */ |
206 | tx_buf->len = tx_buf->offset = 0; | 278 | tx_buf->len = tx_buf->offset = 0; |
207 | __skb_queue_head_init(&tx_buf->skb_queue); | 279 | __skb_queue_head_init(&tx_buf->skb_queue); |
@@ -274,7 +346,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) | |||
274 | ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC); | 346 | ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC); |
275 | if (ret) { | 347 | if (ret) { |
276 | tx_buf->len = tx_buf->offset = 0; | 348 | tx_buf->len = tx_buf->offset = 0; |
277 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | 349 | ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, false); |
278 | __skb_queue_head_init(&tx_buf->skb_queue); | 350 | __skb_queue_head_init(&tx_buf->skb_queue); |
279 | list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); | 351 | list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); |
280 | hif_dev->tx.tx_buf_cnt++; | 352 | hif_dev->tx.tx_buf_cnt++; |
@@ -286,10 +358,11 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) | |||
286 | return ret; | 358 | return ret; |
287 | } | 359 | } |
288 | 360 | ||
289 | static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, | 361 | static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb) |
290 | struct ath9k_htc_tx_ctl *tx_ctl) | ||
291 | { | 362 | { |
363 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
292 | unsigned long flags; | 364 | unsigned long flags; |
365 | int ret = 0; | ||
293 | 366 | ||
294 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | 367 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); |
295 | 368 | ||
@@ -304,26 +377,36 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, | |||
304 | return -ENOMEM; | 377 | return -ENOMEM; |
305 | } | 378 | } |
306 | 379 | ||
307 | __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); | 380 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
308 | hif_dev->tx.tx_skb_cnt++; | ||
309 | 381 | ||
310 | /* Send normal frames immediately */ | 382 | tx_ctl = HTC_SKB_CB(skb); |
311 | if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL))) | 383 | |
312 | __hif_usb_tx(hif_dev); | 384 | /* Mgmt/Beacon frames don't use the TX buffer pool */ |
385 | if ((tx_ctl->type == ATH9K_HTC_MGMT) || | ||
386 | (tx_ctl->type == ATH9K_HTC_BEACON)) { | ||
387 | ret = hif_usb_send_mgmt(hif_dev, skb); | ||
388 | } | ||
389 | |||
390 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | ||
391 | |||
392 | if ((tx_ctl->type == ATH9K_HTC_NORMAL) || | ||
393 | (tx_ctl->type == ATH9K_HTC_AMPDU)) { | ||
394 | __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); | ||
395 | hif_dev->tx.tx_skb_cnt++; | ||
396 | } | ||
313 | 397 | ||
314 | /* Check if AMPDUs have to be sent immediately */ | 398 | /* Check if AMPDUs have to be sent immediately */ |
315 | if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) && | 399 | if ((hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && |
316 | (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && | ||
317 | (hif_dev->tx.tx_skb_cnt < 2)) { | 400 | (hif_dev->tx.tx_skb_cnt < 2)) { |
318 | __hif_usb_tx(hif_dev); | 401 | __hif_usb_tx(hif_dev); |
319 | } | 402 | } |
320 | 403 | ||
321 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | 404 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
322 | 405 | ||
323 | return 0; | 406 | return ret; |
324 | } | 407 | } |
325 | 408 | ||
326 | static void hif_usb_start(void *hif_handle, u8 pipe_id) | 409 | static void hif_usb_start(void *hif_handle) |
327 | { | 410 | { |
328 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | 411 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; |
329 | unsigned long flags; | 412 | unsigned long flags; |
@@ -335,14 +418,14 @@ static void hif_usb_start(void *hif_handle, u8 pipe_id) | |||
335 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | 418 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
336 | } | 419 | } |
337 | 420 | ||
338 | static void hif_usb_stop(void *hif_handle, u8 pipe_id) | 421 | static void hif_usb_stop(void *hif_handle) |
339 | { | 422 | { |
340 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | 423 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; |
341 | struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; | 424 | struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; |
342 | unsigned long flags; | 425 | unsigned long flags; |
343 | 426 | ||
344 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | 427 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); |
345 | ath9k_skb_queue_purge(hif_dev, &hif_dev->tx.tx_skb_queue); | 428 | ath9k_skb_queue_complete(hif_dev, &hif_dev->tx.tx_skb_queue, false); |
346 | hif_dev->tx.tx_skb_cnt = 0; | 429 | hif_dev->tx.tx_skb_cnt = 0; |
347 | hif_dev->tx.flags |= HIF_USB_TX_STOP; | 430 | hif_dev->tx.flags |= HIF_USB_TX_STOP; |
348 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | 431 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
@@ -352,17 +435,18 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id) | |||
352 | &hif_dev->tx.tx_pending, list) { | 435 | &hif_dev->tx.tx_pending, list) { |
353 | usb_kill_urb(tx_buf->urb); | 436 | usb_kill_urb(tx_buf->urb); |
354 | } | 437 | } |
438 | |||
439 | usb_kill_anchored_urbs(&hif_dev->mgmt_submitted); | ||
355 | } | 440 | } |
356 | 441 | ||
357 | static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, | 442 | static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb) |
358 | struct ath9k_htc_tx_ctl *tx_ctl) | ||
359 | { | 443 | { |
360 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | 444 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; |
361 | int ret = 0; | 445 | int ret = 0; |
362 | 446 | ||
363 | switch (pipe_id) { | 447 | switch (pipe_id) { |
364 | case USB_WLAN_TX_PIPE: | 448 | case USB_WLAN_TX_PIPE: |
365 | ret = hif_usb_send_tx(hif_dev, skb, tx_ctl); | 449 | ret = hif_usb_send_tx(hif_dev, skb); |
366 | break; | 450 | break; |
367 | case USB_REG_OUT_PIPE: | 451 | case USB_REG_OUT_PIPE: |
368 | ret = hif_usb_send_regout(hif_dev, skb); | 452 | ret = hif_usb_send_regout(hif_dev, skb); |
@@ -377,6 +461,40 @@ static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, | |||
377 | return ret; | 461 | return ret; |
378 | } | 462 | } |
379 | 463 | ||
464 | static inline bool check_index(struct sk_buff *skb, u8 idx) | ||
465 | { | ||
466 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
467 | |||
468 | tx_ctl = HTC_SKB_CB(skb); | ||
469 | |||
470 | if ((tx_ctl->type == ATH9K_HTC_AMPDU) && | ||
471 | (tx_ctl->sta_idx == idx)) | ||
472 | return true; | ||
473 | |||
474 | return false; | ||
475 | } | ||
476 | |||
477 | static void hif_usb_sta_drain(void *hif_handle, u8 idx) | ||
478 | { | ||
479 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | ||
480 | struct sk_buff *skb, *tmp; | ||
481 | unsigned long flags; | ||
482 | |||
483 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | ||
484 | |||
485 | skb_queue_walk_safe(&hif_dev->tx.tx_skb_queue, skb, tmp) { | ||
486 | if (check_index(skb, idx)) { | ||
487 | __skb_unlink(skb, &hif_dev->tx.tx_skb_queue); | ||
488 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | ||
489 | skb, false); | ||
490 | hif_dev->tx.tx_skb_cnt--; | ||
491 | TX_STAT_INC(skb_failed); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | ||
496 | } | ||
497 | |||
380 | static struct ath9k_htc_hif hif_usb = { | 498 | static struct ath9k_htc_hif hif_usb = { |
381 | .transport = ATH9K_HIF_USB, | 499 | .transport = ATH9K_HIF_USB, |
382 | .name = "ath9k_hif_usb", | 500 | .name = "ath9k_hif_usb", |
@@ -386,6 +504,7 @@ static struct ath9k_htc_hif hif_usb = { | |||
386 | 504 | ||
387 | .start = hif_usb_start, | 505 | .start = hif_usb_start, |
388 | .stop = hif_usb_stop, | 506 | .stop = hif_usb_stop, |
507 | .sta_drain = hif_usb_sta_drain, | ||
389 | .send = hif_usb_send, | 508 | .send = hif_usb_send, |
390 | }; | 509 | }; |
391 | 510 | ||
@@ -567,6 +686,9 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) | |||
567 | case -ESHUTDOWN: | 686 | case -ESHUTDOWN: |
568 | goto free; | 687 | goto free; |
569 | default: | 688 | default: |
689 | skb_reset_tail_pointer(skb); | ||
690 | skb_trim(skb, 0); | ||
691 | |||
570 | goto resubmit; | 692 | goto resubmit; |
571 | } | 693 | } |
572 | 694 | ||
@@ -591,23 +713,15 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) | |||
591 | USB_REG_IN_PIPE), | 713 | USB_REG_IN_PIPE), |
592 | nskb->data, MAX_REG_IN_BUF_SIZE, | 714 | nskb->data, MAX_REG_IN_BUF_SIZE, |
593 | ath9k_hif_usb_reg_in_cb, nskb); | 715 | ath9k_hif_usb_reg_in_cb, nskb); |
594 | |||
595 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
596 | if (ret) { | ||
597 | kfree_skb(nskb); | ||
598 | urb->context = NULL; | ||
599 | } | ||
600 | |||
601 | return; | ||
602 | } | 716 | } |
603 | 717 | ||
604 | resubmit: | 718 | resubmit: |
605 | skb_reset_tail_pointer(skb); | 719 | usb_anchor_urb(urb, &hif_dev->reg_in_submitted); |
606 | skb_trim(skb, 0); | ||
607 | |||
608 | ret = usb_submit_urb(urb, GFP_ATOMIC); | 720 | ret = usb_submit_urb(urb, GFP_ATOMIC); |
609 | if (ret) | 721 | if (ret) { |
722 | usb_unanchor_urb(urb); | ||
610 | goto free; | 723 | goto free; |
724 | } | ||
611 | 725 | ||
612 | return; | 726 | return; |
613 | free: | 727 | free: |
@@ -641,6 +755,8 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) | |||
641 | kfree(tx_buf->buf); | 755 | kfree(tx_buf->buf); |
642 | kfree(tx_buf); | 756 | kfree(tx_buf); |
643 | } | 757 | } |
758 | |||
759 | usb_kill_anchored_urbs(&hif_dev->mgmt_submitted); | ||
644 | } | 760 | } |
645 | 761 | ||
646 | static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) | 762 | static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) |
@@ -652,6 +768,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) | |||
652 | INIT_LIST_HEAD(&hif_dev->tx.tx_pending); | 768 | INIT_LIST_HEAD(&hif_dev->tx.tx_pending); |
653 | spin_lock_init(&hif_dev->tx.tx_lock); | 769 | spin_lock_init(&hif_dev->tx.tx_lock); |
654 | __skb_queue_head_init(&hif_dev->tx.tx_skb_queue); | 770 | __skb_queue_head_init(&hif_dev->tx.tx_skb_queue); |
771 | init_usb_anchor(&hif_dev->mgmt_submitted); | ||
655 | 772 | ||
656 | for (i = 0; i < MAX_TX_URB_NUM; i++) { | 773 | for (i = 0; i < MAX_TX_URB_NUM; i++) { |
657 | tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); | 774 | tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); |
@@ -748,43 +865,67 @@ err_urb: | |||
748 | return ret; | 865 | return ret; |
749 | } | 866 | } |
750 | 867 | ||
751 | static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev) | 868 | static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev) |
752 | { | 869 | { |
753 | if (hif_dev->reg_in_urb) { | 870 | usb_kill_anchored_urbs(&hif_dev->reg_in_submitted); |
754 | usb_kill_urb(hif_dev->reg_in_urb); | ||
755 | if (hif_dev->reg_in_urb->context) | ||
756 | kfree_skb((void *)hif_dev->reg_in_urb->context); | ||
757 | usb_free_urb(hif_dev->reg_in_urb); | ||
758 | hif_dev->reg_in_urb = NULL; | ||
759 | } | ||
760 | } | 871 | } |
761 | 872 | ||
762 | static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev) | 873 | static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) |
763 | { | 874 | { |
764 | struct sk_buff *skb; | 875 | struct urb *urb = NULL; |
876 | struct sk_buff *skb = NULL; | ||
877 | int i, ret; | ||
765 | 878 | ||
766 | hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 879 | init_usb_anchor(&hif_dev->reg_in_submitted); |
767 | if (hif_dev->reg_in_urb == NULL) | ||
768 | return -ENOMEM; | ||
769 | 880 | ||
770 | skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); | 881 | for (i = 0; i < MAX_REG_IN_URB_NUM; i++) { |
771 | if (!skb) | ||
772 | goto err; | ||
773 | 882 | ||
774 | usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev, | 883 | /* Allocate URB */ |
775 | usb_rcvbulkpipe(hif_dev->udev, | 884 | urb = usb_alloc_urb(0, GFP_KERNEL); |
776 | USB_REG_IN_PIPE), | 885 | if (urb == NULL) { |
777 | skb->data, MAX_REG_IN_BUF_SIZE, | 886 | ret = -ENOMEM; |
778 | ath9k_hif_usb_reg_in_cb, skb); | 887 | goto err_urb; |
888 | } | ||
779 | 889 | ||
780 | if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0) | 890 | /* Allocate buffer */ |
781 | goto err; | 891 | skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); |
892 | if (!skb) { | ||
893 | ret = -ENOMEM; | ||
894 | goto err_skb; | ||
895 | } | ||
896 | |||
897 | usb_fill_bulk_urb(urb, hif_dev->udev, | ||
898 | usb_rcvbulkpipe(hif_dev->udev, | ||
899 | USB_REG_IN_PIPE), | ||
900 | skb->data, MAX_REG_IN_BUF_SIZE, | ||
901 | ath9k_hif_usb_reg_in_cb, skb); | ||
902 | |||
903 | /* Anchor URB */ | ||
904 | usb_anchor_urb(urb, &hif_dev->reg_in_submitted); | ||
905 | |||
906 | /* Submit URB */ | ||
907 | ret = usb_submit_urb(urb, GFP_KERNEL); | ||
908 | if (ret) { | ||
909 | usb_unanchor_urb(urb); | ||
910 | goto err_submit; | ||
911 | } | ||
912 | |||
913 | /* | ||
914 | * Drop reference count. | ||
915 | * This ensures that the URB is freed when killing them. | ||
916 | */ | ||
917 | usb_free_urb(urb); | ||
918 | } | ||
782 | 919 | ||
783 | return 0; | 920 | return 0; |
784 | 921 | ||
785 | err: | 922 | err_submit: |
786 | ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); | 923 | kfree_skb(skb); |
787 | return -ENOMEM; | 924 | err_skb: |
925 | usb_free_urb(urb); | ||
926 | err_urb: | ||
927 | ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); | ||
928 | return ret; | ||
788 | } | 929 | } |
789 | 930 | ||
790 | static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) | 931 | static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) |
@@ -801,7 +942,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) | |||
801 | goto err_rx; | 942 | goto err_rx; |
802 | 943 | ||
803 | /* Register Read */ | 944 | /* Register Read */ |
804 | if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0) | 945 | if (ath9k_hif_usb_alloc_reg_in_urbs(hif_dev) < 0) |
805 | goto err_reg; | 946 | goto err_reg; |
806 | 947 | ||
807 | return 0; | 948 | return 0; |
@@ -816,7 +957,7 @@ err: | |||
816 | static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) | 957 | static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) |
817 | { | 958 | { |
818 | usb_kill_anchored_urbs(&hif_dev->regout_submitted); | 959 | usb_kill_anchored_urbs(&hif_dev->regout_submitted); |
819 | ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); | 960 | ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); |
820 | ath9k_hif_usb_dealloc_tx_urbs(hif_dev); | 961 | ath9k_hif_usb_dealloc_tx_urbs(hif_dev); |
821 | ath9k_hif_usb_dealloc_rx_urbs(hif_dev); | 962 | ath9k_hif_usb_dealloc_rx_urbs(hif_dev); |
822 | } | 963 | } |
@@ -1026,10 +1167,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, | |||
1026 | /* Find out which firmware to load */ | 1167 | /* Find out which firmware to load */ |
1027 | 1168 | ||
1028 | if (IS_AR7010_DEVICE(id->driver_info)) | 1169 | if (IS_AR7010_DEVICE(id->driver_info)) |
1029 | if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) | 1170 | hif_dev->fw_name = FIRMWARE_AR7010_1_1; |
1030 | hif_dev->fw_name = FIRMWARE_AR7010_1_1; | ||
1031 | else | ||
1032 | hif_dev->fw_name = FIRMWARE_AR7010; | ||
1033 | else | 1171 | else |
1034 | hif_dev->fw_name = FIRMWARE_AR9271; | 1172 | hif_dev->fw_name = FIRMWARE_AR9271; |
1035 | 1173 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 7b9d863d403..2bdcdbc14b1 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h | |||
@@ -17,6 +17,9 @@ | |||
17 | #ifndef HTC_USB_H | 17 | #ifndef HTC_USB_H |
18 | #define HTC_USB_H | 18 | #define HTC_USB_H |
19 | 19 | ||
20 | #define MAJOR_VERSION_REQ 1 | ||
21 | #define MINOR_VERSION_REQ 2 | ||
22 | |||
20 | #define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB)) | 23 | #define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB)) |
21 | 24 | ||
22 | #define AR9271_FIRMWARE 0x501000 | 25 | #define AR9271_FIRMWARE 0x501000 |
@@ -31,7 +34,7 @@ | |||
31 | 34 | ||
32 | /* FIXME: Verify these numbers (with Windows) */ | 35 | /* FIXME: Verify these numbers (with Windows) */ |
33 | #define MAX_TX_URB_NUM 8 | 36 | #define MAX_TX_URB_NUM 8 |
34 | #define MAX_TX_BUF_NUM 1024 | 37 | #define MAX_TX_BUF_NUM 256 |
35 | #define MAX_TX_BUF_SIZE 32768 | 38 | #define MAX_TX_BUF_SIZE 32768 |
36 | #define MAX_TX_AGGR_NUM 20 | 39 | #define MAX_TX_AGGR_NUM 20 |
37 | 40 | ||
@@ -40,7 +43,7 @@ | |||
40 | #define MAX_PKT_NUM_IN_TRANSFER 10 | 43 | #define MAX_PKT_NUM_IN_TRANSFER 10 |
41 | 44 | ||
42 | #define MAX_REG_OUT_URB_NUM 1 | 45 | #define MAX_REG_OUT_URB_NUM 1 |
43 | #define MAX_REG_OUT_BUF_NUM 8 | 46 | #define MAX_REG_IN_URB_NUM 64 |
44 | 47 | ||
45 | #define MAX_REG_IN_BUF_SIZE 64 | 48 | #define MAX_REG_IN_BUF_SIZE 64 |
46 | 49 | ||
@@ -90,9 +93,10 @@ struct hif_device_usb { | |||
90 | const struct firmware *firmware; | 93 | const struct firmware *firmware; |
91 | struct htc_target *htc_handle; | 94 | struct htc_target *htc_handle; |
92 | struct hif_usb_tx tx; | 95 | struct hif_usb_tx tx; |
93 | struct urb *reg_in_urb; | ||
94 | struct usb_anchor regout_submitted; | 96 | struct usb_anchor regout_submitted; |
95 | struct usb_anchor rx_submitted; | 97 | struct usb_anchor rx_submitted; |
98 | struct usb_anchor reg_in_submitted; | ||
99 | struct usb_anchor mgmt_submitted; | ||
96 | struct sk_buff *remain_skb; | 100 | struct sk_buff *remain_skb; |
97 | const char *fw_name; | 101 | const char *fw_name; |
98 | int rx_remain_len; | 102 | int rx_remain_len; |
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 753a245c5ad..dfc7a982fc7 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -66,13 +66,13 @@ enum htc_opmode { | |||
66 | HTC_M_WDS = 2 | 66 | HTC_M_WDS = 2 |
67 | }; | 67 | }; |
68 | 68 | ||
69 | #define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr) | 69 | #define ATH9K_HTC_AMPDU 1 |
70 | #define ATH9K_HTC_AMPDU 1 | ||
71 | #define ATH9K_HTC_NORMAL 2 | 70 | #define ATH9K_HTC_NORMAL 2 |
71 | #define ATH9K_HTC_BEACON 3 | ||
72 | #define ATH9K_HTC_MGMT 4 | ||
72 | 73 | ||
73 | #define ATH9K_HTC_TX_CTSONLY 0x1 | 74 | #define ATH9K_HTC_TX_CTSONLY 0x1 |
74 | #define ATH9K_HTC_TX_RTSCTS 0x2 | 75 | #define ATH9K_HTC_TX_RTSCTS 0x2 |
75 | #define ATH9K_HTC_TX_USE_MIN_RATE 0x100 | ||
76 | 76 | ||
77 | struct tx_frame_hdr { | 77 | struct tx_frame_hdr { |
78 | u8 data_type; | 78 | u8 data_type; |
@@ -82,7 +82,8 @@ struct tx_frame_hdr { | |||
82 | __be32 flags; /* ATH9K_HTC_TX_* */ | 82 | __be32 flags; /* ATH9K_HTC_TX_* */ |
83 | u8 key_type; | 83 | u8 key_type; |
84 | u8 keyix; | 84 | u8 keyix; |
85 | u8 reserved[26]; | 85 | u8 cookie; |
86 | u8 pad; | ||
86 | } __packed; | 87 | } __packed; |
87 | 88 | ||
88 | struct tx_mgmt_hdr { | 89 | struct tx_mgmt_hdr { |
@@ -92,50 +93,34 @@ struct tx_mgmt_hdr { | |||
92 | u8 flags; | 93 | u8 flags; |
93 | u8 key_type; | 94 | u8 key_type; |
94 | u8 keyix; | 95 | u8 keyix; |
95 | u16 reserved; | 96 | u8 cookie; |
97 | u8 pad; | ||
96 | } __packed; | 98 | } __packed; |
97 | 99 | ||
98 | struct tx_beacon_header { | 100 | struct tx_beacon_header { |
99 | u8 len_changed; | ||
100 | u8 vif_index; | 101 | u8 vif_index; |
102 | u8 len_changed; | ||
101 | u16 rev; | 103 | u16 rev; |
102 | } __packed; | 104 | } __packed; |
103 | 105 | ||
104 | struct ath9k_htc_target_hw { | 106 | #define MAX_TX_AMPDU_SUBFRAMES_9271 17 |
105 | u32 flags; | 107 | #define MAX_TX_AMPDU_SUBFRAMES_7010 22 |
106 | u32 flags_ext; | ||
107 | u32 ampdu_limit; | ||
108 | u8 ampdu_subframes; | ||
109 | u8 tx_chainmask; | ||
110 | u8 tx_chainmask_legacy; | ||
111 | u8 rtscts_ratecode; | ||
112 | u8 protmode; | ||
113 | } __packed; | ||
114 | 108 | ||
115 | struct ath9k_htc_cap_target { | 109 | struct ath9k_htc_cap_target { |
116 | u32 flags; | 110 | __be32 ampdu_limit; |
117 | u32 flags_ext; | ||
118 | u32 ampdu_limit; | ||
119 | u8 ampdu_subframes; | 111 | u8 ampdu_subframes; |
112 | u8 enable_coex; | ||
120 | u8 tx_chainmask; | 113 | u8 tx_chainmask; |
121 | u8 tx_chainmask_legacy; | 114 | u8 pad; |
122 | u8 rtscts_ratecode; | ||
123 | u8 protmode; | ||
124 | } __packed; | 115 | } __packed; |
125 | 116 | ||
126 | struct ath9k_htc_target_vif { | 117 | struct ath9k_htc_target_vif { |
127 | u8 index; | 118 | u8 index; |
128 | u8 des_bssid[ETH_ALEN]; | 119 | u8 opmode; |
129 | __be32 opmode; | ||
130 | u8 myaddr[ETH_ALEN]; | 120 | u8 myaddr[ETH_ALEN]; |
131 | u8 bssid[ETH_ALEN]; | ||
132 | u32 flags; | ||
133 | u32 flags_ext; | ||
134 | u16 ps_sta; | ||
135 | __be16 rtsthreshold; | ||
136 | u8 ath_cap; | 121 | u8 ath_cap; |
137 | u8 node; | 122 | __be16 rtsthreshold; |
138 | s8 mcast_rate; | 123 | u8 pad; |
139 | } __packed; | 124 | } __packed; |
140 | 125 | ||
141 | #define ATH_HTC_STA_AUTH 0x0001 | 126 | #define ATH_HTC_STA_AUTH 0x0001 |
@@ -143,27 +128,16 @@ struct ath9k_htc_target_vif { | |||
143 | #define ATH_HTC_STA_ERP 0x0004 | 128 | #define ATH_HTC_STA_ERP 0x0004 |
144 | #define ATH_HTC_STA_HT 0x0008 | 129 | #define ATH_HTC_STA_HT 0x0008 |
145 | 130 | ||
146 | /* FIXME: UAPSD variables */ | ||
147 | struct ath9k_htc_target_sta { | 131 | struct ath9k_htc_target_sta { |
148 | u16 associd; | ||
149 | u16 txpower; | ||
150 | u32 ucastkey; | ||
151 | u8 macaddr[ETH_ALEN]; | 132 | u8 macaddr[ETH_ALEN]; |
152 | u8 bssid[ETH_ALEN]; | 133 | u8 bssid[ETH_ALEN]; |
153 | u8 sta_index; | 134 | u8 sta_index; |
154 | u8 vif_index; | 135 | u8 vif_index; |
155 | u8 vif_sta; | ||
156 | __be16 flags; /* ATH_HTC_STA_* */ | ||
157 | u16 htcap; | ||
158 | u8 valid; | ||
159 | u16 capinfo; | ||
160 | struct ath9k_htc_target_hw *hw; | ||
161 | struct ath9k_htc_target_vif *vif; | ||
162 | u16 txseqmgmt; | ||
163 | u8 is_vif_sta; | 136 | u8 is_vif_sta; |
164 | u16 maxampdu; | 137 | __be16 flags; /* ATH_HTC_STA_* */ |
165 | u16 iv16; | 138 | __be16 htcap; |
166 | u32 iv32; | 139 | __be16 maxampdu; |
140 | u8 pad; | ||
167 | } __packed; | 141 | } __packed; |
168 | 142 | ||
169 | struct ath9k_htc_target_aggr { | 143 | struct ath9k_htc_target_aggr { |
@@ -197,12 +171,38 @@ struct ath9k_htc_target_rate { | |||
197 | struct ath9k_htc_rate rates; | 171 | struct ath9k_htc_rate rates; |
198 | }; | 172 | }; |
199 | 173 | ||
200 | struct ath9k_htc_target_stats { | 174 | struct ath9k_htc_target_rate_mask { |
201 | __be32 tx_shortretry; | 175 | u8 vif_index; |
202 | __be32 tx_longretry; | 176 | u8 band; |
203 | __be32 tx_xretries; | 177 | __be32 mask; |
204 | __be32 ht_txunaggr_xretry; | 178 | u16 pad; |
205 | __be32 ht_tx_xretries; | 179 | } __packed; |
180 | |||
181 | struct ath9k_htc_target_int_stats { | ||
182 | __be32 rx; | ||
183 | __be32 rxorn; | ||
184 | __be32 rxeol; | ||
185 | __be32 txurn; | ||
186 | __be32 txto; | ||
187 | __be32 cst; | ||
188 | } __packed; | ||
189 | |||
190 | struct ath9k_htc_target_tx_stats { | ||
191 | __be32 xretries; | ||
192 | __be32 fifoerr; | ||
193 | __be32 filtered; | ||
194 | __be32 timer_exp; | ||
195 | __be32 shortretries; | ||
196 | __be32 longretries; | ||
197 | __be32 qnull; | ||
198 | __be32 encap_fail; | ||
199 | __be32 nobuf; | ||
200 | } __packed; | ||
201 | |||
202 | struct ath9k_htc_target_rx_stats { | ||
203 | __be32 nobuf; | ||
204 | __be32 host_send; | ||
205 | __be32 host_done; | ||
206 | } __packed; | 206 | } __packed; |
207 | 207 | ||
208 | #define ATH9K_HTC_MAX_VIF 2 | 208 | #define ATH9K_HTC_MAX_VIF 2 |
@@ -244,6 +244,8 @@ struct ath9k_htc_vif { | |||
244 | u8 index; | 244 | u8 index; |
245 | u16 seq_no; | 245 | u16 seq_no; |
246 | bool beacon_configured; | 246 | bool beacon_configured; |
247 | int bslot; | ||
248 | __le64 tsfadjust; | ||
247 | }; | 249 | }; |
248 | 250 | ||
249 | struct ath9k_vif_iter_data { | 251 | struct ath9k_vif_iter_data { |
@@ -282,23 +284,65 @@ struct ath9k_htc_rx { | |||
282 | spinlock_t rxbuflock; | 284 | spinlock_t rxbuflock; |
283 | }; | 285 | }; |
284 | 286 | ||
287 | #define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */ | ||
288 | #define ATH9K_HTC_TX_TIMEOUT_INTERVAL 2500 /* ms */ | ||
289 | #define ATH9K_HTC_TX_RESERVE 10 | ||
290 | #define ATH9K_HTC_TX_TIMEOUT_COUNT 20 | ||
291 | #define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE) | ||
292 | |||
293 | #define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0) | ||
294 | #define ATH9K_HTC_OP_TX_DRAIN BIT(1) | ||
295 | |||
296 | struct ath9k_htc_tx { | ||
297 | u8 flags; | ||
298 | int queued_cnt; | ||
299 | struct sk_buff_head mgmt_ep_queue; | ||
300 | struct sk_buff_head cab_ep_queue; | ||
301 | struct sk_buff_head data_be_queue; | ||
302 | struct sk_buff_head data_bk_queue; | ||
303 | struct sk_buff_head data_vi_queue; | ||
304 | struct sk_buff_head data_vo_queue; | ||
305 | struct sk_buff_head tx_failed; | ||
306 | DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); | ||
307 | struct timer_list cleanup_timer; | ||
308 | spinlock_t tx_lock; | ||
309 | }; | ||
310 | |||
285 | struct ath9k_htc_tx_ctl { | 311 | struct ath9k_htc_tx_ctl { |
286 | u8 type; /* ATH9K_HTC_* */ | 312 | u8 type; /* ATH9K_HTC_* */ |
313 | u8 epid; | ||
314 | u8 txok; | ||
315 | u8 sta_idx; | ||
316 | unsigned long timestamp; | ||
287 | }; | 317 | }; |
288 | 318 | ||
319 | static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) | ||
320 | { | ||
321 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
322 | |||
323 | BUILD_BUG_ON(sizeof(struct ath9k_htc_tx_ctl) > | ||
324 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE); | ||
325 | return (struct ath9k_htc_tx_ctl *) &tx_info->driver_data; | ||
326 | } | ||
327 | |||
289 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | 328 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS |
290 | 329 | ||
291 | #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) | 330 | #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) |
292 | #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) | 331 | #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) |
332 | #define CAB_STAT_INC priv->debug.tx_stats.cab_queued++ | ||
293 | 333 | ||
294 | #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) | 334 | #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) |
295 | 335 | ||
336 | void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, | ||
337 | struct ath_htc_rx_status *rxs); | ||
338 | |||
296 | struct ath_tx_stats { | 339 | struct ath_tx_stats { |
297 | u32 buf_queued; | 340 | u32 buf_queued; |
298 | u32 buf_completed; | 341 | u32 buf_completed; |
299 | u32 skb_queued; | 342 | u32 skb_queued; |
300 | u32 skb_completed; | 343 | u32 skb_success; |
301 | u32 skb_dropped; | 344 | u32 skb_failed; |
345 | u32 cab_queued; | ||
302 | u32 queue_stats[WME_NUM_AC]; | 346 | u32 queue_stats[WME_NUM_AC]; |
303 | }; | 347 | }; |
304 | 348 | ||
@@ -306,55 +350,57 @@ struct ath_rx_stats { | |||
306 | u32 skb_allocated; | 350 | u32 skb_allocated; |
307 | u32 skb_completed; | 351 | u32 skb_completed; |
308 | u32 skb_dropped; | 352 | u32 skb_dropped; |
353 | u32 err_crc; | ||
354 | u32 err_decrypt_crc; | ||
355 | u32 err_mic; | ||
356 | u32 err_pre_delim; | ||
357 | u32 err_post_delim; | ||
358 | u32 err_decrypt_busy; | ||
359 | u32 err_phy; | ||
360 | u32 err_phy_stats[ATH9K_PHYERR_MAX]; | ||
309 | }; | 361 | }; |
310 | 362 | ||
311 | struct ath9k_debug { | 363 | struct ath9k_debug { |
312 | struct dentry *debugfs_phy; | 364 | struct dentry *debugfs_phy; |
313 | struct dentry *debugfs_tgt_stats; | ||
314 | struct dentry *debugfs_xmit; | ||
315 | struct dentry *debugfs_recv; | ||
316 | struct ath_tx_stats tx_stats; | 365 | struct ath_tx_stats tx_stats; |
317 | struct ath_rx_stats rx_stats; | 366 | struct ath_rx_stats rx_stats; |
318 | u32 txrate; | ||
319 | }; | 367 | }; |
320 | 368 | ||
321 | #else | 369 | #else |
322 | 370 | ||
323 | #define TX_STAT_INC(c) do { } while (0) | 371 | #define TX_STAT_INC(c) do { } while (0) |
324 | #define RX_STAT_INC(c) do { } while (0) | 372 | #define RX_STAT_INC(c) do { } while (0) |
373 | #define CAB_STAT_INC do { } while (0) | ||
325 | 374 | ||
326 | #define TX_QSTAT_INC(c) do { } while (0) | 375 | #define TX_QSTAT_INC(c) do { } while (0) |
327 | 376 | ||
377 | static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, | ||
378 | struct ath_htc_rx_status *rxs) | ||
379 | { | ||
380 | } | ||
381 | |||
328 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ | 382 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ |
329 | 383 | ||
330 | #define ATH_LED_PIN_DEF 1 | 384 | #define ATH_LED_PIN_DEF 1 |
331 | #define ATH_LED_PIN_9287 8 | 385 | #define ATH_LED_PIN_9287 10 |
332 | #define ATH_LED_PIN_9271 15 | 386 | #define ATH_LED_PIN_9271 15 |
333 | #define ATH_LED_PIN_7010 12 | 387 | #define ATH_LED_PIN_7010 12 |
334 | #define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */ | ||
335 | #define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */ | ||
336 | |||
337 | enum ath_led_type { | ||
338 | ATH_LED_RADIO, | ||
339 | ATH_LED_ASSOC, | ||
340 | ATH_LED_TX, | ||
341 | ATH_LED_RX | ||
342 | }; | ||
343 | 388 | ||
344 | struct ath_led { | 389 | #define BSTUCK_THRESHOLD 10 |
345 | struct ath9k_htc_priv *priv; | 390 | |
346 | struct led_classdev led_cdev; | 391 | /* |
347 | enum ath_led_type led_type; | 392 | * Adjust these when the max. no of beaconing interfaces is |
348 | struct delayed_work brightness_work; | 393 | * increased. |
349 | char name[32]; | 394 | */ |
350 | bool registered; | 395 | #define DEFAULT_SWBA_RESPONSE 40 /* in TUs */ |
351 | int brightness; | 396 | #define MIN_SWBA_RESPONSE 10 /* in TUs */ |
352 | }; | ||
353 | 397 | ||
354 | struct htc_beacon_config { | 398 | struct htc_beacon_config { |
399 | struct ieee80211_vif *bslot[ATH9K_HTC_MAX_BCN_VIF]; | ||
355 | u16 beacon_interval; | 400 | u16 beacon_interval; |
356 | u16 dtim_period; | 401 | u16 dtim_period; |
357 | u16 bmiss_timeout; | 402 | u16 bmiss_timeout; |
403 | u32 bmiss_cnt; | ||
358 | }; | 404 | }; |
359 | 405 | ||
360 | struct ath_btcoex { | 406 | struct ath_btcoex { |
@@ -372,14 +418,11 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); | |||
372 | 418 | ||
373 | #define OP_INVALID BIT(0) | 419 | #define OP_INVALID BIT(0) |
374 | #define OP_SCANNING BIT(1) | 420 | #define OP_SCANNING BIT(1) |
375 | #define OP_LED_ASSOCIATED BIT(2) | 421 | #define OP_ENABLE_BEACON BIT(2) |
376 | #define OP_LED_ON BIT(3) | 422 | #define OP_BT_PRIORITY_DETECTED BIT(3) |
377 | #define OP_ENABLE_BEACON BIT(4) | 423 | #define OP_BT_SCAN BIT(4) |
378 | #define OP_LED_DEINIT BIT(5) | 424 | #define OP_ANI_RUNNING BIT(5) |
379 | #define OP_BT_PRIORITY_DETECTED BIT(6) | 425 | #define OP_TSF_RESET BIT(6) |
380 | #define OP_BT_SCAN BIT(7) | ||
381 | #define OP_ANI_RUNNING BIT(8) | ||
382 | #define OP_TSF_RESET BIT(9) | ||
383 | 426 | ||
384 | struct ath9k_htc_priv { | 427 | struct ath9k_htc_priv { |
385 | struct device *dev; | 428 | struct device *dev; |
@@ -388,6 +431,9 @@ struct ath9k_htc_priv { | |||
388 | struct htc_target *htc; | 431 | struct htc_target *htc; |
389 | struct wmi *wmi; | 432 | struct wmi *wmi; |
390 | 433 | ||
434 | u16 fw_version_major; | ||
435 | u16 fw_version_minor; | ||
436 | |||
391 | enum htc_endpoint_id wmi_cmd_ep; | 437 | enum htc_endpoint_id wmi_cmd_ep; |
392 | enum htc_endpoint_id beacon_ep; | 438 | enum htc_endpoint_id beacon_ep; |
393 | enum htc_endpoint_id cab_ep; | 439 | enum htc_endpoint_id cab_ep; |
@@ -411,27 +457,23 @@ struct ath9k_htc_priv { | |||
411 | u16 txpowlimit; | 457 | u16 txpowlimit; |
412 | u16 nvifs; | 458 | u16 nvifs; |
413 | u16 nstations; | 459 | u16 nstations; |
414 | u32 bmiss_cnt; | ||
415 | bool rearm_ani; | 460 | bool rearm_ani; |
416 | bool reconfig_beacon; | 461 | bool reconfig_beacon; |
462 | unsigned int rxfilter; | ||
417 | 463 | ||
418 | struct ath9k_hw_cal_data caldata; | 464 | struct ath9k_hw_cal_data caldata; |
465 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | ||
419 | 466 | ||
420 | spinlock_t beacon_lock; | 467 | spinlock_t beacon_lock; |
468 | struct htc_beacon_config cur_beacon_conf; | ||
421 | 469 | ||
422 | bool tx_queues_stop; | 470 | struct ath9k_htc_rx rx; |
423 | spinlock_t tx_lock; | 471 | struct ath9k_htc_tx tx; |
424 | 472 | ||
425 | struct ieee80211_vif *vif; | ||
426 | struct htc_beacon_config cur_beacon_conf; | ||
427 | unsigned int rxfilter; | ||
428 | struct tasklet_struct swba_tasklet; | 473 | struct tasklet_struct swba_tasklet; |
429 | struct tasklet_struct rx_tasklet; | 474 | struct tasklet_struct rx_tasklet; |
430 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | ||
431 | struct ath9k_htc_rx rx; | ||
432 | struct tasklet_struct tx_tasklet; | ||
433 | struct sk_buff_head tx_queue; | ||
434 | struct delayed_work ani_work; | 475 | struct delayed_work ani_work; |
476 | struct tasklet_struct tx_failed_tasklet; | ||
435 | struct work_struct ps_work; | 477 | struct work_struct ps_work; |
436 | struct work_struct fatal_work; | 478 | struct work_struct fatal_work; |
437 | 479 | ||
@@ -440,15 +482,13 @@ struct ath9k_htc_priv { | |||
440 | bool ps_enabled; | 482 | bool ps_enabled; |
441 | bool ps_idle; | 483 | bool ps_idle; |
442 | 484 | ||
443 | struct ath_led radio_led; | 485 | #ifdef CONFIG_MAC80211_LEDS |
444 | struct ath_led assoc_led; | 486 | enum led_brightness brightness; |
445 | struct ath_led tx_led; | 487 | bool led_registered; |
446 | struct ath_led rx_led; | 488 | char led_name[32]; |
447 | struct delayed_work ath9k_led_blink_work; | 489 | struct led_classdev led_cdev; |
448 | int led_on_duration; | 490 | struct work_struct led_work; |
449 | int led_off_duration; | 491 | #endif |
450 | int led_on_cnt; | ||
451 | int led_off_cnt; | ||
452 | 492 | ||
453 | int beaconq; | 493 | int beaconq; |
454 | int cabq; | 494 | int cabq; |
@@ -470,11 +510,18 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) | |||
470 | 510 | ||
471 | void ath9k_htc_reset(struct ath9k_htc_priv *priv); | 511 | void ath9k_htc_reset(struct ath9k_htc_priv *priv); |
472 | 512 | ||
513 | void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, | ||
514 | struct ieee80211_vif *vif); | ||
515 | void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, | ||
516 | struct ieee80211_vif *vif); | ||
517 | void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv, | ||
518 | struct ieee80211_vif *vif); | ||
473 | void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); | 519 | void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); |
474 | void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, | 520 | void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, |
475 | struct ieee80211_vif *vif); | 521 | struct ieee80211_vif *vif); |
476 | void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv); | 522 | void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv); |
477 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending); | 523 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, |
524 | struct wmi_event_swba *swba); | ||
478 | 525 | ||
479 | void ath9k_htc_rxep(void *priv, struct sk_buff *skb, | 526 | void ath9k_htc_rxep(void *priv, struct sk_buff *skb, |
480 | enum htc_endpoint_id ep_id); | 527 | enum htc_endpoint_id ep_id); |
@@ -483,7 +530,8 @@ void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id, | |||
483 | void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, | 530 | void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, |
484 | enum htc_endpoint_id ep_id, bool txok); | 531 | enum htc_endpoint_id ep_id, bool txok); |
485 | 532 | ||
486 | int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv); | 533 | int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv, |
534 | u8 enable_coex); | ||
487 | void ath9k_htc_station_work(struct work_struct *work); | 535 | void ath9k_htc_station_work(struct work_struct *work); |
488 | void ath9k_htc_aggr_work(struct work_struct *work); | 536 | void ath9k_htc_aggr_work(struct work_struct *work); |
489 | void ath9k_htc_ani_work(struct work_struct *work); | 537 | void ath9k_htc_ani_work(struct work_struct *work); |
@@ -491,14 +539,23 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv); | |||
491 | void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); | 539 | void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); |
492 | 540 | ||
493 | int ath9k_tx_init(struct ath9k_htc_priv *priv); | 541 | int ath9k_tx_init(struct ath9k_htc_priv *priv); |
494 | void ath9k_tx_tasklet(unsigned long data); | 542 | int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, |
495 | int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb); | 543 | struct sk_buff *skb, u8 slot, bool is_cab); |
496 | void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); | 544 | void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); |
497 | bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype); | 545 | bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype); |
498 | int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv); | 546 | int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv); |
499 | int get_hw_qnum(u16 queue, int *hwq_map); | 547 | int get_hw_qnum(u16 queue, int *hwq_map); |
500 | int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, | 548 | int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, |
501 | struct ath9k_tx_queue_info *qinfo); | 549 | struct ath9k_tx_queue_info *qinfo); |
550 | void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv); | ||
551 | void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv); | ||
552 | int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv); | ||
553 | void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot); | ||
554 | void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv); | ||
555 | void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event); | ||
556 | void ath9k_htc_tx_failed(struct ath9k_htc_priv *priv); | ||
557 | void ath9k_tx_failed_tasklet(unsigned long data); | ||
558 | void ath9k_htc_tx_cleanup_timer(unsigned long data); | ||
502 | 559 | ||
503 | int ath9k_rx_init(struct ath9k_htc_priv *priv); | 560 | int ath9k_rx_init(struct ath9k_htc_priv *priv); |
504 | void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); | 561 | void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); |
@@ -516,9 +573,24 @@ void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); | |||
516 | void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw); | 573 | void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw); |
517 | void ath9k_htc_radio_enable(struct ieee80211_hw *hw); | 574 | void ath9k_htc_radio_enable(struct ieee80211_hw *hw); |
518 | void ath9k_htc_radio_disable(struct ieee80211_hw *hw); | 575 | void ath9k_htc_radio_disable(struct ieee80211_hw *hw); |
519 | void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv); | 576 | |
577 | #ifdef CONFIG_MAC80211_LEDS | ||
520 | void ath9k_init_leds(struct ath9k_htc_priv *priv); | 578 | void ath9k_init_leds(struct ath9k_htc_priv *priv); |
521 | void ath9k_deinit_leds(struct ath9k_htc_priv *priv); | 579 | void ath9k_deinit_leds(struct ath9k_htc_priv *priv); |
580 | void ath9k_led_work(struct work_struct *work); | ||
581 | #else | ||
582 | static inline void ath9k_init_leds(struct ath9k_htc_priv *priv) | ||
583 | { | ||
584 | } | ||
585 | |||
586 | static inline void ath9k_deinit_leds(struct ath9k_htc_priv *priv) | ||
587 | { | ||
588 | } | ||
589 | |||
590 | static inline void ath9k_led_work(struct work_struct *work) | ||
591 | { | ||
592 | } | ||
593 | #endif | ||
522 | 594 | ||
523 | int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, | 595 | int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, |
524 | u16 devid, char *product, u32 drv_info); | 596 | u16 devid, char *product, u32 drv_info); |
@@ -528,15 +600,9 @@ void ath9k_htc_suspend(struct htc_target *htc_handle); | |||
528 | int ath9k_htc_resume(struct htc_target *htc_handle); | 600 | int ath9k_htc_resume(struct htc_target *htc_handle); |
529 | #endif | 601 | #endif |
530 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | 602 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS |
531 | int ath9k_htc_debug_create_root(void); | ||
532 | void ath9k_htc_debug_remove_root(void); | ||
533 | int ath9k_htc_init_debug(struct ath_hw *ah); | 603 | int ath9k_htc_init_debug(struct ath_hw *ah); |
534 | void ath9k_htc_exit_debug(struct ath_hw *ah); | ||
535 | #else | 604 | #else |
536 | static inline int ath9k_htc_debug_create_root(void) { return 0; }; | ||
537 | static inline void ath9k_htc_debug_remove_root(void) {}; | ||
538 | static inline int ath9k_htc_init_debug(struct ath_hw *ah) { return 0; }; | 605 | static inline int ath9k_htc_init_debug(struct ath_hw *ah) { return 0; }; |
539 | static inline void ath9k_htc_exit_debug(struct ath_hw *ah) {}; | ||
540 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ | 606 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ |
541 | 607 | ||
542 | #endif /* HTC_H */ | 608 | #endif /* HTC_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 8d1d8792436..0ded2c66d5f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |||
@@ -18,6 +18,50 @@ | |||
18 | 18 | ||
19 | #define FUDGE 2 | 19 | #define FUDGE 2 |
20 | 20 | ||
21 | void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) | ||
22 | { | ||
23 | struct ath_hw *ah = priv->ah; | ||
24 | struct ath9k_tx_queue_info qi, qi_be; | ||
25 | |||
26 | memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); | ||
27 | memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); | ||
28 | |||
29 | ath9k_hw_get_txq_props(ah, priv->beaconq, &qi); | ||
30 | |||
31 | if (priv->ah->opmode == NL80211_IFTYPE_AP) { | ||
32 | qi.tqi_aifs = 1; | ||
33 | qi.tqi_cwmin = 0; | ||
34 | qi.tqi_cwmax = 0; | ||
35 | } else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { | ||
36 | int qnum = priv->hwq_map[WME_AC_BE]; | ||
37 | |||
38 | ath9k_hw_get_txq_props(ah, qnum, &qi_be); | ||
39 | |||
40 | qi.tqi_aifs = qi_be.tqi_aifs; | ||
41 | |||
42 | /* | ||
43 | * For WIFI Beacon Distribution | ||
44 | * Long slot time : 2x cwmin | ||
45 | * Short slot time : 4x cwmin | ||
46 | */ | ||
47 | if (ah->slottime == ATH9K_SLOT_TIME_20) | ||
48 | qi.tqi_cwmin = 2*qi_be.tqi_cwmin; | ||
49 | else | ||
50 | qi.tqi_cwmin = 4*qi_be.tqi_cwmin; | ||
51 | |||
52 | qi.tqi_cwmax = qi_be.tqi_cwmax; | ||
53 | |||
54 | } | ||
55 | |||
56 | if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { | ||
57 | ath_err(ath9k_hw_common(ah), | ||
58 | "Unable to update beacon queue %u!\n", priv->beaconq); | ||
59 | } else { | ||
60 | ath9k_hw_resettxqueue(ah, priv->beaconq); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | |||
21 | static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, | 65 | static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, |
22 | struct htc_beacon_config *bss_conf) | 66 | struct htc_beacon_config *bss_conf) |
23 | { | 67 | { |
@@ -30,7 +74,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, | |||
30 | __be32 htc_imask = 0; | 74 | __be32 htc_imask = 0; |
31 | u64 tsf; | 75 | u64 tsf; |
32 | int num_beacons, offset, dtim_dec_count, cfp_dec_count; | 76 | int num_beacons, offset, dtim_dec_count, cfp_dec_count; |
33 | int ret; | 77 | int ret __attribute__ ((unused)); |
34 | u8 cmd_rsp; | 78 | u8 cmd_rsp; |
35 | 79 | ||
36 | memset(&bs, 0, sizeof(bs)); | 80 | memset(&bs, 0, sizeof(bs)); |
@@ -146,7 +190,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, | |||
146 | enum ath9k_int imask = 0; | 190 | enum ath9k_int imask = 0; |
147 | u32 nexttbtt, intval, tsftu; | 191 | u32 nexttbtt, intval, tsftu; |
148 | __be32 htc_imask = 0; | 192 | __be32 htc_imask = 0; |
149 | int ret; | 193 | int ret __attribute__ ((unused)); |
150 | u8 cmd_rsp; | 194 | u8 cmd_rsp; |
151 | u64 tsf; | 195 | u64 tsf; |
152 | 196 | ||
@@ -154,8 +198,17 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, | |||
154 | intval /= ATH9K_HTC_MAX_BCN_VIF; | 198 | intval /= ATH9K_HTC_MAX_BCN_VIF; |
155 | nexttbtt = intval; | 199 | nexttbtt = intval; |
156 | 200 | ||
201 | /* | ||
202 | * To reduce beacon misses under heavy TX load, | ||
203 | * set the beacon response time to a larger value. | ||
204 | */ | ||
205 | if (intval > DEFAULT_SWBA_RESPONSE) | ||
206 | priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE; | ||
207 | else | ||
208 | priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; | ||
209 | |||
157 | if (priv->op_flags & OP_TSF_RESET) { | 210 | if (priv->op_flags & OP_TSF_RESET) { |
158 | intval |= ATH9K_BEACON_RESET_TSF; | 211 | ath9k_hw_reset_tsf(priv->ah); |
159 | priv->op_flags &= ~OP_TSF_RESET; | 212 | priv->op_flags &= ~OP_TSF_RESET; |
160 | } else { | 213 | } else { |
161 | /* | 214 | /* |
@@ -168,18 +221,20 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, | |||
168 | } while (nexttbtt < tsftu); | 221 | } while (nexttbtt < tsftu); |
169 | } | 222 | } |
170 | 223 | ||
171 | intval |= ATH9K_BEACON_ENA; | ||
172 | |||
173 | if (priv->op_flags & OP_ENABLE_BEACON) | 224 | if (priv->op_flags & OP_ENABLE_BEACON) |
174 | imask |= ATH9K_INT_SWBA; | 225 | imask |= ATH9K_INT_SWBA; |
175 | 226 | ||
176 | ath_dbg(common, ATH_DBG_CONFIG, | 227 | ath_dbg(common, ATH_DBG_CONFIG, |
177 | "AP Beacon config, intval: %d, nexttbtt: %u imask: 0x%x\n", | 228 | "AP Beacon config, intval: %d, nexttbtt: %u, resp_time: %d " |
178 | bss_conf->beacon_interval, nexttbtt, imask); | 229 | "imask: 0x%x\n", |
230 | bss_conf->beacon_interval, nexttbtt, | ||
231 | priv->ah->config.sw_beacon_response_time, imask); | ||
232 | |||
233 | ath9k_htc_beaconq_config(priv); | ||
179 | 234 | ||
180 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 235 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
181 | ath9k_hw_beaconinit(priv->ah, nexttbtt, intval); | 236 | ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); |
182 | priv->bmiss_cnt = 0; | 237 | priv->cur_beacon_conf.bmiss_cnt = 0; |
183 | htc_imask = cpu_to_be32(imask); | 238 | htc_imask = cpu_to_be32(imask); |
184 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); | 239 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); |
185 | } | 240 | } |
@@ -191,7 +246,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, | |||
191 | enum ath9k_int imask = 0; | 246 | enum ath9k_int imask = 0; |
192 | u32 nexttbtt, intval, tsftu; | 247 | u32 nexttbtt, intval, tsftu; |
193 | __be32 htc_imask = 0; | 248 | __be32 htc_imask = 0; |
194 | int ret; | 249 | int ret __attribute__ ((unused)); |
195 | u8 cmd_rsp; | 250 | u8 cmd_rsp; |
196 | u64 tsf; | 251 | u64 tsf; |
197 | 252 | ||
@@ -207,17 +262,26 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, | |||
207 | nexttbtt += intval; | 262 | nexttbtt += intval; |
208 | } while (nexttbtt < tsftu); | 263 | } while (nexttbtt < tsftu); |
209 | 264 | ||
210 | intval |= ATH9K_BEACON_ENA; | 265 | /* |
266 | * Only one IBSS interfce is allowed. | ||
267 | */ | ||
268 | if (intval > DEFAULT_SWBA_RESPONSE) | ||
269 | priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE; | ||
270 | else | ||
271 | priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; | ||
272 | |||
211 | if (priv->op_flags & OP_ENABLE_BEACON) | 273 | if (priv->op_flags & OP_ENABLE_BEACON) |
212 | imask |= ATH9K_INT_SWBA; | 274 | imask |= ATH9K_INT_SWBA; |
213 | 275 | ||
214 | ath_dbg(common, ATH_DBG_CONFIG, | 276 | ath_dbg(common, ATH_DBG_CONFIG, |
215 | "IBSS Beacon config, intval: %d, nexttbtt: %u, imask: 0x%x\n", | 277 | "IBSS Beacon config, intval: %d, nexttbtt: %u, " |
216 | bss_conf->beacon_interval, nexttbtt, imask); | 278 | "resp_time: %d, imask: 0x%x\n", |
279 | bss_conf->beacon_interval, nexttbtt, | ||
280 | priv->ah->config.sw_beacon_response_time, imask); | ||
217 | 281 | ||
218 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 282 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
219 | ath9k_hw_beaconinit(priv->ah, nexttbtt, intval); | 283 | ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); |
220 | priv->bmiss_cnt = 0; | 284 | priv->cur_beacon_conf.bmiss_cnt = 0; |
221 | htc_imask = cpu_to_be32(imask); | 285 | htc_imask = cpu_to_be32(imask); |
222 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); | 286 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); |
223 | } | 287 | } |
@@ -228,38 +292,101 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, | |||
228 | dev_kfree_skb_any(skb); | 292 | dev_kfree_skb_any(skb); |
229 | } | 293 | } |
230 | 294 | ||
231 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) | 295 | static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, |
296 | int slot) | ||
232 | { | 297 | { |
233 | struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv; | 298 | struct ath_common *common = ath9k_hw_common(priv->ah); |
299 | struct ieee80211_vif *vif; | ||
300 | struct sk_buff *skb; | ||
301 | struct ieee80211_hdr *hdr; | ||
302 | int padpos, padsize, ret, tx_slot; | ||
303 | |||
304 | spin_lock_bh(&priv->beacon_lock); | ||
305 | |||
306 | vif = priv->cur_beacon_conf.bslot[slot]; | ||
307 | |||
308 | skb = ieee80211_get_buffered_bc(priv->hw, vif); | ||
309 | |||
310 | while(skb) { | ||
311 | hdr = (struct ieee80211_hdr *) skb->data; | ||
312 | |||
313 | padpos = ath9k_cmn_padpos(hdr->frame_control); | ||
314 | padsize = padpos & 3; | ||
315 | if (padsize && skb->len > padpos) { | ||
316 | if (skb_headroom(skb) < padsize) { | ||
317 | dev_kfree_skb_any(skb); | ||
318 | goto next; | ||
319 | } | ||
320 | skb_push(skb, padsize); | ||
321 | memmove(skb->data, skb->data + padsize, padpos); | ||
322 | } | ||
323 | |||
324 | tx_slot = ath9k_htc_tx_get_slot(priv); | ||
325 | if (tx_slot < 0) { | ||
326 | ath_dbg(common, ATH_DBG_XMIT, "No free CAB slot\n"); | ||
327 | dev_kfree_skb_any(skb); | ||
328 | goto next; | ||
329 | } | ||
330 | |||
331 | ret = ath9k_htc_tx_start(priv, skb, tx_slot, true); | ||
332 | if (ret != 0) { | ||
333 | ath9k_htc_tx_clear_slot(priv, tx_slot); | ||
334 | dev_kfree_skb_any(skb); | ||
335 | |||
336 | ath_dbg(common, ATH_DBG_XMIT, | ||
337 | "Failed to send CAB frame\n"); | ||
338 | } else { | ||
339 | spin_lock_bh(&priv->tx.tx_lock); | ||
340 | priv->tx.queued_cnt++; | ||
341 | spin_unlock_bh(&priv->tx.tx_lock); | ||
342 | } | ||
343 | next: | ||
344 | skb = ieee80211_get_buffered_bc(priv->hw, vif); | ||
345 | } | ||
346 | |||
347 | spin_unlock_bh(&priv->beacon_lock); | ||
348 | } | ||
349 | |||
350 | static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, | ||
351 | int slot) | ||
352 | { | ||
353 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
354 | struct ieee80211_vif *vif; | ||
355 | struct ath9k_htc_vif *avp; | ||
234 | struct tx_beacon_header beacon_hdr; | 356 | struct tx_beacon_header beacon_hdr; |
235 | struct ath9k_htc_tx_ctl tx_ctl; | 357 | struct ath9k_htc_tx_ctl *tx_ctl; |
236 | struct ieee80211_tx_info *info; | 358 | struct ieee80211_tx_info *info; |
359 | struct ieee80211_mgmt *mgmt; | ||
237 | struct sk_buff *beacon; | 360 | struct sk_buff *beacon; |
238 | u8 *tx_fhdr; | 361 | u8 *tx_fhdr; |
362 | int ret; | ||
239 | 363 | ||
240 | memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); | 364 | memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); |
241 | memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); | ||
242 | |||
243 | /* FIXME: Handle BMISS */ | ||
244 | if (beacon_pending != 0) { | ||
245 | priv->bmiss_cnt++; | ||
246 | return; | ||
247 | } | ||
248 | 365 | ||
249 | spin_lock_bh(&priv->beacon_lock); | 366 | spin_lock_bh(&priv->beacon_lock); |
250 | 367 | ||
368 | vif = priv->cur_beacon_conf.bslot[slot]; | ||
369 | avp = (struct ath9k_htc_vif *)vif->drv_priv; | ||
370 | |||
251 | if (unlikely(priv->op_flags & OP_SCANNING)) { | 371 | if (unlikely(priv->op_flags & OP_SCANNING)) { |
252 | spin_unlock_bh(&priv->beacon_lock); | 372 | spin_unlock_bh(&priv->beacon_lock); |
253 | return; | 373 | return; |
254 | } | 374 | } |
255 | 375 | ||
256 | /* Get a new beacon */ | 376 | /* Get a new beacon */ |
257 | beacon = ieee80211_beacon_get(priv->hw, priv->vif); | 377 | beacon = ieee80211_beacon_get(priv->hw, vif); |
258 | if (!beacon) { | 378 | if (!beacon) { |
259 | spin_unlock_bh(&priv->beacon_lock); | 379 | spin_unlock_bh(&priv->beacon_lock); |
260 | return; | 380 | return; |
261 | } | 381 | } |
262 | 382 | ||
383 | /* | ||
384 | * Update the TSF adjust value here, the HW will | ||
385 | * add this value for every beacon. | ||
386 | */ | ||
387 | mgmt = (struct ieee80211_mgmt *)beacon->data; | ||
388 | mgmt->u.beacon.timestamp = avp->tsfadjust; | ||
389 | |||
263 | info = IEEE80211_SKB_CB(beacon); | 390 | info = IEEE80211_SKB_CB(beacon); |
264 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | 391 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { |
265 | struct ieee80211_hdr *hdr = | 392 | struct ieee80211_hdr *hdr = |
@@ -269,45 +396,149 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) | |||
269 | hdr->seq_ctrl |= cpu_to_le16(avp->seq_no); | 396 | hdr->seq_ctrl |= cpu_to_le16(avp->seq_no); |
270 | } | 397 | } |
271 | 398 | ||
272 | tx_ctl.type = ATH9K_HTC_NORMAL; | 399 | tx_ctl = HTC_SKB_CB(beacon); |
400 | memset(tx_ctl, 0, sizeof(*tx_ctl)); | ||
401 | |||
402 | tx_ctl->type = ATH9K_HTC_BEACON; | ||
403 | tx_ctl->epid = priv->beacon_ep; | ||
404 | |||
273 | beacon_hdr.vif_index = avp->index; | 405 | beacon_hdr.vif_index = avp->index; |
274 | tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); | 406 | tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); |
275 | memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); | 407 | memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); |
276 | 408 | ||
277 | htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl); | 409 | ret = htc_send(priv->htc, beacon); |
410 | if (ret != 0) { | ||
411 | if (ret == -ENOMEM) { | ||
412 | ath_dbg(common, ATH_DBG_BSTUCK, | ||
413 | "Failed to send beacon, no free TX buffer\n"); | ||
414 | } | ||
415 | dev_kfree_skb_any(beacon); | ||
416 | } | ||
278 | 417 | ||
279 | spin_unlock_bh(&priv->beacon_lock); | 418 | spin_unlock_bh(&priv->beacon_lock); |
280 | } | 419 | } |
281 | 420 | ||
282 | /* Currently, only for IBSS */ | 421 | static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv, |
283 | void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) | 422 | struct wmi_event_swba *swba) |
284 | { | 423 | { |
285 | struct ath_hw *ah = priv->ah; | 424 | struct ath_common *common = ath9k_hw_common(priv->ah); |
286 | struct ath9k_tx_queue_info qi, qi_be; | 425 | u64 tsf; |
287 | int qnum = priv->hwq_map[WME_AC_BE]; | 426 | u32 tsftu; |
427 | u16 intval; | ||
428 | int slot; | ||
288 | 429 | ||
289 | memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); | 430 | intval = priv->cur_beacon_conf.beacon_interval & ATH9K_BEACON_PERIOD; |
290 | memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); | ||
291 | 431 | ||
292 | ath9k_hw_get_txq_props(ah, qnum, &qi_be); | 432 | tsf = be64_to_cpu(swba->tsf); |
433 | tsftu = TSF_TO_TU(tsf >> 32, tsf); | ||
434 | slot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval; | ||
435 | slot = ATH9K_HTC_MAX_BCN_VIF - slot - 1; | ||
293 | 436 | ||
294 | qi.tqi_aifs = qi_be.tqi_aifs; | 437 | ath_dbg(common, ATH_DBG_BEACON, |
295 | /* For WIFI Beacon Distribution | 438 | "Choose slot: %d, tsf: %llu, tsftu: %u, intval: %u\n", |
296 | * Long slot time : 2x cwmin | 439 | slot, tsf, tsftu, intval); |
297 | * Short slot time : 4x cwmin | ||
298 | */ | ||
299 | if (ah->slottime == ATH9K_SLOT_TIME_20) | ||
300 | qi.tqi_cwmin = 2*qi_be.tqi_cwmin; | ||
301 | else | ||
302 | qi.tqi_cwmin = 4*qi_be.tqi_cwmin; | ||
303 | qi.tqi_cwmax = qi_be.tqi_cwmax; | ||
304 | 440 | ||
305 | if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { | 441 | return slot; |
306 | ath_err(ath9k_hw_common(ah), | 442 | } |
307 | "Unable to update beacon queue %u!\n", qnum); | 443 | |
308 | } else { | 444 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, |
309 | ath9k_hw_resettxqueue(ah, priv->beaconq); | 445 | struct wmi_event_swba *swba) |
446 | { | ||
447 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
448 | int slot; | ||
449 | |||
450 | if (swba->beacon_pending != 0) { | ||
451 | priv->cur_beacon_conf.bmiss_cnt++; | ||
452 | if (priv->cur_beacon_conf.bmiss_cnt > BSTUCK_THRESHOLD) { | ||
453 | ath_dbg(common, ATH_DBG_BSTUCK, | ||
454 | "Beacon stuck, HW reset\n"); | ||
455 | ieee80211_queue_work(priv->hw, | ||
456 | &priv->fatal_work); | ||
457 | } | ||
458 | return; | ||
310 | } | 459 | } |
460 | |||
461 | if (priv->cur_beacon_conf.bmiss_cnt) { | ||
462 | ath_dbg(common, ATH_DBG_BSTUCK, | ||
463 | "Resuming beacon xmit after %u misses\n", | ||
464 | priv->cur_beacon_conf.bmiss_cnt); | ||
465 | priv->cur_beacon_conf.bmiss_cnt = 0; | ||
466 | } | ||
467 | |||
468 | slot = ath9k_htc_choose_bslot(priv, swba); | ||
469 | spin_lock_bh(&priv->beacon_lock); | ||
470 | if (priv->cur_beacon_conf.bslot[slot] == NULL) { | ||
471 | spin_unlock_bh(&priv->beacon_lock); | ||
472 | return; | ||
473 | } | ||
474 | spin_unlock_bh(&priv->beacon_lock); | ||
475 | |||
476 | ath9k_htc_send_buffered(priv, slot); | ||
477 | ath9k_htc_send_beacon(priv, slot); | ||
478 | } | ||
479 | |||
480 | void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, | ||
481 | struct ieee80211_vif *vif) | ||
482 | { | ||
483 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
484 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; | ||
485 | int i = 0; | ||
486 | |||
487 | spin_lock_bh(&priv->beacon_lock); | ||
488 | for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) { | ||
489 | if (priv->cur_beacon_conf.bslot[i] == NULL) { | ||
490 | avp->bslot = i; | ||
491 | break; | ||
492 | } | ||
493 | } | ||
494 | |||
495 | priv->cur_beacon_conf.bslot[avp->bslot] = vif; | ||
496 | spin_unlock_bh(&priv->beacon_lock); | ||
497 | |||
498 | ath_dbg(common, ATH_DBG_CONFIG, | ||
499 | "Added interface at beacon slot: %d\n", avp->bslot); | ||
500 | } | ||
501 | |||
502 | void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, | ||
503 | struct ieee80211_vif *vif) | ||
504 | { | ||
505 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
506 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; | ||
507 | |||
508 | spin_lock_bh(&priv->beacon_lock); | ||
509 | priv->cur_beacon_conf.bslot[avp->bslot] = NULL; | ||
510 | spin_unlock_bh(&priv->beacon_lock); | ||
511 | |||
512 | ath_dbg(common, ATH_DBG_CONFIG, | ||
513 | "Removed interface at beacon slot: %d\n", avp->bslot); | ||
514 | } | ||
515 | |||
516 | /* | ||
517 | * Calculate the TSF adjustment value for all slots | ||
518 | * other than zero. | ||
519 | */ | ||
520 | void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv, | ||
521 | struct ieee80211_vif *vif) | ||
522 | { | ||
523 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
524 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; | ||
525 | struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; | ||
526 | u64 tsfadjust; | ||
527 | |||
528 | if (avp->bslot == 0) | ||
529 | return; | ||
530 | |||
531 | /* | ||
532 | * The beacon interval cannot be different for multi-AP mode, | ||
533 | * and we reach here only for VIF slots greater than zero, | ||
534 | * so beacon_interval is guaranteed to be set in cur_conf. | ||
535 | */ | ||
536 | tsfadjust = cur_conf->beacon_interval * avp->bslot / ATH9K_HTC_MAX_BCN_VIF; | ||
537 | avp->tsfadjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); | ||
538 | |||
539 | ath_dbg(common, ATH_DBG_CONFIG, | ||
540 | "tsfadjust is: %llu for bslot: %d\n", | ||
541 | (unsigned long long)tsfadjust, avp->bslot); | ||
311 | } | 542 | } |
312 | 543 | ||
313 | static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | 544 | static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif) |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c new file mode 100644 index 00000000000..aa48b3abbc4 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c | |||
@@ -0,0 +1,960 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010-2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "htc.h" | ||
18 | |||
19 | static int ath9k_debugfs_open(struct inode *inode, struct file *file) | ||
20 | { | ||
21 | file->private_data = inode->i_private; | ||
22 | return 0; | ||
23 | } | ||
24 | |||
25 | static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, | ||
26 | size_t count, loff_t *ppos) | ||
27 | { | ||
28 | struct ath9k_htc_priv *priv = file->private_data; | ||
29 | struct ath9k_htc_target_int_stats cmd_rsp; | ||
30 | char buf[512]; | ||
31 | unsigned int len = 0; | ||
32 | int ret = 0; | ||
33 | |||
34 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
35 | |||
36 | ath9k_htc_ps_wakeup(priv); | ||
37 | |||
38 | WMI_CMD(WMI_INT_STATS_CMDID); | ||
39 | if (ret) { | ||
40 | ath9k_htc_ps_restore(priv); | ||
41 | return -EINVAL; | ||
42 | } | ||
43 | |||
44 | ath9k_htc_ps_restore(priv); | ||
45 | |||
46 | len += snprintf(buf + len, sizeof(buf) - len, | ||
47 | "%20s : %10u\n", "RX", | ||
48 | be32_to_cpu(cmd_rsp.rx)); | ||
49 | |||
50 | len += snprintf(buf + len, sizeof(buf) - len, | ||
51 | "%20s : %10u\n", "RXORN", | ||
52 | be32_to_cpu(cmd_rsp.rxorn)); | ||
53 | |||
54 | len += snprintf(buf + len, sizeof(buf) - len, | ||
55 | "%20s : %10u\n", "RXEOL", | ||
56 | be32_to_cpu(cmd_rsp.rxeol)); | ||
57 | |||
58 | len += snprintf(buf + len, sizeof(buf) - len, | ||
59 | "%20s : %10u\n", "TXURN", | ||
60 | be32_to_cpu(cmd_rsp.txurn)); | ||
61 | |||
62 | len += snprintf(buf + len, sizeof(buf) - len, | ||
63 | "%20s : %10u\n", "TXTO", | ||
64 | be32_to_cpu(cmd_rsp.txto)); | ||
65 | |||
66 | len += snprintf(buf + len, sizeof(buf) - len, | ||
67 | "%20s : %10u\n", "CST", | ||
68 | be32_to_cpu(cmd_rsp.cst)); | ||
69 | |||
70 | if (len > sizeof(buf)) | ||
71 | len = sizeof(buf); | ||
72 | |||
73 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
74 | } | ||
75 | |||
76 | static const struct file_operations fops_tgt_int_stats = { | ||
77 | .read = read_file_tgt_int_stats, | ||
78 | .open = ath9k_debugfs_open, | ||
79 | .owner = THIS_MODULE, | ||
80 | .llseek = default_llseek, | ||
81 | }; | ||
82 | |||
83 | static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf, | ||
84 | size_t count, loff_t *ppos) | ||
85 | { | ||
86 | struct ath9k_htc_priv *priv = file->private_data; | ||
87 | struct ath9k_htc_target_tx_stats cmd_rsp; | ||
88 | char buf[512]; | ||
89 | unsigned int len = 0; | ||
90 | int ret = 0; | ||
91 | |||
92 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
93 | |||
94 | ath9k_htc_ps_wakeup(priv); | ||
95 | |||
96 | WMI_CMD(WMI_TX_STATS_CMDID); | ||
97 | if (ret) { | ||
98 | ath9k_htc_ps_restore(priv); | ||
99 | return -EINVAL; | ||
100 | } | ||
101 | |||
102 | ath9k_htc_ps_restore(priv); | ||
103 | |||
104 | len += snprintf(buf + len, sizeof(buf) - len, | ||
105 | "%20s : %10u\n", "Xretries", | ||
106 | be32_to_cpu(cmd_rsp.xretries)); | ||
107 | |||
108 | len += snprintf(buf + len, sizeof(buf) - len, | ||
109 | "%20s : %10u\n", "FifoErr", | ||
110 | be32_to_cpu(cmd_rsp.fifoerr)); | ||
111 | |||
112 | len += snprintf(buf + len, sizeof(buf) - len, | ||
113 | "%20s : %10u\n", "Filtered", | ||
114 | be32_to_cpu(cmd_rsp.filtered)); | ||
115 | |||
116 | len += snprintf(buf + len, sizeof(buf) - len, | ||
117 | "%20s : %10u\n", "TimerExp", | ||
118 | be32_to_cpu(cmd_rsp.timer_exp)); | ||
119 | |||
120 | len += snprintf(buf + len, sizeof(buf) - len, | ||
121 | "%20s : %10u\n", "ShortRetries", | ||
122 | be32_to_cpu(cmd_rsp.shortretries)); | ||
123 | |||
124 | len += snprintf(buf + len, sizeof(buf) - len, | ||
125 | "%20s : %10u\n", "LongRetries", | ||
126 | be32_to_cpu(cmd_rsp.longretries)); | ||
127 | |||
128 | len += snprintf(buf + len, sizeof(buf) - len, | ||
129 | "%20s : %10u\n", "QueueNull", | ||
130 | be32_to_cpu(cmd_rsp.qnull)); | ||
131 | |||
132 | len += snprintf(buf + len, sizeof(buf) - len, | ||
133 | "%20s : %10u\n", "EncapFail", | ||
134 | be32_to_cpu(cmd_rsp.encap_fail)); | ||
135 | |||
136 | len += snprintf(buf + len, sizeof(buf) - len, | ||
137 | "%20s : %10u\n", "NoBuf", | ||
138 | be32_to_cpu(cmd_rsp.nobuf)); | ||
139 | |||
140 | if (len > sizeof(buf)) | ||
141 | len = sizeof(buf); | ||
142 | |||
143 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
144 | } | ||
145 | |||
146 | static const struct file_operations fops_tgt_tx_stats = { | ||
147 | .read = read_file_tgt_tx_stats, | ||
148 | .open = ath9k_debugfs_open, | ||
149 | .owner = THIS_MODULE, | ||
150 | .llseek = default_llseek, | ||
151 | }; | ||
152 | |||
153 | static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf, | ||
154 | size_t count, loff_t *ppos) | ||
155 | { | ||
156 | struct ath9k_htc_priv *priv = file->private_data; | ||
157 | struct ath9k_htc_target_rx_stats cmd_rsp; | ||
158 | char buf[512]; | ||
159 | unsigned int len = 0; | ||
160 | int ret = 0; | ||
161 | |||
162 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
163 | |||
164 | ath9k_htc_ps_wakeup(priv); | ||
165 | |||
166 | WMI_CMD(WMI_RX_STATS_CMDID); | ||
167 | if (ret) { | ||
168 | ath9k_htc_ps_restore(priv); | ||
169 | return -EINVAL; | ||
170 | } | ||
171 | |||
172 | ath9k_htc_ps_restore(priv); | ||
173 | |||
174 | len += snprintf(buf + len, sizeof(buf) - len, | ||
175 | "%20s : %10u\n", "NoBuf", | ||
176 | be32_to_cpu(cmd_rsp.nobuf)); | ||
177 | |||
178 | len += snprintf(buf + len, sizeof(buf) - len, | ||
179 | "%20s : %10u\n", "HostSend", | ||
180 | be32_to_cpu(cmd_rsp.host_send)); | ||
181 | |||
182 | len += snprintf(buf + len, sizeof(buf) - len, | ||
183 | "%20s : %10u\n", "HostDone", | ||
184 | be32_to_cpu(cmd_rsp.host_done)); | ||
185 | |||
186 | if (len > sizeof(buf)) | ||
187 | len = sizeof(buf); | ||
188 | |||
189 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
190 | } | ||
191 | |||
192 | static const struct file_operations fops_tgt_rx_stats = { | ||
193 | .read = read_file_tgt_rx_stats, | ||
194 | .open = ath9k_debugfs_open, | ||
195 | .owner = THIS_MODULE, | ||
196 | .llseek = default_llseek, | ||
197 | }; | ||
198 | |||
199 | static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | ||
200 | size_t count, loff_t *ppos) | ||
201 | { | ||
202 | struct ath9k_htc_priv *priv = file->private_data; | ||
203 | char buf[512]; | ||
204 | unsigned int len = 0; | ||
205 | |||
206 | len += snprintf(buf + len, sizeof(buf) - len, | ||
207 | "%20s : %10u\n", "Buffers queued", | ||
208 | priv->debug.tx_stats.buf_queued); | ||
209 | len += snprintf(buf + len, sizeof(buf) - len, | ||
210 | "%20s : %10u\n", "Buffers completed", | ||
211 | priv->debug.tx_stats.buf_completed); | ||
212 | len += snprintf(buf + len, sizeof(buf) - len, | ||
213 | "%20s : %10u\n", "SKBs queued", | ||
214 | priv->debug.tx_stats.skb_queued); | ||
215 | len += snprintf(buf + len, sizeof(buf) - len, | ||
216 | "%20s : %10u\n", "SKBs success", | ||
217 | priv->debug.tx_stats.skb_success); | ||
218 | len += snprintf(buf + len, sizeof(buf) - len, | ||
219 | "%20s : %10u\n", "SKBs failed", | ||
220 | priv->debug.tx_stats.skb_failed); | ||
221 | len += snprintf(buf + len, sizeof(buf) - len, | ||
222 | "%20s : %10u\n", "CAB queued", | ||
223 | priv->debug.tx_stats.cab_queued); | ||
224 | |||
225 | len += snprintf(buf + len, sizeof(buf) - len, | ||
226 | "%20s : %10u\n", "BE queued", | ||
227 | priv->debug.tx_stats.queue_stats[WME_AC_BE]); | ||
228 | len += snprintf(buf + len, sizeof(buf) - len, | ||
229 | "%20s : %10u\n", "BK queued", | ||
230 | priv->debug.tx_stats.queue_stats[WME_AC_BK]); | ||
231 | len += snprintf(buf + len, sizeof(buf) - len, | ||
232 | "%20s : %10u\n", "VI queued", | ||
233 | priv->debug.tx_stats.queue_stats[WME_AC_VI]); | ||
234 | len += snprintf(buf + len, sizeof(buf) - len, | ||
235 | "%20s : %10u\n", "VO queued", | ||
236 | priv->debug.tx_stats.queue_stats[WME_AC_VO]); | ||
237 | |||
238 | if (len > sizeof(buf)) | ||
239 | len = sizeof(buf); | ||
240 | |||
241 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
242 | } | ||
243 | |||
244 | static const struct file_operations fops_xmit = { | ||
245 | .read = read_file_xmit, | ||
246 | .open = ath9k_debugfs_open, | ||
247 | .owner = THIS_MODULE, | ||
248 | .llseek = default_llseek, | ||
249 | }; | ||
250 | |||
251 | void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, | ||
252 | struct ath_htc_rx_status *rxs) | ||
253 | { | ||
254 | #define RX_PHY_ERR_INC(c) priv->debug.rx_stats.err_phy_stats[c]++ | ||
255 | |||
256 | if (rxs->rs_status & ATH9K_RXERR_CRC) | ||
257 | priv->debug.rx_stats.err_crc++; | ||
258 | if (rxs->rs_status & ATH9K_RXERR_DECRYPT) | ||
259 | priv->debug.rx_stats.err_decrypt_crc++; | ||
260 | if (rxs->rs_status & ATH9K_RXERR_MIC) | ||
261 | priv->debug.rx_stats.err_mic++; | ||
262 | if (rxs->rs_status & ATH9K_RX_DELIM_CRC_PRE) | ||
263 | priv->debug.rx_stats.err_pre_delim++; | ||
264 | if (rxs->rs_status & ATH9K_RX_DELIM_CRC_POST) | ||
265 | priv->debug.rx_stats.err_post_delim++; | ||
266 | if (rxs->rs_status & ATH9K_RX_DECRYPT_BUSY) | ||
267 | priv->debug.rx_stats.err_decrypt_busy++; | ||
268 | |||
269 | if (rxs->rs_status & ATH9K_RXERR_PHY) { | ||
270 | priv->debug.rx_stats.err_phy++; | ||
271 | if (rxs->rs_phyerr < ATH9K_PHYERR_MAX) | ||
272 | RX_PHY_ERR_INC(rxs->rs_phyerr); | ||
273 | } | ||
274 | |||
275 | #undef RX_PHY_ERR_INC | ||
276 | } | ||
277 | |||
278 | static ssize_t read_file_recv(struct file *file, char __user *user_buf, | ||
279 | size_t count, loff_t *ppos) | ||
280 | { | ||
281 | #define PHY_ERR(s, p) \ | ||
282 | len += snprintf(buf + len, size - len, "%20s : %10u\n", s, \ | ||
283 | priv->debug.rx_stats.err_phy_stats[p]); | ||
284 | |||
285 | struct ath9k_htc_priv *priv = file->private_data; | ||
286 | char *buf; | ||
287 | unsigned int len = 0, size = 1500; | ||
288 | ssize_t retval = 0; | ||
289 | |||
290 | buf = kzalloc(size, GFP_KERNEL); | ||
291 | if (buf == NULL) | ||
292 | return -ENOMEM; | ||
293 | |||
294 | len += snprintf(buf + len, size - len, | ||
295 | "%20s : %10u\n", "SKBs allocated", | ||
296 | priv->debug.rx_stats.skb_allocated); | ||
297 | len += snprintf(buf + len, size - len, | ||
298 | "%20s : %10u\n", "SKBs completed", | ||
299 | priv->debug.rx_stats.skb_completed); | ||
300 | len += snprintf(buf + len, size - len, | ||
301 | "%20s : %10u\n", "SKBs Dropped", | ||
302 | priv->debug.rx_stats.skb_dropped); | ||
303 | |||
304 | len += snprintf(buf + len, size - len, | ||
305 | "%20s : %10u\n", "CRC ERR", | ||
306 | priv->debug.rx_stats.err_crc); | ||
307 | len += snprintf(buf + len, size - len, | ||
308 | "%20s : %10u\n", "DECRYPT CRC ERR", | ||
309 | priv->debug.rx_stats.err_decrypt_crc); | ||
310 | len += snprintf(buf + len, size - len, | ||
311 | "%20s : %10u\n", "MIC ERR", | ||
312 | priv->debug.rx_stats.err_mic); | ||
313 | len += snprintf(buf + len, size - len, | ||
314 | "%20s : %10u\n", "PRE-DELIM CRC ERR", | ||
315 | priv->debug.rx_stats.err_pre_delim); | ||
316 | len += snprintf(buf + len, size - len, | ||
317 | "%20s : %10u\n", "POST-DELIM CRC ERR", | ||
318 | priv->debug.rx_stats.err_post_delim); | ||
319 | len += snprintf(buf + len, size - len, | ||
320 | "%20s : %10u\n", "DECRYPT BUSY ERR", | ||
321 | priv->debug.rx_stats.err_decrypt_busy); | ||
322 | len += snprintf(buf + len, size - len, | ||
323 | "%20s : %10u\n", "TOTAL PHY ERR", | ||
324 | priv->debug.rx_stats.err_phy); | ||
325 | |||
326 | |||
327 | PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); | ||
328 | PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); | ||
329 | PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); | ||
330 | PHY_ERR("RATE", ATH9K_PHYERR_RATE); | ||
331 | PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH); | ||
332 | PHY_ERR("RADAR", ATH9K_PHYERR_RADAR); | ||
333 | PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE); | ||
334 | PHY_ERR("TOR", ATH9K_PHYERR_TOR); | ||
335 | PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING); | ||
336 | PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); | ||
337 | PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); | ||
338 | PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); | ||
339 | PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP); | ||
340 | PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE); | ||
341 | PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART); | ||
342 | PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT); | ||
343 | PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING); | ||
344 | PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC); | ||
345 | PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL); | ||
346 | PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE); | ||
347 | PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART); | ||
348 | PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); | ||
349 | PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP); | ||
350 | PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR); | ||
351 | PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); | ||
352 | PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL); | ||
353 | |||
354 | if (len > size) | ||
355 | len = size; | ||
356 | |||
357 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
358 | kfree(buf); | ||
359 | |||
360 | return retval; | ||
361 | |||
362 | #undef PHY_ERR | ||
363 | } | ||
364 | |||
365 | static const struct file_operations fops_recv = { | ||
366 | .read = read_file_recv, | ||
367 | .open = ath9k_debugfs_open, | ||
368 | .owner = THIS_MODULE, | ||
369 | .llseek = default_llseek, | ||
370 | }; | ||
371 | |||
372 | static ssize_t read_file_slot(struct file *file, char __user *user_buf, | ||
373 | size_t count, loff_t *ppos) | ||
374 | { | ||
375 | struct ath9k_htc_priv *priv = file->private_data; | ||
376 | char buf[512]; | ||
377 | unsigned int len = 0; | ||
378 | |||
379 | spin_lock_bh(&priv->tx.tx_lock); | ||
380 | |||
381 | len += snprintf(buf + len, sizeof(buf) - len, "TX slot bitmap : "); | ||
382 | |||
383 | len += bitmap_scnprintf(buf + len, sizeof(buf) - len, | ||
384 | priv->tx.tx_slot, MAX_TX_BUF_NUM); | ||
385 | |||
386 | len += snprintf(buf + len, sizeof(buf) - len, "\n"); | ||
387 | |||
388 | len += snprintf(buf + len, sizeof(buf) - len, | ||
389 | "Used slots : %d\n", | ||
390 | bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM)); | ||
391 | |||
392 | spin_unlock_bh(&priv->tx.tx_lock); | ||
393 | |||
394 | if (len > sizeof(buf)) | ||
395 | len = sizeof(buf); | ||
396 | |||
397 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
398 | } | ||
399 | |||
400 | static const struct file_operations fops_slot = { | ||
401 | .read = read_file_slot, | ||
402 | .open = ath9k_debugfs_open, | ||
403 | .owner = THIS_MODULE, | ||
404 | .llseek = default_llseek, | ||
405 | }; | ||
406 | |||
407 | static ssize_t read_file_queue(struct file *file, char __user *user_buf, | ||
408 | size_t count, loff_t *ppos) | ||
409 | { | ||
410 | struct ath9k_htc_priv *priv = file->private_data; | ||
411 | char buf[512]; | ||
412 | unsigned int len = 0; | ||
413 | |||
414 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
415 | "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue)); | ||
416 | |||
417 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
418 | "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue)); | ||
419 | |||
420 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
421 | "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue)); | ||
422 | |||
423 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
424 | "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue)); | ||
425 | |||
426 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
427 | "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue)); | ||
428 | |||
429 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
430 | "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue)); | ||
431 | |||
432 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
433 | "Failed queue", skb_queue_len(&priv->tx.tx_failed)); | ||
434 | |||
435 | spin_lock_bh(&priv->tx.tx_lock); | ||
436 | len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", | ||
437 | "Queued count", priv->tx.queued_cnt); | ||
438 | spin_unlock_bh(&priv->tx.tx_lock); | ||
439 | |||
440 | if (len > sizeof(buf)) | ||
441 | len = sizeof(buf); | ||
442 | |||
443 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
444 | |||
445 | } | ||
446 | |||
447 | static const struct file_operations fops_queue = { | ||
448 | .read = read_file_queue, | ||
449 | .open = ath9k_debugfs_open, | ||
450 | .owner = THIS_MODULE, | ||
451 | .llseek = default_llseek, | ||
452 | }; | ||
453 | |||
454 | static ssize_t read_file_debug(struct file *file, char __user *user_buf, | ||
455 | size_t count, loff_t *ppos) | ||
456 | { | ||
457 | struct ath9k_htc_priv *priv = file->private_data; | ||
458 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
459 | char buf[32]; | ||
460 | unsigned int len; | ||
461 | |||
462 | len = sprintf(buf, "0x%08x\n", common->debug_mask); | ||
463 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
464 | } | ||
465 | |||
466 | static ssize_t write_file_debug(struct file *file, const char __user *user_buf, | ||
467 | size_t count, loff_t *ppos) | ||
468 | { | ||
469 | struct ath9k_htc_priv *priv = file->private_data; | ||
470 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
471 | unsigned long mask; | ||
472 | char buf[32]; | ||
473 | ssize_t len; | ||
474 | |||
475 | len = min(count, sizeof(buf) - 1); | ||
476 | if (copy_from_user(buf, user_buf, len)) | ||
477 | return -EFAULT; | ||
478 | |||
479 | buf[len] = '\0'; | ||
480 | if (strict_strtoul(buf, 0, &mask)) | ||
481 | return -EINVAL; | ||
482 | |||
483 | common->debug_mask = mask; | ||
484 | return count; | ||
485 | } | ||
486 | |||
487 | static const struct file_operations fops_debug = { | ||
488 | .read = read_file_debug, | ||
489 | .write = write_file_debug, | ||
490 | .open = ath9k_debugfs_open, | ||
491 | .owner = THIS_MODULE, | ||
492 | .llseek = default_llseek, | ||
493 | }; | ||
494 | |||
495 | static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, | ||
496 | size_t count, loff_t *ppos) | ||
497 | { | ||
498 | struct ath9k_htc_priv *priv = file->private_data; | ||
499 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
500 | struct base_eep_header *pBase = NULL; | ||
501 | unsigned int len = 0, size = 1500; | ||
502 | ssize_t retval = 0; | ||
503 | char *buf; | ||
504 | |||
505 | /* | ||
506 | * This can be done since all the 3 EEPROM families have the | ||
507 | * same base header upto a certain point, and we are interested in | ||
508 | * the data only upto that point. | ||
509 | */ | ||
510 | |||
511 | if (AR_SREV_9271(priv->ah)) | ||
512 | pBase = (struct base_eep_header *) | ||
513 | &priv->ah->eeprom.map4k.baseEepHeader; | ||
514 | else if (priv->ah->hw_version.usbdev == AR9280_USB) | ||
515 | pBase = (struct base_eep_header *) | ||
516 | &priv->ah->eeprom.def.baseEepHeader; | ||
517 | else if (priv->ah->hw_version.usbdev == AR9287_USB) | ||
518 | pBase = (struct base_eep_header *) | ||
519 | &priv->ah->eeprom.map9287.baseEepHeader; | ||
520 | |||
521 | if (pBase == NULL) { | ||
522 | ath_err(common, "Unknown EEPROM type\n"); | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | buf = kzalloc(size, GFP_KERNEL); | ||
527 | if (buf == NULL) | ||
528 | return -ENOMEM; | ||
529 | |||
530 | len += snprintf(buf + len, size - len, | ||
531 | "%20s : %10d\n", "Major Version", | ||
532 | pBase->version >> 12); | ||
533 | len += snprintf(buf + len, size - len, | ||
534 | "%20s : %10d\n", "Minor Version", | ||
535 | pBase->version & 0xFFF); | ||
536 | len += snprintf(buf + len, size - len, | ||
537 | "%20s : %10d\n", "Checksum", | ||
538 | pBase->checksum); | ||
539 | len += snprintf(buf + len, size - len, | ||
540 | "%20s : %10d\n", "Length", | ||
541 | pBase->length); | ||
542 | len += snprintf(buf + len, size - len, | ||
543 | "%20s : %10d\n", "RegDomain1", | ||
544 | pBase->regDmn[0]); | ||
545 | len += snprintf(buf + len, size - len, | ||
546 | "%20s : %10d\n", "RegDomain2", | ||
547 | pBase->regDmn[1]); | ||
548 | len += snprintf(buf + len, size - len, | ||
549 | "%20s : %10d\n", | ||
550 | "TX Mask", pBase->txMask); | ||
551 | len += snprintf(buf + len, size - len, | ||
552 | "%20s : %10d\n", | ||
553 | "RX Mask", pBase->rxMask); | ||
554 | len += snprintf(buf + len, size - len, | ||
555 | "%20s : %10d\n", | ||
556 | "Allow 5GHz", | ||
557 | !!(pBase->opCapFlags & AR5416_OPFLAGS_11A)); | ||
558 | len += snprintf(buf + len, size - len, | ||
559 | "%20s : %10d\n", | ||
560 | "Allow 2GHz", | ||
561 | !!(pBase->opCapFlags & AR5416_OPFLAGS_11G)); | ||
562 | len += snprintf(buf + len, size - len, | ||
563 | "%20s : %10d\n", | ||
564 | "Disable 2GHz HT20", | ||
565 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT20)); | ||
566 | len += snprintf(buf + len, size - len, | ||
567 | "%20s : %10d\n", | ||
568 | "Disable 2GHz HT40", | ||
569 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT40)); | ||
570 | len += snprintf(buf + len, size - len, | ||
571 | "%20s : %10d\n", | ||
572 | "Disable 5Ghz HT20", | ||
573 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT20)); | ||
574 | len += snprintf(buf + len, size - len, | ||
575 | "%20s : %10d\n", | ||
576 | "Disable 5Ghz HT40", | ||
577 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT40)); | ||
578 | len += snprintf(buf + len, size - len, | ||
579 | "%20s : %10d\n", | ||
580 | "Big Endian", | ||
581 | !!(pBase->eepMisc & 0x01)); | ||
582 | len += snprintf(buf + len, size - len, | ||
583 | "%20s : %10d\n", | ||
584 | "Cal Bin Major Ver", | ||
585 | (pBase->binBuildNumber >> 24) & 0xFF); | ||
586 | len += snprintf(buf + len, size - len, | ||
587 | "%20s : %10d\n", | ||
588 | "Cal Bin Minor Ver", | ||
589 | (pBase->binBuildNumber >> 16) & 0xFF); | ||
590 | len += snprintf(buf + len, size - len, | ||
591 | "%20s : %10d\n", | ||
592 | "Cal Bin Build", | ||
593 | (pBase->binBuildNumber >> 8) & 0xFF); | ||
594 | |||
595 | /* | ||
596 | * UB91 specific data. | ||
597 | */ | ||
598 | if (AR_SREV_9271(priv->ah)) { | ||
599 | struct base_eep_header_4k *pBase4k = | ||
600 | &priv->ah->eeprom.map4k.baseEepHeader; | ||
601 | |||
602 | len += snprintf(buf + len, size - len, | ||
603 | "%20s : %10d\n", | ||
604 | "TX Gain type", | ||
605 | pBase4k->txGainType); | ||
606 | } | ||
607 | |||
608 | /* | ||
609 | * UB95 specific data. | ||
610 | */ | ||
611 | if (priv->ah->hw_version.usbdev == AR9287_USB) { | ||
612 | struct base_eep_ar9287_header *pBase9287 = | ||
613 | &priv->ah->eeprom.map9287.baseEepHeader; | ||
614 | |||
615 | len += snprintf(buf + len, size - len, | ||
616 | "%20s : %10ddB\n", | ||
617 | "Power Table Offset", | ||
618 | pBase9287->pwrTableOffset); | ||
619 | |||
620 | len += snprintf(buf + len, size - len, | ||
621 | "%20s : %10d\n", | ||
622 | "OpenLoop Power Ctrl", | ||
623 | pBase9287->openLoopPwrCntl); | ||
624 | } | ||
625 | |||
626 | len += snprintf(buf + len, size - len, | ||
627 | "%20s : %02X:%02X:%02X:%02X:%02X:%02X\n", | ||
628 | "MacAddress", | ||
629 | pBase->macAddr[0], pBase->macAddr[1], pBase->macAddr[2], | ||
630 | pBase->macAddr[3], pBase->macAddr[4], pBase->macAddr[5]); | ||
631 | if (len > size) | ||
632 | len = size; | ||
633 | |||
634 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
635 | kfree(buf); | ||
636 | |||
637 | return retval; | ||
638 | } | ||
639 | |||
640 | static const struct file_operations fops_base_eeprom = { | ||
641 | .read = read_file_base_eeprom, | ||
642 | .open = ath9k_debugfs_open, | ||
643 | .owner = THIS_MODULE, | ||
644 | .llseek = default_llseek, | ||
645 | }; | ||
646 | |||
647 | static ssize_t read_4k_modal_eeprom(struct file *file, | ||
648 | char __user *user_buf, | ||
649 | size_t count, loff_t *ppos) | ||
650 | { | ||
651 | #define PR_EEP(_s, _val) \ | ||
652 | do { \ | ||
653 | len += snprintf(buf + len, size - len, "%20s : %10d\n", \ | ||
654 | _s, (_val)); \ | ||
655 | } while (0) | ||
656 | |||
657 | struct ath9k_htc_priv *priv = file->private_data; | ||
658 | struct modal_eep_4k_header *pModal = &priv->ah->eeprom.map4k.modalHeader; | ||
659 | unsigned int len = 0, size = 2048; | ||
660 | ssize_t retval = 0; | ||
661 | char *buf; | ||
662 | |||
663 | buf = kzalloc(size, GFP_KERNEL); | ||
664 | if (buf == NULL) | ||
665 | return -ENOMEM; | ||
666 | |||
667 | PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]); | ||
668 | PR_EEP("Ant. Common Control", pModal->antCtrlCommon); | ||
669 | PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]); | ||
670 | PR_EEP("Switch Settle", pModal->switchSettling); | ||
671 | PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]); | ||
672 | PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]); | ||
673 | PR_EEP("ADC Desired size", pModal->adcDesiredSize); | ||
674 | PR_EEP("PGA Desired size", pModal->pgaDesiredSize); | ||
675 | PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]); | ||
676 | PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff); | ||
677 | PR_EEP("txEndToRxOn", pModal->txEndToRxOn); | ||
678 | PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn); | ||
679 | PR_EEP("CCA Threshold)", pModal->thresh62); | ||
680 | PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]); | ||
681 | PR_EEP("xpdGain", pModal->xpdGain); | ||
682 | PR_EEP("External PD", pModal->xpd); | ||
683 | PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]); | ||
684 | PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]); | ||
685 | PR_EEP("pdGainOverlap", pModal->pdGainOverlap); | ||
686 | PR_EEP("O/D Bias Version", pModal->version); | ||
687 | PR_EEP("CCK OutputBias", pModal->ob_0); | ||
688 | PR_EEP("BPSK OutputBias", pModal->ob_1); | ||
689 | PR_EEP("QPSK OutputBias", pModal->ob_2); | ||
690 | PR_EEP("16QAM OutputBias", pModal->ob_3); | ||
691 | PR_EEP("64QAM OutputBias", pModal->ob_4); | ||
692 | PR_EEP("CCK Driver1_Bias", pModal->db1_0); | ||
693 | PR_EEP("BPSK Driver1_Bias", pModal->db1_1); | ||
694 | PR_EEP("QPSK Driver1_Bias", pModal->db1_2); | ||
695 | PR_EEP("16QAM Driver1_Bias", pModal->db1_3); | ||
696 | PR_EEP("64QAM Driver1_Bias", pModal->db1_4); | ||
697 | PR_EEP("CCK Driver2_Bias", pModal->db2_0); | ||
698 | PR_EEP("BPSK Driver2_Bias", pModal->db2_1); | ||
699 | PR_EEP("QPSK Driver2_Bias", pModal->db2_2); | ||
700 | PR_EEP("16QAM Driver2_Bias", pModal->db2_3); | ||
701 | PR_EEP("64QAM Driver2_Bias", pModal->db2_4); | ||
702 | PR_EEP("xPA Bias Level", pModal->xpaBiasLvl); | ||
703 | PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart); | ||
704 | PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn); | ||
705 | PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc); | ||
706 | PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]); | ||
707 | PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]); | ||
708 | PR_EEP("HT40 Switch Settle", pModal->swSettleHt40); | ||
709 | PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]); | ||
710 | PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]); | ||
711 | PR_EEP("Ant. Diversity ctl1", pModal->antdiv_ctl1); | ||
712 | PR_EEP("Ant. Diversity ctl2", pModal->antdiv_ctl2); | ||
713 | PR_EEP("TX Diversity", pModal->tx_diversity); | ||
714 | |||
715 | if (len > size) | ||
716 | len = size; | ||
717 | |||
718 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
719 | kfree(buf); | ||
720 | |||
721 | return retval; | ||
722 | |||
723 | #undef PR_EEP | ||
724 | } | ||
725 | |||
726 | static ssize_t read_def_modal_eeprom(struct file *file, | ||
727 | char __user *user_buf, | ||
728 | size_t count, loff_t *ppos) | ||
729 | { | ||
730 | #define PR_EEP(_s, _val) \ | ||
731 | do { \ | ||
732 | if (pBase->opCapFlags & AR5416_OPFLAGS_11G) { \ | ||
733 | pModal = &priv->ah->eeprom.def.modalHeader[1]; \ | ||
734 | len += snprintf(buf + len, size - len, "%20s : %8d%7s", \ | ||
735 | _s, (_val), "|"); \ | ||
736 | } \ | ||
737 | if (pBase->opCapFlags & AR5416_OPFLAGS_11A) { \ | ||
738 | pModal = &priv->ah->eeprom.def.modalHeader[0]; \ | ||
739 | len += snprintf(buf + len, size - len, "%9d\n", \ | ||
740 | (_val)); \ | ||
741 | } \ | ||
742 | } while (0) | ||
743 | |||
744 | struct ath9k_htc_priv *priv = file->private_data; | ||
745 | struct base_eep_header *pBase = &priv->ah->eeprom.def.baseEepHeader; | ||
746 | struct modal_eep_header *pModal = NULL; | ||
747 | unsigned int len = 0, size = 3500; | ||
748 | ssize_t retval = 0; | ||
749 | char *buf; | ||
750 | |||
751 | buf = kzalloc(size, GFP_KERNEL); | ||
752 | if (buf == NULL) | ||
753 | return -ENOMEM; | ||
754 | |||
755 | len += snprintf(buf + len, size - len, | ||
756 | "%31s %15s\n", "2G", "5G"); | ||
757 | len += snprintf(buf + len, size - len, | ||
758 | "%32s %16s\n", "====", "====\n"); | ||
759 | |||
760 | PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]); | ||
761 | PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]); | ||
762 | PR_EEP("Chain2 Ant. Control", pModal->antCtrlChain[2]); | ||
763 | PR_EEP("Ant. Common Control", pModal->antCtrlCommon); | ||
764 | PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]); | ||
765 | PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]); | ||
766 | PR_EEP("Chain2 Ant. Gain", pModal->antennaGainCh[2]); | ||
767 | PR_EEP("Switch Settle", pModal->switchSettling); | ||
768 | PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]); | ||
769 | PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]); | ||
770 | PR_EEP("Chain2 TxRxAtten", pModal->txRxAttenCh[2]); | ||
771 | PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]); | ||
772 | PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]); | ||
773 | PR_EEP("Chain2 RxTxMargin", pModal->rxTxMarginCh[2]); | ||
774 | PR_EEP("ADC Desired size", pModal->adcDesiredSize); | ||
775 | PR_EEP("PGA Desired size", pModal->pgaDesiredSize); | ||
776 | PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]); | ||
777 | PR_EEP("Chain1 xlna Gain", pModal->xlnaGainCh[1]); | ||
778 | PR_EEP("Chain2 xlna Gain", pModal->xlnaGainCh[2]); | ||
779 | PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff); | ||
780 | PR_EEP("txEndToRxOn", pModal->txEndToRxOn); | ||
781 | PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn); | ||
782 | PR_EEP("CCA Threshold)", pModal->thresh62); | ||
783 | PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]); | ||
784 | PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]); | ||
785 | PR_EEP("Chain2 NF Threshold", pModal->noiseFloorThreshCh[2]); | ||
786 | PR_EEP("xpdGain", pModal->xpdGain); | ||
787 | PR_EEP("External PD", pModal->xpd); | ||
788 | PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]); | ||
789 | PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]); | ||
790 | PR_EEP("Chain2 I Coefficient", pModal->iqCalICh[2]); | ||
791 | PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]); | ||
792 | PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]); | ||
793 | PR_EEP("Chain2 Q Coefficient", pModal->iqCalQCh[2]); | ||
794 | PR_EEP("pdGainOverlap", pModal->pdGainOverlap); | ||
795 | PR_EEP("Chain0 OutputBias", pModal->ob); | ||
796 | PR_EEP("Chain0 DriverBias", pModal->db); | ||
797 | PR_EEP("xPA Bias Level", pModal->xpaBiasLvl); | ||
798 | PR_EEP("2chain pwr decrease", pModal->pwrDecreaseFor2Chain); | ||
799 | PR_EEP("3chain pwr decrease", pModal->pwrDecreaseFor3Chain); | ||
800 | PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart); | ||
801 | PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn); | ||
802 | PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc); | ||
803 | PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]); | ||
804 | PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]); | ||
805 | PR_EEP("Chain2 bswAtten", pModal->bswAtten[2]); | ||
806 | PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]); | ||
807 | PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]); | ||
808 | PR_EEP("Chain2 bswMargin", pModal->bswMargin[2]); | ||
809 | PR_EEP("HT40 Switch Settle", pModal->swSettleHt40); | ||
810 | PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]); | ||
811 | PR_EEP("Chain1 xatten2Db", pModal->xatten2Db[1]); | ||
812 | PR_EEP("Chain2 xatten2Db", pModal->xatten2Db[2]); | ||
813 | PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]); | ||
814 | PR_EEP("Chain1 xatten2Margin", pModal->xatten2Margin[1]); | ||
815 | PR_EEP("Chain2 xatten2Margin", pModal->xatten2Margin[2]); | ||
816 | PR_EEP("Chain1 OutputBias", pModal->ob_ch1); | ||
817 | PR_EEP("Chain1 DriverBias", pModal->db_ch1); | ||
818 | PR_EEP("LNA Control", pModal->lna_ctl); | ||
819 | PR_EEP("XPA Bias Freq0", pModal->xpaBiasLvlFreq[0]); | ||
820 | PR_EEP("XPA Bias Freq1", pModal->xpaBiasLvlFreq[1]); | ||
821 | PR_EEP("XPA Bias Freq2", pModal->xpaBiasLvlFreq[2]); | ||
822 | |||
823 | if (len > size) | ||
824 | len = size; | ||
825 | |||
826 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
827 | kfree(buf); | ||
828 | |||
829 | return retval; | ||
830 | |||
831 | #undef PR_EEP | ||
832 | } | ||
833 | |||
834 | static ssize_t read_9287_modal_eeprom(struct file *file, | ||
835 | char __user *user_buf, | ||
836 | size_t count, loff_t *ppos) | ||
837 | { | ||
838 | #define PR_EEP(_s, _val) \ | ||
839 | do { \ | ||
840 | len += snprintf(buf + len, size - len, "%20s : %10d\n", \ | ||
841 | _s, (_val)); \ | ||
842 | } while (0) | ||
843 | |||
844 | struct ath9k_htc_priv *priv = file->private_data; | ||
845 | struct modal_eep_ar9287_header *pModal = &priv->ah->eeprom.map9287.modalHeader; | ||
846 | unsigned int len = 0, size = 3000; | ||
847 | ssize_t retval = 0; | ||
848 | char *buf; | ||
849 | |||
850 | buf = kzalloc(size, GFP_KERNEL); | ||
851 | if (buf == NULL) | ||
852 | return -ENOMEM; | ||
853 | |||
854 | PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]); | ||
855 | PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]); | ||
856 | PR_EEP("Ant. Common Control", pModal->antCtrlCommon); | ||
857 | PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]); | ||
858 | PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]); | ||
859 | PR_EEP("Switch Settle", pModal->switchSettling); | ||
860 | PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]); | ||
861 | PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]); | ||
862 | PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]); | ||
863 | PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]); | ||
864 | PR_EEP("ADC Desired size", pModal->adcDesiredSize); | ||
865 | PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff); | ||
866 | PR_EEP("txEndToRxOn", pModal->txEndToRxOn); | ||
867 | PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn); | ||
868 | PR_EEP("CCA Threshold)", pModal->thresh62); | ||
869 | PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]); | ||
870 | PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]); | ||
871 | PR_EEP("xpdGain", pModal->xpdGain); | ||
872 | PR_EEP("External PD", pModal->xpd); | ||
873 | PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]); | ||
874 | PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]); | ||
875 | PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]); | ||
876 | PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]); | ||
877 | PR_EEP("pdGainOverlap", pModal->pdGainOverlap); | ||
878 | PR_EEP("xPA Bias Level", pModal->xpaBiasLvl); | ||
879 | PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart); | ||
880 | PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn); | ||
881 | PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc); | ||
882 | PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]); | ||
883 | PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]); | ||
884 | PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]); | ||
885 | PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]); | ||
886 | PR_EEP("HT40 Switch Settle", pModal->swSettleHt40); | ||
887 | PR_EEP("AR92x7 Version", pModal->version); | ||
888 | PR_EEP("DriverBias1", pModal->db1); | ||
889 | PR_EEP("DriverBias2", pModal->db1); | ||
890 | PR_EEP("CCK OutputBias", pModal->ob_cck); | ||
891 | PR_EEP("PSK OutputBias", pModal->ob_psk); | ||
892 | PR_EEP("QAM OutputBias", pModal->ob_qam); | ||
893 | PR_EEP("PAL_OFF OutputBias", pModal->ob_pal_off); | ||
894 | |||
895 | if (len > size) | ||
896 | len = size; | ||
897 | |||
898 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
899 | kfree(buf); | ||
900 | |||
901 | return retval; | ||
902 | |||
903 | #undef PR_EEP | ||
904 | } | ||
905 | |||
906 | static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf, | ||
907 | size_t count, loff_t *ppos) | ||
908 | { | ||
909 | struct ath9k_htc_priv *priv = file->private_data; | ||
910 | |||
911 | if (AR_SREV_9271(priv->ah)) | ||
912 | return read_4k_modal_eeprom(file, user_buf, count, ppos); | ||
913 | else if (priv->ah->hw_version.usbdev == AR9280_USB) | ||
914 | return read_def_modal_eeprom(file, user_buf, count, ppos); | ||
915 | else if (priv->ah->hw_version.usbdev == AR9287_USB) | ||
916 | return read_9287_modal_eeprom(file, user_buf, count, ppos); | ||
917 | |||
918 | return 0; | ||
919 | } | ||
920 | |||
921 | static const struct file_operations fops_modal_eeprom = { | ||
922 | .read = read_file_modal_eeprom, | ||
923 | .open = ath9k_debugfs_open, | ||
924 | .owner = THIS_MODULE, | ||
925 | .llseek = default_llseek, | ||
926 | }; | ||
927 | |||
928 | int ath9k_htc_init_debug(struct ath_hw *ah) | ||
929 | { | ||
930 | struct ath_common *common = ath9k_hw_common(ah); | ||
931 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
932 | |||
933 | priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME, | ||
934 | priv->hw->wiphy->debugfsdir); | ||
935 | if (!priv->debug.debugfs_phy) | ||
936 | return -ENOMEM; | ||
937 | |||
938 | debugfs_create_file("tgt_int_stats", S_IRUSR, priv->debug.debugfs_phy, | ||
939 | priv, &fops_tgt_int_stats); | ||
940 | debugfs_create_file("tgt_tx_stats", S_IRUSR, priv->debug.debugfs_phy, | ||
941 | priv, &fops_tgt_tx_stats); | ||
942 | debugfs_create_file("tgt_rx_stats", S_IRUSR, priv->debug.debugfs_phy, | ||
943 | priv, &fops_tgt_rx_stats); | ||
944 | debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy, | ||
945 | priv, &fops_xmit); | ||
946 | debugfs_create_file("recv", S_IRUSR, priv->debug.debugfs_phy, | ||
947 | priv, &fops_recv); | ||
948 | debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy, | ||
949 | priv, &fops_slot); | ||
950 | debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy, | ||
951 | priv, &fops_queue); | ||
952 | debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy, | ||
953 | priv, &fops_debug); | ||
954 | debugfs_create_file("base_eeprom", S_IRUSR, priv->debug.debugfs_phy, | ||
955 | priv, &fops_base_eeprom); | ||
956 | debugfs_create_file("modal_eeprom", S_IRUSR, priv->debug.debugfs_phy, | ||
957 | priv, &fops_modal_eeprom); | ||
958 | |||
959 | return 0; | ||
960 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 7e630a81b45..af57fe5aab9 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | |||
@@ -65,17 +65,19 @@ static void ath_btcoex_period_work(struct work_struct *work) | |||
65 | u32 timer_period; | 65 | u32 timer_period; |
66 | bool is_btscan; | 66 | bool is_btscan; |
67 | int ret; | 67 | int ret; |
68 | u8 cmd_rsp, aggr; | ||
69 | 68 | ||
70 | ath_detect_bt_priority(priv); | 69 | ath_detect_bt_priority(priv); |
71 | 70 | ||
72 | is_btscan = !!(priv->op_flags & OP_BT_SCAN); | 71 | is_btscan = !!(priv->op_flags & OP_BT_SCAN); |
73 | 72 | ||
74 | aggr = priv->op_flags & OP_BT_PRIORITY_DETECTED; | 73 | ret = ath9k_htc_update_cap_target(priv, |
75 | 74 | !!(priv->op_flags & OP_BT_PRIORITY_DETECTED)); | |
76 | WMI_CMD_BUF(WMI_AGGR_LIMIT_CMD, &aggr); | 75 | if (ret) { |
76 | ath_err(common, "Unable to set BTCOEX parameters\n"); | ||
77 | return; | ||
78 | } | ||
77 | 79 | ||
78 | ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL : | 80 | ath9k_hw_btcoex_bt_stomp(priv->ah, is_btscan ? ATH_BTCOEX_STOMP_ALL : |
79 | btcoex->bt_stomp_type); | 81 | btcoex->bt_stomp_type); |
80 | 82 | ||
81 | timer_period = is_btscan ? btcoex->btscan_no_stomp : | 83 | timer_period = is_btscan ? btcoex->btscan_no_stomp : |
@@ -103,9 +105,9 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work) | |||
103 | "time slice work for bt and wlan\n"); | 105 | "time slice work for bt and wlan\n"); |
104 | 106 | ||
105 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) | 107 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) |
106 | ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE); | 108 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); |
107 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | 109 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) |
108 | ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW); | 110 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); |
109 | } | 111 | } |
110 | 112 | ||
111 | void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv) | 113 | void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv) |
@@ -152,140 +154,41 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv) | |||
152 | /* LED */ | 154 | /* LED */ |
153 | /*******/ | 155 | /*******/ |
154 | 156 | ||
155 | static void ath9k_led_blink_work(struct work_struct *work) | 157 | #ifdef CONFIG_MAC80211_LEDS |
158 | void ath9k_led_work(struct work_struct *work) | ||
156 | { | 159 | { |
157 | struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv, | 160 | struct ath9k_htc_priv *priv = container_of(work, |
158 | ath9k_led_blink_work.work); | 161 | struct ath9k_htc_priv, |
162 | led_work); | ||
159 | 163 | ||
160 | if (!(priv->op_flags & OP_LED_ASSOCIATED)) | 164 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, |
161 | return; | 165 | (priv->brightness == LED_OFF)); |
162 | |||
163 | if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) || | ||
164 | (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) | ||
165 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0); | ||
166 | else | ||
167 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, | ||
168 | (priv->op_flags & OP_LED_ON) ? 1 : 0); | ||
169 | |||
170 | ieee80211_queue_delayed_work(priv->hw, | ||
171 | &priv->ath9k_led_blink_work, | ||
172 | (priv->op_flags & OP_LED_ON) ? | ||
173 | msecs_to_jiffies(priv->led_off_duration) : | ||
174 | msecs_to_jiffies(priv->led_on_duration)); | ||
175 | |||
176 | priv->led_on_duration = priv->led_on_cnt ? | ||
177 | max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) : | ||
178 | ATH_LED_ON_DURATION_IDLE; | ||
179 | priv->led_off_duration = priv->led_off_cnt ? | ||
180 | max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) : | ||
181 | ATH_LED_OFF_DURATION_IDLE; | ||
182 | priv->led_on_cnt = priv->led_off_cnt = 0; | ||
183 | |||
184 | if (priv->op_flags & OP_LED_ON) | ||
185 | priv->op_flags &= ~OP_LED_ON; | ||
186 | else | ||
187 | priv->op_flags |= OP_LED_ON; | ||
188 | } | ||
189 | |||
190 | static void ath9k_led_brightness_work(struct work_struct *work) | ||
191 | { | ||
192 | struct ath_led *led = container_of(work, struct ath_led, | ||
193 | brightness_work.work); | ||
194 | struct ath9k_htc_priv *priv = led->priv; | ||
195 | |||
196 | switch (led->brightness) { | ||
197 | case LED_OFF: | ||
198 | if (led->led_type == ATH_LED_ASSOC || | ||
199 | led->led_type == ATH_LED_RADIO) { | ||
200 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, | ||
201 | (led->led_type == ATH_LED_RADIO)); | ||
202 | priv->op_flags &= ~OP_LED_ASSOCIATED; | ||
203 | if (led->led_type == ATH_LED_RADIO) | ||
204 | priv->op_flags &= ~OP_LED_ON; | ||
205 | } else { | ||
206 | priv->led_off_cnt++; | ||
207 | } | ||
208 | break; | ||
209 | case LED_FULL: | ||
210 | if (led->led_type == ATH_LED_ASSOC) { | ||
211 | priv->op_flags |= OP_LED_ASSOCIATED; | ||
212 | ieee80211_queue_delayed_work(priv->hw, | ||
213 | &priv->ath9k_led_blink_work, 0); | ||
214 | } else if (led->led_type == ATH_LED_RADIO) { | ||
215 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0); | ||
216 | priv->op_flags |= OP_LED_ON; | ||
217 | } else { | ||
218 | priv->led_on_cnt++; | ||
219 | } | ||
220 | break; | ||
221 | default: | ||
222 | break; | ||
223 | } | ||
224 | } | 166 | } |
225 | 167 | ||
226 | static void ath9k_led_brightness(struct led_classdev *led_cdev, | 168 | static void ath9k_led_brightness(struct led_classdev *led_cdev, |
227 | enum led_brightness brightness) | 169 | enum led_brightness brightness) |
228 | { | 170 | { |
229 | struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); | 171 | struct ath9k_htc_priv *priv = container_of(led_cdev, |
230 | struct ath9k_htc_priv *priv = led->priv; | 172 | struct ath9k_htc_priv, |
231 | 173 | led_cdev); | |
232 | led->brightness = brightness; | ||
233 | if (!(priv->op_flags & OP_LED_DEINIT)) | ||
234 | ieee80211_queue_delayed_work(priv->hw, | ||
235 | &led->brightness_work, 0); | ||
236 | } | ||
237 | |||
238 | void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv) | ||
239 | { | ||
240 | cancel_delayed_work_sync(&priv->radio_led.brightness_work); | ||
241 | cancel_delayed_work_sync(&priv->assoc_led.brightness_work); | ||
242 | cancel_delayed_work_sync(&priv->tx_led.brightness_work); | ||
243 | cancel_delayed_work_sync(&priv->rx_led.brightness_work); | ||
244 | } | ||
245 | |||
246 | static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led, | ||
247 | char *trigger) | ||
248 | { | ||
249 | int ret; | ||
250 | |||
251 | led->priv = priv; | ||
252 | led->led_cdev.name = led->name; | ||
253 | led->led_cdev.default_trigger = trigger; | ||
254 | led->led_cdev.brightness_set = ath9k_led_brightness; | ||
255 | 174 | ||
256 | ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev); | 175 | /* Not locked, but it's just a tiny green light..*/ |
257 | if (ret) | 176 | priv->brightness = brightness; |
258 | ath_err(ath9k_hw_common(priv->ah), | 177 | ieee80211_queue_work(priv->hw, &priv->led_work); |
259 | "Failed to register led:%s", led->name); | ||
260 | else | ||
261 | led->registered = 1; | ||
262 | |||
263 | INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work); | ||
264 | |||
265 | return ret; | ||
266 | } | ||
267 | |||
268 | static void ath9k_unregister_led(struct ath_led *led) | ||
269 | { | ||
270 | if (led->registered) { | ||
271 | led_classdev_unregister(&led->led_cdev); | ||
272 | led->registered = 0; | ||
273 | } | ||
274 | } | 178 | } |
275 | 179 | ||
276 | void ath9k_deinit_leds(struct ath9k_htc_priv *priv) | 180 | void ath9k_deinit_leds(struct ath9k_htc_priv *priv) |
277 | { | 181 | { |
278 | priv->op_flags |= OP_LED_DEINIT; | 182 | if (!priv->led_registered) |
279 | ath9k_unregister_led(&priv->assoc_led); | 183 | return; |
280 | priv->op_flags &= ~OP_LED_ASSOCIATED; | 184 | |
281 | ath9k_unregister_led(&priv->tx_led); | 185 | ath9k_led_brightness(&priv->led_cdev, LED_OFF); |
282 | ath9k_unregister_led(&priv->rx_led); | 186 | led_classdev_unregister(&priv->led_cdev); |
283 | ath9k_unregister_led(&priv->radio_led); | 187 | cancel_work_sync(&priv->led_work); |
284 | } | 188 | } |
285 | 189 | ||
286 | void ath9k_init_leds(struct ath9k_htc_priv *priv) | 190 | void ath9k_init_leds(struct ath9k_htc_priv *priv) |
287 | { | 191 | { |
288 | char *trigger; | ||
289 | int ret; | 192 | int ret; |
290 | 193 | ||
291 | if (AR_SREV_9287(priv->ah)) | 194 | if (AR_SREV_9287(priv->ah)) |
@@ -303,48 +206,21 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv) | |||
303 | /* LED off, active low */ | 206 | /* LED off, active low */ |
304 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1); | 207 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1); |
305 | 208 | ||
306 | INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work); | 209 | snprintf(priv->led_name, sizeof(priv->led_name), |
307 | 210 | "ath9k_htc-%s", wiphy_name(priv->hw->wiphy)); | |
308 | trigger = ieee80211_get_radio_led_name(priv->hw); | 211 | priv->led_cdev.name = priv->led_name; |
309 | snprintf(priv->radio_led.name, sizeof(priv->radio_led.name), | 212 | priv->led_cdev.brightness_set = ath9k_led_brightness; |
310 | "ath9k-%s::radio", wiphy_name(priv->hw->wiphy)); | ||
311 | ret = ath9k_register_led(priv, &priv->radio_led, trigger); | ||
312 | priv->radio_led.led_type = ATH_LED_RADIO; | ||
313 | if (ret) | ||
314 | goto fail; | ||
315 | |||
316 | trigger = ieee80211_get_assoc_led_name(priv->hw); | ||
317 | snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name), | ||
318 | "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy)); | ||
319 | ret = ath9k_register_led(priv, &priv->assoc_led, trigger); | ||
320 | priv->assoc_led.led_type = ATH_LED_ASSOC; | ||
321 | if (ret) | ||
322 | goto fail; | ||
323 | |||
324 | trigger = ieee80211_get_tx_led_name(priv->hw); | ||
325 | snprintf(priv->tx_led.name, sizeof(priv->tx_led.name), | ||
326 | "ath9k-%s::tx", wiphy_name(priv->hw->wiphy)); | ||
327 | ret = ath9k_register_led(priv, &priv->tx_led, trigger); | ||
328 | priv->tx_led.led_type = ATH_LED_TX; | ||
329 | if (ret) | ||
330 | goto fail; | ||
331 | |||
332 | trigger = ieee80211_get_rx_led_name(priv->hw); | ||
333 | snprintf(priv->rx_led.name, sizeof(priv->rx_led.name), | ||
334 | "ath9k-%s::rx", wiphy_name(priv->hw->wiphy)); | ||
335 | ret = ath9k_register_led(priv, &priv->rx_led, trigger); | ||
336 | priv->rx_led.led_type = ATH_LED_RX; | ||
337 | if (ret) | ||
338 | goto fail; | ||
339 | |||
340 | priv->op_flags &= ~OP_LED_DEINIT; | ||
341 | 213 | ||
342 | return; | 214 | ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &priv->led_cdev); |
215 | if (ret < 0) | ||
216 | return; | ||
217 | |||
218 | INIT_WORK(&priv->led_work, ath9k_led_work); | ||
219 | priv->led_registered = true; | ||
343 | 220 | ||
344 | fail: | 221 | return; |
345 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | ||
346 | ath9k_deinit_leds(priv); | ||
347 | } | 222 | } |
223 | #endif | ||
348 | 224 | ||
349 | /*******************/ | 225 | /*******************/ |
350 | /* Rfkill */ | 226 | /* Rfkill */ |
@@ -398,9 +274,9 @@ void ath9k_htc_radio_enable(struct ieee80211_hw *hw) | |||
398 | 274 | ||
399 | /* Start TX */ | 275 | /* Start TX */ |
400 | htc_start(priv->htc); | 276 | htc_start(priv->htc); |
401 | spin_lock_bh(&priv->tx_lock); | 277 | spin_lock_bh(&priv->tx.tx_lock); |
402 | priv->tx_queues_stop = false; | 278 | priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; |
403 | spin_unlock_bh(&priv->tx_lock); | 279 | spin_unlock_bh(&priv->tx.tx_lock); |
404 | ieee80211_wake_queues(hw); | 280 | ieee80211_wake_queues(hw); |
405 | 281 | ||
406 | WMI_CMD(WMI_ENABLE_INTR_CMDID); | 282 | WMI_CMD(WMI_ENABLE_INTR_CMDID); |
@@ -429,13 +305,15 @@ void ath9k_htc_radio_disable(struct ieee80211_hw *hw) | |||
429 | 305 | ||
430 | /* Stop TX */ | 306 | /* Stop TX */ |
431 | ieee80211_stop_queues(hw); | 307 | ieee80211_stop_queues(hw); |
432 | htc_stop(priv->htc); | 308 | ath9k_htc_tx_drain(priv); |
433 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 309 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
434 | skb_queue_purge(&priv->tx_queue); | ||
435 | 310 | ||
436 | /* Stop RX */ | 311 | /* Stop RX */ |
437 | WMI_CMD(WMI_STOP_RECV_CMDID); | 312 | WMI_CMD(WMI_STOP_RECV_CMDID); |
438 | 313 | ||
314 | /* Clear the WMI event queue */ | ||
315 | ath9k_wmi_event_drain(priv); | ||
316 | |||
439 | /* | 317 | /* |
440 | * The MIB counters have to be disabled here, | 318 | * The MIB counters have to be disabled here, |
441 | * since the target doesn't do it. | 319 | * since the target doesn't do it. |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index fc67c937e17..bfdc8a88718 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -117,6 +117,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = { | |||
117 | RATE(540, 0x0c, 0), | 117 | RATE(540, 0x0c, 0), |
118 | }; | 118 | }; |
119 | 119 | ||
120 | #ifdef CONFIG_MAC80211_LEDS | ||
121 | static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = { | ||
122 | { .throughput = 0 * 1024, .blink_time = 334 }, | ||
123 | { .throughput = 1 * 1024, .blink_time = 260 }, | ||
124 | { .throughput = 5 * 1024, .blink_time = 220 }, | ||
125 | { .throughput = 10 * 1024, .blink_time = 190 }, | ||
126 | { .throughput = 20 * 1024, .blink_time = 170 }, | ||
127 | { .throughput = 50 * 1024, .blink_time = 150 }, | ||
128 | { .throughput = 70 * 1024, .blink_time = 130 }, | ||
129 | { .throughput = 100 * 1024, .blink_time = 110 }, | ||
130 | { .throughput = 200 * 1024, .blink_time = 80 }, | ||
131 | { .throughput = 300 * 1024, .blink_time = 50 }, | ||
132 | }; | ||
133 | #endif | ||
134 | |||
120 | static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv) | 135 | static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv) |
121 | { | 136 | { |
122 | int time_left; | 137 | int time_left; |
@@ -140,7 +155,6 @@ static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv) | |||
140 | 155 | ||
141 | static void ath9k_deinit_priv(struct ath9k_htc_priv *priv) | 156 | static void ath9k_deinit_priv(struct ath9k_htc_priv *priv) |
142 | { | 157 | { |
143 | ath9k_htc_exit_debug(priv->ah); | ||
144 | ath9k_hw_deinit(priv->ah); | 158 | ath9k_hw_deinit(priv->ah); |
145 | kfree(priv->ah); | 159 | kfree(priv->ah); |
146 | priv->ah = NULL; | 160 | priv->ah = NULL; |
@@ -244,7 +258,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid, | |||
244 | */ | 258 | */ |
245 | 259 | ||
246 | if (IS_AR7010_DEVICE(drv_info)) | 260 | if (IS_AR7010_DEVICE(drv_info)) |
247 | priv->htc->credits = 45; | 261 | priv->htc->credits = 48; |
248 | else | 262 | else |
249 | priv->htc->credits = 33; | 263 | priv->htc->credits = 33; |
250 | 264 | ||
@@ -430,13 +444,16 @@ static void ath9k_regwrite_flush(void *hw_priv) | |||
430 | mutex_unlock(&priv->wmi->multi_write_mutex); | 444 | mutex_unlock(&priv->wmi->multi_write_mutex); |
431 | } | 445 | } |
432 | 446 | ||
433 | static const struct ath_ops ath9k_common_ops = { | 447 | static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr) |
434 | .read = ath9k_regread, | 448 | { |
435 | .multi_read = ath9k_multi_regread, | 449 | u32 val; |
436 | .write = ath9k_regwrite, | 450 | |
437 | .enable_write_buffer = ath9k_enable_regwrite_buffer, | 451 | val = ath9k_regread(hw_priv, reg_offset); |
438 | .write_flush = ath9k_regwrite_flush, | 452 | val &= ~clr; |
439 | }; | 453 | val |= set; |
454 | ath9k_regwrite(hw_priv, val, reg_offset); | ||
455 | return val; | ||
456 | } | ||
440 | 457 | ||
441 | static void ath_usb_read_cachesize(struct ath_common *common, int *csz) | 458 | static void ath_usb_read_cachesize(struct ath_common *common, int *csz) |
442 | { | 459 | { |
@@ -561,13 +578,7 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv) | |||
561 | int i = 0; | 578 | int i = 0; |
562 | 579 | ||
563 | /* Get the hardware key cache size. */ | 580 | /* Get the hardware key cache size. */ |
564 | common->keymax = priv->ah->caps.keycache_size; | 581 | common->keymax = AR_KEYTABLE_SIZE; |
565 | if (common->keymax > ATH_KEYMAX) { | ||
566 | ath_dbg(common, ATH_DBG_ANY, | ||
567 | "Warning, using only %u entries in %u key cache\n", | ||
568 | ATH_KEYMAX, common->keymax); | ||
569 | common->keymax = ATH_KEYMAX; | ||
570 | } | ||
571 | 582 | ||
572 | if (priv->ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) | 583 | if (priv->ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) |
573 | common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; | 584 | common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; |
@@ -646,7 +657,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
646 | { | 657 | { |
647 | struct ath_hw *ah = NULL; | 658 | struct ath_hw *ah = NULL; |
648 | struct ath_common *common; | 659 | struct ath_common *common; |
649 | int ret = 0, csz = 0; | 660 | int i, ret = 0, csz = 0; |
650 | 661 | ||
651 | priv->op_flags |= OP_INVALID; | 662 | priv->op_flags |= OP_INVALID; |
652 | 663 | ||
@@ -658,30 +669,35 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
658 | ah->hw_version.subsysid = 0; /* FIXME */ | 669 | ah->hw_version.subsysid = 0; /* FIXME */ |
659 | ah->hw_version.usbdev = drv_info; | 670 | ah->hw_version.usbdev = drv_info; |
660 | ah->ah_flags |= AH_USE_EEPROM; | 671 | ah->ah_flags |= AH_USE_EEPROM; |
672 | ah->reg_ops.read = ath9k_regread; | ||
673 | ah->reg_ops.multi_read = ath9k_multi_regread; | ||
674 | ah->reg_ops.write = ath9k_regwrite; | ||
675 | ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer; | ||
676 | ah->reg_ops.write_flush = ath9k_regwrite_flush; | ||
677 | ah->reg_ops.rmw = ath9k_reg_rmw; | ||
661 | priv->ah = ah; | 678 | priv->ah = ah; |
662 | 679 | ||
663 | common = ath9k_hw_common(ah); | 680 | common = ath9k_hw_common(ah); |
664 | common->ops = &ath9k_common_ops; | 681 | common->ops = &ah->reg_ops; |
665 | common->bus_ops = &ath9k_usb_bus_ops; | 682 | common->bus_ops = &ath9k_usb_bus_ops; |
666 | common->ah = ah; | 683 | common->ah = ah; |
667 | common->hw = priv->hw; | 684 | common->hw = priv->hw; |
668 | common->priv = priv; | 685 | common->priv = priv; |
669 | common->debug_mask = ath9k_debug; | 686 | common->debug_mask = ath9k_debug; |
670 | 687 | ||
671 | spin_lock_init(&priv->wmi->wmi_lock); | ||
672 | spin_lock_init(&priv->beacon_lock); | 688 | spin_lock_init(&priv->beacon_lock); |
673 | spin_lock_init(&priv->tx_lock); | 689 | spin_lock_init(&priv->tx.tx_lock); |
674 | mutex_init(&priv->mutex); | 690 | mutex_init(&priv->mutex); |
675 | mutex_init(&priv->htc_pm_lock); | 691 | mutex_init(&priv->htc_pm_lock); |
676 | tasklet_init(&priv->swba_tasklet, ath9k_swba_tasklet, | ||
677 | (unsigned long)priv); | ||
678 | tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, | 692 | tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, |
679 | (unsigned long)priv); | 693 | (unsigned long)priv); |
680 | tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, | 694 | tasklet_init(&priv->tx_failed_tasklet, ath9k_tx_failed_tasklet, |
681 | (unsigned long)priv); | 695 | (unsigned long)priv); |
682 | INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work); | 696 | INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work); |
683 | INIT_WORK(&priv->ps_work, ath9k_ps_work); | 697 | INIT_WORK(&priv->ps_work, ath9k_ps_work); |
684 | INIT_WORK(&priv->fatal_work, ath9k_fatal_work); | 698 | INIT_WORK(&priv->fatal_work, ath9k_fatal_work); |
699 | setup_timer(&priv->tx.cleanup_timer, ath9k_htc_tx_cleanup_timer, | ||
700 | (unsigned long)priv); | ||
685 | 701 | ||
686 | /* | 702 | /* |
687 | * Cache line size is used to size and align various | 703 | * Cache line size is used to size and align various |
@@ -698,16 +714,13 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
698 | goto err_hw; | 714 | goto err_hw; |
699 | } | 715 | } |
700 | 716 | ||
701 | ret = ath9k_htc_init_debug(ah); | ||
702 | if (ret) { | ||
703 | ath_err(common, "Unable to create debugfs files\n"); | ||
704 | goto err_debug; | ||
705 | } | ||
706 | |||
707 | ret = ath9k_init_queues(priv); | 717 | ret = ath9k_init_queues(priv); |
708 | if (ret) | 718 | if (ret) |
709 | goto err_queues; | 719 | goto err_queues; |
710 | 720 | ||
721 | for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) | ||
722 | priv->cur_beacon_conf.bslot[i] = NULL; | ||
723 | |||
711 | ath9k_init_crypto(priv); | 724 | ath9k_init_crypto(priv); |
712 | ath9k_init_channels_rates(priv); | 725 | ath9k_init_channels_rates(priv); |
713 | ath9k_init_misc(priv); | 726 | ath9k_init_misc(priv); |
@@ -720,8 +733,6 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
720 | return 0; | 733 | return 0; |
721 | 734 | ||
722 | err_queues: | 735 | err_queues: |
723 | ath9k_htc_exit_debug(ah); | ||
724 | err_debug: | ||
725 | ath9k_hw_deinit(ah); | 736 | ath9k_hw_deinit(ah); |
726 | err_hw: | 737 | err_hw: |
727 | 738 | ||
@@ -742,17 +753,27 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
742 | IEEE80211_HW_HAS_RATE_CONTROL | | 753 | IEEE80211_HW_HAS_RATE_CONTROL | |
743 | IEEE80211_HW_RX_INCLUDES_FCS | | 754 | IEEE80211_HW_RX_INCLUDES_FCS | |
744 | IEEE80211_HW_SUPPORTS_PS | | 755 | IEEE80211_HW_SUPPORTS_PS | |
745 | IEEE80211_HW_PS_NULLFUNC_STACK; | 756 | IEEE80211_HW_PS_NULLFUNC_STACK | |
757 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | ||
746 | 758 | ||
747 | hw->wiphy->interface_modes = | 759 | hw->wiphy->interface_modes = |
748 | BIT(NL80211_IFTYPE_STATION) | | 760 | BIT(NL80211_IFTYPE_STATION) | |
749 | BIT(NL80211_IFTYPE_ADHOC); | 761 | BIT(NL80211_IFTYPE_ADHOC) | |
762 | BIT(NL80211_IFTYPE_AP) | | ||
763 | BIT(NL80211_IFTYPE_P2P_GO) | | ||
764 | BIT(NL80211_IFTYPE_P2P_CLIENT); | ||
750 | 765 | ||
751 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 766 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
752 | 767 | ||
753 | hw->queues = 4; | 768 | hw->queues = 4; |
754 | hw->channel_change_time = 5000; | 769 | hw->channel_change_time = 5000; |
755 | hw->max_listen_interval = 10; | 770 | hw->max_listen_interval = 10; |
771 | |||
772 | if (AR_SREV_9271(priv->ah)) | ||
773 | hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_9271; | ||
774 | else | ||
775 | hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_7010; | ||
776 | |||
756 | hw->vif_data_size = sizeof(struct ath9k_htc_vif); | 777 | hw->vif_data_size = sizeof(struct ath9k_htc_vif); |
757 | hw->sta_data_size = sizeof(struct ath9k_htc_sta); | 778 | hw->sta_data_size = sizeof(struct ath9k_htc_sta); |
758 | 779 | ||
@@ -779,6 +800,43 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
779 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | 800 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); |
780 | } | 801 | } |
781 | 802 | ||
803 | static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv) | ||
804 | { | ||
805 | struct ieee80211_hw *hw = priv->hw; | ||
806 | struct wmi_fw_version cmd_rsp; | ||
807 | int ret; | ||
808 | |||
809 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
810 | |||
811 | WMI_CMD(WMI_GET_FW_VERSION); | ||
812 | if (ret) | ||
813 | return -EINVAL; | ||
814 | |||
815 | priv->fw_version_major = be16_to_cpu(cmd_rsp.major); | ||
816 | priv->fw_version_minor = be16_to_cpu(cmd_rsp.minor); | ||
817 | |||
818 | snprintf(hw->wiphy->fw_version, ETHTOOL_BUSINFO_LEN, "%d.%d", | ||
819 | priv->fw_version_major, | ||
820 | priv->fw_version_minor); | ||
821 | |||
822 | dev_info(priv->dev, "ath9k_htc: FW Version: %d.%d\n", | ||
823 | priv->fw_version_major, | ||
824 | priv->fw_version_minor); | ||
825 | |||
826 | /* | ||
827 | * Check if the available FW matches the driver's | ||
828 | * required version. | ||
829 | */ | ||
830 | if (priv->fw_version_major != MAJOR_VERSION_REQ || | ||
831 | priv->fw_version_minor != MINOR_VERSION_REQ) { | ||
832 | dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n", | ||
833 | MAJOR_VERSION_REQ, MINOR_VERSION_REQ); | ||
834 | return -EINVAL; | ||
835 | } | ||
836 | |||
837 | return 0; | ||
838 | } | ||
839 | |||
782 | static int ath9k_init_device(struct ath9k_htc_priv *priv, | 840 | static int ath9k_init_device(struct ath9k_htc_priv *priv, |
783 | u16 devid, char *product, u32 drv_info) | 841 | u16 devid, char *product, u32 drv_info) |
784 | { | 842 | { |
@@ -798,6 +856,10 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, | |||
798 | common = ath9k_hw_common(ah); | 856 | common = ath9k_hw_common(ah); |
799 | ath9k_set_hw_capab(priv, hw); | 857 | ath9k_set_hw_capab(priv, hw); |
800 | 858 | ||
859 | error = ath9k_init_firmware_version(priv); | ||
860 | if (error != 0) | ||
861 | goto err_fw; | ||
862 | |||
801 | /* Initialize regulatory */ | 863 | /* Initialize regulatory */ |
802 | error = ath_regd_init(&common->regulatory, priv->hw->wiphy, | 864 | error = ath_regd_init(&common->regulatory, priv->hw->wiphy, |
803 | ath9k_reg_notifier); | 865 | ath9k_reg_notifier); |
@@ -816,6 +878,13 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, | |||
816 | if (error != 0) | 878 | if (error != 0) |
817 | goto err_rx; | 879 | goto err_rx; |
818 | 880 | ||
881 | #ifdef CONFIG_MAC80211_LEDS | ||
882 | /* must be initialized before ieee80211_register_hw */ | ||
883 | priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw, | ||
884 | IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_htc_tpt_blink, | ||
885 | ARRAY_SIZE(ath9k_htc_tpt_blink)); | ||
886 | #endif | ||
887 | |||
819 | /* Register with mac80211 */ | 888 | /* Register with mac80211 */ |
820 | error = ieee80211_register_hw(hw); | 889 | error = ieee80211_register_hw(hw); |
821 | if (error) | 890 | if (error) |
@@ -828,6 +897,12 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, | |||
828 | goto err_world; | 897 | goto err_world; |
829 | } | 898 | } |
830 | 899 | ||
900 | error = ath9k_htc_init_debug(priv->ah); | ||
901 | if (error) { | ||
902 | ath_err(common, "Unable to create debugfs files\n"); | ||
903 | goto err_world; | ||
904 | } | ||
905 | |||
831 | ath_dbg(common, ATH_DBG_CONFIG, | 906 | ath_dbg(common, ATH_DBG_CONFIG, |
832 | "WMI:%d, BCN:%d, CAB:%d, UAPSD:%d, MGMT:%d, " | 907 | "WMI:%d, BCN:%d, CAB:%d, UAPSD:%d, MGMT:%d, " |
833 | "BE:%d, BK:%d, VI:%d, VO:%d\n", | 908 | "BE:%d, BK:%d, VI:%d, VO:%d\n", |
@@ -858,6 +933,8 @@ err_rx: | |||
858 | err_tx: | 933 | err_tx: |
859 | /* Nothing */ | 934 | /* Nothing */ |
860 | err_regd: | 935 | err_regd: |
936 | /* Nothing */ | ||
937 | err_fw: | ||
861 | ath9k_deinit_priv(priv); | 938 | ath9k_deinit_priv(priv); |
862 | err_init: | 939 | err_init: |
863 | return error; | 940 | return error; |
@@ -946,38 +1023,20 @@ int ath9k_htc_resume(struct htc_target *htc_handle) | |||
946 | 1023 | ||
947 | static int __init ath9k_htc_init(void) | 1024 | static int __init ath9k_htc_init(void) |
948 | { | 1025 | { |
949 | int error; | 1026 | if (ath9k_hif_usb_init() < 0) { |
950 | |||
951 | error = ath9k_htc_debug_create_root(); | ||
952 | if (error < 0) { | ||
953 | printk(KERN_ERR | ||
954 | "ath9k_htc: Unable to create debugfs root: %d\n", | ||
955 | error); | ||
956 | goto err_dbg; | ||
957 | } | ||
958 | |||
959 | error = ath9k_hif_usb_init(); | ||
960 | if (error < 0) { | ||
961 | printk(KERN_ERR | 1027 | printk(KERN_ERR |
962 | "ath9k_htc: No USB devices found," | 1028 | "ath9k_htc: No USB devices found," |
963 | " driver not installed.\n"); | 1029 | " driver not installed.\n"); |
964 | error = -ENODEV; | 1030 | return -ENODEV; |
965 | goto err_usb; | ||
966 | } | 1031 | } |
967 | 1032 | ||
968 | return 0; | 1033 | return 0; |
969 | |||
970 | err_usb: | ||
971 | ath9k_htc_debug_remove_root(); | ||
972 | err_dbg: | ||
973 | return error; | ||
974 | } | 1034 | } |
975 | module_init(ath9k_htc_init); | 1035 | module_init(ath9k_htc_init); |
976 | 1036 | ||
977 | static void __exit ath9k_htc_exit(void) | 1037 | static void __exit ath9k_htc_exit(void) |
978 | { | 1038 | { |
979 | ath9k_hif_usb_exit(); | 1039 | ath9k_hif_usb_exit(); |
980 | ath9k_htc_debug_remove_root(); | ||
981 | printk(KERN_INFO "ath9k_htc: Driver unloaded\n"); | 1040 | printk(KERN_INFO "ath9k_htc: Driver unloaded\n"); |
982 | } | 1041 | } |
983 | module_exit(ath9k_htc_exit); | 1042 | module_exit(ath9k_htc_exit); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index db8c0c044e9..5aa104fe7ee 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -16,10 +16,6 @@ | |||
16 | 16 | ||
17 | #include "htc.h" | 17 | #include "htc.h" |
18 | 18 | ||
19 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
20 | static struct dentry *ath9k_debugfs_root; | ||
21 | #endif | ||
22 | |||
23 | /*************/ | 19 | /*************/ |
24 | /* Utilities */ | 20 | /* Utilities */ |
25 | /*************/ | 21 | /*************/ |
@@ -197,11 +193,16 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) | |||
197 | 193 | ||
198 | ath9k_htc_stop_ani(priv); | 194 | ath9k_htc_stop_ani(priv); |
199 | ieee80211_stop_queues(priv->hw); | 195 | ieee80211_stop_queues(priv->hw); |
200 | htc_stop(priv->htc); | 196 | |
197 | del_timer_sync(&priv->tx.cleanup_timer); | ||
198 | ath9k_htc_tx_drain(priv); | ||
199 | |||
201 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 200 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
202 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 201 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
203 | WMI_CMD(WMI_STOP_RECV_CMDID); | 202 | WMI_CMD(WMI_STOP_RECV_CMDID); |
204 | 203 | ||
204 | ath9k_wmi_event_drain(priv); | ||
205 | |||
205 | caldata = &priv->caldata; | 206 | caldata = &priv->caldata; |
206 | ret = ath9k_hw_reset(ah, ah->curchan, caldata, false); | 207 | ret = ath9k_hw_reset(ah, ah->curchan, caldata, false); |
207 | if (ret) { | 208 | if (ret) { |
@@ -225,6 +226,9 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) | |||
225 | ath9k_htc_vif_reconfig(priv); | 226 | ath9k_htc_vif_reconfig(priv); |
226 | ieee80211_wake_queues(priv->hw); | 227 | ieee80211_wake_queues(priv->hw); |
227 | 228 | ||
229 | mod_timer(&priv->tx.cleanup_timer, | ||
230 | jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); | ||
231 | |||
228 | ath9k_htc_ps_restore(priv); | 232 | ath9k_htc_ps_restore(priv); |
229 | mutex_unlock(&priv->mutex); | 233 | mutex_unlock(&priv->mutex); |
230 | } | 234 | } |
@@ -250,11 +254,16 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
250 | fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); | 254 | fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); |
251 | 255 | ||
252 | ath9k_htc_ps_wakeup(priv); | 256 | ath9k_htc_ps_wakeup(priv); |
253 | htc_stop(priv->htc); | 257 | |
258 | del_timer_sync(&priv->tx.cleanup_timer); | ||
259 | ath9k_htc_tx_drain(priv); | ||
260 | |||
254 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 261 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
255 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 262 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
256 | WMI_CMD(WMI_STOP_RECV_CMDID); | 263 | WMI_CMD(WMI_STOP_RECV_CMDID); |
257 | 264 | ||
265 | ath9k_wmi_event_drain(priv); | ||
266 | |||
258 | ath_dbg(common, ATH_DBG_CONFIG, | 267 | ath_dbg(common, ATH_DBG_CONFIG, |
259 | "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", | 268 | "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", |
260 | priv->ah->curchan->channel, | 269 | priv->ah->curchan->channel, |
@@ -263,6 +272,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
263 | 272 | ||
264 | if (!fastcc) | 273 | if (!fastcc) |
265 | caldata = &priv->caldata; | 274 | caldata = &priv->caldata; |
275 | |||
266 | ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); | 276 | ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); |
267 | if (ret) { | 277 | if (ret) { |
268 | ath_err(common, | 278 | ath_err(common, |
@@ -296,6 +306,9 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
296 | !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) | 306 | !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) |
297 | ath9k_htc_vif_reconfig(priv); | 307 | ath9k_htc_vif_reconfig(priv); |
298 | 308 | ||
309 | mod_timer(&priv->tx.cleanup_timer, | ||
310 | jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); | ||
311 | |||
299 | err: | 312 | err: |
300 | ath9k_htc_ps_restore(priv); | 313 | ath9k_htc_ps_restore(priv); |
301 | return ret; | 314 | return ret; |
@@ -319,6 +332,11 @@ static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) | |||
319 | memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); | 332 | memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); |
320 | hvif.index = priv->mon_vif_idx; | 333 | hvif.index = priv->mon_vif_idx; |
321 | WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); | 334 | WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); |
335 | if (ret) { | ||
336 | ath_err(common, "Unable to remove monitor interface at idx: %d\n", | ||
337 | priv->mon_vif_idx); | ||
338 | } | ||
339 | |||
322 | priv->nvifs--; | 340 | priv->nvifs--; |
323 | priv->vif_slot &= ~(1 << priv->mon_vif_idx); | 341 | priv->vif_slot &= ~(1 << priv->mon_vif_idx); |
324 | } | 342 | } |
@@ -349,7 +367,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) | |||
349 | memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); | 367 | memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); |
350 | memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); | 368 | memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); |
351 | 369 | ||
352 | hvif.opmode = cpu_to_be32(HTC_M_MONITOR); | 370 | hvif.opmode = HTC_M_MONITOR; |
353 | hvif.index = ffz(priv->vif_slot); | 371 | hvif.index = ffz(priv->vif_slot); |
354 | 372 | ||
355 | WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); | 373 | WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); |
@@ -382,7 +400,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) | |||
382 | tsta.is_vif_sta = 1; | 400 | tsta.is_vif_sta = 1; |
383 | tsta.sta_index = sta_idx; | 401 | tsta.sta_index = sta_idx; |
384 | tsta.vif_index = hvif.index; | 402 | tsta.vif_index = hvif.index; |
385 | tsta.maxampdu = 0xffff; | 403 | tsta.maxampdu = cpu_to_be16(0xffff); |
386 | 404 | ||
387 | WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); | 405 | WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); |
388 | if (ret) { | 406 | if (ret) { |
@@ -449,6 +467,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, | |||
449 | struct ath9k_htc_sta *ista; | 467 | struct ath9k_htc_sta *ista; |
450 | int ret, sta_idx; | 468 | int ret, sta_idx; |
451 | u8 cmd_rsp; | 469 | u8 cmd_rsp; |
470 | u16 maxampdu; | ||
452 | 471 | ||
453 | if (priv->nstations >= ATH9K_HTC_MAX_STA) | 472 | if (priv->nstations >= ATH9K_HTC_MAX_STA) |
454 | return -ENOBUFS; | 473 | return -ENOBUFS; |
@@ -463,9 +482,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, | |||
463 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | 482 | ista = (struct ath9k_htc_sta *) sta->drv_priv; |
464 | memcpy(&tsta.macaddr, sta->addr, ETH_ALEN); | 483 | memcpy(&tsta.macaddr, sta->addr, ETH_ALEN); |
465 | memcpy(&tsta.bssid, common->curbssid, ETH_ALEN); | 484 | memcpy(&tsta.bssid, common->curbssid, ETH_ALEN); |
466 | tsta.associd = common->curaid; | ||
467 | tsta.is_vif_sta = 0; | 485 | tsta.is_vif_sta = 0; |
468 | tsta.valid = true; | ||
469 | ista->index = sta_idx; | 486 | ista->index = sta_idx; |
470 | } else { | 487 | } else { |
471 | memcpy(&tsta.macaddr, vif->addr, ETH_ALEN); | 488 | memcpy(&tsta.macaddr, vif->addr, ETH_ALEN); |
@@ -474,7 +491,15 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, | |||
474 | 491 | ||
475 | tsta.sta_index = sta_idx; | 492 | tsta.sta_index = sta_idx; |
476 | tsta.vif_index = avp->index; | 493 | tsta.vif_index = avp->index; |
477 | tsta.maxampdu = 0xffff; | 494 | |
495 | if (!sta) { | ||
496 | tsta.maxampdu = cpu_to_be16(0xffff); | ||
497 | } else { | ||
498 | maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + | ||
499 | sta->ht_cap.ampdu_factor); | ||
500 | tsta.maxampdu = cpu_to_be16(maxampdu); | ||
501 | } | ||
502 | |||
478 | if (sta && sta->ht_cap.ht_supported) | 503 | if (sta && sta->ht_cap.ht_supported) |
479 | tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); | 504 | tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); |
480 | 505 | ||
@@ -547,7 +572,8 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv, | |||
547 | return 0; | 572 | return 0; |
548 | } | 573 | } |
549 | 574 | ||
550 | int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv) | 575 | int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv, |
576 | u8 enable_coex) | ||
551 | { | 577 | { |
552 | struct ath9k_htc_cap_target tcap; | 578 | struct ath9k_htc_cap_target tcap; |
553 | int ret; | 579 | int ret; |
@@ -555,13 +581,9 @@ int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv) | |||
555 | 581 | ||
556 | memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target)); | 582 | memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target)); |
557 | 583 | ||
558 | /* FIXME: Values are hardcoded */ | 584 | tcap.ampdu_limit = cpu_to_be32(0xffff); |
559 | tcap.flags = 0x240c40; | 585 | tcap.ampdu_subframes = priv->hw->max_tx_aggregation_subframes; |
560 | tcap.flags_ext = 0x80601000; | 586 | tcap.enable_coex = enable_coex; |
561 | tcap.ampdu_limit = 0xffff0000; | ||
562 | tcap.ampdu_subframes = 20; | ||
563 | tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask; | ||
564 | tcap.protmode = 1; | ||
565 | tcap.tx_chainmask = priv->ah->caps.tx_chainmask; | 587 | tcap.tx_chainmask = priv->ah->caps.tx_chainmask; |
566 | 588 | ||
567 | WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap); | 589 | WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap); |
@@ -709,218 +731,13 @@ static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv, | |||
709 | (aggr.aggr_enable) ? "Starting" : "Stopping", | 731 | (aggr.aggr_enable) ? "Starting" : "Stopping", |
710 | sta->addr, tid); | 732 | sta->addr, tid); |
711 | 733 | ||
712 | spin_lock_bh(&priv->tx_lock); | 734 | spin_lock_bh(&priv->tx.tx_lock); |
713 | ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP; | 735 | ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP; |
714 | spin_unlock_bh(&priv->tx_lock); | 736 | spin_unlock_bh(&priv->tx.tx_lock); |
715 | 737 | ||
716 | return ret; | 738 | return ret; |
717 | } | 739 | } |
718 | 740 | ||
719 | /*********/ | ||
720 | /* DEBUG */ | ||
721 | /*********/ | ||
722 | |||
723 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
724 | |||
725 | static int ath9k_debugfs_open(struct inode *inode, struct file *file) | ||
726 | { | ||
727 | file->private_data = inode->i_private; | ||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, | ||
732 | size_t count, loff_t *ppos) | ||
733 | { | ||
734 | struct ath9k_htc_priv *priv = file->private_data; | ||
735 | struct ath9k_htc_target_stats cmd_rsp; | ||
736 | char buf[512]; | ||
737 | unsigned int len = 0; | ||
738 | int ret = 0; | ||
739 | |||
740 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
741 | |||
742 | WMI_CMD(WMI_TGT_STATS_CMDID); | ||
743 | if (ret) | ||
744 | return -EINVAL; | ||
745 | |||
746 | |||
747 | len += snprintf(buf + len, sizeof(buf) - len, | ||
748 | "%19s : %10u\n", "TX Short Retries", | ||
749 | be32_to_cpu(cmd_rsp.tx_shortretry)); | ||
750 | len += snprintf(buf + len, sizeof(buf) - len, | ||
751 | "%19s : %10u\n", "TX Long Retries", | ||
752 | be32_to_cpu(cmd_rsp.tx_longretry)); | ||
753 | len += snprintf(buf + len, sizeof(buf) - len, | ||
754 | "%19s : %10u\n", "TX Xretries", | ||
755 | be32_to_cpu(cmd_rsp.tx_xretries)); | ||
756 | len += snprintf(buf + len, sizeof(buf) - len, | ||
757 | "%19s : %10u\n", "TX Unaggr. Xretries", | ||
758 | be32_to_cpu(cmd_rsp.ht_txunaggr_xretry)); | ||
759 | len += snprintf(buf + len, sizeof(buf) - len, | ||
760 | "%19s : %10u\n", "TX Xretries (HT)", | ||
761 | be32_to_cpu(cmd_rsp.ht_tx_xretries)); | ||
762 | len += snprintf(buf + len, sizeof(buf) - len, | ||
763 | "%19s : %10u\n", "TX Rate", priv->debug.txrate); | ||
764 | |||
765 | if (len > sizeof(buf)) | ||
766 | len = sizeof(buf); | ||
767 | |||
768 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
769 | } | ||
770 | |||
771 | static const struct file_operations fops_tgt_stats = { | ||
772 | .read = read_file_tgt_stats, | ||
773 | .open = ath9k_debugfs_open, | ||
774 | .owner = THIS_MODULE, | ||
775 | .llseek = default_llseek, | ||
776 | }; | ||
777 | |||
778 | static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | ||
779 | size_t count, loff_t *ppos) | ||
780 | { | ||
781 | struct ath9k_htc_priv *priv = file->private_data; | ||
782 | char buf[512]; | ||
783 | unsigned int len = 0; | ||
784 | |||
785 | len += snprintf(buf + len, sizeof(buf) - len, | ||
786 | "%20s : %10u\n", "Buffers queued", | ||
787 | priv->debug.tx_stats.buf_queued); | ||
788 | len += snprintf(buf + len, sizeof(buf) - len, | ||
789 | "%20s : %10u\n", "Buffers completed", | ||
790 | priv->debug.tx_stats.buf_completed); | ||
791 | len += snprintf(buf + len, sizeof(buf) - len, | ||
792 | "%20s : %10u\n", "SKBs queued", | ||
793 | priv->debug.tx_stats.skb_queued); | ||
794 | len += snprintf(buf + len, sizeof(buf) - len, | ||
795 | "%20s : %10u\n", "SKBs completed", | ||
796 | priv->debug.tx_stats.skb_completed); | ||
797 | len += snprintf(buf + len, sizeof(buf) - len, | ||
798 | "%20s : %10u\n", "SKBs dropped", | ||
799 | priv->debug.tx_stats.skb_dropped); | ||
800 | |||
801 | len += snprintf(buf + len, sizeof(buf) - len, | ||
802 | "%20s : %10u\n", "BE queued", | ||
803 | priv->debug.tx_stats.queue_stats[WME_AC_BE]); | ||
804 | len += snprintf(buf + len, sizeof(buf) - len, | ||
805 | "%20s : %10u\n", "BK queued", | ||
806 | priv->debug.tx_stats.queue_stats[WME_AC_BK]); | ||
807 | len += snprintf(buf + len, sizeof(buf) - len, | ||
808 | "%20s : %10u\n", "VI queued", | ||
809 | priv->debug.tx_stats.queue_stats[WME_AC_VI]); | ||
810 | len += snprintf(buf + len, sizeof(buf) - len, | ||
811 | "%20s : %10u\n", "VO queued", | ||
812 | priv->debug.tx_stats.queue_stats[WME_AC_VO]); | ||
813 | |||
814 | if (len > sizeof(buf)) | ||
815 | len = sizeof(buf); | ||
816 | |||
817 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
818 | } | ||
819 | |||
820 | static const struct file_operations fops_xmit = { | ||
821 | .read = read_file_xmit, | ||
822 | .open = ath9k_debugfs_open, | ||
823 | .owner = THIS_MODULE, | ||
824 | .llseek = default_llseek, | ||
825 | }; | ||
826 | |||
827 | static ssize_t read_file_recv(struct file *file, char __user *user_buf, | ||
828 | size_t count, loff_t *ppos) | ||
829 | { | ||
830 | struct ath9k_htc_priv *priv = file->private_data; | ||
831 | char buf[512]; | ||
832 | unsigned int len = 0; | ||
833 | |||
834 | len += snprintf(buf + len, sizeof(buf) - len, | ||
835 | "%20s : %10u\n", "SKBs allocated", | ||
836 | priv->debug.rx_stats.skb_allocated); | ||
837 | len += snprintf(buf + len, sizeof(buf) - len, | ||
838 | "%20s : %10u\n", "SKBs completed", | ||
839 | priv->debug.rx_stats.skb_completed); | ||
840 | len += snprintf(buf + len, sizeof(buf) - len, | ||
841 | "%20s : %10u\n", "SKBs Dropped", | ||
842 | priv->debug.rx_stats.skb_dropped); | ||
843 | |||
844 | if (len > sizeof(buf)) | ||
845 | len = sizeof(buf); | ||
846 | |||
847 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
848 | } | ||
849 | |||
850 | static const struct file_operations fops_recv = { | ||
851 | .read = read_file_recv, | ||
852 | .open = ath9k_debugfs_open, | ||
853 | .owner = THIS_MODULE, | ||
854 | .llseek = default_llseek, | ||
855 | }; | ||
856 | |||
857 | int ath9k_htc_init_debug(struct ath_hw *ah) | ||
858 | { | ||
859 | struct ath_common *common = ath9k_hw_common(ah); | ||
860 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
861 | |||
862 | if (!ath9k_debugfs_root) | ||
863 | return -ENOENT; | ||
864 | |||
865 | priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy), | ||
866 | ath9k_debugfs_root); | ||
867 | if (!priv->debug.debugfs_phy) | ||
868 | goto err; | ||
869 | |||
870 | priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR, | ||
871 | priv->debug.debugfs_phy, | ||
872 | priv, &fops_tgt_stats); | ||
873 | if (!priv->debug.debugfs_tgt_stats) | ||
874 | goto err; | ||
875 | |||
876 | |||
877 | priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR, | ||
878 | priv->debug.debugfs_phy, | ||
879 | priv, &fops_xmit); | ||
880 | if (!priv->debug.debugfs_xmit) | ||
881 | goto err; | ||
882 | |||
883 | priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR, | ||
884 | priv->debug.debugfs_phy, | ||
885 | priv, &fops_recv); | ||
886 | if (!priv->debug.debugfs_recv) | ||
887 | goto err; | ||
888 | |||
889 | return 0; | ||
890 | |||
891 | err: | ||
892 | ath9k_htc_exit_debug(ah); | ||
893 | return -ENOMEM; | ||
894 | } | ||
895 | |||
896 | void ath9k_htc_exit_debug(struct ath_hw *ah) | ||
897 | { | ||
898 | struct ath_common *common = ath9k_hw_common(ah); | ||
899 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
900 | |||
901 | debugfs_remove(priv->debug.debugfs_recv); | ||
902 | debugfs_remove(priv->debug.debugfs_xmit); | ||
903 | debugfs_remove(priv->debug.debugfs_tgt_stats); | ||
904 | debugfs_remove(priv->debug.debugfs_phy); | ||
905 | } | ||
906 | |||
907 | int ath9k_htc_debug_create_root(void) | ||
908 | { | ||
909 | ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); | ||
910 | if (!ath9k_debugfs_root) | ||
911 | return -ENOENT; | ||
912 | |||
913 | return 0; | ||
914 | } | ||
915 | |||
916 | void ath9k_htc_debug_remove_root(void) | ||
917 | { | ||
918 | debugfs_remove(ath9k_debugfs_root); | ||
919 | ath9k_debugfs_root = NULL; | ||
920 | } | ||
921 | |||
922 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ | ||
923 | |||
924 | /*******/ | 741 | /*******/ |
925 | /* ANI */ | 742 | /* ANI */ |
926 | /*******/ | 743 | /*******/ |
@@ -1040,7 +857,8 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1040 | { | 857 | { |
1041 | struct ieee80211_hdr *hdr; | 858 | struct ieee80211_hdr *hdr; |
1042 | struct ath9k_htc_priv *priv = hw->priv; | 859 | struct ath9k_htc_priv *priv = hw->priv; |
1043 | int padpos, padsize, ret; | 860 | struct ath_common *common = ath9k_hw_common(priv->ah); |
861 | int padpos, padsize, ret, slot; | ||
1044 | 862 | ||
1045 | hdr = (struct ieee80211_hdr *) skb->data; | 863 | hdr = (struct ieee80211_hdr *) skb->data; |
1046 | 864 | ||
@@ -1048,30 +866,32 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1048 | padpos = ath9k_cmn_padpos(hdr->frame_control); | 866 | padpos = ath9k_cmn_padpos(hdr->frame_control); |
1049 | padsize = padpos & 3; | 867 | padsize = padpos & 3; |
1050 | if (padsize && skb->len > padpos) { | 868 | if (padsize && skb->len > padpos) { |
1051 | if (skb_headroom(skb) < padsize) | 869 | if (skb_headroom(skb) < padsize) { |
870 | ath_dbg(common, ATH_DBG_XMIT, "No room for padding\n"); | ||
1052 | goto fail_tx; | 871 | goto fail_tx; |
872 | } | ||
1053 | skb_push(skb, padsize); | 873 | skb_push(skb, padsize); |
1054 | memmove(skb->data, skb->data + padsize, padpos); | 874 | memmove(skb->data, skb->data + padsize, padpos); |
1055 | } | 875 | } |
1056 | 876 | ||
1057 | ret = ath9k_htc_tx_start(priv, skb); | 877 | slot = ath9k_htc_tx_get_slot(priv); |
1058 | if (ret != 0) { | 878 | if (slot < 0) { |
1059 | if (ret == -ENOMEM) { | 879 | ath_dbg(common, ATH_DBG_XMIT, "No free TX slot\n"); |
1060 | ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
1061 | "Stopping TX queues\n"); | ||
1062 | ieee80211_stop_queues(hw); | ||
1063 | spin_lock_bh(&priv->tx_lock); | ||
1064 | priv->tx_queues_stop = true; | ||
1065 | spin_unlock_bh(&priv->tx_lock); | ||
1066 | } else { | ||
1067 | ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
1068 | "Tx failed\n"); | ||
1069 | } | ||
1070 | goto fail_tx; | 880 | goto fail_tx; |
1071 | } | 881 | } |
1072 | 882 | ||
883 | ret = ath9k_htc_tx_start(priv, skb, slot, false); | ||
884 | if (ret != 0) { | ||
885 | ath_dbg(common, ATH_DBG_XMIT, "Tx failed\n"); | ||
886 | goto clear_slot; | ||
887 | } | ||
888 | |||
889 | ath9k_htc_check_stop_queues(priv); | ||
890 | |||
1073 | return; | 891 | return; |
1074 | 892 | ||
893 | clear_slot: | ||
894 | ath9k_htc_tx_clear_slot(priv, slot); | ||
1075 | fail_tx: | 895 | fail_tx: |
1076 | dev_kfree_skb_any(skb); | 896 | dev_kfree_skb_any(skb); |
1077 | } | 897 | } |
@@ -1122,7 +942,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
1122 | 942 | ||
1123 | ath9k_host_rx_init(priv); | 943 | ath9k_host_rx_init(priv); |
1124 | 944 | ||
1125 | ret = ath9k_htc_update_cap_target(priv); | 945 | ret = ath9k_htc_update_cap_target(priv, 0); |
1126 | if (ret) | 946 | if (ret) |
1127 | ath_dbg(common, ATH_DBG_CONFIG, | 947 | ath_dbg(common, ATH_DBG_CONFIG, |
1128 | "Failed to update capability in target\n"); | 948 | "Failed to update capability in target\n"); |
@@ -1130,12 +950,15 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
1130 | priv->op_flags &= ~OP_INVALID; | 950 | priv->op_flags &= ~OP_INVALID; |
1131 | htc_start(priv->htc); | 951 | htc_start(priv->htc); |
1132 | 952 | ||
1133 | spin_lock_bh(&priv->tx_lock); | 953 | spin_lock_bh(&priv->tx.tx_lock); |
1134 | priv->tx_queues_stop = false; | 954 | priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; |
1135 | spin_unlock_bh(&priv->tx_lock); | 955 | spin_unlock_bh(&priv->tx.tx_lock); |
1136 | 956 | ||
1137 | ieee80211_wake_queues(hw); | 957 | ieee80211_wake_queues(hw); |
1138 | 958 | ||
959 | mod_timer(&priv->tx.cleanup_timer, | ||
960 | jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); | ||
961 | |||
1139 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) { | 962 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) { |
1140 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | 963 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, |
1141 | AR_STOMP_LOW_WLAN_WGHT); | 964 | AR_STOMP_LOW_WLAN_WGHT); |
@@ -1152,7 +975,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
1152 | struct ath9k_htc_priv *priv = hw->priv; | 975 | struct ath9k_htc_priv *priv = hw->priv; |
1153 | struct ath_hw *ah = priv->ah; | 976 | struct ath_hw *ah = priv->ah; |
1154 | struct ath_common *common = ath9k_hw_common(ah); | 977 | struct ath_common *common = ath9k_hw_common(ah); |
1155 | int ret = 0; | 978 | int ret __attribute__ ((unused)); |
1156 | u8 cmd_rsp; | 979 | u8 cmd_rsp; |
1157 | 980 | ||
1158 | mutex_lock(&priv->mutex); | 981 | mutex_lock(&priv->mutex); |
@@ -1164,25 +987,27 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
1164 | } | 987 | } |
1165 | 988 | ||
1166 | ath9k_htc_ps_wakeup(priv); | 989 | ath9k_htc_ps_wakeup(priv); |
1167 | htc_stop(priv->htc); | 990 | |
1168 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 991 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
1169 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 992 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
1170 | WMI_CMD(WMI_STOP_RECV_CMDID); | 993 | WMI_CMD(WMI_STOP_RECV_CMDID); |
1171 | 994 | ||
1172 | tasklet_kill(&priv->swba_tasklet); | ||
1173 | tasklet_kill(&priv->rx_tasklet); | 995 | tasklet_kill(&priv->rx_tasklet); |
1174 | tasklet_kill(&priv->tx_tasklet); | ||
1175 | 996 | ||
1176 | skb_queue_purge(&priv->tx_queue); | 997 | del_timer_sync(&priv->tx.cleanup_timer); |
998 | ath9k_htc_tx_drain(priv); | ||
999 | ath9k_wmi_event_drain(priv); | ||
1177 | 1000 | ||
1178 | mutex_unlock(&priv->mutex); | 1001 | mutex_unlock(&priv->mutex); |
1179 | 1002 | ||
1180 | /* Cancel all the running timers/work .. */ | 1003 | /* Cancel all the running timers/work .. */ |
1181 | cancel_work_sync(&priv->fatal_work); | 1004 | cancel_work_sync(&priv->fatal_work); |
1182 | cancel_work_sync(&priv->ps_work); | 1005 | cancel_work_sync(&priv->ps_work); |
1183 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | 1006 | |
1007 | #ifdef CONFIG_MAC80211_LEDS | ||
1008 | cancel_work_sync(&priv->led_work); | ||
1009 | #endif | ||
1184 | ath9k_htc_stop_ani(priv); | 1010 | ath9k_htc_stop_ani(priv); |
1185 | ath9k_led_stop_brightness(priv); | ||
1186 | 1011 | ||
1187 | mutex_lock(&priv->mutex); | 1012 | mutex_lock(&priv->mutex); |
1188 | 1013 | ||
@@ -1245,13 +1070,13 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | |||
1245 | 1070 | ||
1246 | switch (vif->type) { | 1071 | switch (vif->type) { |
1247 | case NL80211_IFTYPE_STATION: | 1072 | case NL80211_IFTYPE_STATION: |
1248 | hvif.opmode = cpu_to_be32(HTC_M_STA); | 1073 | hvif.opmode = HTC_M_STA; |
1249 | break; | 1074 | break; |
1250 | case NL80211_IFTYPE_ADHOC: | 1075 | case NL80211_IFTYPE_ADHOC: |
1251 | hvif.opmode = cpu_to_be32(HTC_M_IBSS); | 1076 | hvif.opmode = HTC_M_IBSS; |
1252 | break; | 1077 | break; |
1253 | case NL80211_IFTYPE_AP: | 1078 | case NL80211_IFTYPE_AP: |
1254 | hvif.opmode = cpu_to_be32(HTC_M_HOSTAP); | 1079 | hvif.opmode = HTC_M_HOSTAP; |
1255 | break; | 1080 | break; |
1256 | default: | 1081 | default: |
1257 | ath_err(common, | 1082 | ath_err(common, |
@@ -1281,14 +1106,20 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | |||
1281 | 1106 | ||
1282 | priv->vif_slot |= (1 << avp->index); | 1107 | priv->vif_slot |= (1 << avp->index); |
1283 | priv->nvifs++; | 1108 | priv->nvifs++; |
1284 | priv->vif = vif; | ||
1285 | 1109 | ||
1286 | INC_VIF(priv, vif->type); | 1110 | INC_VIF(priv, vif->type); |
1111 | |||
1112 | if ((vif->type == NL80211_IFTYPE_AP) || | ||
1113 | (vif->type == NL80211_IFTYPE_ADHOC)) | ||
1114 | ath9k_htc_assign_bslot(priv, vif); | ||
1115 | |||
1287 | ath9k_htc_set_opmode(priv); | 1116 | ath9k_htc_set_opmode(priv); |
1288 | 1117 | ||
1289 | if ((priv->ah->opmode == NL80211_IFTYPE_AP) && | 1118 | if ((priv->ah->opmode == NL80211_IFTYPE_AP) && |
1290 | !(priv->op_flags & OP_ANI_RUNNING)) | 1119 | !(priv->op_flags & OP_ANI_RUNNING)) { |
1120 | ath9k_hw_set_tsfadjust(priv->ah, 1); | ||
1291 | ath9k_htc_start_ani(priv); | 1121 | ath9k_htc_start_ani(priv); |
1122 | } | ||
1292 | 1123 | ||
1293 | ath_dbg(common, ATH_DBG_CONFIG, | 1124 | ath_dbg(common, ATH_DBG_CONFIG, |
1294 | "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); | 1125 | "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); |
@@ -1317,13 +1148,21 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, | |||
1317 | memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); | 1148 | memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); |
1318 | hvif.index = avp->index; | 1149 | hvif.index = avp->index; |
1319 | WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); | 1150 | WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); |
1151 | if (ret) { | ||
1152 | ath_err(common, "Unable to remove interface at idx: %d\n", | ||
1153 | avp->index); | ||
1154 | } | ||
1320 | priv->nvifs--; | 1155 | priv->nvifs--; |
1321 | priv->vif_slot &= ~(1 << avp->index); | 1156 | priv->vif_slot &= ~(1 << avp->index); |
1322 | 1157 | ||
1323 | ath9k_htc_remove_station(priv, vif, NULL); | 1158 | ath9k_htc_remove_station(priv, vif, NULL); |
1324 | priv->vif = NULL; | ||
1325 | 1159 | ||
1326 | DEC_VIF(priv, vif->type); | 1160 | DEC_VIF(priv, vif->type); |
1161 | |||
1162 | if ((vif->type == NL80211_IFTYPE_AP) || | ||
1163 | (vif->type == NL80211_IFTYPE_ADHOC)) | ||
1164 | ath9k_htc_remove_bslot(priv, vif); | ||
1165 | |||
1327 | ath9k_htc_set_opmode(priv); | 1166 | ath9k_htc_set_opmode(priv); |
1328 | 1167 | ||
1329 | /* | 1168 | /* |
@@ -1493,10 +1332,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw, | |||
1493 | struct ieee80211_sta *sta) | 1332 | struct ieee80211_sta *sta) |
1494 | { | 1333 | { |
1495 | struct ath9k_htc_priv *priv = hw->priv; | 1334 | struct ath9k_htc_priv *priv = hw->priv; |
1335 | struct ath9k_htc_sta *ista; | ||
1496 | int ret; | 1336 | int ret; |
1497 | 1337 | ||
1498 | mutex_lock(&priv->mutex); | 1338 | mutex_lock(&priv->mutex); |
1499 | ath9k_htc_ps_wakeup(priv); | 1339 | ath9k_htc_ps_wakeup(priv); |
1340 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
1341 | htc_sta_drain(priv->htc, ista->index); | ||
1500 | ret = ath9k_htc_remove_station(priv, vif, sta); | 1342 | ret = ath9k_htc_remove_station(priv, vif, sta); |
1501 | ath9k_htc_ps_restore(priv); | 1343 | ath9k_htc_ps_restore(priv); |
1502 | mutex_unlock(&priv->mutex); | 1344 | mutex_unlock(&priv->mutex); |
@@ -1644,6 +1486,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1644 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { | 1486 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { |
1645 | ath_dbg(common, ATH_DBG_CONFIG, | 1487 | ath_dbg(common, ATH_DBG_CONFIG, |
1646 | "Beacon enabled for BSS: %pM\n", bss_conf->bssid); | 1488 | "Beacon enabled for BSS: %pM\n", bss_conf->bssid); |
1489 | ath9k_htc_set_tsfadjust(priv, vif); | ||
1647 | priv->op_flags |= OP_ENABLE_BEACON; | 1490 | priv->op_flags |= OP_ENABLE_BEACON; |
1648 | ath9k_htc_beacon_config(priv, vif); | 1491 | ath9k_htc_beacon_config(priv, vif); |
1649 | } | 1492 | } |
@@ -1741,6 +1584,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, | |||
1741 | int ret = 0; | 1584 | int ret = 0; |
1742 | 1585 | ||
1743 | mutex_lock(&priv->mutex); | 1586 | mutex_lock(&priv->mutex); |
1587 | ath9k_htc_ps_wakeup(priv); | ||
1744 | 1588 | ||
1745 | switch (action) { | 1589 | switch (action) { |
1746 | case IEEE80211_AMPDU_RX_START: | 1590 | case IEEE80211_AMPDU_RX_START: |
@@ -1758,14 +1602,15 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, | |||
1758 | break; | 1602 | break; |
1759 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 1603 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
1760 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | 1604 | ista = (struct ath9k_htc_sta *) sta->drv_priv; |
1761 | spin_lock_bh(&priv->tx_lock); | 1605 | spin_lock_bh(&priv->tx.tx_lock); |
1762 | ista->tid_state[tid] = AGGR_OPERATIONAL; | 1606 | ista->tid_state[tid] = AGGR_OPERATIONAL; |
1763 | spin_unlock_bh(&priv->tx_lock); | 1607 | spin_unlock_bh(&priv->tx.tx_lock); |
1764 | break; | 1608 | break; |
1765 | default: | 1609 | default: |
1766 | ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); | 1610 | ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); |
1767 | } | 1611 | } |
1768 | 1612 | ||
1613 | ath9k_htc_ps_restore(priv); | ||
1769 | mutex_unlock(&priv->mutex); | 1614 | mutex_unlock(&priv->mutex); |
1770 | 1615 | ||
1771 | return ret; | 1616 | return ret; |
@@ -1816,6 +1661,55 @@ static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw, | |||
1816 | mutex_unlock(&priv->mutex); | 1661 | mutex_unlock(&priv->mutex); |
1817 | } | 1662 | } |
1818 | 1663 | ||
1664 | /* | ||
1665 | * Currently, this is used only for selecting the minimum rate | ||
1666 | * for management frames, rate selection for data frames remain | ||
1667 | * unaffected. | ||
1668 | */ | ||
1669 | static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw, | ||
1670 | struct ieee80211_vif *vif, | ||
1671 | const struct cfg80211_bitrate_mask *mask) | ||
1672 | { | ||
1673 | struct ath9k_htc_priv *priv = hw->priv; | ||
1674 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1675 | struct ath9k_htc_target_rate_mask tmask; | ||
1676 | struct ath9k_htc_vif *avp = (void *)vif->drv_priv; | ||
1677 | int ret = 0; | ||
1678 | u8 cmd_rsp; | ||
1679 | |||
1680 | memset(&tmask, 0, sizeof(struct ath9k_htc_target_rate_mask)); | ||
1681 | |||
1682 | tmask.vif_index = avp->index; | ||
1683 | tmask.band = IEEE80211_BAND_2GHZ; | ||
1684 | tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_2GHZ].legacy); | ||
1685 | |||
1686 | WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask); | ||
1687 | if (ret) { | ||
1688 | ath_err(common, | ||
1689 | "Unable to set 2G rate mask for " | ||
1690 | "interface at idx: %d\n", avp->index); | ||
1691 | goto out; | ||
1692 | } | ||
1693 | |||
1694 | tmask.band = IEEE80211_BAND_5GHZ; | ||
1695 | tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_5GHZ].legacy); | ||
1696 | |||
1697 | WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask); | ||
1698 | if (ret) { | ||
1699 | ath_err(common, | ||
1700 | "Unable to set 5G rate mask for " | ||
1701 | "interface at idx: %d\n", avp->index); | ||
1702 | goto out; | ||
1703 | } | ||
1704 | |||
1705 | ath_dbg(common, ATH_DBG_CONFIG, | ||
1706 | "Set bitrate masks: 0x%x, 0x%x\n", | ||
1707 | mask->control[IEEE80211_BAND_2GHZ].legacy, | ||
1708 | mask->control[IEEE80211_BAND_5GHZ].legacy); | ||
1709 | out: | ||
1710 | return ret; | ||
1711 | } | ||
1712 | |||
1819 | struct ieee80211_ops ath9k_htc_ops = { | 1713 | struct ieee80211_ops ath9k_htc_ops = { |
1820 | .tx = ath9k_htc_tx, | 1714 | .tx = ath9k_htc_tx, |
1821 | .start = ath9k_htc_start, | 1715 | .start = ath9k_htc_start, |
@@ -1838,4 +1732,5 @@ struct ieee80211_ops ath9k_htc_ops = { | |||
1838 | .set_rts_threshold = ath9k_htc_set_rts_threshold, | 1732 | .set_rts_threshold = ath9k_htc_set_rts_threshold, |
1839 | .rfkill_poll = ath9k_htc_rfkill_poll_state, | 1733 | .rfkill_poll = ath9k_htc_rfkill_poll_state, |
1840 | .set_coverage_class = ath9k_htc_set_coverage_class, | 1734 | .set_coverage_class = ath9k_htc_set_coverage_class, |
1735 | .set_bitrate_mask = ath9k_htc_set_bitrate_mask, | ||
1841 | }; | 1736 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 4a4f27ba96a..a898dac2233 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -53,6 +53,138 @@ int get_hw_qnum(u16 queue, int *hwq_map) | |||
53 | } | 53 | } |
54 | } | 54 | } |
55 | 55 | ||
56 | void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv) | ||
57 | { | ||
58 | spin_lock_bh(&priv->tx.tx_lock); | ||
59 | priv->tx.queued_cnt++; | ||
60 | if ((priv->tx.queued_cnt >= ATH9K_HTC_TX_THRESHOLD) && | ||
61 | !(priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) { | ||
62 | priv->tx.flags |= ATH9K_HTC_OP_TX_QUEUES_STOP; | ||
63 | ieee80211_stop_queues(priv->hw); | ||
64 | } | ||
65 | spin_unlock_bh(&priv->tx.tx_lock); | ||
66 | } | ||
67 | |||
68 | void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv) | ||
69 | { | ||
70 | spin_lock_bh(&priv->tx.tx_lock); | ||
71 | if ((priv->tx.queued_cnt < ATH9K_HTC_TX_THRESHOLD) && | ||
72 | (priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) { | ||
73 | priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; | ||
74 | ieee80211_wake_queues(priv->hw); | ||
75 | } | ||
76 | spin_unlock_bh(&priv->tx.tx_lock); | ||
77 | } | ||
78 | |||
79 | int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv) | ||
80 | { | ||
81 | int slot; | ||
82 | |||
83 | spin_lock_bh(&priv->tx.tx_lock); | ||
84 | slot = find_first_zero_bit(priv->tx.tx_slot, MAX_TX_BUF_NUM); | ||
85 | if (slot >= MAX_TX_BUF_NUM) { | ||
86 | spin_unlock_bh(&priv->tx.tx_lock); | ||
87 | return -ENOBUFS; | ||
88 | } | ||
89 | __set_bit(slot, priv->tx.tx_slot); | ||
90 | spin_unlock_bh(&priv->tx.tx_lock); | ||
91 | |||
92 | return slot; | ||
93 | } | ||
94 | |||
95 | void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot) | ||
96 | { | ||
97 | spin_lock_bh(&priv->tx.tx_lock); | ||
98 | __clear_bit(slot, priv->tx.tx_slot); | ||
99 | spin_unlock_bh(&priv->tx.tx_lock); | ||
100 | } | ||
101 | |||
102 | static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, | ||
103 | u16 qnum) | ||
104 | { | ||
105 | enum htc_endpoint_id epid; | ||
106 | |||
107 | switch (qnum) { | ||
108 | case 0: | ||
109 | TX_QSTAT_INC(WME_AC_VO); | ||
110 | epid = priv->data_vo_ep; | ||
111 | break; | ||
112 | case 1: | ||
113 | TX_QSTAT_INC(WME_AC_VI); | ||
114 | epid = priv->data_vi_ep; | ||
115 | break; | ||
116 | case 2: | ||
117 | TX_QSTAT_INC(WME_AC_BE); | ||
118 | epid = priv->data_be_ep; | ||
119 | break; | ||
120 | case 3: | ||
121 | default: | ||
122 | TX_QSTAT_INC(WME_AC_BK); | ||
123 | epid = priv->data_bk_ep; | ||
124 | break; | ||
125 | } | ||
126 | |||
127 | return epid; | ||
128 | } | ||
129 | |||
130 | static inline struct sk_buff_head* | ||
131 | get_htc_epid_queue(struct ath9k_htc_priv *priv, u8 epid) | ||
132 | { | ||
133 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
134 | struct sk_buff_head *epid_queue = NULL; | ||
135 | |||
136 | if (epid == priv->mgmt_ep) | ||
137 | epid_queue = &priv->tx.mgmt_ep_queue; | ||
138 | else if (epid == priv->cab_ep) | ||
139 | epid_queue = &priv->tx.cab_ep_queue; | ||
140 | else if (epid == priv->data_be_ep) | ||
141 | epid_queue = &priv->tx.data_be_queue; | ||
142 | else if (epid == priv->data_bk_ep) | ||
143 | epid_queue = &priv->tx.data_bk_queue; | ||
144 | else if (epid == priv->data_vi_ep) | ||
145 | epid_queue = &priv->tx.data_vi_queue; | ||
146 | else if (epid == priv->data_vo_ep) | ||
147 | epid_queue = &priv->tx.data_vo_queue; | ||
148 | else | ||
149 | ath_err(common, "Invalid EPID: %d\n", epid); | ||
150 | |||
151 | return epid_queue; | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * Removes the driver header and returns the TX slot number | ||
156 | */ | ||
157 | static inline int strip_drv_header(struct ath9k_htc_priv *priv, | ||
158 | struct sk_buff *skb) | ||
159 | { | ||
160 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
161 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
162 | int slot; | ||
163 | |||
164 | tx_ctl = HTC_SKB_CB(skb); | ||
165 | |||
166 | if (tx_ctl->epid == priv->mgmt_ep) { | ||
167 | struct tx_mgmt_hdr *tx_mhdr = | ||
168 | (struct tx_mgmt_hdr *)skb->data; | ||
169 | slot = tx_mhdr->cookie; | ||
170 | skb_pull(skb, sizeof(struct tx_mgmt_hdr)); | ||
171 | } else if ((tx_ctl->epid == priv->data_bk_ep) || | ||
172 | (tx_ctl->epid == priv->data_be_ep) || | ||
173 | (tx_ctl->epid == priv->data_vi_ep) || | ||
174 | (tx_ctl->epid == priv->data_vo_ep) || | ||
175 | (tx_ctl->epid == priv->cab_ep)) { | ||
176 | struct tx_frame_hdr *tx_fhdr = | ||
177 | (struct tx_frame_hdr *)skb->data; | ||
178 | slot = tx_fhdr->cookie; | ||
179 | skb_pull(skb, sizeof(struct tx_frame_hdr)); | ||
180 | } else { | ||
181 | ath_err(common, "Unsupported EPID: %d\n", tx_ctl->epid); | ||
182 | slot = -EINVAL; | ||
183 | } | ||
184 | |||
185 | return slot; | ||
186 | } | ||
187 | |||
56 | int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, | 188 | int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, |
57 | struct ath9k_tx_queue_info *qinfo) | 189 | struct ath9k_tx_queue_info *qinfo) |
58 | { | 190 | { |
@@ -79,23 +211,140 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, | |||
79 | return error; | 211 | return error; |
80 | } | 212 | } |
81 | 213 | ||
82 | int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) | 214 | static void ath9k_htc_tx_mgmt(struct ath9k_htc_priv *priv, |
215 | struct ath9k_htc_vif *avp, | ||
216 | struct sk_buff *skb, | ||
217 | u8 sta_idx, u8 vif_idx, u8 slot) | ||
218 | { | ||
219 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
220 | struct ieee80211_mgmt *mgmt; | ||
221 | struct ieee80211_hdr *hdr; | ||
222 | struct tx_mgmt_hdr mgmt_hdr; | ||
223 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
224 | u8 *tx_fhdr; | ||
225 | |||
226 | tx_ctl = HTC_SKB_CB(skb); | ||
227 | hdr = (struct ieee80211_hdr *) skb->data; | ||
228 | |||
229 | memset(tx_ctl, 0, sizeof(*tx_ctl)); | ||
230 | memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); | ||
231 | |||
232 | /* | ||
233 | * Set the TSF adjust value for probe response | ||
234 | * frame also. | ||
235 | */ | ||
236 | if (avp && unlikely(ieee80211_is_probe_resp(hdr->frame_control))) { | ||
237 | mgmt = (struct ieee80211_mgmt *)skb->data; | ||
238 | mgmt->u.probe_resp.timestamp = avp->tsfadjust; | ||
239 | } | ||
240 | |||
241 | tx_ctl->type = ATH9K_HTC_MGMT; | ||
242 | |||
243 | mgmt_hdr.node_idx = sta_idx; | ||
244 | mgmt_hdr.vif_idx = vif_idx; | ||
245 | mgmt_hdr.tidno = 0; | ||
246 | mgmt_hdr.flags = 0; | ||
247 | mgmt_hdr.cookie = slot; | ||
248 | |||
249 | mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); | ||
250 | if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) | ||
251 | mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; | ||
252 | else | ||
253 | mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx; | ||
254 | |||
255 | tx_fhdr = skb_push(skb, sizeof(mgmt_hdr)); | ||
256 | memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); | ||
257 | tx_ctl->epid = priv->mgmt_ep; | ||
258 | } | ||
259 | |||
260 | static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv, | ||
261 | struct ieee80211_vif *vif, | ||
262 | struct sk_buff *skb, | ||
263 | u8 sta_idx, u8 vif_idx, u8 slot, | ||
264 | bool is_cab) | ||
265 | { | ||
266 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
267 | struct ieee80211_hdr *hdr; | ||
268 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
269 | struct tx_frame_hdr tx_hdr; | ||
270 | u32 flags = 0; | ||
271 | u8 *qc, *tx_fhdr; | ||
272 | u16 qnum; | ||
273 | |||
274 | tx_ctl = HTC_SKB_CB(skb); | ||
275 | hdr = (struct ieee80211_hdr *) skb->data; | ||
276 | |||
277 | memset(tx_ctl, 0, sizeof(*tx_ctl)); | ||
278 | memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); | ||
279 | |||
280 | tx_hdr.node_idx = sta_idx; | ||
281 | tx_hdr.vif_idx = vif_idx; | ||
282 | tx_hdr.cookie = slot; | ||
283 | |||
284 | /* | ||
285 | * This is a bit redundant but it helps to get | ||
286 | * the per-packet index quickly when draining the | ||
287 | * TX queue in the HIF layer. Otherwise we would | ||
288 | * have to parse the packet contents ... | ||
289 | */ | ||
290 | tx_ctl->sta_idx = sta_idx; | ||
291 | |||
292 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
293 | tx_ctl->type = ATH9K_HTC_AMPDU; | ||
294 | tx_hdr.data_type = ATH9K_HTC_AMPDU; | ||
295 | } else { | ||
296 | tx_ctl->type = ATH9K_HTC_NORMAL; | ||
297 | tx_hdr.data_type = ATH9K_HTC_NORMAL; | ||
298 | } | ||
299 | |||
300 | if (ieee80211_is_data_qos(hdr->frame_control)) { | ||
301 | qc = ieee80211_get_qos_ctl(hdr); | ||
302 | tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
303 | } | ||
304 | |||
305 | /* Check for RTS protection */ | ||
306 | if (priv->hw->wiphy->rts_threshold != (u32) -1) | ||
307 | if (skb->len > priv->hw->wiphy->rts_threshold) | ||
308 | flags |= ATH9K_HTC_TX_RTSCTS; | ||
309 | |||
310 | /* CTS-to-self */ | ||
311 | if (!(flags & ATH9K_HTC_TX_RTSCTS) && | ||
312 | (vif && vif->bss_conf.use_cts_prot)) | ||
313 | flags |= ATH9K_HTC_TX_CTSONLY; | ||
314 | |||
315 | tx_hdr.flags = cpu_to_be32(flags); | ||
316 | tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); | ||
317 | if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) | ||
318 | tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; | ||
319 | else | ||
320 | tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx; | ||
321 | |||
322 | tx_fhdr = skb_push(skb, sizeof(tx_hdr)); | ||
323 | memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); | ||
324 | |||
325 | if (is_cab) { | ||
326 | CAB_STAT_INC; | ||
327 | tx_ctl->epid = priv->cab_ep; | ||
328 | return; | ||
329 | } | ||
330 | |||
331 | qnum = skb_get_queue_mapping(skb); | ||
332 | tx_ctl->epid = get_htc_epid(priv, qnum); | ||
333 | } | ||
334 | |||
335 | int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, | ||
336 | struct sk_buff *skb, | ||
337 | u8 slot, bool is_cab) | ||
83 | { | 338 | { |
84 | struct ieee80211_hdr *hdr; | 339 | struct ieee80211_hdr *hdr; |
85 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 340 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
86 | struct ieee80211_sta *sta = tx_info->control.sta; | 341 | struct ieee80211_sta *sta = tx_info->control.sta; |
87 | struct ieee80211_vif *vif = tx_info->control.vif; | 342 | struct ieee80211_vif *vif = tx_info->control.vif; |
88 | struct ath9k_htc_sta *ista; | 343 | struct ath9k_htc_sta *ista; |
89 | struct ath9k_htc_vif *avp; | 344 | struct ath9k_htc_vif *avp = NULL; |
90 | struct ath9k_htc_tx_ctl tx_ctl; | ||
91 | enum htc_endpoint_id epid; | ||
92 | u16 qnum; | ||
93 | __le16 fc; | ||
94 | u8 *tx_fhdr; | ||
95 | u8 sta_idx, vif_idx; | 345 | u8 sta_idx, vif_idx; |
96 | 346 | ||
97 | hdr = (struct ieee80211_hdr *) skb->data; | 347 | hdr = (struct ieee80211_hdr *) skb->data; |
98 | fc = hdr->frame_control; | ||
99 | 348 | ||
100 | /* | 349 | /* |
101 | * Find out on which interface this packet has to be | 350 | * Find out on which interface this packet has to be |
@@ -124,218 +373,430 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) | |||
124 | sta_idx = priv->vif_sta_pos[vif_idx]; | 373 | sta_idx = priv->vif_sta_pos[vif_idx]; |
125 | } | 374 | } |
126 | 375 | ||
127 | memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); | 376 | if (ieee80211_is_data(hdr->frame_control)) |
377 | ath9k_htc_tx_data(priv, vif, skb, | ||
378 | sta_idx, vif_idx, slot, is_cab); | ||
379 | else | ||
380 | ath9k_htc_tx_mgmt(priv, avp, skb, | ||
381 | sta_idx, vif_idx, slot); | ||
128 | 382 | ||
129 | if (ieee80211_is_data(fc)) { | ||
130 | struct tx_frame_hdr tx_hdr; | ||
131 | u32 flags = 0; | ||
132 | u8 *qc; | ||
133 | 383 | ||
134 | memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); | 384 | return htc_send(priv->htc, skb); |
385 | } | ||
135 | 386 | ||
136 | tx_hdr.node_idx = sta_idx; | 387 | static inline bool __ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, |
137 | tx_hdr.vif_idx = vif_idx; | 388 | struct ath9k_htc_sta *ista, u8 tid) |
389 | { | ||
390 | bool ret = false; | ||
138 | 391 | ||
139 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | 392 | spin_lock_bh(&priv->tx.tx_lock); |
140 | tx_ctl.type = ATH9K_HTC_AMPDU; | 393 | if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP)) |
141 | tx_hdr.data_type = ATH9K_HTC_AMPDU; | 394 | ret = true; |
142 | } else { | 395 | spin_unlock_bh(&priv->tx.tx_lock); |
143 | tx_ctl.type = ATH9K_HTC_NORMAL; | 396 | |
144 | tx_hdr.data_type = ATH9K_HTC_NORMAL; | 397 | return ret; |
145 | } | 398 | } |
399 | |||
400 | static void ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, | ||
401 | struct ieee80211_vif *vif, | ||
402 | struct sk_buff *skb) | ||
403 | { | ||
404 | struct ieee80211_sta *sta; | ||
405 | struct ieee80211_hdr *hdr; | ||
406 | __le16 fc; | ||
407 | |||
408 | hdr = (struct ieee80211_hdr *) skb->data; | ||
409 | fc = hdr->frame_control; | ||
410 | |||
411 | rcu_read_lock(); | ||
412 | |||
413 | sta = ieee80211_find_sta(vif, hdr->addr1); | ||
414 | if (!sta) { | ||
415 | rcu_read_unlock(); | ||
416 | return; | ||
417 | } | ||
146 | 418 | ||
419 | if (sta && conf_is_ht(&priv->hw->conf) && | ||
420 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { | ||
147 | if (ieee80211_is_data_qos(fc)) { | 421 | if (ieee80211_is_data_qos(fc)) { |
422 | u8 *qc, tid; | ||
423 | struct ath9k_htc_sta *ista; | ||
424 | |||
148 | qc = ieee80211_get_qos_ctl(hdr); | 425 | qc = ieee80211_get_qos_ctl(hdr); |
149 | tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | 426 | tid = qc[0] & 0xf; |
427 | ista = (struct ath9k_htc_sta *)sta->drv_priv; | ||
428 | if (__ath9k_htc_check_tx_aggr(priv, ista, tid)) { | ||
429 | ieee80211_start_tx_ba_session(sta, tid, 0); | ||
430 | spin_lock_bh(&priv->tx.tx_lock); | ||
431 | ista->tid_state[tid] = AGGR_PROGRESS; | ||
432 | spin_unlock_bh(&priv->tx.tx_lock); | ||
433 | } | ||
150 | } | 434 | } |
435 | } | ||
151 | 436 | ||
152 | /* Check for RTS protection */ | 437 | rcu_read_unlock(); |
153 | if (priv->hw->wiphy->rts_threshold != (u32) -1) | 438 | } |
154 | if (skb->len > priv->hw->wiphy->rts_threshold) | ||
155 | flags |= ATH9K_HTC_TX_RTSCTS; | ||
156 | 439 | ||
157 | /* CTS-to-self */ | 440 | static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, |
158 | if (!(flags & ATH9K_HTC_TX_RTSCTS) && | 441 | struct sk_buff *skb, |
159 | (vif && vif->bss_conf.use_cts_prot)) | 442 | struct __wmi_event_txstatus *txs) |
160 | flags |= ATH9K_HTC_TX_CTSONLY; | 443 | { |
444 | struct ieee80211_vif *vif; | ||
445 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
446 | struct ieee80211_tx_info *tx_info; | ||
447 | struct ieee80211_tx_rate *rate; | ||
448 | struct ieee80211_conf *cur_conf = &priv->hw->conf; | ||
449 | bool txok; | ||
450 | int slot; | ||
161 | 451 | ||
162 | tx_hdr.flags = cpu_to_be32(flags); | 452 | slot = strip_drv_header(priv, skb); |
163 | tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); | 453 | if (slot < 0) { |
164 | if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) | 454 | dev_kfree_skb_any(skb); |
165 | tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; | 455 | return; |
166 | else | 456 | } |
167 | tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx; | ||
168 | 457 | ||
169 | tx_fhdr = skb_push(skb, sizeof(tx_hdr)); | 458 | tx_ctl = HTC_SKB_CB(skb); |
170 | memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); | 459 | txok = tx_ctl->txok; |
460 | tx_info = IEEE80211_SKB_CB(skb); | ||
461 | vif = tx_info->control.vif; | ||
462 | rate = &tx_info->status.rates[0]; | ||
171 | 463 | ||
172 | qnum = skb_get_queue_mapping(skb); | 464 | memset(&tx_info->status, 0, sizeof(tx_info->status)); |
173 | 465 | ||
174 | switch (qnum) { | 466 | /* |
175 | case 0: | 467 | * URB submission failed for this frame, it never reached |
176 | TX_QSTAT_INC(WME_AC_VO); | 468 | * the target. |
177 | epid = priv->data_vo_ep; | 469 | */ |
178 | break; | 470 | if (!txok || !vif || !txs) |
179 | case 1: | 471 | goto send_mac80211; |
180 | TX_QSTAT_INC(WME_AC_VI); | 472 | |
181 | epid = priv->data_vi_ep; | 473 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_ACK) |
182 | break; | 474 | tx_info->flags |= IEEE80211_TX_STAT_ACK; |
183 | case 2: | ||
184 | TX_QSTAT_INC(WME_AC_BE); | ||
185 | epid = priv->data_be_ep; | ||
186 | break; | ||
187 | case 3: | ||
188 | default: | ||
189 | TX_QSTAT_INC(WME_AC_BK); | ||
190 | epid = priv->data_bk_ep; | ||
191 | break; | ||
192 | } | ||
193 | } else { | ||
194 | struct tx_mgmt_hdr mgmt_hdr; | ||
195 | 475 | ||
196 | memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); | 476 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_FILT) |
477 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | ||
197 | 478 | ||
198 | tx_ctl.type = ATH9K_HTC_NORMAL; | 479 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_RTC_CTS) |
480 | rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; | ||
199 | 481 | ||
200 | mgmt_hdr.node_idx = sta_idx; | 482 | rate->count = 1; |
201 | mgmt_hdr.vif_idx = vif_idx; | 483 | rate->idx = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_RATE); |
202 | mgmt_hdr.tidno = 0; | ||
203 | mgmt_hdr.flags = 0; | ||
204 | 484 | ||
205 | mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); | 485 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_MCS) { |
206 | if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) | 486 | rate->flags |= IEEE80211_TX_RC_MCS; |
207 | mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; | ||
208 | else | ||
209 | mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx; | ||
210 | 487 | ||
211 | tx_fhdr = skb_push(skb, sizeof(mgmt_hdr)); | 488 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_CW40) |
212 | memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); | 489 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; |
213 | epid = priv->mgmt_ep; | 490 | if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI) |
491 | rate->flags |= IEEE80211_TX_RC_SHORT_GI; | ||
492 | } else { | ||
493 | if (cur_conf->channel->band == IEEE80211_BAND_5GHZ) | ||
494 | rate->idx += 4; /* No CCK rates */ | ||
214 | } | 495 | } |
215 | 496 | ||
216 | return htc_send(priv->htc, skb, epid, &tx_ctl); | 497 | ath9k_htc_check_tx_aggr(priv, vif, skb); |
498 | |||
499 | send_mac80211: | ||
500 | spin_lock_bh(&priv->tx.tx_lock); | ||
501 | if (WARN_ON(--priv->tx.queued_cnt < 0)) | ||
502 | priv->tx.queued_cnt = 0; | ||
503 | spin_unlock_bh(&priv->tx.tx_lock); | ||
504 | |||
505 | ath9k_htc_tx_clear_slot(priv, slot); | ||
506 | |||
507 | /* Send status to mac80211 */ | ||
508 | ieee80211_tx_status(priv->hw, skb); | ||
217 | } | 509 | } |
218 | 510 | ||
219 | static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, | 511 | static inline void ath9k_htc_tx_drainq(struct ath9k_htc_priv *priv, |
220 | struct ath9k_htc_sta *ista, u8 tid) | 512 | struct sk_buff_head *queue) |
221 | { | 513 | { |
222 | bool ret = false; | 514 | struct sk_buff *skb; |
223 | 515 | ||
224 | spin_lock_bh(&priv->tx_lock); | 516 | while ((skb = skb_dequeue(queue)) != NULL) { |
225 | if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP)) | 517 | ath9k_htc_tx_process(priv, skb, NULL); |
226 | ret = true; | 518 | } |
227 | spin_unlock_bh(&priv->tx_lock); | 519 | } |
228 | 520 | ||
229 | return ret; | 521 | void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv) |
522 | { | ||
523 | struct ath9k_htc_tx_event *event, *tmp; | ||
524 | |||
525 | spin_lock_bh(&priv->tx.tx_lock); | ||
526 | priv->tx.flags |= ATH9K_HTC_OP_TX_DRAIN; | ||
527 | spin_unlock_bh(&priv->tx.tx_lock); | ||
528 | |||
529 | /* | ||
530 | * Ensure that all pending TX frames are flushed, | ||
531 | * and that the TX completion/failed tasklets is killed. | ||
532 | */ | ||
533 | htc_stop(priv->htc); | ||
534 | tasklet_kill(&priv->wmi->wmi_event_tasklet); | ||
535 | tasklet_kill(&priv->tx_failed_tasklet); | ||
536 | |||
537 | ath9k_htc_tx_drainq(priv, &priv->tx.mgmt_ep_queue); | ||
538 | ath9k_htc_tx_drainq(priv, &priv->tx.cab_ep_queue); | ||
539 | ath9k_htc_tx_drainq(priv, &priv->tx.data_be_queue); | ||
540 | ath9k_htc_tx_drainq(priv, &priv->tx.data_bk_queue); | ||
541 | ath9k_htc_tx_drainq(priv, &priv->tx.data_vi_queue); | ||
542 | ath9k_htc_tx_drainq(priv, &priv->tx.data_vo_queue); | ||
543 | ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed); | ||
544 | |||
545 | /* | ||
546 | * The TX cleanup timer has already been killed. | ||
547 | */ | ||
548 | spin_lock_bh(&priv->wmi->event_lock); | ||
549 | list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) { | ||
550 | list_del(&event->list); | ||
551 | kfree(event); | ||
552 | } | ||
553 | spin_unlock_bh(&priv->wmi->event_lock); | ||
554 | |||
555 | spin_lock_bh(&priv->tx.tx_lock); | ||
556 | priv->tx.flags &= ~ATH9K_HTC_OP_TX_DRAIN; | ||
557 | spin_unlock_bh(&priv->tx.tx_lock); | ||
230 | } | 558 | } |
231 | 559 | ||
232 | void ath9k_tx_tasklet(unsigned long data) | 560 | void ath9k_tx_failed_tasklet(unsigned long data) |
233 | { | 561 | { |
234 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; | 562 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; |
235 | struct ieee80211_vif *vif; | ||
236 | struct ieee80211_sta *sta; | ||
237 | struct ieee80211_hdr *hdr; | ||
238 | struct ieee80211_tx_info *tx_info; | ||
239 | struct sk_buff *skb = NULL; | ||
240 | __le16 fc; | ||
241 | 563 | ||
242 | while ((skb = skb_dequeue(&priv->tx_queue)) != NULL) { | 564 | spin_lock_bh(&priv->tx.tx_lock); |
565 | if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { | ||
566 | spin_unlock_bh(&priv->tx.tx_lock); | ||
567 | return; | ||
568 | } | ||
569 | spin_unlock_bh(&priv->tx.tx_lock); | ||
243 | 570 | ||
244 | hdr = (struct ieee80211_hdr *) skb->data; | 571 | ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed); |
245 | fc = hdr->frame_control; | 572 | } |
246 | tx_info = IEEE80211_SKB_CB(skb); | ||
247 | vif = tx_info->control.vif; | ||
248 | 573 | ||
249 | memset(&tx_info->status, 0, sizeof(tx_info->status)); | 574 | static inline bool check_cookie(struct ath9k_htc_priv *priv, |
575 | struct sk_buff *skb, | ||
576 | u8 cookie, u8 epid) | ||
577 | { | ||
578 | u8 fcookie = 0; | ||
579 | |||
580 | if (epid == priv->mgmt_ep) { | ||
581 | struct tx_mgmt_hdr *hdr; | ||
582 | hdr = (struct tx_mgmt_hdr *) skb->data; | ||
583 | fcookie = hdr->cookie; | ||
584 | } else if ((epid == priv->data_bk_ep) || | ||
585 | (epid == priv->data_be_ep) || | ||
586 | (epid == priv->data_vi_ep) || | ||
587 | (epid == priv->data_vo_ep) || | ||
588 | (epid == priv->cab_ep)) { | ||
589 | struct tx_frame_hdr *hdr; | ||
590 | hdr = (struct tx_frame_hdr *) skb->data; | ||
591 | fcookie = hdr->cookie; | ||
592 | } | ||
250 | 593 | ||
251 | if (!vif) | 594 | if (fcookie == cookie) |
252 | goto send_mac80211; | 595 | return true; |
253 | 596 | ||
254 | rcu_read_lock(); | 597 | return false; |
598 | } | ||
255 | 599 | ||
256 | sta = ieee80211_find_sta(vif, hdr->addr1); | 600 | static struct sk_buff* ath9k_htc_tx_get_packet(struct ath9k_htc_priv *priv, |
257 | if (!sta) { | 601 | struct __wmi_event_txstatus *txs) |
258 | rcu_read_unlock(); | 602 | { |
259 | ieee80211_tx_status(priv->hw, skb); | 603 | struct ath_common *common = ath9k_hw_common(priv->ah); |
260 | continue; | 604 | struct sk_buff_head *epid_queue; |
605 | struct sk_buff *skb, *tmp; | ||
606 | unsigned long flags; | ||
607 | u8 epid = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_EPID); | ||
608 | |||
609 | epid_queue = get_htc_epid_queue(priv, epid); | ||
610 | if (!epid_queue) | ||
611 | return NULL; | ||
612 | |||
613 | spin_lock_irqsave(&epid_queue->lock, flags); | ||
614 | skb_queue_walk_safe(epid_queue, skb, tmp) { | ||
615 | if (check_cookie(priv, skb, txs->cookie, epid)) { | ||
616 | __skb_unlink(skb, epid_queue); | ||
617 | spin_unlock_irqrestore(&epid_queue->lock, flags); | ||
618 | return skb; | ||
261 | } | 619 | } |
620 | } | ||
621 | spin_unlock_irqrestore(&epid_queue->lock, flags); | ||
622 | |||
623 | ath_dbg(common, ATH_DBG_XMIT, | ||
624 | "No matching packet for cookie: %d, epid: %d\n", | ||
625 | txs->cookie, epid); | ||
262 | 626 | ||
263 | /* Check if we need to start aggregation */ | 627 | return NULL; |
628 | } | ||
264 | 629 | ||
265 | if (sta && conf_is_ht(&priv->hw->conf) && | 630 | void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event) |
266 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { | 631 | { |
267 | if (ieee80211_is_data_qos(fc)) { | 632 | struct wmi_event_txstatus *txs = (struct wmi_event_txstatus *)wmi_event; |
268 | u8 *qc, tid; | 633 | struct __wmi_event_txstatus *__txs; |
269 | struct ath9k_htc_sta *ista; | 634 | struct sk_buff *skb; |
635 | struct ath9k_htc_tx_event *tx_pend; | ||
636 | int i; | ||
270 | 637 | ||
271 | qc = ieee80211_get_qos_ctl(hdr); | 638 | for (i = 0; i < txs->cnt; i++) { |
272 | tid = qc[0] & 0xf; | 639 | WARN_ON(txs->cnt > HTC_MAX_TX_STATUS); |
273 | ista = (struct ath9k_htc_sta *)sta->drv_priv; | ||
274 | 640 | ||
275 | if (ath9k_htc_check_tx_aggr(priv, ista, tid)) { | 641 | __txs = &txs->txstatus[i]; |
276 | ieee80211_start_tx_ba_session(sta, tid, 0); | ||
277 | spin_lock_bh(&priv->tx_lock); | ||
278 | ista->tid_state[tid] = AGGR_PROGRESS; | ||
279 | spin_unlock_bh(&priv->tx_lock); | ||
280 | } | ||
281 | } | ||
282 | } | ||
283 | 642 | ||
284 | rcu_read_unlock(); | 643 | skb = ath9k_htc_tx_get_packet(priv, __txs); |
644 | if (!skb) { | ||
645 | /* | ||
646 | * Store this event, so that the TX cleanup | ||
647 | * routine can check later for the needed packet. | ||
648 | */ | ||
649 | tx_pend = kzalloc(sizeof(struct ath9k_htc_tx_event), | ||
650 | GFP_ATOMIC); | ||
651 | if (!tx_pend) | ||
652 | continue; | ||
653 | |||
654 | memcpy(&tx_pend->txs, __txs, | ||
655 | sizeof(struct __wmi_event_txstatus)); | ||
656 | |||
657 | spin_lock(&priv->wmi->event_lock); | ||
658 | list_add_tail(&tx_pend->list, | ||
659 | &priv->wmi->pending_tx_events); | ||
660 | spin_unlock(&priv->wmi->event_lock); | ||
285 | 661 | ||
286 | send_mac80211: | 662 | continue; |
287 | /* Send status to mac80211 */ | 663 | } |
288 | ieee80211_tx_status(priv->hw, skb); | 664 | |
665 | ath9k_htc_tx_process(priv, skb, __txs); | ||
289 | } | 666 | } |
290 | 667 | ||
291 | /* Wake TX queues if needed */ | 668 | /* Wake TX queues if needed */ |
292 | spin_lock_bh(&priv->tx_lock); | 669 | ath9k_htc_check_wake_queues(priv); |
293 | if (priv->tx_queues_stop) { | ||
294 | priv->tx_queues_stop = false; | ||
295 | spin_unlock_bh(&priv->tx_lock); | ||
296 | ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
297 | "Waking up TX queues\n"); | ||
298 | ieee80211_wake_queues(priv->hw); | ||
299 | return; | ||
300 | } | ||
301 | spin_unlock_bh(&priv->tx_lock); | ||
302 | } | 670 | } |
303 | 671 | ||
304 | void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, | 672 | void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, |
305 | enum htc_endpoint_id ep_id, bool txok) | 673 | enum htc_endpoint_id ep_id, bool txok) |
306 | { | 674 | { |
307 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; | 675 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; |
308 | struct ath_common *common = ath9k_hw_common(priv->ah); | 676 | struct ath9k_htc_tx_ctl *tx_ctl; |
309 | struct ieee80211_tx_info *tx_info; | 677 | struct sk_buff_head *epid_queue; |
310 | 678 | ||
311 | if (!skb) | 679 | tx_ctl = HTC_SKB_CB(skb); |
680 | tx_ctl->txok = txok; | ||
681 | tx_ctl->timestamp = jiffies; | ||
682 | |||
683 | if (!txok) { | ||
684 | skb_queue_tail(&priv->tx.tx_failed, skb); | ||
685 | tasklet_schedule(&priv->tx_failed_tasklet); | ||
312 | return; | 686 | return; |
687 | } | ||
313 | 688 | ||
314 | if (ep_id == priv->mgmt_ep) { | 689 | epid_queue = get_htc_epid_queue(priv, ep_id); |
315 | skb_pull(skb, sizeof(struct tx_mgmt_hdr)); | 690 | if (!epid_queue) { |
316 | } else if ((ep_id == priv->data_bk_ep) || | ||
317 | (ep_id == priv->data_be_ep) || | ||
318 | (ep_id == priv->data_vi_ep) || | ||
319 | (ep_id == priv->data_vo_ep)) { | ||
320 | skb_pull(skb, sizeof(struct tx_frame_hdr)); | ||
321 | } else { | ||
322 | ath_err(common, "Unsupported TX EPID: %d\n", ep_id); | ||
323 | dev_kfree_skb_any(skb); | 691 | dev_kfree_skb_any(skb); |
324 | return; | 692 | return; |
325 | } | 693 | } |
326 | 694 | ||
327 | tx_info = IEEE80211_SKB_CB(skb); | 695 | skb_queue_tail(epid_queue, skb); |
696 | } | ||
328 | 697 | ||
329 | if (txok) | 698 | static inline bool check_packet(struct ath9k_htc_priv *priv, struct sk_buff *skb) |
330 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 699 | { |
700 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
701 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
331 | 702 | ||
332 | skb_queue_tail(&priv->tx_queue, skb); | 703 | tx_ctl = HTC_SKB_CB(skb); |
333 | tasklet_schedule(&priv->tx_tasklet); | 704 | |
705 | if (time_after(jiffies, | ||
706 | tx_ctl->timestamp + | ||
707 | msecs_to_jiffies(ATH9K_HTC_TX_TIMEOUT_INTERVAL))) { | ||
708 | ath_dbg(common, ATH_DBG_XMIT, | ||
709 | "Dropping a packet due to TX timeout\n"); | ||
710 | return true; | ||
711 | } | ||
712 | |||
713 | return false; | ||
714 | } | ||
715 | |||
716 | static void ath9k_htc_tx_cleanup_queue(struct ath9k_htc_priv *priv, | ||
717 | struct sk_buff_head *epid_queue) | ||
718 | { | ||
719 | bool process = false; | ||
720 | unsigned long flags; | ||
721 | struct sk_buff *skb, *tmp; | ||
722 | struct sk_buff_head queue; | ||
723 | |||
724 | skb_queue_head_init(&queue); | ||
725 | |||
726 | spin_lock_irqsave(&epid_queue->lock, flags); | ||
727 | skb_queue_walk_safe(epid_queue, skb, tmp) { | ||
728 | if (check_packet(priv, skb)) { | ||
729 | __skb_unlink(skb, epid_queue); | ||
730 | __skb_queue_tail(&queue, skb); | ||
731 | process = true; | ||
732 | } | ||
733 | } | ||
734 | spin_unlock_irqrestore(&epid_queue->lock, flags); | ||
735 | |||
736 | if (process) { | ||
737 | skb_queue_walk_safe(&queue, skb, tmp) { | ||
738 | __skb_unlink(skb, &queue); | ||
739 | ath9k_htc_tx_process(priv, skb, NULL); | ||
740 | } | ||
741 | } | ||
742 | } | ||
743 | |||
744 | void ath9k_htc_tx_cleanup_timer(unsigned long data) | ||
745 | { | ||
746 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) data; | ||
747 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
748 | struct ath9k_htc_tx_event *event, *tmp; | ||
749 | struct sk_buff *skb; | ||
750 | |||
751 | spin_lock(&priv->wmi->event_lock); | ||
752 | list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) { | ||
753 | |||
754 | skb = ath9k_htc_tx_get_packet(priv, &event->txs); | ||
755 | if (skb) { | ||
756 | ath_dbg(common, ATH_DBG_XMIT, | ||
757 | "Found packet for cookie: %d, epid: %d\n", | ||
758 | event->txs.cookie, | ||
759 | MS(event->txs.ts_rate, ATH9K_HTC_TXSTAT_EPID)); | ||
760 | |||
761 | ath9k_htc_tx_process(priv, skb, &event->txs); | ||
762 | list_del(&event->list); | ||
763 | kfree(event); | ||
764 | continue; | ||
765 | } | ||
766 | |||
767 | if (++event->count >= ATH9K_HTC_TX_TIMEOUT_COUNT) { | ||
768 | list_del(&event->list); | ||
769 | kfree(event); | ||
770 | } | ||
771 | } | ||
772 | spin_unlock(&priv->wmi->event_lock); | ||
773 | |||
774 | /* | ||
775 | * Check if status-pending packets have to be cleaned up. | ||
776 | */ | ||
777 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.mgmt_ep_queue); | ||
778 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.cab_ep_queue); | ||
779 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_be_queue); | ||
780 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_bk_queue); | ||
781 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vi_queue); | ||
782 | ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vo_queue); | ||
783 | |||
784 | /* Wake TX queues if needed */ | ||
785 | ath9k_htc_check_wake_queues(priv); | ||
786 | |||
787 | mod_timer(&priv->tx.cleanup_timer, | ||
788 | jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); | ||
334 | } | 789 | } |
335 | 790 | ||
336 | int ath9k_tx_init(struct ath9k_htc_priv *priv) | 791 | int ath9k_tx_init(struct ath9k_htc_priv *priv) |
337 | { | 792 | { |
338 | skb_queue_head_init(&priv->tx_queue); | 793 | skb_queue_head_init(&priv->tx.mgmt_ep_queue); |
794 | skb_queue_head_init(&priv->tx.cab_ep_queue); | ||
795 | skb_queue_head_init(&priv->tx.data_be_queue); | ||
796 | skb_queue_head_init(&priv->tx.data_bk_queue); | ||
797 | skb_queue_head_init(&priv->tx.data_vi_queue); | ||
798 | skb_queue_head_init(&priv->tx.data_vo_queue); | ||
799 | skb_queue_head_init(&priv->tx.tx_failed); | ||
339 | return 0; | 800 | return 0; |
340 | } | 801 | } |
341 | 802 | ||
@@ -507,8 +968,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
507 | int last_rssi = ATH_RSSI_DUMMY_MARKER; | 968 | int last_rssi = ATH_RSSI_DUMMY_MARKER; |
508 | __le16 fc; | 969 | __le16 fc; |
509 | 970 | ||
510 | if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) { | 971 | if (skb->len < HTC_RX_FRAME_HEADER_SIZE) { |
511 | ath_err(common, "Corrupted RX frame, dropping\n"); | 972 | ath_err(common, "Corrupted RX frame, dropping (len: %d)\n", |
973 | skb->len); | ||
512 | goto rx_next; | 974 | goto rx_next; |
513 | } | 975 | } |
514 | 976 | ||
@@ -522,6 +984,8 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
522 | goto rx_next; | 984 | goto rx_next; |
523 | } | 985 | } |
524 | 986 | ||
987 | ath9k_htc_err_stat_rx(priv, rxstatus); | ||
988 | |||
525 | /* Get the RX status information */ | 989 | /* Get the RX status information */ |
526 | memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); | 990 | memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); |
527 | skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); | 991 | skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 62e139a30a7..cee970fdf65 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c | |||
@@ -17,8 +17,8 @@ | |||
17 | #include "htc.h" | 17 | #include "htc.h" |
18 | 18 | ||
19 | static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, | 19 | static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, |
20 | u16 len, u8 flags, u8 epid, | 20 | u16 len, u8 flags, u8 epid) |
21 | struct ath9k_htc_tx_ctl *tx_ctl) | 21 | |
22 | { | 22 | { |
23 | struct htc_frame_hdr *hdr; | 23 | struct htc_frame_hdr *hdr; |
24 | struct htc_endpoint *endpoint = &target->endpoint[epid]; | 24 | struct htc_endpoint *endpoint = &target->endpoint[epid]; |
@@ -30,8 +30,8 @@ static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, | |||
30 | hdr->flags = flags; | 30 | hdr->flags = flags; |
31 | hdr->payload_len = cpu_to_be16(len); | 31 | hdr->payload_len = cpu_to_be16(len); |
32 | 32 | ||
33 | status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb, | 33 | status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb); |
34 | tx_ctl); | 34 | |
35 | return status; | 35 | return status; |
36 | } | 36 | } |
37 | 37 | ||
@@ -162,7 +162,7 @@ static int htc_config_pipe_credits(struct htc_target *target) | |||
162 | 162 | ||
163 | target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS; | 163 | target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS; |
164 | 164 | ||
165 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); | 165 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); |
166 | if (ret) | 166 | if (ret) |
167 | goto err; | 167 | goto err; |
168 | 168 | ||
@@ -197,7 +197,7 @@ static int htc_setup_complete(struct htc_target *target) | |||
197 | 197 | ||
198 | target->htc_flags |= HTC_OP_START_WAIT; | 198 | target->htc_flags |= HTC_OP_START_WAIT; |
199 | 199 | ||
200 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); | 200 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); |
201 | if (ret) | 201 | if (ret) |
202 | goto err; | 202 | goto err; |
203 | 203 | ||
@@ -268,7 +268,7 @@ int htc_connect_service(struct htc_target *target, | |||
268 | conn_msg->dl_pipeid = endpoint->dl_pipeid; | 268 | conn_msg->dl_pipeid = endpoint->dl_pipeid; |
269 | conn_msg->ul_pipeid = endpoint->ul_pipeid; | 269 | conn_msg->ul_pipeid = endpoint->ul_pipeid; |
270 | 270 | ||
271 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); | 271 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); |
272 | if (ret) | 272 | if (ret) |
273 | goto err; | 273 | goto err; |
274 | 274 | ||
@@ -286,35 +286,33 @@ err: | |||
286 | return ret; | 286 | return ret; |
287 | } | 287 | } |
288 | 288 | ||
289 | int htc_send(struct htc_target *target, struct sk_buff *skb, | 289 | int htc_send(struct htc_target *target, struct sk_buff *skb) |
290 | enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl) | ||
291 | { | 290 | { |
292 | return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl); | 291 | struct ath9k_htc_tx_ctl *tx_ctl; |
292 | |||
293 | tx_ctl = HTC_SKB_CB(skb); | ||
294 | return htc_issue_send(target, skb, skb->len, 0, tx_ctl->epid); | ||
293 | } | 295 | } |
294 | 296 | ||
295 | void htc_stop(struct htc_target *target) | 297 | int htc_send_epid(struct htc_target *target, struct sk_buff *skb, |
298 | enum htc_endpoint_id epid) | ||
296 | { | 299 | { |
297 | enum htc_endpoint_id epid; | 300 | return htc_issue_send(target, skb, skb->len, 0, epid); |
298 | struct htc_endpoint *endpoint; | 301 | } |
299 | 302 | ||
300 | for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) { | 303 | void htc_stop(struct htc_target *target) |
301 | endpoint = &target->endpoint[epid]; | 304 | { |
302 | if (endpoint->service_id != 0) | 305 | target->hif->stop(target->hif_dev); |
303 | target->hif->stop(target->hif_dev, endpoint->ul_pipeid); | ||
304 | } | ||
305 | } | 306 | } |
306 | 307 | ||
307 | void htc_start(struct htc_target *target) | 308 | void htc_start(struct htc_target *target) |
308 | { | 309 | { |
309 | enum htc_endpoint_id epid; | 310 | target->hif->start(target->hif_dev); |
310 | struct htc_endpoint *endpoint; | 311 | } |
311 | 312 | ||
312 | for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) { | 313 | void htc_sta_drain(struct htc_target *target, u8 idx) |
313 | endpoint = &target->endpoint[epid]; | 314 | { |
314 | if (endpoint->service_id != 0) | 315 | target->hif->sta_drain(target->hif_dev, idx); |
315 | target->hif->start(target->hif_dev, | ||
316 | endpoint->ul_pipeid); | ||
317 | } | ||
318 | } | 316 | } |
319 | 317 | ||
320 | void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, | 318 | void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index ecd018798c4..91a5305db95 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h | |||
@@ -33,10 +33,10 @@ struct ath9k_htc_hif { | |||
33 | u8 control_dl_pipe; | 33 | u8 control_dl_pipe; |
34 | u8 control_ul_pipe; | 34 | u8 control_ul_pipe; |
35 | 35 | ||
36 | void (*start) (void *hif_handle, u8 pipe); | 36 | void (*start) (void *hif_handle); |
37 | void (*stop) (void *hif_handle, u8 pipe); | 37 | void (*stop) (void *hif_handle); |
38 | int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf, | 38 | void (*sta_drain) (void *hif_handle, u8 idx); |
39 | struct ath9k_htc_tx_ctl *tx_ctl); | 39 | int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf); |
40 | }; | 40 | }; |
41 | 41 | ||
42 | enum htc_endpoint_id { | 42 | enum htc_endpoint_id { |
@@ -83,21 +83,10 @@ struct htc_ep_callbacks { | |||
83 | void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id); | 83 | void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id); |
84 | }; | 84 | }; |
85 | 85 | ||
86 | #define HTC_TX_QUEUE_SIZE 256 | ||
87 | |||
88 | struct htc_txq { | ||
89 | struct sk_buff *buf[HTC_TX_QUEUE_SIZE]; | ||
90 | u32 txqdepth; | ||
91 | u16 txbuf_cnt; | ||
92 | u16 txq_head; | ||
93 | u16 txq_tail; | ||
94 | }; | ||
95 | |||
96 | struct htc_endpoint { | 86 | struct htc_endpoint { |
97 | u16 service_id; | 87 | u16 service_id; |
98 | 88 | ||
99 | struct htc_ep_callbacks ep_callbacks; | 89 | struct htc_ep_callbacks ep_callbacks; |
100 | struct htc_txq htc_txq; | ||
101 | u32 max_txqdepth; | 90 | u32 max_txqdepth; |
102 | int max_msglen; | 91 | int max_msglen; |
103 | 92 | ||
@@ -205,10 +194,12 @@ int htc_init(struct htc_target *target); | |||
205 | int htc_connect_service(struct htc_target *target, | 194 | int htc_connect_service(struct htc_target *target, |
206 | struct htc_service_connreq *service_connreq, | 195 | struct htc_service_connreq *service_connreq, |
207 | enum htc_endpoint_id *conn_rsp_eid); | 196 | enum htc_endpoint_id *conn_rsp_eid); |
208 | int htc_send(struct htc_target *target, struct sk_buff *skb, | 197 | int htc_send(struct htc_target *target, struct sk_buff *skb); |
209 | enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl); | 198 | int htc_send_epid(struct htc_target *target, struct sk_buff *skb, |
199 | enum htc_endpoint_id epid); | ||
210 | void htc_stop(struct htc_target *target); | 200 | void htc_stop(struct htc_target *target); |
211 | void htc_start(struct htc_target *target); | 201 | void htc_start(struct htc_target *target); |
202 | void htc_sta_drain(struct htc_target *target, u8 idx); | ||
212 | 203 | ||
213 | void ath9k_htc_rx_msg(struct htc_target *htc_handle, | 204 | void ath9k_htc_rx_msg(struct htc_target *htc_handle, |
214 | struct sk_buff *skb, u32 len, u8 pipe_id); | 205 | struct sk_buff *skb, u32 len, u8 pipe_id); |
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index c8f254fe0f0..8b8f0445aef 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h | |||
@@ -116,16 +116,21 @@ static inline void ath9k_hw_clr11n_aggr(struct ath_hw *ah, void *ds) | |||
116 | ath9k_hw_ops(ah)->clr11n_aggr(ah, ds); | 116 | ath9k_hw_ops(ah)->clr11n_aggr(ah, ds); |
117 | } | 117 | } |
118 | 118 | ||
119 | static inline void ath9k_hw_set11n_burstduration(struct ath_hw *ah, void *ds, | 119 | static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) |
120 | u32 burstDuration) | ||
121 | { | 120 | { |
122 | ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration); | 121 | ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val); |
123 | } | 122 | } |
124 | 123 | ||
125 | static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, | 124 | static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, |
126 | u32 vmf) | 125 | struct ath_hw_antcomb_conf *antconf) |
127 | { | 126 | { |
128 | ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf); | 127 | ath9k_hw_ops(ah)->antdiv_comb_conf_get(ah, antconf); |
128 | } | ||
129 | |||
130 | static inline void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah, | ||
131 | struct ath_hw_antcomb_conf *antconf) | ||
132 | { | ||
133 | ath9k_hw_ops(ah)->antdiv_comb_conf_set(ah, antconf); | ||
129 | } | 134 | } |
130 | 135 | ||
131 | /* Private hardware call ops */ | 136 | /* Private hardware call ops */ |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index c95bc5cc1a1..b75b5dca4e2 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -130,6 +130,20 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) | |||
130 | } | 130 | } |
131 | EXPORT_SYMBOL(ath9k_hw_wait); | 131 | EXPORT_SYMBOL(ath9k_hw_wait); |
132 | 132 | ||
133 | void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array, | ||
134 | int column, unsigned int *writecnt) | ||
135 | { | ||
136 | int r; | ||
137 | |||
138 | ENABLE_REGWRITE_BUFFER(ah); | ||
139 | for (r = 0; r < array->ia_rows; r++) { | ||
140 | REG_WRITE(ah, INI_RA(array, r, 0), | ||
141 | INI_RA(array, r, column)); | ||
142 | DO_DELAY(*writecnt); | ||
143 | } | ||
144 | REGWRITE_BUFFER_FLUSH(ah); | ||
145 | } | ||
146 | |||
133 | u32 ath9k_hw_reverse_bits(u32 val, u32 n) | 147 | u32 ath9k_hw_reverse_bits(u32 val, u32 n) |
134 | { | 148 | { |
135 | u32 retval; | 149 | u32 retval; |
@@ -142,25 +156,6 @@ u32 ath9k_hw_reverse_bits(u32 val, u32 n) | |||
142 | return retval; | 156 | return retval; |
143 | } | 157 | } |
144 | 158 | ||
145 | bool ath9k_get_channel_edges(struct ath_hw *ah, | ||
146 | u16 flags, u16 *low, | ||
147 | u16 *high) | ||
148 | { | ||
149 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
150 | |||
151 | if (flags & CHANNEL_5GHZ) { | ||
152 | *low = pCap->low_5ghz_chan; | ||
153 | *high = pCap->high_5ghz_chan; | ||
154 | return true; | ||
155 | } | ||
156 | if ((flags & CHANNEL_2GHZ)) { | ||
157 | *low = pCap->low_2ghz_chan; | ||
158 | *high = pCap->high_2ghz_chan; | ||
159 | return true; | ||
160 | } | ||
161 | return false; | ||
162 | } | ||
163 | |||
164 | u16 ath9k_hw_computetxtime(struct ath_hw *ah, | 159 | u16 ath9k_hw_computetxtime(struct ath_hw *ah, |
165 | u8 phy, int kbps, | 160 | u8 phy, int kbps, |
166 | u32 frameLen, u16 rateix, | 161 | u32 frameLen, u16 rateix, |
@@ -252,6 +247,17 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah) | |||
252 | { | 247 | { |
253 | u32 val; | 248 | u32 val; |
254 | 249 | ||
250 | switch (ah->hw_version.devid) { | ||
251 | case AR5416_AR9100_DEVID: | ||
252 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; | ||
253 | break; | ||
254 | case AR9300_DEVID_AR9340: | ||
255 | ah->hw_version.macVersion = AR_SREV_VERSION_9340; | ||
256 | val = REG_READ(ah, AR_SREV); | ||
257 | ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); | ||
258 | return; | ||
259 | } | ||
260 | |||
255 | val = REG_READ(ah, AR_SREV) & AR_SREV_ID; | 261 | val = REG_READ(ah, AR_SREV) & AR_SREV_ID; |
256 | 262 | ||
257 | if (val == 0xFF) { | 263 | if (val == 0xFF) { |
@@ -364,11 +370,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
364 | ah->config.spurchans[i][1] = AR_NO_SPUR; | 370 | ah->config.spurchans[i][1] = AR_NO_SPUR; |
365 | } | 371 | } |
366 | 372 | ||
367 | if (ah->hw_version.devid != AR2427_DEVID_PCIE) | ||
368 | ah->config.ht_enable = 1; | ||
369 | else | ||
370 | ah->config.ht_enable = 0; | ||
371 | |||
372 | /* PAPRD needs some more work to be enabled */ | 373 | /* PAPRD needs some more work to be enabled */ |
373 | ah->config.paprd_disable = 1; | 374 | ah->config.paprd_disable = 1; |
374 | 375 | ||
@@ -410,6 +411,8 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) | |||
410 | ah->sta_id1_defaults = | 411 | ah->sta_id1_defaults = |
411 | AR_STA_ID1_CRPT_MIC_ENABLE | | 412 | AR_STA_ID1_CRPT_MIC_ENABLE | |
412 | AR_STA_ID1_MCAST_KSRCH; | 413 | AR_STA_ID1_MCAST_KSRCH; |
414 | if (AR_SREV_9100(ah)) | ||
415 | ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX; | ||
413 | ah->enable_32kHz_clock = DONT_USE_32KHZ; | 416 | ah->enable_32kHz_clock = DONT_USE_32KHZ; |
414 | ah->slottime = 20; | 417 | ah->slottime = 20; |
415 | ah->globaltxtimeout = (u32) -1; | 418 | ah->globaltxtimeout = (u32) -1; |
@@ -470,7 +473,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah) | |||
470 | return ecode; | 473 | return ecode; |
471 | } | 474 | } |
472 | 475 | ||
473 | if (!AR_SREV_9100(ah)) { | 476 | if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) { |
474 | ath9k_hw_ani_setup(ah); | 477 | ath9k_hw_ani_setup(ah); |
475 | ath9k_hw_ani_init(ah); | 478 | ath9k_hw_ani_init(ah); |
476 | } | 479 | } |
@@ -492,9 +495,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
492 | struct ath_common *common = ath9k_hw_common(ah); | 495 | struct ath_common *common = ath9k_hw_common(ah); |
493 | int r = 0; | 496 | int r = 0; |
494 | 497 | ||
495 | if (ah->hw_version.devid == AR5416_AR9100_DEVID) | ||
496 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; | ||
497 | |||
498 | ath9k_hw_read_revisions(ah); | 498 | ath9k_hw_read_revisions(ah); |
499 | 499 | ||
500 | /* | 500 | /* |
@@ -552,6 +552,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
552 | case AR_SREV_VERSION_9271: | 552 | case AR_SREV_VERSION_9271: |
553 | case AR_SREV_VERSION_9300: | 553 | case AR_SREV_VERSION_9300: |
554 | case AR_SREV_VERSION_9485: | 554 | case AR_SREV_VERSION_9485: |
555 | case AR_SREV_VERSION_9340: | ||
555 | break; | 556 | break; |
556 | default: | 557 | default: |
557 | ath_err(common, | 558 | ath_err(common, |
@@ -560,7 +561,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
560 | return -EOPNOTSUPP; | 561 | return -EOPNOTSUPP; |
561 | } | 562 | } |
562 | 563 | ||
563 | if (AR_SREV_9271(ah) || AR_SREV_9100(ah)) | 564 | if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah)) |
564 | ah->is_pciexpress = false; | 565 | ah->is_pciexpress = false; |
565 | 566 | ||
566 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); | 567 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); |
@@ -629,6 +630,7 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
629 | case AR2427_DEVID_PCIE: | 630 | case AR2427_DEVID_PCIE: |
630 | case AR9300_DEVID_PCIE: | 631 | case AR9300_DEVID_PCIE: |
631 | case AR9300_DEVID_AR9485_PCIE: | 632 | case AR9300_DEVID_AR9485_PCIE: |
633 | case AR9300_DEVID_AR9340: | ||
632 | break; | 634 | break; |
633 | default: | 635 | default: |
634 | if (common->bus_ops->ath_bus_type == ATH_USB) | 636 | if (common->bus_ops->ath_bus_type == ATH_USB) |
@@ -671,48 +673,89 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) | |||
671 | REGWRITE_BUFFER_FLUSH(ah); | 673 | REGWRITE_BUFFER_FLUSH(ah); |
672 | } | 674 | } |
673 | 675 | ||
674 | unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) | 676 | u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) |
675 | { | 677 | { |
676 | REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) & ~(PLL3_DO_MEAS_MASK))); | 678 | REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); |
677 | udelay(100); | 679 | udelay(100); |
678 | REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) | PLL3_DO_MEAS_MASK)); | 680 | REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); |
679 | 681 | ||
680 | while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) | 682 | while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) |
681 | udelay(100); | 683 | udelay(100); |
682 | 684 | ||
683 | return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; | 685 | return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; |
684 | } | 686 | } |
685 | EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); | 687 | EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); |
686 | 688 | ||
687 | #define DPLL2_KD_VAL 0x3D | ||
688 | #define DPLL2_KI_VAL 0x06 | ||
689 | #define DPLL3_PHASE_SHIFT_VAL 0x1 | ||
690 | |||
691 | static void ath9k_hw_init_pll(struct ath_hw *ah, | 689 | static void ath9k_hw_init_pll(struct ath_hw *ah, |
692 | struct ath9k_channel *chan) | 690 | struct ath9k_channel *chan) |
693 | { | 691 | { |
694 | u32 pll; | 692 | u32 pll; |
695 | 693 | ||
696 | if (AR_SREV_9485(ah)) { | 694 | if (AR_SREV_9485(ah)) { |
697 | REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); | ||
698 | REG_WRITE(ah, AR_CH0_DDR_DPLL2, 0x19e82f01); | ||
699 | 695 | ||
700 | REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3, | 696 | /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */ |
701 | AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | 697 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, |
702 | 698 | AR_CH0_BB_DPLL2_PLL_PWD, 0x1); | |
703 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); | 699 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, |
704 | udelay(1000); | 700 | AR_CH0_DPLL2_KD, 0x40); |
701 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
702 | AR_CH0_DPLL2_KI, 0x4); | ||
705 | 703 | ||
706 | REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); | 704 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, |
705 | AR_CH0_BB_DPLL1_REFDIV, 0x5); | ||
706 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, | ||
707 | AR_CH0_BB_DPLL1_NINI, 0x58); | ||
708 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, | ||
709 | AR_CH0_BB_DPLL1_NFRAC, 0x0); | ||
707 | 710 | ||
708 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | 711 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, |
709 | AR_CH0_DPLL2_KD, DPLL2_KD_VAL); | 712 | AR_CH0_BB_DPLL2_OUTDIV, 0x1); |
713 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
714 | AR_CH0_BB_DPLL2_LOCAL_PLL, 0x1); | ||
710 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | 715 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, |
711 | AR_CH0_DPLL2_KI, DPLL2_KI_VAL); | 716 | AR_CH0_BB_DPLL2_EN_NEGTRIG, 0x1); |
712 | 717 | ||
718 | /* program BB PLL phase_shift to 0x6 */ | ||
713 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, | 719 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, |
714 | AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | 720 | AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x6); |
715 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c); | 721 | |
722 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
723 | AR_CH0_BB_DPLL2_PLL_PWD, 0x0); | ||
724 | udelay(1000); | ||
725 | } else if (AR_SREV_9340(ah)) { | ||
726 | u32 regval, pll2_divint, pll2_divfrac, refdiv; | ||
727 | |||
728 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); | ||
729 | udelay(1000); | ||
730 | |||
731 | REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16); | ||
732 | udelay(100); | ||
733 | |||
734 | if (ah->is_clk_25mhz) { | ||
735 | pll2_divint = 0x54; | ||
736 | pll2_divfrac = 0x1eb85; | ||
737 | refdiv = 3; | ||
738 | } else { | ||
739 | pll2_divint = 88; | ||
740 | pll2_divfrac = 0; | ||
741 | refdiv = 5; | ||
742 | } | ||
743 | |||
744 | regval = REG_READ(ah, AR_PHY_PLL_MODE); | ||
745 | regval |= (0x1 << 16); | ||
746 | REG_WRITE(ah, AR_PHY_PLL_MODE, regval); | ||
747 | udelay(100); | ||
748 | |||
749 | REG_WRITE(ah, AR_PHY_PLL_CONTROL, (refdiv << 27) | | ||
750 | (pll2_divint << 18) | pll2_divfrac); | ||
751 | udelay(100); | ||
752 | |||
753 | regval = REG_READ(ah, AR_PHY_PLL_MODE); | ||
754 | regval = (regval & 0x80071fff) | (0x1 << 30) | (0x1 << 13) | | ||
755 | (0x4 << 26) | (0x18 << 19); | ||
756 | REG_WRITE(ah, AR_PHY_PLL_MODE, regval); | ||
757 | REG_WRITE(ah, AR_PHY_PLL_MODE, | ||
758 | REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff); | ||
716 | udelay(1000); | 759 | udelay(1000); |
717 | } | 760 | } |
718 | 761 | ||
@@ -720,6 +763,9 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
720 | 763 | ||
721 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); | 764 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); |
722 | 765 | ||
766 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) | ||
767 | udelay(1000); | ||
768 | |||
723 | /* Switch the core clock for ar9271 to 117Mhz */ | 769 | /* Switch the core clock for ar9271 to 117Mhz */ |
724 | if (AR_SREV_9271(ah)) { | 770 | if (AR_SREV_9271(ah)) { |
725 | udelay(500); | 771 | udelay(500); |
@@ -729,17 +775,34 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
729 | udelay(RTC_PLL_SETTLE_DELAY); | 775 | udelay(RTC_PLL_SETTLE_DELAY); |
730 | 776 | ||
731 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); | 777 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); |
778 | |||
779 | if (AR_SREV_9340(ah)) { | ||
780 | if (ah->is_clk_25mhz) { | ||
781 | REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1); | ||
782 | REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7); | ||
783 | REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae); | ||
784 | } else { | ||
785 | REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1); | ||
786 | REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400); | ||
787 | REG_WRITE(ah, AR_SLP32_INC, 0x0001e800); | ||
788 | } | ||
789 | udelay(100); | ||
790 | } | ||
732 | } | 791 | } |
733 | 792 | ||
734 | static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | 793 | static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, |
735 | enum nl80211_iftype opmode) | 794 | enum nl80211_iftype opmode) |
736 | { | 795 | { |
796 | u32 sync_default = AR_INTR_SYNC_DEFAULT; | ||
737 | u32 imr_reg = AR_IMR_TXERR | | 797 | u32 imr_reg = AR_IMR_TXERR | |
738 | AR_IMR_TXURN | | 798 | AR_IMR_TXURN | |
739 | AR_IMR_RXERR | | 799 | AR_IMR_RXERR | |
740 | AR_IMR_RXORN | | 800 | AR_IMR_RXORN | |
741 | AR_IMR_BCNMISC; | 801 | AR_IMR_BCNMISC; |
742 | 802 | ||
803 | if (AR_SREV_9340(ah)) | ||
804 | sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; | ||
805 | |||
743 | if (AR_SREV_9300_20_OR_LATER(ah)) { | 806 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
744 | imr_reg |= AR_IMR_RXOK_HP; | 807 | imr_reg |= AR_IMR_RXOK_HP; |
745 | if (ah->config.rx_intr_mitigation) | 808 | if (ah->config.rx_intr_mitigation) |
@@ -770,7 +833,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
770 | 833 | ||
771 | if (!AR_SREV_9100(ah)) { | 834 | if (!AR_SREV_9100(ah)) { |
772 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); | 835 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); |
773 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT); | 836 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default); |
774 | REG_WRITE(ah, AR_INTR_SYNC_MASK, 0); | 837 | REG_WRITE(ah, AR_INTR_SYNC_MASK, 0); |
775 | } | 838 | } |
776 | 839 | ||
@@ -830,8 +893,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
830 | ah->misc_mode); | 893 | ah->misc_mode); |
831 | 894 | ||
832 | if (ah->misc_mode != 0) | 895 | if (ah->misc_mode != 0) |
833 | REG_WRITE(ah, AR_PCU_MISC, | 896 | REG_SET_BIT(ah, AR_PCU_MISC, ah->misc_mode); |
834 | REG_READ(ah, AR_PCU_MISC) | ah->misc_mode); | ||
835 | 897 | ||
836 | if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ) | 898 | if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ) |
837 | sifstime = 16; | 899 | sifstime = 16; |
@@ -899,23 +961,19 @@ u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan) | |||
899 | static inline void ath9k_hw_set_dma(struct ath_hw *ah) | 961 | static inline void ath9k_hw_set_dma(struct ath_hw *ah) |
900 | { | 962 | { |
901 | struct ath_common *common = ath9k_hw_common(ah); | 963 | struct ath_common *common = ath9k_hw_common(ah); |
902 | u32 regval; | ||
903 | 964 | ||
904 | ENABLE_REGWRITE_BUFFER(ah); | 965 | ENABLE_REGWRITE_BUFFER(ah); |
905 | 966 | ||
906 | /* | 967 | /* |
907 | * set AHB_MODE not to do cacheline prefetches | 968 | * set AHB_MODE not to do cacheline prefetches |
908 | */ | 969 | */ |
909 | if (!AR_SREV_9300_20_OR_LATER(ah)) { | 970 | if (!AR_SREV_9300_20_OR_LATER(ah)) |
910 | regval = REG_READ(ah, AR_AHB_MODE); | 971 | REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN); |
911 | REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN); | ||
912 | } | ||
913 | 972 | ||
914 | /* | 973 | /* |
915 | * let mac dma reads be in 128 byte chunks | 974 | * let mac dma reads be in 128 byte chunks |
916 | */ | 975 | */ |
917 | regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK; | 976 | REG_RMW(ah, AR_TXCFG, AR_TXCFG_DMASZ_128B, AR_TXCFG_DMASZ_MASK); |
918 | REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B); | ||
919 | 977 | ||
920 | REGWRITE_BUFFER_FLUSH(ah); | 978 | REGWRITE_BUFFER_FLUSH(ah); |
921 | 979 | ||
@@ -932,8 +990,7 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah) | |||
932 | /* | 990 | /* |
933 | * let mac dma writes be in 128 byte chunks | 991 | * let mac dma writes be in 128 byte chunks |
934 | */ | 992 | */ |
935 | regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK; | 993 | REG_RMW(ah, AR_RXCFG, AR_RXCFG_DMASZ_128B, AR_RXCFG_DMASZ_MASK); |
936 | REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B); | ||
937 | 994 | ||
938 | /* | 995 | /* |
939 | * Setup receive FIFO threshold to hold off TX activities | 996 | * Setup receive FIFO threshold to hold off TX activities |
@@ -972,30 +1029,27 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah) | |||
972 | 1029 | ||
973 | static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) | 1030 | static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) |
974 | { | 1031 | { |
975 | u32 val; | 1032 | u32 mask = AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC; |
1033 | u32 set = AR_STA_ID1_KSRCH_MODE; | ||
976 | 1034 | ||
977 | val = REG_READ(ah, AR_STA_ID1); | ||
978 | val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC); | ||
979 | switch (opmode) { | 1035 | switch (opmode) { |
980 | case NL80211_IFTYPE_AP: | ||
981 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP | ||
982 | | AR_STA_ID1_KSRCH_MODE); | ||
983 | REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); | ||
984 | break; | ||
985 | case NL80211_IFTYPE_ADHOC: | 1036 | case NL80211_IFTYPE_ADHOC: |
986 | case NL80211_IFTYPE_MESH_POINT: | 1037 | case NL80211_IFTYPE_MESH_POINT: |
987 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC | 1038 | set |= AR_STA_ID1_ADHOC; |
988 | | AR_STA_ID1_KSRCH_MODE); | ||
989 | REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); | 1039 | REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); |
990 | break; | 1040 | break; |
1041 | case NL80211_IFTYPE_AP: | ||
1042 | set |= AR_STA_ID1_STA_AP; | ||
1043 | /* fall through */ | ||
991 | case NL80211_IFTYPE_STATION: | 1044 | case NL80211_IFTYPE_STATION: |
992 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); | 1045 | REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); |
993 | break; | 1046 | break; |
994 | default: | 1047 | default: |
995 | if (ah->is_monitoring) | 1048 | if (!ah->is_monitoring) |
996 | REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); | 1049 | set = 0; |
997 | break; | 1050 | break; |
998 | } | 1051 | } |
1052 | REG_RMW(ah, AR_STA_ID1, set, mask); | ||
999 | } | 1053 | } |
1000 | 1054 | ||
1001 | void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, | 1055 | void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, |
@@ -1021,10 +1075,8 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
1021 | u32 tmpReg; | 1075 | u32 tmpReg; |
1022 | 1076 | ||
1023 | if (AR_SREV_9100(ah)) { | 1077 | if (AR_SREV_9100(ah)) { |
1024 | u32 val = REG_READ(ah, AR_RTC_DERIVED_CLK); | 1078 | REG_RMW_FIELD(ah, AR_RTC_DERIVED_CLK, |
1025 | val &= ~AR_RTC_DERIVED_CLK_PERIOD; | 1079 | AR_RTC_DERIVED_CLK_PERIOD, 1); |
1026 | val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD); | ||
1027 | REG_WRITE(ah, AR_RTC_DERIVED_CLK, val); | ||
1028 | (void)REG_READ(ah, AR_RTC_DERIVED_CLK); | 1080 | (void)REG_READ(ah, AR_RTC_DERIVED_CLK); |
1029 | } | 1081 | } |
1030 | 1082 | ||
@@ -1212,6 +1264,20 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, | |||
1212 | return true; | 1264 | return true; |
1213 | } | 1265 | } |
1214 | 1266 | ||
1267 | static void ath9k_hw_apply_gpio_override(struct ath_hw *ah) | ||
1268 | { | ||
1269 | u32 gpio_mask = ah->gpio_mask; | ||
1270 | int i; | ||
1271 | |||
1272 | for (i = 0; gpio_mask; i++, gpio_mask >>= 1) { | ||
1273 | if (!(gpio_mask & 1)) | ||
1274 | continue; | ||
1275 | |||
1276 | ath9k_hw_cfg_output(ah, i, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
1277 | ath9k_hw_set_gpio(ah, i, !!(ah->gpio_val & BIT(i))); | ||
1278 | } | ||
1279 | } | ||
1280 | |||
1215 | bool ath9k_hw_check_alive(struct ath_hw *ah) | 1281 | bool ath9k_hw_check_alive(struct ath_hw *ah) |
1216 | { | 1282 | { |
1217 | int count = 50; | 1283 | int count = 50; |
@@ -1409,7 +1475,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1409 | REGWRITE_BUFFER_FLUSH(ah); | 1475 | REGWRITE_BUFFER_FLUSH(ah); |
1410 | 1476 | ||
1411 | ah->intr_txqs = 0; | 1477 | ah->intr_txqs = 0; |
1412 | for (i = 0; i < ah->caps.total_queues; i++) | 1478 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) |
1413 | ath9k_hw_resettxqueue(ah, i); | 1479 | ath9k_hw_resettxqueue(ah, i); |
1414 | 1480 | ||
1415 | ath9k_hw_init_interrupt_masks(ah, ah->opmode); | 1481 | ath9k_hw_init_interrupt_masks(ah, ah->opmode); |
@@ -1426,8 +1492,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1426 | ar9002_hw_enable_wep_aggregation(ah); | 1492 | ar9002_hw_enable_wep_aggregation(ah); |
1427 | } | 1493 | } |
1428 | 1494 | ||
1429 | REG_WRITE(ah, AR_STA_ID1, | 1495 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM); |
1430 | REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); | ||
1431 | 1496 | ||
1432 | ath9k_hw_set_dma(ah); | 1497 | ath9k_hw_set_dma(ah); |
1433 | 1498 | ||
@@ -1480,7 +1545,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1480 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); | 1545 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); |
1481 | } | 1546 | } |
1482 | #ifdef __BIG_ENDIAN | 1547 | #ifdef __BIG_ENDIAN |
1483 | else | 1548 | else if (AR_SREV_9340(ah)) |
1549 | REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0); | ||
1550 | else | ||
1484 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); | 1551 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); |
1485 | #endif | 1552 | #endif |
1486 | } | 1553 | } |
@@ -1491,6 +1558,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1491 | if (AR_SREV_9300_20_OR_LATER(ah)) | 1558 | if (AR_SREV_9300_20_OR_LATER(ah)) |
1492 | ar9003_hw_bb_watchdog_config(ah); | 1559 | ar9003_hw_bb_watchdog_config(ah); |
1493 | 1560 | ||
1561 | ath9k_hw_apply_gpio_override(ah); | ||
1562 | |||
1494 | return 0; | 1563 | return 0; |
1495 | } | 1564 | } |
1496 | EXPORT_SYMBOL(ath9k_hw_reset); | 1565 | EXPORT_SYMBOL(ath9k_hw_reset); |
@@ -1670,21 +1739,15 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) | |||
1670 | case NL80211_IFTYPE_MESH_POINT: | 1739 | case NL80211_IFTYPE_MESH_POINT: |
1671 | REG_SET_BIT(ah, AR_TXCFG, | 1740 | REG_SET_BIT(ah, AR_TXCFG, |
1672 | AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); | 1741 | AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); |
1673 | REG_WRITE(ah, AR_NEXT_NDP_TIMER, | 1742 | REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon + |
1674 | TU_TO_USEC(next_beacon + | 1743 | TU_TO_USEC(ah->atim_window ? ah->atim_window : 1)); |
1675 | (ah->atim_window ? ah-> | ||
1676 | atim_window : 1))); | ||
1677 | flags |= AR_NDP_TIMER_EN; | 1744 | flags |= AR_NDP_TIMER_EN; |
1678 | case NL80211_IFTYPE_AP: | 1745 | case NL80211_IFTYPE_AP: |
1679 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); | 1746 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon); |
1680 | REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, | 1747 | REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, next_beacon - |
1681 | TU_TO_USEC(next_beacon - | 1748 | TU_TO_USEC(ah->config.dma_beacon_response_time)); |
1682 | ah->config. | 1749 | REG_WRITE(ah, AR_NEXT_SWBA, next_beacon - |
1683 | dma_beacon_response_time)); | 1750 | TU_TO_USEC(ah->config.sw_beacon_response_time)); |
1684 | REG_WRITE(ah, AR_NEXT_SWBA, | ||
1685 | TU_TO_USEC(next_beacon - | ||
1686 | ah->config. | ||
1687 | sw_beacon_response_time)); | ||
1688 | flags |= | 1751 | flags |= |
1689 | AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; | 1752 | AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; |
1690 | break; | 1753 | break; |
@@ -1696,18 +1759,13 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) | |||
1696 | break; | 1759 | break; |
1697 | } | 1760 | } |
1698 | 1761 | ||
1699 | REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period)); | 1762 | REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period); |
1700 | REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period)); | 1763 | REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period); |
1701 | REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period)); | 1764 | REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period); |
1702 | REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period)); | 1765 | REG_WRITE(ah, AR_NDP_PERIOD, beacon_period); |
1703 | 1766 | ||
1704 | REGWRITE_BUFFER_FLUSH(ah); | 1767 | REGWRITE_BUFFER_FLUSH(ah); |
1705 | 1768 | ||
1706 | beacon_period &= ~ATH9K_BEACON_ENA; | ||
1707 | if (beacon_period & ATH9K_BEACON_RESET_TSF) { | ||
1708 | ath9k_hw_reset_tsf(ah); | ||
1709 | } | ||
1710 | |||
1711 | REG_SET_BIT(ah, AR_TIMER_MODE, flags); | 1769 | REG_SET_BIT(ah, AR_TIMER_MODE, flags); |
1712 | } | 1770 | } |
1713 | EXPORT_SYMBOL(ath9k_hw_beaconinit); | 1771 | EXPORT_SYMBOL(ath9k_hw_beaconinit); |
@@ -1795,7 +1853,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
1795 | struct ath_common *common = ath9k_hw_common(ah); | 1853 | struct ath_common *common = ath9k_hw_common(ah); |
1796 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | 1854 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; |
1797 | 1855 | ||
1798 | u16 capField = 0, eeval; | 1856 | u16 eeval; |
1799 | u8 ant_div_ctl1, tx_chainmask, rx_chainmask; | 1857 | u8 ant_div_ctl1, tx_chainmask, rx_chainmask; |
1800 | 1858 | ||
1801 | eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); | 1859 | eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); |
@@ -1806,8 +1864,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
1806 | eeval |= AR9285_RDEXT_DEFAULT; | 1864 | eeval |= AR9285_RDEXT_DEFAULT; |
1807 | regulatory->current_rd_ext = eeval; | 1865 | regulatory->current_rd_ext = eeval; |
1808 | 1866 | ||
1809 | capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP); | ||
1810 | |||
1811 | if (ah->opmode != NL80211_IFTYPE_AP && | 1867 | if (ah->opmode != NL80211_IFTYPE_AP && |
1812 | ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) { | 1868 | ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) { |
1813 | if (regulatory->current_rd == 0x64 || | 1869 | if (regulatory->current_rd == 0x64 || |
@@ -1842,6 +1898,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
1842 | !(AR_SREV_9271(ah))) | 1898 | !(AR_SREV_9271(ah))) |
1843 | /* CB71: GPIO 0 is pulled down to indicate 3 rx chains */ | 1899 | /* CB71: GPIO 0 is pulled down to indicate 3 rx chains */ |
1844 | pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7; | 1900 | pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7; |
1901 | else if (AR_SREV_9100(ah)) | ||
1902 | pCap->rx_chainmask = 0x7; | ||
1845 | else | 1903 | else |
1846 | /* Use rx_chainmask from EEPROM. */ | 1904 | /* Use rx_chainmask from EEPROM. */ |
1847 | pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK); | 1905 | pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK); |
@@ -1852,36 +1910,13 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
1852 | if (AR_SREV_9300_20_OR_LATER(ah)) | 1910 | if (AR_SREV_9300_20_OR_LATER(ah)) |
1853 | ah->misc_mode |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH; | 1911 | ah->misc_mode |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH; |
1854 | 1912 | ||
1855 | pCap->low_2ghz_chan = 2312; | ||
1856 | pCap->high_2ghz_chan = 2732; | ||
1857 | |||
1858 | pCap->low_5ghz_chan = 4920; | ||
1859 | pCap->high_5ghz_chan = 6100; | ||
1860 | |||
1861 | common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; | 1913 | common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; |
1862 | 1914 | ||
1863 | if (ah->config.ht_enable) | 1915 | if (ah->hw_version.devid != AR2427_DEVID_PCIE) |
1864 | pCap->hw_caps |= ATH9K_HW_CAP_HT; | 1916 | pCap->hw_caps |= ATH9K_HW_CAP_HT; |
1865 | else | 1917 | else |
1866 | pCap->hw_caps &= ~ATH9K_HW_CAP_HT; | 1918 | pCap->hw_caps &= ~ATH9K_HW_CAP_HT; |
1867 | 1919 | ||
1868 | if (capField & AR_EEPROM_EEPCAP_MAXQCU) | ||
1869 | pCap->total_queues = | ||
1870 | MS(capField, AR_EEPROM_EEPCAP_MAXQCU); | ||
1871 | else | ||
1872 | pCap->total_queues = ATH9K_NUM_TX_QUEUES; | ||
1873 | |||
1874 | if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES) | ||
1875 | pCap->keycache_size = | ||
1876 | 1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES); | ||
1877 | else | ||
1878 | pCap->keycache_size = AR_KEYTABLE_SIZE; | ||
1879 | |||
1880 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) | ||
1881 | pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1; | ||
1882 | else | ||
1883 | pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; | ||
1884 | |||
1885 | if (AR_SREV_9271(ah)) | 1920 | if (AR_SREV_9271(ah)) |
1886 | pCap->num_gpio_pins = AR9271_NUM_GPIO; | 1921 | pCap->num_gpio_pins = AR9271_NUM_GPIO; |
1887 | else if (AR_DEVID_7010(ah)) | 1922 | else if (AR_DEVID_7010(ah)) |
@@ -1900,8 +1935,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
1900 | pCap->rts_aggr_limit = (8 * 1024); | 1935 | pCap->rts_aggr_limit = (8 * 1024); |
1901 | } | 1936 | } |
1902 | 1937 | ||
1903 | pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM; | ||
1904 | |||
1905 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | 1938 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) |
1906 | ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT); | 1939 | ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT); |
1907 | if (ah->rfsilent & EEP_RFSILENT_ENABLED) { | 1940 | if (ah->rfsilent & EEP_RFSILENT_ENABLED) { |
@@ -1923,32 +1956,23 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
1923 | else | 1956 | else |
1924 | pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; | 1957 | pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; |
1925 | 1958 | ||
1926 | if (regulatory->current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) { | 1959 | if (common->btcoex_enabled) { |
1927 | pCap->reg_cap = | 1960 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
1928 | AR_EEPROM_EEREGCAP_EN_KK_NEW_11A | | ||
1929 | AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN | | ||
1930 | AR_EEPROM_EEREGCAP_EN_KK_U2 | | ||
1931 | AR_EEPROM_EEREGCAP_EN_KK_MIDBAND; | ||
1932 | } else { | ||
1933 | pCap->reg_cap = | ||
1934 | AR_EEPROM_EEREGCAP_EN_KK_NEW_11A | | ||
1935 | AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN; | ||
1936 | } | ||
1937 | |||
1938 | /* Advertise midband for AR5416 with FCC midband set in eeprom */ | ||
1939 | if (regulatory->current_rd_ext & (1 << REG_EXT_FCC_MIDBAND) && | ||
1940 | AR_SREV_5416(ah)) | ||
1941 | pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND; | ||
1942 | |||
1943 | if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) { | ||
1944 | btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO; | ||
1945 | btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO; | ||
1946 | |||
1947 | if (AR_SREV_9285(ah)) { | ||
1948 | btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; | 1961 | btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; |
1949 | btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO; | 1962 | btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300; |
1950 | } else { | 1963 | btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300; |
1951 | btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE; | 1964 | btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300; |
1965 | } else if (AR_SREV_9280_20_OR_LATER(ah)) { | ||
1966 | btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280; | ||
1967 | btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280; | ||
1968 | |||
1969 | if (AR_SREV_9285(ah)) { | ||
1970 | btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; | ||
1971 | btcoex_hw->btpriority_gpio = | ||
1972 | ATH_BTPRIORITY_GPIO_9285; | ||
1973 | } else { | ||
1974 | btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE; | ||
1975 | } | ||
1952 | } | 1976 | } |
1953 | } else { | 1977 | } else { |
1954 | btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; | 1978 | btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; |
@@ -1998,6 +2022,22 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
1998 | } | 2022 | } |
1999 | 2023 | ||
2000 | 2024 | ||
2025 | if (AR_SREV_9485(ah)) { | ||
2026 | ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); | ||
2027 | /* | ||
2028 | * enable the diversity-combining algorithm only when | ||
2029 | * both enable_lna_div and enable_fast_div are set | ||
2030 | * Table for Diversity | ||
2031 | * ant_div_alt_lnaconf bit 0-1 | ||
2032 | * ant_div_main_lnaconf bit 2-3 | ||
2033 | * ant_div_alt_gaintb bit 4 | ||
2034 | * ant_div_main_gaintb bit 5 | ||
2035 | * enable_ant_div_lnadiv bit 6 | ||
2036 | * enable_ant_fast_div bit 7 | ||
2037 | */ | ||
2038 | if ((ant_div_ctl1 >> 0x6) == 0x3) | ||
2039 | pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB; | ||
2040 | } | ||
2001 | 2041 | ||
2002 | if (AR_SREV_9485_10(ah)) { | 2042 | if (AR_SREV_9485_10(ah)) { |
2003 | pCap->pcie_lcr_extsync_en = true; | 2043 | pCap->pcie_lcr_extsync_en = true; |
@@ -2186,11 +2226,9 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) | |||
2186 | REG_WRITE(ah, AR_PHY_ERR, phybits); | 2226 | REG_WRITE(ah, AR_PHY_ERR, phybits); |
2187 | 2227 | ||
2188 | if (phybits) | 2228 | if (phybits) |
2189 | REG_WRITE(ah, AR_RXCFG, | 2229 | REG_SET_BIT(ah, AR_RXCFG, AR_RXCFG_ZLFDMA); |
2190 | REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA); | ||
2191 | else | 2230 | else |
2192 | REG_WRITE(ah, AR_RXCFG, | 2231 | REG_CLR_BIT(ah, AR_RXCFG, AR_RXCFG_ZLFDMA); |
2193 | REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA); | ||
2194 | 2232 | ||
2195 | REGWRITE_BUFFER_FLUSH(ah); | 2233 | REGWRITE_BUFFER_FLUSH(ah); |
2196 | } | 2234 | } |
@@ -2366,10 +2404,11 @@ static u32 rightmost_index(struct ath_gen_timer_table *timer_table, u32 *mask) | |||
2366 | return timer_table->gen_timer_index[b]; | 2404 | return timer_table->gen_timer_index[b]; |
2367 | } | 2405 | } |
2368 | 2406 | ||
2369 | static u32 ath9k_hw_gettsf32(struct ath_hw *ah) | 2407 | u32 ath9k_hw_gettsf32(struct ath_hw *ah) |
2370 | { | 2408 | { |
2371 | return REG_READ(ah, AR_TSF_L32); | 2409 | return REG_READ(ah, AR_TSF_L32); |
2372 | } | 2410 | } |
2411 | EXPORT_SYMBOL(ath9k_hw_gettsf32); | ||
2373 | 2412 | ||
2374 | struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, | 2413 | struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, |
2375 | void (*trigger)(void *), | 2414 | void (*trigger)(void *), |
@@ -2402,11 +2441,11 @@ EXPORT_SYMBOL(ath_gen_timer_alloc); | |||
2402 | 2441 | ||
2403 | void ath9k_hw_gen_timer_start(struct ath_hw *ah, | 2442 | void ath9k_hw_gen_timer_start(struct ath_hw *ah, |
2404 | struct ath_gen_timer *timer, | 2443 | struct ath_gen_timer *timer, |
2405 | u32 timer_next, | 2444 | u32 trig_timeout, |
2406 | u32 timer_period) | 2445 | u32 timer_period) |
2407 | { | 2446 | { |
2408 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; | 2447 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; |
2409 | u32 tsf; | 2448 | u32 tsf, timer_next; |
2410 | 2449 | ||
2411 | BUG_ON(!timer_period); | 2450 | BUG_ON(!timer_period); |
2412 | 2451 | ||
@@ -2414,18 +2453,13 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah, | |||
2414 | 2453 | ||
2415 | tsf = ath9k_hw_gettsf32(ah); | 2454 | tsf = ath9k_hw_gettsf32(ah); |
2416 | 2455 | ||
2456 | timer_next = tsf + trig_timeout; | ||
2457 | |||
2417 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER, | 2458 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER, |
2418 | "current tsf %x period %x timer_next %x\n", | 2459 | "current tsf %x period %x timer_next %x\n", |
2419 | tsf, timer_period, timer_next); | 2460 | tsf, timer_period, timer_next); |
2420 | 2461 | ||
2421 | /* | 2462 | /* |
2422 | * Pull timer_next forward if the current TSF already passed it | ||
2423 | * because of software latency | ||
2424 | */ | ||
2425 | if (timer_next < tsf) | ||
2426 | timer_next = tsf + timer_period; | ||
2427 | |||
2428 | /* | ||
2429 | * Program generic timer registers | 2463 | * Program generic timer registers |
2430 | */ | 2464 | */ |
2431 | REG_WRITE(ah, gen_tmr_configuration[timer->index].next_addr, | 2465 | REG_WRITE(ah, gen_tmr_configuration[timer->index].next_addr, |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 6650fd48415..7af2773d2bf 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -43,6 +43,7 @@ | |||
43 | #define AR9287_DEVID_PCI 0x002d | 43 | #define AR9287_DEVID_PCI 0x002d |
44 | #define AR9287_DEVID_PCIE 0x002e | 44 | #define AR9287_DEVID_PCIE 0x002e |
45 | #define AR9300_DEVID_PCIE 0x0030 | 45 | #define AR9300_DEVID_PCIE 0x0030 |
46 | #define AR9300_DEVID_AR9340 0x0031 | ||
46 | #define AR9300_DEVID_AR9485_PCIE 0x0032 | 47 | #define AR9300_DEVID_AR9485_PCIE 0x0032 |
47 | 48 | ||
48 | #define AR5416_AR9100_DEVID 0x000b | 49 | #define AR5416_AR9100_DEVID 0x000b |
@@ -55,6 +56,9 @@ | |||
55 | #define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa | 56 | #define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa |
56 | #define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab | 57 | #define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab |
57 | 58 | ||
59 | #define AR9300_NUM_BT_WEIGHTS 4 | ||
60 | #define AR9300_NUM_WLAN_WEIGHTS 4 | ||
61 | |||
58 | #define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1) | 62 | #define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1) |
59 | 63 | ||
60 | #define ATH_DEFAULT_NOISE_FLOOR -95 | 64 | #define ATH_DEFAULT_NOISE_FLOOR -95 |
@@ -65,53 +69,49 @@ | |||
65 | 69 | ||
66 | /* Register read/write primitives */ | 70 | /* Register read/write primitives */ |
67 | #define REG_WRITE(_ah, _reg, _val) \ | 71 | #define REG_WRITE(_ah, _reg, _val) \ |
68 | ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg)) | 72 | (_ah)->reg_ops.write((_ah), (_val), (_reg)) |
69 | 73 | ||
70 | #define REG_READ(_ah, _reg) \ | 74 | #define REG_READ(_ah, _reg) \ |
71 | ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) | 75 | (_ah)->reg_ops.read((_ah), (_reg)) |
72 | 76 | ||
73 | #define REG_READ_MULTI(_ah, _addr, _val, _cnt) \ | 77 | #define REG_READ_MULTI(_ah, _addr, _val, _cnt) \ |
74 | ath9k_hw_common(_ah)->ops->multi_read((_ah), (_addr), (_val), (_cnt)) | 78 | (_ah)->reg_ops.multi_read((_ah), (_addr), (_val), (_cnt)) |
79 | |||
80 | #define REG_RMW(_ah, _reg, _set, _clr) \ | ||
81 | (_ah)->reg_ops.rmw((_ah), (_reg), (_set), (_clr)) | ||
75 | 82 | ||
76 | #define ENABLE_REGWRITE_BUFFER(_ah) \ | 83 | #define ENABLE_REGWRITE_BUFFER(_ah) \ |
77 | do { \ | 84 | do { \ |
78 | if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \ | 85 | if ((_ah)->reg_ops.enable_write_buffer) \ |
79 | ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \ | 86 | (_ah)->reg_ops.enable_write_buffer((_ah)); \ |
80 | } while (0) | 87 | } while (0) |
81 | 88 | ||
82 | #define REGWRITE_BUFFER_FLUSH(_ah) \ | 89 | #define REGWRITE_BUFFER_FLUSH(_ah) \ |
83 | do { \ | 90 | do { \ |
84 | if (ath9k_hw_common(_ah)->ops->write_flush) \ | 91 | if ((_ah)->reg_ops.write_flush) \ |
85 | ath9k_hw_common(_ah)->ops->write_flush((_ah)); \ | 92 | (_ah)->reg_ops.write_flush((_ah)); \ |
86 | } while (0) | 93 | } while (0) |
87 | 94 | ||
88 | #define SM(_v, _f) (((_v) << _f##_S) & _f) | 95 | #define SM(_v, _f) (((_v) << _f##_S) & _f) |
89 | #define MS(_v, _f) (((_v) & _f) >> _f##_S) | 96 | #define MS(_v, _f) (((_v) & _f) >> _f##_S) |
90 | #define REG_RMW(_a, _r, _set, _clr) \ | ||
91 | REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set)) | ||
92 | #define REG_RMW_FIELD(_a, _r, _f, _v) \ | 97 | #define REG_RMW_FIELD(_a, _r, _f, _v) \ |
93 | REG_WRITE(_a, _r, \ | 98 | REG_RMW(_a, _r, (((_v) << _f##_S) & _f), (_f)) |
94 | (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f)) | ||
95 | #define REG_READ_FIELD(_a, _r, _f) \ | 99 | #define REG_READ_FIELD(_a, _r, _f) \ |
96 | (((REG_READ(_a, _r) & _f) >> _f##_S)) | 100 | (((REG_READ(_a, _r) & _f) >> _f##_S)) |
97 | #define REG_SET_BIT(_a, _r, _f) \ | 101 | #define REG_SET_BIT(_a, _r, _f) \ |
98 | REG_WRITE(_a, _r, REG_READ(_a, _r) | (_f)) | 102 | REG_RMW(_a, _r, (_f), 0) |
99 | #define REG_CLR_BIT(_a, _r, _f) \ | 103 | #define REG_CLR_BIT(_a, _r, _f) \ |
100 | REG_WRITE(_a, _r, REG_READ(_a, _r) & ~(_f)) | 104 | REG_RMW(_a, _r, 0, (_f)) |
101 | 105 | ||
102 | #define DO_DELAY(x) do { \ | 106 | #define DO_DELAY(x) do { \ |
103 | if ((++(x) % 64) == 0) \ | 107 | if (((++(x) % 64) == 0) && \ |
104 | udelay(1); \ | 108 | (ath9k_hw_common(ah)->bus_ops->ath_bus_type \ |
109 | != ATH_USB)) \ | ||
110 | udelay(1); \ | ||
105 | } while (0) | 111 | } while (0) |
106 | 112 | ||
107 | #define REG_WRITE_ARRAY(iniarray, column, regWr) do { \ | 113 | #define REG_WRITE_ARRAY(iniarray, column, regWr) \ |
108 | int r; \ | 114 | ath9k_hw_write_array(ah, iniarray, column, &(regWr)) |
109 | for (r = 0; r < ((iniarray)->ia_rows); r++) { \ | ||
110 | REG_WRITE(ah, INI_RA((iniarray), (r), 0), \ | ||
111 | INI_RA((iniarray), r, (column))); \ | ||
112 | DO_DELAY(regWr); \ | ||
113 | } \ | ||
114 | } while (0) | ||
115 | 115 | ||
116 | #define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0 | 116 | #define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0 |
117 | #define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1 | 117 | #define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1 |
@@ -125,7 +125,7 @@ | |||
125 | #define AR_GPIO_BIT(_gpio) (1 << (_gpio)) | 125 | #define AR_GPIO_BIT(_gpio) (1 << (_gpio)) |
126 | 126 | ||
127 | #define BASE_ACTIVATE_DELAY 100 | 127 | #define BASE_ACTIVATE_DELAY 100 |
128 | #define RTC_PLL_SETTLE_DELAY 100 | 128 | #define RTC_PLL_SETTLE_DELAY (AR_SREV_9340(ah) ? 1000 : 100) |
129 | #define COEF_SCALE_S 24 | 129 | #define COEF_SCALE_S 24 |
130 | #define HT40_CHANNEL_CENTER_SHIFT 10 | 130 | #define HT40_CHANNEL_CENTER_SHIFT 10 |
131 | 131 | ||
@@ -178,7 +178,6 @@ enum ath9k_hw_caps { | |||
178 | ATH9K_HW_CAP_HT = BIT(0), | 178 | ATH9K_HW_CAP_HT = BIT(0), |
179 | ATH9K_HW_CAP_RFSILENT = BIT(1), | 179 | ATH9K_HW_CAP_RFSILENT = BIT(1), |
180 | ATH9K_HW_CAP_CST = BIT(2), | 180 | ATH9K_HW_CAP_CST = BIT(2), |
181 | ATH9K_HW_CAP_ENHANCEDPM = BIT(3), | ||
182 | ATH9K_HW_CAP_AUTOSLEEP = BIT(4), | 181 | ATH9K_HW_CAP_AUTOSLEEP = BIT(4), |
183 | ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(5), | 182 | ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(5), |
184 | ATH9K_HW_CAP_EDMA = BIT(6), | 183 | ATH9K_HW_CAP_EDMA = BIT(6), |
@@ -195,17 +194,11 @@ enum ath9k_hw_caps { | |||
195 | 194 | ||
196 | struct ath9k_hw_capabilities { | 195 | struct ath9k_hw_capabilities { |
197 | u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ | 196 | u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ |
198 | u16 total_queues; | ||
199 | u16 keycache_size; | ||
200 | u16 low_5ghz_chan, high_5ghz_chan; | ||
201 | u16 low_2ghz_chan, high_2ghz_chan; | ||
202 | u16 rts_aggr_limit; | 197 | u16 rts_aggr_limit; |
203 | u8 tx_chainmask; | 198 | u8 tx_chainmask; |
204 | u8 rx_chainmask; | 199 | u8 rx_chainmask; |
205 | u8 max_txchains; | 200 | u8 max_txchains; |
206 | u8 max_rxchains; | 201 | u8 max_rxchains; |
207 | u16 tx_triglevel_max; | ||
208 | u16 reg_cap; | ||
209 | u8 num_gpio_pins; | 202 | u8 num_gpio_pins; |
210 | u8 rx_hp_qdepth; | 203 | u8 rx_hp_qdepth; |
211 | u8 rx_lp_qdepth; | 204 | u8 rx_lp_qdepth; |
@@ -227,7 +220,6 @@ struct ath9k_ops_config { | |||
227 | u8 pcie_clock_req; | 220 | u8 pcie_clock_req; |
228 | u32 pcie_waen; | 221 | u32 pcie_waen; |
229 | u8 analog_shiftreg; | 222 | u8 analog_shiftreg; |
230 | u8 ht_enable; | ||
231 | u8 paprd_disable; | 223 | u8 paprd_disable; |
232 | u32 ofdm_trig_low; | 224 | u32 ofdm_trig_low; |
233 | u32 ofdm_trig_high; | 225 | u32 ofdm_trig_high; |
@@ -412,8 +404,6 @@ struct ath9k_beacon_state { | |||
412 | u32 bs_nextdtim; | 404 | u32 bs_nextdtim; |
413 | u32 bs_intval; | 405 | u32 bs_intval; |
414 | #define ATH9K_BEACON_PERIOD 0x0000ffff | 406 | #define ATH9K_BEACON_PERIOD 0x0000ffff |
415 | #define ATH9K_BEACON_ENA 0x00800000 | ||
416 | #define ATH9K_BEACON_RESET_TSF 0x01000000 | ||
417 | #define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */ | 407 | #define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */ |
418 | u32 bs_dtimperiod; | 408 | u32 bs_dtimperiod; |
419 | u16 bs_cfpperiod; | 409 | u16 bs_cfpperiod; |
@@ -489,6 +479,10 @@ struct ath_hw_antcomb_conf { | |||
489 | u8 main_lna_conf; | 479 | u8 main_lna_conf; |
490 | u8 alt_lna_conf; | 480 | u8 alt_lna_conf; |
491 | u8 fast_div_bias; | 481 | u8 fast_div_bias; |
482 | u8 main_gaintb; | ||
483 | u8 alt_gaintb; | ||
484 | int lna1_lna2_delta; | ||
485 | u8 div_group; | ||
492 | }; | 486 | }; |
493 | 487 | ||
494 | /** | 488 | /** |
@@ -638,10 +632,12 @@ struct ath_hw_ops { | |||
638 | u32 numDelims); | 632 | u32 numDelims); |
639 | void (*set11n_aggr_last)(struct ath_hw *ah, void *ds); | 633 | void (*set11n_aggr_last)(struct ath_hw *ah, void *ds); |
640 | void (*clr11n_aggr)(struct ath_hw *ah, void *ds); | 634 | void (*clr11n_aggr)(struct ath_hw *ah, void *ds); |
641 | void (*set11n_burstduration)(struct ath_hw *ah, void *ds, | 635 | void (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val); |
642 | u32 burstDuration); | 636 | void (*antdiv_comb_conf_get)(struct ath_hw *ah, |
643 | void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds, | 637 | struct ath_hw_antcomb_conf *antconf); |
644 | u32 vmf); | 638 | void (*antdiv_comb_conf_set)(struct ath_hw *ah, |
639 | struct ath_hw_antcomb_conf *antconf); | ||
640 | |||
645 | }; | 641 | }; |
646 | 642 | ||
647 | struct ath_nf_limits { | 643 | struct ath_nf_limits { |
@@ -655,6 +651,8 @@ struct ath_nf_limits { | |||
655 | #define AH_UNPLUGGED 0x2 /* The card has been physically removed. */ | 651 | #define AH_UNPLUGGED 0x2 /* The card has been physically removed. */ |
656 | 652 | ||
657 | struct ath_hw { | 653 | struct ath_hw { |
654 | struct ath_ops reg_ops; | ||
655 | |||
658 | struct ieee80211_hw *hw; | 656 | struct ieee80211_hw *hw; |
659 | struct ath_common common; | 657 | struct ath_common common; |
660 | struct ath9k_hw_version hw_version; | 658 | struct ath9k_hw_version hw_version; |
@@ -784,6 +782,8 @@ struct ath_hw { | |||
784 | 782 | ||
785 | /* Bluetooth coexistance */ | 783 | /* Bluetooth coexistance */ |
786 | struct ath_btcoex_hw btcoex_hw; | 784 | struct ath_btcoex_hw btcoex_hw; |
785 | u32 bt_coex_bt_weight[AR9300_NUM_BT_WEIGHTS]; | ||
786 | u32 bt_coex_wlan_weight[AR9300_NUM_WLAN_WEIGHTS]; | ||
787 | 787 | ||
788 | u32 intr_txqs; | 788 | u32 intr_txqs; |
789 | u8 txchainmask; | 789 | u8 txchainmask; |
@@ -794,7 +794,9 @@ struct ath_hw { | |||
794 | u32 originalGain[22]; | 794 | u32 originalGain[22]; |
795 | int initPDADC; | 795 | int initPDADC; |
796 | int PDADCdelta; | 796 | int PDADCdelta; |
797 | u8 led_pin; | 797 | int led_pin; |
798 | u32 gpio_mask; | ||
799 | u32 gpio_val; | ||
798 | 800 | ||
799 | struct ar5416IniArray iniModes; | 801 | struct ar5416IniArray iniModes; |
800 | struct ar5416IniArray iniCommon; | 802 | struct ar5416IniArray iniCommon; |
@@ -810,6 +812,7 @@ struct ath_hw { | |||
810 | struct ar5416IniArray iniPcieSerdes; | 812 | struct ar5416IniArray iniPcieSerdes; |
811 | struct ar5416IniArray iniPcieSerdesLowPower; | 813 | struct ar5416IniArray iniPcieSerdesLowPower; |
812 | struct ar5416IniArray iniModesAdditional; | 814 | struct ar5416IniArray iniModesAdditional; |
815 | struct ar5416IniArray iniModesAdditional_40M; | ||
813 | struct ar5416IniArray iniModesRxGain; | 816 | struct ar5416IniArray iniModesRxGain; |
814 | struct ar5416IniArray iniModesTxGain; | 817 | struct ar5416IniArray iniModesTxGain; |
815 | struct ar5416IniArray iniModes_9271_1_0_only; | 818 | struct ar5416IniArray iniModes_9271_1_0_only; |
@@ -856,6 +859,16 @@ struct ath_hw { | |||
856 | 859 | ||
857 | /* Enterprise mode cap */ | 860 | /* Enterprise mode cap */ |
858 | u32 ent_mode; | 861 | u32 ent_mode; |
862 | |||
863 | bool is_clk_25mhz; | ||
864 | }; | ||
865 | |||
866 | struct ath_bus_ops { | ||
867 | enum ath_bus_type ath_bus_type; | ||
868 | void (*read_cachesize)(struct ath_common *common, int *csz); | ||
869 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); | ||
870 | void (*bt_coex_prep)(struct ath_common *common); | ||
871 | void (*extn_synch_en)(struct ath_common *common); | ||
859 | }; | 872 | }; |
860 | 873 | ||
861 | static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) | 874 | static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) |
@@ -900,15 +913,12 @@ void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, | |||
900 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); | 913 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); |
901 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah); | 914 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah); |
902 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); | 915 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); |
903 | void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, | ||
904 | struct ath_hw_antcomb_conf *antconf); | ||
905 | void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah, | ||
906 | struct ath_hw_antcomb_conf *antconf); | ||
907 | 916 | ||
908 | /* General Operation */ | 917 | /* General Operation */ |
909 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); | 918 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); |
919 | void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array, | ||
920 | int column, unsigned int *writecnt); | ||
910 | u32 ath9k_hw_reverse_bits(u32 val, u32 n); | 921 | u32 ath9k_hw_reverse_bits(u32 val, u32 n); |
911 | bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high); | ||
912 | u16 ath9k_hw_computetxtime(struct ath_hw *ah, | 922 | u16 ath9k_hw_computetxtime(struct ath_hw *ah, |
913 | u8 phy, int kbps, | 923 | u8 phy, int kbps, |
914 | u32 frameLen, u16 rateix, bool shortPreamble); | 924 | u32 frameLen, u16 rateix, bool shortPreamble); |
@@ -924,12 +934,13 @@ void ath9k_hw_setopmode(struct ath_hw *ah); | |||
924 | void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1); | 934 | void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1); |
925 | void ath9k_hw_setbssidmask(struct ath_hw *ah); | 935 | void ath9k_hw_setbssidmask(struct ath_hw *ah); |
926 | void ath9k_hw_write_associd(struct ath_hw *ah); | 936 | void ath9k_hw_write_associd(struct ath_hw *ah); |
937 | u32 ath9k_hw_gettsf32(struct ath_hw *ah); | ||
927 | u64 ath9k_hw_gettsf64(struct ath_hw *ah); | 938 | u64 ath9k_hw_gettsf64(struct ath_hw *ah); |
928 | void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); | 939 | void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); |
929 | void ath9k_hw_reset_tsf(struct ath_hw *ah); | 940 | void ath9k_hw_reset_tsf(struct ath_hw *ah); |
930 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); | 941 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); |
931 | void ath9k_hw_init_global_settings(struct ath_hw *ah); | 942 | void ath9k_hw_init_global_settings(struct ath_hw *ah); |
932 | unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah); | 943 | u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah); |
933 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); | 944 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); |
934 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); | 945 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); |
935 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | 946 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 79aec983279..b172d150951 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/ath9k_platform.h> | ||
18 | 19 | ||
19 | #include "ath9k.h" | 20 | #include "ath9k.h" |
20 | 21 | ||
@@ -195,10 +196,27 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) | |||
195 | return val; | 196 | return val; |
196 | } | 197 | } |
197 | 198 | ||
198 | static const struct ath_ops ath9k_common_ops = { | 199 | static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr) |
199 | .read = ath9k_ioread32, | 200 | { |
200 | .write = ath9k_iowrite32, | 201 | struct ath_hw *ah = (struct ath_hw *) hw_priv; |
201 | }; | 202 | struct ath_common *common = ath9k_hw_common(ah); |
203 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
204 | unsigned long uninitialized_var(flags); | ||
205 | u32 val; | ||
206 | |||
207 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) | ||
208 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | ||
209 | |||
210 | val = ioread32(sc->mem + reg_offset); | ||
211 | val &= ~clr; | ||
212 | val |= set; | ||
213 | iowrite32(val, sc->mem + reg_offset); | ||
214 | |||
215 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) | ||
216 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); | ||
217 | |||
218 | return val; | ||
219 | } | ||
202 | 220 | ||
203 | /**************************/ | 221 | /**************************/ |
204 | /* Initialization */ | 222 | /* Initialization */ |
@@ -389,13 +407,7 @@ void ath9k_init_crypto(struct ath_softc *sc) | |||
389 | int i = 0; | 407 | int i = 0; |
390 | 408 | ||
391 | /* Get the hardware key cache size. */ | 409 | /* Get the hardware key cache size. */ |
392 | common->keymax = sc->sc_ah->caps.keycache_size; | 410 | common->keymax = AR_KEYTABLE_SIZE; |
393 | if (common->keymax > ATH_KEYMAX) { | ||
394 | ath_dbg(common, ATH_DBG_ANY, | ||
395 | "Warning, using only %u entries in %u key cache\n", | ||
396 | ATH_KEYMAX, common->keymax); | ||
397 | common->keymax = ATH_KEYMAX; | ||
398 | } | ||
399 | 411 | ||
400 | /* | 412 | /* |
401 | * Reset the key cache since some parts do not | 413 | * Reset the key cache since some parts do not |
@@ -537,6 +549,7 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
537 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | 549 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, |
538 | const struct ath_bus_ops *bus_ops) | 550 | const struct ath_bus_ops *bus_ops) |
539 | { | 551 | { |
552 | struct ath9k_platform_data *pdata = sc->dev->platform_data; | ||
540 | struct ath_hw *ah = NULL; | 553 | struct ath_hw *ah = NULL; |
541 | struct ath_common *common; | 554 | struct ath_common *common; |
542 | int ret = 0, i; | 555 | int ret = 0, i; |
@@ -549,13 +562,23 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
549 | ah->hw = sc->hw; | 562 | ah->hw = sc->hw; |
550 | ah->hw_version.devid = devid; | 563 | ah->hw_version.devid = devid; |
551 | ah->hw_version.subsysid = subsysid; | 564 | ah->hw_version.subsysid = subsysid; |
565 | ah->reg_ops.read = ath9k_ioread32; | ||
566 | ah->reg_ops.write = ath9k_iowrite32; | ||
567 | ah->reg_ops.rmw = ath9k_reg_rmw; | ||
552 | sc->sc_ah = ah; | 568 | sc->sc_ah = ah; |
553 | 569 | ||
554 | if (!sc->dev->platform_data) | 570 | if (!pdata) { |
555 | ah->ah_flags |= AH_USE_EEPROM; | 571 | ah->ah_flags |= AH_USE_EEPROM; |
572 | sc->sc_ah->led_pin = -1; | ||
573 | } else { | ||
574 | sc->sc_ah->gpio_mask = pdata->gpio_mask; | ||
575 | sc->sc_ah->gpio_val = pdata->gpio_val; | ||
576 | sc->sc_ah->led_pin = pdata->led_pin; | ||
577 | ah->is_clk_25mhz = pdata->is_clk_25mhz; | ||
578 | } | ||
556 | 579 | ||
557 | common = ath9k_hw_common(ah); | 580 | common = ath9k_hw_common(ah); |
558 | common->ops = &ath9k_common_ops; | 581 | common->ops = &ah->reg_ops; |
559 | common->bus_ops = bus_ops; | 582 | common->bus_ops = bus_ops; |
560 | common->ah = ah; | 583 | common->ah = ah; |
561 | common->hw = sc->hw; | 584 | common->hw = sc->hw; |
@@ -587,6 +610,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
587 | if (ret) | 610 | if (ret) |
588 | goto err_hw; | 611 | goto err_hw; |
589 | 612 | ||
613 | if (pdata && pdata->macaddr) | ||
614 | memcpy(common->macaddr, pdata->macaddr, ETH_ALEN); | ||
615 | |||
590 | ret = ath9k_init_queues(sc); | 616 | ret = ath9k_init_queues(sc); |
591 | if (ret) | 617 | if (ret) |
592 | goto err_queues; | 618 | goto err_queues; |
@@ -679,6 +705,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
679 | if (AR_SREV_5416(sc->sc_ah)) | 705 | if (AR_SREV_5416(sc->sc_ah)) |
680 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 706 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
681 | 707 | ||
708 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | ||
709 | |||
682 | hw->queues = 4; | 710 | hw->queues = 4; |
683 | hw->max_rates = 4; | 711 | hw->max_rates = 4; |
684 | hw->channel_change_time = 5000; | 712 | hw->channel_change_time = 5000; |
@@ -773,6 +801,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
773 | 801 | ||
774 | INIT_WORK(&sc->hw_check_work, ath_hw_check); | 802 | INIT_WORK(&sc->hw_check_work, ath_hw_check); |
775 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); | 803 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); |
804 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | ||
776 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | 805 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; |
777 | 806 | ||
778 | ath_init_leds(sc); | 807 | ath_init_leds(sc); |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index edc1cbbfeca..bd6d2b9d736 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -209,15 +209,8 @@ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, | |||
209 | { | 209 | { |
210 | u32 cw; | 210 | u32 cw; |
211 | struct ath_common *common = ath9k_hw_common(ah); | 211 | struct ath_common *common = ath9k_hw_common(ah); |
212 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
213 | struct ath9k_tx_queue_info *qi; | 212 | struct ath9k_tx_queue_info *qi; |
214 | 213 | ||
215 | if (q >= pCap->total_queues) { | ||
216 | ath_dbg(common, ATH_DBG_QUEUE, | ||
217 | "Set TXQ properties, invalid queue: %u\n", q); | ||
218 | return false; | ||
219 | } | ||
220 | |||
221 | qi = &ah->txq[q]; | 214 | qi = &ah->txq[q]; |
222 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | 215 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { |
223 | ath_dbg(common, ATH_DBG_QUEUE, | 216 | ath_dbg(common, ATH_DBG_QUEUE, |
@@ -280,15 +273,8 @@ bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q, | |||
280 | struct ath9k_tx_queue_info *qinfo) | 273 | struct ath9k_tx_queue_info *qinfo) |
281 | { | 274 | { |
282 | struct ath_common *common = ath9k_hw_common(ah); | 275 | struct ath_common *common = ath9k_hw_common(ah); |
283 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
284 | struct ath9k_tx_queue_info *qi; | 276 | struct ath9k_tx_queue_info *qi; |
285 | 277 | ||
286 | if (q >= pCap->total_queues) { | ||
287 | ath_dbg(common, ATH_DBG_QUEUE, | ||
288 | "Get TXQ properties, invalid queue: %u\n", q); | ||
289 | return false; | ||
290 | } | ||
291 | |||
292 | qi = &ah->txq[q]; | 278 | qi = &ah->txq[q]; |
293 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | 279 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { |
294 | ath_dbg(common, ATH_DBG_QUEUE, | 280 | ath_dbg(common, ATH_DBG_QUEUE, |
@@ -320,28 +306,27 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, | |||
320 | { | 306 | { |
321 | struct ath_common *common = ath9k_hw_common(ah); | 307 | struct ath_common *common = ath9k_hw_common(ah); |
322 | struct ath9k_tx_queue_info *qi; | 308 | struct ath9k_tx_queue_info *qi; |
323 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
324 | int q; | 309 | int q; |
325 | 310 | ||
326 | switch (type) { | 311 | switch (type) { |
327 | case ATH9K_TX_QUEUE_BEACON: | 312 | case ATH9K_TX_QUEUE_BEACON: |
328 | q = pCap->total_queues - 1; | 313 | q = ATH9K_NUM_TX_QUEUES - 1; |
329 | break; | 314 | break; |
330 | case ATH9K_TX_QUEUE_CAB: | 315 | case ATH9K_TX_QUEUE_CAB: |
331 | q = pCap->total_queues - 2; | 316 | q = ATH9K_NUM_TX_QUEUES - 2; |
332 | break; | 317 | break; |
333 | case ATH9K_TX_QUEUE_PSPOLL: | 318 | case ATH9K_TX_QUEUE_PSPOLL: |
334 | q = 1; | 319 | q = 1; |
335 | break; | 320 | break; |
336 | case ATH9K_TX_QUEUE_UAPSD: | 321 | case ATH9K_TX_QUEUE_UAPSD: |
337 | q = pCap->total_queues - 3; | 322 | q = ATH9K_NUM_TX_QUEUES - 3; |
338 | break; | 323 | break; |
339 | case ATH9K_TX_QUEUE_DATA: | 324 | case ATH9K_TX_QUEUE_DATA: |
340 | for (q = 0; q < pCap->total_queues; q++) | 325 | for (q = 0; q < ATH9K_NUM_TX_QUEUES; q++) |
341 | if (ah->txq[q].tqi_type == | 326 | if (ah->txq[q].tqi_type == |
342 | ATH9K_TX_QUEUE_INACTIVE) | 327 | ATH9K_TX_QUEUE_INACTIVE) |
343 | break; | 328 | break; |
344 | if (q == pCap->total_queues) { | 329 | if (q == ATH9K_NUM_TX_QUEUES) { |
345 | ath_err(common, "No available TX queue\n"); | 330 | ath_err(common, "No available TX queue\n"); |
346 | return -1; | 331 | return -1; |
347 | } | 332 | } |
@@ -382,15 +367,9 @@ EXPORT_SYMBOL(ath9k_hw_setuptxqueue); | |||
382 | 367 | ||
383 | bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) | 368 | bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) |
384 | { | 369 | { |
385 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
386 | struct ath_common *common = ath9k_hw_common(ah); | 370 | struct ath_common *common = ath9k_hw_common(ah); |
387 | struct ath9k_tx_queue_info *qi; | 371 | struct ath9k_tx_queue_info *qi; |
388 | 372 | ||
389 | if (q >= pCap->total_queues) { | ||
390 | ath_dbg(common, ATH_DBG_QUEUE, | ||
391 | "Release TXQ, invalid queue: %u\n", q); | ||
392 | return false; | ||
393 | } | ||
394 | qi = &ah->txq[q]; | 373 | qi = &ah->txq[q]; |
395 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | 374 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { |
396 | ath_dbg(common, ATH_DBG_QUEUE, | 375 | ath_dbg(common, ATH_DBG_QUEUE, |
@@ -414,18 +393,11 @@ EXPORT_SYMBOL(ath9k_hw_releasetxqueue); | |||
414 | 393 | ||
415 | bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | 394 | bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) |
416 | { | 395 | { |
417 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
418 | struct ath_common *common = ath9k_hw_common(ah); | 396 | struct ath_common *common = ath9k_hw_common(ah); |
419 | struct ath9k_channel *chan = ah->curchan; | 397 | struct ath9k_channel *chan = ah->curchan; |
420 | struct ath9k_tx_queue_info *qi; | 398 | struct ath9k_tx_queue_info *qi; |
421 | u32 cwMin, chanCwMin, value; | 399 | u32 cwMin, chanCwMin, value; |
422 | 400 | ||
423 | if (q >= pCap->total_queues) { | ||
424 | ath_dbg(common, ATH_DBG_QUEUE, | ||
425 | "Reset TXQ, invalid queue: %u\n", q); | ||
426 | return false; | ||
427 | } | ||
428 | |||
429 | qi = &ah->txq[q]; | 401 | qi = &ah->txq[q]; |
430 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | 402 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { |
431 | ath_dbg(common, ATH_DBG_QUEUE, | 403 | ath_dbg(common, ATH_DBG_QUEUE, |
@@ -458,17 +430,21 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | |||
458 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)); | 430 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)); |
459 | 431 | ||
460 | REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ); | 432 | REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ); |
461 | REG_WRITE(ah, AR_DMISC(q), | 433 | |
462 | AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2); | 434 | if (AR_SREV_9340(ah)) |
435 | REG_WRITE(ah, AR_DMISC(q), | ||
436 | AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1); | ||
437 | else | ||
438 | REG_WRITE(ah, AR_DMISC(q), | ||
439 | AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2); | ||
463 | 440 | ||
464 | if (qi->tqi_cbrPeriod) { | 441 | if (qi->tqi_cbrPeriod) { |
465 | REG_WRITE(ah, AR_QCBRCFG(q), | 442 | REG_WRITE(ah, AR_QCBRCFG(q), |
466 | SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) | | 443 | SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) | |
467 | SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH)); | 444 | SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH)); |
468 | REG_WRITE(ah, AR_QMISC(q), | 445 | REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_FSP_CBR | |
469 | REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | | 446 | (qi->tqi_cbrOverflowLimit ? |
470 | (qi->tqi_cbrOverflowLimit ? | 447 | AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0)); |
471 | AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0)); | ||
472 | } | 448 | } |
473 | if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) { | 449 | if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) { |
474 | REG_WRITE(ah, AR_QRDYTIMECFG(q), | 450 | REG_WRITE(ah, AR_QRDYTIMECFG(q), |
@@ -481,40 +457,31 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | |||
481 | (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0)); | 457 | (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0)); |
482 | 458 | ||
483 | if (qi->tqi_burstTime | 459 | if (qi->tqi_burstTime |
484 | && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) { | 460 | && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) |
485 | REG_WRITE(ah, AR_QMISC(q), | 461 | REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_RDYTIME_EXP_POLICY); |
486 | REG_READ(ah, AR_QMISC(q)) | | ||
487 | AR_Q_MISC_RDYTIME_EXP_POLICY); | ||
488 | 462 | ||
489 | } | 463 | if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) |
490 | 464 | REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS); | |
491 | if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) { | ||
492 | REG_WRITE(ah, AR_DMISC(q), | ||
493 | REG_READ(ah, AR_DMISC(q)) | | ||
494 | AR_D_MISC_POST_FR_BKOFF_DIS); | ||
495 | } | ||
496 | 465 | ||
497 | REGWRITE_BUFFER_FLUSH(ah); | 466 | REGWRITE_BUFFER_FLUSH(ah); |
498 | 467 | ||
499 | if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) { | 468 | if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) |
500 | REG_WRITE(ah, AR_DMISC(q), | 469 | REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_FRAG_BKOFF_EN); |
501 | REG_READ(ah, AR_DMISC(q)) | | 470 | |
502 | AR_D_MISC_FRAG_BKOFF_EN); | ||
503 | } | ||
504 | switch (qi->tqi_type) { | 471 | switch (qi->tqi_type) { |
505 | case ATH9K_TX_QUEUE_BEACON: | 472 | case ATH9K_TX_QUEUE_BEACON: |
506 | ENABLE_REGWRITE_BUFFER(ah); | 473 | ENABLE_REGWRITE_BUFFER(ah); |
507 | 474 | ||
508 | REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) | 475 | REG_SET_BIT(ah, AR_QMISC(q), |
509 | | AR_Q_MISC_FSP_DBA_GATED | 476 | AR_Q_MISC_FSP_DBA_GATED |
510 | | AR_Q_MISC_BEACON_USE | 477 | | AR_Q_MISC_BEACON_USE |
511 | | AR_Q_MISC_CBR_INCR_DIS1); | 478 | | AR_Q_MISC_CBR_INCR_DIS1); |
512 | 479 | ||
513 | REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) | 480 | REG_SET_BIT(ah, AR_DMISC(q), |
514 | | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << | 481 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << |
515 | AR_D_MISC_ARB_LOCKOUT_CNTRL_S) | 482 | AR_D_MISC_ARB_LOCKOUT_CNTRL_S) |
516 | | AR_D_MISC_BEACON_USE | 483 | | AR_D_MISC_BEACON_USE |
517 | | AR_D_MISC_POST_FR_BKOFF_DIS); | 484 | | AR_D_MISC_POST_FR_BKOFF_DIS); |
518 | 485 | ||
519 | REGWRITE_BUFFER_FLUSH(ah); | 486 | REGWRITE_BUFFER_FLUSH(ah); |
520 | 487 | ||
@@ -533,41 +500,38 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | |||
533 | case ATH9K_TX_QUEUE_CAB: | 500 | case ATH9K_TX_QUEUE_CAB: |
534 | ENABLE_REGWRITE_BUFFER(ah); | 501 | ENABLE_REGWRITE_BUFFER(ah); |
535 | 502 | ||
536 | REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) | 503 | REG_SET_BIT(ah, AR_QMISC(q), |
537 | | AR_Q_MISC_FSP_DBA_GATED | 504 | AR_Q_MISC_FSP_DBA_GATED |
538 | | AR_Q_MISC_CBR_INCR_DIS1 | 505 | | AR_Q_MISC_CBR_INCR_DIS1 |
539 | | AR_Q_MISC_CBR_INCR_DIS0); | 506 | | AR_Q_MISC_CBR_INCR_DIS0); |
540 | value = (qi->tqi_readyTime - | 507 | value = (qi->tqi_readyTime - |
541 | (ah->config.sw_beacon_response_time - | 508 | (ah->config.sw_beacon_response_time - |
542 | ah->config.dma_beacon_response_time) - | 509 | ah->config.dma_beacon_response_time) - |
543 | ah->config.additional_swba_backoff) * 1024; | 510 | ah->config.additional_swba_backoff) * 1024; |
544 | REG_WRITE(ah, AR_QRDYTIMECFG(q), | 511 | REG_WRITE(ah, AR_QRDYTIMECFG(q), |
545 | value | AR_Q_RDYTIMECFG_EN); | 512 | value | AR_Q_RDYTIMECFG_EN); |
546 | REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) | 513 | REG_SET_BIT(ah, AR_DMISC(q), |
547 | | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << | 514 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << |
548 | AR_D_MISC_ARB_LOCKOUT_CNTRL_S)); | 515 | AR_D_MISC_ARB_LOCKOUT_CNTRL_S)); |
549 | 516 | ||
550 | REGWRITE_BUFFER_FLUSH(ah); | 517 | REGWRITE_BUFFER_FLUSH(ah); |
551 | 518 | ||
552 | break; | 519 | break; |
553 | case ATH9K_TX_QUEUE_PSPOLL: | 520 | case ATH9K_TX_QUEUE_PSPOLL: |
554 | REG_WRITE(ah, AR_QMISC(q), | 521 | REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_CBR_INCR_DIS1); |
555 | REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1); | ||
556 | break; | 522 | break; |
557 | case ATH9K_TX_QUEUE_UAPSD: | 523 | case ATH9K_TX_QUEUE_UAPSD: |
558 | REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) | | 524 | REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS); |
559 | AR_D_MISC_POST_FR_BKOFF_DIS); | ||
560 | break; | 525 | break; |
561 | default: | 526 | default: |
562 | break; | 527 | break; |
563 | } | 528 | } |
564 | 529 | ||
565 | if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) { | 530 | if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) { |
566 | REG_WRITE(ah, AR_DMISC(q), | 531 | REG_SET_BIT(ah, AR_DMISC(q), |
567 | REG_READ(ah, AR_DMISC(q)) | | 532 | SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, |
568 | SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, | 533 | AR_D_MISC_ARB_LOCKOUT_CNTRL) | |
569 | AR_D_MISC_ARB_LOCKOUT_CNTRL) | | 534 | AR_D_MISC_POST_FR_BKOFF_DIS); |
570 | AR_D_MISC_POST_FR_BKOFF_DIS); | ||
571 | } | 535 | } |
572 | 536 | ||
573 | if (AR_SREV_9300_20_OR_LATER(ah)) | 537 | if (AR_SREV_9300_20_OR_LATER(ah)) |
@@ -754,7 +718,6 @@ EXPORT_SYMBOL(ath9k_hw_abortpcurecv); | |||
754 | bool ath9k_hw_stopdmarecv(struct ath_hw *ah, bool *reset) | 718 | bool ath9k_hw_stopdmarecv(struct ath_hw *ah, bool *reset) |
755 | { | 719 | { |
756 | #define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ | 720 | #define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ |
757 | #define AH_RX_TIME_QUANTUM 100 /* usec */ | ||
758 | struct ath_common *common = ath9k_hw_common(ah); | 721 | struct ath_common *common = ath9k_hw_common(ah); |
759 | u32 mac_status, last_mac_status = 0; | 722 | u32 mac_status, last_mac_status = 0; |
760 | int i; | 723 | int i; |
@@ -797,7 +760,6 @@ bool ath9k_hw_stopdmarecv(struct ath_hw *ah, bool *reset) | |||
797 | return true; | 760 | return true; |
798 | } | 761 | } |
799 | 762 | ||
800 | #undef AH_RX_TIME_QUANTUM | ||
801 | #undef AH_RX_STOP_DMA_TIMEOUT | 763 | #undef AH_RX_STOP_DMA_TIMEOUT |
802 | } | 764 | } |
803 | EXPORT_SYMBOL(ath9k_hw_stopdmarecv); | 765 | EXPORT_SYMBOL(ath9k_hw_stopdmarecv); |
@@ -855,10 +817,14 @@ EXPORT_SYMBOL(ath9k_hw_disable_interrupts); | |||
855 | void ath9k_hw_enable_interrupts(struct ath_hw *ah) | 817 | void ath9k_hw_enable_interrupts(struct ath_hw *ah) |
856 | { | 818 | { |
857 | struct ath_common *common = ath9k_hw_common(ah); | 819 | struct ath_common *common = ath9k_hw_common(ah); |
820 | u32 sync_default = AR_INTR_SYNC_DEFAULT; | ||
858 | 821 | ||
859 | if (!(ah->imask & ATH9K_INT_GLOBAL)) | 822 | if (!(ah->imask & ATH9K_INT_GLOBAL)) |
860 | return; | 823 | return; |
861 | 824 | ||
825 | if (AR_SREV_9340(ah)) | ||
826 | sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; | ||
827 | |||
862 | ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n"); | 828 | ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n"); |
863 | REG_WRITE(ah, AR_IER, AR_IER_ENABLE); | 829 | REG_WRITE(ah, AR_IER, AR_IER_ENABLE); |
864 | if (!AR_SREV_9100(ah)) { | 830 | if (!AR_SREV_9100(ah)) { |
@@ -867,10 +833,8 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah) | |||
867 | REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ); | 833 | REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ); |
868 | 834 | ||
869 | 835 | ||
870 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, | 836 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default); |
871 | AR_INTR_SYNC_DEFAULT); | 837 | REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default); |
872 | REG_WRITE(ah, AR_INTR_SYNC_MASK, | ||
873 | AR_INTR_SYNC_DEFAULT); | ||
874 | } | 838 | } |
875 | ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", | 839 | ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", |
876 | REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); | 840 | REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); |
@@ -926,6 +890,9 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | |||
926 | mask |= AR_IMR_GENTMR; | 890 | mask |= AR_IMR_GENTMR; |
927 | } | 891 | } |
928 | 892 | ||
893 | if (ints & ATH9K_INT_GENTIMER) | ||
894 | mask |= AR_IMR_GENTMR; | ||
895 | |||
929 | if (ints & (ATH9K_INT_BMISC)) { | 896 | if (ints & (ATH9K_INT_BMISC)) { |
930 | mask |= AR_IMR_BCNMISC; | 897 | mask |= AR_IMR_BCNMISC; |
931 | if (ints & ATH9K_INT_TIM) | 898 | if (ints & ATH9K_INT_TIM) |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index c2a59386fb9..b60c130917f 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -239,7 +239,6 @@ struct ath_desc { | |||
239 | void *ds_vdata; | 239 | void *ds_vdata; |
240 | } __packed __aligned(4); | 240 | } __packed __aligned(4); |
241 | 241 | ||
242 | #define ATH9K_TXDESC_CLRDMASK 0x0001 | ||
243 | #define ATH9K_TXDESC_NOACK 0x0002 | 242 | #define ATH9K_TXDESC_NOACK 0x0002 |
244 | #define ATH9K_TXDESC_RTSENA 0x0004 | 243 | #define ATH9K_TXDESC_RTSENA 0x0004 |
245 | #define ATH9K_TXDESC_CTSENA 0x0008 | 244 | #define ATH9K_TXDESC_CTSENA 0x0008 |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 17d04ff8d67..17ebdf1e8b7 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -299,7 +299,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
299 | 299 | ||
300 | if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { | 300 | if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { |
301 | if (sc->sc_flags & SC_OP_BEACONS) | 301 | if (sc->sc_flags & SC_OP_BEACONS) |
302 | ath_beacon_config(sc, NULL); | 302 | ath_set_beacon(sc); |
303 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | 303 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); |
304 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); | 304 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); |
305 | ath_start_ani(common); | 305 | ath_start_ani(common); |
@@ -624,6 +624,43 @@ out: | |||
624 | ath9k_ps_restore(sc); | 624 | ath9k_ps_restore(sc); |
625 | } | 625 | } |
626 | 626 | ||
627 | static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) | ||
628 | { | ||
629 | static int count; | ||
630 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
631 | |||
632 | if (pll_sqsum >= 0x40000) { | ||
633 | count++; | ||
634 | if (count == 3) { | ||
635 | /* Rx is hung for more than 500ms. Reset it */ | ||
636 | ath_dbg(common, ATH_DBG_RESET, | ||
637 | "Possible RX hang, resetting"); | ||
638 | ath_reset(sc, true); | ||
639 | count = 0; | ||
640 | } | ||
641 | } else | ||
642 | count = 0; | ||
643 | } | ||
644 | |||
645 | void ath_hw_pll_work(struct work_struct *work) | ||
646 | { | ||
647 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
648 | hw_pll_work.work); | ||
649 | u32 pll_sqsum; | ||
650 | |||
651 | if (AR_SREV_9485(sc->sc_ah)) { | ||
652 | |||
653 | ath9k_ps_wakeup(sc); | ||
654 | pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); | ||
655 | ath9k_ps_restore(sc); | ||
656 | |||
657 | ath_hw_pll_rx_hang_check(sc, pll_sqsum); | ||
658 | |||
659 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); | ||
660 | } | ||
661 | } | ||
662 | |||
663 | |||
627 | void ath9k_tasklet(unsigned long data) | 664 | void ath9k_tasklet(unsigned long data) |
628 | { | 665 | { |
629 | struct ath_softc *sc = (struct ath_softc *)data; | 666 | struct ath_softc *sc = (struct ath_softc *)data; |
@@ -652,6 +689,17 @@ void ath9k_tasklet(unsigned long data) | |||
652 | !ath9k_hw_check_alive(ah)) | 689 | !ath9k_hw_check_alive(ah)) |
653 | ieee80211_queue_work(sc->hw, &sc->hw_check_work); | 690 | ieee80211_queue_work(sc->hw, &sc->hw_check_work); |
654 | 691 | ||
692 | if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { | ||
693 | /* | ||
694 | * TSF sync does not look correct; remain awake to sync with | ||
695 | * the next Beacon. | ||
696 | */ | ||
697 | ath_dbg(common, ATH_DBG_PS, | ||
698 | "TSFOOR - Sync with next Beacon\n"); | ||
699 | sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC | | ||
700 | PS_TSFOOR_SYNC; | ||
701 | } | ||
702 | |||
655 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | 703 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
656 | rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL | | 704 | rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL | |
657 | ATH9K_INT_RXORN); | 705 | ATH9K_INT_RXORN); |
@@ -674,16 +722,6 @@ void ath9k_tasklet(unsigned long data) | |||
674 | ath_tx_tasklet(sc); | 722 | ath_tx_tasklet(sc); |
675 | } | 723 | } |
676 | 724 | ||
677 | if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { | ||
678 | /* | ||
679 | * TSF sync does not look correct; remain awake to sync with | ||
680 | * the next Beacon. | ||
681 | */ | ||
682 | ath_dbg(common, ATH_DBG_PS, | ||
683 | "TSFOOR - Sync with next Beacon\n"); | ||
684 | sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC; | ||
685 | } | ||
686 | |||
687 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 725 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
688 | if (status & ATH9K_INT_GENTIMER) | 726 | if (status & ATH9K_INT_GENTIMER) |
689 | ath_gen_timer_isr(sc->sc_ah); | 727 | ath_gen_timer_isr(sc->sc_ah); |
@@ -828,48 +866,6 @@ chip_reset: | |||
828 | #undef SCHED_INTR | 866 | #undef SCHED_INTR |
829 | } | 867 | } |
830 | 868 | ||
831 | static void ath9k_bss_assoc_info(struct ath_softc *sc, | ||
832 | struct ieee80211_hw *hw, | ||
833 | struct ieee80211_vif *vif, | ||
834 | struct ieee80211_bss_conf *bss_conf) | ||
835 | { | ||
836 | struct ath_hw *ah = sc->sc_ah; | ||
837 | struct ath_common *common = ath9k_hw_common(ah); | ||
838 | |||
839 | if (bss_conf->assoc) { | ||
840 | ath_dbg(common, ATH_DBG_CONFIG, | ||
841 | "Bss Info ASSOC %d, bssid: %pM\n", | ||
842 | bss_conf->aid, common->curbssid); | ||
843 | |||
844 | /* New association, store aid */ | ||
845 | common->curaid = bss_conf->aid; | ||
846 | ath9k_hw_write_associd(ah); | ||
847 | |||
848 | /* | ||
849 | * Request a re-configuration of Beacon related timers | ||
850 | * on the receipt of the first Beacon frame (i.e., | ||
851 | * after time sync with the AP). | ||
852 | */ | ||
853 | sc->ps_flags |= PS_BEACON_SYNC; | ||
854 | |||
855 | /* Configure the beacon */ | ||
856 | ath_beacon_config(sc, vif); | ||
857 | |||
858 | /* Reset rssi stats */ | ||
859 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
860 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | ||
861 | |||
862 | sc->sc_flags |= SC_OP_ANI_RUN; | ||
863 | ath_start_ani(common); | ||
864 | } else { | ||
865 | ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); | ||
866 | common->curaid = 0; | ||
867 | /* Stop ANI */ | ||
868 | sc->sc_flags &= ~SC_OP_ANI_RUN; | ||
869 | del_timer_sync(&common->ani.timer); | ||
870 | } | ||
871 | } | ||
872 | |||
873 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | 869 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) |
874 | { | 870 | { |
875 | struct ath_hw *ah = sc->sc_ah; | 871 | struct ath_hw *ah = sc->sc_ah; |
@@ -899,7 +895,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
899 | goto out; | 895 | goto out; |
900 | } | 896 | } |
901 | if (sc->sc_flags & SC_OP_BEACONS) | 897 | if (sc->sc_flags & SC_OP_BEACONS) |
902 | ath_beacon_config(sc, NULL); /* restart beacons */ | 898 | ath_set_beacon(sc); /* restart beacons */ |
903 | 899 | ||
904 | /* Re-Enable interrupts */ | 900 | /* Re-Enable interrupts */ |
905 | ath9k_hw_set_interrupts(ah, ah->imask); | 901 | ath9k_hw_set_interrupts(ah, ah->imask); |
@@ -1006,7 +1002,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1006 | sc->config.txpowlimit, &sc->curtxpow); | 1002 | sc->config.txpowlimit, &sc->curtxpow); |
1007 | 1003 | ||
1008 | if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) | 1004 | if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) |
1009 | ath_beacon_config(sc, NULL); /* restart beacons */ | 1005 | ath_set_beacon(sc); /* restart beacons */ |
1010 | 1006 | ||
1011 | ath9k_hw_set_interrupts(ah, ah->imask); | 1007 | ath9k_hw_set_interrupts(ah, ah->imask); |
1012 | 1008 | ||
@@ -1389,7 +1385,9 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
1389 | ath9k_hw_set_tsfadjust(ah, 0); | 1385 | ath9k_hw_set_tsfadjust(ah, 0); |
1390 | sc->sc_flags &= ~SC_OP_TSF_RESET; | 1386 | sc->sc_flags &= ~SC_OP_TSF_RESET; |
1391 | 1387 | ||
1392 | if (iter_data.nwds + iter_data.nmeshes) | 1388 | if (iter_data.nmeshes) |
1389 | ah->opmode = NL80211_IFTYPE_MESH_POINT; | ||
1390 | else if (iter_data.nwds) | ||
1393 | ah->opmode = NL80211_IFTYPE_AP; | 1391 | ah->opmode = NL80211_IFTYPE_AP; |
1394 | else if (iter_data.nadhocs) | 1392 | else if (iter_data.nadhocs) |
1395 | ah->opmode = NL80211_IFTYPE_ADHOC; | 1393 | ah->opmode = NL80211_IFTYPE_ADHOC; |
@@ -1413,6 +1411,7 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
1413 | 1411 | ||
1414 | /* Set up ANI */ | 1412 | /* Set up ANI */ |
1415 | if ((iter_data.naps + iter_data.nadhocs) > 0) { | 1413 | if ((iter_data.naps + iter_data.nadhocs) > 0) { |
1414 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | ||
1416 | sc->sc_flags |= SC_OP_ANI_RUN; | 1415 | sc->sc_flags |= SC_OP_ANI_RUN; |
1417 | ath_start_ani(common); | 1416 | ath_start_ani(common); |
1418 | } else { | 1417 | } else { |
@@ -1452,7 +1451,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1452 | struct ath_softc *sc = hw->priv; | 1451 | struct ath_softc *sc = hw->priv; |
1453 | struct ath_hw *ah = sc->sc_ah; | 1452 | struct ath_hw *ah = sc->sc_ah; |
1454 | struct ath_common *common = ath9k_hw_common(ah); | 1453 | struct ath_common *common = ath9k_hw_common(ah); |
1455 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
1456 | int ret = 0; | 1454 | int ret = 0; |
1457 | 1455 | ||
1458 | ath9k_ps_wakeup(sc); | 1456 | ath9k_ps_wakeup(sc); |
@@ -1482,8 +1480,9 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1482 | } | 1480 | } |
1483 | } | 1481 | } |
1484 | 1482 | ||
1485 | if ((vif->type == NL80211_IFTYPE_ADHOC) && | 1483 | if ((ah->opmode == NL80211_IFTYPE_ADHOC) || |
1486 | sc->nvifs > 0) { | 1484 | ((vif->type == NL80211_IFTYPE_ADHOC) && |
1485 | sc->nvifs > 0)) { | ||
1487 | ath_err(common, "Cannot create ADHOC interface when other" | 1486 | ath_err(common, "Cannot create ADHOC interface when other" |
1488 | " interfaces already exist.\n"); | 1487 | " interfaces already exist.\n"); |
1489 | ret = -EINVAL; | 1488 | ret = -EINVAL; |
@@ -1493,10 +1492,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1493 | ath_dbg(common, ATH_DBG_CONFIG, | 1492 | ath_dbg(common, ATH_DBG_CONFIG, |
1494 | "Attach a VIF of type: %d\n", vif->type); | 1493 | "Attach a VIF of type: %d\n", vif->type); |
1495 | 1494 | ||
1496 | /* Set the VIF opmode */ | ||
1497 | avp->av_opmode = vif->type; | ||
1498 | avp->av_bslot = -1; | ||
1499 | |||
1500 | sc->nvifs++; | 1495 | sc->nvifs++; |
1501 | 1496 | ||
1502 | ath9k_do_vif_add_setup(hw, vif); | 1497 | ath9k_do_vif_add_setup(hw, vif); |
@@ -1782,23 +1777,68 @@ static int ath9k_sta_add(struct ieee80211_hw *hw, | |||
1782 | struct ieee80211_sta *sta) | 1777 | struct ieee80211_sta *sta) |
1783 | { | 1778 | { |
1784 | struct ath_softc *sc = hw->priv; | 1779 | struct ath_softc *sc = hw->priv; |
1780 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1781 | struct ath_node *an = (struct ath_node *) sta->drv_priv; | ||
1782 | struct ieee80211_key_conf ps_key = { }; | ||
1785 | 1783 | ||
1786 | ath_node_attach(sc, sta); | 1784 | ath_node_attach(sc, sta); |
1787 | 1785 | ||
1786 | if (vif->type != NL80211_IFTYPE_AP && | ||
1787 | vif->type != NL80211_IFTYPE_AP_VLAN) | ||
1788 | return 0; | ||
1789 | |||
1790 | an->ps_key = ath_key_config(common, vif, sta, &ps_key); | ||
1791 | |||
1788 | return 0; | 1792 | return 0; |
1789 | } | 1793 | } |
1790 | 1794 | ||
1795 | static void ath9k_del_ps_key(struct ath_softc *sc, | ||
1796 | struct ieee80211_vif *vif, | ||
1797 | struct ieee80211_sta *sta) | ||
1798 | { | ||
1799 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1800 | struct ath_node *an = (struct ath_node *) sta->drv_priv; | ||
1801 | struct ieee80211_key_conf ps_key = { .hw_key_idx = an->ps_key }; | ||
1802 | |||
1803 | if (!an->ps_key) | ||
1804 | return; | ||
1805 | |||
1806 | ath_key_delete(common, &ps_key); | ||
1807 | } | ||
1808 | |||
1791 | static int ath9k_sta_remove(struct ieee80211_hw *hw, | 1809 | static int ath9k_sta_remove(struct ieee80211_hw *hw, |
1792 | struct ieee80211_vif *vif, | 1810 | struct ieee80211_vif *vif, |
1793 | struct ieee80211_sta *sta) | 1811 | struct ieee80211_sta *sta) |
1794 | { | 1812 | { |
1795 | struct ath_softc *sc = hw->priv; | 1813 | struct ath_softc *sc = hw->priv; |
1796 | 1814 | ||
1815 | ath9k_del_ps_key(sc, vif, sta); | ||
1797 | ath_node_detach(sc, sta); | 1816 | ath_node_detach(sc, sta); |
1798 | 1817 | ||
1799 | return 0; | 1818 | return 0; |
1800 | } | 1819 | } |
1801 | 1820 | ||
1821 | static void ath9k_sta_notify(struct ieee80211_hw *hw, | ||
1822 | struct ieee80211_vif *vif, | ||
1823 | enum sta_notify_cmd cmd, | ||
1824 | struct ieee80211_sta *sta) | ||
1825 | { | ||
1826 | struct ath_softc *sc = hw->priv; | ||
1827 | struct ath_node *an = (struct ath_node *) sta->drv_priv; | ||
1828 | |||
1829 | switch (cmd) { | ||
1830 | case STA_NOTIFY_SLEEP: | ||
1831 | an->sleeping = true; | ||
1832 | if (ath_tx_aggr_sleep(sc, an)) | ||
1833 | ieee80211_sta_set_tim(sta); | ||
1834 | break; | ||
1835 | case STA_NOTIFY_AWAKE: | ||
1836 | an->sleeping = false; | ||
1837 | ath_tx_aggr_wakeup(sc, an); | ||
1838 | break; | ||
1839 | } | ||
1840 | } | ||
1841 | |||
1802 | static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, | 1842 | static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, |
1803 | const struct ieee80211_tx_queue_params *params) | 1843 | const struct ieee80211_tx_queue_params *params) |
1804 | { | 1844 | { |
@@ -1855,12 +1895,29 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
1855 | if (ath9k_modparam_nohwcrypt) | 1895 | if (ath9k_modparam_nohwcrypt) |
1856 | return -ENOSPC; | 1896 | return -ENOSPC; |
1857 | 1897 | ||
1898 | if (vif->type == NL80211_IFTYPE_ADHOC && | ||
1899 | (key->cipher == WLAN_CIPHER_SUITE_TKIP || | ||
1900 | key->cipher == WLAN_CIPHER_SUITE_CCMP) && | ||
1901 | !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | ||
1902 | /* | ||
1903 | * For now, disable hw crypto for the RSN IBSS group keys. This | ||
1904 | * could be optimized in the future to use a modified key cache | ||
1905 | * design to support per-STA RX GTK, but until that gets | ||
1906 | * implemented, use of software crypto for group addressed | ||
1907 | * frames is a acceptable to allow RSN IBSS to be used. | ||
1908 | */ | ||
1909 | return -EOPNOTSUPP; | ||
1910 | } | ||
1911 | |||
1858 | mutex_lock(&sc->mutex); | 1912 | mutex_lock(&sc->mutex); |
1859 | ath9k_ps_wakeup(sc); | 1913 | ath9k_ps_wakeup(sc); |
1860 | ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n"); | 1914 | ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n"); |
1861 | 1915 | ||
1862 | switch (cmd) { | 1916 | switch (cmd) { |
1863 | case SET_KEY: | 1917 | case SET_KEY: |
1918 | if (sta) | ||
1919 | ath9k_del_ps_key(sc, vif, sta); | ||
1920 | |||
1864 | ret = ath_key_config(common, vif, sta, key); | 1921 | ret = ath_key_config(common, vif, sta, key); |
1865 | if (ret >= 0) { | 1922 | if (ret >= 0) { |
1866 | key->hw_key_idx = ret; | 1923 | key->hw_key_idx = ret; |
@@ -1886,6 +1943,92 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
1886 | 1943 | ||
1887 | return ret; | 1944 | return ret; |
1888 | } | 1945 | } |
1946 | static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | ||
1947 | { | ||
1948 | struct ath_softc *sc = data; | ||
1949 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1950 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | ||
1951 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
1952 | |||
1953 | switch (sc->sc_ah->opmode) { | ||
1954 | case NL80211_IFTYPE_ADHOC: | ||
1955 | /* There can be only one vif available */ | ||
1956 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | ||
1957 | common->curaid = bss_conf->aid; | ||
1958 | ath9k_hw_write_associd(sc->sc_ah); | ||
1959 | /* configure beacon */ | ||
1960 | if (bss_conf->enable_beacon) | ||
1961 | ath_beacon_config(sc, vif); | ||
1962 | break; | ||
1963 | case NL80211_IFTYPE_STATION: | ||
1964 | /* | ||
1965 | * Skip iteration if primary station vif's bss info | ||
1966 | * was not changed | ||
1967 | */ | ||
1968 | if (sc->sc_flags & SC_OP_PRIM_STA_VIF) | ||
1969 | break; | ||
1970 | |||
1971 | if (bss_conf->assoc) { | ||
1972 | sc->sc_flags |= SC_OP_PRIM_STA_VIF; | ||
1973 | avp->primary_sta_vif = true; | ||
1974 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | ||
1975 | common->curaid = bss_conf->aid; | ||
1976 | ath9k_hw_write_associd(sc->sc_ah); | ||
1977 | ath_dbg(common, ATH_DBG_CONFIG, | ||
1978 | "Bss Info ASSOC %d, bssid: %pM\n", | ||
1979 | bss_conf->aid, common->curbssid); | ||
1980 | ath_beacon_config(sc, vif); | ||
1981 | /* | ||
1982 | * Request a re-configuration of Beacon related timers | ||
1983 | * on the receipt of the first Beacon frame (i.e., | ||
1984 | * after time sync with the AP). | ||
1985 | */ | ||
1986 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | ||
1987 | /* Reset rssi stats */ | ||
1988 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
1989 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | ||
1990 | |||
1991 | sc->sc_flags |= SC_OP_ANI_RUN; | ||
1992 | ath_start_ani(common); | ||
1993 | } | ||
1994 | break; | ||
1995 | default: | ||
1996 | break; | ||
1997 | } | ||
1998 | } | ||
1999 | |||
2000 | static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) | ||
2001 | { | ||
2002 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2003 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | ||
2004 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
2005 | |||
2006 | /* Reconfigure bss info */ | ||
2007 | if (avp->primary_sta_vif && !bss_conf->assoc) { | ||
2008 | ath_dbg(common, ATH_DBG_CONFIG, | ||
2009 | "Bss Info DISASSOC %d, bssid %pM\n", | ||
2010 | common->curaid, common->curbssid); | ||
2011 | sc->sc_flags &= ~(SC_OP_PRIM_STA_VIF | SC_OP_BEACONS); | ||
2012 | avp->primary_sta_vif = false; | ||
2013 | memset(common->curbssid, 0, ETH_ALEN); | ||
2014 | common->curaid = 0; | ||
2015 | } | ||
2016 | |||
2017 | ieee80211_iterate_active_interfaces_atomic( | ||
2018 | sc->hw, ath9k_bss_iter, sc); | ||
2019 | |||
2020 | /* | ||
2021 | * None of station vifs are associated. | ||
2022 | * Clear bssid & aid | ||
2023 | */ | ||
2024 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && | ||
2025 | !(sc->sc_flags & SC_OP_PRIM_STA_VIF)) { | ||
2026 | ath9k_hw_write_associd(sc->sc_ah); | ||
2027 | /* Stop ANI */ | ||
2028 | sc->sc_flags &= ~SC_OP_ANI_RUN; | ||
2029 | del_timer_sync(&common->ani.timer); | ||
2030 | } | ||
2031 | } | ||
1889 | 2032 | ||
1890 | static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | 2033 | static void ath9k_bss_info_changed(struct ieee80211_hw *hw, |
1891 | struct ieee80211_vif *vif, | 2034 | struct ieee80211_vif *vif, |
@@ -1893,7 +2036,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1893 | u32 changed) | 2036 | u32 changed) |
1894 | { | 2037 | { |
1895 | struct ath_softc *sc = hw->priv; | 2038 | struct ath_softc *sc = hw->priv; |
1896 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | ||
1897 | struct ath_hw *ah = sc->sc_ah; | 2039 | struct ath_hw *ah = sc->sc_ah; |
1898 | struct ath_common *common = ath9k_hw_common(ah); | 2040 | struct ath_common *common = ath9k_hw_common(ah); |
1899 | struct ath_vif *avp = (void *)vif->drv_priv; | 2041 | struct ath_vif *avp = (void *)vif->drv_priv; |
@@ -1904,20 +2046,10 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1904 | mutex_lock(&sc->mutex); | 2046 | mutex_lock(&sc->mutex); |
1905 | 2047 | ||
1906 | if (changed & BSS_CHANGED_BSSID) { | 2048 | if (changed & BSS_CHANGED_BSSID) { |
1907 | /* Set BSSID */ | 2049 | ath9k_config_bss(sc, vif); |
1908 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | ||
1909 | memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN); | ||
1910 | common->curaid = 0; | ||
1911 | ath9k_hw_write_associd(ah); | ||
1912 | |||
1913 | /* Set aggregation protection mode parameters */ | ||
1914 | sc->config.ath_aggr_prot = 0; | ||
1915 | 2050 | ||
1916 | ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n", | 2051 | ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n", |
1917 | common->curbssid, common->curaid); | 2052 | common->curbssid, common->curaid); |
1918 | |||
1919 | /* need to reconfigure the beacon */ | ||
1920 | sc->sc_flags &= ~SC_OP_BEACONS ; | ||
1921 | } | 2053 | } |
1922 | 2054 | ||
1923 | /* Enable transmission of beacons (AP, IBSS, MESH) */ | 2055 | /* Enable transmission of beacons (AP, IBSS, MESH) */ |
@@ -1958,7 +2090,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1958 | } | 2090 | } |
1959 | 2091 | ||
1960 | if (changed & BSS_CHANGED_BEACON_INT) { | 2092 | if (changed & BSS_CHANGED_BEACON_INT) { |
1961 | cur_conf->beacon_interval = bss_conf->beacon_int; | ||
1962 | /* | 2093 | /* |
1963 | * In case of AP mode, the HW TSF has to be reset | 2094 | * In case of AP mode, the HW TSF has to be reset |
1964 | * when the beacon interval changes. | 2095 | * when the beacon interval changes. |
@@ -1970,9 +2101,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1970 | if (!error) | 2101 | if (!error) |
1971 | ath_beacon_config(sc, vif); | 2102 | ath_beacon_config(sc, vif); |
1972 | ath9k_set_beaconing_status(sc, true); | 2103 | ath9k_set_beaconing_status(sc, true); |
1973 | } else { | 2104 | } else |
1974 | ath_beacon_config(sc, vif); | 2105 | ath_beacon_config(sc, vif); |
1975 | } | ||
1976 | } | 2106 | } |
1977 | 2107 | ||
1978 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 2108 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
@@ -1994,12 +2124,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1994 | sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; | 2124 | sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; |
1995 | } | 2125 | } |
1996 | 2126 | ||
1997 | if (changed & BSS_CHANGED_ASSOC) { | ||
1998 | ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", | ||
1999 | bss_conf->assoc); | ||
2000 | ath9k_bss_assoc_info(sc, hw, vif, bss_conf); | ||
2001 | } | ||
2002 | |||
2003 | mutex_unlock(&sc->mutex); | 2127 | mutex_unlock(&sc->mutex); |
2004 | ath9k_ps_restore(sc); | 2128 | ath9k_ps_restore(sc); |
2005 | } | 2129 | } |
@@ -2141,19 +2265,26 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | |||
2141 | static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | 2265 | static void ath9k_flush(struct ieee80211_hw *hw, bool drop) |
2142 | { | 2266 | { |
2143 | struct ath_softc *sc = hw->priv; | 2267 | struct ath_softc *sc = hw->priv; |
2268 | struct ath_hw *ah = sc->sc_ah; | ||
2269 | struct ath_common *common = ath9k_hw_common(ah); | ||
2144 | int timeout = 200; /* ms */ | 2270 | int timeout = 200; /* ms */ |
2145 | int i, j; | 2271 | int i, j; |
2272 | bool drain_txq; | ||
2146 | 2273 | ||
2147 | ath9k_ps_wakeup(sc); | ||
2148 | mutex_lock(&sc->mutex); | 2274 | mutex_lock(&sc->mutex); |
2149 | |||
2150 | cancel_delayed_work_sync(&sc->tx_complete_work); | 2275 | cancel_delayed_work_sync(&sc->tx_complete_work); |
2151 | 2276 | ||
2277 | if (sc->sc_flags & SC_OP_INVALID) { | ||
2278 | ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); | ||
2279 | mutex_unlock(&sc->mutex); | ||
2280 | return; | ||
2281 | } | ||
2282 | |||
2152 | if (drop) | 2283 | if (drop) |
2153 | timeout = 1; | 2284 | timeout = 1; |
2154 | 2285 | ||
2155 | for (j = 0; j < timeout; j++) { | 2286 | for (j = 0; j < timeout; j++) { |
2156 | int npend = 0; | 2287 | bool npend = false; |
2157 | 2288 | ||
2158 | if (j) | 2289 | if (j) |
2159 | usleep_range(1000, 2000); | 2290 | usleep_range(1000, 2000); |
@@ -2162,22 +2293,43 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | |||
2162 | if (!ATH_TXQ_SETUP(sc, i)) | 2293 | if (!ATH_TXQ_SETUP(sc, i)) |
2163 | continue; | 2294 | continue; |
2164 | 2295 | ||
2165 | npend += ath9k_has_pending_frames(sc, &sc->tx.txq[i]); | 2296 | npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]); |
2297 | |||
2298 | if (npend) | ||
2299 | break; | ||
2166 | } | 2300 | } |
2167 | 2301 | ||
2168 | if (!npend) | 2302 | if (!npend) |
2169 | goto out; | 2303 | goto out; |
2170 | } | 2304 | } |
2171 | 2305 | ||
2172 | if (!ath_drain_all_txq(sc, false)) | 2306 | ath9k_ps_wakeup(sc); |
2307 | spin_lock_bh(&sc->sc_pcu_lock); | ||
2308 | drain_txq = ath_drain_all_txq(sc, false); | ||
2309 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
2310 | if (!drain_txq) | ||
2173 | ath_reset(sc, false); | 2311 | ath_reset(sc, false); |
2174 | 2312 | ath9k_ps_restore(sc); | |
2175 | ieee80211_wake_queues(hw); | 2313 | ieee80211_wake_queues(hw); |
2176 | 2314 | ||
2177 | out: | 2315 | out: |
2178 | ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); | 2316 | ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); |
2179 | mutex_unlock(&sc->mutex); | 2317 | mutex_unlock(&sc->mutex); |
2180 | ath9k_ps_restore(sc); | 2318 | } |
2319 | |||
2320 | static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) | ||
2321 | { | ||
2322 | struct ath_softc *sc = hw->priv; | ||
2323 | int i; | ||
2324 | |||
2325 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
2326 | if (!ATH_TXQ_SETUP(sc, i)) | ||
2327 | continue; | ||
2328 | |||
2329 | if (ath9k_has_pending_frames(sc, &sc->tx.txq[i])) | ||
2330 | return true; | ||
2331 | } | ||
2332 | return false; | ||
2181 | } | 2333 | } |
2182 | 2334 | ||
2183 | struct ieee80211_ops ath9k_ops = { | 2335 | struct ieee80211_ops ath9k_ops = { |
@@ -2191,6 +2343,7 @@ struct ieee80211_ops ath9k_ops = { | |||
2191 | .configure_filter = ath9k_configure_filter, | 2343 | .configure_filter = ath9k_configure_filter, |
2192 | .sta_add = ath9k_sta_add, | 2344 | .sta_add = ath9k_sta_add, |
2193 | .sta_remove = ath9k_sta_remove, | 2345 | .sta_remove = ath9k_sta_remove, |
2346 | .sta_notify = ath9k_sta_notify, | ||
2194 | .conf_tx = ath9k_conf_tx, | 2347 | .conf_tx = ath9k_conf_tx, |
2195 | .bss_info_changed = ath9k_bss_info_changed, | 2348 | .bss_info_changed = ath9k_bss_info_changed, |
2196 | .set_key = ath9k_set_key, | 2349 | .set_key = ath9k_set_key, |
@@ -2202,4 +2355,5 @@ struct ieee80211_ops ath9k_ops = { | |||
2202 | .rfkill_poll = ath9k_rfkill_poll_state, | 2355 | .rfkill_poll = ath9k_rfkill_poll_state, |
2203 | .set_coverage_class = ath9k_set_coverage_class, | 2356 | .set_coverage_class = ath9k_set_coverage_class, |
2204 | .flush = ath9k_flush, | 2357 | .flush = ath9k_flush, |
2358 | .tx_frames_pending = ath9k_tx_frames_pending, | ||
2205 | }; | 2359 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index 5e3d7496986..9441bf8ca2f 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h | |||
@@ -19,7 +19,6 @@ | |||
19 | 19 | ||
20 | #define CHANSEL_DIV 15 | 20 | #define CHANSEL_DIV 15 |
21 | #define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV) | 21 | #define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV) |
22 | #define CHANSEL_2G_9485(_freq) ((((_freq) * 0x10000) - 215) / CHANSEL_DIV) | ||
23 | #define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV) | 22 | #define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV) |
24 | 23 | ||
25 | #define AR_PHY_BASE 0x9800 | 24 | #define AR_PHY_BASE 0x9800 |
@@ -38,26 +37,15 @@ | |||
38 | #define AR_PHY_CLC_Q0 0x0000ffd0 | 37 | #define AR_PHY_CLC_Q0 0x0000ffd0 |
39 | #define AR_PHY_CLC_Q0_S 5 | 38 | #define AR_PHY_CLC_Q0_S 5 |
40 | 39 | ||
41 | #define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \ | ||
42 | int r; \ | ||
43 | for (r = 0; r < ((iniarray)->ia_rows); r++) { \ | ||
44 | REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \ | ||
45 | DO_DELAY(regWr); \ | ||
46 | } \ | ||
47 | } while (0) | ||
48 | |||
49 | #define ANTSWAP_AB 0x0001 | 40 | #define ANTSWAP_AB 0x0001 |
50 | #define REDUCE_CHAIN_0 0x00000050 | 41 | #define REDUCE_CHAIN_0 0x00000050 |
51 | #define REDUCE_CHAIN_1 0x00000051 | 42 | #define REDUCE_CHAIN_1 0x00000051 |
52 | #define AR_PHY_CHIP_ID 0x9818 | 43 | #define AR_PHY_CHIP_ID 0x9818 |
53 | 44 | ||
54 | #define RF_BANK_SETUP(_bank, _iniarray, _col) do { \ | ||
55 | int i; \ | ||
56 | for (i = 0; i < (_iniarray)->ia_rows; i++) \ | ||
57 | (_bank)[i] = INI_RA((_iniarray), i, _col);; \ | ||
58 | } while (0) | ||
59 | |||
60 | #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 | 45 | #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 |
61 | #define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 | 46 | #define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 |
62 | 47 | ||
48 | #define AR_PHY_PLL_CONTROL 0x16180 | ||
49 | #define AR_PHY_PLL_MODE 0x16184 | ||
50 | |||
63 | #endif | 51 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 4c0d36a6980..4ccbf2ddb55 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -854,14 +854,13 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
854 | ath_rc_rate_set_rtscts(sc, rate_table, tx_info); | 854 | ath_rc_rate_set_rtscts(sc, rate_table, tx_info); |
855 | } | 855 | } |
856 | 856 | ||
857 | static bool ath_rc_update_per(struct ath_softc *sc, | 857 | static void ath_rc_update_per(struct ath_softc *sc, |
858 | const struct ath_rate_table *rate_table, | 858 | const struct ath_rate_table *rate_table, |
859 | struct ath_rate_priv *ath_rc_priv, | 859 | struct ath_rate_priv *ath_rc_priv, |
860 | struct ieee80211_tx_info *tx_info, | 860 | struct ieee80211_tx_info *tx_info, |
861 | int tx_rate, int xretries, int retries, | 861 | int tx_rate, int xretries, int retries, |
862 | u32 now_msec) | 862 | u32 now_msec) |
863 | { | 863 | { |
864 | bool state_change = false; | ||
865 | int count, n_bad_frames; | 864 | int count, n_bad_frames; |
866 | u8 last_per; | 865 | u8 last_per; |
867 | static const u32 nretry_to_per_lookup[10] = { | 866 | static const u32 nretry_to_per_lookup[10] = { |
@@ -992,8 +991,6 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
992 | 991 | ||
993 | } | 992 | } |
994 | } | 993 | } |
995 | |||
996 | return state_change; | ||
997 | } | 994 | } |
998 | 995 | ||
999 | static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, | 996 | static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, |
@@ -1017,7 +1014,6 @@ static void ath_rc_update_ht(struct ath_softc *sc, | |||
1017 | u32 now_msec = jiffies_to_msecs(jiffies); | 1014 | u32 now_msec = jiffies_to_msecs(jiffies); |
1018 | int rate; | 1015 | int rate; |
1019 | u8 last_per; | 1016 | u8 last_per; |
1020 | bool state_change = false; | ||
1021 | const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; | 1017 | const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; |
1022 | int size = ath_rc_priv->rate_table_size; | 1018 | int size = ath_rc_priv->rate_table_size; |
1023 | 1019 | ||
@@ -1027,9 +1023,9 @@ static void ath_rc_update_ht(struct ath_softc *sc, | |||
1027 | last_per = ath_rc_priv->per[tx_rate]; | 1023 | last_per = ath_rc_priv->per[tx_rate]; |
1028 | 1024 | ||
1029 | /* Update PER first */ | 1025 | /* Update PER first */ |
1030 | state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv, | 1026 | ath_rc_update_per(sc, rate_table, ath_rc_priv, |
1031 | tx_info, tx_rate, xretries, | 1027 | tx_info, tx_rate, xretries, |
1032 | retries, now_msec); | 1028 | retries, now_msec); |
1033 | 1029 | ||
1034 | /* | 1030 | /* |
1035 | * If this rate looks bad (high PER) then stop using it for | 1031 | * If this rate looks bad (high PER) then stop using it for |
@@ -1092,8 +1088,7 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, | |||
1092 | if (!(rate->flags & IEEE80211_TX_RC_MCS)) | 1088 | if (!(rate->flags & IEEE80211_TX_RC_MCS)) |
1093 | return rate->idx; | 1089 | return rate->idx; |
1094 | 1090 | ||
1095 | while (rate->idx > mcs_rix_off[i] && | 1091 | while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) { |
1096 | i < ARRAY_SIZE(mcs_rix_off)) { | ||
1097 | rix++; i++; | 1092 | rix++; i++; |
1098 | } | 1093 | } |
1099 | 1094 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index b29c80def35..4f52e0429f9 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -28,6 +28,33 @@ static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, | |||
28 | (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50); | 28 | (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50); |
29 | } | 29 | } |
30 | 30 | ||
31 | static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio, | ||
32 | int curr_main_set, int curr_alt_set, | ||
33 | int alt_rssi_avg, int main_rssi_avg) | ||
34 | { | ||
35 | bool result = false; | ||
36 | switch (div_group) { | ||
37 | case 0: | ||
38 | if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) | ||
39 | result = true; | ||
40 | break; | ||
41 | case 1: | ||
42 | if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) && | ||
43 | (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) && | ||
44 | (alt_rssi_avg >= (main_rssi_avg - 5))) || | ||
45 | ((curr_main_set == ATH_ANT_DIV_COMB_LNA1) && | ||
46 | (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) && | ||
47 | (alt_rssi_avg >= (main_rssi_avg - 2)))) && | ||
48 | (alt_rssi_avg >= 4)) | ||
49 | result = true; | ||
50 | else | ||
51 | result = false; | ||
52 | break; | ||
53 | } | ||
54 | |||
55 | return result; | ||
56 | } | ||
57 | |||
31 | static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) | 58 | static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) |
32 | { | 59 | { |
33 | return sc->ps_enabled && | 60 | return sc->ps_enabled && |
@@ -75,7 +102,6 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) | |||
75 | *sc->rx.rxlink = bf->bf_daddr; | 102 | *sc->rx.rxlink = bf->bf_daddr; |
76 | 103 | ||
77 | sc->rx.rxlink = &ds->ds_link; | 104 | sc->rx.rxlink = &ds->ds_link; |
78 | ath9k_hw_rxena(ah); | ||
79 | } | 105 | } |
80 | 106 | ||
81 | static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) | 107 | static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) |
@@ -426,9 +452,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
426 | else | 452 | else |
427 | rfilt |= ATH9K_RX_FILTER_BEACON; | 453 | rfilt |= ATH9K_RX_FILTER_BEACON; |
428 | 454 | ||
429 | if ((AR_SREV_9280_20_OR_LATER(sc->sc_ah) || | 455 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
430 | AR_SREV_9285_12_OR_LATER(sc->sc_ah)) && | ||
431 | (sc->sc_ah->opmode == NL80211_IFTYPE_AP) && | ||
432 | (sc->rx.rxfilter & FIF_PSPOLL)) | 456 | (sc->rx.rxfilter & FIF_PSPOLL)) |
433 | rfilt |= ATH9K_RX_FILTER_PSPOLL; | 457 | rfilt |= ATH9K_RX_FILTER_PSPOLL; |
434 | 458 | ||
@@ -574,7 +598,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) | |||
574 | sc->ps_flags &= ~PS_BEACON_SYNC; | 598 | sc->ps_flags &= ~PS_BEACON_SYNC; |
575 | ath_dbg(common, ATH_DBG_PS, | 599 | ath_dbg(common, ATH_DBG_PS, |
576 | "Reconfigure Beacon timers based on timestamp from the AP\n"); | 600 | "Reconfigure Beacon timers based on timestamp from the AP\n"); |
577 | ath_beacon_config(sc, NULL); | 601 | ath_set_beacon(sc); |
602 | sc->ps_flags &= ~PS_TSFOOR_SYNC; | ||
578 | } | 603 | } |
579 | 604 | ||
580 | if (ath_beacon_dtim_pending_cab(skb)) { | 605 | if (ath_beacon_dtim_pending_cab(skb)) { |
@@ -919,7 +944,8 @@ static void ath9k_process_rssi(struct ath_common *common, | |||
919 | int last_rssi; | 944 | int last_rssi; |
920 | __le16 fc; | 945 | __le16 fc; |
921 | 946 | ||
922 | if (ah->opmode != NL80211_IFTYPE_STATION) | 947 | if ((ah->opmode != NL80211_IFTYPE_STATION) && |
948 | (ah->opmode != NL80211_IFTYPE_ADHOC)) | ||
923 | return; | 949 | return; |
924 | 950 | ||
925 | fc = hdr->frame_control; | 951 | fc = hdr->frame_control; |
@@ -1291,49 +1317,138 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb, | |||
1291 | } | 1317 | } |
1292 | } | 1318 | } |
1293 | 1319 | ||
1294 | static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf) | 1320 | static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, |
1321 | struct ath_ant_comb *antcomb, int alt_ratio) | ||
1295 | { | 1322 | { |
1296 | /* Adjust the fast_div_bias based on main and alt lna conf */ | 1323 | if (ant_conf->div_group == 0) { |
1297 | switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) { | 1324 | /* Adjust the fast_div_bias based on main and alt lna conf */ |
1298 | case (0x01): /* A-B LNA2 */ | 1325 | switch ((ant_conf->main_lna_conf << 4) | |
1299 | ant_conf->fast_div_bias = 0x3b; | 1326 | ant_conf->alt_lna_conf) { |
1300 | break; | 1327 | case (0x01): /* A-B LNA2 */ |
1301 | case (0x02): /* A-B LNA1 */ | 1328 | ant_conf->fast_div_bias = 0x3b; |
1302 | ant_conf->fast_div_bias = 0x3d; | 1329 | break; |
1303 | break; | 1330 | case (0x02): /* A-B LNA1 */ |
1304 | case (0x03): /* A-B A+B */ | 1331 | ant_conf->fast_div_bias = 0x3d; |
1305 | ant_conf->fast_div_bias = 0x1; | 1332 | break; |
1306 | break; | 1333 | case (0x03): /* A-B A+B */ |
1307 | case (0x10): /* LNA2 A-B */ | 1334 | ant_conf->fast_div_bias = 0x1; |
1308 | ant_conf->fast_div_bias = 0x7; | 1335 | break; |
1309 | break; | 1336 | case (0x10): /* LNA2 A-B */ |
1310 | case (0x12): /* LNA2 LNA1 */ | 1337 | ant_conf->fast_div_bias = 0x7; |
1311 | ant_conf->fast_div_bias = 0x2; | 1338 | break; |
1312 | break; | 1339 | case (0x12): /* LNA2 LNA1 */ |
1313 | case (0x13): /* LNA2 A+B */ | 1340 | ant_conf->fast_div_bias = 0x2; |
1314 | ant_conf->fast_div_bias = 0x7; | 1341 | break; |
1315 | break; | 1342 | case (0x13): /* LNA2 A+B */ |
1316 | case (0x20): /* LNA1 A-B */ | 1343 | ant_conf->fast_div_bias = 0x7; |
1317 | ant_conf->fast_div_bias = 0x6; | 1344 | break; |
1318 | break; | 1345 | case (0x20): /* LNA1 A-B */ |
1319 | case (0x21): /* LNA1 LNA2 */ | 1346 | ant_conf->fast_div_bias = 0x6; |
1320 | ant_conf->fast_div_bias = 0x0; | 1347 | break; |
1321 | break; | 1348 | case (0x21): /* LNA1 LNA2 */ |
1322 | case (0x23): /* LNA1 A+B */ | 1349 | ant_conf->fast_div_bias = 0x0; |
1323 | ant_conf->fast_div_bias = 0x6; | 1350 | break; |
1324 | break; | 1351 | case (0x23): /* LNA1 A+B */ |
1325 | case (0x30): /* A+B A-B */ | 1352 | ant_conf->fast_div_bias = 0x6; |
1326 | ant_conf->fast_div_bias = 0x1; | 1353 | break; |
1327 | break; | 1354 | case (0x30): /* A+B A-B */ |
1328 | case (0x31): /* A+B LNA2 */ | 1355 | ant_conf->fast_div_bias = 0x1; |
1329 | ant_conf->fast_div_bias = 0x3b; | 1356 | break; |
1330 | break; | 1357 | case (0x31): /* A+B LNA2 */ |
1331 | case (0x32): /* A+B LNA1 */ | 1358 | ant_conf->fast_div_bias = 0x3b; |
1332 | ant_conf->fast_div_bias = 0x3d; | 1359 | break; |
1333 | break; | 1360 | case (0x32): /* A+B LNA1 */ |
1334 | default: | 1361 | ant_conf->fast_div_bias = 0x3d; |
1335 | break; | 1362 | break; |
1363 | default: | ||
1364 | break; | ||
1365 | } | ||
1366 | } else if (ant_conf->div_group == 2) { | ||
1367 | /* Adjust the fast_div_bias based on main and alt_lna_conf */ | ||
1368 | switch ((ant_conf->main_lna_conf << 4) | | ||
1369 | ant_conf->alt_lna_conf) { | ||
1370 | case (0x01): /* A-B LNA2 */ | ||
1371 | ant_conf->fast_div_bias = 0x1; | ||
1372 | ant_conf->main_gaintb = 0; | ||
1373 | ant_conf->alt_gaintb = 0; | ||
1374 | break; | ||
1375 | case (0x02): /* A-B LNA1 */ | ||
1376 | ant_conf->fast_div_bias = 0x1; | ||
1377 | ant_conf->main_gaintb = 0; | ||
1378 | ant_conf->alt_gaintb = 0; | ||
1379 | break; | ||
1380 | case (0x03): /* A-B A+B */ | ||
1381 | ant_conf->fast_div_bias = 0x1; | ||
1382 | ant_conf->main_gaintb = 0; | ||
1383 | ant_conf->alt_gaintb = 0; | ||
1384 | break; | ||
1385 | case (0x10): /* LNA2 A-B */ | ||
1386 | if (!(antcomb->scan) && | ||
1387 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1388 | ant_conf->fast_div_bias = 0x1; | ||
1389 | else | ||
1390 | ant_conf->fast_div_bias = 0x2; | ||
1391 | ant_conf->main_gaintb = 0; | ||
1392 | ant_conf->alt_gaintb = 0; | ||
1393 | break; | ||
1394 | case (0x12): /* LNA2 LNA1 */ | ||
1395 | ant_conf->fast_div_bias = 0x1; | ||
1396 | ant_conf->main_gaintb = 0; | ||
1397 | ant_conf->alt_gaintb = 0; | ||
1398 | break; | ||
1399 | case (0x13): /* LNA2 A+B */ | ||
1400 | if (!(antcomb->scan) && | ||
1401 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1402 | ant_conf->fast_div_bias = 0x1; | ||
1403 | else | ||
1404 | ant_conf->fast_div_bias = 0x2; | ||
1405 | ant_conf->main_gaintb = 0; | ||
1406 | ant_conf->alt_gaintb = 0; | ||
1407 | break; | ||
1408 | case (0x20): /* LNA1 A-B */ | ||
1409 | if (!(antcomb->scan) && | ||
1410 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1411 | ant_conf->fast_div_bias = 0x1; | ||
1412 | else | ||
1413 | ant_conf->fast_div_bias = 0x2; | ||
1414 | ant_conf->main_gaintb = 0; | ||
1415 | ant_conf->alt_gaintb = 0; | ||
1416 | break; | ||
1417 | case (0x21): /* LNA1 LNA2 */ | ||
1418 | ant_conf->fast_div_bias = 0x1; | ||
1419 | ant_conf->main_gaintb = 0; | ||
1420 | ant_conf->alt_gaintb = 0; | ||
1421 | break; | ||
1422 | case (0x23): /* LNA1 A+B */ | ||
1423 | if (!(antcomb->scan) && | ||
1424 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1425 | ant_conf->fast_div_bias = 0x1; | ||
1426 | else | ||
1427 | ant_conf->fast_div_bias = 0x2; | ||
1428 | ant_conf->main_gaintb = 0; | ||
1429 | ant_conf->alt_gaintb = 0; | ||
1430 | break; | ||
1431 | case (0x30): /* A+B A-B */ | ||
1432 | ant_conf->fast_div_bias = 0x1; | ||
1433 | ant_conf->main_gaintb = 0; | ||
1434 | ant_conf->alt_gaintb = 0; | ||
1435 | break; | ||
1436 | case (0x31): /* A+B LNA2 */ | ||
1437 | ant_conf->fast_div_bias = 0x1; | ||
1438 | ant_conf->main_gaintb = 0; | ||
1439 | ant_conf->alt_gaintb = 0; | ||
1440 | break; | ||
1441 | case (0x32): /* A+B LNA1 */ | ||
1442 | ant_conf->fast_div_bias = 0x1; | ||
1443 | ant_conf->main_gaintb = 0; | ||
1444 | ant_conf->alt_gaintb = 0; | ||
1445 | break; | ||
1446 | default: | ||
1447 | break; | ||
1448 | } | ||
1449 | |||
1336 | } | 1450 | } |
1451 | |||
1337 | } | 1452 | } |
1338 | 1453 | ||
1339 | /* Antenna diversity and combining */ | 1454 | /* Antenna diversity and combining */ |
@@ -1342,7 +1457,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | |||
1342 | struct ath_hw_antcomb_conf div_ant_conf; | 1457 | struct ath_hw_antcomb_conf div_ant_conf; |
1343 | struct ath_ant_comb *antcomb = &sc->ant_comb; | 1458 | struct ath_ant_comb *antcomb = &sc->ant_comb; |
1344 | int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; | 1459 | int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; |
1345 | int curr_main_set, curr_bias; | 1460 | int curr_main_set; |
1346 | int main_rssi = rs->rs_rssi_ctl0; | 1461 | int main_rssi = rs->rs_rssi_ctl0; |
1347 | int alt_rssi = rs->rs_rssi_ctl1; | 1462 | int alt_rssi = rs->rs_rssi_ctl1; |
1348 | int rx_ant_conf, main_ant_conf; | 1463 | int rx_ant_conf, main_ant_conf; |
@@ -1353,8 +1468,8 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | |||
1353 | main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & | 1468 | main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & |
1354 | ATH_ANT_RX_MASK; | 1469 | ATH_ANT_RX_MASK; |
1355 | 1470 | ||
1356 | /* Record packet only when alt_rssi is positive */ | 1471 | /* Record packet only when both main_rssi and alt_rssi is positive */ |
1357 | if (alt_rssi > 0) { | 1472 | if (main_rssi > 0 && alt_rssi > 0) { |
1358 | antcomb->total_pkt_count++; | 1473 | antcomb->total_pkt_count++; |
1359 | antcomb->main_total_rssi += main_rssi; | 1474 | antcomb->main_total_rssi += main_rssi; |
1360 | antcomb->alt_total_rssi += alt_rssi; | 1475 | antcomb->alt_total_rssi += alt_rssi; |
@@ -1396,7 +1511,6 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | |||
1396 | ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); | 1511 | ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); |
1397 | curr_alt_set = div_ant_conf.alt_lna_conf; | 1512 | curr_alt_set = div_ant_conf.alt_lna_conf; |
1398 | curr_main_set = div_ant_conf.main_lna_conf; | 1513 | curr_main_set = div_ant_conf.main_lna_conf; |
1399 | curr_bias = div_ant_conf.fast_div_bias; | ||
1400 | 1514 | ||
1401 | antcomb->count++; | 1515 | antcomb->count++; |
1402 | 1516 | ||
@@ -1415,7 +1529,9 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | |||
1415 | } | 1529 | } |
1416 | 1530 | ||
1417 | if (!antcomb->scan) { | 1531 | if (!antcomb->scan) { |
1418 | if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { | 1532 | if (ath_ant_div_comb_alt_check(div_ant_conf.div_group, |
1533 | alt_ratio, curr_main_set, curr_alt_set, | ||
1534 | alt_rssi_avg, main_rssi_avg)) { | ||
1419 | if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) { | 1535 | if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) { |
1420 | /* Switch main and alt LNA */ | 1536 | /* Switch main and alt LNA */ |
1421 | div_ant_conf.main_lna_conf = | 1537 | div_ant_conf.main_lna_conf = |
@@ -1444,7 +1560,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | |||
1444 | } | 1560 | } |
1445 | 1561 | ||
1446 | if ((alt_rssi_avg < (main_rssi_avg + | 1562 | if ((alt_rssi_avg < (main_rssi_avg + |
1447 | ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA))) | 1563 | div_ant_conf.lna1_lna2_delta))) |
1448 | goto div_comb_done; | 1564 | goto div_comb_done; |
1449 | } | 1565 | } |
1450 | 1566 | ||
@@ -1558,8 +1674,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | |||
1558 | antcomb->quick_scan_cnt++; | 1674 | antcomb->quick_scan_cnt++; |
1559 | 1675 | ||
1560 | div_comb_done: | 1676 | div_comb_done: |
1561 | ath_ant_div_conf_fast_divbias(&div_ant_conf); | 1677 | ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio); |
1562 | |||
1563 | ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf); | 1678 | ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf); |
1564 | 1679 | ||
1565 | antcomb->scan_start_time = jiffies; | 1680 | antcomb->scan_start_time = jiffies; |
@@ -1746,7 +1861,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1746 | if ((sc->ps_flags & (PS_WAIT_FOR_BEACON | | 1861 | if ((sc->ps_flags & (PS_WAIT_FOR_BEACON | |
1747 | PS_WAIT_FOR_CAB | | 1862 | PS_WAIT_FOR_CAB | |
1748 | PS_WAIT_FOR_PSPOLL_DATA)) || | 1863 | PS_WAIT_FOR_PSPOLL_DATA)) || |
1749 | unlikely(ath9k_check_auto_sleep(sc))) | 1864 | ath9k_check_auto_sleep(sc)) |
1750 | ath_rx_ps(sc, skb); | 1865 | ath_rx_ps(sc, skb); |
1751 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 1866 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
1752 | 1867 | ||
@@ -1767,6 +1882,7 @@ requeue: | |||
1767 | } else { | 1882 | } else { |
1768 | list_move_tail(&bf->list, &sc->rx.rxbuf); | 1883 | list_move_tail(&bf->list, &sc->rx.rxbuf); |
1769 | ath_rx_buf_link(sc, bf); | 1884 | ath_rx_buf_link(sc, bf); |
1885 | ath9k_hw_rxena(ah); | ||
1770 | } | 1886 | } |
1771 | } while (1); | 1887 | } while (1); |
1772 | 1888 | ||
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 8fa8acfde62..456f3ec20fe 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -693,7 +693,7 @@ | |||
693 | #define AR_RC_APB 0x00000002 | 693 | #define AR_RC_APB 0x00000002 |
694 | #define AR_RC_HOSTIF 0x00000100 | 694 | #define AR_RC_HOSTIF 0x00000100 |
695 | 695 | ||
696 | #define AR_WA 0x4004 | 696 | #define AR_WA (AR_SREV_9340(ah) ? 0x40c4 : 0x4004) |
697 | #define AR_WA_BIT6 (1 << 6) | 697 | #define AR_WA_BIT6 (1 << 6) |
698 | #define AR_WA_BIT7 (1 << 7) | 698 | #define AR_WA_BIT7 (1 << 7) |
699 | #define AR_WA_BIT23 (1 << 23) | 699 | #define AR_WA_BIT23 (1 << 23) |
@@ -712,7 +712,7 @@ | |||
712 | #define AR_PM_STATE 0x4008 | 712 | #define AR_PM_STATE 0x4008 |
713 | #define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000 | 713 | #define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000 |
714 | 714 | ||
715 | #define AR_HOST_TIMEOUT 0x4018 | 715 | #define AR_HOST_TIMEOUT (AR_SREV_9340(ah) ? 0x4008 : 0x4018) |
716 | #define AR_HOST_TIMEOUT_APB_CNTR 0x0000FFFF | 716 | #define AR_HOST_TIMEOUT_APB_CNTR 0x0000FFFF |
717 | #define AR_HOST_TIMEOUT_APB_CNTR_S 0 | 717 | #define AR_HOST_TIMEOUT_APB_CNTR_S 0 |
718 | #define AR_HOST_TIMEOUT_LCL_CNTR 0xFFFF0000 | 718 | #define AR_HOST_TIMEOUT_LCL_CNTR 0xFFFF0000 |
@@ -742,7 +742,8 @@ | |||
742 | #define EEPROM_PROTECT_WP_1024_2047 0x8000 | 742 | #define EEPROM_PROTECT_WP_1024_2047 0x8000 |
743 | 743 | ||
744 | #define AR_SREV \ | 744 | #define AR_SREV \ |
745 | ((AR_SREV_9100(ah)) ? 0x0600 : 0x4020) | 745 | ((AR_SREV_9100(ah)) ? 0x0600 : (AR_SREV_9340(ah) \ |
746 | ? 0x400c : 0x4020)) | ||
746 | 747 | ||
747 | #define AR_SREV_ID \ | 748 | #define AR_SREV_ID \ |
748 | ((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF) | 749 | ((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF) |
@@ -790,6 +791,7 @@ | |||
790 | #define AR_SREV_VERSION_9485 0x240 | 791 | #define AR_SREV_VERSION_9485 0x240 |
791 | #define AR_SREV_REVISION_9485_10 0 | 792 | #define AR_SREV_REVISION_9485_10 0 |
792 | #define AR_SREV_REVISION_9485_11 1 | 793 | #define AR_SREV_REVISION_9485_11 1 |
794 | #define AR_SREV_VERSION_9340 0x300 | ||
793 | 795 | ||
794 | #define AR_SREV_5416(_ah) \ | 796 | #define AR_SREV_5416(_ah) \ |
795 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ | 797 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ |
@@ -858,9 +860,7 @@ | |||
858 | #define AR_SREV_9300(_ah) \ | 860 | #define AR_SREV_9300(_ah) \ |
859 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) | 861 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) |
860 | #define AR_SREV_9300_20_OR_LATER(_ah) \ | 862 | #define AR_SREV_9300_20_OR_LATER(_ah) \ |
861 | (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \ | 863 | ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300) |
862 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \ | ||
863 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20))) | ||
864 | 864 | ||
865 | #define AR_SREV_9485(_ah) \ | 865 | #define AR_SREV_9485(_ah) \ |
866 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) | 866 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) |
@@ -870,6 +870,11 @@ | |||
870 | #define AR_SREV_9485_11(_ah) \ | 870 | #define AR_SREV_9485_11(_ah) \ |
871 | (AR_SREV_9485(_ah) && \ | 871 | (AR_SREV_9485(_ah) && \ |
872 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11)) | 872 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11)) |
873 | #define AR_SREV_9485_OR_LATER(_ah) \ | ||
874 | (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485)) | ||
875 | |||
876 | #define AR_SREV_9340(_ah) \ | ||
877 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340)) | ||
873 | 878 | ||
874 | #define AR_SREV_9285E_20(_ah) \ | 879 | #define AR_SREV_9285E_20(_ah) \ |
875 | (AR_SREV_9285_12_OR_LATER(_ah) && \ | 880 | (AR_SREV_9285_12_OR_LATER(_ah) && \ |
@@ -912,11 +917,11 @@ enum ath_usb_dev { | |||
912 | #define AR_INTR_SPURIOUS 0xFFFFFFFF | 917 | #define AR_INTR_SPURIOUS 0xFFFFFFFF |
913 | 918 | ||
914 | 919 | ||
915 | #define AR_INTR_SYNC_CAUSE_CLR 0x4028 | 920 | #define AR_INTR_SYNC_CAUSE (AR_SREV_9340(ah) ? 0x4010 : 0x4028) |
921 | #define AR_INTR_SYNC_CAUSE_CLR (AR_SREV_9340(ah) ? 0x4010 : 0x4028) | ||
916 | 922 | ||
917 | #define AR_INTR_SYNC_CAUSE 0x4028 | ||
918 | 923 | ||
919 | #define AR_INTR_SYNC_ENABLE 0x402c | 924 | #define AR_INTR_SYNC_ENABLE (AR_SREV_9340(ah) ? 0x4014 : 0x402c) |
920 | #define AR_INTR_SYNC_ENABLE_GPIO 0xFFFC0000 | 925 | #define AR_INTR_SYNC_ENABLE_GPIO 0xFFFC0000 |
921 | #define AR_INTR_SYNC_ENABLE_GPIO_S 18 | 926 | #define AR_INTR_SYNC_ENABLE_GPIO_S 18 |
922 | 927 | ||
@@ -956,24 +961,24 @@ enum { | |||
956 | 961 | ||
957 | }; | 962 | }; |
958 | 963 | ||
959 | #define AR_INTR_ASYNC_MASK 0x4030 | 964 | #define AR_INTR_ASYNC_MASK (AR_SREV_9340(ah) ? 0x4018 : 0x4030) |
960 | #define AR_INTR_ASYNC_MASK_GPIO 0xFFFC0000 | 965 | #define AR_INTR_ASYNC_MASK_GPIO 0xFFFC0000 |
961 | #define AR_INTR_ASYNC_MASK_GPIO_S 18 | 966 | #define AR_INTR_ASYNC_MASK_GPIO_S 18 |
962 | 967 | ||
963 | #define AR_INTR_SYNC_MASK 0x4034 | 968 | #define AR_INTR_SYNC_MASK (AR_SREV_9340(ah) ? 0x401c : 0x4034) |
964 | #define AR_INTR_SYNC_MASK_GPIO 0xFFFC0000 | 969 | #define AR_INTR_SYNC_MASK_GPIO 0xFFFC0000 |
965 | #define AR_INTR_SYNC_MASK_GPIO_S 18 | 970 | #define AR_INTR_SYNC_MASK_GPIO_S 18 |
966 | 971 | ||
967 | #define AR_INTR_ASYNC_CAUSE_CLR 0x4038 | 972 | #define AR_INTR_ASYNC_CAUSE_CLR (AR_SREV_9340(ah) ? 0x4020 : 0x4038) |
968 | #define AR_INTR_ASYNC_CAUSE 0x4038 | 973 | #define AR_INTR_ASYNC_CAUSE (AR_SREV_9340(ah) ? 0x4020 : 0x4038) |
969 | 974 | ||
970 | #define AR_INTR_ASYNC_ENABLE 0x403c | 975 | #define AR_INTR_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4024 : 0x403c) |
971 | #define AR_INTR_ASYNC_ENABLE_GPIO 0xFFFC0000 | 976 | #define AR_INTR_ASYNC_ENABLE_GPIO 0xFFFC0000 |
972 | #define AR_INTR_ASYNC_ENABLE_GPIO_S 18 | 977 | #define AR_INTR_ASYNC_ENABLE_GPIO_S 18 |
973 | 978 | ||
974 | #define AR_PCIE_SERDES 0x4040 | 979 | #define AR_PCIE_SERDES 0x4040 |
975 | #define AR_PCIE_SERDES2 0x4044 | 980 | #define AR_PCIE_SERDES2 0x4044 |
976 | #define AR_PCIE_PM_CTRL 0x4014 | 981 | #define AR_PCIE_PM_CTRL (AR_SREV_9340(ah) ? 0x4004 : 0x4014) |
977 | #define AR_PCIE_PM_CTRL_ENA 0x00080000 | 982 | #define AR_PCIE_PM_CTRL_ENA 0x00080000 |
978 | 983 | ||
979 | #define AR_NUM_GPIO 14 | 984 | #define AR_NUM_GPIO 14 |
@@ -984,7 +989,7 @@ enum { | |||
984 | #define AR9300_NUM_GPIO 17 | 989 | #define AR9300_NUM_GPIO 17 |
985 | #define AR7010_NUM_GPIO 16 | 990 | #define AR7010_NUM_GPIO 16 |
986 | 991 | ||
987 | #define AR_GPIO_IN_OUT 0x4048 | 992 | #define AR_GPIO_IN_OUT (AR_SREV_9340(ah) ? 0x4028 : 0x4048) |
988 | #define AR_GPIO_IN_VAL 0x0FFFC000 | 993 | #define AR_GPIO_IN_VAL 0x0FFFC000 |
989 | #define AR_GPIO_IN_VAL_S 14 | 994 | #define AR_GPIO_IN_VAL_S 14 |
990 | #define AR928X_GPIO_IN_VAL 0x000FFC00 | 995 | #define AR928X_GPIO_IN_VAL 0x000FFC00 |
@@ -998,11 +1003,12 @@ enum { | |||
998 | #define AR7010_GPIO_IN_VAL 0x0000FFFF | 1003 | #define AR7010_GPIO_IN_VAL 0x0000FFFF |
999 | #define AR7010_GPIO_IN_VAL_S 0 | 1004 | #define AR7010_GPIO_IN_VAL_S 0 |
1000 | 1005 | ||
1001 | #define AR_GPIO_IN 0x404c | 1006 | #define AR_GPIO_IN (AR_SREV_9340(ah) ? 0x402c : 0x404c) |
1002 | #define AR9300_GPIO_IN_VAL 0x0001FFFF | 1007 | #define AR9300_GPIO_IN_VAL 0x0001FFFF |
1003 | #define AR9300_GPIO_IN_VAL_S 0 | 1008 | #define AR9300_GPIO_IN_VAL_S 0 |
1004 | 1009 | ||
1005 | #define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c) | 1010 | #define AR_GPIO_OE_OUT (AR_SREV_9340(ah) ? 0x4030 : \ |
1011 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)) | ||
1006 | #define AR_GPIO_OE_OUT_DRV 0x3 | 1012 | #define AR_GPIO_OE_OUT_DRV 0x3 |
1007 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 | 1013 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 |
1008 | #define AR_GPIO_OE_OUT_DRV_LOW 0x1 | 1014 | #define AR_GPIO_OE_OUT_DRV_LOW 0x1 |
@@ -1024,11 +1030,13 @@ enum { | |||
1024 | #define AR7010_GPIO_INT_MASK 0x52024 | 1030 | #define AR7010_GPIO_INT_MASK 0x52024 |
1025 | #define AR7010_GPIO_FUNCTION 0x52028 | 1031 | #define AR7010_GPIO_FUNCTION 0x52028 |
1026 | 1032 | ||
1027 | #define AR_GPIO_INTR_POL (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050) | 1033 | #define AR_GPIO_INTR_POL (AR_SREV_9340(ah) ? 0x4038 : \ |
1034 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050)) | ||
1028 | #define AR_GPIO_INTR_POL_VAL 0x0001FFFF | 1035 | #define AR_GPIO_INTR_POL_VAL 0x0001FFFF |
1029 | #define AR_GPIO_INTR_POL_VAL_S 0 | 1036 | #define AR_GPIO_INTR_POL_VAL_S 0 |
1030 | 1037 | ||
1031 | #define AR_GPIO_INPUT_EN_VAL (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054) | 1038 | #define AR_GPIO_INPUT_EN_VAL (AR_SREV_9340(ah) ? 0x403c : \ |
1039 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054)) | ||
1032 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004 | 1040 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004 |
1033 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2 | 1041 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2 |
1034 | #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008 | 1042 | #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008 |
@@ -1046,13 +1054,15 @@ enum { | |||
1046 | #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000 | 1054 | #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000 |
1047 | #define AR_GPIO_JTAG_DISABLE 0x00020000 | 1055 | #define AR_GPIO_JTAG_DISABLE 0x00020000 |
1048 | 1056 | ||
1049 | #define AR_GPIO_INPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058) | 1057 | #define AR_GPIO_INPUT_MUX1 (AR_SREV_9340(ah) ? 0x4040 : \ |
1058 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058)) | ||
1050 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000 | 1059 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000 |
1051 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16 | 1060 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16 |
1052 | #define AR_GPIO_INPUT_MUX1_BT_PRIORITY 0x00000f00 | 1061 | #define AR_GPIO_INPUT_MUX1_BT_PRIORITY 0x00000f00 |
1053 | #define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8 | 1062 | #define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8 |
1054 | 1063 | ||
1055 | #define AR_GPIO_INPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c) | 1064 | #define AR_GPIO_INPUT_MUX2 (AR_SREV_9340(ah) ? 0x4044 : \ |
1065 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c)) | ||
1056 | #define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f | 1066 | #define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f |
1057 | #define AR_GPIO_INPUT_MUX2_CLK25_S 0 | 1067 | #define AR_GPIO_INPUT_MUX2_CLK25_S 0 |
1058 | #define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0 | 1068 | #define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0 |
@@ -1060,13 +1070,18 @@ enum { | |||
1060 | #define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00 | 1070 | #define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00 |
1061 | #define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8 | 1071 | #define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8 |
1062 | 1072 | ||
1063 | #define AR_GPIO_OUTPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060) | 1073 | #define AR_GPIO_OUTPUT_MUX1 (AR_SREV_9340(ah) ? 0x4048 : \ |
1064 | #define AR_GPIO_OUTPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064) | 1074 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060)) |
1065 | #define AR_GPIO_OUTPUT_MUX3 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068) | 1075 | #define AR_GPIO_OUTPUT_MUX2 (AR_SREV_9340(ah) ? 0x404c : \ |
1076 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064)) | ||
1077 | #define AR_GPIO_OUTPUT_MUX3 (AR_SREV_9340(ah) ? 0x4050 : \ | ||
1078 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068)) | ||
1066 | 1079 | ||
1067 | #define AR_INPUT_STATE (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c) | 1080 | #define AR_INPUT_STATE (AR_SREV_9340(ah) ? 0x4054 : \ |
1081 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c)) | ||
1068 | 1082 | ||
1069 | #define AR_EEPROM_STATUS_DATA (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c) | 1083 | #define AR_EEPROM_STATUS_DATA (AR_SREV_9340(ah) ? 0x40c8 : \ |
1084 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c)) | ||
1070 | #define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff | 1085 | #define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff |
1071 | #define AR_EEPROM_STATUS_DATA_VAL_S 0 | 1086 | #define AR_EEPROM_STATUS_DATA_VAL_S 0 |
1072 | #define AR_EEPROM_STATUS_DATA_BUSY 0x00010000 | 1087 | #define AR_EEPROM_STATUS_DATA_BUSY 0x00010000 |
@@ -1074,28 +1089,51 @@ enum { | |||
1074 | #define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000 | 1089 | #define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000 |
1075 | #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000 | 1090 | #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000 |
1076 | 1091 | ||
1077 | #define AR_OBS (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080) | 1092 | #define AR_OBS (AR_SREV_9340(ah) ? 0x405c : \ |
1093 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080)) | ||
1078 | 1094 | ||
1079 | #define AR_GPIO_PDPU (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088) | 1095 | #define AR_GPIO_PDPU (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088) |
1080 | 1096 | ||
1081 | #define AR_PCIE_MSI (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094) | 1097 | #define AR_PCIE_MSI (AR_SREV_9340(ah) ? 0x40d8 : \ |
1098 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094)) | ||
1082 | #define AR_PCIE_MSI_ENABLE 0x00000001 | 1099 | #define AR_PCIE_MSI_ENABLE 0x00000001 |
1083 | 1100 | ||
1084 | #define AR_INTR_PRIO_SYNC_ENABLE 0x40c4 | 1101 | #define AR_INTR_PRIO_SYNC_ENABLE (AR_SREV_9340(ah) ? 0x4088 : 0x40c4) |
1085 | #define AR_INTR_PRIO_ASYNC_MASK 0x40c8 | 1102 | #define AR_INTR_PRIO_ASYNC_MASK (AR_SREV_9340(ah) ? 0x408c : 0x40c8) |
1086 | #define AR_INTR_PRIO_SYNC_MASK 0x40cc | 1103 | #define AR_INTR_PRIO_SYNC_MASK (AR_SREV_9340(ah) ? 0x4090 : 0x40cc) |
1087 | #define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4 | 1104 | #define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4) |
1088 | #define AR_ENT_OTP 0x40d8 | 1105 | #define AR_ENT_OTP 0x40d8 |
1089 | #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 | 1106 | #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 |
1090 | #define AR_ENT_OTP_MPSD 0x00800000 | 1107 | #define AR_ENT_OTP_MPSD 0x00800000 |
1091 | #define AR_CH0_BB_DPLL2 0x16184 | 1108 | |
1109 | #define AR_CH0_BB_DPLL1 0x16180 | ||
1110 | #define AR_CH0_BB_DPLL1_REFDIV 0xF8000000 | ||
1111 | #define AR_CH0_BB_DPLL1_REFDIV_S 27 | ||
1112 | #define AR_CH0_BB_DPLL1_NINI 0x07FC0000 | ||
1113 | #define AR_CH0_BB_DPLL1_NINI_S 18 | ||
1114 | #define AR_CH0_BB_DPLL1_NFRAC 0x0003FFFF | ||
1115 | #define AR_CH0_BB_DPLL1_NFRAC_S 0 | ||
1116 | |||
1117 | #define AR_CH0_BB_DPLL2 0x16184 | ||
1118 | #define AR_CH0_BB_DPLL2_LOCAL_PLL 0x40000000 | ||
1119 | #define AR_CH0_BB_DPLL2_LOCAL_PLL_S 30 | ||
1120 | #define AR_CH0_DPLL2_KI 0x3C000000 | ||
1121 | #define AR_CH0_DPLL2_KI_S 26 | ||
1122 | #define AR_CH0_DPLL2_KD 0x03F80000 | ||
1123 | #define AR_CH0_DPLL2_KD_S 19 | ||
1124 | #define AR_CH0_BB_DPLL2_EN_NEGTRIG 0x00040000 | ||
1125 | #define AR_CH0_BB_DPLL2_EN_NEGTRIG_S 18 | ||
1126 | #define AR_CH0_BB_DPLL2_PLL_PWD 0x00010000 | ||
1127 | #define AR_CH0_BB_DPLL2_PLL_PWD_S 16 | ||
1128 | #define AR_CH0_BB_DPLL2_OUTDIV 0x0000E000 | ||
1129 | #define AR_CH0_BB_DPLL2_OUTDIV_S 13 | ||
1130 | |||
1092 | #define AR_CH0_BB_DPLL3 0x16188 | 1131 | #define AR_CH0_BB_DPLL3 0x16188 |
1132 | #define AR_CH0_BB_DPLL3_PHASE_SHIFT 0x3F800000 | ||
1133 | #define AR_CH0_BB_DPLL3_PHASE_SHIFT_S 23 | ||
1134 | |||
1093 | #define AR_CH0_DDR_DPLL2 0x16244 | 1135 | #define AR_CH0_DDR_DPLL2 0x16244 |
1094 | #define AR_CH0_DDR_DPLL3 0x16248 | 1136 | #define AR_CH0_DDR_DPLL3 0x16248 |
1095 | #define AR_CH0_DPLL2_KD 0x03F80000 | ||
1096 | #define AR_CH0_DPLL2_KD_S 19 | ||
1097 | #define AR_CH0_DPLL2_KI 0x3C000000 | ||
1098 | #define AR_CH0_DPLL2_KI_S 26 | ||
1099 | #define AR_CH0_DPLL3_PHASE_SHIFT 0x3F800000 | 1137 | #define AR_CH0_DPLL3_PHASE_SHIFT 0x3F800000 |
1100 | #define AR_CH0_DPLL3_PHASE_SHIFT_S 23 | 1138 | #define AR_CH0_DPLL3_PHASE_SHIFT_S 23 |
1101 | #define AR_PHY_CCA_NOM_VAL_2GHZ -118 | 1139 | #define AR_PHY_CCA_NOM_VAL_2GHZ -118 |
@@ -1144,6 +1182,7 @@ enum { | |||
1144 | #define AR_RTC_PLL_REFDIV_5 0x000000c0 | 1182 | #define AR_RTC_PLL_REFDIV_5 0x000000c0 |
1145 | #define AR_RTC_PLL_CLKSEL 0x00000300 | 1183 | #define AR_RTC_PLL_CLKSEL 0x00000300 |
1146 | #define AR_RTC_PLL_CLKSEL_S 8 | 1184 | #define AR_RTC_PLL_CLKSEL_S 8 |
1185 | #define AR_RTC_PLL_BYPASS 0x00010000 | ||
1147 | 1186 | ||
1148 | #define PLL3 0x16188 | 1187 | #define PLL3 0x16188 |
1149 | #define PLL3_DO_MEAS_MASK 0x40000000 | 1188 | #define PLL3_DO_MEAS_MASK 0x40000000 |
@@ -1190,7 +1229,8 @@ enum { | |||
1190 | 1229 | ||
1191 | /* RTC_DERIVED_* - only for AR9100 */ | 1230 | /* RTC_DERIVED_* - only for AR9100 */ |
1192 | 1231 | ||
1193 | #define AR_RTC_DERIVED_CLK (AR_RTC_BASE + 0x0038) | 1232 | #define AR_RTC_DERIVED_CLK \ |
1233 | (AR_SREV_9100(ah) ? (AR_RTC_BASE + 0x0038) : 0x7038) | ||
1194 | #define AR_RTC_DERIVED_CLK_PERIOD 0x0000fffe | 1234 | #define AR_RTC_DERIVED_CLK_PERIOD 0x0000fffe |
1195 | #define AR_RTC_DERIVED_CLK_PERIOD_S 1 | 1235 | #define AR_RTC_DERIVED_CLK_PERIOD_S 1 |
1196 | 1236 | ||
@@ -1396,6 +1436,7 @@ enum { | |||
1396 | #define AR_STA_ID1_PCF 0x00100000 | 1436 | #define AR_STA_ID1_PCF 0x00100000 |
1397 | #define AR_STA_ID1_USE_DEFANT 0x00200000 | 1437 | #define AR_STA_ID1_USE_DEFANT 0x00200000 |
1398 | #define AR_STA_ID1_DEFANT_UPDATE 0x00400000 | 1438 | #define AR_STA_ID1_DEFANT_UPDATE 0x00400000 |
1439 | #define AR_STA_ID1_AR9100_BA_FIX 0x00400000 | ||
1399 | #define AR_STA_ID1_RTS_USE_DEF 0x00800000 | 1440 | #define AR_STA_ID1_RTS_USE_DEF 0x00800000 |
1400 | #define AR_STA_ID1_ACKCTS_6MB 0x01000000 | 1441 | #define AR_STA_ID1_ACKCTS_6MB 0x01000000 |
1401 | #define AR_STA_ID1_BASE_RATE_11B 0x02000000 | 1442 | #define AR_STA_ID1_BASE_RATE_11B 0x02000000 |
@@ -1668,6 +1709,22 @@ enum { | |||
1668 | #define AR_BTCOEX_WL_WGHT 0xffff0000 | 1709 | #define AR_BTCOEX_WL_WGHT 0xffff0000 |
1669 | #define AR_BTCOEX_WL_WGHT_S 16 | 1710 | #define AR_BTCOEX_WL_WGHT_S 16 |
1670 | 1711 | ||
1712 | #define AR_BT_COEX_WL_WEIGHTS0 0x8174 | ||
1713 | #define AR_BT_COEX_WL_WEIGHTS1 0x81c4 | ||
1714 | |||
1715 | #define AR_BT_COEX_BT_WEIGHTS0 0x83ac | ||
1716 | #define AR_BT_COEX_BT_WEIGHTS1 0x83b0 | ||
1717 | #define AR_BT_COEX_BT_WEIGHTS2 0x83b4 | ||
1718 | #define AR_BT_COEX_BT_WEIGHTS3 0x83b8 | ||
1719 | |||
1720 | #define AR9300_BT_WGHT 0xcccc4444 | ||
1721 | #define AR9300_STOMP_ALL_WLAN_WGHT0 0xfffffff0 | ||
1722 | #define AR9300_STOMP_ALL_WLAN_WGHT1 0xfffffff0 | ||
1723 | #define AR9300_STOMP_LOW_WLAN_WGHT0 0x88888880 | ||
1724 | #define AR9300_STOMP_LOW_WLAN_WGHT1 0x88888880 | ||
1725 | #define AR9300_STOMP_NONE_WLAN_WGHT0 0x00000000 | ||
1726 | #define AR9300_STOMP_NONE_WLAN_WGHT1 0x00000000 | ||
1727 | |||
1671 | #define AR_BT_COEX_MODE2 0x817c | 1728 | #define AR_BT_COEX_MODE2 0x817c |
1672 | #define AR_BT_BCN_MISS_THRESH 0x000000ff | 1729 | #define AR_BT_BCN_MISS_THRESH 0x000000ff |
1673 | #define AR_BT_BCN_MISS_THRESH_S 0 | 1730 | #define AR_BT_BCN_MISS_THRESH_S 0 |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index d3d24904f62..f9b1eb4853c 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c | |||
@@ -23,20 +23,18 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
23 | return "WMI_ECHO_CMDID"; | 23 | return "WMI_ECHO_CMDID"; |
24 | case WMI_ACCESS_MEMORY_CMDID: | 24 | case WMI_ACCESS_MEMORY_CMDID: |
25 | return "WMI_ACCESS_MEMORY_CMDID"; | 25 | return "WMI_ACCESS_MEMORY_CMDID"; |
26 | case WMI_GET_FW_VERSION: | ||
27 | return "WMI_GET_FW_VERSION"; | ||
26 | case WMI_DISABLE_INTR_CMDID: | 28 | case WMI_DISABLE_INTR_CMDID: |
27 | return "WMI_DISABLE_INTR_CMDID"; | 29 | return "WMI_DISABLE_INTR_CMDID"; |
28 | case WMI_ENABLE_INTR_CMDID: | 30 | case WMI_ENABLE_INTR_CMDID: |
29 | return "WMI_ENABLE_INTR_CMDID"; | 31 | return "WMI_ENABLE_INTR_CMDID"; |
30 | case WMI_RX_LINK_CMDID: | ||
31 | return "WMI_RX_LINK_CMDID"; | ||
32 | case WMI_ATH_INIT_CMDID: | 32 | case WMI_ATH_INIT_CMDID: |
33 | return "WMI_ATH_INIT_CMDID"; | 33 | return "WMI_ATH_INIT_CMDID"; |
34 | case WMI_ABORT_TXQ_CMDID: | 34 | case WMI_ABORT_TXQ_CMDID: |
35 | return "WMI_ABORT_TXQ_CMDID"; | 35 | return "WMI_ABORT_TXQ_CMDID"; |
36 | case WMI_STOP_TX_DMA_CMDID: | 36 | case WMI_STOP_TX_DMA_CMDID: |
37 | return "WMI_STOP_TX_DMA_CMDID"; | 37 | return "WMI_STOP_TX_DMA_CMDID"; |
38 | case WMI_STOP_DMA_RECV_CMDID: | ||
39 | return "WMI_STOP_DMA_RECV_CMDID"; | ||
40 | case WMI_ABORT_TX_DMA_CMDID: | 38 | case WMI_ABORT_TX_DMA_CMDID: |
41 | return "WMI_ABORT_TX_DMA_CMDID"; | 39 | return "WMI_ABORT_TX_DMA_CMDID"; |
42 | case WMI_DRAIN_TXQ_CMDID: | 40 | case WMI_DRAIN_TXQ_CMDID: |
@@ -51,8 +49,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
51 | return "WMI_FLUSH_RECV_CMDID"; | 49 | return "WMI_FLUSH_RECV_CMDID"; |
52 | case WMI_SET_MODE_CMDID: | 50 | case WMI_SET_MODE_CMDID: |
53 | return "WMI_SET_MODE_CMDID"; | 51 | return "WMI_SET_MODE_CMDID"; |
54 | case WMI_RESET_CMDID: | ||
55 | return "WMI_RESET_CMDID"; | ||
56 | case WMI_NODE_CREATE_CMDID: | 52 | case WMI_NODE_CREATE_CMDID: |
57 | return "WMI_NODE_CREATE_CMDID"; | 53 | return "WMI_NODE_CREATE_CMDID"; |
58 | case WMI_NODE_REMOVE_CMDID: | 54 | case WMI_NODE_REMOVE_CMDID: |
@@ -61,8 +57,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
61 | return "WMI_VAP_REMOVE_CMDID"; | 57 | return "WMI_VAP_REMOVE_CMDID"; |
62 | case WMI_VAP_CREATE_CMDID: | 58 | case WMI_VAP_CREATE_CMDID: |
63 | return "WMI_VAP_CREATE_CMDID"; | 59 | return "WMI_VAP_CREATE_CMDID"; |
64 | case WMI_BEACON_UPDATE_CMDID: | ||
65 | return "WMI_BEACON_UPDATE_CMDID"; | ||
66 | case WMI_REG_READ_CMDID: | 60 | case WMI_REG_READ_CMDID: |
67 | return "WMI_REG_READ_CMDID"; | 61 | return "WMI_REG_READ_CMDID"; |
68 | case WMI_REG_WRITE_CMDID: | 62 | case WMI_REG_WRITE_CMDID: |
@@ -71,22 +65,22 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
71 | return "WMI_RC_STATE_CHANGE_CMDID"; | 65 | return "WMI_RC_STATE_CHANGE_CMDID"; |
72 | case WMI_RC_RATE_UPDATE_CMDID: | 66 | case WMI_RC_RATE_UPDATE_CMDID: |
73 | return "WMI_RC_RATE_UPDATE_CMDID"; | 67 | return "WMI_RC_RATE_UPDATE_CMDID"; |
74 | case WMI_DEBUG_INFO_CMDID: | ||
75 | return "WMI_DEBUG_INFO_CMDID"; | ||
76 | case WMI_HOST_ATTACH: | ||
77 | return "WMI_HOST_ATTACH"; | ||
78 | case WMI_TARGET_IC_UPDATE_CMDID: | 68 | case WMI_TARGET_IC_UPDATE_CMDID: |
79 | return "WMI_TARGET_IC_UPDATE_CMDID"; | 69 | return "WMI_TARGET_IC_UPDATE_CMDID"; |
80 | case WMI_TGT_STATS_CMDID: | ||
81 | return "WMI_TGT_STATS_CMDID"; | ||
82 | case WMI_TX_AGGR_ENABLE_CMDID: | 70 | case WMI_TX_AGGR_ENABLE_CMDID: |
83 | return "WMI_TX_AGGR_ENABLE_CMDID"; | 71 | return "WMI_TX_AGGR_ENABLE_CMDID"; |
84 | case WMI_TGT_DETACH_CMDID: | 72 | case WMI_TGT_DETACH_CMDID: |
85 | return "WMI_TGT_DETACH_CMDID"; | 73 | return "WMI_TGT_DETACH_CMDID"; |
86 | case WMI_TGT_TXQ_ENABLE_CMDID: | 74 | case WMI_NODE_UPDATE_CMDID: |
87 | return "WMI_TGT_TXQ_ENABLE_CMDID"; | 75 | return "WMI_NODE_UPDATE_CMDID"; |
88 | case WMI_AGGR_LIMIT_CMD: | 76 | case WMI_INT_STATS_CMDID: |
89 | return "WMI_AGGR_LIMIT_CMD"; | 77 | return "WMI_INT_STATS_CMDID"; |
78 | case WMI_TX_STATS_CMDID: | ||
79 | return "WMI_TX_STATS_CMDID"; | ||
80 | case WMI_RX_STATS_CMDID: | ||
81 | return "WMI_RX_STATS_CMDID"; | ||
82 | case WMI_BITRATE_MASK_CMDID: | ||
83 | return "WMI_BITRATE_MASK_CMDID"; | ||
90 | } | 84 | } |
91 | 85 | ||
92 | return "Bogus"; | 86 | return "Bogus"; |
@@ -102,9 +96,15 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv) | |||
102 | 96 | ||
103 | wmi->drv_priv = priv; | 97 | wmi->drv_priv = priv; |
104 | wmi->stopped = false; | 98 | wmi->stopped = false; |
99 | skb_queue_head_init(&wmi->wmi_event_queue); | ||
100 | spin_lock_init(&wmi->wmi_lock); | ||
101 | spin_lock_init(&wmi->event_lock); | ||
105 | mutex_init(&wmi->op_mutex); | 102 | mutex_init(&wmi->op_mutex); |
106 | mutex_init(&wmi->multi_write_mutex); | 103 | mutex_init(&wmi->multi_write_mutex); |
107 | init_completion(&wmi->cmd_wait); | 104 | init_completion(&wmi->cmd_wait); |
105 | INIT_LIST_HEAD(&wmi->pending_tx_events); | ||
106 | tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet, | ||
107 | (unsigned long)wmi); | ||
108 | 108 | ||
109 | return wmi; | 109 | return wmi; |
110 | } | 110 | } |
@@ -120,11 +120,65 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv) | |||
120 | kfree(priv->wmi); | 120 | kfree(priv->wmi); |
121 | } | 121 | } |
122 | 122 | ||
123 | void ath9k_swba_tasklet(unsigned long data) | 123 | void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv) |
124 | { | 124 | { |
125 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; | 125 | unsigned long flags; |
126 | 126 | ||
127 | ath9k_htc_swba(priv, priv->wmi->beacon_pending); | 127 | tasklet_kill(&priv->wmi->wmi_event_tasklet); |
128 | spin_lock_irqsave(&priv->wmi->wmi_lock, flags); | ||
129 | __skb_queue_purge(&priv->wmi->wmi_event_queue); | ||
130 | spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); | ||
131 | } | ||
132 | |||
133 | void ath9k_wmi_event_tasklet(unsigned long data) | ||
134 | { | ||
135 | struct wmi *wmi = (struct wmi *)data; | ||
136 | struct ath9k_htc_priv *priv = wmi->drv_priv; | ||
137 | struct wmi_cmd_hdr *hdr; | ||
138 | void *wmi_event; | ||
139 | struct wmi_event_swba *swba; | ||
140 | struct sk_buff *skb = NULL; | ||
141 | unsigned long flags; | ||
142 | u16 cmd_id; | ||
143 | |||
144 | do { | ||
145 | spin_lock_irqsave(&wmi->wmi_lock, flags); | ||
146 | skb = __skb_dequeue(&wmi->wmi_event_queue); | ||
147 | if (!skb) { | ||
148 | spin_unlock_irqrestore(&wmi->wmi_lock, flags); | ||
149 | return; | ||
150 | } | ||
151 | spin_unlock_irqrestore(&wmi->wmi_lock, flags); | ||
152 | |||
153 | hdr = (struct wmi_cmd_hdr *) skb->data; | ||
154 | cmd_id = be16_to_cpu(hdr->command_id); | ||
155 | wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); | ||
156 | |||
157 | switch (cmd_id) { | ||
158 | case WMI_SWBA_EVENTID: | ||
159 | swba = (struct wmi_event_swba *) wmi_event; | ||
160 | ath9k_htc_swba(priv, swba); | ||
161 | break; | ||
162 | case WMI_FATAL_EVENTID: | ||
163 | ieee80211_queue_work(wmi->drv_priv->hw, | ||
164 | &wmi->drv_priv->fatal_work); | ||
165 | break; | ||
166 | case WMI_TXSTATUS_EVENTID: | ||
167 | spin_lock_bh(&priv->tx.tx_lock); | ||
168 | if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { | ||
169 | spin_unlock_bh(&priv->tx.tx_lock); | ||
170 | break; | ||
171 | } | ||
172 | spin_unlock_bh(&priv->tx.tx_lock); | ||
173 | |||
174 | ath9k_htc_txstatus(priv, wmi_event); | ||
175 | break; | ||
176 | default: | ||
177 | break; | ||
178 | } | ||
179 | |||
180 | kfree_skb(skb); | ||
181 | } while (1); | ||
128 | } | 182 | } |
129 | 183 | ||
130 | void ath9k_fatal_work(struct work_struct *work) | 184 | void ath9k_fatal_work(struct work_struct *work) |
@@ -153,10 +207,6 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, | |||
153 | struct wmi *wmi = (struct wmi *) priv; | 207 | struct wmi *wmi = (struct wmi *) priv; |
154 | struct wmi_cmd_hdr *hdr; | 208 | struct wmi_cmd_hdr *hdr; |
155 | u16 cmd_id; | 209 | u16 cmd_id; |
156 | void *wmi_event; | ||
157 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
158 | __be32 txrate; | ||
159 | #endif | ||
160 | 210 | ||
161 | if (unlikely(wmi->stopped)) | 211 | if (unlikely(wmi->stopped)) |
162 | goto free_skb; | 212 | goto free_skb; |
@@ -165,26 +215,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, | |||
165 | cmd_id = be16_to_cpu(hdr->command_id); | 215 | cmd_id = be16_to_cpu(hdr->command_id); |
166 | 216 | ||
167 | if (cmd_id & 0x1000) { | 217 | if (cmd_id & 0x1000) { |
168 | wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); | 218 | spin_lock(&wmi->wmi_lock); |
169 | switch (cmd_id) { | 219 | __skb_queue_tail(&wmi->wmi_event_queue, skb); |
170 | case WMI_SWBA_EVENTID: | 220 | spin_unlock(&wmi->wmi_lock); |
171 | wmi->beacon_pending = *(u8 *)wmi_event; | 221 | tasklet_schedule(&wmi->wmi_event_tasklet); |
172 | tasklet_schedule(&wmi->drv_priv->swba_tasklet); | ||
173 | break; | ||
174 | case WMI_FATAL_EVENTID: | ||
175 | ieee80211_queue_work(wmi->drv_priv->hw, | ||
176 | &wmi->drv_priv->fatal_work); | ||
177 | break; | ||
178 | case WMI_TXRATE_EVENTID: | ||
179 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
180 | txrate = ((struct wmi_event_txrate *)wmi_event)->txrate; | ||
181 | wmi->drv_priv->debug.txrate = be32_to_cpu(txrate); | ||
182 | #endif | ||
183 | break; | ||
184 | default: | ||
185 | break; | ||
186 | } | ||
187 | kfree_skb(skb); | ||
188 | return; | 222 | return; |
189 | } | 223 | } |
190 | 224 | ||
@@ -243,7 +277,7 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi, | |||
243 | hdr->command_id = cpu_to_be16(cmd); | 277 | hdr->command_id = cpu_to_be16(cmd); |
244 | hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); | 278 | hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); |
245 | 279 | ||
246 | return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL); | 280 | return htc_send_epid(wmi->htc, skb, wmi->ctrl_epid); |
247 | } | 281 | } |
248 | 282 | ||
249 | int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | 283 | int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 42084277522..6095eeb6e02 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h | |||
@@ -17,7 +17,6 @@ | |||
17 | #ifndef WMI_H | 17 | #ifndef WMI_H |
18 | #define WMI_H | 18 | #define WMI_H |
19 | 19 | ||
20 | |||
21 | struct wmi_event_txrate { | 20 | struct wmi_event_txrate { |
22 | __be32 txrate; | 21 | __be32 txrate; |
23 | struct { | 22 | struct { |
@@ -31,18 +30,65 @@ struct wmi_cmd_hdr { | |||
31 | __be16 seq_no; | 30 | __be16 seq_no; |
32 | } __packed; | 31 | } __packed; |
33 | 32 | ||
33 | struct wmi_fw_version { | ||
34 | __be16 major; | ||
35 | __be16 minor; | ||
36 | |||
37 | } __packed; | ||
38 | |||
39 | struct wmi_event_swba { | ||
40 | __be64 tsf; | ||
41 | u8 beacon_pending; | ||
42 | }; | ||
43 | |||
44 | /* | ||
45 | * 64 - HTC header - WMI header - 1 / txstatus | ||
46 | * And some other hdr. space is also accounted for. | ||
47 | * 12 seems to be the magic number. | ||
48 | */ | ||
49 | #define HTC_MAX_TX_STATUS 12 | ||
50 | |||
51 | #define ATH9K_HTC_TXSTAT_ACK BIT(0) | ||
52 | #define ATH9K_HTC_TXSTAT_FILT BIT(1) | ||
53 | #define ATH9K_HTC_TXSTAT_RTC_CTS BIT(2) | ||
54 | #define ATH9K_HTC_TXSTAT_MCS BIT(3) | ||
55 | #define ATH9K_HTC_TXSTAT_CW40 BIT(4) | ||
56 | #define ATH9K_HTC_TXSTAT_SGI BIT(5) | ||
57 | |||
58 | /* | ||
59 | * Legacy rates are indicated as indices. | ||
60 | * HT rates are indicated as dot11 numbers. | ||
61 | * This allows us to resrict the rate field | ||
62 | * to 4 bits. | ||
63 | */ | ||
64 | #define ATH9K_HTC_TXSTAT_RATE 0x0f | ||
65 | #define ATH9K_HTC_TXSTAT_RATE_S 0 | ||
66 | |||
67 | #define ATH9K_HTC_TXSTAT_EPID 0xf0 | ||
68 | #define ATH9K_HTC_TXSTAT_EPID_S 4 | ||
69 | |||
70 | struct __wmi_event_txstatus { | ||
71 | u8 cookie; | ||
72 | u8 ts_rate; /* Also holds EP ID */ | ||
73 | u8 ts_flags; | ||
74 | }; | ||
75 | |||
76 | struct wmi_event_txstatus { | ||
77 | u8 cnt; | ||
78 | struct __wmi_event_txstatus txstatus[HTC_MAX_TX_STATUS]; | ||
79 | } __packed; | ||
80 | |||
34 | enum wmi_cmd_id { | 81 | enum wmi_cmd_id { |
35 | WMI_ECHO_CMDID = 0x0001, | 82 | WMI_ECHO_CMDID = 0x0001, |
36 | WMI_ACCESS_MEMORY_CMDID, | 83 | WMI_ACCESS_MEMORY_CMDID, |
37 | 84 | ||
38 | /* Commands to Target */ | 85 | /* Commands to Target */ |
86 | WMI_GET_FW_VERSION, | ||
39 | WMI_DISABLE_INTR_CMDID, | 87 | WMI_DISABLE_INTR_CMDID, |
40 | WMI_ENABLE_INTR_CMDID, | 88 | WMI_ENABLE_INTR_CMDID, |
41 | WMI_RX_LINK_CMDID, | ||
42 | WMI_ATH_INIT_CMDID, | 89 | WMI_ATH_INIT_CMDID, |
43 | WMI_ABORT_TXQ_CMDID, | 90 | WMI_ABORT_TXQ_CMDID, |
44 | WMI_STOP_TX_DMA_CMDID, | 91 | WMI_STOP_TX_DMA_CMDID, |
45 | WMI_STOP_DMA_RECV_CMDID, | ||
46 | WMI_ABORT_TX_DMA_CMDID, | 92 | WMI_ABORT_TX_DMA_CMDID, |
47 | WMI_DRAIN_TXQ_CMDID, | 93 | WMI_DRAIN_TXQ_CMDID, |
48 | WMI_DRAIN_TXQ_ALL_CMDID, | 94 | WMI_DRAIN_TXQ_ALL_CMDID, |
@@ -50,24 +96,22 @@ enum wmi_cmd_id { | |||
50 | WMI_STOP_RECV_CMDID, | 96 | WMI_STOP_RECV_CMDID, |
51 | WMI_FLUSH_RECV_CMDID, | 97 | WMI_FLUSH_RECV_CMDID, |
52 | WMI_SET_MODE_CMDID, | 98 | WMI_SET_MODE_CMDID, |
53 | WMI_RESET_CMDID, | ||
54 | WMI_NODE_CREATE_CMDID, | 99 | WMI_NODE_CREATE_CMDID, |
55 | WMI_NODE_REMOVE_CMDID, | 100 | WMI_NODE_REMOVE_CMDID, |
56 | WMI_VAP_REMOVE_CMDID, | 101 | WMI_VAP_REMOVE_CMDID, |
57 | WMI_VAP_CREATE_CMDID, | 102 | WMI_VAP_CREATE_CMDID, |
58 | WMI_BEACON_UPDATE_CMDID, | ||
59 | WMI_REG_READ_CMDID, | 103 | WMI_REG_READ_CMDID, |
60 | WMI_REG_WRITE_CMDID, | 104 | WMI_REG_WRITE_CMDID, |
61 | WMI_RC_STATE_CHANGE_CMDID, | 105 | WMI_RC_STATE_CHANGE_CMDID, |
62 | WMI_RC_RATE_UPDATE_CMDID, | 106 | WMI_RC_RATE_UPDATE_CMDID, |
63 | WMI_DEBUG_INFO_CMDID, | ||
64 | WMI_HOST_ATTACH, | ||
65 | WMI_TARGET_IC_UPDATE_CMDID, | 107 | WMI_TARGET_IC_UPDATE_CMDID, |
66 | WMI_TGT_STATS_CMDID, | ||
67 | WMI_TX_AGGR_ENABLE_CMDID, | 108 | WMI_TX_AGGR_ENABLE_CMDID, |
68 | WMI_TGT_DETACH_CMDID, | 109 | WMI_TGT_DETACH_CMDID, |
69 | WMI_TGT_TXQ_ENABLE_CMDID, | 110 | WMI_NODE_UPDATE_CMDID, |
70 | WMI_AGGR_LIMIT_CMD = 0x0026, | 111 | WMI_INT_STATS_CMDID, |
112 | WMI_TX_STATS_CMDID, | ||
113 | WMI_RX_STATS_CMDID, | ||
114 | WMI_BITRATE_MASK_CMDID, | ||
71 | }; | 115 | }; |
72 | 116 | ||
73 | enum wmi_event_id { | 117 | enum wmi_event_id { |
@@ -76,9 +120,8 @@ enum wmi_event_id { | |||
76 | WMI_FATAL_EVENTID, | 120 | WMI_FATAL_EVENTID, |
77 | WMI_TXTO_EVENTID, | 121 | WMI_TXTO_EVENTID, |
78 | WMI_BMISS_EVENTID, | 122 | WMI_BMISS_EVENTID, |
79 | WMI_WLAN_TXCOMP_EVENTID, | ||
80 | WMI_DELBA_EVENTID, | 123 | WMI_DELBA_EVENTID, |
81 | WMI_TXRATE_EVENTID, | 124 | WMI_TXSTATUS_EVENTID, |
82 | }; | 125 | }; |
83 | 126 | ||
84 | #define MAX_CMD_NUMBER 62 | 127 | #define MAX_CMD_NUMBER 62 |
@@ -88,6 +131,12 @@ struct register_write { | |||
88 | __be32 val; | 131 | __be32 val; |
89 | }; | 132 | }; |
90 | 133 | ||
134 | struct ath9k_htc_tx_event { | ||
135 | int count; | ||
136 | struct __wmi_event_txstatus txs; | ||
137 | struct list_head list; | ||
138 | }; | ||
139 | |||
91 | struct wmi { | 140 | struct wmi { |
92 | struct ath9k_htc_priv *drv_priv; | 141 | struct ath9k_htc_priv *drv_priv; |
93 | struct htc_target *htc; | 142 | struct htc_target *htc; |
@@ -95,12 +144,16 @@ struct wmi { | |||
95 | struct mutex op_mutex; | 144 | struct mutex op_mutex; |
96 | struct completion cmd_wait; | 145 | struct completion cmd_wait; |
97 | enum wmi_cmd_id last_cmd_id; | 146 | enum wmi_cmd_id last_cmd_id; |
147 | struct sk_buff_head wmi_event_queue; | ||
148 | struct tasklet_struct wmi_event_tasklet; | ||
98 | u16 tx_seq_id; | 149 | u16 tx_seq_id; |
99 | u8 *cmd_rsp_buf; | 150 | u8 *cmd_rsp_buf; |
100 | u32 cmd_rsp_len; | 151 | u32 cmd_rsp_len; |
101 | bool stopped; | 152 | bool stopped; |
102 | 153 | ||
103 | u8 beacon_pending; | 154 | struct list_head pending_tx_events; |
155 | spinlock_t event_lock; | ||
156 | |||
104 | spinlock_t wmi_lock; | 157 | spinlock_t wmi_lock; |
105 | 158 | ||
106 | atomic_t mwrite_cnt; | 159 | atomic_t mwrite_cnt; |
@@ -117,8 +170,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | |||
117 | u8 *cmd_buf, u32 cmd_len, | 170 | u8 *cmd_buf, u32 cmd_len, |
118 | u8 *rsp_buf, u32 rsp_len, | 171 | u8 *rsp_buf, u32 rsp_len, |
119 | u32 timeout); | 172 | u32 timeout); |
120 | void ath9k_swba_tasklet(unsigned long data); | 173 | void ath9k_wmi_event_tasklet(unsigned long data); |
121 | void ath9k_fatal_work(struct work_struct *work); | 174 | void ath9k_fatal_work(struct work_struct *work); |
175 | void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv); | ||
122 | 176 | ||
123 | #define WMI_CMD(_wmi_cmd) \ | 177 | #define WMI_CMD(_wmi_cmd) \ |
124 | do { \ | 178 | do { \ |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 88fa7fdffd0..97dd1fac98b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -357,6 +357,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
357 | struct ath_frame_info *fi; | 357 | struct ath_frame_info *fi; |
358 | int nframes; | 358 | int nframes; |
359 | u8 tidno; | 359 | u8 tidno; |
360 | bool clear_filter; | ||
360 | 361 | ||
361 | skb = bf->bf_mpdu; | 362 | skb = bf->bf_mpdu; |
362 | hdr = (struct ieee80211_hdr *)skb->data; | 363 | hdr = (struct ieee80211_hdr *)skb->data; |
@@ -441,22 +442,24 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
441 | /* transmit completion */ | 442 | /* transmit completion */ |
442 | acked_cnt++; | 443 | acked_cnt++; |
443 | } else { | 444 | } else { |
444 | if (!(tid->state & AGGR_CLEANUP) && retry) { | 445 | if ((tid->state & AGGR_CLEANUP) || !retry) { |
445 | if (fi->retries < ATH_MAX_SW_RETRIES) { | ||
446 | ath_tx_set_retry(sc, txq, bf->bf_mpdu); | ||
447 | txpending = 1; | ||
448 | } else { | ||
449 | bf->bf_state.bf_type |= BUF_XRETRY; | ||
450 | txfail = 1; | ||
451 | sendbar = 1; | ||
452 | txfail_cnt++; | ||
453 | } | ||
454 | } else { | ||
455 | /* | 446 | /* |
456 | * cleanup in progress, just fail | 447 | * cleanup in progress, just fail |
457 | * the un-acked sub-frames | 448 | * the un-acked sub-frames |
458 | */ | 449 | */ |
459 | txfail = 1; | 450 | txfail = 1; |
451 | } else if (fi->retries < ATH_MAX_SW_RETRIES) { | ||
452 | if (!(ts->ts_status & ATH9K_TXERR_FILT) || | ||
453 | !an->sleeping) | ||
454 | ath_tx_set_retry(sc, txq, bf->bf_mpdu); | ||
455 | |||
456 | clear_filter = true; | ||
457 | txpending = 1; | ||
458 | } else { | ||
459 | bf->bf_state.bf_type |= BUF_XRETRY; | ||
460 | txfail = 1; | ||
461 | sendbar = 1; | ||
462 | txfail_cnt++; | ||
460 | } | 463 | } |
461 | } | 464 | } |
462 | 465 | ||
@@ -496,6 +499,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
496 | !txfail, sendbar); | 499 | !txfail, sendbar); |
497 | } else { | 500 | } else { |
498 | /* retry the un-acked ones */ | 501 | /* retry the un-acked ones */ |
502 | ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false); | ||
499 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { | 503 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { |
500 | if (bf->bf_next == NULL && bf_last->bf_stale) { | 504 | if (bf->bf_next == NULL && bf_last->bf_stale) { |
501 | struct ath_buf *tbf; | 505 | struct ath_buf *tbf; |
@@ -546,7 +550,12 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
546 | 550 | ||
547 | /* prepend un-acked frames to the beginning of the pending frame queue */ | 551 | /* prepend un-acked frames to the beginning of the pending frame queue */ |
548 | if (!list_empty(&bf_pending)) { | 552 | if (!list_empty(&bf_pending)) { |
553 | if (an->sleeping) | ||
554 | ieee80211_sta_set_tim(sta); | ||
555 | |||
549 | spin_lock_bh(&txq->axq_lock); | 556 | spin_lock_bh(&txq->axq_lock); |
557 | if (clear_filter) | ||
558 | tid->ac->clear_ps_filter = true; | ||
550 | list_splice(&bf_pending, &tid->buf_q); | 559 | list_splice(&bf_pending, &tid->buf_q); |
551 | ath_tx_queue_tid(txq, tid); | 560 | ath_tx_queue_tid(txq, tid); |
552 | spin_unlock_bh(&txq->axq_lock); | 561 | spin_unlock_bh(&txq->axq_lock); |
@@ -816,6 +825,11 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
816 | bf = list_first_entry(&bf_q, struct ath_buf, list); | 825 | bf = list_first_entry(&bf_q, struct ath_buf, list); |
817 | bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); | 826 | bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); |
818 | 827 | ||
828 | if (tid->ac->clear_ps_filter) { | ||
829 | tid->ac->clear_ps_filter = false; | ||
830 | ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); | ||
831 | } | ||
832 | |||
819 | /* if only one frame, send as non-aggregate */ | 833 | /* if only one frame, send as non-aggregate */ |
820 | if (bf == bf->bf_lastbf) { | 834 | if (bf == bf->bf_lastbf) { |
821 | fi = get_frame_info(bf->bf_mpdu); | 835 | fi = get_frame_info(bf->bf_mpdu); |
@@ -896,6 +910,67 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | |||
896 | ath_tx_flush_tid(sc, txtid); | 910 | ath_tx_flush_tid(sc, txtid); |
897 | } | 911 | } |
898 | 912 | ||
913 | bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an) | ||
914 | { | ||
915 | struct ath_atx_tid *tid; | ||
916 | struct ath_atx_ac *ac; | ||
917 | struct ath_txq *txq; | ||
918 | bool buffered = false; | ||
919 | int tidno; | ||
920 | |||
921 | for (tidno = 0, tid = &an->tid[tidno]; | ||
922 | tidno < WME_NUM_TID; tidno++, tid++) { | ||
923 | |||
924 | if (!tid->sched) | ||
925 | continue; | ||
926 | |||
927 | ac = tid->ac; | ||
928 | txq = ac->txq; | ||
929 | |||
930 | spin_lock_bh(&txq->axq_lock); | ||
931 | |||
932 | if (!list_empty(&tid->buf_q)) | ||
933 | buffered = true; | ||
934 | |||
935 | tid->sched = false; | ||
936 | list_del(&tid->list); | ||
937 | |||
938 | if (ac->sched) { | ||
939 | ac->sched = false; | ||
940 | list_del(&ac->list); | ||
941 | } | ||
942 | |||
943 | spin_unlock_bh(&txq->axq_lock); | ||
944 | } | ||
945 | |||
946 | return buffered; | ||
947 | } | ||
948 | |||
949 | void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) | ||
950 | { | ||
951 | struct ath_atx_tid *tid; | ||
952 | struct ath_atx_ac *ac; | ||
953 | struct ath_txq *txq; | ||
954 | int tidno; | ||
955 | |||
956 | for (tidno = 0, tid = &an->tid[tidno]; | ||
957 | tidno < WME_NUM_TID; tidno++, tid++) { | ||
958 | |||
959 | ac = tid->ac; | ||
960 | txq = ac->txq; | ||
961 | |||
962 | spin_lock_bh(&txq->axq_lock); | ||
963 | ac->clear_ps_filter = true; | ||
964 | |||
965 | if (!list_empty(&tid->buf_q) && !tid->paused) { | ||
966 | ath_tx_queue_tid(txq, tid); | ||
967 | ath_txq_schedule(sc, txq); | ||
968 | } | ||
969 | |||
970 | spin_unlock_bh(&txq->axq_lock); | ||
971 | } | ||
972 | } | ||
973 | |||
899 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | 974 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) |
900 | { | 975 | { |
901 | struct ath_atx_tid *txtid; | 976 | struct ath_atx_tid *txtid; |
@@ -1451,7 +1526,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1451 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; | 1526 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; |
1452 | struct ieee80211_hdr *hdr; | 1527 | struct ieee80211_hdr *hdr; |
1453 | struct ath_frame_info *fi = get_frame_info(skb); | 1528 | struct ath_frame_info *fi = get_frame_info(skb); |
1454 | struct ath_node *an; | 1529 | struct ath_node *an = NULL; |
1455 | struct ath_atx_tid *tid; | 1530 | struct ath_atx_tid *tid; |
1456 | enum ath9k_key_type keytype; | 1531 | enum ath9k_key_type keytype; |
1457 | u16 seqno = 0; | 1532 | u16 seqno = 0; |
@@ -1459,11 +1534,13 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1459 | 1534 | ||
1460 | keytype = ath9k_cmn_get_hw_crypto_keytype(skb); | 1535 | keytype = ath9k_cmn_get_hw_crypto_keytype(skb); |
1461 | 1536 | ||
1537 | if (sta) | ||
1538 | an = (struct ath_node *) sta->drv_priv; | ||
1539 | |||
1462 | hdr = (struct ieee80211_hdr *)skb->data; | 1540 | hdr = (struct ieee80211_hdr *)skb->data; |
1463 | if (sta && ieee80211_is_data_qos(hdr->frame_control) && | 1541 | if (an && ieee80211_is_data_qos(hdr->frame_control) && |
1464 | conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) { | 1542 | conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) { |
1465 | 1543 | ||
1466 | an = (struct ath_node *) sta->drv_priv; | ||
1467 | tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; | 1544 | tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; |
1468 | 1545 | ||
1469 | /* | 1546 | /* |
@@ -1479,6 +1556,8 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1479 | memset(fi, 0, sizeof(*fi)); | 1556 | memset(fi, 0, sizeof(*fi)); |
1480 | if (hw_key) | 1557 | if (hw_key) |
1481 | fi->keyix = hw_key->hw_key_idx; | 1558 | fi->keyix = hw_key->hw_key_idx; |
1559 | else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0) | ||
1560 | fi->keyix = an->ps_key; | ||
1482 | else | 1561 | else |
1483 | fi->keyix = ATH9K_TXKEYIX_INVALID; | 1562 | fi->keyix = ATH9K_TXKEYIX_INVALID; |
1484 | fi->keytype = keytype; | 1563 | fi->keytype = keytype; |
@@ -1491,7 +1570,6 @@ static int setup_tx_flags(struct sk_buff *skb) | |||
1491 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1570 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1492 | int flags = 0; | 1571 | int flags = 0; |
1493 | 1572 | ||
1494 | flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ | ||
1495 | flags |= ATH9K_TXDESC_INTREQ; | 1573 | flags |= ATH9K_TXDESC_INTREQ; |
1496 | 1574 | ||
1497 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) | 1575 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) |
@@ -1585,8 +1663,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) | |||
1585 | rix = rates[i].idx; | 1663 | rix = rates[i].idx; |
1586 | series[i].Tries = rates[i].count; | 1664 | series[i].Tries = rates[i].count; |
1587 | 1665 | ||
1588 | if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) || | 1666 | if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) { |
1589 | (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) { | ||
1590 | series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; | 1667 | series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; |
1591 | flags |= ATH9K_TXDESC_RTSENA; | 1668 | flags |= ATH9K_TXDESC_RTSENA; |
1592 | } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { | 1669 | } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { |
@@ -1655,8 +1732,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) | |||
1655 | !is_pspoll, ctsrate, | 1732 | !is_pspoll, ctsrate, |
1656 | 0, series, 4, flags); | 1733 | 0, series, 4, flags); |
1657 | 1734 | ||
1658 | if (sc->config.ath_aggr_prot && flags) | ||
1659 | ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192); | ||
1660 | } | 1735 | } |
1661 | 1736 | ||
1662 | static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, | 1737 | static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, |
@@ -1754,6 +1829,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
1754 | if (txctl->paprd) | 1829 | if (txctl->paprd) |
1755 | bf->bf_state.bfs_paprd_timestamp = jiffies; | 1830 | bf->bf_state.bfs_paprd_timestamp = jiffies; |
1756 | 1831 | ||
1832 | if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) | ||
1833 | ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); | ||
1834 | |||
1757 | ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); | 1835 | ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); |
1758 | } | 1836 | } |
1759 | 1837 | ||
@@ -1767,6 +1845,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1767 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 1845 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
1768 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1846 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1769 | struct ieee80211_sta *sta = info->control.sta; | 1847 | struct ieee80211_sta *sta = info->control.sta; |
1848 | struct ieee80211_vif *vif = info->control.vif; | ||
1770 | struct ath_softc *sc = hw->priv; | 1849 | struct ath_softc *sc = hw->priv; |
1771 | struct ath_txq *txq = txctl->txq; | 1850 | struct ath_txq *txq = txctl->txq; |
1772 | struct ath_buf *bf; | 1851 | struct ath_buf *bf; |
@@ -1804,6 +1883,11 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1804 | memmove(skb->data, skb->data + padsize, padpos); | 1883 | memmove(skb->data, skb->data + padsize, padpos); |
1805 | } | 1884 | } |
1806 | 1885 | ||
1886 | if ((vif && vif->type != NL80211_IFTYPE_AP && | ||
1887 | vif->type != NL80211_IFTYPE_AP_VLAN) || | ||
1888 | !ieee80211_is_data(hdr->frame_control)) | ||
1889 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | ||
1890 | |||
1807 | setup_frame_info(hw, skb, frmlen); | 1891 | setup_frame_info(hw, skb, frmlen); |
1808 | 1892 | ||
1809 | /* | 1893 | /* |
@@ -1980,7 +2064,7 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, | |||
1980 | if (ieee80211_is_data(hdr->frame_control) && | 2064 | if (ieee80211_is_data(hdr->frame_control) && |
1981 | (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN | | 2065 | (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN | |
1982 | ATH9K_TX_DELIM_UNDERRUN)) && | 2066 | ATH9K_TX_DELIM_UNDERRUN)) && |
1983 | ah->tx_trig_level >= sc->sc_ah->caps.tx_triglevel_max) | 2067 | ah->tx_trig_level >= sc->sc_ah->config.max_txtrig_level) |
1984 | tx_info->status.rates[tx_rateindex].count = | 2068 | tx_info->status.rates[tx_rateindex].count = |
1985 | hw->max_rate_tries; | 2069 | hw->max_rate_tries; |
1986 | } | 2070 | } |
@@ -2099,28 +2183,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2099 | } | 2183 | } |
2100 | } | 2184 | } |
2101 | 2185 | ||
2102 | static void ath_hw_pll_work(struct work_struct *work) | ||
2103 | { | ||
2104 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
2105 | hw_pll_work.work); | ||
2106 | static int count; | ||
2107 | |||
2108 | if (AR_SREV_9485(sc->sc_ah)) { | ||
2109 | if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) { | ||
2110 | count++; | ||
2111 | |||
2112 | if (count == 3) { | ||
2113 | /* Rx is hung for more than 500ms. Reset it */ | ||
2114 | ath_reset(sc, true); | ||
2115 | count = 0; | ||
2116 | } | ||
2117 | } else | ||
2118 | count = 0; | ||
2119 | |||
2120 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); | ||
2121 | } | ||
2122 | } | ||
2123 | |||
2124 | static void ath_tx_complete_poll_work(struct work_struct *work) | 2186 | static void ath_tx_complete_poll_work(struct work_struct *work) |
2125 | { | 2187 | { |
2126 | struct ath_softc *sc = container_of(work, struct ath_softc, | 2188 | struct ath_softc *sc = container_of(work, struct ath_softc, |
@@ -2144,33 +2206,6 @@ static void ath_tx_complete_poll_work(struct work_struct *work) | |||
2144 | } else { | 2206 | } else { |
2145 | txq->axq_tx_inprogress = true; | 2207 | txq->axq_tx_inprogress = true; |
2146 | } | 2208 | } |
2147 | } else { | ||
2148 | /* If the queue has pending buffers, then it | ||
2149 | * should be doing tx work (and have axq_depth). | ||
2150 | * Shouldn't get to this state I think..but | ||
2151 | * we do. | ||
2152 | */ | ||
2153 | if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && | ||
2154 | (txq->pending_frames > 0 || | ||
2155 | !list_empty(&txq->axq_acq) || | ||
2156 | txq->stopped)) { | ||
2157 | ath_err(ath9k_hw_common(sc->sc_ah), | ||
2158 | "txq: %p axq_qnum: %u," | ||
2159 | " mac80211_qnum: %i" | ||
2160 | " axq_link: %p" | ||
2161 | " pending frames: %i" | ||
2162 | " axq_acq empty: %i" | ||
2163 | " stopped: %i" | ||
2164 | " axq_depth: 0 Attempting to" | ||
2165 | " restart tx logic.\n", | ||
2166 | txq, txq->axq_qnum, | ||
2167 | txq->mac80211_qnum, | ||
2168 | txq->axq_link, | ||
2169 | txq->pending_frames, | ||
2170 | list_empty(&txq->axq_acq), | ||
2171 | txq->stopped); | ||
2172 | ath_txq_schedule(sc, txq); | ||
2173 | } | ||
2174 | } | 2209 | } |
2175 | spin_unlock_bh(&txq->axq_lock); | 2210 | spin_unlock_bh(&txq->axq_lock); |
2176 | } | 2211 | } |
@@ -2342,7 +2377,6 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) | |||
2342 | } | 2377 | } |
2343 | 2378 | ||
2344 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); | 2379 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); |
2345 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | ||
2346 | 2380 | ||
2347 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 2381 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
2348 | error = ath_tx_edma_init(sc); | 2382 | error = ath_tx_edma_init(sc); |
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index 3d4ed586373..bb578690935 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h | |||
@@ -448,6 +448,8 @@ struct carl9170_ba_stats { | |||
448 | 448 | ||
449 | struct carl9170_sta_info { | 449 | struct carl9170_sta_info { |
450 | bool ht_sta; | 450 | bool ht_sta; |
451 | bool sleeping; | ||
452 | atomic_t pending_frames; | ||
451 | unsigned int ampdu_max_len; | 453 | unsigned int ampdu_max_len; |
452 | struct carl9170_sta_tid *agg[CARL9170_NUM_TID]; | 454 | struct carl9170_sta_tid *agg[CARL9170_NUM_TID]; |
453 | struct carl9170_ba_stats stats[CARL9170_NUM_TID]; | 455 | struct carl9170_ba_stats stats[CARL9170_NUM_TID]; |
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 89fe60accf8..7d5c65ea94e 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -883,7 +883,7 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw, | |||
883 | * then checking the error flags, later. | 883 | * then checking the error flags, later. |
884 | */ | 884 | */ |
885 | 885 | ||
886 | if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI) | 886 | if (*new_flags & FIF_ALLMULTI) |
887 | multicast = ~0ULL; | 887 | multicast = ~0ULL; |
888 | 888 | ||
889 | if (multicast != ar->cur_mc_hash) | 889 | if (multicast != ar->cur_mc_hash) |
@@ -1193,6 +1193,8 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw, | |||
1193 | struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; | 1193 | struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; |
1194 | unsigned int i; | 1194 | unsigned int i; |
1195 | 1195 | ||
1196 | atomic_set(&sta_info->pending_frames, 0); | ||
1197 | |||
1196 | if (sta->ht_cap.ht_supported) { | 1198 | if (sta->ht_cap.ht_supported) { |
1197 | if (sta->ht_cap.ampdu_density > 6) { | 1199 | if (sta->ht_cap.ampdu_density > 6) { |
1198 | /* | 1200 | /* |
@@ -1467,99 +1469,17 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw, | |||
1467 | enum sta_notify_cmd cmd, | 1469 | enum sta_notify_cmd cmd, |
1468 | struct ieee80211_sta *sta) | 1470 | struct ieee80211_sta *sta) |
1469 | { | 1471 | { |
1470 | struct ar9170 *ar = hw->priv; | ||
1471 | struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; | 1472 | struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; |
1472 | struct sk_buff *skb, *tmp; | ||
1473 | struct sk_buff_head free; | ||
1474 | int i; | ||
1475 | 1473 | ||
1476 | switch (cmd) { | 1474 | switch (cmd) { |
1477 | case STA_NOTIFY_SLEEP: | 1475 | case STA_NOTIFY_SLEEP: |
1478 | /* | 1476 | sta_info->sleeping = true; |
1479 | * Since the peer is no longer listening, we have to return | 1477 | if (atomic_read(&sta_info->pending_frames)) |
1480 | * as many SKBs as possible back to the mac80211 stack. | 1478 | ieee80211_sta_block_awake(hw, sta, true); |
1481 | * It will deal with the retry procedure, once the peer | ||
1482 | * has become available again. | ||
1483 | * | ||
1484 | * NB: Ideally, the driver should return the all frames in | ||
1485 | * the correct, ascending order. However, I think that this | ||
1486 | * functionality should be implemented in the stack and not | ||
1487 | * here... | ||
1488 | */ | ||
1489 | |||
1490 | __skb_queue_head_init(&free); | ||
1491 | |||
1492 | if (sta->ht_cap.ht_supported) { | ||
1493 | rcu_read_lock(); | ||
1494 | for (i = 0; i < CARL9170_NUM_TID; i++) { | ||
1495 | struct carl9170_sta_tid *tid_info; | ||
1496 | |||
1497 | tid_info = rcu_dereference(sta_info->agg[i]); | ||
1498 | |||
1499 | if (!tid_info) | ||
1500 | continue; | ||
1501 | |||
1502 | spin_lock_bh(&ar->tx_ampdu_list_lock); | ||
1503 | if (tid_info->state > | ||
1504 | CARL9170_TID_STATE_SUSPEND) | ||
1505 | tid_info->state = | ||
1506 | CARL9170_TID_STATE_SUSPEND; | ||
1507 | spin_unlock_bh(&ar->tx_ampdu_list_lock); | ||
1508 | |||
1509 | spin_lock_bh(&tid_info->lock); | ||
1510 | while ((skb = __skb_dequeue(&tid_info->queue))) | ||
1511 | __skb_queue_tail(&free, skb); | ||
1512 | spin_unlock_bh(&tid_info->lock); | ||
1513 | } | ||
1514 | rcu_read_unlock(); | ||
1515 | } | ||
1516 | |||
1517 | for (i = 0; i < ar->hw->queues; i++) { | ||
1518 | spin_lock_bh(&ar->tx_pending[i].lock); | ||
1519 | skb_queue_walk_safe(&ar->tx_pending[i], skb, tmp) { | ||
1520 | struct _carl9170_tx_superframe *super; | ||
1521 | struct ieee80211_hdr *hdr; | ||
1522 | struct ieee80211_tx_info *info; | ||
1523 | |||
1524 | super = (void *) skb->data; | ||
1525 | hdr = (void *) super->frame_data; | ||
1526 | |||
1527 | if (compare_ether_addr(hdr->addr1, sta->addr)) | ||
1528 | continue; | ||
1529 | |||
1530 | __skb_unlink(skb, &ar->tx_pending[i]); | ||
1531 | |||
1532 | info = IEEE80211_SKB_CB(skb); | ||
1533 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | ||
1534 | atomic_dec(&ar->tx_ampdu_upload); | ||
1535 | |||
1536 | carl9170_tx_status(ar, skb, false); | ||
1537 | } | ||
1538 | spin_unlock_bh(&ar->tx_pending[i].lock); | ||
1539 | } | ||
1540 | |||
1541 | while ((skb = __skb_dequeue(&free))) | ||
1542 | carl9170_tx_status(ar, skb, false); | ||
1543 | |||
1544 | break; | 1479 | break; |
1545 | 1480 | ||
1546 | case STA_NOTIFY_AWAKE: | 1481 | case STA_NOTIFY_AWAKE: |
1547 | if (!sta->ht_cap.ht_supported) | 1482 | sta_info->sleeping = false; |
1548 | return; | ||
1549 | |||
1550 | rcu_read_lock(); | ||
1551 | for (i = 0; i < CARL9170_NUM_TID; i++) { | ||
1552 | struct carl9170_sta_tid *tid_info; | ||
1553 | |||
1554 | tid_info = rcu_dereference(sta_info->agg[i]); | ||
1555 | |||
1556 | if (!tid_info) | ||
1557 | continue; | ||
1558 | |||
1559 | if ((tid_info->state == CARL9170_TID_STATE_SUSPEND)) | ||
1560 | tid_info->state = CARL9170_TID_STATE_IDLE; | ||
1561 | } | ||
1562 | rcu_read_unlock(); | ||
1563 | break; | 1483 | break; |
1564 | } | 1484 | } |
1565 | } | 1485 | } |
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index cb70ed7ec5c..e94084fcf6f 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c | |||
@@ -104,12 +104,60 @@ static void carl9170_tx_accounting(struct ar9170 *ar, struct sk_buff *skb) | |||
104 | spin_unlock_bh(&ar->tx_stats_lock); | 104 | spin_unlock_bh(&ar->tx_stats_lock); |
105 | } | 105 | } |
106 | 106 | ||
107 | /* needs rcu_read_lock */ | ||
108 | static struct ieee80211_sta *__carl9170_get_tx_sta(struct ar9170 *ar, | ||
109 | struct sk_buff *skb) | ||
110 | { | ||
111 | struct _carl9170_tx_superframe *super = (void *) skb->data; | ||
112 | struct ieee80211_hdr *hdr = (void *) super->frame_data; | ||
113 | struct ieee80211_vif *vif; | ||
114 | unsigned int vif_id; | ||
115 | |||
116 | vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >> | ||
117 | CARL9170_TX_SUPER_MISC_VIF_ID_S; | ||
118 | |||
119 | if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC)) | ||
120 | return NULL; | ||
121 | |||
122 | vif = rcu_dereference(ar->vif_priv[vif_id].vif); | ||
123 | if (unlikely(!vif)) | ||
124 | return NULL; | ||
125 | |||
126 | /* | ||
127 | * Normally we should use wrappers like ieee80211_get_DA to get | ||
128 | * the correct peer ieee80211_sta. | ||
129 | * | ||
130 | * But there is a problem with indirect traffic (broadcasts, or | ||
131 | * data which is designated for other stations) in station mode. | ||
132 | * The frame will be directed to the AP for distribution and not | ||
133 | * to the actual destination. | ||
134 | */ | ||
135 | |||
136 | return ieee80211_find_sta(vif, hdr->addr1); | ||
137 | } | ||
138 | |||
139 | static void carl9170_tx_ps_unblock(struct ar9170 *ar, struct sk_buff *skb) | ||
140 | { | ||
141 | struct ieee80211_sta *sta; | ||
142 | struct carl9170_sta_info *sta_info; | ||
143 | |||
144 | rcu_read_lock(); | ||
145 | sta = __carl9170_get_tx_sta(ar, skb); | ||
146 | if (unlikely(!sta)) | ||
147 | goto out_rcu; | ||
148 | |||
149 | sta_info = (struct carl9170_sta_info *) sta->drv_priv; | ||
150 | if (atomic_dec_return(&sta_info->pending_frames) == 0) | ||
151 | ieee80211_sta_block_awake(ar->hw, sta, false); | ||
152 | |||
153 | out_rcu: | ||
154 | rcu_read_unlock(); | ||
155 | } | ||
156 | |||
107 | static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb) | 157 | static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb) |
108 | { | 158 | { |
109 | struct ieee80211_tx_info *txinfo; | ||
110 | int queue; | 159 | int queue; |
111 | 160 | ||
112 | txinfo = IEEE80211_SKB_CB(skb); | ||
113 | queue = skb_get_queue_mapping(skb); | 161 | queue = skb_get_queue_mapping(skb); |
114 | 162 | ||
115 | spin_lock_bh(&ar->tx_stats_lock); | 163 | spin_lock_bh(&ar->tx_stats_lock); |
@@ -135,6 +183,7 @@ static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb) | |||
135 | } | 183 | } |
136 | 184 | ||
137 | spin_unlock_bh(&ar->tx_stats_lock); | 185 | spin_unlock_bh(&ar->tx_stats_lock); |
186 | |||
138 | if (atomic_dec_and_test(&ar->tx_total_queued)) | 187 | if (atomic_dec_and_test(&ar->tx_total_queued)) |
139 | complete(&ar->tx_flush); | 188 | complete(&ar->tx_flush); |
140 | } | 189 | } |
@@ -329,13 +378,9 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, | |||
329 | { | 378 | { |
330 | struct _carl9170_tx_superframe *super = (void *) skb->data; | 379 | struct _carl9170_tx_superframe *super = (void *) skb->data; |
331 | struct ieee80211_hdr *hdr = (void *) super->frame_data; | 380 | struct ieee80211_hdr *hdr = (void *) super->frame_data; |
332 | struct ieee80211_tx_info *tx_info; | ||
333 | struct carl9170_tx_info *ar_info; | ||
334 | struct carl9170_sta_info *sta_info; | ||
335 | struct ieee80211_sta *sta; | 381 | struct ieee80211_sta *sta; |
382 | struct carl9170_sta_info *sta_info; | ||
336 | struct carl9170_sta_tid *tid_info; | 383 | struct carl9170_sta_tid *tid_info; |
337 | struct ieee80211_vif *vif; | ||
338 | unsigned int vif_id; | ||
339 | u8 tid; | 384 | u8 tid; |
340 | 385 | ||
341 | if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || | 386 | if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || |
@@ -343,30 +388,8 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, | |||
343 | (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR)))) | 388 | (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR)))) |
344 | return; | 389 | return; |
345 | 390 | ||
346 | tx_info = IEEE80211_SKB_CB(skb); | ||
347 | ar_info = (void *) tx_info->rate_driver_data; | ||
348 | |||
349 | vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >> | ||
350 | CARL9170_TX_SUPER_MISC_VIF_ID_S; | ||
351 | |||
352 | if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC)) | ||
353 | return; | ||
354 | |||
355 | rcu_read_lock(); | 391 | rcu_read_lock(); |
356 | vif = rcu_dereference(ar->vif_priv[vif_id].vif); | 392 | sta = __carl9170_get_tx_sta(ar, skb); |
357 | if (unlikely(!vif)) | ||
358 | goto out_rcu; | ||
359 | |||
360 | /* | ||
361 | * Normally we should use wrappers like ieee80211_get_DA to get | ||
362 | * the correct peer ieee80211_sta. | ||
363 | * | ||
364 | * But there is a problem with indirect traffic (broadcasts, or | ||
365 | * data which is designated for other stations) in station mode. | ||
366 | * The frame will be directed to the AP for distribution and not | ||
367 | * to the actual destination. | ||
368 | */ | ||
369 | sta = ieee80211_find_sta(vif, hdr->addr1); | ||
370 | if (unlikely(!sta)) | 393 | if (unlikely(!sta)) |
371 | goto out_rcu; | 394 | goto out_rcu; |
372 | 395 | ||
@@ -427,6 +450,7 @@ void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, | |||
427 | if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) | 450 | if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) |
428 | carl9170_tx_status_process_ampdu(ar, skb, txinfo); | 451 | carl9170_tx_status_process_ampdu(ar, skb, txinfo); |
429 | 452 | ||
453 | carl9170_tx_ps_unblock(ar, skb); | ||
430 | carl9170_tx_put_skb(skb); | 454 | carl9170_tx_put_skb(skb); |
431 | } | 455 | } |
432 | 456 | ||
@@ -540,11 +564,7 @@ static void carl9170_tx_ampdu_timeout(struct ar9170 *ar) | |||
540 | struct sk_buff *skb; | 564 | struct sk_buff *skb; |
541 | struct ieee80211_tx_info *txinfo; | 565 | struct ieee80211_tx_info *txinfo; |
542 | struct carl9170_tx_info *arinfo; | 566 | struct carl9170_tx_info *arinfo; |
543 | struct _carl9170_tx_superframe *super; | ||
544 | struct ieee80211_sta *sta; | 567 | struct ieee80211_sta *sta; |
545 | struct ieee80211_vif *vif; | ||
546 | struct ieee80211_hdr *hdr; | ||
547 | unsigned int vif_id; | ||
548 | 568 | ||
549 | rcu_read_lock(); | 569 | rcu_read_lock(); |
550 | list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) { | 570 | list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) { |
@@ -562,20 +582,7 @@ static void carl9170_tx_ampdu_timeout(struct ar9170 *ar) | |||
562 | msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT))) | 582 | msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT))) |
563 | goto unlock; | 583 | goto unlock; |
564 | 584 | ||
565 | super = (void *) skb->data; | 585 | sta = __carl9170_get_tx_sta(ar, skb); |
566 | hdr = (void *) super->frame_data; | ||
567 | |||
568 | vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >> | ||
569 | CARL9170_TX_SUPER_MISC_VIF_ID_S; | ||
570 | |||
571 | if (WARN_ON(vif_id >= AR9170_MAX_VIRTUAL_MAC)) | ||
572 | goto unlock; | ||
573 | |||
574 | vif = rcu_dereference(ar->vif_priv[vif_id].vif); | ||
575 | if (WARN_ON(!vif)) | ||
576 | goto unlock; | ||
577 | |||
578 | sta = ieee80211_find_sta(vif, hdr->addr1); | ||
579 | if (WARN_ON(!sta)) | 586 | if (WARN_ON(!sta)) |
580 | goto unlock; | 587 | goto unlock; |
581 | 588 | ||
@@ -611,7 +618,6 @@ static void __carl9170_tx_process_status(struct ar9170 *ar, | |||
611 | { | 618 | { |
612 | struct sk_buff *skb; | 619 | struct sk_buff *skb; |
613 | struct ieee80211_tx_info *txinfo; | 620 | struct ieee80211_tx_info *txinfo; |
614 | struct carl9170_tx_info *arinfo; | ||
615 | unsigned int r, t, q; | 621 | unsigned int r, t, q; |
616 | bool success = true; | 622 | bool success = true; |
617 | 623 | ||
@@ -627,7 +633,6 @@ static void __carl9170_tx_process_status(struct ar9170 *ar, | |||
627 | } | 633 | } |
628 | 634 | ||
629 | txinfo = IEEE80211_SKB_CB(skb); | 635 | txinfo = IEEE80211_SKB_CB(skb); |
630 | arinfo = (void *) txinfo->rate_driver_data; | ||
631 | 636 | ||
632 | if (!(info & CARL9170_TX_STATUS_SUCCESS)) | 637 | if (!(info & CARL9170_TX_STATUS_SUCCESS)) |
633 | success = false; | 638 | success = false; |
@@ -1199,15 +1204,6 @@ static struct sk_buff *carl9170_tx_pick_skb(struct ar9170 *ar, | |||
1199 | arinfo = (void *) info->rate_driver_data; | 1204 | arinfo = (void *) info->rate_driver_data; |
1200 | 1205 | ||
1201 | arinfo->timeout = jiffies; | 1206 | arinfo->timeout = jiffies; |
1202 | |||
1203 | /* | ||
1204 | * increase ref count to "2". | ||
1205 | * Ref counting is the easiest way to solve the race between | ||
1206 | * the the urb's completion routine: carl9170_tx_callback and | ||
1207 | * wlan tx status functions: carl9170_tx_status/janitor. | ||
1208 | */ | ||
1209 | carl9170_tx_get_skb(skb); | ||
1210 | |||
1211 | return skb; | 1207 | return skb; |
1212 | 1208 | ||
1213 | err_unlock: | 1209 | err_unlock: |
@@ -1228,6 +1224,36 @@ void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb) | |||
1228 | __carl9170_tx_process_status(ar, super->s.cookie, q); | 1224 | __carl9170_tx_process_status(ar, super->s.cookie, q); |
1229 | } | 1225 | } |
1230 | 1226 | ||
1227 | static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb) | ||
1228 | { | ||
1229 | struct ieee80211_sta *sta; | ||
1230 | struct carl9170_sta_info *sta_info; | ||
1231 | |||
1232 | rcu_read_lock(); | ||
1233 | sta = __carl9170_get_tx_sta(ar, skb); | ||
1234 | if (!sta) | ||
1235 | goto out_rcu; | ||
1236 | |||
1237 | sta_info = (void *) sta->drv_priv; | ||
1238 | if (unlikely(sta_info->sleeping)) { | ||
1239 | struct ieee80211_tx_info *tx_info; | ||
1240 | |||
1241 | rcu_read_unlock(); | ||
1242 | |||
1243 | tx_info = IEEE80211_SKB_CB(skb); | ||
1244 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) | ||
1245 | atomic_dec(&ar->tx_ampdu_upload); | ||
1246 | |||
1247 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | ||
1248 | carl9170_tx_status(ar, skb, false); | ||
1249 | return true; | ||
1250 | } | ||
1251 | |||
1252 | out_rcu: | ||
1253 | rcu_read_unlock(); | ||
1254 | return false; | ||
1255 | } | ||
1256 | |||
1231 | static void carl9170_tx(struct ar9170 *ar) | 1257 | static void carl9170_tx(struct ar9170 *ar) |
1232 | { | 1258 | { |
1233 | struct sk_buff *skb; | 1259 | struct sk_buff *skb; |
@@ -1247,6 +1273,9 @@ static void carl9170_tx(struct ar9170 *ar) | |||
1247 | if (unlikely(!skb)) | 1273 | if (unlikely(!skb)) |
1248 | break; | 1274 | break; |
1249 | 1275 | ||
1276 | if (unlikely(carl9170_tx_ps_drop(ar, skb))) | ||
1277 | continue; | ||
1278 | |||
1250 | atomic_inc(&ar->tx_total_pending); | 1279 | atomic_inc(&ar->tx_total_pending); |
1251 | 1280 | ||
1252 | q = __carl9170_get_queue(ar, i); | 1281 | q = __carl9170_get_queue(ar, i); |
@@ -1256,6 +1285,16 @@ static void carl9170_tx(struct ar9170 *ar) | |||
1256 | */ | 1285 | */ |
1257 | skb_queue_tail(&ar->tx_status[q], skb); | 1286 | skb_queue_tail(&ar->tx_status[q], skb); |
1258 | 1287 | ||
1288 | /* | ||
1289 | * increase ref count to "2". | ||
1290 | * Ref counting is the easiest way to solve the | ||
1291 | * race between the urb's completion routine: | ||
1292 | * carl9170_tx_callback | ||
1293 | * and wlan tx status functions: | ||
1294 | * carl9170_tx_status/janitor. | ||
1295 | */ | ||
1296 | carl9170_tx_get_skb(skb); | ||
1297 | |||
1259 | carl9170_usb_tx(ar, skb); | 1298 | carl9170_usb_tx(ar, skb); |
1260 | schedule_garbagecollector = true; | 1299 | schedule_garbagecollector = true; |
1261 | } | 1300 | } |
@@ -1275,7 +1314,6 @@ static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, | |||
1275 | struct carl9170_sta_info *sta_info; | 1314 | struct carl9170_sta_info *sta_info; |
1276 | struct carl9170_sta_tid *agg; | 1315 | struct carl9170_sta_tid *agg; |
1277 | struct sk_buff *iter; | 1316 | struct sk_buff *iter; |
1278 | unsigned int max; | ||
1279 | u16 tid, seq, qseq, off; | 1317 | u16 tid, seq, qseq, off; |
1280 | bool run = false; | 1318 | bool run = false; |
1281 | 1319 | ||
@@ -1285,7 +1323,6 @@ static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, | |||
1285 | 1323 | ||
1286 | rcu_read_lock(); | 1324 | rcu_read_lock(); |
1287 | agg = rcu_dereference(sta_info->agg[tid]); | 1325 | agg = rcu_dereference(sta_info->agg[tid]); |
1288 | max = sta_info->ampdu_max_len; | ||
1289 | 1326 | ||
1290 | if (!agg) | 1327 | if (!agg) |
1291 | goto err_unlock_rcu; | 1328 | goto err_unlock_rcu; |
@@ -1368,6 +1405,11 @@ void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1368 | * all ressouces which are associated with the frame. | 1405 | * all ressouces which are associated with the frame. |
1369 | */ | 1406 | */ |
1370 | 1407 | ||
1408 | if (sta) { | ||
1409 | struct carl9170_sta_info *stai = (void *) sta->drv_priv; | ||
1410 | atomic_inc(&stai->pending_frames); | ||
1411 | } | ||
1412 | |||
1371 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | 1413 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { |
1372 | run = carl9170_tx_ampdu_queue(ar, sta, skb); | 1414 | run = carl9170_tx_ampdu_queue(ar, sta, skb); |
1373 | if (run) | 1415 | if (run) |
diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 37b8e115375..a61ef3d6d89 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c | |||
@@ -23,6 +23,14 @@ | |||
23 | 23 | ||
24 | #define REG_READ (common->ops->read) | 24 | #define REG_READ (common->ops->read) |
25 | #define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg) | 25 | #define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg) |
26 | #define ENABLE_REGWRITE_BUFFER(_ah) \ | ||
27 | if (common->ops->enable_write_buffer) \ | ||
28 | common->ops->enable_write_buffer((_ah)); | ||
29 | |||
30 | #define REGWRITE_BUFFER_FLUSH(_ah) \ | ||
31 | if (common->ops->write_flush) \ | ||
32 | common->ops->write_flush((_ah)); | ||
33 | |||
26 | 34 | ||
27 | #define IEEE80211_WEP_NKID 4 /* number of key ids */ | 35 | #define IEEE80211_WEP_NKID 4 /* number of key ids */ |
28 | 36 | ||
@@ -42,6 +50,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry) | |||
42 | 50 | ||
43 | keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry)); | 51 | keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry)); |
44 | 52 | ||
53 | ENABLE_REGWRITE_BUFFER(ah); | ||
54 | |||
45 | REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); | 55 | REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); |
46 | REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); | 56 | REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); |
47 | REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); | 57 | REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); |
@@ -66,6 +76,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry) | |||
66 | 76 | ||
67 | } | 77 | } |
68 | 78 | ||
79 | REGWRITE_BUFFER_FLUSH(ah); | ||
80 | |||
69 | return true; | 81 | return true; |
70 | } | 82 | } |
71 | EXPORT_SYMBOL(ath_hw_keyreset); | 83 | EXPORT_SYMBOL(ath_hw_keyreset); |
@@ -104,9 +116,13 @@ static bool ath_hw_keysetmac(struct ath_common *common, | |||
104 | } else { | 116 | } else { |
105 | macLo = macHi = 0; | 117 | macLo = macHi = 0; |
106 | } | 118 | } |
119 | ENABLE_REGWRITE_BUFFER(ah); | ||
120 | |||
107 | REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); | 121 | REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); |
108 | REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag); | 122 | REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag); |
109 | 123 | ||
124 | REGWRITE_BUFFER_FLUSH(ah); | ||
125 | |||
110 | return true; | 126 | return true; |
111 | } | 127 | } |
112 | 128 | ||
@@ -223,6 +239,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, | |||
223 | mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff; | 239 | mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff; |
224 | mic4 = get_unaligned_le32(k->kv_txmic + 4); | 240 | mic4 = get_unaligned_le32(k->kv_txmic + 4); |
225 | 241 | ||
242 | ENABLE_REGWRITE_BUFFER(ah); | ||
243 | |||
226 | /* Write RX[31:0] and TX[31:16] */ | 244 | /* Write RX[31:0] and TX[31:16] */ |
227 | REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); | 245 | REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); |
228 | REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1); | 246 | REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1); |
@@ -236,6 +254,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, | |||
236 | REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), | 254 | REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), |
237 | AR_KEYTABLE_TYPE_CLR); | 255 | AR_KEYTABLE_TYPE_CLR); |
238 | 256 | ||
257 | REGWRITE_BUFFER_FLUSH(ah); | ||
258 | |||
239 | } else { | 259 | } else { |
240 | /* | 260 | /* |
241 | * TKIP uses four key cache entries (two for group | 261 | * TKIP uses four key cache entries (two for group |
@@ -258,6 +278,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, | |||
258 | mic0 = get_unaligned_le32(k->kv_mic + 0); | 278 | mic0 = get_unaligned_le32(k->kv_mic + 0); |
259 | mic2 = get_unaligned_le32(k->kv_mic + 4); | 279 | mic2 = get_unaligned_le32(k->kv_mic + 4); |
260 | 280 | ||
281 | ENABLE_REGWRITE_BUFFER(ah); | ||
282 | |||
261 | /* Write MIC key[31:0] */ | 283 | /* Write MIC key[31:0] */ |
262 | REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); | 284 | REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); |
263 | REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); | 285 | REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); |
@@ -270,8 +292,12 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, | |||
270 | REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); | 292 | REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); |
271 | REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), | 293 | REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), |
272 | AR_KEYTABLE_TYPE_CLR); | 294 | AR_KEYTABLE_TYPE_CLR); |
295 | |||
296 | REGWRITE_BUFFER_FLUSH(ah); | ||
273 | } | 297 | } |
274 | 298 | ||
299 | ENABLE_REGWRITE_BUFFER(ah); | ||
300 | |||
275 | /* MAC address registers are reserved for the MIC entry */ | 301 | /* MAC address registers are reserved for the MIC entry */ |
276 | REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0); | 302 | REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0); |
277 | REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0); | 303 | REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0); |
@@ -283,7 +309,11 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, | |||
283 | */ | 309 | */ |
284 | REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); | 310 | REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); |
285 | REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); | 311 | REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); |
312 | |||
313 | REGWRITE_BUFFER_FLUSH(ah); | ||
286 | } else { | 314 | } else { |
315 | ENABLE_REGWRITE_BUFFER(ah); | ||
316 | |||
287 | /* Write key[47:0] */ | 317 | /* Write key[47:0] */ |
288 | REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); | 318 | REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); |
289 | REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); | 319 | REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); |
@@ -296,6 +326,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, | |||
296 | REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); | 326 | REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); |
297 | REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); | 327 | REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); |
298 | 328 | ||
329 | REGWRITE_BUFFER_FLUSH(ah); | ||
330 | |||
299 | /* Write MAC address for the entry */ | 331 | /* Write MAC address for the entry */ |
300 | (void) ath_hw_keysetmac(common, entry, mac); | 332 | (void) ath_hw_keysetmac(common, entry, mac); |
301 | } | 333 | } |
@@ -451,6 +483,9 @@ int ath_key_config(struct ath_common *common, | |||
451 | memset(&hk, 0, sizeof(hk)); | 483 | memset(&hk, 0, sizeof(hk)); |
452 | 484 | ||
453 | switch (key->cipher) { | 485 | switch (key->cipher) { |
486 | case 0: | ||
487 | hk.kv_type = ATH_CIPHER_CLR; | ||
488 | break; | ||
454 | case WLAN_CIPHER_SUITE_WEP40: | 489 | case WLAN_CIPHER_SUITE_WEP40: |
455 | case WLAN_CIPHER_SUITE_WEP104: | 490 | case WLAN_CIPHER_SUITE_WEP104: |
456 | hk.kv_type = ATH_CIPHER_WEP; | 491 | hk.kv_type = ATH_CIPHER_WEP; |
@@ -466,7 +501,8 @@ int ath_key_config(struct ath_common *common, | |||
466 | } | 501 | } |
467 | 502 | ||
468 | hk.kv_len = key->keylen; | 503 | hk.kv_len = key->keylen; |
469 | memcpy(hk.kv_val, key->key, key->keylen); | 504 | if (key->keylen) |
505 | memcpy(hk.kv_val, key->key, key->keylen); | ||
470 | 506 | ||
471 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | 507 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { |
472 | switch (vif->type) { | 508 | switch (vif->type) { |
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 0e1b8793c86..028310f263c 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c | |||
@@ -97,8 +97,8 @@ static const struct ieee80211_regdomain ath_world_regdom_66_69 = { | |||
97 | } | 97 | } |
98 | }; | 98 | }; |
99 | 99 | ||
100 | /* Can be used by 0x67, 0x6A and 0x68 */ | 100 | /* Can be used by 0x67, 0x68, 0x6A and 0x6C */ |
101 | static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = { | 101 | static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = { |
102 | .n_reg_rules = 4, | 102 | .n_reg_rules = 4, |
103 | .alpha2 = "99", | 103 | .alpha2 = "99", |
104 | .reg_rules = { | 104 | .reg_rules = { |
@@ -151,7 +151,8 @@ ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) | |||
151 | case 0x67: | 151 | case 0x67: |
152 | case 0x68: | 152 | case 0x68: |
153 | case 0x6A: | 153 | case 0x6A: |
154 | return &ath_world_regdom_67_68_6A; | 154 | case 0x6C: |
155 | return &ath_world_regdom_67_68_6A_6C; | ||
155 | default: | 156 | default: |
156 | WARN_ON(1); | 157 | WARN_ON(1); |
157 | return ath_default_world_regdomain(); | 158 | return ath_default_world_regdomain(); |
@@ -333,6 +334,7 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy, | |||
333 | case 0x63: | 334 | case 0x63: |
334 | case 0x66: | 335 | case 0x66: |
335 | case 0x67: | 336 | case 0x67: |
337 | case 0x6C: | ||
336 | ath_reg_apply_beaconing_flags(wiphy, initiator); | 338 | ath_reg_apply_beaconing_flags(wiphy, initiator); |
337 | break; | 339 | break; |
338 | case 0x68: | 340 | case 0x68: |
diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h index 5c2cfe69415..24b53839fc3 100644 --- a/drivers/net/wireless/ath/regd_common.h +++ b/drivers/net/wireless/ath/regd_common.h | |||
@@ -86,6 +86,7 @@ enum EnumRd { | |||
86 | WOR9_WORLD = 0x69, | 86 | WOR9_WORLD = 0x69, |
87 | WORA_WORLD = 0x6A, | 87 | WORA_WORLD = 0x6A, |
88 | WORB_WORLD = 0x6B, | 88 | WORB_WORLD = 0x6B, |
89 | WORC_WORLD = 0x6C, | ||
89 | 90 | ||
90 | MKK3_MKKB = 0x80, | 91 | MKK3_MKKB = 0x80, |
91 | MKK3_MKKA2 = 0x81, | 92 | MKK3_MKKA2 = 0x81, |
@@ -282,6 +283,7 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = { | |||
282 | {WOR9_WORLD, NO_CTL, NO_CTL}, | 283 | {WOR9_WORLD, NO_CTL, NO_CTL}, |
283 | {WORA_WORLD, NO_CTL, NO_CTL}, | 284 | {WORA_WORLD, NO_CTL, NO_CTL}, |
284 | {WORB_WORLD, NO_CTL, NO_CTL}, | 285 | {WORB_WORLD, NO_CTL, NO_CTL}, |
286 | {WORC_WORLD, NO_CTL, NO_CTL}, | ||
285 | }; | 287 | }; |
286 | 288 | ||
287 | static struct country_code_to_enum_rd allCountries[] = { | 289 | static struct country_code_to_enum_rd allCountries[] = { |