blob: cfe6fc78067a5d20dccd28c33d8d26656bb1a326 [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
197static inline u16 ar9170_get_tid(struct sk_buff *skb)
198{
199 struct ar9170_tx_control *txc = (void *) skb->data;
200 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
201
202 return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
203}
204
205#define GET_NEXT_SEQ(seq) ((seq + 1) & 0x0fff)
206#define GET_NEXT_SEQ_FROM_SKB(skb) (GET_NEXT_SEQ(ar9170_get_seq(skb)))
207
208#if (defined AR9170_QUEUE_DEBUG) || (defined AR9170_TXAGG_DEBUG)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100209static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
210{
211 struct ar9170_tx_control *txc = (void *) skb->data;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200212 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
213 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
214 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100215
Christian Lamparteracbadf02009-07-11 17:24:14 +0200216 printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x s:%d "
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200217 "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
Christian Lampartere9348cd2009-03-21 23:05:13 +0100218 wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
Christian Lamparteracbadf02009-07-11 17:24:14 +0200219 ieee80211_get_DA(hdr), arinfo->flags, ar9170_get_seq_h(hdr),
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200220 le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
221 jiffies_to_msecs(arinfo->timeout - jiffies));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100222}
223
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200224static void __ar9170_dump_txqueue(struct ar9170 *ar,
225 struct sk_buff_head *queue)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100226{
227 struct sk_buff *skb;
228 int i = 0;
229
230 printk(KERN_DEBUG "---[ cut here ]---\n");
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200231 printk(KERN_DEBUG "%s: %d entries in queue.\n",
Christian Lampartere9348cd2009-03-21 23:05:13 +0100232 wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
233
234 skb_queue_walk(queue, skb) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200235 printk(KERN_DEBUG "index:%d => \n", i++);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100236 ar9170_print_txheader(ar, skb);
237 }
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200238 if (i != skb_queue_len(queue))
239 printk(KERN_DEBUG "WARNING: queue frame counter "
240 "mismatch %d != %d\n", skb_queue_len(queue), i);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100241 printk(KERN_DEBUG "---[ end ]---\n");
242}
Christian Lamparteracbadf02009-07-11 17:24:14 +0200243#endif /* AR9170_QUEUE_DEBUG || AR9170_TXAGG_DEBUG */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100244
Christian Lamparteracbadf02009-07-11 17:24:14 +0200245#ifdef AR9170_QUEUE_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200246static void ar9170_dump_txqueue(struct ar9170 *ar,
247 struct sk_buff_head *queue)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100248{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200249 unsigned long flags;
250
251 spin_lock_irqsave(&queue->lock, flags);
252 __ar9170_dump_txqueue(ar, queue);
253 spin_unlock_irqrestore(&queue->lock, flags);
254}
Christian Lamparteracbadf02009-07-11 17:24:14 +0200255#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200256
Christian Lamparteracbadf02009-07-11 17:24:14 +0200257#ifdef AR9170_QUEUE_STOP_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200258static void __ar9170_dump_txstats(struct ar9170 *ar)
259{
260 int i;
261
262 printk(KERN_DEBUG "%s: QoS queue stats\n",
263 wiphy_name(ar->hw->wiphy));
264
265 for (i = 0; i < __AR9170_NUM_TXQ; i++)
Christian Lamparteracbadf02009-07-11 17:24:14 +0200266 printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d "
267 " stopped:%d\n", wiphy_name(ar->hw->wiphy), i,
268 ar->tx_stats[i].limit, ar->tx_stats[i].len,
269 skb_queue_len(&ar->tx_status[i]),
270 ieee80211_queue_stopped(ar->hw, i));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200271}
Christian Lamparteracbadf02009-07-11 17:24:14 +0200272#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200273
Christian Lamparteracbadf02009-07-11 17:24:14 +0200274#ifdef AR9170_TXAGG_DEBUG
275static void ar9170_dump_tx_status_ampdu(struct ar9170 *ar)
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200276{
Christian Lampartere9348cd2009-03-21 23:05:13 +0100277 unsigned long flags;
278
Christian Lamparteracbadf02009-07-11 17:24:14 +0200279 spin_lock_irqsave(&ar->tx_status_ampdu.lock, flags);
280 printk(KERN_DEBUG "%s: A-MPDU tx_status queue => \n",
281 wiphy_name(ar->hw->wiphy));
282 __ar9170_dump_txqueue(ar, &ar->tx_status_ampdu);
283 spin_unlock_irqrestore(&ar->tx_status_ampdu.lock, flags);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200284}
Christian Lamparteracbadf02009-07-11 17:24:14 +0200285
286#endif /* AR9170_TXAGG_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200287
288/* caller must guarantee exclusive access for _bin_ queue. */
289static void ar9170_recycle_expired(struct ar9170 *ar,
290 struct sk_buff_head *queue,
291 struct sk_buff_head *bin)
292{
293 struct sk_buff *skb, *old = NULL;
294 unsigned long flags;
295
296 spin_lock_irqsave(&queue->lock, flags);
297 while ((skb = skb_peek(queue))) {
298 struct ieee80211_tx_info *txinfo;
299 struct ar9170_tx_info *arinfo;
300
301 txinfo = IEEE80211_SKB_CB(skb);
302 arinfo = (void *) txinfo->rate_driver_data;
303
304 if (time_is_before_jiffies(arinfo->timeout)) {
305#ifdef AR9170_QUEUE_DEBUG
306 printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => "
307 "recycle \n", wiphy_name(ar->hw->wiphy),
308 jiffies, arinfo->timeout);
309 ar9170_print_txheader(ar, skb);
310#endif /* AR9170_QUEUE_DEBUG */
311 __skb_unlink(skb, queue);
312 __skb_queue_tail(bin, skb);
313 } else {
314 break;
315 }
316
317 if (unlikely(old == skb)) {
318 /* bail out - queue is shot. */
319
320 WARN_ON(1);
321 break;
322 }
323 old = skb;
324 }
325 spin_unlock_irqrestore(&queue->lock, flags);
326}
327
328static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
329 u16 tx_status)
330{
331 struct ieee80211_tx_info *txinfo;
332 unsigned int retries = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100333
334 txinfo = IEEE80211_SKB_CB(skb);
335 ieee80211_tx_info_clear_status(txinfo);
336
337 switch (tx_status) {
338 case AR9170_TX_STATUS_RETRY:
339 retries = 2;
340 case AR9170_TX_STATUS_COMPLETE:
341 txinfo->flags |= IEEE80211_TX_STAT_ACK;
342 break;
343
344 case AR9170_TX_STATUS_FAILED:
345 retries = ar->hw->conf.long_frame_max_tx_count;
346 break;
347
348 default:
349 printk(KERN_ERR "%s: invalid tx_status response (%x).\n",
350 wiphy_name(ar->hw->wiphy), tx_status);
351 break;
352 }
353
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200354 txinfo->status.rates[0].count = retries + 1;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100355 skb_pull(skb, sizeof(struct ar9170_tx_control));
356 ieee80211_tx_status_irqsafe(ar->hw, skb);
357}
Christian Lampartere9348cd2009-03-21 23:05:13 +0100358
Christian Lamparteracbadf02009-07-11 17:24:14 +0200359static void ar9170_tx_fake_ampdu_status(struct ar9170 *ar)
360{
361 struct sk_buff_head success;
362 struct sk_buff *skb;
363 unsigned int i;
364 unsigned long queue_bitmap = 0;
365
366 skb_queue_head_init(&success);
367
368 while (skb_queue_len(&ar->tx_status_ampdu) > AR9170_NUM_TX_STATUS)
369 __skb_queue_tail(&success, skb_dequeue(&ar->tx_status_ampdu));
370
371 ar9170_recycle_expired(ar, &ar->tx_status_ampdu, &success);
372
373#ifdef AR9170_TXAGG_DEBUG
374 printk(KERN_DEBUG "%s: collected %d A-MPDU frames.\n",
375 wiphy_name(ar->hw->wiphy), skb_queue_len(&success));
376 __ar9170_dump_txqueue(ar, &success);
377#endif /* AR9170_TXAGG_DEBUG */
378
379 while ((skb = __skb_dequeue(&success))) {
380 struct ieee80211_tx_info *txinfo;
381
382 queue_bitmap |= BIT(skb_get_queue_mapping(skb));
383
384 txinfo = IEEE80211_SKB_CB(skb);
385 ieee80211_tx_info_clear_status(txinfo);
386
387 txinfo->flags |= IEEE80211_TX_STAT_ACK;
388 txinfo->status.rates[0].count = 1;
389
390 skb_pull(skb, sizeof(struct ar9170_tx_control));
391 ieee80211_tx_status_irqsafe(ar->hw, skb);
392 }
393
394 for_each_bit(i, &queue_bitmap, BITS_PER_BYTE) {
395#ifdef AR9170_QUEUE_STOP_DEBUG
396 printk(KERN_DEBUG "%s: wake queue %d\n",
397 wiphy_name(ar->hw->wiphy), i);
398 __ar9170_dump_txstats(ar);
399#endif /* AR9170_QUEUE_STOP_DEBUG */
400 ieee80211_wake_queue(ar->hw, i);
401 }
402
403 if (queue_bitmap)
404 ar9170_tx(ar);
405}
406
407static void ar9170_tx_ampdu_callback(struct ar9170 *ar, struct sk_buff *skb)
408{
409 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
410 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
411
412 arinfo->timeout = jiffies +
413 msecs_to_jiffies(AR9170_BA_TIMEOUT);
414
415 skb_queue_tail(&ar->tx_status_ampdu, skb);
416 ar9170_tx_fake_ampdu_status(ar);
417 ar->tx_ampdu_pending--;
418
419 if (!list_empty(&ar->tx_ampdu_list) && !ar->tx_ampdu_pending)
420 ar9170_tx_ampdu(ar);
421}
422
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200423void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100424{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200425 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
426 struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data;
427 unsigned int queue = skb_get_queue_mapping(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100428 unsigned long flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100429
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200430 spin_lock_irqsave(&ar->tx_stats_lock, flags);
431 ar->tx_stats[queue].len--;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100432
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200433 if (skb_queue_empty(&ar->tx_pending[queue])) {
434#ifdef AR9170_QUEUE_STOP_DEBUG
435 printk(KERN_DEBUG "%s: wake queue %d\n",
436 wiphy_name(ar->hw->wiphy), queue);
437 __ar9170_dump_txstats(ar);
438#endif /* AR9170_QUEUE_STOP_DEBUG */
439 ieee80211_wake_queue(ar->hw, queue);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100440 }
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200441 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
442
443 if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) {
Christian Lamparteracbadf02009-07-11 17:24:14 +0200444 ar9170_tx_ampdu_callback(ar, skb);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200445 } else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) {
446 arinfo->timeout = jiffies +
447 msecs_to_jiffies(AR9170_TX_TIMEOUT);
448
449 skb_queue_tail(&ar->tx_status[queue], skb);
450 } else if (arinfo->flags & AR9170_TX_FLAG_NO_ACK) {
451 ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED);
452 } else {
453#ifdef AR9170_QUEUE_DEBUG
454 printk(KERN_DEBUG "%s: unsupported frame flags!\n",
455 wiphy_name(ar->hw->wiphy));
456 ar9170_print_txheader(ar, skb);
457#endif /* AR9170_QUEUE_DEBUG */
458 dev_kfree_skb_any(skb);
459 }
460
461 if (!ar->tx_stats[queue].len &&
462 !skb_queue_empty(&ar->tx_pending[queue])) {
463 ar9170_tx(ar);
464 }
Christian Lampartere9348cd2009-03-21 23:05:13 +0100465}
466
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200467static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
468 const u8 *mac,
469 struct sk_buff_head *queue,
470 const u32 rate)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100471{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200472 unsigned long flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100473 struct sk_buff *skb;
474
475 /*
476 * Unfortunately, the firmware does not tell to which (queued) frame
477 * this transmission status report belongs to.
478 *
479 * So we have to make risky guesses - with the scarce information
480 * the firmware provided (-> destination MAC, and phy_control) -
481 * and hope that we picked the right one...
482 */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100483
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200484 spin_lock_irqsave(&queue->lock, flags);
485 skb_queue_walk(queue, skb) {
486 struct ar9170_tx_control *txc = (void *) skb->data;
487 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
488 u32 r;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100489
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200490 if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) {
491#ifdef AR9170_QUEUE_DEBUG
492 printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n",
493 wiphy_name(ar->hw->wiphy), mac,
494 ieee80211_get_DA(hdr));
495 ar9170_print_txheader(ar, skb);
496#endif /* AR9170_QUEUE_DEBUG */
497 continue;
498 }
499
500 r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >>
501 AR9170_TX_PHY_MCS_SHIFT;
502
503 if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) {
504#ifdef AR9170_QUEUE_DEBUG
505 printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n",
506 wiphy_name(ar->hw->wiphy), rate, r);
507 ar9170_print_txheader(ar, skb);
508#endif /* AR9170_QUEUE_DEBUG */
509 continue;
510 }
511
512 __skb_unlink(skb, queue);
513 spin_unlock_irqrestore(&queue->lock, flags);
514 return skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100515 }
Christian Lampartere9348cd2009-03-21 23:05:13 +0100516
517#ifdef AR9170_QUEUE_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200518 printk(KERN_ERR "%s: ESS:[%pM] does not have any "
519 "outstanding frames in queue.\n",
520 wiphy_name(ar->hw->wiphy), mac);
521 __ar9170_dump_txqueue(ar, queue);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100522#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200523 spin_unlock_irqrestore(&queue->lock, flags);
524
525 return NULL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100526}
527
Christian Lamparteracbadf02009-07-11 17:24:14 +0200528static void ar9170_handle_block_ack(struct ar9170 *ar, u16 count, u16 r)
529{
530 struct sk_buff *skb;
531 struct ieee80211_tx_info *txinfo;
532
533 while (count) {
534 skb = ar9170_get_queued_skb(ar, NULL, &ar->tx_status_ampdu, r);
535 if (!skb)
536 break;
537
538 txinfo = IEEE80211_SKB_CB(skb);
539 ieee80211_tx_info_clear_status(txinfo);
540
541 /* FIXME: maybe more ? */
542 txinfo->status.rates[0].count = 1;
543
544 skb_pull(skb, sizeof(struct ar9170_tx_control));
545 ieee80211_tx_status_irqsafe(ar->hw, skb);
546 count--;
547 }
548
549#ifdef AR9170_TXAGG_DEBUG
550 if (count) {
551 printk(KERN_DEBUG "%s: got %d more failed mpdus, but no more "
552 "suitable frames left in tx_status queue.\n",
553 wiphy_name(ar->hw->wiphy), count);
554
555 ar9170_dump_tx_status_ampdu(ar);
556 }
557#endif /* AR9170_TXAGG_DEBUG */
558}
559
Christian Lampartere9348cd2009-03-21 23:05:13 +0100560/*
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200561 * This worker tries to keeps an maintain tx_status queues.
562 * So we can guarantee that incoming tx_status reports are
563 * actually for a pending frame.
Christian Lampartere9348cd2009-03-21 23:05:13 +0100564 */
565
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200566static void ar9170_tx_janitor(struct work_struct *work)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100567{
568 struct ar9170 *ar = container_of(work, struct ar9170,
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200569 tx_janitor.work);
570 struct sk_buff_head waste;
571 unsigned int i;
572 bool resched = false;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100573
Christian Lamparter4a48e2a2009-03-23 12:15:43 +0100574 if (unlikely(!IS_STARTED(ar)))
575 return ;
576
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200577 skb_queue_head_init(&waste);
578
579 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
Christian Lampartere9348cd2009-03-21 23:05:13 +0100580#ifdef AR9170_QUEUE_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200581 printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n",
582 wiphy_name(ar->hw->wiphy), i);
583 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
584 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100585#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200586
587 ar9170_recycle_expired(ar, &ar->tx_status[i], &waste);
588 ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste);
589 skb_queue_purge(&waste);
590
591 if (!skb_queue_empty(&ar->tx_status[i]) ||
592 !skb_queue_empty(&ar->tx_pending[i]))
593 resched = true;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100594 }
595
Christian Lamparteracbadf02009-07-11 17:24:14 +0200596 ar9170_tx_fake_ampdu_status(ar);
597
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200598 if (resched)
599 queue_delayed_work(ar->hw->workqueue,
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)
651 queue_work(ar->hw->workqueue, &ar->beacon_work);
652 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 Lampartercca847992009-04-19 01:28:12 +0200851 case AR9170_RX_STATUS_MODULATION_OFDM:
852 switch (head->plcp[0] & 0xf) {
853 case 0xb:
854 status->rate_idx = 0;
855 break;
856 case 0xf:
857 status->rate_idx = 1;
858 break;
859 case 0xa:
860 status->rate_idx = 2;
861 break;
862 case 0xe:
863 status->rate_idx = 3;
864 break;
865 case 0x9:
866 status->rate_idx = 4;
867 break;
868 case 0xd:
869 status->rate_idx = 5;
870 break;
871 case 0x8:
872 status->rate_idx = 6;
873 break;
874 case 0xc:
875 status->rate_idx = 7;
876 break;
877 default:
878 if (ar9170_nag_limiter(ar))
879 printk(KERN_ERR "%s: invalid plcp ofdm rate "
880 "(%x).\n", wiphy_name(ar->hw->wiphy),
881 head->plcp[0]);
882 return -EINVAL;
883 }
884 if (status->band == IEEE80211_BAND_2GHZ)
885 status->rate_idx += 4;
886 break;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100887
Christian Lampartercca847992009-04-19 01:28:12 +0200888 case AR9170_RX_STATUS_MODULATION_HT:
889 if (head->plcp[3] & 0x80)
890 status->flag |= RX_FLAG_40MHZ;
891 if (head->plcp[6] & 0x80)
892 status->flag |= RX_FLAG_SHORT_GI;
893
894 status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f);
895 status->flag |= RX_FLAG_HT;
896 break;
897
898 case AR9170_RX_STATUS_MODULATION_DUPOFDM:
899 /* XXX */
900 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
Christian Lamparter864cc022009-05-23 20:28:21 +02001233 ar->filter_changed = 0;
1234
Christian Lampartere9348cd2009-03-21 23:05:13 +01001235 /* reinitialize queues statistics */
1236 memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001237 for (i = 0; i < __AR9170_NUM_TXQ; i++)
1238 ar->tx_stats[i].limit = AR9170_TXQ_DEPTH;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001239
1240 /* reset QoS defaults */
1241 AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/
1242 AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023, 0); /* BACKGROUND */
1243 AR9170_FILL_QUEUE(ar->edcf[2], 2, 7, 15, 94); /* VIDEO */
1244 AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */
1245 AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
1246
Christian Lamparteracbadf02009-07-11 17:24:14 +02001247 /* set sane AMPDU defaults */
1248 ar->global_ampdu_density = 6;
1249 ar->global_ampdu_factor = 3;
1250
Christian Lampartercca847992009-04-19 01:28:12 +02001251 ar->bad_hw_nagger = jiffies;
1252
Christian Lampartere9348cd2009-03-21 23:05:13 +01001253 err = ar->open(ar);
1254 if (err)
1255 goto out;
1256
1257 err = ar9170_init_mac(ar);
1258 if (err)
1259 goto out;
1260
1261 err = ar9170_set_qos(ar);
1262 if (err)
1263 goto out;
1264
1265 err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
1266 if (err)
1267 goto out;
1268
1269 err = ar9170_init_rf(ar);
1270 if (err)
1271 goto out;
1272
1273 /* start DMA */
1274 err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
1275 if (err)
1276 goto out;
1277
1278 ar->state = AR9170_STARTED;
1279
1280out:
1281 mutex_unlock(&ar->mutex);
1282 return err;
1283}
1284
1285static void ar9170_op_stop(struct ieee80211_hw *hw)
1286{
1287 struct ar9170 *ar = hw->priv;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001288 unsigned int i;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001289
1290 if (IS_STARTED(ar))
1291 ar->state = AR9170_IDLE;
1292
Christian Lamparter32c16282009-03-28 01:46:14 +01001293 flush_workqueue(ar->hw->workqueue);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001294
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001295 cancel_delayed_work_sync(&ar->tx_janitor);
Christian Lamparteracbadf02009-07-11 17:24:14 +02001296 cancel_delayed_work_sync(&ar->led_work);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001297 cancel_work_sync(&ar->filter_config_work);
1298 cancel_work_sync(&ar->beacon_work);
Christian Lamparterb55d6bc2009-05-23 20:31:21 +02001299 mutex_lock(&ar->mutex);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001300
1301 if (IS_ACCEPTING_CMD(ar)) {
1302 ar9170_set_leds_state(ar, 0);
1303
1304 /* stop DMA */
1305 ar9170_write_reg(ar, 0x1c3d30, 0);
1306 ar->stop(ar);
1307 }
1308
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001309 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1310 skb_queue_purge(&ar->tx_pending[i]);
1311 skb_queue_purge(&ar->tx_status[i]);
1312 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02001313 skb_queue_purge(&ar->tx_status_ampdu);
1314
Christian Lampartere9348cd2009-03-21 23:05:13 +01001315 mutex_unlock(&ar->mutex);
1316}
1317
Christian Lamparteracbadf02009-07-11 17:24:14 +02001318static void ar9170_tx_indicate_immba(struct ar9170 *ar, struct sk_buff *skb)
1319{
1320 struct ar9170_tx_control *txc = (void *) skb->data;
1321
1322 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_IMM_AMPDU);
1323}
1324
1325static void ar9170_tx_copy_phy(struct ar9170 *ar, struct sk_buff *dst,
1326 struct sk_buff *src)
1327{
1328 struct ar9170_tx_control *dst_txc, *src_txc;
1329 struct ieee80211_tx_info *dst_info, *src_info;
1330 struct ar9170_tx_info *dst_arinfo, *src_arinfo;
1331
1332 src_txc = (void *) src->data;
1333 src_info = IEEE80211_SKB_CB(src);
1334 src_arinfo = (void *) src_info->rate_driver_data;
1335
1336 dst_txc = (void *) dst->data;
1337 dst_info = IEEE80211_SKB_CB(dst);
1338 dst_arinfo = (void *) dst_info->rate_driver_data;
1339
1340 dst_txc->phy_control = src_txc->phy_control;
1341
1342 /* same MCS for the whole aggregate */
1343 memcpy(dst_info->driver_rates, src_info->driver_rates,
1344 sizeof(dst_info->driver_rates));
1345}
1346
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001347static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001348{
Christian Lampartere9348cd2009-03-21 23:05:13 +01001349 struct ieee80211_hdr *hdr;
1350 struct ar9170_tx_control *txc;
1351 struct ieee80211_tx_info *info;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001352 struct ieee80211_tx_rate *txrate;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001353 struct ar9170_tx_info *arinfo;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001354 unsigned int queue = skb_get_queue_mapping(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001355 u16 keytype = 0;
1356 u16 len, icv = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001357
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001358 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001359
1360 hdr = (void *)skb->data;
1361 info = IEEE80211_SKB_CB(skb);
1362 len = skb->len;
1363
Christian Lampartere9348cd2009-03-21 23:05:13 +01001364 txc = (void *)skb_push(skb, sizeof(*txc));
1365
Christian Lampartere9348cd2009-03-21 23:05:13 +01001366 if (info->control.hw_key) {
1367 icv = info->control.hw_key->icv_len;
1368
1369 switch (info->control.hw_key->alg) {
1370 case ALG_WEP:
1371 keytype = AR9170_TX_MAC_ENCR_RC4;
1372 break;
1373 case ALG_TKIP:
1374 keytype = AR9170_TX_MAC_ENCR_RC4;
1375 break;
1376 case ALG_CCMP:
1377 keytype = AR9170_TX_MAC_ENCR_AES;
1378 break;
1379 default:
1380 WARN_ON(1);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001381 goto err_out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001382 }
1383 }
1384
1385 /* Length */
1386 txc->length = cpu_to_le16(len + icv + 4);
1387
1388 txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
1389 AR9170_TX_MAC_BACKOFF);
1390 txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
1391 AR9170_TX_MAC_QOS_SHIFT);
1392 txc->mac_control |= cpu_to_le16(keytype);
1393 txc->phy_control = cpu_to_le32(0);
1394
1395 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
1396 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
1397
Christian Lampartere9348cd2009-03-21 23:05:13 +01001398 txrate = &info->control.rates[0];
Christian Lampartere9348cd2009-03-21 23:05:13 +01001399 if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1400 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
1401 else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1402 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
1403
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001404 arinfo = (void *)info->rate_driver_data;
1405 arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT);
1406
1407 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
1408 (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
1409 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1410 if (unlikely(!info->control.sta))
1411 goto err_out;
1412
1413 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
1414 arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK;
Christian Lamparteracbadf02009-07-11 17:24:14 +02001415
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001416 goto out;
1417 }
1418
1419 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
1420 /*
1421 * WARNING:
1422 * Putting the QoS queue bits into an unexplored territory is
1423 * certainly not elegant.
1424 *
1425 * In my defense: This idea provides a reasonable way to
1426 * smuggle valuable information to the tx_status callback.
1427 * Also, the idea behind this bit-abuse came straight from
1428 * the original driver code.
1429 */
1430
1431 txc->phy_control |=
1432 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
1433 arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK;
1434 } else {
1435 arinfo->flags = AR9170_TX_FLAG_NO_ACK;
1436 }
1437
1438out:
1439 return 0;
1440
1441err_out:
1442 skb_pull(skb, sizeof(*txc));
1443 return -EINVAL;
1444}
1445
1446static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
1447{
1448 struct ar9170_tx_control *txc;
1449 struct ieee80211_tx_info *info;
1450 struct ieee80211_rate *rate = NULL;
1451 struct ieee80211_tx_rate *txrate;
1452 u32 power, chains;
1453
1454 txc = (void *) skb->data;
1455 info = IEEE80211_SKB_CB(skb);
1456 txrate = &info->control.rates[0];
1457
Christian Lampartere9348cd2009-03-21 23:05:13 +01001458 if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
1459 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
1460
1461 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1462 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
1463
1464 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1465 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
1466 /* this works because 40 MHz is 2 and dup is 3 */
1467 if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
1468 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
1469
1470 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
1471 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
1472
1473 if (txrate->flags & IEEE80211_TX_RC_MCS) {
1474 u32 r = txrate->idx;
1475 u8 *txpower;
1476
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001477 /* heavy clip control */
1478 txc->phy_control |= cpu_to_le32((r & 0x7) << 7);
1479
Christian Lampartere9348cd2009-03-21 23:05:13 +01001480 r <<= AR9170_TX_PHY_MCS_SHIFT;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001481 BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK);
1482
Christian Lampartere9348cd2009-03-21 23:05:13 +01001483 txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
1484 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
1485
1486 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1487 if (info->band == IEEE80211_BAND_5GHZ)
1488 txpower = ar->power_5G_ht40;
1489 else
1490 txpower = ar->power_2G_ht40;
1491 } else {
1492 if (info->band == IEEE80211_BAND_5GHZ)
1493 txpower = ar->power_5G_ht20;
1494 else
1495 txpower = ar->power_2G_ht20;
1496 }
1497
1498 power = txpower[(txrate->idx) & 7];
1499 } else {
1500 u8 *txpower;
1501 u32 mod;
1502 u32 phyrate;
1503 u8 idx = txrate->idx;
1504
1505 if (info->band != IEEE80211_BAND_2GHZ) {
1506 idx += 4;
1507 txpower = ar->power_5G_leg;
1508 mod = AR9170_TX_PHY_MOD_OFDM;
1509 } else {
1510 if (idx < 4) {
1511 txpower = ar->power_2G_cck;
1512 mod = AR9170_TX_PHY_MOD_CCK;
1513 } else {
1514 mod = AR9170_TX_PHY_MOD_OFDM;
1515 txpower = ar->power_2G_ofdm;
1516 }
1517 }
1518
1519 rate = &__ar9170_ratetable[idx];
1520
1521 phyrate = rate->hw_value & 0xF;
1522 power = txpower[(rate->hw_value & 0x30) >> 4];
1523 phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
1524
1525 txc->phy_control |= cpu_to_le32(mod);
1526 txc->phy_control |= cpu_to_le32(phyrate);
1527 }
1528
1529 power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
1530 power &= AR9170_TX_PHY_TX_PWR_MASK;
1531 txc->phy_control |= cpu_to_le32(power);
1532
1533 /* set TX chains */
1534 if (ar->eeprom.tx_mask == 1) {
1535 chains = AR9170_TX_PHY_TXCHAIN_1;
1536 } else {
1537 chains = AR9170_TX_PHY_TXCHAIN_2;
1538
1539 /* >= 36M legacy OFDM - use only one chain */
1540 if (rate && rate->bitrate >= 360)
1541 chains = AR9170_TX_PHY_TXCHAIN_1;
1542 }
1543 txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001544}
Christian Lampartere9348cd2009-03-21 23:05:13 +01001545
Christian Lamparteracbadf02009-07-11 17:24:14 +02001546static bool ar9170_tx_ampdu(struct ar9170 *ar)
1547{
1548 struct sk_buff_head agg;
1549 struct ar9170_sta_tid *tid_info = NULL, *tmp;
1550 struct sk_buff *skb, *first = NULL;
1551 unsigned long flags, f2;
1552 unsigned int i = 0;
1553 u16 seq, queue, tmpssn;
1554 bool run = false;
1555
1556 skb_queue_head_init(&agg);
1557
1558 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1559 if (list_empty(&ar->tx_ampdu_list)) {
1560#ifdef AR9170_TXAGG_DEBUG
1561 printk(KERN_DEBUG "%s: aggregation list is empty.\n",
1562 wiphy_name(ar->hw->wiphy));
1563#endif /* AR9170_TXAGG_DEBUG */
1564 goto out_unlock;
1565 }
1566
1567 list_for_each_entry_safe(tid_info, tmp, &ar->tx_ampdu_list, list) {
1568 if (tid_info->state != AR9170_TID_STATE_COMPLETE) {
1569#ifdef AR9170_TXAGG_DEBUG
1570 printk(KERN_DEBUG "%s: dangling aggregation entry!\n",
1571 wiphy_name(ar->hw->wiphy));
1572#endif /* AR9170_TXAGG_DEBUG */
1573 continue;
1574 }
1575
1576 if (++i > 64) {
1577#ifdef AR9170_TXAGG_DEBUG
1578 printk(KERN_DEBUG "%s: enough frames aggregated.\n",
1579 wiphy_name(ar->hw->wiphy));
1580#endif /* AR9170_TXAGG_DEBUG */
1581 break;
1582 }
1583
1584 queue = TID_TO_WME_AC(tid_info->tid);
1585
1586 if (skb_queue_len(&ar->tx_pending[queue]) >=
1587 AR9170_NUM_TX_AGG_MAX) {
1588#ifdef AR9170_TXAGG_DEBUG
1589 printk(KERN_DEBUG "%s: queue %d full.\n",
1590 wiphy_name(ar->hw->wiphy), queue);
1591#endif /* AR9170_TXAGG_DEBUG */
1592 continue;
1593 }
1594
1595 list_del_init(&tid_info->list);
1596
1597 spin_lock_irqsave(&tid_info->queue.lock, f2);
1598 tmpssn = seq = tid_info->ssn;
1599 first = skb_peek(&tid_info->queue);
1600
1601 if (likely(first))
1602 tmpssn = ar9170_get_seq(first);
1603
1604 if (unlikely(tmpssn != seq)) {
1605#ifdef AR9170_TXAGG_DEBUG
1606 printk(KERN_DEBUG "%s: ssn mismatch [%d != %d]\n.",
1607 wiphy_name(ar->hw->wiphy), seq, tmpssn);
1608#endif /* AR9170_TXAGG_DEBUG */
1609 tid_info->ssn = tmpssn;
1610 }
1611
1612#ifdef AR9170_TXAGG_DEBUG
1613 printk(KERN_DEBUG "%s: generate A-MPDU for tid:%d ssn:%d with "
1614 "%d queued frames.\n", wiphy_name(ar->hw->wiphy),
1615 tid_info->tid, tid_info->ssn,
1616 skb_queue_len(&tid_info->queue));
1617 __ar9170_dump_txqueue(ar, &tid_info->queue);
1618#endif /* AR9170_TXAGG_DEBUG */
1619
1620 while ((skb = skb_peek(&tid_info->queue))) {
1621 if (unlikely(ar9170_get_seq(skb) != seq))
1622 break;
1623
1624 __skb_unlink(skb, &tid_info->queue);
1625 tid_info->ssn = seq = GET_NEXT_SEQ(seq);
1626
1627 if (unlikely(skb_get_queue_mapping(skb) != queue)) {
1628#ifdef AR9170_TXAGG_DEBUG
1629 printk(KERN_DEBUG "%s: tid:%d(q:%d) queue:%d "
1630 "!match.\n", wiphy_name(ar->hw->wiphy),
1631 tid_info->tid,
1632 TID_TO_WME_AC(tid_info->tid),
1633 skb_get_queue_mapping(skb));
1634#endif /* AR9170_TXAGG_DEBUG */
1635 dev_kfree_skb_any(skb);
1636 continue;
1637 }
1638
1639 if (unlikely(first == skb)) {
1640 ar9170_tx_prepare_phy(ar, skb);
1641 __skb_queue_tail(&agg, skb);
1642 first = skb;
1643 } else {
1644 ar9170_tx_copy_phy(ar, skb, first);
1645 __skb_queue_tail(&agg, skb);
1646 }
1647
1648 if (unlikely(skb_queue_len(&agg) ==
1649 AR9170_NUM_TX_AGG_MAX))
1650 break;
1651 }
1652
1653 if (skb_queue_empty(&tid_info->queue))
1654 tid_info->active = false;
1655 else
1656 list_add_tail(&tid_info->list,
1657 &ar->tx_ampdu_list);
1658
1659 spin_unlock_irqrestore(&tid_info->queue.lock, f2);
1660
1661 if (unlikely(skb_queue_empty(&agg))) {
1662#ifdef AR9170_TXAGG_DEBUG
1663 printk(KERN_DEBUG "%s: queued empty list!\n",
1664 wiphy_name(ar->hw->wiphy));
1665#endif /* AR9170_TXAGG_DEBUG */
1666 continue;
1667 }
1668
1669 /*
1670 * tell the FW/HW that this is the last frame,
1671 * that way it will wait for the immediate block ack.
1672 */
1673 if (likely(skb_peek_tail(&agg)))
1674 ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg));
1675
1676#ifdef AR9170_TXAGG_DEBUG
1677 printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n",
1678 wiphy_name(ar->hw->wiphy));
1679 __ar9170_dump_txqueue(ar, &agg);
1680#endif /* AR9170_TXAGG_DEBUG */
1681
1682 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1683
1684 spin_lock_irqsave(&ar->tx_pending[queue].lock, flags);
1685 skb_queue_splice_tail_init(&agg, &ar->tx_pending[queue]);
1686 spin_unlock_irqrestore(&ar->tx_pending[queue].lock, flags);
1687 run = true;
1688
1689 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1690 }
1691
1692out_unlock:
1693 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1694 __skb_queue_purge(&agg);
1695
1696 return run;
1697}
1698
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001699static void ar9170_tx(struct ar9170 *ar)
1700{
1701 struct sk_buff *skb;
1702 unsigned long flags;
1703 struct ieee80211_tx_info *info;
1704 struct ar9170_tx_info *arinfo;
1705 unsigned int i, frames, frames_failed, remaining_space;
1706 int err;
1707 bool schedule_garbagecollector = false;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001708
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001709 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001710
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001711 if (unlikely(!IS_STARTED(ar)))
1712 return ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001713
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001714 remaining_space = AR9170_TX_MAX_PENDING;
1715
1716 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1717 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1718 if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
1719#ifdef AR9170_QUEUE_DEBUG
1720 printk(KERN_DEBUG "%s: queue %d full\n",
1721 wiphy_name(ar->hw->wiphy), i);
1722
Christian Lamparteracbadf02009-07-11 17:24:14 +02001723 printk(KERN_DEBUG "%s: stuck frames: ===> \n",
1724 wiphy_name(ar->hw->wiphy));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001725 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1726 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
1727#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparteracbadf02009-07-11 17:24:14 +02001728
1729#ifdef AR9170_QUEUE_STOP_DEBUG
1730 printk(KERN_DEBUG "%s: stop queue %d\n",
1731 wiphy_name(ar->hw->wiphy), i);
1732 __ar9170_dump_txstats(ar);
1733#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001734 ieee80211_stop_queue(ar->hw, i);
1735 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1736 continue;
1737 }
1738
1739 frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
1740 skb_queue_len(&ar->tx_pending[i]));
1741
1742 if (remaining_space < frames) {
1743#ifdef AR9170_QUEUE_DEBUG
1744 printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
1745 "remaining slots:%d, needed:%d\n",
1746 wiphy_name(ar->hw->wiphy), i, remaining_space,
1747 frames);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001748#endif /* AR9170_QUEUE_DEBUG */
1749 frames = remaining_space;
1750 }
1751
1752 ar->tx_stats[i].len += frames;
1753 ar->tx_stats[i].count += frames;
1754 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1755
1756 if (!frames)
1757 continue;
1758
1759 frames_failed = 0;
1760 while (frames) {
1761 skb = skb_dequeue(&ar->tx_pending[i]);
1762 if (unlikely(!skb)) {
1763 frames_failed += frames;
1764 frames = 0;
1765 break;
1766 }
1767
1768 info = IEEE80211_SKB_CB(skb);
1769 arinfo = (void *) info->rate_driver_data;
1770
1771 /* TODO: cancel stuck frames */
1772 arinfo->timeout = jiffies +
1773 msecs_to_jiffies(AR9170_TX_TIMEOUT);
1774
Christian Lamparteracbadf02009-07-11 17:24:14 +02001775 if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK)
1776 ar->tx_ampdu_pending++;
1777
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001778#ifdef AR9170_QUEUE_DEBUG
1779 printk(KERN_DEBUG "%s: send frame q:%d =>\n",
1780 wiphy_name(ar->hw->wiphy), i);
1781 ar9170_print_txheader(ar, skb);
1782#endif /* AR9170_QUEUE_DEBUG */
1783
1784 err = ar->tx(ar, skb);
1785 if (unlikely(err)) {
Christian Lamparteracbadf02009-07-11 17:24:14 +02001786 if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK)
1787 ar->tx_ampdu_pending--;
1788
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001789 frames_failed++;
1790 dev_kfree_skb_any(skb);
1791 } else {
1792 remaining_space--;
1793 schedule_garbagecollector = true;
1794 }
1795
1796 frames--;
1797 }
1798
1799#ifdef AR9170_QUEUE_DEBUG
1800 printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n",
1801 wiphy_name(ar->hw->wiphy), i);
1802
1803 printk(KERN_DEBUG "%s: unprocessed pending frames left:\n",
1804 wiphy_name(ar->hw->wiphy));
1805 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1806#endif /* AR9170_QUEUE_DEBUG */
1807
1808 if (unlikely(frames_failed)) {
1809#ifdef AR9170_QUEUE_DEBUG
Christian Lamparteracbadf02009-07-11 17:24:14 +02001810 printk(KERN_DEBUG "%s: frames failed %d =>\n",
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001811 wiphy_name(ar->hw->wiphy), frames_failed);
1812#endif /* AR9170_QUEUE_DEBUG */
1813
1814 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1815 ar->tx_stats[i].len -= frames_failed;
1816 ar->tx_stats[i].count -= frames_failed;
Christian Lamparteracbadf02009-07-11 17:24:14 +02001817#ifdef AR9170_QUEUE_STOP_DEBUG
1818 printk(KERN_DEBUG "%s: wake queue %d\n",
1819 wiphy_name(ar->hw->wiphy), i);
1820 __ar9170_dump_txstats(ar);
1821#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001822 ieee80211_wake_queue(ar->hw, i);
1823 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001824 }
1825 }
1826
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001827 if (schedule_garbagecollector)
1828 queue_delayed_work(ar->hw->workqueue,
1829 &ar->tx_janitor,
1830 msecs_to_jiffies(AR9170_JANITOR_DELAY));
1831}
1832
Christian Lamparteracbadf02009-07-11 17:24:14 +02001833static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb)
1834{
1835 struct ieee80211_tx_info *txinfo;
1836 struct ar9170_sta_info *sta_info;
1837 struct ar9170_sta_tid *agg;
1838 struct sk_buff *iter;
1839 unsigned long flags, f2;
1840 unsigned int max;
1841 u16 tid, seq, qseq;
1842 bool run = false, queue = false;
1843
1844 tid = ar9170_get_tid(skb);
1845 seq = ar9170_get_seq(skb);
1846 txinfo = IEEE80211_SKB_CB(skb);
1847 sta_info = (void *) txinfo->control.sta->drv_priv;
1848 agg = &sta_info->agg[tid];
1849 max = sta_info->ampdu_max_len;
1850
1851 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1852
1853 if (unlikely(agg->state != AR9170_TID_STATE_COMPLETE)) {
1854#ifdef AR9170_TXAGG_DEBUG
1855 printk(KERN_DEBUG "%s: BlockACK session not fully initialized "
1856 "for ESS:%pM tid:%d state:%d.\n",
1857 wiphy_name(ar->hw->wiphy), agg->addr, agg->tid,
1858 agg->state);
1859#endif /* AR9170_TXAGG_DEBUG */
1860 goto err_unlock;
1861 }
1862
1863 if (!agg->active) {
1864 agg->active = true;
1865 agg->ssn = seq;
1866 queue = true;
1867 }
1868
1869 /* check if seq is within the BA window */
1870 if (unlikely(!BAW_WITHIN(agg->ssn, max, seq))) {
1871#ifdef AR9170_TXAGG_DEBUG
1872 printk(KERN_DEBUG "%s: frame with tid:%d seq:%d does not "
1873 "fit into BA window (%d - %d)\n",
1874 wiphy_name(ar->hw->wiphy), tid, seq, agg->ssn,
1875 (agg->ssn + max) & 0xfff);
1876#endif /* AR9170_TXAGG_DEBUG */
1877 goto err_unlock;
1878 }
1879
1880 spin_lock_irqsave(&agg->queue.lock, f2);
1881
1882 skb_queue_reverse_walk(&agg->queue, iter) {
1883 qseq = ar9170_get_seq(iter);
1884
1885 if (GET_NEXT_SEQ(qseq) == seq) {
1886 __skb_queue_after(&agg->queue, iter, skb);
1887 goto queued;
1888 }
1889 }
1890
1891 __skb_queue_head(&agg->queue, skb);
1892
1893queued:
1894 spin_unlock_irqrestore(&agg->queue.lock, f2);
1895
1896#ifdef AR9170_TXAGG_DEBUG
1897 printk(KERN_DEBUG "%s: new aggregate %p queued.\n",
1898 wiphy_name(ar->hw->wiphy), skb);
1899 __ar9170_dump_txqueue(ar, &agg->queue);
1900#endif /* AR9170_TXAGG_DEBUG */
1901
1902 if (skb_queue_len(&agg->queue) >= AR9170_NUM_TX_AGG_MAX)
1903 run = true;
1904
1905 if (queue)
1906 list_add_tail(&agg->list, &ar->tx_ampdu_list);
1907
1908 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1909 return run;
1910
1911err_unlock:
1912 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1913 dev_kfree_skb_irq(skb);
1914 return false;
1915}
1916
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001917int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1918{
1919 struct ar9170 *ar = hw->priv;
1920 struct ieee80211_tx_info *info;
1921
1922 if (unlikely(!IS_STARTED(ar)))
1923 goto err_free;
1924
1925 if (unlikely(ar9170_tx_prepare(ar, skb)))
1926 goto err_free;
1927
1928 info = IEEE80211_SKB_CB(skb);
1929 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
Christian Lamparteracbadf02009-07-11 17:24:14 +02001930 bool run = ar9170_tx_ampdu_queue(ar, skb);
1931
1932 if (run || !ar->tx_ampdu_pending)
1933 ar9170_tx_ampdu(ar);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001934 } else {
1935 unsigned int queue = skb_get_queue_mapping(skb);
1936
1937 ar9170_tx_prepare_phy(ar, skb);
1938 skb_queue_tail(&ar->tx_pending[queue], skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001939 }
1940
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001941 ar9170_tx(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001942 return NETDEV_TX_OK;
1943
Christian Lampartere9348cd2009-03-21 23:05:13 +01001944err_free:
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001945 dev_kfree_skb_any(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001946 return NETDEV_TX_OK;
1947}
1948
1949static int ar9170_op_add_interface(struct ieee80211_hw *hw,
1950 struct ieee80211_if_init_conf *conf)
1951{
1952 struct ar9170 *ar = hw->priv;
1953 int err = 0;
1954
1955 mutex_lock(&ar->mutex);
1956
1957 if (ar->vif) {
1958 err = -EBUSY;
1959 goto unlock;
1960 }
1961
1962 ar->vif = conf->vif;
1963 memcpy(ar->mac_addr, conf->mac_addr, ETH_ALEN);
1964
1965 if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
1966 ar->rx_software_decryption = true;
1967 ar->disable_offload = true;
1968 }
1969
1970 ar->cur_filter = 0;
1971 ar->want_filter = AR9170_MAC_REG_FTF_DEFAULTS;
1972 err = ar9170_update_frame_filter(ar);
1973 if (err)
1974 goto unlock;
1975
1976 err = ar9170_set_operating_mode(ar);
1977
1978unlock:
1979 mutex_unlock(&ar->mutex);
1980 return err;
1981}
1982
1983static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
1984 struct ieee80211_if_init_conf *conf)
1985{
1986 struct ar9170 *ar = hw->priv;
1987
1988 mutex_lock(&ar->mutex);
1989 ar->vif = NULL;
1990 ar->want_filter = 0;
1991 ar9170_update_frame_filter(ar);
1992 ar9170_set_beacon_timers(ar);
1993 dev_kfree_skb(ar->beacon);
1994 ar->beacon = NULL;
1995 ar->sniffer_enabled = false;
1996 ar->rx_software_decryption = false;
1997 ar9170_set_operating_mode(ar);
1998 mutex_unlock(&ar->mutex);
1999}
2000
2001static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
2002{
2003 struct ar9170 *ar = hw->priv;
2004 int err = 0;
2005
2006 mutex_lock(&ar->mutex);
2007
Christian Lampartere9348cd2009-03-21 23:05:13 +01002008 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
2009 /* TODO */
2010 err = 0;
2011 }
2012
2013 if (changed & IEEE80211_CONF_CHANGE_PS) {
2014 /* TODO */
2015 err = 0;
2016 }
2017
2018 if (changed & IEEE80211_CONF_CHANGE_POWER) {
2019 /* TODO */
2020 err = 0;
2021 }
2022
2023 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
2024 /*
2025 * is it long_frame_max_tx_count or short_frame_max_tx_count?
2026 */
2027
2028 err = ar9170_set_hwretry_limit(ar,
2029 ar->hw->conf.long_frame_max_tx_count);
2030 if (err)
2031 goto out;
2032 }
2033
Johannes Berg57c4d7b2009-04-23 16:10:04 +02002034 if (changed & BSS_CHANGED_BEACON_INT) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002035 err = ar9170_set_beacon_timers(ar);
2036 if (err)
2037 goto out;
2038 }
2039
2040 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002041
2042 /* adjust slot time for 5 GHz */
2043 err = ar9170_set_slot_time(ar);
2044 if (err)
2045 goto out;
2046
2047 err = ar9170_set_dyn_sifs_ack(ar);
2048 if (err)
2049 goto out;
2050
Christian Lampartere9348cd2009-03-21 23:05:13 +01002051 err = ar9170_set_channel(ar, hw->conf.channel,
Johannes Berg9e52b06232009-04-20 18:27:04 +02002052 AR9170_RFI_NONE,
2053 nl80211_to_ar9170(hw->conf.channel_type));
Christian Lampartere9348cd2009-03-21 23:05:13 +01002054 if (err)
2055 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002056 }
2057
2058out:
2059 mutex_unlock(&ar->mutex);
2060 return err;
2061}
2062
Christian Lampartere9348cd2009-03-21 23:05:13 +01002063static void ar9170_set_filters(struct work_struct *work)
2064{
2065 struct ar9170 *ar = container_of(work, struct ar9170,
2066 filter_config_work);
2067 int err;
2068
Christian Lampartere9348cd2009-03-21 23:05:13 +01002069 if (unlikely(!IS_STARTED(ar)))
Christian Lamparter32c16282009-03-28 01:46:14 +01002070 return ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002071
Christian Lamparter32c16282009-03-28 01:46:14 +01002072 mutex_lock(&ar->mutex);
Christian Lamparter864cc022009-05-23 20:28:21 +02002073 if (test_and_clear_bit(AR9170_FILTER_CHANGED_MODE,
2074 &ar->filter_changed)) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002075 err = ar9170_set_operating_mode(ar);
2076 if (err)
2077 goto unlock;
2078 }
2079
Christian Lamparter864cc022009-05-23 20:28:21 +02002080 if (test_and_clear_bit(AR9170_FILTER_CHANGED_MULTICAST,
2081 &ar->filter_changed)) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002082 err = ar9170_update_multicast(ar);
2083 if (err)
2084 goto unlock;
2085 }
2086
Christian Lamparter864cc022009-05-23 20:28:21 +02002087 if (test_and_clear_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
2088 &ar->filter_changed)) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002089 err = ar9170_update_frame_filter(ar);
Christian Lamparter864cc022009-05-23 20:28:21 +02002090 if (err)
2091 goto unlock;
2092 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01002093
2094unlock:
2095 mutex_unlock(&ar->mutex);
2096}
2097
2098static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
2099 unsigned int changed_flags,
2100 unsigned int *new_flags,
2101 int mc_count, struct dev_mc_list *mclist)
2102{
2103 struct ar9170 *ar = hw->priv;
2104
2105 /* mask supported flags */
2106 *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
Christian Lampartercca847992009-04-19 01:28:12 +02002107 FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
2108 ar->filter_state = *new_flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002109 /*
2110 * We can support more by setting the sniffer bit and
2111 * then checking the error flags, later.
2112 */
2113
2114 if (changed_flags & FIF_ALLMULTI) {
2115 if (*new_flags & FIF_ALLMULTI) {
2116 ar->want_mc_hash = ~0ULL;
2117 } else {
2118 u64 mchash;
2119 int i;
2120
2121 /* always get broadcast frames */
Christian Lamparter864cc022009-05-23 20:28:21 +02002122 mchash = 1ULL << (0xff >> 2);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002123
2124 for (i = 0; i < mc_count; i++) {
2125 if (WARN_ON(!mclist))
2126 break;
2127 mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
2128 mclist = mclist->next;
2129 }
2130 ar->want_mc_hash = mchash;
2131 }
Christian Lamparter864cc022009-05-23 20:28:21 +02002132 set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002133 }
2134
2135 if (changed_flags & FIF_CONTROL) {
2136 u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
2137 AR9170_MAC_REG_FTF_RTS |
2138 AR9170_MAC_REG_FTF_CTS |
2139 AR9170_MAC_REG_FTF_ACK |
2140 AR9170_MAC_REG_FTF_CFE |
2141 AR9170_MAC_REG_FTF_CFE_ACK;
2142
2143 if (*new_flags & FIF_CONTROL)
2144 ar->want_filter = ar->cur_filter | filter;
2145 else
2146 ar->want_filter = ar->cur_filter & ~filter;
2147
Christian Lamparter864cc022009-05-23 20:28:21 +02002148 set_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
2149 &ar->filter_changed);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002150 }
2151
2152 if (changed_flags & FIF_PROMISC_IN_BSS) {
2153 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
Christian Lamparter864cc022009-05-23 20:28:21 +02002154 set_bit(AR9170_FILTER_CHANGED_MODE,
2155 &ar->filter_changed);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002156 }
2157
2158 if (likely(IS_STARTED(ar)))
2159 queue_work(ar->hw->workqueue, &ar->filter_config_work);
2160}
2161
2162static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
2163 struct ieee80211_vif *vif,
2164 struct ieee80211_bss_conf *bss_conf,
2165 u32 changed)
2166{
2167 struct ar9170 *ar = hw->priv;
2168 int err = 0;
2169
2170 mutex_lock(&ar->mutex);
2171
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002172 if (changed & BSS_CHANGED_BSSID) {
2173 memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN);
2174 err = ar9170_set_operating_mode(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02002175 if (err)
2176 goto out;
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002177 }
2178
2179 if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) {
2180 err = ar9170_update_beacon(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02002181 if (err)
2182 goto out;
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002183
Christian Lamparter29ceff52009-06-01 21:42:01 +02002184 err = ar9170_set_beacon_timers(ar);
2185 if (err)
2186 goto out;
2187 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01002188
2189 if (changed & BSS_CHANGED_ASSOC) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002190#ifndef CONFIG_AR9170_LEDS
2191 /* enable assoc LED. */
2192 err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
2193#endif /* CONFIG_AR9170_LEDS */
2194 }
2195
Christian Lamparter29ceff52009-06-01 21:42:01 +02002196 if (changed & BSS_CHANGED_BEACON_INT) {
Johannes Berg57c4d7b2009-04-23 16:10:04 +02002197 err = ar9170_set_beacon_timers(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02002198 if (err)
2199 goto out;
2200 }
Johannes Berg57c4d7b2009-04-23 16:10:04 +02002201
Christian Lampartere9348cd2009-03-21 23:05:13 +01002202 if (changed & BSS_CHANGED_HT) {
2203 /* TODO */
2204 err = 0;
2205 }
2206
2207 if (changed & BSS_CHANGED_ERP_SLOT) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002208 err = ar9170_set_slot_time(ar);
2209 if (err)
2210 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002211 }
2212
2213 if (changed & BSS_CHANGED_BASIC_RATES) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002214 err = ar9170_set_basic_rates(ar);
2215 if (err)
2216 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002217 }
2218
Christian Lamparter29ceff52009-06-01 21:42:01 +02002219out:
Christian Lampartere9348cd2009-03-21 23:05:13 +01002220 mutex_unlock(&ar->mutex);
2221}
2222
2223static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
2224{
2225 struct ar9170 *ar = hw->priv;
2226 int err;
2227 u32 tsf_low;
2228 u32 tsf_high;
2229 u64 tsf;
2230
2231 mutex_lock(&ar->mutex);
2232 err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low);
2233 if (!err)
2234 err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high);
2235 mutex_unlock(&ar->mutex);
2236
2237 if (WARN_ON(err))
2238 return 0;
2239
2240 tsf = tsf_high;
2241 tsf = (tsf << 32) | tsf_low;
2242 return tsf;
2243}
2244
2245static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2246 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
2247 struct ieee80211_key_conf *key)
2248{
2249 struct ar9170 *ar = hw->priv;
2250 int err = 0, i;
2251 u8 ktype;
2252
2253 if ((!ar->vif) || (ar->disable_offload))
2254 return -EOPNOTSUPP;
2255
2256 switch (key->alg) {
2257 case ALG_WEP:
Zhu Yie31a16d2009-05-21 21:47:03 +08002258 if (key->keylen == WLAN_KEY_LEN_WEP40)
Christian Lampartere9348cd2009-03-21 23:05:13 +01002259 ktype = AR9170_ENC_ALG_WEP64;
2260 else
2261 ktype = AR9170_ENC_ALG_WEP128;
2262 break;
2263 case ALG_TKIP:
2264 ktype = AR9170_ENC_ALG_TKIP;
2265 break;
2266 case ALG_CCMP:
2267 ktype = AR9170_ENC_ALG_AESCCMP;
2268 break;
2269 default:
2270 return -EOPNOTSUPP;
2271 }
2272
2273 mutex_lock(&ar->mutex);
2274 if (cmd == SET_KEY) {
2275 if (unlikely(!IS_STARTED(ar))) {
2276 err = -EOPNOTSUPP;
2277 goto out;
2278 }
2279
2280 /* group keys need all-zeroes address */
2281 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
2282 sta = NULL;
2283
2284 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
2285 for (i = 0; i < 64; i++)
2286 if (!(ar->usedkeys & BIT(i)))
2287 break;
2288 if (i == 64) {
2289 ar->rx_software_decryption = true;
2290 ar9170_set_operating_mode(ar);
2291 err = -ENOSPC;
2292 goto out;
2293 }
2294 } else {
2295 i = 64 + key->keyidx;
2296 }
2297
2298 key->hw_key_idx = i;
2299
2300 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
2301 key->key, min_t(u8, 16, key->keylen));
2302 if (err)
2303 goto out;
2304
2305 if (key->alg == ALG_TKIP) {
2306 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
2307 ktype, 1, key->key + 16, 16);
2308 if (err)
2309 goto out;
2310
2311 /*
2312 * hardware is not capable generating the MMIC
2313 * for fragmented frames!
2314 */
2315 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
2316 }
2317
2318 if (i < 64)
2319 ar->usedkeys |= BIT(i);
2320
2321 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
2322 } else {
2323 if (unlikely(!IS_STARTED(ar))) {
2324 /* The device is gone... together with the key ;-) */
2325 err = 0;
2326 goto out;
2327 }
2328
2329 err = ar9170_disable_key(ar, key->hw_key_idx);
2330 if (err)
2331 goto out;
2332
2333 if (key->hw_key_idx < 64) {
2334 ar->usedkeys &= ~BIT(key->hw_key_idx);
2335 } else {
2336 err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
2337 AR9170_ENC_ALG_NONE, 0,
2338 NULL, 0);
2339 if (err)
2340 goto out;
2341
2342 if (key->alg == ALG_TKIP) {
2343 err = ar9170_upload_key(ar, key->hw_key_idx,
2344 NULL,
2345 AR9170_ENC_ALG_NONE, 1,
2346 NULL, 0);
2347 if (err)
2348 goto out;
2349 }
2350
2351 }
2352 }
2353
2354 ar9170_regwrite_begin(ar);
2355 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
2356 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
2357 ar9170_regwrite_finish();
2358 err = ar9170_regwrite_result();
2359
2360out:
2361 mutex_unlock(&ar->mutex);
2362
2363 return err;
2364}
2365
2366static void ar9170_sta_notify(struct ieee80211_hw *hw,
2367 struct ieee80211_vif *vif,
2368 enum sta_notify_cmd cmd,
2369 struct ieee80211_sta *sta)
2370{
Christian Lamparteracbadf02009-07-11 17:24:14 +02002371 struct ar9170 *ar = hw->priv;
2372 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2373 unsigned int i;
2374
2375 switch (cmd) {
2376 case STA_NOTIFY_ADD:
2377 memset(sta_info, 0, sizeof(*sta_info));
2378
2379 if (!sta->ht_cap.ht_supported)
2380 break;
2381
2382 if (sta->ht_cap.ampdu_density > ar->global_ampdu_density)
2383 ar->global_ampdu_density = sta->ht_cap.ampdu_density;
2384
2385 if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor)
2386 ar->global_ampdu_factor = sta->ht_cap.ampdu_factor;
2387
2388 for (i = 0; i < AR9170_NUM_TID; i++) {
2389 sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN;
2390 sta_info->agg[i].active = false;
2391 sta_info->agg[i].ssn = 0;
2392 sta_info->agg[i].retry = 0;
2393 sta_info->agg[i].tid = i;
2394 INIT_LIST_HEAD(&sta_info->agg[i].list);
2395 skb_queue_head_init(&sta_info->agg[i].queue);
2396 }
2397
2398 sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor);
2399 break;
2400
2401 case STA_NOTIFY_REMOVE:
2402 if (!sta->ht_cap.ht_supported)
2403 break;
2404
2405 for (i = 0; i < AR9170_NUM_TID; i++) {
2406 sta_info->agg[i].state = AR9170_TID_STATE_INVALID;
2407 skb_queue_purge(&sta_info->agg[i].queue);
2408 }
2409
2410 break;
2411
2412 default:
2413 break;
2414 }
2415
2416 if (IS_STARTED(ar) && ar->filter_changed)
2417 queue_work(ar->hw->workqueue, &ar->filter_config_work);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002418}
2419
2420static int ar9170_get_stats(struct ieee80211_hw *hw,
2421 struct ieee80211_low_level_stats *stats)
2422{
2423 struct ar9170 *ar = hw->priv;
2424 u32 val;
2425 int err;
2426
2427 mutex_lock(&ar->mutex);
2428 err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
2429 ar->stats.dot11ACKFailureCount += val;
2430
2431 memcpy(stats, &ar->stats, sizeof(*stats));
2432 mutex_unlock(&ar->mutex);
2433
2434 return 0;
2435}
2436
2437static int ar9170_get_tx_stats(struct ieee80211_hw *hw,
2438 struct ieee80211_tx_queue_stats *tx_stats)
2439{
2440 struct ar9170 *ar = hw->priv;
2441
2442 spin_lock_bh(&ar->tx_stats_lock);
2443 memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues);
2444 spin_unlock_bh(&ar->tx_stats_lock);
2445
2446 return 0;
2447}
2448
2449static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
2450 const struct ieee80211_tx_queue_params *param)
2451{
2452 struct ar9170 *ar = hw->priv;
2453 int ret;
2454
2455 mutex_lock(&ar->mutex);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002456 if ((param) && !(queue > __AR9170_NUM_TXQ)) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002457 memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
2458 param, sizeof(*param));
2459
2460 ret = ar9170_set_qos(ar);
2461 } else
2462 ret = -EINVAL;
2463
2464 mutex_unlock(&ar->mutex);
2465 return ret;
2466}
2467
Johannes Berg9e52b06232009-04-20 18:27:04 +02002468static int ar9170_ampdu_action(struct ieee80211_hw *hw,
2469 enum ieee80211_ampdu_mlme_action action,
2470 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
2471{
Christian Lamparteracbadf02009-07-11 17:24:14 +02002472 struct ar9170 *ar = hw->priv;
2473 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2474 struct ar9170_sta_tid *tid_info = &sta_info->agg[tid];
2475 unsigned long flags;
2476
2477 if (!modparam_ht)
2478 return -EOPNOTSUPP;
2479
Johannes Berg9e52b06232009-04-20 18:27:04 +02002480 switch (action) {
Christian Lamparteracbadf02009-07-11 17:24:14 +02002481 case IEEE80211_AMPDU_TX_START:
2482 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2483 if (tid_info->state != AR9170_TID_STATE_SHUTDOWN ||
2484 !list_empty(&tid_info->list)) {
2485 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2486#ifdef AR9170_TXAGG_DEBUG
2487 printk(KERN_INFO "%s: A-MPDU [ESS:[%pM] tid:[%d]] "
2488 "is in a very bad state!\n",
2489 wiphy_name(hw->wiphy), sta->addr, tid);
2490#endif /* AR9170_TXAGG_DEBUG */
2491 return -EBUSY;
2492 }
2493
2494 *ssn = tid_info->ssn;
2495 tid_info->state = AR9170_TID_STATE_PROGRESS;
2496 tid_info->active = false;
2497 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2498 ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
2499 break;
2500
2501 case IEEE80211_AMPDU_TX_STOP:
2502 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2503 tid_info->state = AR9170_TID_STATE_SHUTDOWN;
2504 list_del_init(&tid_info->list);
2505 tid_info->active = false;
2506 skb_queue_purge(&tid_info->queue);
2507 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2508 ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
2509 break;
2510
2511 case IEEE80211_AMPDU_TX_OPERATIONAL:
2512#ifdef AR9170_TXAGG_DEBUG
2513 printk(KERN_INFO "%s: A-MPDU for %pM [tid:%d] Operational.\n",
2514 wiphy_name(hw->wiphy), sta->addr, tid);
2515#endif /* AR9170_TXAGG_DEBUG */
2516 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2517 sta_info->agg[tid].state = AR9170_TID_STATE_COMPLETE;
2518 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2519 break;
2520
Johannes Berg9e52b06232009-04-20 18:27:04 +02002521 case IEEE80211_AMPDU_RX_START:
2522 case IEEE80211_AMPDU_RX_STOP:
Christian Lamparteracbadf02009-07-11 17:24:14 +02002523 /* Handled by firmware */
2524 break;
2525
Johannes Berg9e52b06232009-04-20 18:27:04 +02002526 default:
2527 return -EOPNOTSUPP;
2528 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02002529
2530 return 0;
Johannes Berg9e52b06232009-04-20 18:27:04 +02002531}
2532
Christian Lampartere9348cd2009-03-21 23:05:13 +01002533static const struct ieee80211_ops ar9170_ops = {
2534 .start = ar9170_op_start,
2535 .stop = ar9170_op_stop,
2536 .tx = ar9170_op_tx,
2537 .add_interface = ar9170_op_add_interface,
2538 .remove_interface = ar9170_op_remove_interface,
2539 .config = ar9170_op_config,
Christian Lampartere9348cd2009-03-21 23:05:13 +01002540 .configure_filter = ar9170_op_configure_filter,
2541 .conf_tx = ar9170_conf_tx,
2542 .bss_info_changed = ar9170_op_bss_info_changed,
2543 .get_tsf = ar9170_op_get_tsf,
2544 .set_key = ar9170_set_key,
2545 .sta_notify = ar9170_sta_notify,
2546 .get_stats = ar9170_get_stats,
2547 .get_tx_stats = ar9170_get_tx_stats,
Johannes Berg9e52b06232009-04-20 18:27:04 +02002548 .ampdu_action = ar9170_ampdu_action,
Christian Lampartere9348cd2009-03-21 23:05:13 +01002549};
2550
2551void *ar9170_alloc(size_t priv_size)
2552{
2553 struct ieee80211_hw *hw;
2554 struct ar9170 *ar;
Christian Lampartercca847992009-04-19 01:28:12 +02002555 struct sk_buff *skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002556 int i;
2557
Christian Lampartercca847992009-04-19 01:28:12 +02002558 /*
2559 * this buffer is used for rx stream reconstruction.
2560 * Under heavy load this device (or the transport layer?)
2561 * tends to split the streams into seperate rx descriptors.
2562 */
2563
2564 skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL);
2565 if (!skb)
2566 goto err_nomem;
2567
Christian Lampartere9348cd2009-03-21 23:05:13 +01002568 hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
2569 if (!hw)
Christian Lampartercca847992009-04-19 01:28:12 +02002570 goto err_nomem;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002571
2572 ar = hw->priv;
2573 ar->hw = hw;
Christian Lampartercca847992009-04-19 01:28:12 +02002574 ar->rx_failover = skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002575
2576 mutex_init(&ar->mutex);
2577 spin_lock_init(&ar->cmdlock);
2578 spin_lock_init(&ar->tx_stats_lock);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002579 spin_lock_init(&ar->tx_ampdu_list_lock);
2580 skb_queue_head_init(&ar->tx_status_ampdu);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002581 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
2582 skb_queue_head_init(&ar->tx_status[i]);
2583 skb_queue_head_init(&ar->tx_pending[i]);
2584 }
Christian Lampartercca847992009-04-19 01:28:12 +02002585 ar9170_rx_reset_rx_mpdu(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002586 INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
2587 INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002588 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002589 INIT_LIST_HEAD(&ar->tx_ampdu_list);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002590
2591 /* all hw supports 2.4 GHz, so set channel to 1 by default */
2592 ar->channel = &ar9170_2ghz_chantable[0];
2593
2594 /* first part of wiphy init */
2595 ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2596 BIT(NL80211_IFTYPE_WDS) |
2597 BIT(NL80211_IFTYPE_ADHOC);
2598 ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
2599 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
2600 IEEE80211_HW_SIGNAL_DBM |
2601 IEEE80211_HW_NOISE_DBM;
2602
Christian Lamparteracbadf02009-07-11 17:24:14 +02002603 if (modparam_ht) {
2604 ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
2605 } else {
2606 ar9170_band_2GHz.ht_cap.ht_supported = false;
2607 ar9170_band_5GHz.ht_cap.ht_supported = false;
2608 }
2609
Christian Lamparter4a48e2a2009-03-23 12:15:43 +01002610 ar->hw->queues = __AR9170_NUM_TXQ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002611 ar->hw->extra_tx_headroom = 8;
2612 ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
2613
2614 ar->hw->max_rates = 1;
2615 ar->hw->max_rate_tries = 3;
2616
2617 for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
2618 ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
2619
2620 return ar;
Christian Lampartercca847992009-04-19 01:28:12 +02002621
2622err_nomem:
2623 kfree_skb(skb);
2624 return ERR_PTR(-ENOMEM);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002625}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002626
2627static int ar9170_read_eeprom(struct ar9170 *ar)
2628{
2629#define RW 8 /* number of words to read at once */
2630#define RB (sizeof(u32) * RW)
2631 DECLARE_MAC_BUF(mbuf);
2632 u8 *eeprom = (void *)&ar->eeprom;
2633 u8 *addr = ar->eeprom.mac_address;
2634 __le32 offsets[RW];
Christian Lamparteracbadf02009-07-11 17:24:14 +02002635 unsigned int rx_streams, tx_streams, tx_params = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002636 int i, j, err, bands = 0;
2637
2638 BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
2639
2640 BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
2641#ifndef __CHECKER__
2642 /* don't want to handle trailing remains */
2643 BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
2644#endif
2645
2646 for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
2647 for (j = 0; j < RW; j++)
2648 offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
2649 RB * i + 4 * j);
2650
2651 err = ar->exec_cmd(ar, AR9170_CMD_RREG,
2652 RB, (u8 *) &offsets,
2653 RB, eeprom + RB * i);
2654 if (err)
2655 return err;
2656 }
2657
2658#undef RW
2659#undef RB
2660
2661 if (ar->eeprom.length == cpu_to_le16(0xFFFF))
2662 return -ENODATA;
2663
2664 if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
2665 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
2666 bands++;
2667 }
2668 if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
2669 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
2670 bands++;
2671 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02002672
2673 rx_streams = hweight8(ar->eeprom.rx_mask);
2674 tx_streams = hweight8(ar->eeprom.tx_mask);
2675
2676 if (rx_streams != tx_streams)
2677 tx_params = IEEE80211_HT_MCS_TX_RX_DIFF;
2678
2679 if (tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS)
2680 tx_params = (tx_streams - 1) <<
2681 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
2682
2683 ar9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
2684 ar9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params;
2685
Christian Lampartere9348cd2009-03-21 23:05:13 +01002686 /*
2687 * I measured this, a bandswitch takes roughly
2688 * 135 ms and a frequency switch about 80.
2689 *
2690 * FIXME: measure these values again once EEPROM settings
2691 * are used, that will influence them!
2692 */
2693 if (bands == 2)
2694 ar->hw->channel_change_time = 135 * 1000;
2695 else
2696 ar->hw->channel_change_time = 80 * 1000;
2697
Christian Lamparter1878f772009-03-30 22:30:32 -04002698 ar->regulatory.current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
2699 ar->regulatory.current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
2700
Christian Lampartere9348cd2009-03-21 23:05:13 +01002701 /* second part of wiphy init */
2702 SET_IEEE80211_PERM_ADDR(ar->hw, addr);
2703
2704 return bands ? 0 : -EINVAL;
2705}
2706
Christian Lamparter1878f772009-03-30 22:30:32 -04002707static int ar9170_reg_notifier(struct wiphy *wiphy,
2708 struct regulatory_request *request)
2709{
2710 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2711 struct ar9170 *ar = hw->priv;
2712
2713 return ath_reg_notifier_apply(wiphy, request, &ar->regulatory);
2714}
2715
Christian Lampartere9348cd2009-03-21 23:05:13 +01002716int ar9170_register(struct ar9170 *ar, struct device *pdev)
2717{
2718 int err;
2719
2720 /* try to read EEPROM, init MAC addr */
2721 err = ar9170_read_eeprom(ar);
2722 if (err)
2723 goto err_out;
2724
Christian Lamparter1878f772009-03-30 22:30:32 -04002725 err = ath_regd_init(&ar->regulatory, ar->hw->wiphy,
2726 ar9170_reg_notifier);
Luis R. Rodriguez85efc862009-04-13 21:41:46 -04002727 if (err)
2728 goto err_out;
Christian Lamparter1878f772009-03-30 22:30:32 -04002729
Christian Lampartere9348cd2009-03-21 23:05:13 +01002730 err = ieee80211_register_hw(ar->hw);
2731 if (err)
2732 goto err_out;
2733
Christian Lamparter1878f772009-03-30 22:30:32 -04002734 if (!ath_is_world_regd(&ar->regulatory))
2735 regulatory_hint(ar->hw->wiphy, ar->regulatory.alpha2);
2736
Christian Lampartere9348cd2009-03-21 23:05:13 +01002737 err = ar9170_init_leds(ar);
2738 if (err)
2739 goto err_unreg;
2740
2741#ifdef CONFIG_AR9170_LEDS
2742 err = ar9170_register_leds(ar);
2743 if (err)
2744 goto err_unreg;
2745#endif /* CONFIG_AR9170_LEDS */
2746
2747 dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
2748 wiphy_name(ar->hw->wiphy));
2749
2750 return err;
2751
2752err_unreg:
2753 ieee80211_unregister_hw(ar->hw);
2754
2755err_out:
2756 return err;
2757}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002758
2759void ar9170_unregister(struct ar9170 *ar)
2760{
2761#ifdef CONFIG_AR9170_LEDS
2762 ar9170_unregister_leds(ar);
2763#endif /* CONFIG_AR9170_LEDS */
2764
Christian Lampartercca847992009-04-19 01:28:12 +02002765 kfree_skb(ar->rx_failover);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002766 ieee80211_unregister_hw(ar->hw);
2767 mutex_destroy(&ar->mutex);
2768}