diff options
Diffstat (limited to 'drivers/net/wireless/ath/ar9170')
-rw-r--r-- | drivers/net/wireless/ath/ar9170/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/ar9170.h | 24 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/cmd.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/cmd.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/hw.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/mac.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/main.c | 256 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/phy.c | 99 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/usb.c | 204 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/usb.h | 3 |
10 files changed, 368 insertions, 248 deletions
diff --git a/drivers/net/wireless/ath/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig index 05918f1e685a..d7a4799d20fb 100644 --- a/drivers/net/wireless/ath/ar9170/Kconfig +++ b/drivers/net/wireless/ath/ar9170/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config AR9170_USB | 1 | config AR9170_USB |
2 | tristate "Atheros AR9170 802.11n USB support" | 2 | tristate "Atheros AR9170 802.11n USB support" |
3 | depends on USB && MAC80211 && WLAN_80211 | 3 | depends on USB && MAC80211 |
4 | select FW_LOADER | 4 | select FW_LOADER |
5 | help | 5 | help |
6 | This is a driver for the Atheros "otus" 802.11n USB devices. | 6 | This is a driver for the Atheros "otus" 802.11n USB devices. |
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index 914e4718a9a8..dc662b76a1c8 100644 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h | |||
@@ -109,7 +109,6 @@ struct ar9170_rxstream_mpdu_merge { | |||
109 | bool has_plcp; | 109 | bool has_plcp; |
110 | }; | 110 | }; |
111 | 111 | ||
112 | #define AR9170_NUM_MAX_BA_RETRY 5 | ||
113 | #define AR9170_NUM_TID 16 | 112 | #define AR9170_NUM_TID 16 |
114 | #define WME_BA_BMP_SIZE 64 | 113 | #define WME_BA_BMP_SIZE 64 |
115 | #define AR9170_NUM_MAX_AGG_LEN (2 * WME_BA_BMP_SIZE) | 114 | #define AR9170_NUM_MAX_AGG_LEN (2 * WME_BA_BMP_SIZE) |
@@ -143,7 +142,12 @@ struct ar9170_sta_tid { | |||
143 | u16 tid; | 142 | u16 tid; |
144 | enum ar9170_tid_state state; | 143 | enum ar9170_tid_state state; |
145 | bool active; | 144 | bool active; |
146 | u8 retry; | 145 | }; |
146 | |||
147 | struct ar9170_tx_queue_stats { | ||
148 | unsigned int len; | ||
149 | unsigned int limit; | ||
150 | unsigned int count; | ||
147 | }; | 151 | }; |
148 | 152 | ||
149 | #define AR9170_QUEUE_TIMEOUT 64 | 153 | #define AR9170_QUEUE_TIMEOUT 64 |
@@ -154,12 +158,15 @@ struct ar9170_sta_tid { | |||
154 | 158 | ||
155 | #define AR9170_NUM_TX_STATUS 128 | 159 | #define AR9170_NUM_TX_STATUS 128 |
156 | #define AR9170_NUM_TX_AGG_MAX 30 | 160 | #define AR9170_NUM_TX_AGG_MAX 30 |
161 | #define AR9170_NUM_TX_LIMIT_HARD AR9170_TXQ_DEPTH | ||
162 | #define AR9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH - 10) | ||
157 | 163 | ||
158 | struct ar9170 { | 164 | struct ar9170 { |
159 | struct ieee80211_hw *hw; | 165 | struct ieee80211_hw *hw; |
160 | struct ath_common common; | 166 | struct ath_common common; |
161 | struct mutex mutex; | 167 | struct mutex mutex; |
162 | enum ar9170_device_state state; | 168 | enum ar9170_device_state state; |
169 | bool registered; | ||
163 | unsigned long bad_hw_nagger; | 170 | unsigned long bad_hw_nagger; |
164 | 171 | ||
165 | int (*open)(struct ar9170 *); | 172 | int (*open)(struct ar9170 *); |
@@ -172,8 +179,6 @@ struct ar9170 { | |||
172 | 179 | ||
173 | /* interface mode settings */ | 180 | /* interface mode settings */ |
174 | struct ieee80211_vif *vif; | 181 | struct ieee80211_vif *vif; |
175 | u8 mac_addr[ETH_ALEN]; | ||
176 | u8 bssid[ETH_ALEN]; | ||
177 | 182 | ||
178 | /* beaconing */ | 183 | /* beaconing */ |
179 | struct sk_buff *beacon; | 184 | struct sk_buff *beacon; |
@@ -204,6 +209,8 @@ struct ar9170 { | |||
204 | u8 power_2G_ht20[8]; | 209 | u8 power_2G_ht20[8]; |
205 | u8 power_2G_ht40[8]; | 210 | u8 power_2G_ht40[8]; |
206 | 211 | ||
212 | u8 phy_heavy_clip; | ||
213 | |||
207 | #ifdef CONFIG_AR9170_LEDS | 214 | #ifdef CONFIG_AR9170_LEDS |
208 | struct delayed_work led_work; | 215 | struct delayed_work led_work; |
209 | struct ar9170_led leds[AR9170_NUM_LEDS]; | 216 | struct ar9170_led leds[AR9170_NUM_LEDS]; |
@@ -211,7 +218,7 @@ struct ar9170 { | |||
211 | 218 | ||
212 | /* qos queue settings */ | 219 | /* qos queue settings */ |
213 | spinlock_t tx_stats_lock; | 220 | spinlock_t tx_stats_lock; |
214 | struct ieee80211_tx_queue_stats tx_stats[5]; | 221 | struct ar9170_tx_queue_stats tx_stats[5]; |
215 | struct ieee80211_tx_queue_params edcf[5]; | 222 | struct ieee80211_tx_queue_params edcf[5]; |
216 | 223 | ||
217 | spinlock_t cmdlock; | 224 | spinlock_t cmdlock; |
@@ -231,7 +238,7 @@ struct ar9170 { | |||
231 | struct sk_buff_head tx_status_ampdu; | 238 | struct sk_buff_head tx_status_ampdu; |
232 | spinlock_t tx_ampdu_list_lock; | 239 | spinlock_t tx_ampdu_list_lock; |
233 | struct list_head tx_ampdu_list; | 240 | struct list_head tx_ampdu_list; |
234 | unsigned int tx_ampdu_pending; | 241 | atomic_t tx_ampdu_pending; |
235 | 242 | ||
236 | /* rxstream mpdu merge */ | 243 | /* rxstream mpdu merge */ |
237 | struct ar9170_rxstream_mpdu_merge rx_mpdu; | 244 | struct ar9170_rxstream_mpdu_merge rx_mpdu; |
@@ -248,13 +255,8 @@ struct ar9170_sta_info { | |||
248 | unsigned int ampdu_max_len; | 255 | unsigned int ampdu_max_len; |
249 | }; | 256 | }; |
250 | 257 | ||
251 | #define AR9170_TX_FLAG_WAIT_FOR_ACK BIT(0) | ||
252 | #define AR9170_TX_FLAG_NO_ACK BIT(1) | ||
253 | #define AR9170_TX_FLAG_BLOCK_ACK BIT(2) | ||
254 | |||
255 | struct ar9170_tx_info { | 258 | struct ar9170_tx_info { |
256 | unsigned long timeout; | 259 | unsigned long timeout; |
257 | unsigned int flags; | ||
258 | }; | 260 | }; |
259 | 261 | ||
260 | #define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) | 262 | #define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) |
diff --git a/drivers/net/wireless/ath/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c index f57a6200167b..cf6f5c4174a6 100644 --- a/drivers/net/wireless/ath/ar9170/cmd.c +++ b/drivers/net/wireless/ath/ar9170/cmd.c | |||
@@ -72,8 +72,7 @@ int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) | |||
72 | return err; | 72 | return err; |
73 | } | 73 | } |
74 | 74 | ||
75 | static int ar9170_read_mreg(struct ar9170 *ar, int nregs, | 75 | int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out) |
76 | const u32 *regs, u32 *out) | ||
77 | { | 76 | { |
78 | int i, err; | 77 | int i, err; |
79 | __le32 *offs, *res; | 78 | __le32 *offs, *res; |
diff --git a/drivers/net/wireless/ath/ar9170/cmd.h b/drivers/net/wireless/ath/ar9170/cmd.h index a4f0e50e52b4..826c45e6b274 100644 --- a/drivers/net/wireless/ath/ar9170/cmd.h +++ b/drivers/net/wireless/ath/ar9170/cmd.h | |||
@@ -44,6 +44,7 @@ | |||
44 | int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len); | 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); | 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); | 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); | ||
47 | int ar9170_echo_test(struct ar9170 *ar, u32 v); | 48 | int ar9170_echo_test(struct ar9170 *ar, u32 v); |
48 | 49 | ||
49 | /* | 50 | /* |
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h index 6cbfb2f83391..0a1d4c28e68a 100644 --- a/drivers/net/wireless/ath/ar9170/hw.h +++ b/drivers/net/wireless/ath/ar9170/hw.h | |||
@@ -152,14 +152,14 @@ enum ar9170_cmd { | |||
152 | #define AR9170_MAC_REG_FTF_BIT14 BIT(14) | 152 | #define AR9170_MAC_REG_FTF_BIT14 BIT(14) |
153 | #define AR9170_MAC_REG_FTF_BIT15 BIT(15) | 153 | #define AR9170_MAC_REG_FTF_BIT15 BIT(15) |
154 | #define AR9170_MAC_REG_FTF_BAR BIT(24) | 154 | #define AR9170_MAC_REG_FTF_BAR BIT(24) |
155 | #define AR9170_MAC_REG_FTF_BIT25 BIT(25) | 155 | #define AR9170_MAC_REG_FTF_BA BIT(25) |
156 | #define AR9170_MAC_REG_FTF_PSPOLL BIT(26) | 156 | #define AR9170_MAC_REG_FTF_PSPOLL BIT(26) |
157 | #define AR9170_MAC_REG_FTF_RTS BIT(27) | 157 | #define AR9170_MAC_REG_FTF_RTS BIT(27) |
158 | #define AR9170_MAC_REG_FTF_CTS BIT(28) | 158 | #define AR9170_MAC_REG_FTF_CTS BIT(28) |
159 | #define AR9170_MAC_REG_FTF_ACK BIT(29) | 159 | #define AR9170_MAC_REG_FTF_ACK BIT(29) |
160 | #define AR9170_MAC_REG_FTF_CFE BIT(30) | 160 | #define AR9170_MAC_REG_FTF_CFE BIT(30) |
161 | #define AR9170_MAC_REG_FTF_CFE_ACK BIT(31) | 161 | #define AR9170_MAC_REG_FTF_CFE_ACK BIT(31) |
162 | #define AR9170_MAC_REG_FTF_DEFAULTS 0x0500ffff | 162 | #define AR9170_MAC_REG_FTF_DEFAULTS 0x0700ffff |
163 | #define AR9170_MAC_REG_FTF_MONITOR 0xfd00ffff | 163 | #define AR9170_MAC_REG_FTF_MONITOR 0xfd00ffff |
164 | 164 | ||
165 | #define AR9170_MAC_REG_RX_TOTAL (AR9170_MAC_REG_BASE + 0x6A0) | 165 | #define AR9170_MAC_REG_RX_TOTAL (AR9170_MAC_REG_BASE + 0x6A0) |
@@ -276,6 +276,7 @@ struct ar9170_tx_control { | |||
276 | #define AR9170_TX_MAC_RATE_PROBE 0x8000 | 276 | #define AR9170_TX_MAC_RATE_PROBE 0x8000 |
277 | 277 | ||
278 | /* either-or */ | 278 | /* either-or */ |
279 | #define AR9170_TX_PHY_MOD_MASK 0x00000003 | ||
279 | #define AR9170_TX_PHY_MOD_CCK 0x00000000 | 280 | #define AR9170_TX_PHY_MOD_CCK 0x00000000 |
280 | #define AR9170_TX_PHY_MOD_OFDM 0x00000001 | 281 | #define AR9170_TX_PHY_MOD_OFDM 0x00000001 |
281 | #define AR9170_TX_PHY_MOD_HT 0x00000002 | 282 | #define AR9170_TX_PHY_MOD_HT 0x00000002 |
@@ -311,6 +312,8 @@ struct ar9170_tx_control { | |||
311 | 312 | ||
312 | #define AR9170_TX_PHY_SHORT_GI 0x80000000 | 313 | #define AR9170_TX_PHY_SHORT_GI 0x80000000 |
313 | 314 | ||
315 | #define AR5416_MAX_RATE_POWER 63 | ||
316 | |||
314 | struct ar9170_rx_head { | 317 | struct ar9170_rx_head { |
315 | u8 plcp[12]; | 318 | u8 plcp[12]; |
316 | } __packed; | 319 | } __packed; |
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c index 614e3218a2bc..857e86104295 100644 --- a/drivers/net/wireless/ath/ar9170/mac.c +++ b/drivers/net/wireless/ath/ar9170/mac.c | |||
@@ -35,6 +35,9 @@ | |||
35 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 35 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
36 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 36 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
37 | */ | 37 | */ |
38 | |||
39 | #include <asm/unaligned.h> | ||
40 | |||
38 | #include "ar9170.h" | 41 | #include "ar9170.h" |
39 | #include "cmd.h" | 42 | #include "cmd.h" |
40 | 43 | ||
@@ -114,7 +117,7 @@ int ar9170_set_qos(struct ar9170 *ar) | |||
114 | ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP, | 117 | ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP, |
115 | ar->edcf[0].txop | ar->edcf[1].txop << 16); | 118 | ar->edcf[0].txop | ar->edcf[1].txop << 16); |
116 | ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP, | 119 | ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP, |
117 | ar->edcf[1].txop | ar->edcf[3].txop << 16); | 120 | ar->edcf[2].txop | ar->edcf[3].txop << 16); |
118 | 121 | ||
119 | ar9170_regwrite_finish(); | 122 | ar9170_regwrite_finish(); |
120 | 123 | ||
@@ -227,11 +230,8 @@ static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac) | |||
227 | 230 | ||
228 | ar9170_regwrite_begin(ar); | 231 | ar9170_regwrite_begin(ar); |
229 | 232 | ||
230 | ar9170_regwrite(reg, | 233 | ar9170_regwrite(reg, get_unaligned_le32(mac)); |
231 | (mac[3] << 24) | (mac[2] << 16) | | 234 | ar9170_regwrite(reg + 4, get_unaligned_le16(mac + 4)); |
232 | (mac[1] << 8) | mac[0]); | ||
233 | |||
234 | ar9170_regwrite(reg + 4, (mac[5] << 8) | mac[4]); | ||
235 | 235 | ||
236 | ar9170_regwrite_finish(); | 236 | ar9170_regwrite_finish(); |
237 | 237 | ||
@@ -311,13 +311,14 @@ static int ar9170_set_promiscouous(struct ar9170 *ar) | |||
311 | 311 | ||
312 | int ar9170_set_operating_mode(struct ar9170 *ar) | 312 | int ar9170_set_operating_mode(struct ar9170 *ar) |
313 | { | 313 | { |
314 | struct ath_common *common = &ar->common; | ||
314 | u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS; | 315 | u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS; |
315 | u8 *mac_addr, *bssid; | 316 | u8 *mac_addr, *bssid; |
316 | int err; | 317 | int err; |
317 | 318 | ||
318 | if (ar->vif) { | 319 | if (ar->vif) { |
319 | mac_addr = ar->mac_addr; | 320 | mac_addr = common->macaddr; |
320 | bssid = ar->bssid; | 321 | bssid = common->curbssid; |
321 | 322 | ||
322 | switch (ar->vif->type) { | 323 | switch (ar->vif->type) { |
323 | case NL80211_IFTYPE_MESH_POINT: | 324 | case NL80211_IFTYPE_MESH_POINT: |
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index c1f8c69db165..c53692980990 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -38,6 +38,7 @@ | |||
38 | */ | 38 | */ |
39 | 39 | ||
40 | #include <linux/init.h> | 40 | #include <linux/init.h> |
41 | #include <linux/slab.h> | ||
41 | #include <linux/module.h> | 42 | #include <linux/module.h> |
42 | #include <linux/etherdevice.h> | 43 | #include <linux/etherdevice.h> |
43 | #include <net/mac80211.h> | 44 | #include <net/mac80211.h> |
@@ -194,12 +195,15 @@ static inline u16 ar9170_get_seq(struct sk_buff *skb) | |||
194 | return ar9170_get_seq_h((void *) txc->frame_data); | 195 | return ar9170_get_seq_h((void *) txc->frame_data); |
195 | } | 196 | } |
196 | 197 | ||
198 | static inline u16 ar9170_get_tid_h(struct ieee80211_hdr *hdr) | ||
199 | { | ||
200 | return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
201 | } | ||
202 | |||
197 | static inline u16 ar9170_get_tid(struct sk_buff *skb) | 203 | static inline u16 ar9170_get_tid(struct sk_buff *skb) |
198 | { | 204 | { |
199 | struct ar9170_tx_control *txc = (void *) skb->data; | 205 | struct ar9170_tx_control *txc = (void *) skb->data; |
200 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; | 206 | return ar9170_get_tid_h((struct ieee80211_hdr *) txc->frame_data); |
201 | |||
202 | return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
203 | } | 207 | } |
204 | 208 | ||
205 | #define GET_NEXT_SEQ(seq) ((seq + 1) & 0x0fff) | 209 | #define GET_NEXT_SEQ(seq) ((seq + 1) & 0x0fff) |
@@ -213,10 +217,10 @@ static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) | |||
213 | struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; | 217 | struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; |
214 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; | 218 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; |
215 | 219 | ||
216 | printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x s:%d " | 220 | printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] s:%d " |
217 | "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", | 221 | "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", |
218 | wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), | 222 | wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), |
219 | ieee80211_get_DA(hdr), arinfo->flags, ar9170_get_seq_h(hdr), | 223 | ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr), |
220 | le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), | 224 | le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), |
221 | jiffies_to_msecs(arinfo->timeout - jiffies)); | 225 | jiffies_to_msecs(arinfo->timeout - jiffies)); |
222 | } | 226 | } |
@@ -391,7 +395,7 @@ static void ar9170_tx_fake_ampdu_status(struct ar9170 *ar) | |||
391 | ieee80211_tx_status_irqsafe(ar->hw, skb); | 395 | ieee80211_tx_status_irqsafe(ar->hw, skb); |
392 | } | 396 | } |
393 | 397 | ||
394 | for_each_bit(i, &queue_bitmap, BITS_PER_BYTE) { | 398 | for_each_set_bit(i, &queue_bitmap, BITS_PER_BYTE) { |
395 | #ifdef AR9170_QUEUE_STOP_DEBUG | 399 | #ifdef AR9170_QUEUE_STOP_DEBUG |
396 | printk(KERN_DEBUG "%s: wake queue %d\n", | 400 | printk(KERN_DEBUG "%s: wake queue %d\n", |
397 | wiphy_name(ar->hw->wiphy), i); | 401 | wiphy_name(ar->hw->wiphy), i); |
@@ -414,9 +418,9 @@ static void ar9170_tx_ampdu_callback(struct ar9170 *ar, struct sk_buff *skb) | |||
414 | 418 | ||
415 | skb_queue_tail(&ar->tx_status_ampdu, skb); | 419 | skb_queue_tail(&ar->tx_status_ampdu, skb); |
416 | ar9170_tx_fake_ampdu_status(ar); | 420 | ar9170_tx_fake_ampdu_status(ar); |
417 | ar->tx_ampdu_pending--; | ||
418 | 421 | ||
419 | if (!list_empty(&ar->tx_ampdu_list) && !ar->tx_ampdu_pending) | 422 | if (atomic_dec_and_test(&ar->tx_ampdu_pending) && |
423 | !list_empty(&ar->tx_ampdu_list)) | ||
420 | ar9170_tx_ampdu(ar); | 424 | ar9170_tx_ampdu(ar); |
421 | } | 425 | } |
422 | 426 | ||
@@ -430,7 +434,7 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) | |||
430 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | 434 | spin_lock_irqsave(&ar->tx_stats_lock, flags); |
431 | ar->tx_stats[queue].len--; | 435 | ar->tx_stats[queue].len--; |
432 | 436 | ||
433 | if (skb_queue_empty(&ar->tx_pending[queue])) { | 437 | if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) { |
434 | #ifdef AR9170_QUEUE_STOP_DEBUG | 438 | #ifdef AR9170_QUEUE_STOP_DEBUG |
435 | printk(KERN_DEBUG "%s: wake queue %d\n", | 439 | printk(KERN_DEBUG "%s: wake queue %d\n", |
436 | wiphy_name(ar->hw->wiphy), queue); | 440 | wiphy_name(ar->hw->wiphy), queue); |
@@ -440,22 +444,17 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) | |||
440 | } | 444 | } |
441 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | 445 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); |
442 | 446 | ||
443 | if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) { | 447 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) { |
444 | ar9170_tx_ampdu_callback(ar, skb); | ||
445 | } else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) { | ||
446 | arinfo->timeout = jiffies + | ||
447 | msecs_to_jiffies(AR9170_TX_TIMEOUT); | ||
448 | |||
449 | skb_queue_tail(&ar->tx_status[queue], skb); | ||
450 | } else if (arinfo->flags & AR9170_TX_FLAG_NO_ACK) { | ||
451 | ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); | 448 | ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); |
452 | } else { | 449 | } else { |
453 | #ifdef AR9170_QUEUE_DEBUG | 450 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { |
454 | printk(KERN_DEBUG "%s: unsupported frame flags!\n", | 451 | ar9170_tx_ampdu_callback(ar, skb); |
455 | wiphy_name(ar->hw->wiphy)); | 452 | } else { |
456 | ar9170_print_txheader(ar, skb); | 453 | arinfo->timeout = jiffies + |
457 | #endif /* AR9170_QUEUE_DEBUG */ | 454 | msecs_to_jiffies(AR9170_TX_TIMEOUT); |
458 | dev_kfree_skb_any(skb); | 455 | |
456 | skb_queue_tail(&ar->tx_status[queue], skb); | ||
457 | } | ||
459 | } | 458 | } |
460 | 459 | ||
461 | if (!ar->tx_stats[queue].len && | 460 | if (!ar->tx_stats[queue].len && |
@@ -850,6 +849,7 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, | |||
850 | } | 849 | } |
851 | break; | 850 | break; |
852 | 851 | ||
852 | case AR9170_RX_STATUS_MODULATION_DUPOFDM: | ||
853 | case AR9170_RX_STATUS_MODULATION_OFDM: | 853 | case AR9170_RX_STATUS_MODULATION_OFDM: |
854 | switch (head->plcp[0] & 0xf) { | 854 | switch (head->plcp[0] & 0xf) { |
855 | case 0xb: | 855 | case 0xb: |
@@ -897,8 +897,7 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, | |||
897 | status->flag |= RX_FLAG_HT; | 897 | status->flag |= RX_FLAG_HT; |
898 | break; | 898 | break; |
899 | 899 | ||
900 | case AR9170_RX_STATUS_MODULATION_DUPOFDM: | 900 | default: |
901 | /* XXX */ | ||
902 | if (ar9170_nag_limiter(ar)) | 901 | if (ar9170_nag_limiter(ar)) |
903 | printk(KERN_ERR "%s: invalid modulation\n", | 902 | printk(KERN_ERR "%s: invalid modulation\n", |
904 | wiphy_name(ar->hw->wiphy)); | 903 | wiphy_name(ar->hw->wiphy)); |
@@ -1248,6 +1247,7 @@ static int ar9170_op_start(struct ieee80211_hw *hw) | |||
1248 | ar->global_ampdu_density = 6; | 1247 | ar->global_ampdu_density = 6; |
1249 | ar->global_ampdu_factor = 3; | 1248 | ar->global_ampdu_factor = 3; |
1250 | 1249 | ||
1250 | atomic_set(&ar->tx_ampdu_pending, 0); | ||
1251 | ar->bad_hw_nagger = jiffies; | 1251 | ar->bad_hw_nagger = jiffies; |
1252 | 1252 | ||
1253 | err = ar->open(ar); | 1253 | err = ar->open(ar); |
@@ -1406,17 +1406,6 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) | |||
1406 | 1406 | ||
1407 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && | 1407 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && |
1408 | (is_valid_ether_addr(ieee80211_get_DA(hdr)))) { | 1408 | (is_valid_ether_addr(ieee80211_get_DA(hdr)))) { |
1409 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
1410 | if (unlikely(!info->control.sta)) | ||
1411 | goto err_out; | ||
1412 | |||
1413 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); | ||
1414 | arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK; | ||
1415 | |||
1416 | goto out; | ||
1417 | } | ||
1418 | |||
1419 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); | ||
1420 | /* | 1409 | /* |
1421 | * WARNING: | 1410 | * WARNING: |
1422 | * Putting the QoS queue bits into an unexplored territory is | 1411 | * Putting the QoS queue bits into an unexplored territory is |
@@ -1430,12 +1419,17 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) | |||
1430 | 1419 | ||
1431 | txc->phy_control |= | 1420 | txc->phy_control |= |
1432 | cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); | 1421 | cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); |
1433 | arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK; | 1422 | |
1434 | } else { | 1423 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { |
1435 | arinfo->flags = AR9170_TX_FLAG_NO_ACK; | 1424 | if (unlikely(!info->control.sta)) |
1425 | goto err_out; | ||
1426 | |||
1427 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); | ||
1428 | } else { | ||
1429 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); | ||
1430 | } | ||
1436 | } | 1431 | } |
1437 | 1432 | ||
1438 | out: | ||
1439 | return 0; | 1433 | return 0; |
1440 | 1434 | ||
1441 | err_out: | 1435 | err_out: |
@@ -1670,8 +1664,7 @@ static bool ar9170_tx_ampdu(struct ar9170 *ar) | |||
1670 | * tell the FW/HW that this is the last frame, | 1664 | * tell the FW/HW that this is the last frame, |
1671 | * that way it will wait for the immediate block ack. | 1665 | * that way it will wait for the immediate block ack. |
1672 | */ | 1666 | */ |
1673 | if (likely(skb_peek_tail(&agg))) | 1667 | ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg)); |
1674 | ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg)); | ||
1675 | 1668 | ||
1676 | #ifdef AR9170_TXAGG_DEBUG | 1669 | #ifdef AR9170_TXAGG_DEBUG |
1677 | printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n", | 1670 | printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n", |
@@ -1715,6 +1708,21 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1715 | 1708 | ||
1716 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { | 1709 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { |
1717 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | 1710 | spin_lock_irqsave(&ar->tx_stats_lock, flags); |
1711 | frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len, | ||
1712 | skb_queue_len(&ar->tx_pending[i])); | ||
1713 | |||
1714 | if (remaining_space < frames) { | ||
1715 | #ifdef AR9170_QUEUE_DEBUG | ||
1716 | printk(KERN_DEBUG "%s: tx quota reached queue:%d, " | ||
1717 | "remaining slots:%d, needed:%d\n", | ||
1718 | wiphy_name(ar->hw->wiphy), i, remaining_space, | ||
1719 | frames); | ||
1720 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1721 | frames = remaining_space; | ||
1722 | } | ||
1723 | |||
1724 | ar->tx_stats[i].len += frames; | ||
1725 | ar->tx_stats[i].count += frames; | ||
1718 | if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { | 1726 | if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { |
1719 | #ifdef AR9170_QUEUE_DEBUG | 1727 | #ifdef AR9170_QUEUE_DEBUG |
1720 | printk(KERN_DEBUG "%s: queue %d full\n", | 1728 | printk(KERN_DEBUG "%s: queue %d full\n", |
@@ -1732,25 +1740,8 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1732 | __ar9170_dump_txstats(ar); | 1740 | __ar9170_dump_txstats(ar); |
1733 | #endif /* AR9170_QUEUE_STOP_DEBUG */ | 1741 | #endif /* AR9170_QUEUE_STOP_DEBUG */ |
1734 | ieee80211_stop_queue(ar->hw, i); | 1742 | ieee80211_stop_queue(ar->hw, i); |
1735 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1736 | continue; | ||
1737 | } | 1743 | } |
1738 | 1744 | ||
1739 | frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len, | ||
1740 | skb_queue_len(&ar->tx_pending[i])); | ||
1741 | |||
1742 | if (remaining_space < frames) { | ||
1743 | #ifdef AR9170_QUEUE_DEBUG | ||
1744 | printk(KERN_DEBUG "%s: tx quota reached queue:%d, " | ||
1745 | "remaining slots:%d, needed:%d\n", | ||
1746 | wiphy_name(ar->hw->wiphy), i, remaining_space, | ||
1747 | frames); | ||
1748 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1749 | frames = remaining_space; | ||
1750 | } | ||
1751 | |||
1752 | ar->tx_stats[i].len += frames; | ||
1753 | ar->tx_stats[i].count += frames; | ||
1754 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | 1745 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); |
1755 | 1746 | ||
1756 | if (!frames) | 1747 | if (!frames) |
@@ -1772,8 +1763,8 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1772 | arinfo->timeout = jiffies + | 1763 | arinfo->timeout = jiffies + |
1773 | msecs_to_jiffies(AR9170_TX_TIMEOUT); | 1764 | msecs_to_jiffies(AR9170_TX_TIMEOUT); |
1774 | 1765 | ||
1775 | if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK) | 1766 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
1776 | ar->tx_ampdu_pending++; | 1767 | atomic_inc(&ar->tx_ampdu_pending); |
1777 | 1768 | ||
1778 | #ifdef AR9170_QUEUE_DEBUG | 1769 | #ifdef AR9170_QUEUE_DEBUG |
1779 | printk(KERN_DEBUG "%s: send frame q:%d =>\n", | 1770 | printk(KERN_DEBUG "%s: send frame q:%d =>\n", |
@@ -1783,8 +1774,8 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1783 | 1774 | ||
1784 | err = ar->tx(ar, skb); | 1775 | err = ar->tx(ar, skb); |
1785 | if (unlikely(err)) { | 1776 | if (unlikely(err)) { |
1786 | if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK) | 1777 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
1787 | ar->tx_ampdu_pending--; | 1778 | atomic_dec(&ar->tx_ampdu_pending); |
1788 | 1779 | ||
1789 | frames_failed++; | 1780 | frames_failed++; |
1790 | dev_kfree_skb_any(skb); | 1781 | dev_kfree_skb_any(skb); |
@@ -1931,7 +1922,7 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1931 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | 1922 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { |
1932 | bool run = ar9170_tx_ampdu_queue(ar, skb); | 1923 | bool run = ar9170_tx_ampdu_queue(ar, skb); |
1933 | 1924 | ||
1934 | if (run || !ar->tx_ampdu_pending) | 1925 | if (run || !atomic_read(&ar->tx_ampdu_pending)) |
1935 | ar9170_tx_ampdu(ar); | 1926 | ar9170_tx_ampdu(ar); |
1936 | } else { | 1927 | } else { |
1937 | unsigned int queue = skb_get_queue_mapping(skb); | 1928 | unsigned int queue = skb_get_queue_mapping(skb); |
@@ -1949,9 +1940,10 @@ err_free: | |||
1949 | } | 1940 | } |
1950 | 1941 | ||
1951 | static int ar9170_op_add_interface(struct ieee80211_hw *hw, | 1942 | static int ar9170_op_add_interface(struct ieee80211_hw *hw, |
1952 | struct ieee80211_if_init_conf *conf) | 1943 | struct ieee80211_vif *vif) |
1953 | { | 1944 | { |
1954 | struct ar9170 *ar = hw->priv; | 1945 | struct ar9170 *ar = hw->priv; |
1946 | struct ath_common *common = &ar->common; | ||
1955 | int err = 0; | 1947 | int err = 0; |
1956 | 1948 | ||
1957 | mutex_lock(&ar->mutex); | 1949 | mutex_lock(&ar->mutex); |
@@ -1961,8 +1953,8 @@ static int ar9170_op_add_interface(struct ieee80211_hw *hw, | |||
1961 | goto unlock; | 1953 | goto unlock; |
1962 | } | 1954 | } |
1963 | 1955 | ||
1964 | ar->vif = conf->vif; | 1956 | ar->vif = vif; |
1965 | memcpy(ar->mac_addr, conf->mac_addr, ETH_ALEN); | 1957 | memcpy(common->macaddr, vif->addr, ETH_ALEN); |
1966 | 1958 | ||
1967 | if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) { | 1959 | if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) { |
1968 | ar->rx_software_decryption = true; | 1960 | ar->rx_software_decryption = true; |
@@ -1982,7 +1974,7 @@ unlock: | |||
1982 | } | 1974 | } |
1983 | 1975 | ||
1984 | static void ar9170_op_remove_interface(struct ieee80211_hw *hw, | 1976 | static void ar9170_op_remove_interface(struct ieee80211_hw *hw, |
1985 | struct ieee80211_if_init_conf *conf) | 1977 | struct ieee80211_vif *vif) |
1986 | { | 1978 | { |
1987 | struct ar9170 *ar = hw->priv; | 1979 | struct ar9170 *ar = hw->priv; |
1988 | 1980 | ||
@@ -2131,12 +2123,13 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, | |||
2131 | u32 changed) | 2123 | u32 changed) |
2132 | { | 2124 | { |
2133 | struct ar9170 *ar = hw->priv; | 2125 | struct ar9170 *ar = hw->priv; |
2126 | struct ath_common *common = &ar->common; | ||
2134 | int err = 0; | 2127 | int err = 0; |
2135 | 2128 | ||
2136 | mutex_lock(&ar->mutex); | 2129 | mutex_lock(&ar->mutex); |
2137 | 2130 | ||
2138 | if (changed & BSS_CHANGED_BSSID) { | 2131 | if (changed & BSS_CHANGED_BSSID) { |
2139 | memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN); | 2132 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
2140 | err = ar9170_set_operating_mode(ar); | 2133 | err = ar9170_set_operating_mode(ar); |
2141 | if (err) | 2134 | if (err) |
2142 | goto out; | 2135 | goto out; |
@@ -2190,22 +2183,30 @@ static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw) | |||
2190 | { | 2183 | { |
2191 | struct ar9170 *ar = hw->priv; | 2184 | struct ar9170 *ar = hw->priv; |
2192 | int err; | 2185 | int err; |
2193 | u32 tsf_low; | ||
2194 | u32 tsf_high; | ||
2195 | u64 tsf; | 2186 | u64 tsf; |
2187 | #define NR 3 | ||
2188 | static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H, | ||
2189 | AR9170_MAC_REG_TSF_L, | ||
2190 | AR9170_MAC_REG_TSF_H }; | ||
2191 | u32 val[NR]; | ||
2192 | int loops = 0; | ||
2196 | 2193 | ||
2197 | mutex_lock(&ar->mutex); | 2194 | mutex_lock(&ar->mutex); |
2198 | err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low); | 2195 | |
2199 | if (!err) | 2196 | while (loops++ < 10) { |
2200 | err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high); | 2197 | err = ar9170_read_mreg(ar, NR, addr, val); |
2198 | if (err || val[0] == val[2]) | ||
2199 | break; | ||
2200 | } | ||
2201 | |||
2201 | mutex_unlock(&ar->mutex); | 2202 | mutex_unlock(&ar->mutex); |
2202 | 2203 | ||
2203 | if (WARN_ON(err)) | 2204 | if (WARN_ON(err)) |
2204 | return 0; | 2205 | return 0; |
2205 | 2206 | tsf = val[0]; | |
2206 | tsf = tsf_high; | 2207 | tsf = (tsf << 32) | val[1]; |
2207 | tsf = (tsf << 32) | tsf_low; | ||
2208 | return tsf; | 2208 | return tsf; |
2209 | #undef NR | ||
2209 | } | 2210 | } |
2210 | 2211 | ||
2211 | static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 2212 | static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
@@ -2329,55 +2330,55 @@ out: | |||
2329 | return err; | 2330 | return err; |
2330 | } | 2331 | } |
2331 | 2332 | ||
2332 | static void ar9170_sta_notify(struct ieee80211_hw *hw, | 2333 | static int ar9170_sta_add(struct ieee80211_hw *hw, |
2333 | struct ieee80211_vif *vif, | 2334 | struct ieee80211_vif *vif, |
2334 | enum sta_notify_cmd cmd, | 2335 | struct ieee80211_sta *sta) |
2335 | struct ieee80211_sta *sta) | ||
2336 | { | 2336 | { |
2337 | struct ar9170 *ar = hw->priv; | 2337 | struct ar9170 *ar = hw->priv; |
2338 | struct ar9170_sta_info *sta_info = (void *) sta->drv_priv; | 2338 | struct ar9170_sta_info *sta_info = (void *) sta->drv_priv; |
2339 | unsigned int i; | 2339 | unsigned int i; |
2340 | 2340 | ||
2341 | switch (cmd) { | 2341 | memset(sta_info, 0, sizeof(*sta_info)); |
2342 | case STA_NOTIFY_ADD: | ||
2343 | memset(sta_info, 0, sizeof(*sta_info)); | ||
2344 | 2342 | ||
2345 | if (!sta->ht_cap.ht_supported) | 2343 | if (!sta->ht_cap.ht_supported) |
2346 | break; | 2344 | return 0; |
2347 | 2345 | ||
2348 | if (sta->ht_cap.ampdu_density > ar->global_ampdu_density) | 2346 | if (sta->ht_cap.ampdu_density > ar->global_ampdu_density) |
2349 | ar->global_ampdu_density = sta->ht_cap.ampdu_density; | 2347 | ar->global_ampdu_density = sta->ht_cap.ampdu_density; |
2350 | 2348 | ||
2351 | if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor) | 2349 | if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor) |
2352 | ar->global_ampdu_factor = sta->ht_cap.ampdu_factor; | 2350 | ar->global_ampdu_factor = sta->ht_cap.ampdu_factor; |
2353 | 2351 | ||
2354 | for (i = 0; i < AR9170_NUM_TID; i++) { | 2352 | for (i = 0; i < AR9170_NUM_TID; i++) { |
2355 | sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN; | 2353 | sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN; |
2356 | sta_info->agg[i].active = false; | 2354 | sta_info->agg[i].active = false; |
2357 | sta_info->agg[i].ssn = 0; | 2355 | sta_info->agg[i].ssn = 0; |
2358 | sta_info->agg[i].retry = 0; | 2356 | sta_info->agg[i].tid = i; |
2359 | sta_info->agg[i].tid = i; | 2357 | INIT_LIST_HEAD(&sta_info->agg[i].list); |
2360 | INIT_LIST_HEAD(&sta_info->agg[i].list); | 2358 | skb_queue_head_init(&sta_info->agg[i].queue); |
2361 | skb_queue_head_init(&sta_info->agg[i].queue); | 2359 | } |
2362 | } | ||
2363 | 2360 | ||
2364 | sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); | 2361 | sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); |
2365 | break; | ||
2366 | 2362 | ||
2367 | case STA_NOTIFY_REMOVE: | 2363 | return 0; |
2368 | if (!sta->ht_cap.ht_supported) | 2364 | } |
2369 | break; | ||
2370 | 2365 | ||
2371 | for (i = 0; i < AR9170_NUM_TID; i++) { | 2366 | static int ar9170_sta_remove(struct ieee80211_hw *hw, |
2372 | sta_info->agg[i].state = AR9170_TID_STATE_INVALID; | 2367 | struct ieee80211_vif *vif, |
2373 | skb_queue_purge(&sta_info->agg[i].queue); | 2368 | struct ieee80211_sta *sta) |
2374 | } | 2369 | { |
2370 | struct ar9170_sta_info *sta_info = (void *) sta->drv_priv; | ||
2371 | unsigned int i; | ||
2375 | 2372 | ||
2376 | break; | 2373 | if (!sta->ht_cap.ht_supported) |
2374 | return 0; | ||
2377 | 2375 | ||
2378 | default: | 2376 | for (i = 0; i < AR9170_NUM_TID; i++) { |
2379 | break; | 2377 | sta_info->agg[i].state = AR9170_TID_STATE_INVALID; |
2378 | skb_queue_purge(&sta_info->agg[i].queue); | ||
2380 | } | 2379 | } |
2380 | |||
2381 | return 0; | ||
2381 | } | 2382 | } |
2382 | 2383 | ||
2383 | static int ar9170_get_stats(struct ieee80211_hw *hw, | 2384 | static int ar9170_get_stats(struct ieee80211_hw *hw, |
@@ -2397,18 +2398,6 @@ static int ar9170_get_stats(struct ieee80211_hw *hw, | |||
2397 | return 0; | 2398 | return 0; |
2398 | } | 2399 | } |
2399 | 2400 | ||
2400 | static int ar9170_get_tx_stats(struct ieee80211_hw *hw, | ||
2401 | struct ieee80211_tx_queue_stats *tx_stats) | ||
2402 | { | ||
2403 | struct ar9170 *ar = hw->priv; | ||
2404 | |||
2405 | spin_lock_bh(&ar->tx_stats_lock); | ||
2406 | memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues); | ||
2407 | spin_unlock_bh(&ar->tx_stats_lock); | ||
2408 | |||
2409 | return 0; | ||
2410 | } | ||
2411 | |||
2412 | static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, | 2401 | static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, |
2413 | const struct ieee80211_tx_queue_params *param) | 2402 | const struct ieee80211_tx_queue_params *param) |
2414 | { | 2403 | { |
@@ -2430,6 +2419,7 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
2430 | } | 2419 | } |
2431 | 2420 | ||
2432 | static int ar9170_ampdu_action(struct ieee80211_hw *hw, | 2421 | static int ar9170_ampdu_action(struct ieee80211_hw *hw, |
2422 | struct ieee80211_vif *vif, | ||
2433 | enum ieee80211_ampdu_mlme_action action, | 2423 | enum ieee80211_ampdu_mlme_action action, |
2434 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 2424 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) |
2435 | { | 2425 | { |
@@ -2459,7 +2449,7 @@ static int ar9170_ampdu_action(struct ieee80211_hw *hw, | |||
2459 | tid_info->state = AR9170_TID_STATE_PROGRESS; | 2449 | tid_info->state = AR9170_TID_STATE_PROGRESS; |
2460 | tid_info->active = false; | 2450 | tid_info->active = false; |
2461 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | 2451 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); |
2462 | ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 2452 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
2463 | break; | 2453 | break; |
2464 | 2454 | ||
2465 | case IEEE80211_AMPDU_TX_STOP: | 2455 | case IEEE80211_AMPDU_TX_STOP: |
@@ -2469,7 +2459,7 @@ static int ar9170_ampdu_action(struct ieee80211_hw *hw, | |||
2469 | tid_info->active = false; | 2459 | tid_info->active = false; |
2470 | skb_queue_purge(&tid_info->queue); | 2460 | skb_queue_purge(&tid_info->queue); |
2471 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | 2461 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); |
2472 | ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 2462 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
2473 | break; | 2463 | break; |
2474 | 2464 | ||
2475 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 2465 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
@@ -2507,9 +2497,9 @@ static const struct ieee80211_ops ar9170_ops = { | |||
2507 | .bss_info_changed = ar9170_op_bss_info_changed, | 2497 | .bss_info_changed = ar9170_op_bss_info_changed, |
2508 | .get_tsf = ar9170_op_get_tsf, | 2498 | .get_tsf = ar9170_op_get_tsf, |
2509 | .set_key = ar9170_set_key, | 2499 | .set_key = ar9170_set_key, |
2510 | .sta_notify = ar9170_sta_notify, | 2500 | .sta_add = ar9170_sta_add, |
2501 | .sta_remove = ar9170_sta_remove, | ||
2511 | .get_stats = ar9170_get_stats, | 2502 | .get_stats = ar9170_get_stats, |
2512 | .get_tx_stats = ar9170_get_tx_stats, | ||
2513 | .ampdu_action = ar9170_ampdu_action, | 2503 | .ampdu_action = ar9170_ampdu_action, |
2514 | }; | 2504 | }; |
2515 | 2505 | ||
@@ -2523,7 +2513,7 @@ void *ar9170_alloc(size_t priv_size) | |||
2523 | /* | 2513 | /* |
2524 | * this buffer is used for rx stream reconstruction. | 2514 | * this buffer is used for rx stream reconstruction. |
2525 | * Under heavy load this device (or the transport layer?) | 2515 | * Under heavy load this device (or the transport layer?) |
2526 | * tends to split the streams into seperate rx descriptors. | 2516 | * tends to split the streams into separate rx descriptors. |
2527 | */ | 2517 | */ |
2528 | 2518 | ||
2529 | skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL); | 2519 | skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL); |
@@ -2712,7 +2702,8 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev) | |||
2712 | dev_info(pdev, "Atheros AR9170 is registered as '%s'\n", | 2702 | dev_info(pdev, "Atheros AR9170 is registered as '%s'\n", |
2713 | wiphy_name(ar->hw->wiphy)); | 2703 | wiphy_name(ar->hw->wiphy)); |
2714 | 2704 | ||
2715 | return err; | 2705 | ar->registered = true; |
2706 | return 0; | ||
2716 | 2707 | ||
2717 | err_unreg: | 2708 | err_unreg: |
2718 | ieee80211_unregister_hw(ar->hw); | 2709 | ieee80211_unregister_hw(ar->hw); |
@@ -2723,11 +2714,14 @@ err_out: | |||
2723 | 2714 | ||
2724 | void ar9170_unregister(struct ar9170 *ar) | 2715 | void ar9170_unregister(struct ar9170 *ar) |
2725 | { | 2716 | { |
2717 | if (ar->registered) { | ||
2726 | #ifdef CONFIG_AR9170_LEDS | 2718 | #ifdef CONFIG_AR9170_LEDS |
2727 | ar9170_unregister_leds(ar); | 2719 | ar9170_unregister_leds(ar); |
2728 | #endif /* CONFIG_AR9170_LEDS */ | 2720 | #endif /* CONFIG_AR9170_LEDS */ |
2729 | 2721 | ||
2730 | kfree_skb(ar->rx_failover); | ||
2731 | ieee80211_unregister_hw(ar->hw); | 2722 | ieee80211_unregister_hw(ar->hw); |
2723 | } | ||
2724 | |||
2725 | kfree_skb(ar->rx_failover); | ||
2732 | mutex_destroy(&ar->mutex); | 2726 | mutex_destroy(&ar->mutex); |
2733 | } | 2727 | } |
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c index dbd488da18b1..45a415ea809a 100644 --- a/drivers/net/wireless/ath/ar9170/phy.c +++ b/drivers/net/wireless/ath/ar9170/phy.c | |||
@@ -1239,9 +1239,6 @@ static u8 ar9170_get_max_edge_power(struct ar9170 *ar, | |||
1239 | struct ar9170_calctl_edges edges[], | 1239 | struct ar9170_calctl_edges edges[], |
1240 | u32 freq) | 1240 | u32 freq) |
1241 | { | 1241 | { |
1242 | /* TODO: move somewhere else */ | ||
1243 | #define AR5416_MAX_RATE_POWER 63 | ||
1244 | |||
1245 | int i; | 1242 | int i; |
1246 | u8 rc = AR5416_MAX_RATE_POWER; | 1243 | u8 rc = AR5416_MAX_RATE_POWER; |
1247 | u8 f; | 1244 | u8 f; |
@@ -1259,10 +1256,11 @@ static u8 ar9170_get_max_edge_power(struct ar9170 *ar, | |||
1259 | break; | 1256 | break; |
1260 | } | 1257 | } |
1261 | if (i > 0 && f < edges[i].channel) { | 1258 | if (i > 0 && f < edges[i].channel) { |
1262 | if (f > edges[i-1].channel && | 1259 | if (f > edges[i - 1].channel && |
1263 | edges[i-1].power_flags & AR9170_CALCTL_EDGE_FLAGS) { | 1260 | edges[i - 1].power_flags & |
1261 | AR9170_CALCTL_EDGE_FLAGS) { | ||
1264 | /* lower channel has the inband flag set */ | 1262 | /* lower channel has the inband flag set */ |
1265 | rc = edges[i-1].power_flags & | 1263 | rc = edges[i - 1].power_flags & |
1266 | ~AR9170_CALCTL_EDGE_FLAGS; | 1264 | ~AR9170_CALCTL_EDGE_FLAGS; |
1267 | } | 1265 | } |
1268 | break; | 1266 | break; |
@@ -1270,18 +1268,48 @@ static u8 ar9170_get_max_edge_power(struct ar9170 *ar, | |||
1270 | } | 1268 | } |
1271 | 1269 | ||
1272 | if (i == AR5416_NUM_BAND_EDGES) { | 1270 | if (i == AR5416_NUM_BAND_EDGES) { |
1273 | if (f > edges[i-1].channel && | 1271 | if (f > edges[i - 1].channel && |
1274 | edges[i-1].power_flags & AR9170_CALCTL_EDGE_FLAGS) { | 1272 | edges[i - 1].power_flags & AR9170_CALCTL_EDGE_FLAGS) { |
1275 | /* lower channel has the inband flag set */ | 1273 | /* lower channel has the inband flag set */ |
1276 | rc = edges[i-1].power_flags & | 1274 | rc = edges[i - 1].power_flags & |
1277 | ~AR9170_CALCTL_EDGE_FLAGS; | 1275 | ~AR9170_CALCTL_EDGE_FLAGS; |
1278 | } | 1276 | } |
1279 | } | 1277 | } |
1280 | return rc; | 1278 | return rc; |
1281 | } | 1279 | } |
1282 | 1280 | ||
1283 | /* calculate the conformance test limits and apply them to ar->power* | 1281 | static u8 ar9170_get_heavy_clip(struct ar9170 *ar, |
1284 | * (derived from otus hal/hpmain.c, line 3706 ff.) | 1282 | struct ar9170_calctl_edges edges[], |
1283 | u32 freq, enum ar9170_bw bw) | ||
1284 | { | ||
1285 | u8 f; | ||
1286 | int i; | ||
1287 | u8 rc = 0; | ||
1288 | |||
1289 | if (freq < 3000) | ||
1290 | f = freq - 2300; | ||
1291 | else | ||
1292 | f = (freq - 4800) / 5; | ||
1293 | |||
1294 | if (bw == AR9170_BW_40_BELOW || bw == AR9170_BW_40_ABOVE) | ||
1295 | rc |= 0xf0; | ||
1296 | |||
1297 | for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) { | ||
1298 | if (edges[i].channel == 0xff) | ||
1299 | break; | ||
1300 | if (f == edges[i].channel) { | ||
1301 | if (!(edges[i].power_flags & AR9170_CALCTL_EDGE_FLAGS)) | ||
1302 | rc |= 0x0f; | ||
1303 | break; | ||
1304 | } | ||
1305 | } | ||
1306 | |||
1307 | return rc; | ||
1308 | } | ||
1309 | |||
1310 | /* | ||
1311 | * calculate the conformance test limits and the heavy clip parameter | ||
1312 | * and apply them to ar->power* (derived from otus hal/hpmain.c, line 3706) | ||
1285 | */ | 1313 | */ |
1286 | static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) | 1314 | static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) |
1287 | { | 1315 | { |
@@ -1295,7 +1323,8 @@ static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) | |||
1295 | int pwr_cal_len; | 1323 | int pwr_cal_len; |
1296 | } *modes; | 1324 | } *modes; |
1297 | 1325 | ||
1298 | /* order is relevant in the mode_list_*: we fall back to the | 1326 | /* |
1327 | * order is relevant in the mode_list_*: we fall back to the | ||
1299 | * lower indices if any mode is missed in the EEPROM. | 1328 | * lower indices if any mode is missed in the EEPROM. |
1300 | */ | 1329 | */ |
1301 | struct ctl_modes mode_list_2ghz[] = { | 1330 | struct ctl_modes mode_list_2ghz[] = { |
@@ -1313,7 +1342,10 @@ static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) | |||
1313 | 1342 | ||
1314 | #define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n]) | 1343 | #define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n]) |
1315 | 1344 | ||
1316 | /* TODO: investigate the differences between OTUS' | 1345 | ar->phy_heavy_clip = 0; |
1346 | |||
1347 | /* | ||
1348 | * TODO: investigate the differences between OTUS' | ||
1317 | * hpreg.c::zfHpGetRegulatoryDomain() and | 1349 | * hpreg.c::zfHpGetRegulatoryDomain() and |
1318 | * ath/regd.c::ath_regd_get_band_ctl() - | 1350 | * ath/regd.c::ath_regd_get_band_ctl() - |
1319 | * e.g. for FCC3_WORLD the OTUS procedure | 1351 | * e.g. for FCC3_WORLD the OTUS procedure |
@@ -1347,6 +1379,15 @@ static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) | |||
1347 | if (ctl_idx < AR5416_NUM_CTLS) { | 1379 | if (ctl_idx < AR5416_NUM_CTLS) { |
1348 | int f_off = 0; | 1380 | int f_off = 0; |
1349 | 1381 | ||
1382 | /* determine heav clip parameter from | ||
1383 | the 11G edges array */ | ||
1384 | if (modes[i].ctl_mode == CTL_11G) { | ||
1385 | ar->phy_heavy_clip = | ||
1386 | ar9170_get_heavy_clip(ar, | ||
1387 | EDGES(ctl_idx, 1), | ||
1388 | freq, bw); | ||
1389 | } | ||
1390 | |||
1350 | /* adjust freq for 40MHz */ | 1391 | /* adjust freq for 40MHz */ |
1351 | if (modes[i].ctl_mode == CTL_2GHT40 || | 1392 | if (modes[i].ctl_mode == CTL_2GHT40 || |
1352 | modes[i].ctl_mode == CTL_5GHT40) { | 1393 | modes[i].ctl_mode == CTL_5GHT40) { |
@@ -1360,13 +1401,15 @@ static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) | |||
1360 | ar9170_get_max_edge_power(ar, EDGES(ctl_idx, 1), | 1401 | ar9170_get_max_edge_power(ar, EDGES(ctl_idx, 1), |
1361 | freq+f_off); | 1402 | freq+f_off); |
1362 | 1403 | ||
1363 | /* TODO: check if the regulatory max. power is | 1404 | /* |
1405 | * TODO: check if the regulatory max. power is | ||
1364 | * controlled by cfg80211 for DFS | 1406 | * controlled by cfg80211 for DFS |
1365 | * (hpmain applies it to max_power itself for DFS freq) | 1407 | * (hpmain applies it to max_power itself for DFS freq) |
1366 | */ | 1408 | */ |
1367 | 1409 | ||
1368 | } else { | 1410 | } else { |
1369 | /* Workaround in otus driver, hpmain.c, line 3906: | 1411 | /* |
1412 | * Workaround in otus driver, hpmain.c, line 3906: | ||
1370 | * if no data for 5GHT20 are found, take the | 1413 | * if no data for 5GHT20 are found, take the |
1371 | * legacy 5G value. | 1414 | * legacy 5G value. |
1372 | * We extend this here to fallback from any other *HT or | 1415 | * We extend this here to fallback from any other *HT or |
@@ -1390,6 +1433,19 @@ static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) | |||
1390 | modes[i].max_power); | 1433 | modes[i].max_power); |
1391 | } | 1434 | } |
1392 | } | 1435 | } |
1436 | |||
1437 | if (ar->phy_heavy_clip & 0xf0) { | ||
1438 | ar->power_2G_ht40[0]--; | ||
1439 | ar->power_2G_ht40[1]--; | ||
1440 | ar->power_2G_ht40[2]--; | ||
1441 | } | ||
1442 | if (ar->phy_heavy_clip & 0xf) { | ||
1443 | ar->power_2G_ht20[0]++; | ||
1444 | ar->power_2G_ht20[1]++; | ||
1445 | ar->power_2G_ht20[2]++; | ||
1446 | } | ||
1447 | |||
1448 | |||
1393 | #undef EDGES | 1449 | #undef EDGES |
1394 | } | 1450 | } |
1395 | 1451 | ||
@@ -1499,8 +1555,6 @@ static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) | |||
1499 | /* calc. conformance test limits and apply to ar->power*[] */ | 1555 | /* calc. conformance test limits and apply to ar->power*[] */ |
1500 | ar9170_calc_ctl(ar, freq, bw); | 1556 | ar9170_calc_ctl(ar, freq, bw); |
1501 | 1557 | ||
1502 | /* TODO: (heavy clip) regulatory domain power level fine-tuning. */ | ||
1503 | |||
1504 | /* set ACK/CTS TX power */ | 1558 | /* set ACK/CTS TX power */ |
1505 | ar9170_regwrite_begin(ar); | 1559 | ar9170_regwrite_begin(ar); |
1506 | 1560 | ||
@@ -1643,6 +1697,17 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, | |||
1643 | if (err) | 1697 | if (err) |
1644 | return err; | 1698 | return err; |
1645 | 1699 | ||
1700 | if (ar->phy_heavy_clip) { | ||
1701 | err = ar9170_write_reg(ar, 0x1c59e0, | ||
1702 | 0x200 | ar->phy_heavy_clip); | ||
1703 | if (err) { | ||
1704 | if (ar9170_nag_limiter(ar)) | ||
1705 | printk(KERN_ERR "%s: failed to set " | ||
1706 | "heavy clip\n", | ||
1707 | wiphy_name(ar->hw->wiphy)); | ||
1708 | } | ||
1709 | } | ||
1710 | |||
1646 | for (i = 0; i < 2; i++) { | 1711 | for (i = 0; i < 2; i++) { |
1647 | ar->noise[i] = ar9170_calc_noise_dbm( | 1712 | ar->noise[i] = ar9170_calc_noise_dbm( |
1648 | (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff); | 1713 | (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff); |
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index e974e5829e1a..e1c2fcaa8bed 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c | |||
@@ -38,6 +38,7 @@ | |||
38 | */ | 38 | */ |
39 | 39 | ||
40 | #include <linux/module.h> | 40 | #include <linux/module.h> |
41 | #include <linux/slab.h> | ||
41 | #include <linux/usb.h> | 42 | #include <linux/usb.h> |
42 | #include <linux/firmware.h> | 43 | #include <linux/firmware.h> |
43 | #include <linux/etherdevice.h> | 44 | #include <linux/etherdevice.h> |
@@ -68,8 +69,10 @@ static struct usb_device_id ar9170_usb_ids[] = { | |||
68 | { USB_DEVICE(0x0cf3, 0x1002) }, | 69 | { USB_DEVICE(0x0cf3, 0x1002) }, |
69 | /* Cace Airpcap NX */ | 70 | /* Cace Airpcap NX */ |
70 | { USB_DEVICE(0xcace, 0x0300) }, | 71 | { USB_DEVICE(0xcace, 0x0300) }, |
71 | /* D-Link DWA 160A */ | 72 | /* D-Link DWA 160 A1 */ |
72 | { USB_DEVICE(0x07d1, 0x3c10) }, | 73 | { USB_DEVICE(0x07d1, 0x3c10) }, |
74 | /* D-Link DWA 160 A2 */ | ||
75 | { USB_DEVICE(0x07d1, 0x3a09) }, | ||
73 | /* Netgear WNDA3100 */ | 76 | /* Netgear WNDA3100 */ |
74 | { USB_DEVICE(0x0846, 0x9010) }, | 77 | { USB_DEVICE(0x0846, 0x9010) }, |
75 | /* Netgear WN111 v2 */ | 78 | /* Netgear WN111 v2 */ |
@@ -82,6 +85,8 @@ static struct usb_device_id ar9170_usb_ids[] = { | |||
82 | { USB_DEVICE(0x0cde, 0x0023) }, | 85 | { USB_DEVICE(0x0cde, 0x0023) }, |
83 | /* Z-Com UB82 ABG */ | 86 | /* Z-Com UB82 ABG */ |
84 | { USB_DEVICE(0x0cde, 0x0026) }, | 87 | { USB_DEVICE(0x0cde, 0x0026) }, |
88 | /* Sphairon Homelink 1202 */ | ||
89 | { USB_DEVICE(0x0cde, 0x0027) }, | ||
85 | /* Arcadyan WN7512 */ | 90 | /* Arcadyan WN7512 */ |
86 | { USB_DEVICE(0x083a, 0xf522) }, | 91 | { USB_DEVICE(0x083a, 0xf522) }, |
87 | /* Planex GWUS300 */ | 92 | /* Planex GWUS300 */ |
@@ -90,6 +95,8 @@ static struct usb_device_id ar9170_usb_ids[] = { | |||
90 | { USB_DEVICE(0x04bb, 0x093f) }, | 95 | { USB_DEVICE(0x04bb, 0x093f) }, |
91 | /* AVM FRITZ!WLAN USB Stick N */ | 96 | /* AVM FRITZ!WLAN USB Stick N */ |
92 | { USB_DEVICE(0x057C, 0x8401) }, | 97 | { USB_DEVICE(0x057C, 0x8401) }, |
98 | /* NEC WL300NU-G */ | ||
99 | { USB_DEVICE(0x0409, 0x0249) }, | ||
93 | /* AVM FRITZ!WLAN USB Stick N 2.4 */ | 100 | /* AVM FRITZ!WLAN USB Stick N 2.4 */ |
94 | { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY }, | 101 | { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY }, |
95 | 102 | ||
@@ -108,15 +115,15 @@ static void ar9170_usb_submit_urb(struct ar9170_usb *aru) | |||
108 | return ; | 115 | return ; |
109 | 116 | ||
110 | spin_lock_irqsave(&aru->tx_urb_lock, flags); | 117 | spin_lock_irqsave(&aru->tx_urb_lock, flags); |
111 | if (aru->tx_submitted_urbs >= AR9170_NUM_TX_URBS) { | 118 | if (atomic_read(&aru->tx_submitted_urbs) >= AR9170_NUM_TX_URBS) { |
112 | spin_unlock_irqrestore(&aru->tx_urb_lock, flags); | 119 | spin_unlock_irqrestore(&aru->tx_urb_lock, flags); |
113 | return ; | 120 | return ; |
114 | } | 121 | } |
115 | aru->tx_submitted_urbs++; | 122 | atomic_inc(&aru->tx_submitted_urbs); |
116 | 123 | ||
117 | urb = usb_get_from_anchor(&aru->tx_pending); | 124 | urb = usb_get_from_anchor(&aru->tx_pending); |
118 | if (!urb) { | 125 | if (!urb) { |
119 | aru->tx_submitted_urbs--; | 126 | atomic_dec(&aru->tx_submitted_urbs); |
120 | spin_unlock_irqrestore(&aru->tx_urb_lock, flags); | 127 | spin_unlock_irqrestore(&aru->tx_urb_lock, flags); |
121 | 128 | ||
122 | return ; | 129 | return ; |
@@ -133,7 +140,7 @@ static void ar9170_usb_submit_urb(struct ar9170_usb *aru) | |||
133 | err); | 140 | err); |
134 | 141 | ||
135 | usb_unanchor_urb(urb); | 142 | usb_unanchor_urb(urb); |
136 | aru->tx_submitted_urbs--; | 143 | atomic_dec(&aru->tx_submitted_urbs); |
137 | ar9170_tx_callback(&aru->common, urb->context); | 144 | ar9170_tx_callback(&aru->common, urb->context); |
138 | } | 145 | } |
139 | 146 | ||
@@ -151,7 +158,7 @@ static void ar9170_usb_tx_urb_complete_frame(struct urb *urb) | |||
151 | return ; | 158 | return ; |
152 | } | 159 | } |
153 | 160 | ||
154 | aru->tx_submitted_urbs--; | 161 | atomic_dec(&aru->tx_submitted_urbs); |
155 | 162 | ||
156 | ar9170_tx_callback(&aru->common, skb); | 163 | ar9170_tx_callback(&aru->common, skb); |
157 | 164 | ||
@@ -412,7 +419,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd, | |||
412 | spin_unlock_irqrestore(&aru->common.cmdlock, flags); | 419 | spin_unlock_irqrestore(&aru->common.cmdlock, flags); |
413 | 420 | ||
414 | usb_fill_int_urb(urb, aru->udev, | 421 | usb_fill_int_urb(urb, aru->udev, |
415 | usb_sndbulkpipe(aru->udev, AR9170_EP_CMD), | 422 | usb_sndintpipe(aru->udev, AR9170_EP_CMD), |
416 | aru->common.cmdbuf, plen + 4, | 423 | aru->common.cmdbuf, plen + 4, |
417 | ar9170_usb_tx_urb_complete, NULL, 1); | 424 | ar9170_usb_tx_urb_complete, NULL, 1); |
418 | 425 | ||
@@ -578,43 +585,6 @@ static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data, | |||
578 | return 0; | 585 | return 0; |
579 | } | 586 | } |
580 | 587 | ||
581 | static int ar9170_usb_request_firmware(struct ar9170_usb *aru) | ||
582 | { | ||
583 | int err = 0; | ||
584 | |||
585 | err = request_firmware(&aru->firmware, "ar9170.fw", | ||
586 | &aru->udev->dev); | ||
587 | if (!err) { | ||
588 | aru->init_values = NULL; | ||
589 | return 0; | ||
590 | } | ||
591 | |||
592 | if (aru->req_one_stage_fw) { | ||
593 | dev_err(&aru->udev->dev, "ar9170.fw firmware file " | ||
594 | "not found and is required for this device\n"); | ||
595 | return -EINVAL; | ||
596 | } | ||
597 | |||
598 | dev_err(&aru->udev->dev, "ar9170.fw firmware file " | ||
599 | "not found, trying old firmware...\n"); | ||
600 | |||
601 | err = request_firmware(&aru->init_values, "ar9170-1.fw", | ||
602 | &aru->udev->dev); | ||
603 | if (err) { | ||
604 | dev_err(&aru->udev->dev, "file with init values not found.\n"); | ||
605 | return err; | ||
606 | } | ||
607 | |||
608 | err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev); | ||
609 | if (err) { | ||
610 | release_firmware(aru->init_values); | ||
611 | dev_err(&aru->udev->dev, "firmware file not found.\n"); | ||
612 | return err; | ||
613 | } | ||
614 | |||
615 | return err; | ||
616 | } | ||
617 | |||
618 | static int ar9170_usb_reset(struct ar9170_usb *aru) | 588 | static int ar9170_usb_reset(struct ar9170_usb *aru) |
619 | { | 589 | { |
620 | int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING); | 590 | int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING); |
@@ -753,6 +723,109 @@ err_out: | |||
753 | return err; | 723 | return err; |
754 | } | 724 | } |
755 | 725 | ||
726 | static void ar9170_usb_firmware_failed(struct ar9170_usb *aru) | ||
727 | { | ||
728 | struct device *parent = aru->udev->dev.parent; | ||
729 | |||
730 | complete(&aru->firmware_loading_complete); | ||
731 | |||
732 | /* unbind anything failed */ | ||
733 | if (parent) | ||
734 | down(&parent->sem); | ||
735 | device_release_driver(&aru->udev->dev); | ||
736 | if (parent) | ||
737 | up(&parent->sem); | ||
738 | |||
739 | usb_put_dev(aru->udev); | ||
740 | } | ||
741 | |||
742 | static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context) | ||
743 | { | ||
744 | struct ar9170_usb *aru = context; | ||
745 | int err; | ||
746 | |||
747 | aru->firmware = fw; | ||
748 | |||
749 | if (!fw) { | ||
750 | dev_err(&aru->udev->dev, "firmware file not found.\n"); | ||
751 | goto err_freefw; | ||
752 | } | ||
753 | |||
754 | err = ar9170_usb_init_device(aru); | ||
755 | if (err) | ||
756 | goto err_freefw; | ||
757 | |||
758 | err = ar9170_usb_open(&aru->common); | ||
759 | if (err) | ||
760 | goto err_unrx; | ||
761 | |||
762 | err = ar9170_register(&aru->common, &aru->udev->dev); | ||
763 | |||
764 | ar9170_usb_stop(&aru->common); | ||
765 | if (err) | ||
766 | goto err_unrx; | ||
767 | |||
768 | complete(&aru->firmware_loading_complete); | ||
769 | usb_put_dev(aru->udev); | ||
770 | return; | ||
771 | |||
772 | err_unrx: | ||
773 | ar9170_usb_cancel_urbs(aru); | ||
774 | |||
775 | err_freefw: | ||
776 | ar9170_usb_firmware_failed(aru); | ||
777 | } | ||
778 | |||
779 | static void ar9170_usb_firmware_inits(const struct firmware *fw, | ||
780 | void *context) | ||
781 | { | ||
782 | struct ar9170_usb *aru = context; | ||
783 | int err; | ||
784 | |||
785 | if (!fw) { | ||
786 | dev_err(&aru->udev->dev, "file with init values not found.\n"); | ||
787 | ar9170_usb_firmware_failed(aru); | ||
788 | return; | ||
789 | } | ||
790 | |||
791 | aru->init_values = fw; | ||
792 | |||
793 | /* ok so we have the init values -- get code for two-stage */ | ||
794 | |||
795 | err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-2.fw", | ||
796 | &aru->udev->dev, GFP_KERNEL, aru, | ||
797 | ar9170_usb_firmware_finish); | ||
798 | if (err) | ||
799 | ar9170_usb_firmware_failed(aru); | ||
800 | } | ||
801 | |||
802 | static void ar9170_usb_firmware_step2(const struct firmware *fw, void *context) | ||
803 | { | ||
804 | struct ar9170_usb *aru = context; | ||
805 | int err; | ||
806 | |||
807 | if (fw) { | ||
808 | ar9170_usb_firmware_finish(fw, context); | ||
809 | return; | ||
810 | } | ||
811 | |||
812 | if (aru->req_one_stage_fw) { | ||
813 | dev_err(&aru->udev->dev, "ar9170.fw firmware file " | ||
814 | "not found and is required for this device\n"); | ||
815 | ar9170_usb_firmware_failed(aru); | ||
816 | return; | ||
817 | } | ||
818 | |||
819 | dev_err(&aru->udev->dev, "ar9170.fw firmware file " | ||
820 | "not found, trying old firmware...\n"); | ||
821 | |||
822 | err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-1.fw", | ||
823 | &aru->udev->dev, GFP_KERNEL, aru, | ||
824 | ar9170_usb_firmware_inits); | ||
825 | if (err) | ||
826 | ar9170_usb_firmware_failed(aru); | ||
827 | } | ||
828 | |||
756 | static bool ar9170_requires_one_stage(const struct usb_device_id *id) | 829 | static bool ar9170_requires_one_stage(const struct usb_device_id *id) |
757 | { | 830 | { |
758 | if (!id->driver_info) | 831 | if (!id->driver_info) |
@@ -791,10 +864,11 @@ static int ar9170_usb_probe(struct usb_interface *intf, | |||
791 | init_usb_anchor(&aru->tx_pending); | 864 | init_usb_anchor(&aru->tx_pending); |
792 | init_usb_anchor(&aru->tx_submitted); | 865 | init_usb_anchor(&aru->tx_submitted); |
793 | init_completion(&aru->cmd_wait); | 866 | init_completion(&aru->cmd_wait); |
867 | init_completion(&aru->firmware_loading_complete); | ||
794 | spin_lock_init(&aru->tx_urb_lock); | 868 | spin_lock_init(&aru->tx_urb_lock); |
795 | 869 | ||
796 | aru->tx_pending_urbs = 0; | 870 | aru->tx_pending_urbs = 0; |
797 | aru->tx_submitted_urbs = 0; | 871 | atomic_set(&aru->tx_submitted_urbs, 0); |
798 | 872 | ||
799 | aru->common.stop = ar9170_usb_stop; | 873 | aru->common.stop = ar9170_usb_stop; |
800 | aru->common.flush = ar9170_usb_flush; | 874 | aru->common.flush = ar9170_usb_flush; |
@@ -810,33 +884,10 @@ static int ar9170_usb_probe(struct usb_interface *intf, | |||
810 | if (err) | 884 | if (err) |
811 | goto err_freehw; | 885 | goto err_freehw; |
812 | 886 | ||
813 | err = ar9170_usb_request_firmware(aru); | 887 | usb_get_dev(aru->udev); |
814 | if (err) | 888 | return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw", |
815 | goto err_freehw; | 889 | &aru->udev->dev, GFP_KERNEL, aru, |
816 | 890 | ar9170_usb_firmware_step2); | |
817 | err = ar9170_usb_init_device(aru); | ||
818 | if (err) | ||
819 | goto err_freefw; | ||
820 | |||
821 | err = ar9170_usb_open(ar); | ||
822 | if (err) | ||
823 | goto err_unrx; | ||
824 | |||
825 | err = ar9170_register(ar, &udev->dev); | ||
826 | |||
827 | ar9170_usb_stop(ar); | ||
828 | if (err) | ||
829 | goto err_unrx; | ||
830 | |||
831 | return 0; | ||
832 | |||
833 | err_unrx: | ||
834 | ar9170_usb_cancel_urbs(aru); | ||
835 | |||
836 | err_freefw: | ||
837 | release_firmware(aru->init_values); | ||
838 | release_firmware(aru->firmware); | ||
839 | |||
840 | err_freehw: | 891 | err_freehw: |
841 | usb_set_intfdata(intf, NULL); | 892 | usb_set_intfdata(intf, NULL); |
842 | usb_put_dev(udev); | 893 | usb_put_dev(udev); |
@@ -853,15 +904,18 @@ static void ar9170_usb_disconnect(struct usb_interface *intf) | |||
853 | return; | 904 | return; |
854 | 905 | ||
855 | aru->common.state = AR9170_IDLE; | 906 | aru->common.state = AR9170_IDLE; |
907 | |||
908 | wait_for_completion(&aru->firmware_loading_complete); | ||
909 | |||
856 | ar9170_unregister(&aru->common); | 910 | ar9170_unregister(&aru->common); |
857 | ar9170_usb_cancel_urbs(aru); | 911 | ar9170_usb_cancel_urbs(aru); |
858 | 912 | ||
859 | release_firmware(aru->init_values); | ||
860 | release_firmware(aru->firmware); | ||
861 | |||
862 | usb_put_dev(aru->udev); | 913 | usb_put_dev(aru->udev); |
863 | usb_set_intfdata(intf, NULL); | 914 | usb_set_intfdata(intf, NULL); |
864 | ieee80211_free_hw(aru->common.hw); | 915 | ieee80211_free_hw(aru->common.hw); |
916 | |||
917 | release_firmware(aru->init_values); | ||
918 | release_firmware(aru->firmware); | ||
865 | } | 919 | } |
866 | 920 | ||
867 | #ifdef CONFIG_PM | 921 | #ifdef CONFIG_PM |
diff --git a/drivers/net/wireless/ath/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h index d098f4d5d2f2..919b06046eb3 100644 --- a/drivers/net/wireless/ath/ar9170/usb.h +++ b/drivers/net/wireless/ath/ar9170/usb.h | |||
@@ -67,10 +67,11 @@ struct ar9170_usb { | |||
67 | bool req_one_stage_fw; | 67 | bool req_one_stage_fw; |
68 | 68 | ||
69 | spinlock_t tx_urb_lock; | 69 | spinlock_t tx_urb_lock; |
70 | unsigned int tx_submitted_urbs; | 70 | atomic_t tx_submitted_urbs; |
71 | unsigned int tx_pending_urbs; | 71 | unsigned int tx_pending_urbs; |
72 | 72 | ||
73 | struct completion cmd_wait; | 73 | struct completion cmd_wait; |
74 | struct completion firmware_loading_complete; | ||
74 | int readlen; | 75 | int readlen; |
75 | u8 *readbuf; | 76 | u8 *readbuf; |
76 | 77 | ||