blob: b43d4b006d7eba8813e6b5b23d0857caea8d7b3a [file] [log] [blame]
Christian Lampartere9348cd2009-03-21 23:05:13 +01001/*
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
Christian Lampartere9348cd2009-03-21 23:05:13 +010040#include <linux/init.h>
41#include <linux/module.h>
42#include <linux/etherdevice.h>
43#include <net/mac80211.h>
44#include "ar9170.h"
45#include "hw.h"
46#include "cmd.h"
47
48static int modparam_nohwcrypt;
49module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
50MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
Christian Lampartere9348cd2009-03-21 23:05:13 +010051
Christian Lamparteracbadf02009-07-11 17:24:14 +020052static int modparam_ht;
53module_param_named(ht, modparam_ht, bool, S_IRUGO);
54MODULE_PARM_DESC(ht, "enable MPDU aggregation.");
55
Christian Lampartere9348cd2009-03-21 23:05:13 +010056#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \
57 .bitrate = (_bitrate), \
58 .flags = (_flags), \
59 .hw_value = (_hw_rate) | (_txpidx) << 4, \
60}
61
62static struct ieee80211_rate __ar9170_ratetable[] = {
63 RATE(10, 0, 0, 0),
64 RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE),
65 RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE),
66 RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE),
67 RATE(60, 0xb, 0, 0),
68 RATE(90, 0xf, 0, 0),
69 RATE(120, 0xa, 0, 0),
70 RATE(180, 0xe, 0, 0),
71 RATE(240, 0x9, 0, 0),
72 RATE(360, 0xd, 1, 0),
73 RATE(480, 0x8, 2, 0),
74 RATE(540, 0xc, 3, 0),
75};
76#undef RATE
77
78#define ar9170_g_ratetable (__ar9170_ratetable + 0)
79#define ar9170_g_ratetable_size 12
80#define ar9170_a_ratetable (__ar9170_ratetable + 4)
81#define ar9170_a_ratetable_size 8
82
83/*
84 * NB: The hw_value is used as an index into the ar9170_phy_freq_params
85 * array in phy.c so that we don't have to do frequency lookups!
86 */
87#define CHAN(_freq, _idx) { \
88 .center_freq = (_freq), \
89 .hw_value = (_idx), \
90 .max_power = 18, /* XXX */ \
91}
92
93static struct ieee80211_channel ar9170_2ghz_chantable[] = {
94 CHAN(2412, 0),
95 CHAN(2417, 1),
96 CHAN(2422, 2),
97 CHAN(2427, 3),
98 CHAN(2432, 4),
99 CHAN(2437, 5),
100 CHAN(2442, 6),
101 CHAN(2447, 7),
102 CHAN(2452, 8),
103 CHAN(2457, 9),
104 CHAN(2462, 10),
105 CHAN(2467, 11),
106 CHAN(2472, 12),
107 CHAN(2484, 13),
108};
109
110static struct ieee80211_channel ar9170_5ghz_chantable[] = {
111 CHAN(4920, 14),
112 CHAN(4940, 15),
113 CHAN(4960, 16),
114 CHAN(4980, 17),
115 CHAN(5040, 18),
116 CHAN(5060, 19),
117 CHAN(5080, 20),
118 CHAN(5180, 21),
119 CHAN(5200, 22),
120 CHAN(5220, 23),
121 CHAN(5240, 24),
122 CHAN(5260, 25),
123 CHAN(5280, 26),
124 CHAN(5300, 27),
125 CHAN(5320, 28),
126 CHAN(5500, 29),
127 CHAN(5520, 30),
128 CHAN(5540, 31),
129 CHAN(5560, 32),
130 CHAN(5580, 33),
131 CHAN(5600, 34),
132 CHAN(5620, 35),
133 CHAN(5640, 36),
134 CHAN(5660, 37),
135 CHAN(5680, 38),
136 CHAN(5700, 39),
137 CHAN(5745, 40),
138 CHAN(5765, 41),
139 CHAN(5785, 42),
140 CHAN(5805, 43),
141 CHAN(5825, 44),
142 CHAN(5170, 45),
143 CHAN(5190, 46),
144 CHAN(5210, 47),
145 CHAN(5230, 48),
146};
147#undef CHAN
148
Johannes Berg9e52b06232009-04-20 18:27:04 +0200149#define AR9170_HT_CAP \
150{ \
151 .ht_supported = true, \
152 .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
Johannes Berg9e52b06232009-04-20 18:27:04 +0200153 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
154 IEEE80211_HT_CAP_SGI_40 | \
Christian Lamparteracbadf02009-07-11 17:24:14 +0200155 IEEE80211_HT_CAP_GRN_FLD | \
Johannes Berg9e52b06232009-04-20 18:27:04 +0200156 IEEE80211_HT_CAP_DSSSCCK40 | \
157 IEEE80211_HT_CAP_SM_PS, \
Christian Lamparter083c4682009-04-24 21:35:57 +0200158 .ampdu_factor = 3, \
159 .ampdu_density = 6, \
Johannes Berg9e52b06232009-04-20 18:27:04 +0200160 .mcs = { \
Christian Lamparteracbadf02009-07-11 17:24:14 +0200161 .rx_mask = { 0xff, 0xff, 0, 0, 0x1, 0, 0, 0, 0, 0, }, \
162 .rx_highest = cpu_to_le16(300), \
163 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
Johannes Berg9e52b06232009-04-20 18:27:04 +0200164 }, \
165}
166
Christian Lampartere9348cd2009-03-21 23:05:13 +0100167static struct ieee80211_supported_band ar9170_band_2GHz = {
168 .channels = ar9170_2ghz_chantable,
169 .n_channels = ARRAY_SIZE(ar9170_2ghz_chantable),
170 .bitrates = ar9170_g_ratetable,
171 .n_bitrates = ar9170_g_ratetable_size,
Johannes Berg9e52b06232009-04-20 18:27:04 +0200172 .ht_cap = AR9170_HT_CAP,
173};
174
175static struct ieee80211_supported_band ar9170_band_5GHz = {
176 .channels = ar9170_5ghz_chantable,
177 .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
178 .bitrates = ar9170_a_ratetable,
179 .n_bitrates = ar9170_a_ratetable_size,
180 .ht_cap = AR9170_HT_CAP,
Christian Lampartere9348cd2009-03-21 23:05:13 +0100181};
182
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200183static void ar9170_tx(struct ar9170 *ar);
Christian Lamparteracbadf02009-07-11 17:24:14 +0200184static bool ar9170_tx_ampdu(struct ar9170 *ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100185
Christian Lamparteracbadf02009-07-11 17:24:14 +0200186static inline u16 ar9170_get_seq_h(struct ieee80211_hdr *hdr)
187{
188 return le16_to_cpu(hdr->seq_ctrl) >> 4;
189}
190
191static inline u16 ar9170_get_seq(struct sk_buff *skb)
192{
193 struct ar9170_tx_control *txc = (void *) skb->data;
194 return ar9170_get_seq_h((void *) txc->frame_data);
195}
196
Christian Lamparter07bc5452009-11-29 00:59:48 +0100197static inline u16 ar9170_get_tid_h(struct ieee80211_hdr *hdr)
198{
199 return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
200}
201
Christian Lamparteracbadf02009-07-11 17:24:14 +0200202static inline u16 ar9170_get_tid(struct sk_buff *skb)
203{
204 struct ar9170_tx_control *txc = (void *) skb->data;
Christian Lamparter07bc5452009-11-29 00:59:48 +0100205 return ar9170_get_tid_h((struct ieee80211_hdr *) txc->frame_data);
Christian Lamparteracbadf02009-07-11 17:24:14 +0200206}
207
208#define GET_NEXT_SEQ(seq) ((seq + 1) & 0x0fff)
209#define GET_NEXT_SEQ_FROM_SKB(skb) (GET_NEXT_SEQ(ar9170_get_seq(skb)))
210
211#if (defined AR9170_QUEUE_DEBUG) || (defined AR9170_TXAGG_DEBUG)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100212static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
213{
214 struct ar9170_tx_control *txc = (void *) skb->data;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200215 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
216 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
217 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100218
Christian Lamparter15b098b2009-11-29 00:56:55 +0100219 printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] s:%d "
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200220 "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
Christian Lampartere9348cd2009-03-21 23:05:13 +0100221 wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
Christian Lamparter15b098b2009-11-29 00:56:55 +0100222 ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr),
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200223 le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
224 jiffies_to_msecs(arinfo->timeout - jiffies));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100225}
226
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200227static void __ar9170_dump_txqueue(struct ar9170 *ar,
228 struct sk_buff_head *queue)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100229{
230 struct sk_buff *skb;
231 int i = 0;
232
233 printk(KERN_DEBUG "---[ cut here ]---\n");
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200234 printk(KERN_DEBUG "%s: %d entries in queue.\n",
Christian Lampartere9348cd2009-03-21 23:05:13 +0100235 wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
236
237 skb_queue_walk(queue, skb) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200238 printk(KERN_DEBUG "index:%d => \n", i++);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100239 ar9170_print_txheader(ar, skb);
240 }
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200241 if (i != skb_queue_len(queue))
242 printk(KERN_DEBUG "WARNING: queue frame counter "
243 "mismatch %d != %d\n", skb_queue_len(queue), i);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100244 printk(KERN_DEBUG "---[ end ]---\n");
245}
Christian Lamparteracbadf02009-07-11 17:24:14 +0200246#endif /* AR9170_QUEUE_DEBUG || AR9170_TXAGG_DEBUG */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100247
Christian Lamparteracbadf02009-07-11 17:24:14 +0200248#ifdef AR9170_QUEUE_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200249static void ar9170_dump_txqueue(struct ar9170 *ar,
250 struct sk_buff_head *queue)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100251{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200252 unsigned long flags;
253
254 spin_lock_irqsave(&queue->lock, flags);
255 __ar9170_dump_txqueue(ar, queue);
256 spin_unlock_irqrestore(&queue->lock, flags);
257}
Christian Lamparteracbadf02009-07-11 17:24:14 +0200258#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200259
Christian Lamparteracbadf02009-07-11 17:24:14 +0200260#ifdef AR9170_QUEUE_STOP_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200261static void __ar9170_dump_txstats(struct ar9170 *ar)
262{
263 int i;
264
265 printk(KERN_DEBUG "%s: QoS queue stats\n",
266 wiphy_name(ar->hw->wiphy));
267
268 for (i = 0; i < __AR9170_NUM_TXQ; i++)
Christian Lamparteracbadf02009-07-11 17:24:14 +0200269 printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d "
270 " stopped:%d\n", wiphy_name(ar->hw->wiphy), i,
271 ar->tx_stats[i].limit, ar->tx_stats[i].len,
272 skb_queue_len(&ar->tx_status[i]),
273 ieee80211_queue_stopped(ar->hw, i));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200274}
Christian Lamparteracbadf02009-07-11 17:24:14 +0200275#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200276
Christian Lamparteracbadf02009-07-11 17:24:14 +0200277#ifdef AR9170_TXAGG_DEBUG
278static void ar9170_dump_tx_status_ampdu(struct ar9170 *ar)
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200279{
Christian Lampartere9348cd2009-03-21 23:05:13 +0100280 unsigned long flags;
281
Christian Lamparteracbadf02009-07-11 17:24:14 +0200282 spin_lock_irqsave(&ar->tx_status_ampdu.lock, flags);
283 printk(KERN_DEBUG "%s: A-MPDU tx_status queue => \n",
284 wiphy_name(ar->hw->wiphy));
285 __ar9170_dump_txqueue(ar, &ar->tx_status_ampdu);
286 spin_unlock_irqrestore(&ar->tx_status_ampdu.lock, flags);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200287}
Christian Lamparteracbadf02009-07-11 17:24:14 +0200288
289#endif /* AR9170_TXAGG_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200290
291/* caller must guarantee exclusive access for _bin_ queue. */
292static void ar9170_recycle_expired(struct ar9170 *ar,
293 struct sk_buff_head *queue,
294 struct sk_buff_head *bin)
295{
296 struct sk_buff *skb, *old = NULL;
297 unsigned long flags;
298
299 spin_lock_irqsave(&queue->lock, flags);
300 while ((skb = skb_peek(queue))) {
301 struct ieee80211_tx_info *txinfo;
302 struct ar9170_tx_info *arinfo;
303
304 txinfo = IEEE80211_SKB_CB(skb);
305 arinfo = (void *) txinfo->rate_driver_data;
306
307 if (time_is_before_jiffies(arinfo->timeout)) {
308#ifdef AR9170_QUEUE_DEBUG
309 printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => "
310 "recycle \n", wiphy_name(ar->hw->wiphy),
311 jiffies, arinfo->timeout);
312 ar9170_print_txheader(ar, skb);
313#endif /* AR9170_QUEUE_DEBUG */
314 __skb_unlink(skb, queue);
315 __skb_queue_tail(bin, skb);
316 } else {
317 break;
318 }
319
320 if (unlikely(old == skb)) {
321 /* bail out - queue is shot. */
322
323 WARN_ON(1);
324 break;
325 }
326 old = skb;
327 }
328 spin_unlock_irqrestore(&queue->lock, flags);
329}
330
331static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
332 u16 tx_status)
333{
334 struct ieee80211_tx_info *txinfo;
335 unsigned int retries = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100336
337 txinfo = IEEE80211_SKB_CB(skb);
338 ieee80211_tx_info_clear_status(txinfo);
339
340 switch (tx_status) {
341 case AR9170_TX_STATUS_RETRY:
342 retries = 2;
343 case AR9170_TX_STATUS_COMPLETE:
344 txinfo->flags |= IEEE80211_TX_STAT_ACK;
345 break;
346
347 case AR9170_TX_STATUS_FAILED:
348 retries = ar->hw->conf.long_frame_max_tx_count;
349 break;
350
351 default:
352 printk(KERN_ERR "%s: invalid tx_status response (%x).\n",
353 wiphy_name(ar->hw->wiphy), tx_status);
354 break;
355 }
356
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200357 txinfo->status.rates[0].count = retries + 1;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100358 skb_pull(skb, sizeof(struct ar9170_tx_control));
359 ieee80211_tx_status_irqsafe(ar->hw, skb);
360}
Christian Lampartere9348cd2009-03-21 23:05:13 +0100361
Christian Lamparteracbadf02009-07-11 17:24:14 +0200362static void ar9170_tx_fake_ampdu_status(struct ar9170 *ar)
363{
364 struct sk_buff_head success;
365 struct sk_buff *skb;
366 unsigned int i;
367 unsigned long queue_bitmap = 0;
368
369 skb_queue_head_init(&success);
370
371 while (skb_queue_len(&ar->tx_status_ampdu) > AR9170_NUM_TX_STATUS)
372 __skb_queue_tail(&success, skb_dequeue(&ar->tx_status_ampdu));
373
374 ar9170_recycle_expired(ar, &ar->tx_status_ampdu, &success);
375
376#ifdef AR9170_TXAGG_DEBUG
377 printk(KERN_DEBUG "%s: collected %d A-MPDU frames.\n",
378 wiphy_name(ar->hw->wiphy), skb_queue_len(&success));
379 __ar9170_dump_txqueue(ar, &success);
380#endif /* AR9170_TXAGG_DEBUG */
381
382 while ((skb = __skb_dequeue(&success))) {
383 struct ieee80211_tx_info *txinfo;
384
385 queue_bitmap |= BIT(skb_get_queue_mapping(skb));
386
387 txinfo = IEEE80211_SKB_CB(skb);
388 ieee80211_tx_info_clear_status(txinfo);
389
390 txinfo->flags |= IEEE80211_TX_STAT_ACK;
391 txinfo->status.rates[0].count = 1;
392
393 skb_pull(skb, sizeof(struct ar9170_tx_control));
394 ieee80211_tx_status_irqsafe(ar->hw, skb);
395 }
396
Akinobu Mita984b3f52010-03-05 13:41:37 -0800397 for_each_set_bit(i, &queue_bitmap, BITS_PER_BYTE) {
Christian Lamparteracbadf02009-07-11 17:24:14 +0200398#ifdef AR9170_QUEUE_STOP_DEBUG
399 printk(KERN_DEBUG "%s: wake queue %d\n",
400 wiphy_name(ar->hw->wiphy), i);
401 __ar9170_dump_txstats(ar);
402#endif /* AR9170_QUEUE_STOP_DEBUG */
403 ieee80211_wake_queue(ar->hw, i);
404 }
405
406 if (queue_bitmap)
407 ar9170_tx(ar);
408}
409
410static void ar9170_tx_ampdu_callback(struct ar9170 *ar, struct sk_buff *skb)
411{
412 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
413 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
414
415 arinfo->timeout = jiffies +
416 msecs_to_jiffies(AR9170_BA_TIMEOUT);
417
418 skb_queue_tail(&ar->tx_status_ampdu, skb);
419 ar9170_tx_fake_ampdu_status(ar);
Christian Lamparteracbadf02009-07-11 17:24:14 +0200420
Christian Lamparter02bdf5b2009-10-17 21:56:43 +0200421 if (atomic_dec_and_test(&ar->tx_ampdu_pending) &&
422 !list_empty(&ar->tx_ampdu_list))
Christian Lamparteracbadf02009-07-11 17:24:14 +0200423 ar9170_tx_ampdu(ar);
424}
425
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200426void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100427{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200428 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
429 struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data;
430 unsigned int queue = skb_get_queue_mapping(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100431 unsigned long flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100432
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200433 spin_lock_irqsave(&ar->tx_stats_lock, flags);
434 ar->tx_stats[queue].len--;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100435
Christian Lamparter53a76b52009-11-29 00:52:51 +0100436 if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200437#ifdef AR9170_QUEUE_STOP_DEBUG
438 printk(KERN_DEBUG "%s: wake queue %d\n",
439 wiphy_name(ar->hw->wiphy), queue);
440 __ar9170_dump_txstats(ar);
441#endif /* AR9170_QUEUE_STOP_DEBUG */
442 ieee80211_wake_queue(ar->hw, queue);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100443 }
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200444 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
445
Christian Lamparter15b098b2009-11-29 00:56:55 +0100446 if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200447 ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED);
448 } else {
Christian Lamparter15b098b2009-11-29 00:56:55 +0100449 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
450 ar9170_tx_ampdu_callback(ar, skb);
451 } else {
452 arinfo->timeout = jiffies +
453 msecs_to_jiffies(AR9170_TX_TIMEOUT);
454
455 skb_queue_tail(&ar->tx_status[queue], skb);
456 }
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200457 }
458
459 if (!ar->tx_stats[queue].len &&
460 !skb_queue_empty(&ar->tx_pending[queue])) {
461 ar9170_tx(ar);
462 }
Christian Lampartere9348cd2009-03-21 23:05:13 +0100463}
464
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200465static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
466 const u8 *mac,
467 struct sk_buff_head *queue,
468 const u32 rate)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100469{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200470 unsigned long flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100471 struct sk_buff *skb;
472
473 /*
474 * Unfortunately, the firmware does not tell to which (queued) frame
475 * this transmission status report belongs to.
476 *
477 * So we have to make risky guesses - with the scarce information
478 * the firmware provided (-> destination MAC, and phy_control) -
479 * and hope that we picked the right one...
480 */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100481
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200482 spin_lock_irqsave(&queue->lock, flags);
483 skb_queue_walk(queue, skb) {
484 struct ar9170_tx_control *txc = (void *) skb->data;
485 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
486 u32 r;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100487
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200488 if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) {
489#ifdef AR9170_QUEUE_DEBUG
490 printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n",
491 wiphy_name(ar->hw->wiphy), mac,
492 ieee80211_get_DA(hdr));
493 ar9170_print_txheader(ar, skb);
494#endif /* AR9170_QUEUE_DEBUG */
495 continue;
496 }
497
498 r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >>
499 AR9170_TX_PHY_MCS_SHIFT;
500
501 if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) {
502#ifdef AR9170_QUEUE_DEBUG
503 printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n",
504 wiphy_name(ar->hw->wiphy), rate, r);
505 ar9170_print_txheader(ar, skb);
506#endif /* AR9170_QUEUE_DEBUG */
507 continue;
508 }
509
510 __skb_unlink(skb, queue);
511 spin_unlock_irqrestore(&queue->lock, flags);
512 return skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100513 }
Christian Lampartere9348cd2009-03-21 23:05:13 +0100514
515#ifdef AR9170_QUEUE_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200516 printk(KERN_ERR "%s: ESS:[%pM] does not have any "
517 "outstanding frames in queue.\n",
518 wiphy_name(ar->hw->wiphy), mac);
519 __ar9170_dump_txqueue(ar, queue);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100520#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200521 spin_unlock_irqrestore(&queue->lock, flags);
522
523 return NULL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100524}
525
Christian Lamparteracbadf02009-07-11 17:24:14 +0200526static void ar9170_handle_block_ack(struct ar9170 *ar, u16 count, u16 r)
527{
528 struct sk_buff *skb;
529 struct ieee80211_tx_info *txinfo;
530
531 while (count) {
532 skb = ar9170_get_queued_skb(ar, NULL, &ar->tx_status_ampdu, r);
533 if (!skb)
534 break;
535
536 txinfo = IEEE80211_SKB_CB(skb);
537 ieee80211_tx_info_clear_status(txinfo);
538
539 /* FIXME: maybe more ? */
540 txinfo->status.rates[0].count = 1;
541
542 skb_pull(skb, sizeof(struct ar9170_tx_control));
543 ieee80211_tx_status_irqsafe(ar->hw, skb);
544 count--;
545 }
546
547#ifdef AR9170_TXAGG_DEBUG
548 if (count) {
549 printk(KERN_DEBUG "%s: got %d more failed mpdus, but no more "
550 "suitable frames left in tx_status queue.\n",
551 wiphy_name(ar->hw->wiphy), count);
552
553 ar9170_dump_tx_status_ampdu(ar);
554 }
555#endif /* AR9170_TXAGG_DEBUG */
556}
557
Christian Lampartere9348cd2009-03-21 23:05:13 +0100558/*
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200559 * This worker tries to keeps an maintain tx_status queues.
560 * So we can guarantee that incoming tx_status reports are
561 * actually for a pending frame.
Christian Lampartere9348cd2009-03-21 23:05:13 +0100562 */
563
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200564static void ar9170_tx_janitor(struct work_struct *work)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100565{
566 struct ar9170 *ar = container_of(work, struct ar9170,
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200567 tx_janitor.work);
568 struct sk_buff_head waste;
569 unsigned int i;
570 bool resched = false;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100571
Christian Lamparter4a48e2a2009-03-23 12:15:43 +0100572 if (unlikely(!IS_STARTED(ar)))
573 return ;
574
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200575 skb_queue_head_init(&waste);
576
577 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
Christian Lampartere9348cd2009-03-21 23:05:13 +0100578#ifdef AR9170_QUEUE_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200579 printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n",
580 wiphy_name(ar->hw->wiphy), i);
581 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
582 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100583#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200584
585 ar9170_recycle_expired(ar, &ar->tx_status[i], &waste);
586 ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste);
587 skb_queue_purge(&waste);
588
589 if (!skb_queue_empty(&ar->tx_status[i]) ||
590 !skb_queue_empty(&ar->tx_pending[i]))
591 resched = true;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100592 }
593
Christian Lamparteracbadf02009-07-11 17:24:14 +0200594 ar9170_tx_fake_ampdu_status(ar);
595
Luis R. Rodriguez42935ec2009-07-29 20:08:07 -0400596 if (!resched)
597 return;
598
599 ieee80211_queue_delayed_work(ar->hw,
600 &ar->tx_janitor,
601 msecs_to_jiffies(AR9170_JANITOR_DELAY));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100602}
603
Christian Lamparter66d00812009-05-28 17:04:27 +0200604void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100605{
606 struct ar9170_cmd_response *cmd = (void *) buf;
607
608 if ((cmd->type & 0xc0) != 0xc0) {
609 ar->callback_cmd(ar, len, buf);
610 return;
611 }
612
613 /* hardware event handlers */
614 switch (cmd->type) {
615 case 0xc1: {
616 /*
617 * TX status notification:
618 * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
619 *
620 * XX always 81
621 * YY always 00
622 * M1-M6 is the MAC address
623 * R1-R4 is the transmit rate
624 * S1-S2 is the transmit status
625 */
626
627 struct sk_buff *skb;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200628 u32 phy = le32_to_cpu(cmd->tx_status.rate);
629 u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >>
630 AR9170_TX_PHY_QOS_SHIFT;
631#ifdef AR9170_QUEUE_DEBUG
632 printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n",
633 wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q);
634#endif /* AR9170_QUEUE_DEBUG */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100635
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200636 skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst,
637 &ar->tx_status[q],
638 AR9170_TX_INVALID_RATE);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100639 if (unlikely(!skb))
640 return ;
641
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200642 ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100643 break;
644 }
645
646 case 0xc0:
647 /*
648 * pre-TBTT event
649 */
650 if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
Luis R. Rodriguez42935ec2009-07-29 20:08:07 -0400651 ieee80211_queue_work(ar->hw, &ar->beacon_work);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100652 break;
653
654 case 0xc2:
655 /*
656 * (IBSS) beacon send notification
657 * bytes: 04 c2 XX YY B4 B3 B2 B1
658 *
659 * XX always 80
660 * YY always 00
661 * B1-B4 "should" be the number of send out beacons.
662 */
663 break;
664
665 case 0xc3:
666 /* End of Atim Window */
667 break;
668
669 case 0xc4:
Christian Lamparteracbadf02009-07-11 17:24:14 +0200670 /* BlockACK bitmap */
671 break;
672
Christian Lampartere9348cd2009-03-21 23:05:13 +0100673 case 0xc5:
674 /* BlockACK events */
Christian Lamparteracbadf02009-07-11 17:24:14 +0200675 ar9170_handle_block_ack(ar,
676 le16_to_cpu(cmd->ba_fail_cnt.failed),
677 le16_to_cpu(cmd->ba_fail_cnt.rate));
678 ar9170_tx_fake_ampdu_status(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100679 break;
680
681 case 0xc6:
682 /* Watchdog Interrupt */
683 break;
684
685 case 0xc9:
686 /* retransmission issue / SIFS/EIFS collision ?! */
687 break;
688
Johannes Berg2543a0c2009-06-05 11:47:43 +0200689 /* firmware debug */
690 case 0xca:
691 printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, (char *)buf + 4);
692 break;
693 case 0xcb:
694 len -= 4;
695
696 switch (len) {
697 case 1:
698 printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n",
699 *((char *)buf + 4));
700 break;
701 case 2:
702 printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n",
703 le16_to_cpup((__le16 *)((char *)buf + 4)));
704 break;
705 case 4:
706 printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n",
707 le32_to_cpup((__le32 *)((char *)buf + 4)));
708 break;
709 case 8:
710 printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n",
711 (unsigned long)le64_to_cpup(
712 (__le64 *)((char *)buf + 4)));
713 break;
714 }
715 break;
716 case 0xcc:
717 print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE,
718 (char *)buf + 4, len - 4);
719 break;
720
Christian Lampartere9348cd2009-03-21 23:05:13 +0100721 default:
722 printk(KERN_INFO "received unhandled event %x\n", cmd->type);
723 print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
724 break;
725 }
726}
727
Christian Lampartercca847992009-04-19 01:28:12 +0200728static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100729{
Christian Lampartercca847992009-04-19 01:28:12 +0200730 memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head));
731 ar->rx_mpdu.has_plcp = false;
732}
Christian Lampartere9348cd2009-03-21 23:05:13 +0100733
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200734int ar9170_nag_limiter(struct ar9170 *ar)
Christian Lampartercca847992009-04-19 01:28:12 +0200735{
736 bool print_message;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100737
Christian Lampartercca847992009-04-19 01:28:12 +0200738 /*
739 * we expect all sorts of errors in promiscuous mode.
740 * don't bother with it, it's OK!
741 */
742 if (ar->sniffer_enabled)
743 return false;
744
745 /*
746 * only go for frequent errors! The hardware tends to
747 * do some stupid thing once in a while under load, in
748 * noisy environments or just for fun!
749 */
750 if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit())
751 print_message = true;
752 else
753 print_message = false;
754
755 /* reset threshold for "once in a while" */
756 ar->bad_hw_nagger = jiffies + HZ / 4;
757 return print_message;
758}
759
760static int ar9170_rx_mac_status(struct ar9170 *ar,
761 struct ar9170_rx_head *head,
762 struct ar9170_rx_macstatus *mac,
763 struct ieee80211_rx_status *status)
764{
765 u8 error, decrypt;
766
Christian Lampartere9348cd2009-03-21 23:05:13 +0100767 BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
Christian Lampartercca847992009-04-19 01:28:12 +0200768 BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100769
Christian Lampartercca847992009-04-19 01:28:12 +0200770 error = mac->error;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100771 if (error & AR9170_RX_ERROR_MMIC) {
Christian Lampartercca847992009-04-19 01:28:12 +0200772 status->flag |= RX_FLAG_MMIC_ERROR;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100773 error &= ~AR9170_RX_ERROR_MMIC;
774 }
775
776 if (error & AR9170_RX_ERROR_PLCP) {
Christian Lampartercca847992009-04-19 01:28:12 +0200777 status->flag |= RX_FLAG_FAILED_PLCP_CRC;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100778 error &= ~AR9170_RX_ERROR_PLCP;
Christian Lampartercca847992009-04-19 01:28:12 +0200779
780 if (!(ar->filter_state & FIF_PLCPFAIL))
781 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100782 }
783
784 if (error & AR9170_RX_ERROR_FCS) {
Christian Lampartercca847992009-04-19 01:28:12 +0200785 status->flag |= RX_FLAG_FAILED_FCS_CRC;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100786 error &= ~AR9170_RX_ERROR_FCS;
Christian Lampartercca847992009-04-19 01:28:12 +0200787
788 if (!(ar->filter_state & FIF_FCSFAIL))
789 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100790 }
791
Christian Lampartercca847992009-04-19 01:28:12 +0200792 decrypt = ar9170_get_decrypt_type(mac);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100793 if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
794 decrypt != AR9170_ENC_ALG_NONE)
Christian Lampartercca847992009-04-19 01:28:12 +0200795 status->flag |= RX_FLAG_DECRYPTED;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100796
797 /* ignore wrong RA errors */
798 error &= ~AR9170_RX_ERROR_WRONG_RA;
799
800 if (error & AR9170_RX_ERROR_DECRYPT) {
801 error &= ~AR9170_RX_ERROR_DECRYPT;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100802 /*
803 * Rx decryption is done in place,
804 * the original data is lost anyway.
805 */
Christian Lampartercca847992009-04-19 01:28:12 +0200806
807 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100808 }
809
810 /* drop any other error frames */
Christian Lampartercca847992009-04-19 01:28:12 +0200811 if (unlikely(error)) {
812 /* TODO: update netdevice's RX dropped/errors statistics */
813
814 if (ar9170_nag_limiter(ar))
815 printk(KERN_DEBUG "%s: received frame with "
816 "suspicious error code (%#x).\n",
817 wiphy_name(ar->hw->wiphy), error);
818
819 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100820 }
821
Christian Lampartercca847992009-04-19 01:28:12 +0200822 status->band = ar->channel->band;
823 status->freq = ar->channel->center_freq;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100824
Christian Lampartercca847992009-04-19 01:28:12 +0200825 switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) {
826 case AR9170_RX_STATUS_MODULATION_CCK:
827 if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
828 status->flag |= RX_FLAG_SHORTPRE;
829 switch (head->plcp[0]) {
830 case 0x0a:
831 status->rate_idx = 0;
832 break;
833 case 0x14:
834 status->rate_idx = 1;
835 break;
836 case 0x37:
837 status->rate_idx = 2;
838 break;
839 case 0x6e:
840 status->rate_idx = 3;
841 break;
842 default:
843 if (ar9170_nag_limiter(ar))
844 printk(KERN_ERR "%s: invalid plcp cck rate "
845 "(%x).\n", wiphy_name(ar->hw->wiphy),
846 head->plcp[0]);
847 return -EINVAL;
848 }
849 break;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100850
Christian Lamparter7d57b732009-11-14 00:57:58 +0100851 case AR9170_RX_STATUS_MODULATION_DUPOFDM:
Christian Lampartercca847992009-04-19 01:28:12 +0200852 case AR9170_RX_STATUS_MODULATION_OFDM:
853 switch (head->plcp[0] & 0xf) {
854 case 0xb:
855 status->rate_idx = 0;
856 break;
857 case 0xf:
858 status->rate_idx = 1;
859 break;
860 case 0xa:
861 status->rate_idx = 2;
862 break;
863 case 0xe:
864 status->rate_idx = 3;
865 break;
866 case 0x9:
867 status->rate_idx = 4;
868 break;
869 case 0xd:
870 status->rate_idx = 5;
871 break;
872 case 0x8:
873 status->rate_idx = 6;
874 break;
875 case 0xc:
876 status->rate_idx = 7;
877 break;
878 default:
879 if (ar9170_nag_limiter(ar))
880 printk(KERN_ERR "%s: invalid plcp ofdm rate "
881 "(%x).\n", wiphy_name(ar->hw->wiphy),
882 head->plcp[0]);
883 return -EINVAL;
884 }
885 if (status->band == IEEE80211_BAND_2GHZ)
886 status->rate_idx += 4;
887 break;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100888
Christian Lampartercca847992009-04-19 01:28:12 +0200889 case AR9170_RX_STATUS_MODULATION_HT:
890 if (head->plcp[3] & 0x80)
891 status->flag |= RX_FLAG_40MHZ;
892 if (head->plcp[6] & 0x80)
893 status->flag |= RX_FLAG_SHORT_GI;
894
895 status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f);
896 status->flag |= RX_FLAG_HT;
897 break;
898
Christian Lamparter7d57b732009-11-14 00:57:58 +0100899 default:
Christian Lampartercca847992009-04-19 01:28:12 +0200900 if (ar9170_nag_limiter(ar))
901 printk(KERN_ERR "%s: invalid modulation\n",
902 wiphy_name(ar->hw->wiphy));
903 return -EINVAL;
904 }
905
906 return 0;
907}
908
909static void ar9170_rx_phy_status(struct ar9170 *ar,
910 struct ar9170_rx_phystatus *phy,
911 struct ieee80211_rx_status *status)
912{
913 int i;
914
915 BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20);
916
917 for (i = 0; i < 3; i++)
918 if (phy->rssi[i] != 0x80)
919 status->antenna |= BIT(i);
920
921 /* post-process RSSI */
922 for (i = 0; i < 7; i++)
923 if (phy->rssi[i] & 0x80)
924 phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f;
925
926 /* TODO: we could do something with phy_errors */
927 status->signal = ar->noise[0] + phy->rssi_combined;
928 status->noise = ar->noise[0];
929}
930
931static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len)
932{
933 struct sk_buff *skb;
934 int reserved = 0;
935 struct ieee80211_hdr *hdr = (void *) buf;
936
937 if (ieee80211_is_data_qos(hdr->frame_control)) {
938 u8 *qc = ieee80211_get_qos_ctl(hdr);
939 reserved += NET_IP_ALIGN;
940
941 if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
942 reserved += NET_IP_ALIGN;
943 }
944
945 if (ieee80211_has_a4(hdr->frame_control))
946 reserved += NET_IP_ALIGN;
947
948 reserved = 32 + (reserved & NET_IP_ALIGN);
949
950 skb = dev_alloc_skb(len + reserved);
951 if (likely(skb)) {
952 skb_reserve(skb, reserved);
953 memcpy(skb_put(skb, len), buf, len);
954 }
955
956 return skb;
957}
958
959/*
960 * If the frame alignment is right (or the kernel has
961 * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
962 * is only a single MPDU in the USB frame, then we could
963 * submit to mac80211 the SKB directly. However, since
964 * there may be multiple packets in one SKB in stream
965 * mode, and we need to observe the proper ordering,
966 * this is non-trivial.
967 */
968
969static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
970{
971 struct ar9170_rx_head *head;
972 struct ar9170_rx_macstatus *mac;
973 struct ar9170_rx_phystatus *phy = NULL;
974 struct ieee80211_rx_status status;
975 struct sk_buff *skb;
976 int mpdu_len;
977
978 if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac))))
979 return ;
980
981 /* Received MPDU */
982 mpdu_len = len - sizeof(*mac);
983
984 mac = (void *)(buf + mpdu_len);
985 if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
986 /* this frame is too damaged and can't be used - drop it */
987
988 return ;
989 }
990
991 switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) {
992 case AR9170_RX_STATUS_MPDU_FIRST:
993 /* first mpdu packet has the plcp header */
994 if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
995 head = (void *) buf;
996 memcpy(&ar->rx_mpdu.plcp, (void *) buf,
997 sizeof(struct ar9170_rx_head));
998
999 mpdu_len -= sizeof(struct ar9170_rx_head);
1000 buf += sizeof(struct ar9170_rx_head);
1001 ar->rx_mpdu.has_plcp = true;
1002 } else {
1003 if (ar9170_nag_limiter(ar))
1004 printk(KERN_ERR "%s: plcp info is clipped.\n",
1005 wiphy_name(ar->hw->wiphy));
1006 return ;
1007 }
1008 break;
1009
1010 case AR9170_RX_STATUS_MPDU_LAST:
1011 /* last mpdu has a extra tail with phy status information */
1012
1013 if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
1014 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
1015 phy = (void *)(buf + mpdu_len);
1016 } else {
1017 if (ar9170_nag_limiter(ar))
1018 printk(KERN_ERR "%s: frame tail is clipped.\n",
1019 wiphy_name(ar->hw->wiphy));
1020 return ;
1021 }
1022
1023 case AR9170_RX_STATUS_MPDU_MIDDLE:
1024 /* middle mpdus are just data */
1025 if (unlikely(!ar->rx_mpdu.has_plcp)) {
1026 if (!ar9170_nag_limiter(ar))
1027 return ;
1028
1029 printk(KERN_ERR "%s: rx stream did not start "
1030 "with a first_mpdu frame tag.\n",
1031 wiphy_name(ar->hw->wiphy));
1032
1033 return ;
1034 }
1035
1036 head = &ar->rx_mpdu.plcp;
1037 break;
1038
1039 case AR9170_RX_STATUS_MPDU_SINGLE:
1040 /* single mpdu - has plcp (head) and phy status (tail) */
1041 head = (void *) buf;
1042
1043 mpdu_len -= sizeof(struct ar9170_rx_head);
1044 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
1045
1046 buf += sizeof(struct ar9170_rx_head);
1047 phy = (void *)(buf + mpdu_len);
1048 break;
1049
1050 default:
1051 BUG_ON(1);
1052 break;
1053 }
1054
1055 if (unlikely(mpdu_len < FCS_LEN))
1056 return ;
1057
1058 memset(&status, 0, sizeof(status));
1059 if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status)))
1060 return ;
1061
1062 if (phy)
1063 ar9170_rx_phy_status(ar, phy, &status);
1064
1065 skb = ar9170_rx_copy_data(buf, mpdu_len);
Johannes Bergf1d58c22009-06-17 13:13:00 +02001066 if (likely(skb)) {
1067 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
1068 ieee80211_rx_irqsafe(ar->hw, skb);
1069 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001070}
1071
Christian Lampartere9348cd2009-03-21 23:05:13 +01001072void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
1073{
Christian Lampartercca847992009-04-19 01:28:12 +02001074 unsigned int i, tlen, resplen, wlen = 0, clen = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001075 u8 *tbuf, *respbuf;
1076
1077 tbuf = skb->data;
1078 tlen = skb->len;
1079
1080 while (tlen >= 4) {
Christian Lampartercca847992009-04-19 01:28:12 +02001081 clen = tbuf[1] << 8 | tbuf[0];
1082 wlen = ALIGN(clen, 4);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001083
Christian Lampartercca847992009-04-19 01:28:12 +02001084 /* check if this is stream has a valid tag.*/
Christian Lampartere9348cd2009-03-21 23:05:13 +01001085 if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
Christian Lampartercca847992009-04-19 01:28:12 +02001086 /*
1087 * TODO: handle the highly unlikely event that the
1088 * corrupted stream has the TAG at the right position.
1089 */
1090
1091 /* check if the frame can be repaired. */
1092 if (!ar->rx_failover_missing) {
1093 /* this is no "short read". */
1094 if (ar9170_nag_limiter(ar)) {
1095 printk(KERN_ERR "%s: missing tag!\n",
1096 wiphy_name(ar->hw->wiphy));
1097 goto err_telluser;
1098 } else
1099 goto err_silent;
1100 }
1101
1102 if (ar->rx_failover_missing > tlen) {
1103 if (ar9170_nag_limiter(ar)) {
1104 printk(KERN_ERR "%s: possible multi "
1105 "stream corruption!\n",
1106 wiphy_name(ar->hw->wiphy));
1107 goto err_telluser;
1108 } else
1109 goto err_silent;
1110 }
1111
1112 memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
1113 ar->rx_failover_missing -= tlen;
1114
1115 if (ar->rx_failover_missing <= 0) {
1116 /*
1117 * nested ar9170_rx call!
1118 * termination is guranteed, even when the
1119 * combined frame also have a element with
1120 * a bad tag.
1121 */
1122
1123 ar->rx_failover_missing = 0;
1124 ar9170_rx(ar, ar->rx_failover);
1125
1126 skb_reset_tail_pointer(ar->rx_failover);
1127 skb_trim(ar->rx_failover, 0);
1128 }
1129
Christian Lampartere9348cd2009-03-21 23:05:13 +01001130 return ;
1131 }
Christian Lampartercca847992009-04-19 01:28:12 +02001132
1133 /* check if stream is clipped */
Christian Lampartere9348cd2009-03-21 23:05:13 +01001134 if (wlen > tlen - 4) {
Christian Lampartercca847992009-04-19 01:28:12 +02001135 if (ar->rx_failover_missing) {
1136 /* TODO: handle double stream corruption. */
1137 if (ar9170_nag_limiter(ar)) {
1138 printk(KERN_ERR "%s: double rx stream "
1139 "corruption!\n",
1140 wiphy_name(ar->hw->wiphy));
1141 goto err_telluser;
1142 } else
1143 goto err_silent;
1144 }
1145
1146 /*
1147 * save incomplete data set.
1148 * the firmware will resend the missing bits when
1149 * the rx - descriptor comes round again.
1150 */
1151
1152 memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
1153 ar->rx_failover_missing = clen - tlen;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001154 return ;
1155 }
1156 resplen = clen;
1157 respbuf = tbuf + 4;
1158 tbuf += wlen + 4;
1159 tlen -= wlen + 4;
1160
1161 i = 0;
1162
1163 /* weird thing, but this is the same in the original driver */
1164 while (resplen > 2 && i < 12 &&
1165 respbuf[0] == 0xff && respbuf[1] == 0xff) {
1166 i += 2;
1167 resplen -= 2;
1168 respbuf += 2;
1169 }
1170
1171 if (resplen < 4)
1172 continue;
1173
1174 /* found the 6 * 0xffff marker? */
1175 if (i == 12)
1176 ar9170_handle_command_response(ar, respbuf, resplen);
1177 else
Christian Lampartercca847992009-04-19 01:28:12 +02001178 ar9170_handle_mpdu(ar, respbuf, clen);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001179 }
1180
Christian Lampartercca847992009-04-19 01:28:12 +02001181 if (tlen) {
1182 if (net_ratelimit())
1183 printk(KERN_ERR "%s: %d bytes of unprocessed "
1184 "data left in rx stream!\n",
1185 wiphy_name(ar->hw->wiphy), tlen);
1186
1187 goto err_telluser;
1188 }
1189
1190 return ;
1191
1192err_telluser:
1193 printk(KERN_ERR "%s: damaged RX stream data [want:%d, "
1194 "data:%d, rx:%d, pending:%d ]\n",
1195 wiphy_name(ar->hw->wiphy), clen, wlen, tlen,
1196 ar->rx_failover_missing);
1197
1198 if (ar->rx_failover_missing)
1199 print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
1200 ar->rx_failover->data,
1201 ar->rx_failover->len);
1202
1203 print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
1204 skb->data, skb->len);
1205
1206 printk(KERN_ERR "%s: please check your hardware and cables, if "
1207 "you see this message frequently.\n",
1208 wiphy_name(ar->hw->wiphy));
1209
1210err_silent:
1211 if (ar->rx_failover_missing) {
1212 skb_reset_tail_pointer(ar->rx_failover);
1213 skb_trim(ar->rx_failover, 0);
1214 ar->rx_failover_missing = 0;
1215 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001216}
Christian Lampartere9348cd2009-03-21 23:05:13 +01001217
1218#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \
1219do { \
1220 queue.aifs = ai_fs; \
1221 queue.cw_min = cwmin; \
1222 queue.cw_max = cwmax; \
1223 queue.txop = _txop; \
1224} while (0)
1225
1226static int ar9170_op_start(struct ieee80211_hw *hw)
1227{
1228 struct ar9170 *ar = hw->priv;
1229 int err, i;
1230
1231 mutex_lock(&ar->mutex);
1232
1233 /* reinitialize queues statistics */
1234 memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001235 for (i = 0; i < __AR9170_NUM_TXQ; i++)
1236 ar->tx_stats[i].limit = AR9170_TXQ_DEPTH;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001237
1238 /* reset QoS defaults */
1239 AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/
1240 AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023, 0); /* BACKGROUND */
1241 AR9170_FILL_QUEUE(ar->edcf[2], 2, 7, 15, 94); /* VIDEO */
1242 AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */
1243 AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
1244
Christian Lamparteracbadf02009-07-11 17:24:14 +02001245 /* set sane AMPDU defaults */
1246 ar->global_ampdu_density = 6;
1247 ar->global_ampdu_factor = 3;
1248
Christian Lamparter02bdf5b2009-10-17 21:56:43 +02001249 atomic_set(&ar->tx_ampdu_pending, 0);
Christian Lampartercca847992009-04-19 01:28:12 +02001250 ar->bad_hw_nagger = jiffies;
1251
Christian Lampartere9348cd2009-03-21 23:05:13 +01001252 err = ar->open(ar);
1253 if (err)
1254 goto out;
1255
1256 err = ar9170_init_mac(ar);
1257 if (err)
1258 goto out;
1259
1260 err = ar9170_set_qos(ar);
1261 if (err)
1262 goto out;
1263
1264 err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
1265 if (err)
1266 goto out;
1267
1268 err = ar9170_init_rf(ar);
1269 if (err)
1270 goto out;
1271
1272 /* start DMA */
1273 err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
1274 if (err)
1275 goto out;
1276
1277 ar->state = AR9170_STARTED;
1278
1279out:
1280 mutex_unlock(&ar->mutex);
1281 return err;
1282}
1283
1284static void ar9170_op_stop(struct ieee80211_hw *hw)
1285{
1286 struct ar9170 *ar = hw->priv;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001287 unsigned int i;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001288
1289 if (IS_STARTED(ar))
1290 ar->state = AR9170_IDLE;
1291
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001292 cancel_delayed_work_sync(&ar->tx_janitor);
Alexander Beregalovff8365c2009-07-24 11:55:44 +04001293#ifdef CONFIG_AR9170_LEDS
Christian Lamparteracbadf02009-07-11 17:24:14 +02001294 cancel_delayed_work_sync(&ar->led_work);
Alexander Beregalovff8365c2009-07-24 11:55:44 +04001295#endif
Christian Lampartere9348cd2009-03-21 23:05:13 +01001296 cancel_work_sync(&ar->beacon_work);
Luis R. Rodrigueze351cfb2009-07-27 12:51:37 -07001297
Christian Lamparterb55d6bc2009-05-23 20:31:21 +02001298 mutex_lock(&ar->mutex);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001299
1300 if (IS_ACCEPTING_CMD(ar)) {
1301 ar9170_set_leds_state(ar, 0);
1302
1303 /* stop DMA */
1304 ar9170_write_reg(ar, 0x1c3d30, 0);
1305 ar->stop(ar);
1306 }
1307
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001308 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1309 skb_queue_purge(&ar->tx_pending[i]);
1310 skb_queue_purge(&ar->tx_status[i]);
1311 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02001312 skb_queue_purge(&ar->tx_status_ampdu);
1313
Christian Lampartere9348cd2009-03-21 23:05:13 +01001314 mutex_unlock(&ar->mutex);
1315}
1316
Christian Lamparteracbadf02009-07-11 17:24:14 +02001317static void ar9170_tx_indicate_immba(struct ar9170 *ar, struct sk_buff *skb)
1318{
1319 struct ar9170_tx_control *txc = (void *) skb->data;
1320
1321 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_IMM_AMPDU);
1322}
1323
1324static void ar9170_tx_copy_phy(struct ar9170 *ar, struct sk_buff *dst,
1325 struct sk_buff *src)
1326{
1327 struct ar9170_tx_control *dst_txc, *src_txc;
1328 struct ieee80211_tx_info *dst_info, *src_info;
1329 struct ar9170_tx_info *dst_arinfo, *src_arinfo;
1330
1331 src_txc = (void *) src->data;
1332 src_info = IEEE80211_SKB_CB(src);
1333 src_arinfo = (void *) src_info->rate_driver_data;
1334
1335 dst_txc = (void *) dst->data;
1336 dst_info = IEEE80211_SKB_CB(dst);
1337 dst_arinfo = (void *) dst_info->rate_driver_data;
1338
1339 dst_txc->phy_control = src_txc->phy_control;
1340
1341 /* same MCS for the whole aggregate */
1342 memcpy(dst_info->driver_rates, src_info->driver_rates,
1343 sizeof(dst_info->driver_rates));
1344}
1345
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001346static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001347{
Christian Lampartere9348cd2009-03-21 23:05:13 +01001348 struct ieee80211_hdr *hdr;
1349 struct ar9170_tx_control *txc;
1350 struct ieee80211_tx_info *info;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001351 struct ieee80211_tx_rate *txrate;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001352 struct ar9170_tx_info *arinfo;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001353 unsigned int queue = skb_get_queue_mapping(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001354 u16 keytype = 0;
1355 u16 len, icv = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001356
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001357 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001358
1359 hdr = (void *)skb->data;
1360 info = IEEE80211_SKB_CB(skb);
1361 len = skb->len;
1362
Christian Lampartere9348cd2009-03-21 23:05:13 +01001363 txc = (void *)skb_push(skb, sizeof(*txc));
1364
Christian Lampartere9348cd2009-03-21 23:05:13 +01001365 if (info->control.hw_key) {
1366 icv = info->control.hw_key->icv_len;
1367
1368 switch (info->control.hw_key->alg) {
1369 case ALG_WEP:
1370 keytype = AR9170_TX_MAC_ENCR_RC4;
1371 break;
1372 case ALG_TKIP:
1373 keytype = AR9170_TX_MAC_ENCR_RC4;
1374 break;
1375 case ALG_CCMP:
1376 keytype = AR9170_TX_MAC_ENCR_AES;
1377 break;
1378 default:
1379 WARN_ON(1);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001380 goto err_out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001381 }
1382 }
1383
1384 /* Length */
1385 txc->length = cpu_to_le16(len + icv + 4);
1386
1387 txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
1388 AR9170_TX_MAC_BACKOFF);
1389 txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
1390 AR9170_TX_MAC_QOS_SHIFT);
1391 txc->mac_control |= cpu_to_le16(keytype);
1392 txc->phy_control = cpu_to_le32(0);
1393
1394 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
1395 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
1396
Christian Lampartere9348cd2009-03-21 23:05:13 +01001397 txrate = &info->control.rates[0];
Christian Lampartere9348cd2009-03-21 23:05:13 +01001398 if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1399 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
1400 else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1401 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
1402
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001403 arinfo = (void *)info->rate_driver_data;
1404 arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT);
1405
1406 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
1407 (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001408 /*
1409 * WARNING:
1410 * Putting the QoS queue bits into an unexplored territory is
1411 * certainly not elegant.
1412 *
1413 * In my defense: This idea provides a reasonable way to
1414 * smuggle valuable information to the tx_status callback.
1415 * Also, the idea behind this bit-abuse came straight from
1416 * the original driver code.
1417 */
1418
1419 txc->phy_control |=
1420 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
Christian Lamparter15b098b2009-11-29 00:56:55 +01001421
1422 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1423 if (unlikely(!info->control.sta))
1424 goto err_out;
1425
1426 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
1427 } else {
1428 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
1429 }
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001430 }
1431
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001432 return 0;
1433
1434err_out:
1435 skb_pull(skb, sizeof(*txc));
1436 return -EINVAL;
1437}
1438
1439static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
1440{
1441 struct ar9170_tx_control *txc;
1442 struct ieee80211_tx_info *info;
1443 struct ieee80211_rate *rate = NULL;
1444 struct ieee80211_tx_rate *txrate;
1445 u32 power, chains;
1446
1447 txc = (void *) skb->data;
1448 info = IEEE80211_SKB_CB(skb);
1449 txrate = &info->control.rates[0];
1450
Christian Lampartere9348cd2009-03-21 23:05:13 +01001451 if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
1452 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
1453
1454 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1455 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
1456
1457 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1458 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
1459 /* this works because 40 MHz is 2 and dup is 3 */
1460 if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
1461 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
1462
1463 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
1464 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
1465
1466 if (txrate->flags & IEEE80211_TX_RC_MCS) {
1467 u32 r = txrate->idx;
1468 u8 *txpower;
1469
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001470 /* heavy clip control */
1471 txc->phy_control |= cpu_to_le32((r & 0x7) << 7);
1472
Christian Lampartere9348cd2009-03-21 23:05:13 +01001473 r <<= AR9170_TX_PHY_MCS_SHIFT;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001474 BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK);
1475
Christian Lampartere9348cd2009-03-21 23:05:13 +01001476 txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
1477 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
1478
1479 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1480 if (info->band == IEEE80211_BAND_5GHZ)
1481 txpower = ar->power_5G_ht40;
1482 else
1483 txpower = ar->power_2G_ht40;
1484 } else {
1485 if (info->band == IEEE80211_BAND_5GHZ)
1486 txpower = ar->power_5G_ht20;
1487 else
1488 txpower = ar->power_2G_ht20;
1489 }
1490
1491 power = txpower[(txrate->idx) & 7];
1492 } else {
1493 u8 *txpower;
1494 u32 mod;
1495 u32 phyrate;
1496 u8 idx = txrate->idx;
1497
1498 if (info->band != IEEE80211_BAND_2GHZ) {
1499 idx += 4;
1500 txpower = ar->power_5G_leg;
1501 mod = AR9170_TX_PHY_MOD_OFDM;
1502 } else {
1503 if (idx < 4) {
1504 txpower = ar->power_2G_cck;
1505 mod = AR9170_TX_PHY_MOD_CCK;
1506 } else {
1507 mod = AR9170_TX_PHY_MOD_OFDM;
1508 txpower = ar->power_2G_ofdm;
1509 }
1510 }
1511
1512 rate = &__ar9170_ratetable[idx];
1513
1514 phyrate = rate->hw_value & 0xF;
1515 power = txpower[(rate->hw_value & 0x30) >> 4];
1516 phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
1517
1518 txc->phy_control |= cpu_to_le32(mod);
1519 txc->phy_control |= cpu_to_le32(phyrate);
1520 }
1521
1522 power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
1523 power &= AR9170_TX_PHY_TX_PWR_MASK;
1524 txc->phy_control |= cpu_to_le32(power);
1525
1526 /* set TX chains */
1527 if (ar->eeprom.tx_mask == 1) {
1528 chains = AR9170_TX_PHY_TXCHAIN_1;
1529 } else {
1530 chains = AR9170_TX_PHY_TXCHAIN_2;
1531
1532 /* >= 36M legacy OFDM - use only one chain */
1533 if (rate && rate->bitrate >= 360)
1534 chains = AR9170_TX_PHY_TXCHAIN_1;
1535 }
1536 txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001537}
Christian Lampartere9348cd2009-03-21 23:05:13 +01001538
Christian Lamparteracbadf02009-07-11 17:24:14 +02001539static bool ar9170_tx_ampdu(struct ar9170 *ar)
1540{
1541 struct sk_buff_head agg;
1542 struct ar9170_sta_tid *tid_info = NULL, *tmp;
1543 struct sk_buff *skb, *first = NULL;
1544 unsigned long flags, f2;
1545 unsigned int i = 0;
1546 u16 seq, queue, tmpssn;
1547 bool run = false;
1548
1549 skb_queue_head_init(&agg);
1550
1551 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1552 if (list_empty(&ar->tx_ampdu_list)) {
1553#ifdef AR9170_TXAGG_DEBUG
1554 printk(KERN_DEBUG "%s: aggregation list is empty.\n",
1555 wiphy_name(ar->hw->wiphy));
1556#endif /* AR9170_TXAGG_DEBUG */
1557 goto out_unlock;
1558 }
1559
1560 list_for_each_entry_safe(tid_info, tmp, &ar->tx_ampdu_list, list) {
1561 if (tid_info->state != AR9170_TID_STATE_COMPLETE) {
1562#ifdef AR9170_TXAGG_DEBUG
1563 printk(KERN_DEBUG "%s: dangling aggregation entry!\n",
1564 wiphy_name(ar->hw->wiphy));
1565#endif /* AR9170_TXAGG_DEBUG */
1566 continue;
1567 }
1568
1569 if (++i > 64) {
1570#ifdef AR9170_TXAGG_DEBUG
1571 printk(KERN_DEBUG "%s: enough frames aggregated.\n",
1572 wiphy_name(ar->hw->wiphy));
1573#endif /* AR9170_TXAGG_DEBUG */
1574 break;
1575 }
1576
1577 queue = TID_TO_WME_AC(tid_info->tid);
1578
1579 if (skb_queue_len(&ar->tx_pending[queue]) >=
1580 AR9170_NUM_TX_AGG_MAX) {
1581#ifdef AR9170_TXAGG_DEBUG
1582 printk(KERN_DEBUG "%s: queue %d full.\n",
1583 wiphy_name(ar->hw->wiphy), queue);
1584#endif /* AR9170_TXAGG_DEBUG */
1585 continue;
1586 }
1587
1588 list_del_init(&tid_info->list);
1589
1590 spin_lock_irqsave(&tid_info->queue.lock, f2);
1591 tmpssn = seq = tid_info->ssn;
1592 first = skb_peek(&tid_info->queue);
1593
1594 if (likely(first))
1595 tmpssn = ar9170_get_seq(first);
1596
1597 if (unlikely(tmpssn != seq)) {
1598#ifdef AR9170_TXAGG_DEBUG
1599 printk(KERN_DEBUG "%s: ssn mismatch [%d != %d]\n.",
1600 wiphy_name(ar->hw->wiphy), seq, tmpssn);
1601#endif /* AR9170_TXAGG_DEBUG */
1602 tid_info->ssn = tmpssn;
1603 }
1604
1605#ifdef AR9170_TXAGG_DEBUG
1606 printk(KERN_DEBUG "%s: generate A-MPDU for tid:%d ssn:%d with "
1607 "%d queued frames.\n", wiphy_name(ar->hw->wiphy),
1608 tid_info->tid, tid_info->ssn,
1609 skb_queue_len(&tid_info->queue));
1610 __ar9170_dump_txqueue(ar, &tid_info->queue);
1611#endif /* AR9170_TXAGG_DEBUG */
1612
1613 while ((skb = skb_peek(&tid_info->queue))) {
1614 if (unlikely(ar9170_get_seq(skb) != seq))
1615 break;
1616
1617 __skb_unlink(skb, &tid_info->queue);
1618 tid_info->ssn = seq = GET_NEXT_SEQ(seq);
1619
1620 if (unlikely(skb_get_queue_mapping(skb) != queue)) {
1621#ifdef AR9170_TXAGG_DEBUG
1622 printk(KERN_DEBUG "%s: tid:%d(q:%d) queue:%d "
1623 "!match.\n", wiphy_name(ar->hw->wiphy),
1624 tid_info->tid,
1625 TID_TO_WME_AC(tid_info->tid),
1626 skb_get_queue_mapping(skb));
1627#endif /* AR9170_TXAGG_DEBUG */
1628 dev_kfree_skb_any(skb);
1629 continue;
1630 }
1631
1632 if (unlikely(first == skb)) {
1633 ar9170_tx_prepare_phy(ar, skb);
1634 __skb_queue_tail(&agg, skb);
1635 first = skb;
1636 } else {
1637 ar9170_tx_copy_phy(ar, skb, first);
1638 __skb_queue_tail(&agg, skb);
1639 }
1640
1641 if (unlikely(skb_queue_len(&agg) ==
1642 AR9170_NUM_TX_AGG_MAX))
1643 break;
1644 }
1645
1646 if (skb_queue_empty(&tid_info->queue))
1647 tid_info->active = false;
1648 else
1649 list_add_tail(&tid_info->list,
1650 &ar->tx_ampdu_list);
1651
1652 spin_unlock_irqrestore(&tid_info->queue.lock, f2);
1653
1654 if (unlikely(skb_queue_empty(&agg))) {
1655#ifdef AR9170_TXAGG_DEBUG
1656 printk(KERN_DEBUG "%s: queued empty list!\n",
1657 wiphy_name(ar->hw->wiphy));
1658#endif /* AR9170_TXAGG_DEBUG */
1659 continue;
1660 }
1661
1662 /*
1663 * tell the FW/HW that this is the last frame,
1664 * that way it will wait for the immediate block ack.
1665 */
Christian Lamparter07bc5452009-11-29 00:59:48 +01001666 ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg));
Christian Lamparteracbadf02009-07-11 17:24:14 +02001667
1668#ifdef AR9170_TXAGG_DEBUG
1669 printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n",
1670 wiphy_name(ar->hw->wiphy));
1671 __ar9170_dump_txqueue(ar, &agg);
1672#endif /* AR9170_TXAGG_DEBUG */
1673
1674 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1675
1676 spin_lock_irqsave(&ar->tx_pending[queue].lock, flags);
1677 skb_queue_splice_tail_init(&agg, &ar->tx_pending[queue]);
1678 spin_unlock_irqrestore(&ar->tx_pending[queue].lock, flags);
1679 run = true;
1680
1681 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1682 }
1683
1684out_unlock:
1685 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1686 __skb_queue_purge(&agg);
1687
1688 return run;
1689}
1690
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001691static void ar9170_tx(struct ar9170 *ar)
1692{
1693 struct sk_buff *skb;
1694 unsigned long flags;
1695 struct ieee80211_tx_info *info;
1696 struct ar9170_tx_info *arinfo;
1697 unsigned int i, frames, frames_failed, remaining_space;
1698 int err;
1699 bool schedule_garbagecollector = false;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001700
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001701 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001702
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001703 if (unlikely(!IS_STARTED(ar)))
1704 return ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001705
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001706 remaining_space = AR9170_TX_MAX_PENDING;
1707
1708 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1709 spin_lock_irqsave(&ar->tx_stats_lock, flags);
Christian Lamparter53a76b52009-11-29 00:52:51 +01001710 frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
1711 skb_queue_len(&ar->tx_pending[i]));
1712
1713 if (remaining_space < frames) {
1714#ifdef AR9170_QUEUE_DEBUG
1715 printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
1716 "remaining slots:%d, needed:%d\n",
1717 wiphy_name(ar->hw->wiphy), i, remaining_space,
1718 frames);
1719#endif /* AR9170_QUEUE_DEBUG */
1720 frames = remaining_space;
1721 }
1722
1723 ar->tx_stats[i].len += frames;
1724 ar->tx_stats[i].count += frames;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001725 if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
1726#ifdef AR9170_QUEUE_DEBUG
1727 printk(KERN_DEBUG "%s: queue %d full\n",
1728 wiphy_name(ar->hw->wiphy), i);
1729
Christian Lamparteracbadf02009-07-11 17:24:14 +02001730 printk(KERN_DEBUG "%s: stuck frames: ===> \n",
1731 wiphy_name(ar->hw->wiphy));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001732 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1733 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
1734#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparteracbadf02009-07-11 17:24:14 +02001735
1736#ifdef AR9170_QUEUE_STOP_DEBUG
1737 printk(KERN_DEBUG "%s: stop queue %d\n",
1738 wiphy_name(ar->hw->wiphy), i);
1739 __ar9170_dump_txstats(ar);
1740#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001741 ieee80211_stop_queue(ar->hw, i);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001742 }
1743
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001744 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1745
1746 if (!frames)
1747 continue;
1748
1749 frames_failed = 0;
1750 while (frames) {
1751 skb = skb_dequeue(&ar->tx_pending[i]);
1752 if (unlikely(!skb)) {
1753 frames_failed += frames;
1754 frames = 0;
1755 break;
1756 }
1757
1758 info = IEEE80211_SKB_CB(skb);
1759 arinfo = (void *) info->rate_driver_data;
1760
1761 /* TODO: cancel stuck frames */
1762 arinfo->timeout = jiffies +
1763 msecs_to_jiffies(AR9170_TX_TIMEOUT);
1764
Christian Lamparter15b098b2009-11-29 00:56:55 +01001765 if (info->flags & IEEE80211_TX_CTL_AMPDU)
Christian Lamparter02bdf5b2009-10-17 21:56:43 +02001766 atomic_inc(&ar->tx_ampdu_pending);
Christian Lamparteracbadf02009-07-11 17:24:14 +02001767
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001768#ifdef AR9170_QUEUE_DEBUG
1769 printk(KERN_DEBUG "%s: send frame q:%d =>\n",
1770 wiphy_name(ar->hw->wiphy), i);
1771 ar9170_print_txheader(ar, skb);
1772#endif /* AR9170_QUEUE_DEBUG */
1773
1774 err = ar->tx(ar, skb);
1775 if (unlikely(err)) {
Christian Lamparter15b098b2009-11-29 00:56:55 +01001776 if (info->flags & IEEE80211_TX_CTL_AMPDU)
Christian Lamparter02bdf5b2009-10-17 21:56:43 +02001777 atomic_dec(&ar->tx_ampdu_pending);
Christian Lamparteracbadf02009-07-11 17:24:14 +02001778
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001779 frames_failed++;
1780 dev_kfree_skb_any(skb);
1781 } else {
1782 remaining_space--;
1783 schedule_garbagecollector = true;
1784 }
1785
1786 frames--;
1787 }
1788
1789#ifdef AR9170_QUEUE_DEBUG
1790 printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n",
1791 wiphy_name(ar->hw->wiphy), i);
1792
1793 printk(KERN_DEBUG "%s: unprocessed pending frames left:\n",
1794 wiphy_name(ar->hw->wiphy));
1795 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1796#endif /* AR9170_QUEUE_DEBUG */
1797
1798 if (unlikely(frames_failed)) {
1799#ifdef AR9170_QUEUE_DEBUG
Christian Lamparteracbadf02009-07-11 17:24:14 +02001800 printk(KERN_DEBUG "%s: frames failed %d =>\n",
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001801 wiphy_name(ar->hw->wiphy), frames_failed);
1802#endif /* AR9170_QUEUE_DEBUG */
1803
1804 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1805 ar->tx_stats[i].len -= frames_failed;
1806 ar->tx_stats[i].count -= frames_failed;
Christian Lamparteracbadf02009-07-11 17:24:14 +02001807#ifdef AR9170_QUEUE_STOP_DEBUG
1808 printk(KERN_DEBUG "%s: wake queue %d\n",
1809 wiphy_name(ar->hw->wiphy), i);
1810 __ar9170_dump_txstats(ar);
1811#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001812 ieee80211_wake_queue(ar->hw, i);
1813 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001814 }
1815 }
1816
Luis R. Rodriguez42935ec2009-07-29 20:08:07 -04001817 if (!schedule_garbagecollector)
1818 return;
1819
1820 ieee80211_queue_delayed_work(ar->hw,
1821 &ar->tx_janitor,
1822 msecs_to_jiffies(AR9170_JANITOR_DELAY));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001823}
1824
Christian Lamparteracbadf02009-07-11 17:24:14 +02001825static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb)
1826{
1827 struct ieee80211_tx_info *txinfo;
1828 struct ar9170_sta_info *sta_info;
1829 struct ar9170_sta_tid *agg;
1830 struct sk_buff *iter;
1831 unsigned long flags, f2;
1832 unsigned int max;
1833 u16 tid, seq, qseq;
1834 bool run = false, queue = false;
1835
1836 tid = ar9170_get_tid(skb);
1837 seq = ar9170_get_seq(skb);
1838 txinfo = IEEE80211_SKB_CB(skb);
1839 sta_info = (void *) txinfo->control.sta->drv_priv;
1840 agg = &sta_info->agg[tid];
1841 max = sta_info->ampdu_max_len;
1842
1843 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1844
1845 if (unlikely(agg->state != AR9170_TID_STATE_COMPLETE)) {
1846#ifdef AR9170_TXAGG_DEBUG
1847 printk(KERN_DEBUG "%s: BlockACK session not fully initialized "
1848 "for ESS:%pM tid:%d state:%d.\n",
1849 wiphy_name(ar->hw->wiphy), agg->addr, agg->tid,
1850 agg->state);
1851#endif /* AR9170_TXAGG_DEBUG */
1852 goto err_unlock;
1853 }
1854
1855 if (!agg->active) {
1856 agg->active = true;
1857 agg->ssn = seq;
1858 queue = true;
1859 }
1860
1861 /* check if seq is within the BA window */
1862 if (unlikely(!BAW_WITHIN(agg->ssn, max, seq))) {
1863#ifdef AR9170_TXAGG_DEBUG
1864 printk(KERN_DEBUG "%s: frame with tid:%d seq:%d does not "
1865 "fit into BA window (%d - %d)\n",
1866 wiphy_name(ar->hw->wiphy), tid, seq, agg->ssn,
1867 (agg->ssn + max) & 0xfff);
1868#endif /* AR9170_TXAGG_DEBUG */
1869 goto err_unlock;
1870 }
1871
1872 spin_lock_irqsave(&agg->queue.lock, f2);
1873
1874 skb_queue_reverse_walk(&agg->queue, iter) {
1875 qseq = ar9170_get_seq(iter);
1876
1877 if (GET_NEXT_SEQ(qseq) == seq) {
1878 __skb_queue_after(&agg->queue, iter, skb);
1879 goto queued;
1880 }
1881 }
1882
1883 __skb_queue_head(&agg->queue, skb);
1884
1885queued:
1886 spin_unlock_irqrestore(&agg->queue.lock, f2);
1887
1888#ifdef AR9170_TXAGG_DEBUG
1889 printk(KERN_DEBUG "%s: new aggregate %p queued.\n",
1890 wiphy_name(ar->hw->wiphy), skb);
1891 __ar9170_dump_txqueue(ar, &agg->queue);
1892#endif /* AR9170_TXAGG_DEBUG */
1893
1894 if (skb_queue_len(&agg->queue) >= AR9170_NUM_TX_AGG_MAX)
1895 run = true;
1896
1897 if (queue)
1898 list_add_tail(&agg->list, &ar->tx_ampdu_list);
1899
1900 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1901 return run;
1902
1903err_unlock:
1904 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1905 dev_kfree_skb_irq(skb);
1906 return false;
1907}
1908
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001909int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1910{
1911 struct ar9170 *ar = hw->priv;
1912 struct ieee80211_tx_info *info;
1913
1914 if (unlikely(!IS_STARTED(ar)))
1915 goto err_free;
1916
1917 if (unlikely(ar9170_tx_prepare(ar, skb)))
1918 goto err_free;
1919
1920 info = IEEE80211_SKB_CB(skb);
1921 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
Christian Lamparteracbadf02009-07-11 17:24:14 +02001922 bool run = ar9170_tx_ampdu_queue(ar, skb);
1923
Christian Lamparter02bdf5b2009-10-17 21:56:43 +02001924 if (run || !atomic_read(&ar->tx_ampdu_pending))
Christian Lamparteracbadf02009-07-11 17:24:14 +02001925 ar9170_tx_ampdu(ar);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001926 } else {
1927 unsigned int queue = skb_get_queue_mapping(skb);
1928
1929 ar9170_tx_prepare_phy(ar, skb);
1930 skb_queue_tail(&ar->tx_pending[queue], skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001931 }
1932
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001933 ar9170_tx(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001934 return NETDEV_TX_OK;
1935
Christian Lampartere9348cd2009-03-21 23:05:13 +01001936err_free:
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001937 dev_kfree_skb_any(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001938 return NETDEV_TX_OK;
1939}
1940
1941static int ar9170_op_add_interface(struct ieee80211_hw *hw,
Johannes Berg1ed32e42009-12-23 13:15:45 +01001942 struct ieee80211_vif *vif)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001943{
1944 struct ar9170 *ar = hw->priv;
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07001945 struct ath_common *common = &ar->common;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001946 int err = 0;
1947
1948 mutex_lock(&ar->mutex);
1949
1950 if (ar->vif) {
1951 err = -EBUSY;
1952 goto unlock;
1953 }
1954
Johannes Berg1ed32e42009-12-23 13:15:45 +01001955 ar->vif = vif;
1956 memcpy(common->macaddr, vif->addr, ETH_ALEN);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001957
1958 if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
1959 ar->rx_software_decryption = true;
1960 ar->disable_offload = true;
1961 }
1962
1963 ar->cur_filter = 0;
Christian Lampartereeef4182009-08-19 12:43:47 +02001964 err = ar9170_update_frame_filter(ar, AR9170_MAC_REG_FTF_DEFAULTS);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001965 if (err)
1966 goto unlock;
1967
1968 err = ar9170_set_operating_mode(ar);
1969
1970unlock:
1971 mutex_unlock(&ar->mutex);
1972 return err;
1973}
1974
1975static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
Johannes Berg1ed32e42009-12-23 13:15:45 +01001976 struct ieee80211_vif *vif)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001977{
1978 struct ar9170 *ar = hw->priv;
1979
1980 mutex_lock(&ar->mutex);
1981 ar->vif = NULL;
Christian Lampartereeef4182009-08-19 12:43:47 +02001982 ar9170_update_frame_filter(ar, 0);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001983 ar9170_set_beacon_timers(ar);
1984 dev_kfree_skb(ar->beacon);
1985 ar->beacon = NULL;
1986 ar->sniffer_enabled = false;
1987 ar->rx_software_decryption = false;
1988 ar9170_set_operating_mode(ar);
1989 mutex_unlock(&ar->mutex);
1990}
1991
1992static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
1993{
1994 struct ar9170 *ar = hw->priv;
1995 int err = 0;
1996
1997 mutex_lock(&ar->mutex);
1998
Christian Lampartere9348cd2009-03-21 23:05:13 +01001999 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
2000 /* TODO */
2001 err = 0;
2002 }
2003
2004 if (changed & IEEE80211_CONF_CHANGE_PS) {
2005 /* TODO */
2006 err = 0;
2007 }
2008
2009 if (changed & IEEE80211_CONF_CHANGE_POWER) {
2010 /* TODO */
2011 err = 0;
2012 }
2013
2014 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
2015 /*
2016 * is it long_frame_max_tx_count or short_frame_max_tx_count?
2017 */
2018
2019 err = ar9170_set_hwretry_limit(ar,
2020 ar->hw->conf.long_frame_max_tx_count);
2021 if (err)
2022 goto out;
2023 }
2024
Christian Lampartere9348cd2009-03-21 23:05:13 +01002025 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002026
2027 /* adjust slot time for 5 GHz */
2028 err = ar9170_set_slot_time(ar);
2029 if (err)
2030 goto out;
2031
2032 err = ar9170_set_dyn_sifs_ack(ar);
2033 if (err)
2034 goto out;
2035
Christian Lampartere9348cd2009-03-21 23:05:13 +01002036 err = ar9170_set_channel(ar, hw->conf.channel,
Johannes Berg9e52b06232009-04-20 18:27:04 +02002037 AR9170_RFI_NONE,
2038 nl80211_to_ar9170(hw->conf.channel_type));
Christian Lampartere9348cd2009-03-21 23:05:13 +01002039 if (err)
2040 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002041 }
2042
2043out:
2044 mutex_unlock(&ar->mutex);
2045 return err;
2046}
2047
Jiri Pirko22bedad32010-04-01 21:22:57 +00002048static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw,
2049 struct netdev_hw_addr_list *mc_list)
Johannes Berg3ac64be2009-08-17 16:16:53 +02002050{
2051 u64 mchash;
Jiri Pirko22bedad32010-04-01 21:22:57 +00002052 struct netdev_hw_addr *ha;
Johannes Berg3ac64be2009-08-17 16:16:53 +02002053
2054 /* always get broadcast frames */
2055 mchash = 1ULL << (0xff >> 2);
2056
Jiri Pirko22bedad32010-04-01 21:22:57 +00002057 netdev_hw_addr_list_for_each(ha, mc_list)
2058 mchash |= 1ULL << (ha->addr[5] >> 2);
Johannes Berg3ac64be2009-08-17 16:16:53 +02002059
2060 return mchash;
2061}
2062
Christian Lampartere9348cd2009-03-21 23:05:13 +01002063static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
2064 unsigned int changed_flags,
2065 unsigned int *new_flags,
Johannes Berg3ac64be2009-08-17 16:16:53 +02002066 u64 multicast)
Christian Lampartere9348cd2009-03-21 23:05:13 +01002067{
2068 struct ar9170 *ar = hw->priv;
2069
Christian Lampartereeef4182009-08-19 12:43:47 +02002070 if (unlikely(!IS_ACCEPTING_CMD(ar)))
2071 return ;
2072
2073 mutex_lock(&ar->mutex);
2074
Christian Lampartere9348cd2009-03-21 23:05:13 +01002075 /* mask supported flags */
2076 *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
Christian Lampartercca847992009-04-19 01:28:12 +02002077 FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
2078 ar->filter_state = *new_flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002079 /*
2080 * We can support more by setting the sniffer bit and
2081 * then checking the error flags, later.
2082 */
2083
Johannes Berg3ac64be2009-08-17 16:16:53 +02002084 if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
Christian Lampartereeef4182009-08-19 12:43:47 +02002085 multicast = ~0ULL;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002086
Christian Lampartereeef4182009-08-19 12:43:47 +02002087 if (multicast != ar->cur_mc_hash)
2088 ar9170_update_multicast(ar, multicast);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002089
2090 if (changed_flags & FIF_CONTROL) {
2091 u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
2092 AR9170_MAC_REG_FTF_RTS |
2093 AR9170_MAC_REG_FTF_CTS |
2094 AR9170_MAC_REG_FTF_ACK |
2095 AR9170_MAC_REG_FTF_CFE |
2096 AR9170_MAC_REG_FTF_CFE_ACK;
2097
2098 if (*new_flags & FIF_CONTROL)
Christian Lampartereeef4182009-08-19 12:43:47 +02002099 filter |= ar->cur_filter;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002100 else
Christian Lampartereeef4182009-08-19 12:43:47 +02002101 filter &= (~ar->cur_filter);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002102
Christian Lampartereeef4182009-08-19 12:43:47 +02002103 ar9170_update_frame_filter(ar, filter);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002104 }
2105
2106 if (changed_flags & FIF_PROMISC_IN_BSS) {
2107 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
Christian Lampartereeef4182009-08-19 12:43:47 +02002108 ar9170_set_operating_mode(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002109 }
2110
Christian Lampartereeef4182009-08-19 12:43:47 +02002111 mutex_unlock(&ar->mutex);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002112}
2113
Christian Lampartereeef4182009-08-19 12:43:47 +02002114
Christian Lampartere9348cd2009-03-21 23:05:13 +01002115static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
2116 struct ieee80211_vif *vif,
2117 struct ieee80211_bss_conf *bss_conf,
2118 u32 changed)
2119{
2120 struct ar9170 *ar = hw->priv;
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07002121 struct ath_common *common = &ar->common;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002122 int err = 0;
2123
2124 mutex_lock(&ar->mutex);
2125
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002126 if (changed & BSS_CHANGED_BSSID) {
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07002127 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002128 err = ar9170_set_operating_mode(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02002129 if (err)
2130 goto out;
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002131 }
2132
Joerg Albertea39d1a2009-08-21 23:25:07 +02002133 if (changed & BSS_CHANGED_BEACON_ENABLED)
2134 ar->enable_beacon = bss_conf->enable_beacon;
2135
2136 if (changed & BSS_CHANGED_BEACON) {
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002137 err = ar9170_update_beacon(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02002138 if (err)
2139 goto out;
Joerg Albertea39d1a2009-08-21 23:25:07 +02002140 }
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002141
Joerg Albertea39d1a2009-08-21 23:25:07 +02002142 if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON |
2143 BSS_CHANGED_BEACON_INT)) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002144 err = ar9170_set_beacon_timers(ar);
2145 if (err)
2146 goto out;
2147 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01002148
2149 if (changed & BSS_CHANGED_ASSOC) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002150#ifndef CONFIG_AR9170_LEDS
2151 /* enable assoc LED. */
2152 err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
2153#endif /* CONFIG_AR9170_LEDS */
2154 }
2155
2156 if (changed & BSS_CHANGED_HT) {
2157 /* TODO */
2158 err = 0;
2159 }
2160
2161 if (changed & BSS_CHANGED_ERP_SLOT) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002162 err = ar9170_set_slot_time(ar);
2163 if (err)
2164 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002165 }
2166
2167 if (changed & BSS_CHANGED_BASIC_RATES) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002168 err = ar9170_set_basic_rates(ar);
2169 if (err)
2170 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002171 }
2172
Christian Lamparter29ceff52009-06-01 21:42:01 +02002173out:
Christian Lampartere9348cd2009-03-21 23:05:13 +01002174 mutex_unlock(&ar->mutex);
2175}
2176
2177static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
2178{
2179 struct ar9170 *ar = hw->priv;
2180 int err;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002181 u64 tsf;
Joerg Albert181af382009-09-15 23:27:53 +02002182#define NR 3
2183 static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H,
2184 AR9170_MAC_REG_TSF_L,
2185 AR9170_MAC_REG_TSF_H };
2186 u32 val[NR];
2187 int loops = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002188
2189 mutex_lock(&ar->mutex);
Joerg Albert181af382009-09-15 23:27:53 +02002190
2191 while (loops++ < 10) {
2192 err = ar9170_read_mreg(ar, NR, addr, val);
2193 if (err || val[0] == val[2])
2194 break;
2195 }
2196
Christian Lampartere9348cd2009-03-21 23:05:13 +01002197 mutex_unlock(&ar->mutex);
2198
2199 if (WARN_ON(err))
2200 return 0;
Joerg Albert181af382009-09-15 23:27:53 +02002201 tsf = val[0];
2202 tsf = (tsf << 32) | val[1];
Christian Lampartere9348cd2009-03-21 23:05:13 +01002203 return tsf;
Joerg Albert181af382009-09-15 23:27:53 +02002204#undef NR
Christian Lampartere9348cd2009-03-21 23:05:13 +01002205}
2206
2207static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2208 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
2209 struct ieee80211_key_conf *key)
2210{
2211 struct ar9170 *ar = hw->priv;
2212 int err = 0, i;
2213 u8 ktype;
2214
2215 if ((!ar->vif) || (ar->disable_offload))
2216 return -EOPNOTSUPP;
2217
2218 switch (key->alg) {
2219 case ALG_WEP:
Zhu Yie31a16d2009-05-21 21:47:03 +08002220 if (key->keylen == WLAN_KEY_LEN_WEP40)
Christian Lampartere9348cd2009-03-21 23:05:13 +01002221 ktype = AR9170_ENC_ALG_WEP64;
2222 else
2223 ktype = AR9170_ENC_ALG_WEP128;
2224 break;
2225 case ALG_TKIP:
2226 ktype = AR9170_ENC_ALG_TKIP;
2227 break;
2228 case ALG_CCMP:
2229 ktype = AR9170_ENC_ALG_AESCCMP;
2230 break;
2231 default:
2232 return -EOPNOTSUPP;
2233 }
2234
2235 mutex_lock(&ar->mutex);
2236 if (cmd == SET_KEY) {
2237 if (unlikely(!IS_STARTED(ar))) {
2238 err = -EOPNOTSUPP;
2239 goto out;
2240 }
2241
2242 /* group keys need all-zeroes address */
2243 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
2244 sta = NULL;
2245
2246 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
2247 for (i = 0; i < 64; i++)
2248 if (!(ar->usedkeys & BIT(i)))
2249 break;
2250 if (i == 64) {
2251 ar->rx_software_decryption = true;
2252 ar9170_set_operating_mode(ar);
2253 err = -ENOSPC;
2254 goto out;
2255 }
2256 } else {
2257 i = 64 + key->keyidx;
2258 }
2259
2260 key->hw_key_idx = i;
2261
2262 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
2263 key->key, min_t(u8, 16, key->keylen));
2264 if (err)
2265 goto out;
2266
2267 if (key->alg == ALG_TKIP) {
2268 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
2269 ktype, 1, key->key + 16, 16);
2270 if (err)
2271 goto out;
2272
2273 /*
2274 * hardware is not capable generating the MMIC
2275 * for fragmented frames!
2276 */
2277 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
2278 }
2279
2280 if (i < 64)
2281 ar->usedkeys |= BIT(i);
2282
2283 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
2284 } else {
2285 if (unlikely(!IS_STARTED(ar))) {
2286 /* The device is gone... together with the key ;-) */
2287 err = 0;
2288 goto out;
2289 }
2290
2291 err = ar9170_disable_key(ar, key->hw_key_idx);
2292 if (err)
2293 goto out;
2294
2295 if (key->hw_key_idx < 64) {
2296 ar->usedkeys &= ~BIT(key->hw_key_idx);
2297 } else {
2298 err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
2299 AR9170_ENC_ALG_NONE, 0,
2300 NULL, 0);
2301 if (err)
2302 goto out;
2303
2304 if (key->alg == ALG_TKIP) {
2305 err = ar9170_upload_key(ar, key->hw_key_idx,
2306 NULL,
2307 AR9170_ENC_ALG_NONE, 1,
2308 NULL, 0);
2309 if (err)
2310 goto out;
2311 }
2312
2313 }
2314 }
2315
2316 ar9170_regwrite_begin(ar);
2317 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
2318 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
2319 ar9170_regwrite_finish();
2320 err = ar9170_regwrite_result();
2321
2322out:
2323 mutex_unlock(&ar->mutex);
2324
2325 return err;
2326}
2327
Johannes Berg3e60f862010-02-19 19:06:53 +01002328static int ar9170_sta_add(struct ieee80211_hw *hw,
2329 struct ieee80211_vif *vif,
2330 struct ieee80211_sta *sta)
Christian Lampartere9348cd2009-03-21 23:05:13 +01002331{
Christian Lamparteracbadf02009-07-11 17:24:14 +02002332 struct ar9170 *ar = hw->priv;
2333 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2334 unsigned int i;
2335
Johannes Berg3e60f862010-02-19 19:06:53 +01002336 memset(sta_info, 0, sizeof(*sta_info));
Christian Lamparteracbadf02009-07-11 17:24:14 +02002337
Johannes Berg3e60f862010-02-19 19:06:53 +01002338 if (!sta->ht_cap.ht_supported)
2339 return 0;
Christian Lamparteracbadf02009-07-11 17:24:14 +02002340
Johannes Berg3e60f862010-02-19 19:06:53 +01002341 if (sta->ht_cap.ampdu_density > ar->global_ampdu_density)
2342 ar->global_ampdu_density = sta->ht_cap.ampdu_density;
Christian Lamparteracbadf02009-07-11 17:24:14 +02002343
Johannes Berg3e60f862010-02-19 19:06:53 +01002344 if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor)
2345 ar->global_ampdu_factor = sta->ht_cap.ampdu_factor;
Christian Lamparteracbadf02009-07-11 17:24:14 +02002346
Johannes Berg3e60f862010-02-19 19:06:53 +01002347 for (i = 0; i < AR9170_NUM_TID; i++) {
2348 sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN;
2349 sta_info->agg[i].active = false;
2350 sta_info->agg[i].ssn = 0;
2351 sta_info->agg[i].tid = i;
2352 INIT_LIST_HEAD(&sta_info->agg[i].list);
2353 skb_queue_head_init(&sta_info->agg[i].queue);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002354 }
Johannes Berg3e60f862010-02-19 19:06:53 +01002355
2356 sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor);
2357
2358 return 0;
2359}
2360
2361static int ar9170_sta_remove(struct ieee80211_hw *hw,
2362 struct ieee80211_vif *vif,
2363 struct ieee80211_sta *sta)
2364{
2365 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2366 unsigned int i;
2367
2368 if (!sta->ht_cap.ht_supported)
2369 return 0;
2370
2371 for (i = 0; i < AR9170_NUM_TID; i++) {
2372 sta_info->agg[i].state = AR9170_TID_STATE_INVALID;
2373 skb_queue_purge(&sta_info->agg[i].queue);
2374 }
2375
2376 return 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002377}
2378
2379static int ar9170_get_stats(struct ieee80211_hw *hw,
2380 struct ieee80211_low_level_stats *stats)
2381{
2382 struct ar9170 *ar = hw->priv;
2383 u32 val;
2384 int err;
2385
2386 mutex_lock(&ar->mutex);
2387 err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
2388 ar->stats.dot11ACKFailureCount += val;
2389
2390 memcpy(stats, &ar->stats, sizeof(*stats));
2391 mutex_unlock(&ar->mutex);
2392
2393 return 0;
2394}
2395
Christian Lampartere9348cd2009-03-21 23:05:13 +01002396static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
2397 const struct ieee80211_tx_queue_params *param)
2398{
2399 struct ar9170 *ar = hw->priv;
2400 int ret;
2401
2402 mutex_lock(&ar->mutex);
Dan Carpentere9d126c2009-08-09 14:24:09 +02002403 if (queue < __AR9170_NUM_TXQ) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002404 memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
2405 param, sizeof(*param));
2406
2407 ret = ar9170_set_qos(ar);
Dan Carpentere9d126c2009-08-09 14:24:09 +02002408 } else {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002409 ret = -EINVAL;
Dan Carpentere9d126c2009-08-09 14:24:09 +02002410 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01002411
2412 mutex_unlock(&ar->mutex);
2413 return ret;
2414}
2415
Johannes Berg9e52b06232009-04-20 18:27:04 +02002416static int ar9170_ampdu_action(struct ieee80211_hw *hw,
Johannes Bergc951ad32009-11-16 12:00:38 +01002417 struct ieee80211_vif *vif,
Johannes Berg9e52b06232009-04-20 18:27:04 +02002418 enum ieee80211_ampdu_mlme_action action,
2419 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
2420{
Christian Lamparteracbadf02009-07-11 17:24:14 +02002421 struct ar9170 *ar = hw->priv;
2422 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2423 struct ar9170_sta_tid *tid_info = &sta_info->agg[tid];
2424 unsigned long flags;
2425
2426 if (!modparam_ht)
2427 return -EOPNOTSUPP;
2428
Johannes Berg9e52b06232009-04-20 18:27:04 +02002429 switch (action) {
Christian Lamparteracbadf02009-07-11 17:24:14 +02002430 case IEEE80211_AMPDU_TX_START:
2431 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2432 if (tid_info->state != AR9170_TID_STATE_SHUTDOWN ||
2433 !list_empty(&tid_info->list)) {
2434 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2435#ifdef AR9170_TXAGG_DEBUG
2436 printk(KERN_INFO "%s: A-MPDU [ESS:[%pM] tid:[%d]] "
2437 "is in a very bad state!\n",
2438 wiphy_name(hw->wiphy), sta->addr, tid);
2439#endif /* AR9170_TXAGG_DEBUG */
2440 return -EBUSY;
2441 }
2442
2443 *ssn = tid_info->ssn;
2444 tid_info->state = AR9170_TID_STATE_PROGRESS;
2445 tid_info->active = false;
2446 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
Johannes Bergc951ad32009-11-16 12:00:38 +01002447 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002448 break;
2449
2450 case IEEE80211_AMPDU_TX_STOP:
2451 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2452 tid_info->state = AR9170_TID_STATE_SHUTDOWN;
2453 list_del_init(&tid_info->list);
2454 tid_info->active = false;
2455 skb_queue_purge(&tid_info->queue);
2456 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
Johannes Bergc951ad32009-11-16 12:00:38 +01002457 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002458 break;
2459
2460 case IEEE80211_AMPDU_TX_OPERATIONAL:
2461#ifdef AR9170_TXAGG_DEBUG
2462 printk(KERN_INFO "%s: A-MPDU for %pM [tid:%d] Operational.\n",
2463 wiphy_name(hw->wiphy), sta->addr, tid);
2464#endif /* AR9170_TXAGG_DEBUG */
2465 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2466 sta_info->agg[tid].state = AR9170_TID_STATE_COMPLETE;
2467 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2468 break;
2469
Johannes Berg9e52b06232009-04-20 18:27:04 +02002470 case IEEE80211_AMPDU_RX_START:
2471 case IEEE80211_AMPDU_RX_STOP:
Christian Lamparteracbadf02009-07-11 17:24:14 +02002472 /* Handled by firmware */
2473 break;
2474
Johannes Berg9e52b06232009-04-20 18:27:04 +02002475 default:
2476 return -EOPNOTSUPP;
2477 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02002478
2479 return 0;
Johannes Berg9e52b06232009-04-20 18:27:04 +02002480}
2481
Christian Lampartere9348cd2009-03-21 23:05:13 +01002482static const struct ieee80211_ops ar9170_ops = {
2483 .start = ar9170_op_start,
2484 .stop = ar9170_op_stop,
2485 .tx = ar9170_op_tx,
2486 .add_interface = ar9170_op_add_interface,
2487 .remove_interface = ar9170_op_remove_interface,
2488 .config = ar9170_op_config,
Johannes Berg3ac64be2009-08-17 16:16:53 +02002489 .prepare_multicast = ar9170_op_prepare_multicast,
Christian Lampartere9348cd2009-03-21 23:05:13 +01002490 .configure_filter = ar9170_op_configure_filter,
2491 .conf_tx = ar9170_conf_tx,
2492 .bss_info_changed = ar9170_op_bss_info_changed,
2493 .get_tsf = ar9170_op_get_tsf,
2494 .set_key = ar9170_set_key,
Johannes Berg3e60f862010-02-19 19:06:53 +01002495 .sta_add = ar9170_sta_add,
2496 .sta_remove = ar9170_sta_remove,
Christian Lampartere9348cd2009-03-21 23:05:13 +01002497 .get_stats = ar9170_get_stats,
Johannes Berg9e52b06232009-04-20 18:27:04 +02002498 .ampdu_action = ar9170_ampdu_action,
Christian Lampartere9348cd2009-03-21 23:05:13 +01002499};
2500
2501void *ar9170_alloc(size_t priv_size)
2502{
2503 struct ieee80211_hw *hw;
2504 struct ar9170 *ar;
Christian Lampartercca847992009-04-19 01:28:12 +02002505 struct sk_buff *skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002506 int i;
2507
Christian Lampartercca847992009-04-19 01:28:12 +02002508 /*
2509 * this buffer is used for rx stream reconstruction.
2510 * Under heavy load this device (or the transport layer?)
Daniel Mack3ad2f3f2010-02-03 08:01:28 +08002511 * tends to split the streams into separate rx descriptors.
Christian Lampartercca847992009-04-19 01:28:12 +02002512 */
2513
2514 skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL);
2515 if (!skb)
2516 goto err_nomem;
2517
Christian Lampartere9348cd2009-03-21 23:05:13 +01002518 hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
2519 if (!hw)
Christian Lampartercca847992009-04-19 01:28:12 +02002520 goto err_nomem;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002521
2522 ar = hw->priv;
2523 ar->hw = hw;
Christian Lampartercca847992009-04-19 01:28:12 +02002524 ar->rx_failover = skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002525
2526 mutex_init(&ar->mutex);
2527 spin_lock_init(&ar->cmdlock);
2528 spin_lock_init(&ar->tx_stats_lock);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002529 spin_lock_init(&ar->tx_ampdu_list_lock);
2530 skb_queue_head_init(&ar->tx_status_ampdu);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002531 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
2532 skb_queue_head_init(&ar->tx_status[i]);
2533 skb_queue_head_init(&ar->tx_pending[i]);
2534 }
Christian Lampartercca847992009-04-19 01:28:12 +02002535 ar9170_rx_reset_rx_mpdu(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002536 INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002537 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002538 INIT_LIST_HEAD(&ar->tx_ampdu_list);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002539
2540 /* all hw supports 2.4 GHz, so set channel to 1 by default */
2541 ar->channel = &ar9170_2ghz_chantable[0];
2542
2543 /* first part of wiphy init */
2544 ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2545 BIT(NL80211_IFTYPE_WDS) |
2546 BIT(NL80211_IFTYPE_ADHOC);
2547 ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
2548 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
2549 IEEE80211_HW_SIGNAL_DBM |
2550 IEEE80211_HW_NOISE_DBM;
2551
Christian Lamparteracbadf02009-07-11 17:24:14 +02002552 if (modparam_ht) {
2553 ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
2554 } else {
2555 ar9170_band_2GHz.ht_cap.ht_supported = false;
2556 ar9170_band_5GHz.ht_cap.ht_supported = false;
2557 }
2558
Christian Lamparter4a48e2a2009-03-23 12:15:43 +01002559 ar->hw->queues = __AR9170_NUM_TXQ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002560 ar->hw->extra_tx_headroom = 8;
2561 ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
2562
2563 ar->hw->max_rates = 1;
2564 ar->hw->max_rate_tries = 3;
2565
2566 for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
2567 ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
2568
2569 return ar;
Christian Lampartercca847992009-04-19 01:28:12 +02002570
2571err_nomem:
2572 kfree_skb(skb);
2573 return ERR_PTR(-ENOMEM);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002574}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002575
2576static int ar9170_read_eeprom(struct ar9170 *ar)
2577{
2578#define RW 8 /* number of words to read at once */
2579#define RB (sizeof(u32) * RW)
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002580 struct ath_regulatory *regulatory = &ar->common.regulatory;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002581 u8 *eeprom = (void *)&ar->eeprom;
2582 u8 *addr = ar->eeprom.mac_address;
2583 __le32 offsets[RW];
Christian Lamparteracbadf02009-07-11 17:24:14 +02002584 unsigned int rx_streams, tx_streams, tx_params = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002585 int i, j, err, bands = 0;
2586
2587 BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
2588
2589 BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
2590#ifndef __CHECKER__
2591 /* don't want to handle trailing remains */
2592 BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
2593#endif
2594
2595 for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
2596 for (j = 0; j < RW; j++)
2597 offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
2598 RB * i + 4 * j);
2599
2600 err = ar->exec_cmd(ar, AR9170_CMD_RREG,
2601 RB, (u8 *) &offsets,
2602 RB, eeprom + RB * i);
2603 if (err)
2604 return err;
2605 }
2606
2607#undef RW
2608#undef RB
2609
2610 if (ar->eeprom.length == cpu_to_le16(0xFFFF))
2611 return -ENODATA;
2612
2613 if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
2614 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
2615 bands++;
2616 }
2617 if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
2618 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
2619 bands++;
2620 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02002621
2622 rx_streams = hweight8(ar->eeprom.rx_mask);
2623 tx_streams = hweight8(ar->eeprom.tx_mask);
2624
2625 if (rx_streams != tx_streams)
2626 tx_params = IEEE80211_HT_MCS_TX_RX_DIFF;
2627
2628 if (tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS)
2629 tx_params = (tx_streams - 1) <<
2630 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
2631
2632 ar9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
2633 ar9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params;
2634
Christian Lampartere9348cd2009-03-21 23:05:13 +01002635 /*
2636 * I measured this, a bandswitch takes roughly
2637 * 135 ms and a frequency switch about 80.
2638 *
2639 * FIXME: measure these values again once EEPROM settings
2640 * are used, that will influence them!
2641 */
2642 if (bands == 2)
2643 ar->hw->channel_change_time = 135 * 1000;
2644 else
2645 ar->hw->channel_change_time = 80 * 1000;
2646
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002647 regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
2648 regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
Christian Lamparter1878f772009-03-30 22:30:32 -04002649
Christian Lampartere9348cd2009-03-21 23:05:13 +01002650 /* second part of wiphy init */
2651 SET_IEEE80211_PERM_ADDR(ar->hw, addr);
2652
2653 return bands ? 0 : -EINVAL;
2654}
2655
Christian Lamparter1878f772009-03-30 22:30:32 -04002656static int ar9170_reg_notifier(struct wiphy *wiphy,
2657 struct regulatory_request *request)
2658{
2659 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2660 struct ar9170 *ar = hw->priv;
2661
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002662 return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory);
Christian Lamparter1878f772009-03-30 22:30:32 -04002663}
2664
Christian Lampartere9348cd2009-03-21 23:05:13 +01002665int ar9170_register(struct ar9170 *ar, struct device *pdev)
2666{
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002667 struct ath_regulatory *regulatory = &ar->common.regulatory;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002668 int err;
2669
2670 /* try to read EEPROM, init MAC addr */
2671 err = ar9170_read_eeprom(ar);
2672 if (err)
2673 goto err_out;
2674
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002675 err = ath_regd_init(regulatory, ar->hw->wiphy,
Christian Lamparter1878f772009-03-30 22:30:32 -04002676 ar9170_reg_notifier);
Luis R. Rodriguez85efc862009-04-13 21:41:46 -04002677 if (err)
2678 goto err_out;
Christian Lamparter1878f772009-03-30 22:30:32 -04002679
Christian Lampartere9348cd2009-03-21 23:05:13 +01002680 err = ieee80211_register_hw(ar->hw);
2681 if (err)
2682 goto err_out;
2683
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002684 if (!ath_is_world_regd(regulatory))
2685 regulatory_hint(ar->hw->wiphy, regulatory->alpha2);
Christian Lamparter1878f772009-03-30 22:30:32 -04002686
Christian Lampartere9348cd2009-03-21 23:05:13 +01002687 err = ar9170_init_leds(ar);
2688 if (err)
2689 goto err_unreg;
2690
2691#ifdef CONFIG_AR9170_LEDS
2692 err = ar9170_register_leds(ar);
2693 if (err)
2694 goto err_unreg;
2695#endif /* CONFIG_AR9170_LEDS */
2696
2697 dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
2698 wiphy_name(ar->hw->wiphy));
2699
Johannes Berg53576512009-12-23 13:15:30 +01002700 ar->registered = true;
2701 return 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002702
2703err_unreg:
2704 ieee80211_unregister_hw(ar->hw);
2705
2706err_out:
2707 return err;
2708}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002709
2710void ar9170_unregister(struct ar9170 *ar)
2711{
Johannes Berg53576512009-12-23 13:15:30 +01002712 if (ar->registered) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002713#ifdef CONFIG_AR9170_LEDS
Johannes Berg53576512009-12-23 13:15:30 +01002714 ar9170_unregister_leds(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002715#endif /* CONFIG_AR9170_LEDS */
2716
2717 ieee80211_unregister_hw(ar->hw);
Johannes Berg53576512009-12-23 13:15:30 +01002718 }
2719
2720 kfree_skb(ar->rx_failover);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002721 mutex_destroy(&ar->mutex);
2722}