blob: 85a1452a7c3c30707f67b8f2df6d37b95405f20b [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);
Alexander Beregalovff8365c2009-07-24 11:55:44 +04001296#ifdef CONFIG_AR9170_LEDS
Christian Lamparteracbadf02009-07-11 17:24:14 +02001297 cancel_delayed_work_sync(&ar->led_work);
Alexander Beregalovff8365c2009-07-24 11:55:44 +04001298#endif
Christian Lampartere9348cd2009-03-21 23:05:13 +01001299 cancel_work_sync(&ar->filter_config_work);
1300 cancel_work_sync(&ar->beacon_work);
Christian Lamparterb55d6bc2009-05-23 20:31:21 +02001301 mutex_lock(&ar->mutex);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001302
1303 if (IS_ACCEPTING_CMD(ar)) {
1304 ar9170_set_leds_state(ar, 0);
1305
1306 /* stop DMA */
1307 ar9170_write_reg(ar, 0x1c3d30, 0);
1308 ar->stop(ar);
1309 }
1310
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001311 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1312 skb_queue_purge(&ar->tx_pending[i]);
1313 skb_queue_purge(&ar->tx_status[i]);
1314 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02001315 skb_queue_purge(&ar->tx_status_ampdu);
1316
Christian Lampartere9348cd2009-03-21 23:05:13 +01001317 mutex_unlock(&ar->mutex);
1318}
1319
Christian Lamparteracbadf02009-07-11 17:24:14 +02001320static void ar9170_tx_indicate_immba(struct ar9170 *ar, struct sk_buff *skb)
1321{
1322 struct ar9170_tx_control *txc = (void *) skb->data;
1323
1324 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_IMM_AMPDU);
1325}
1326
1327static void ar9170_tx_copy_phy(struct ar9170 *ar, struct sk_buff *dst,
1328 struct sk_buff *src)
1329{
1330 struct ar9170_tx_control *dst_txc, *src_txc;
1331 struct ieee80211_tx_info *dst_info, *src_info;
1332 struct ar9170_tx_info *dst_arinfo, *src_arinfo;
1333
1334 src_txc = (void *) src->data;
1335 src_info = IEEE80211_SKB_CB(src);
1336 src_arinfo = (void *) src_info->rate_driver_data;
1337
1338 dst_txc = (void *) dst->data;
1339 dst_info = IEEE80211_SKB_CB(dst);
1340 dst_arinfo = (void *) dst_info->rate_driver_data;
1341
1342 dst_txc->phy_control = src_txc->phy_control;
1343
1344 /* same MCS for the whole aggregate */
1345 memcpy(dst_info->driver_rates, src_info->driver_rates,
1346 sizeof(dst_info->driver_rates));
1347}
1348
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001349static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001350{
Christian Lampartere9348cd2009-03-21 23:05:13 +01001351 struct ieee80211_hdr *hdr;
1352 struct ar9170_tx_control *txc;
1353 struct ieee80211_tx_info *info;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001354 struct ieee80211_tx_rate *txrate;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001355 struct ar9170_tx_info *arinfo;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001356 unsigned int queue = skb_get_queue_mapping(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001357 u16 keytype = 0;
1358 u16 len, icv = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001359
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001360 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001361
1362 hdr = (void *)skb->data;
1363 info = IEEE80211_SKB_CB(skb);
1364 len = skb->len;
1365
Christian Lampartere9348cd2009-03-21 23:05:13 +01001366 txc = (void *)skb_push(skb, sizeof(*txc));
1367
Christian Lampartere9348cd2009-03-21 23:05:13 +01001368 if (info->control.hw_key) {
1369 icv = info->control.hw_key->icv_len;
1370
1371 switch (info->control.hw_key->alg) {
1372 case ALG_WEP:
1373 keytype = AR9170_TX_MAC_ENCR_RC4;
1374 break;
1375 case ALG_TKIP:
1376 keytype = AR9170_TX_MAC_ENCR_RC4;
1377 break;
1378 case ALG_CCMP:
1379 keytype = AR9170_TX_MAC_ENCR_AES;
1380 break;
1381 default:
1382 WARN_ON(1);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001383 goto err_out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001384 }
1385 }
1386
1387 /* Length */
1388 txc->length = cpu_to_le16(len + icv + 4);
1389
1390 txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
1391 AR9170_TX_MAC_BACKOFF);
1392 txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
1393 AR9170_TX_MAC_QOS_SHIFT);
1394 txc->mac_control |= cpu_to_le16(keytype);
1395 txc->phy_control = cpu_to_le32(0);
1396
1397 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
1398 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
1399
Christian Lampartere9348cd2009-03-21 23:05:13 +01001400 txrate = &info->control.rates[0];
Christian Lampartere9348cd2009-03-21 23:05:13 +01001401 if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1402 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
1403 else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1404 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
1405
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001406 arinfo = (void *)info->rate_driver_data;
1407 arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT);
1408
1409 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
1410 (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
1411 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1412 if (unlikely(!info->control.sta))
1413 goto err_out;
1414
1415 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
1416 arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK;
Christian Lamparteracbadf02009-07-11 17:24:14 +02001417
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001418 goto out;
1419 }
1420
1421 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
1422 /*
1423 * WARNING:
1424 * Putting the QoS queue bits into an unexplored territory is
1425 * certainly not elegant.
1426 *
1427 * In my defense: This idea provides a reasonable way to
1428 * smuggle valuable information to the tx_status callback.
1429 * Also, the idea behind this bit-abuse came straight from
1430 * the original driver code.
1431 */
1432
1433 txc->phy_control |=
1434 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
1435 arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK;
1436 } else {
1437 arinfo->flags = AR9170_TX_FLAG_NO_ACK;
1438 }
1439
1440out:
1441 return 0;
1442
1443err_out:
1444 skb_pull(skb, sizeof(*txc));
1445 return -EINVAL;
1446}
1447
1448static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
1449{
1450 struct ar9170_tx_control *txc;
1451 struct ieee80211_tx_info *info;
1452 struct ieee80211_rate *rate = NULL;
1453 struct ieee80211_tx_rate *txrate;
1454 u32 power, chains;
1455
1456 txc = (void *) skb->data;
1457 info = IEEE80211_SKB_CB(skb);
1458 txrate = &info->control.rates[0];
1459
Christian Lampartere9348cd2009-03-21 23:05:13 +01001460 if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
1461 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
1462
1463 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1464 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
1465
1466 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1467 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
1468 /* this works because 40 MHz is 2 and dup is 3 */
1469 if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
1470 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
1471
1472 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
1473 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
1474
1475 if (txrate->flags & IEEE80211_TX_RC_MCS) {
1476 u32 r = txrate->idx;
1477 u8 *txpower;
1478
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001479 /* heavy clip control */
1480 txc->phy_control |= cpu_to_le32((r & 0x7) << 7);
1481
Christian Lampartere9348cd2009-03-21 23:05:13 +01001482 r <<= AR9170_TX_PHY_MCS_SHIFT;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001483 BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK);
1484
Christian Lampartere9348cd2009-03-21 23:05:13 +01001485 txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
1486 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
1487
1488 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1489 if (info->band == IEEE80211_BAND_5GHZ)
1490 txpower = ar->power_5G_ht40;
1491 else
1492 txpower = ar->power_2G_ht40;
1493 } else {
1494 if (info->band == IEEE80211_BAND_5GHZ)
1495 txpower = ar->power_5G_ht20;
1496 else
1497 txpower = ar->power_2G_ht20;
1498 }
1499
1500 power = txpower[(txrate->idx) & 7];
1501 } else {
1502 u8 *txpower;
1503 u32 mod;
1504 u32 phyrate;
1505 u8 idx = txrate->idx;
1506
1507 if (info->band != IEEE80211_BAND_2GHZ) {
1508 idx += 4;
1509 txpower = ar->power_5G_leg;
1510 mod = AR9170_TX_PHY_MOD_OFDM;
1511 } else {
1512 if (idx < 4) {
1513 txpower = ar->power_2G_cck;
1514 mod = AR9170_TX_PHY_MOD_CCK;
1515 } else {
1516 mod = AR9170_TX_PHY_MOD_OFDM;
1517 txpower = ar->power_2G_ofdm;
1518 }
1519 }
1520
1521 rate = &__ar9170_ratetable[idx];
1522
1523 phyrate = rate->hw_value & 0xF;
1524 power = txpower[(rate->hw_value & 0x30) >> 4];
1525 phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
1526
1527 txc->phy_control |= cpu_to_le32(mod);
1528 txc->phy_control |= cpu_to_le32(phyrate);
1529 }
1530
1531 power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
1532 power &= AR9170_TX_PHY_TX_PWR_MASK;
1533 txc->phy_control |= cpu_to_le32(power);
1534
1535 /* set TX chains */
1536 if (ar->eeprom.tx_mask == 1) {
1537 chains = AR9170_TX_PHY_TXCHAIN_1;
1538 } else {
1539 chains = AR9170_TX_PHY_TXCHAIN_2;
1540
1541 /* >= 36M legacy OFDM - use only one chain */
1542 if (rate && rate->bitrate >= 360)
1543 chains = AR9170_TX_PHY_TXCHAIN_1;
1544 }
1545 txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001546}
Christian Lampartere9348cd2009-03-21 23:05:13 +01001547
Christian Lamparteracbadf02009-07-11 17:24:14 +02001548static bool ar9170_tx_ampdu(struct ar9170 *ar)
1549{
1550 struct sk_buff_head agg;
1551 struct ar9170_sta_tid *tid_info = NULL, *tmp;
1552 struct sk_buff *skb, *first = NULL;
1553 unsigned long flags, f2;
1554 unsigned int i = 0;
1555 u16 seq, queue, tmpssn;
1556 bool run = false;
1557
1558 skb_queue_head_init(&agg);
1559
1560 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1561 if (list_empty(&ar->tx_ampdu_list)) {
1562#ifdef AR9170_TXAGG_DEBUG
1563 printk(KERN_DEBUG "%s: aggregation list is empty.\n",
1564 wiphy_name(ar->hw->wiphy));
1565#endif /* AR9170_TXAGG_DEBUG */
1566 goto out_unlock;
1567 }
1568
1569 list_for_each_entry_safe(tid_info, tmp, &ar->tx_ampdu_list, list) {
1570 if (tid_info->state != AR9170_TID_STATE_COMPLETE) {
1571#ifdef AR9170_TXAGG_DEBUG
1572 printk(KERN_DEBUG "%s: dangling aggregation entry!\n",
1573 wiphy_name(ar->hw->wiphy));
1574#endif /* AR9170_TXAGG_DEBUG */
1575 continue;
1576 }
1577
1578 if (++i > 64) {
1579#ifdef AR9170_TXAGG_DEBUG
1580 printk(KERN_DEBUG "%s: enough frames aggregated.\n",
1581 wiphy_name(ar->hw->wiphy));
1582#endif /* AR9170_TXAGG_DEBUG */
1583 break;
1584 }
1585
1586 queue = TID_TO_WME_AC(tid_info->tid);
1587
1588 if (skb_queue_len(&ar->tx_pending[queue]) >=
1589 AR9170_NUM_TX_AGG_MAX) {
1590#ifdef AR9170_TXAGG_DEBUG
1591 printk(KERN_DEBUG "%s: queue %d full.\n",
1592 wiphy_name(ar->hw->wiphy), queue);
1593#endif /* AR9170_TXAGG_DEBUG */
1594 continue;
1595 }
1596
1597 list_del_init(&tid_info->list);
1598
1599 spin_lock_irqsave(&tid_info->queue.lock, f2);
1600 tmpssn = seq = tid_info->ssn;
1601 first = skb_peek(&tid_info->queue);
1602
1603 if (likely(first))
1604 tmpssn = ar9170_get_seq(first);
1605
1606 if (unlikely(tmpssn != seq)) {
1607#ifdef AR9170_TXAGG_DEBUG
1608 printk(KERN_DEBUG "%s: ssn mismatch [%d != %d]\n.",
1609 wiphy_name(ar->hw->wiphy), seq, tmpssn);
1610#endif /* AR9170_TXAGG_DEBUG */
1611 tid_info->ssn = tmpssn;
1612 }
1613
1614#ifdef AR9170_TXAGG_DEBUG
1615 printk(KERN_DEBUG "%s: generate A-MPDU for tid:%d ssn:%d with "
1616 "%d queued frames.\n", wiphy_name(ar->hw->wiphy),
1617 tid_info->tid, tid_info->ssn,
1618 skb_queue_len(&tid_info->queue));
1619 __ar9170_dump_txqueue(ar, &tid_info->queue);
1620#endif /* AR9170_TXAGG_DEBUG */
1621
1622 while ((skb = skb_peek(&tid_info->queue))) {
1623 if (unlikely(ar9170_get_seq(skb) != seq))
1624 break;
1625
1626 __skb_unlink(skb, &tid_info->queue);
1627 tid_info->ssn = seq = GET_NEXT_SEQ(seq);
1628
1629 if (unlikely(skb_get_queue_mapping(skb) != queue)) {
1630#ifdef AR9170_TXAGG_DEBUG
1631 printk(KERN_DEBUG "%s: tid:%d(q:%d) queue:%d "
1632 "!match.\n", wiphy_name(ar->hw->wiphy),
1633 tid_info->tid,
1634 TID_TO_WME_AC(tid_info->tid),
1635 skb_get_queue_mapping(skb));
1636#endif /* AR9170_TXAGG_DEBUG */
1637 dev_kfree_skb_any(skb);
1638 continue;
1639 }
1640
1641 if (unlikely(first == skb)) {
1642 ar9170_tx_prepare_phy(ar, skb);
1643 __skb_queue_tail(&agg, skb);
1644 first = skb;
1645 } else {
1646 ar9170_tx_copy_phy(ar, skb, first);
1647 __skb_queue_tail(&agg, skb);
1648 }
1649
1650 if (unlikely(skb_queue_len(&agg) ==
1651 AR9170_NUM_TX_AGG_MAX))
1652 break;
1653 }
1654
1655 if (skb_queue_empty(&tid_info->queue))
1656 tid_info->active = false;
1657 else
1658 list_add_tail(&tid_info->list,
1659 &ar->tx_ampdu_list);
1660
1661 spin_unlock_irqrestore(&tid_info->queue.lock, f2);
1662
1663 if (unlikely(skb_queue_empty(&agg))) {
1664#ifdef AR9170_TXAGG_DEBUG
1665 printk(KERN_DEBUG "%s: queued empty list!\n",
1666 wiphy_name(ar->hw->wiphy));
1667#endif /* AR9170_TXAGG_DEBUG */
1668 continue;
1669 }
1670
1671 /*
1672 * tell the FW/HW that this is the last frame,
1673 * that way it will wait for the immediate block ack.
1674 */
1675 if (likely(skb_peek_tail(&agg)))
1676 ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg));
1677
1678#ifdef AR9170_TXAGG_DEBUG
1679 printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n",
1680 wiphy_name(ar->hw->wiphy));
1681 __ar9170_dump_txqueue(ar, &agg);
1682#endif /* AR9170_TXAGG_DEBUG */
1683
1684 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1685
1686 spin_lock_irqsave(&ar->tx_pending[queue].lock, flags);
1687 skb_queue_splice_tail_init(&agg, &ar->tx_pending[queue]);
1688 spin_unlock_irqrestore(&ar->tx_pending[queue].lock, flags);
1689 run = true;
1690
1691 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1692 }
1693
1694out_unlock:
1695 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1696 __skb_queue_purge(&agg);
1697
1698 return run;
1699}
1700
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001701static void ar9170_tx(struct ar9170 *ar)
1702{
1703 struct sk_buff *skb;
1704 unsigned long flags;
1705 struct ieee80211_tx_info *info;
1706 struct ar9170_tx_info *arinfo;
1707 unsigned int i, frames, frames_failed, remaining_space;
1708 int err;
1709 bool schedule_garbagecollector = false;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001710
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001711 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001712
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001713 if (unlikely(!IS_STARTED(ar)))
1714 return ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001715
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001716 remaining_space = AR9170_TX_MAX_PENDING;
1717
1718 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1719 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1720 if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
1721#ifdef AR9170_QUEUE_DEBUG
1722 printk(KERN_DEBUG "%s: queue %d full\n",
1723 wiphy_name(ar->hw->wiphy), i);
1724
Christian Lamparteracbadf02009-07-11 17:24:14 +02001725 printk(KERN_DEBUG "%s: stuck frames: ===> \n",
1726 wiphy_name(ar->hw->wiphy));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001727 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1728 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
1729#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparteracbadf02009-07-11 17:24:14 +02001730
1731#ifdef AR9170_QUEUE_STOP_DEBUG
1732 printk(KERN_DEBUG "%s: stop queue %d\n",
1733 wiphy_name(ar->hw->wiphy), i);
1734 __ar9170_dump_txstats(ar);
1735#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001736 ieee80211_stop_queue(ar->hw, i);
1737 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1738 continue;
1739 }
1740
1741 frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
1742 skb_queue_len(&ar->tx_pending[i]));
1743
1744 if (remaining_space < frames) {
1745#ifdef AR9170_QUEUE_DEBUG
1746 printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
1747 "remaining slots:%d, needed:%d\n",
1748 wiphy_name(ar->hw->wiphy), i, remaining_space,
1749 frames);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001750#endif /* AR9170_QUEUE_DEBUG */
1751 frames = remaining_space;
1752 }
1753
1754 ar->tx_stats[i].len += frames;
1755 ar->tx_stats[i].count += frames;
1756 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1757
1758 if (!frames)
1759 continue;
1760
1761 frames_failed = 0;
1762 while (frames) {
1763 skb = skb_dequeue(&ar->tx_pending[i]);
1764 if (unlikely(!skb)) {
1765 frames_failed += frames;
1766 frames = 0;
1767 break;
1768 }
1769
1770 info = IEEE80211_SKB_CB(skb);
1771 arinfo = (void *) info->rate_driver_data;
1772
1773 /* TODO: cancel stuck frames */
1774 arinfo->timeout = jiffies +
1775 msecs_to_jiffies(AR9170_TX_TIMEOUT);
1776
Christian Lamparteracbadf02009-07-11 17:24:14 +02001777 if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK)
1778 ar->tx_ampdu_pending++;
1779
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001780#ifdef AR9170_QUEUE_DEBUG
1781 printk(KERN_DEBUG "%s: send frame q:%d =>\n",
1782 wiphy_name(ar->hw->wiphy), i);
1783 ar9170_print_txheader(ar, skb);
1784#endif /* AR9170_QUEUE_DEBUG */
1785
1786 err = ar->tx(ar, skb);
1787 if (unlikely(err)) {
Christian Lamparteracbadf02009-07-11 17:24:14 +02001788 if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK)
1789 ar->tx_ampdu_pending--;
1790
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001791 frames_failed++;
1792 dev_kfree_skb_any(skb);
1793 } else {
1794 remaining_space--;
1795 schedule_garbagecollector = true;
1796 }
1797
1798 frames--;
1799 }
1800
1801#ifdef AR9170_QUEUE_DEBUG
1802 printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n",
1803 wiphy_name(ar->hw->wiphy), i);
1804
1805 printk(KERN_DEBUG "%s: unprocessed pending frames left:\n",
1806 wiphy_name(ar->hw->wiphy));
1807 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1808#endif /* AR9170_QUEUE_DEBUG */
1809
1810 if (unlikely(frames_failed)) {
1811#ifdef AR9170_QUEUE_DEBUG
Christian Lamparteracbadf02009-07-11 17:24:14 +02001812 printk(KERN_DEBUG "%s: frames failed %d =>\n",
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001813 wiphy_name(ar->hw->wiphy), frames_failed);
1814#endif /* AR9170_QUEUE_DEBUG */
1815
1816 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1817 ar->tx_stats[i].len -= frames_failed;
1818 ar->tx_stats[i].count -= frames_failed;
Christian Lamparteracbadf02009-07-11 17:24:14 +02001819#ifdef AR9170_QUEUE_STOP_DEBUG
1820 printk(KERN_DEBUG "%s: wake queue %d\n",
1821 wiphy_name(ar->hw->wiphy), i);
1822 __ar9170_dump_txstats(ar);
1823#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001824 ieee80211_wake_queue(ar->hw, i);
1825 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001826 }
1827 }
1828
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001829 if (schedule_garbagecollector)
1830 queue_delayed_work(ar->hw->workqueue,
1831 &ar->tx_janitor,
1832 msecs_to_jiffies(AR9170_JANITOR_DELAY));
1833}
1834
Christian Lamparteracbadf02009-07-11 17:24:14 +02001835static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb)
1836{
1837 struct ieee80211_tx_info *txinfo;
1838 struct ar9170_sta_info *sta_info;
1839 struct ar9170_sta_tid *agg;
1840 struct sk_buff *iter;
1841 unsigned long flags, f2;
1842 unsigned int max;
1843 u16 tid, seq, qseq;
1844 bool run = false, queue = false;
1845
1846 tid = ar9170_get_tid(skb);
1847 seq = ar9170_get_seq(skb);
1848 txinfo = IEEE80211_SKB_CB(skb);
1849 sta_info = (void *) txinfo->control.sta->drv_priv;
1850 agg = &sta_info->agg[tid];
1851 max = sta_info->ampdu_max_len;
1852
1853 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1854
1855 if (unlikely(agg->state != AR9170_TID_STATE_COMPLETE)) {
1856#ifdef AR9170_TXAGG_DEBUG
1857 printk(KERN_DEBUG "%s: BlockACK session not fully initialized "
1858 "for ESS:%pM tid:%d state:%d.\n",
1859 wiphy_name(ar->hw->wiphy), agg->addr, agg->tid,
1860 agg->state);
1861#endif /* AR9170_TXAGG_DEBUG */
1862 goto err_unlock;
1863 }
1864
1865 if (!agg->active) {
1866 agg->active = true;
1867 agg->ssn = seq;
1868 queue = true;
1869 }
1870
1871 /* check if seq is within the BA window */
1872 if (unlikely(!BAW_WITHIN(agg->ssn, max, seq))) {
1873#ifdef AR9170_TXAGG_DEBUG
1874 printk(KERN_DEBUG "%s: frame with tid:%d seq:%d does not "
1875 "fit into BA window (%d - %d)\n",
1876 wiphy_name(ar->hw->wiphy), tid, seq, agg->ssn,
1877 (agg->ssn + max) & 0xfff);
1878#endif /* AR9170_TXAGG_DEBUG */
1879 goto err_unlock;
1880 }
1881
1882 spin_lock_irqsave(&agg->queue.lock, f2);
1883
1884 skb_queue_reverse_walk(&agg->queue, iter) {
1885 qseq = ar9170_get_seq(iter);
1886
1887 if (GET_NEXT_SEQ(qseq) == seq) {
1888 __skb_queue_after(&agg->queue, iter, skb);
1889 goto queued;
1890 }
1891 }
1892
1893 __skb_queue_head(&agg->queue, skb);
1894
1895queued:
1896 spin_unlock_irqrestore(&agg->queue.lock, f2);
1897
1898#ifdef AR9170_TXAGG_DEBUG
1899 printk(KERN_DEBUG "%s: new aggregate %p queued.\n",
1900 wiphy_name(ar->hw->wiphy), skb);
1901 __ar9170_dump_txqueue(ar, &agg->queue);
1902#endif /* AR9170_TXAGG_DEBUG */
1903
1904 if (skb_queue_len(&agg->queue) >= AR9170_NUM_TX_AGG_MAX)
1905 run = true;
1906
1907 if (queue)
1908 list_add_tail(&agg->list, &ar->tx_ampdu_list);
1909
1910 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1911 return run;
1912
1913err_unlock:
1914 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1915 dev_kfree_skb_irq(skb);
1916 return false;
1917}
1918
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001919int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1920{
1921 struct ar9170 *ar = hw->priv;
1922 struct ieee80211_tx_info *info;
1923
1924 if (unlikely(!IS_STARTED(ar)))
1925 goto err_free;
1926
1927 if (unlikely(ar9170_tx_prepare(ar, skb)))
1928 goto err_free;
1929
1930 info = IEEE80211_SKB_CB(skb);
1931 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
Christian Lamparteracbadf02009-07-11 17:24:14 +02001932 bool run = ar9170_tx_ampdu_queue(ar, skb);
1933
1934 if (run || !ar->tx_ampdu_pending)
1935 ar9170_tx_ampdu(ar);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001936 } else {
1937 unsigned int queue = skb_get_queue_mapping(skb);
1938
1939 ar9170_tx_prepare_phy(ar, skb);
1940 skb_queue_tail(&ar->tx_pending[queue], skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001941 }
1942
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001943 ar9170_tx(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001944 return NETDEV_TX_OK;
1945
Christian Lampartere9348cd2009-03-21 23:05:13 +01001946err_free:
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001947 dev_kfree_skb_any(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001948 return NETDEV_TX_OK;
1949}
1950
1951static int ar9170_op_add_interface(struct ieee80211_hw *hw,
1952 struct ieee80211_if_init_conf *conf)
1953{
1954 struct ar9170 *ar = hw->priv;
1955 int err = 0;
1956
1957 mutex_lock(&ar->mutex);
1958
1959 if (ar->vif) {
1960 err = -EBUSY;
1961 goto unlock;
1962 }
1963
1964 ar->vif = conf->vif;
1965 memcpy(ar->mac_addr, conf->mac_addr, ETH_ALEN);
1966
1967 if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
1968 ar->rx_software_decryption = true;
1969 ar->disable_offload = true;
1970 }
1971
1972 ar->cur_filter = 0;
1973 ar->want_filter = AR9170_MAC_REG_FTF_DEFAULTS;
1974 err = ar9170_update_frame_filter(ar);
1975 if (err)
1976 goto unlock;
1977
1978 err = ar9170_set_operating_mode(ar);
1979
1980unlock:
1981 mutex_unlock(&ar->mutex);
1982 return err;
1983}
1984
1985static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
1986 struct ieee80211_if_init_conf *conf)
1987{
1988 struct ar9170 *ar = hw->priv;
1989
1990 mutex_lock(&ar->mutex);
1991 ar->vif = NULL;
1992 ar->want_filter = 0;
1993 ar9170_update_frame_filter(ar);
1994 ar9170_set_beacon_timers(ar);
1995 dev_kfree_skb(ar->beacon);
1996 ar->beacon = NULL;
1997 ar->sniffer_enabled = false;
1998 ar->rx_software_decryption = false;
1999 ar9170_set_operating_mode(ar);
2000 mutex_unlock(&ar->mutex);
2001}
2002
2003static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
2004{
2005 struct ar9170 *ar = hw->priv;
2006 int err = 0;
2007
2008 mutex_lock(&ar->mutex);
2009
Christian Lampartere9348cd2009-03-21 23:05:13 +01002010 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
2011 /* TODO */
2012 err = 0;
2013 }
2014
2015 if (changed & IEEE80211_CONF_CHANGE_PS) {
2016 /* TODO */
2017 err = 0;
2018 }
2019
2020 if (changed & IEEE80211_CONF_CHANGE_POWER) {
2021 /* TODO */
2022 err = 0;
2023 }
2024
2025 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
2026 /*
2027 * is it long_frame_max_tx_count or short_frame_max_tx_count?
2028 */
2029
2030 err = ar9170_set_hwretry_limit(ar,
2031 ar->hw->conf.long_frame_max_tx_count);
2032 if (err)
2033 goto out;
2034 }
2035
Johannes Berg57c4d7b2009-04-23 16:10:04 +02002036 if (changed & BSS_CHANGED_BEACON_INT) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002037 err = ar9170_set_beacon_timers(ar);
2038 if (err)
2039 goto out;
2040 }
2041
2042 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002043
2044 /* adjust slot time for 5 GHz */
2045 err = ar9170_set_slot_time(ar);
2046 if (err)
2047 goto out;
2048
2049 err = ar9170_set_dyn_sifs_ack(ar);
2050 if (err)
2051 goto out;
2052
Christian Lampartere9348cd2009-03-21 23:05:13 +01002053 err = ar9170_set_channel(ar, hw->conf.channel,
Johannes Berg9e52b06232009-04-20 18:27:04 +02002054 AR9170_RFI_NONE,
2055 nl80211_to_ar9170(hw->conf.channel_type));
Christian Lampartere9348cd2009-03-21 23:05:13 +01002056 if (err)
2057 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002058 }
2059
2060out:
2061 mutex_unlock(&ar->mutex);
2062 return err;
2063}
2064
Christian Lampartere9348cd2009-03-21 23:05:13 +01002065static void ar9170_set_filters(struct work_struct *work)
2066{
2067 struct ar9170 *ar = container_of(work, struct ar9170,
2068 filter_config_work);
2069 int err;
2070
Christian Lampartere9348cd2009-03-21 23:05:13 +01002071 if (unlikely(!IS_STARTED(ar)))
Christian Lamparter32c16282009-03-28 01:46:14 +01002072 return ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002073
Christian Lamparter32c16282009-03-28 01:46:14 +01002074 mutex_lock(&ar->mutex);
Christian Lamparter864cc022009-05-23 20:28:21 +02002075 if (test_and_clear_bit(AR9170_FILTER_CHANGED_MODE,
2076 &ar->filter_changed)) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002077 err = ar9170_set_operating_mode(ar);
2078 if (err)
2079 goto unlock;
2080 }
2081
Christian Lamparter864cc022009-05-23 20:28:21 +02002082 if (test_and_clear_bit(AR9170_FILTER_CHANGED_MULTICAST,
2083 &ar->filter_changed)) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002084 err = ar9170_update_multicast(ar);
2085 if (err)
2086 goto unlock;
2087 }
2088
Christian Lamparter864cc022009-05-23 20:28:21 +02002089 if (test_and_clear_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
2090 &ar->filter_changed)) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002091 err = ar9170_update_frame_filter(ar);
Christian Lamparter864cc022009-05-23 20:28:21 +02002092 if (err)
2093 goto unlock;
2094 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01002095
2096unlock:
2097 mutex_unlock(&ar->mutex);
2098}
2099
2100static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
2101 unsigned int changed_flags,
2102 unsigned int *new_flags,
2103 int mc_count, struct dev_mc_list *mclist)
2104{
2105 struct ar9170 *ar = hw->priv;
2106
2107 /* mask supported flags */
2108 *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
Christian Lampartercca847992009-04-19 01:28:12 +02002109 FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
2110 ar->filter_state = *new_flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002111 /*
2112 * We can support more by setting the sniffer bit and
2113 * then checking the error flags, later.
2114 */
2115
2116 if (changed_flags & FIF_ALLMULTI) {
2117 if (*new_flags & FIF_ALLMULTI) {
2118 ar->want_mc_hash = ~0ULL;
2119 } else {
2120 u64 mchash;
2121 int i;
2122
2123 /* always get broadcast frames */
Christian Lamparter864cc022009-05-23 20:28:21 +02002124 mchash = 1ULL << (0xff >> 2);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002125
2126 for (i = 0; i < mc_count; i++) {
2127 if (WARN_ON(!mclist))
2128 break;
2129 mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
2130 mclist = mclist->next;
2131 }
2132 ar->want_mc_hash = mchash;
2133 }
Christian Lamparter864cc022009-05-23 20:28:21 +02002134 set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002135 }
2136
2137 if (changed_flags & FIF_CONTROL) {
2138 u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
2139 AR9170_MAC_REG_FTF_RTS |
2140 AR9170_MAC_REG_FTF_CTS |
2141 AR9170_MAC_REG_FTF_ACK |
2142 AR9170_MAC_REG_FTF_CFE |
2143 AR9170_MAC_REG_FTF_CFE_ACK;
2144
2145 if (*new_flags & FIF_CONTROL)
2146 ar->want_filter = ar->cur_filter | filter;
2147 else
2148 ar->want_filter = ar->cur_filter & ~filter;
2149
Christian Lamparter864cc022009-05-23 20:28:21 +02002150 set_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
2151 &ar->filter_changed);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002152 }
2153
2154 if (changed_flags & FIF_PROMISC_IN_BSS) {
2155 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
Christian Lamparter864cc022009-05-23 20:28:21 +02002156 set_bit(AR9170_FILTER_CHANGED_MODE,
2157 &ar->filter_changed);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002158 }
2159
2160 if (likely(IS_STARTED(ar)))
2161 queue_work(ar->hw->workqueue, &ar->filter_config_work);
2162}
2163
2164static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
2165 struct ieee80211_vif *vif,
2166 struct ieee80211_bss_conf *bss_conf,
2167 u32 changed)
2168{
2169 struct ar9170 *ar = hw->priv;
2170 int err = 0;
2171
2172 mutex_lock(&ar->mutex);
2173
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002174 if (changed & BSS_CHANGED_BSSID) {
2175 memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN);
2176 err = ar9170_set_operating_mode(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02002177 if (err)
2178 goto out;
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002179 }
2180
2181 if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) {
2182 err = ar9170_update_beacon(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02002183 if (err)
2184 goto out;
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002185
Christian Lamparter29ceff52009-06-01 21:42:01 +02002186 err = ar9170_set_beacon_timers(ar);
2187 if (err)
2188 goto out;
2189 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01002190
2191 if (changed & BSS_CHANGED_ASSOC) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002192#ifndef CONFIG_AR9170_LEDS
2193 /* enable assoc LED. */
2194 err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
2195#endif /* CONFIG_AR9170_LEDS */
2196 }
2197
Christian Lamparter29ceff52009-06-01 21:42:01 +02002198 if (changed & BSS_CHANGED_BEACON_INT) {
Johannes Berg57c4d7b2009-04-23 16:10:04 +02002199 err = ar9170_set_beacon_timers(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02002200 if (err)
2201 goto out;
2202 }
Johannes Berg57c4d7b2009-04-23 16:10:04 +02002203
Christian Lampartere9348cd2009-03-21 23:05:13 +01002204 if (changed & BSS_CHANGED_HT) {
2205 /* TODO */
2206 err = 0;
2207 }
2208
2209 if (changed & BSS_CHANGED_ERP_SLOT) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002210 err = ar9170_set_slot_time(ar);
2211 if (err)
2212 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002213 }
2214
2215 if (changed & BSS_CHANGED_BASIC_RATES) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002216 err = ar9170_set_basic_rates(ar);
2217 if (err)
2218 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002219 }
2220
Christian Lamparter29ceff52009-06-01 21:42:01 +02002221out:
Christian Lampartere9348cd2009-03-21 23:05:13 +01002222 mutex_unlock(&ar->mutex);
2223}
2224
2225static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
2226{
2227 struct ar9170 *ar = hw->priv;
2228 int err;
2229 u32 tsf_low;
2230 u32 tsf_high;
2231 u64 tsf;
2232
2233 mutex_lock(&ar->mutex);
2234 err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low);
2235 if (!err)
2236 err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high);
2237 mutex_unlock(&ar->mutex);
2238
2239 if (WARN_ON(err))
2240 return 0;
2241
2242 tsf = tsf_high;
2243 tsf = (tsf << 32) | tsf_low;
2244 return tsf;
2245}
2246
2247static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2248 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
2249 struct ieee80211_key_conf *key)
2250{
2251 struct ar9170 *ar = hw->priv;
2252 int err = 0, i;
2253 u8 ktype;
2254
2255 if ((!ar->vif) || (ar->disable_offload))
2256 return -EOPNOTSUPP;
2257
2258 switch (key->alg) {
2259 case ALG_WEP:
Zhu Yie31a16d2009-05-21 21:47:03 +08002260 if (key->keylen == WLAN_KEY_LEN_WEP40)
Christian Lampartere9348cd2009-03-21 23:05:13 +01002261 ktype = AR9170_ENC_ALG_WEP64;
2262 else
2263 ktype = AR9170_ENC_ALG_WEP128;
2264 break;
2265 case ALG_TKIP:
2266 ktype = AR9170_ENC_ALG_TKIP;
2267 break;
2268 case ALG_CCMP:
2269 ktype = AR9170_ENC_ALG_AESCCMP;
2270 break;
2271 default:
2272 return -EOPNOTSUPP;
2273 }
2274
2275 mutex_lock(&ar->mutex);
2276 if (cmd == SET_KEY) {
2277 if (unlikely(!IS_STARTED(ar))) {
2278 err = -EOPNOTSUPP;
2279 goto out;
2280 }
2281
2282 /* group keys need all-zeroes address */
2283 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
2284 sta = NULL;
2285
2286 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
2287 for (i = 0; i < 64; i++)
2288 if (!(ar->usedkeys & BIT(i)))
2289 break;
2290 if (i == 64) {
2291 ar->rx_software_decryption = true;
2292 ar9170_set_operating_mode(ar);
2293 err = -ENOSPC;
2294 goto out;
2295 }
2296 } else {
2297 i = 64 + key->keyidx;
2298 }
2299
2300 key->hw_key_idx = i;
2301
2302 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
2303 key->key, min_t(u8, 16, key->keylen));
2304 if (err)
2305 goto out;
2306
2307 if (key->alg == ALG_TKIP) {
2308 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
2309 ktype, 1, key->key + 16, 16);
2310 if (err)
2311 goto out;
2312
2313 /*
2314 * hardware is not capable generating the MMIC
2315 * for fragmented frames!
2316 */
2317 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
2318 }
2319
2320 if (i < 64)
2321 ar->usedkeys |= BIT(i);
2322
2323 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
2324 } else {
2325 if (unlikely(!IS_STARTED(ar))) {
2326 /* The device is gone... together with the key ;-) */
2327 err = 0;
2328 goto out;
2329 }
2330
2331 err = ar9170_disable_key(ar, key->hw_key_idx);
2332 if (err)
2333 goto out;
2334
2335 if (key->hw_key_idx < 64) {
2336 ar->usedkeys &= ~BIT(key->hw_key_idx);
2337 } else {
2338 err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
2339 AR9170_ENC_ALG_NONE, 0,
2340 NULL, 0);
2341 if (err)
2342 goto out;
2343
2344 if (key->alg == ALG_TKIP) {
2345 err = ar9170_upload_key(ar, key->hw_key_idx,
2346 NULL,
2347 AR9170_ENC_ALG_NONE, 1,
2348 NULL, 0);
2349 if (err)
2350 goto out;
2351 }
2352
2353 }
2354 }
2355
2356 ar9170_regwrite_begin(ar);
2357 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
2358 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
2359 ar9170_regwrite_finish();
2360 err = ar9170_regwrite_result();
2361
2362out:
2363 mutex_unlock(&ar->mutex);
2364
2365 return err;
2366}
2367
2368static void ar9170_sta_notify(struct ieee80211_hw *hw,
2369 struct ieee80211_vif *vif,
2370 enum sta_notify_cmd cmd,
2371 struct ieee80211_sta *sta)
2372{
Christian Lamparteracbadf02009-07-11 17:24:14 +02002373 struct ar9170 *ar = hw->priv;
2374 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2375 unsigned int i;
2376
2377 switch (cmd) {
2378 case STA_NOTIFY_ADD:
2379 memset(sta_info, 0, sizeof(*sta_info));
2380
2381 if (!sta->ht_cap.ht_supported)
2382 break;
2383
2384 if (sta->ht_cap.ampdu_density > ar->global_ampdu_density)
2385 ar->global_ampdu_density = sta->ht_cap.ampdu_density;
2386
2387 if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor)
2388 ar->global_ampdu_factor = sta->ht_cap.ampdu_factor;
2389
2390 for (i = 0; i < AR9170_NUM_TID; i++) {
2391 sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN;
2392 sta_info->agg[i].active = false;
2393 sta_info->agg[i].ssn = 0;
2394 sta_info->agg[i].retry = 0;
2395 sta_info->agg[i].tid = i;
2396 INIT_LIST_HEAD(&sta_info->agg[i].list);
2397 skb_queue_head_init(&sta_info->agg[i].queue);
2398 }
2399
2400 sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor);
2401 break;
2402
2403 case STA_NOTIFY_REMOVE:
2404 if (!sta->ht_cap.ht_supported)
2405 break;
2406
2407 for (i = 0; i < AR9170_NUM_TID; i++) {
2408 sta_info->agg[i].state = AR9170_TID_STATE_INVALID;
2409 skb_queue_purge(&sta_info->agg[i].queue);
2410 }
2411
2412 break;
2413
2414 default:
2415 break;
2416 }
2417
2418 if (IS_STARTED(ar) && ar->filter_changed)
2419 queue_work(ar->hw->workqueue, &ar->filter_config_work);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002420}
2421
2422static int ar9170_get_stats(struct ieee80211_hw *hw,
2423 struct ieee80211_low_level_stats *stats)
2424{
2425 struct ar9170 *ar = hw->priv;
2426 u32 val;
2427 int err;
2428
2429 mutex_lock(&ar->mutex);
2430 err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
2431 ar->stats.dot11ACKFailureCount += val;
2432
2433 memcpy(stats, &ar->stats, sizeof(*stats));
2434 mutex_unlock(&ar->mutex);
2435
2436 return 0;
2437}
2438
2439static int ar9170_get_tx_stats(struct ieee80211_hw *hw,
2440 struct ieee80211_tx_queue_stats *tx_stats)
2441{
2442 struct ar9170 *ar = hw->priv;
2443
2444 spin_lock_bh(&ar->tx_stats_lock);
2445 memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues);
2446 spin_unlock_bh(&ar->tx_stats_lock);
2447
2448 return 0;
2449}
2450
2451static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
2452 const struct ieee80211_tx_queue_params *param)
2453{
2454 struct ar9170 *ar = hw->priv;
2455 int ret;
2456
2457 mutex_lock(&ar->mutex);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002458 if ((param) && !(queue > __AR9170_NUM_TXQ)) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002459 memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
2460 param, sizeof(*param));
2461
2462 ret = ar9170_set_qos(ar);
2463 } else
2464 ret = -EINVAL;
2465
2466 mutex_unlock(&ar->mutex);
2467 return ret;
2468}
2469
Johannes Berg9e52b06232009-04-20 18:27:04 +02002470static int ar9170_ampdu_action(struct ieee80211_hw *hw,
2471 enum ieee80211_ampdu_mlme_action action,
2472 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
2473{
Christian Lamparteracbadf02009-07-11 17:24:14 +02002474 struct ar9170 *ar = hw->priv;
2475 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2476 struct ar9170_sta_tid *tid_info = &sta_info->agg[tid];
2477 unsigned long flags;
2478
2479 if (!modparam_ht)
2480 return -EOPNOTSUPP;
2481
Johannes Berg9e52b06232009-04-20 18:27:04 +02002482 switch (action) {
Christian Lamparteracbadf02009-07-11 17:24:14 +02002483 case IEEE80211_AMPDU_TX_START:
2484 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2485 if (tid_info->state != AR9170_TID_STATE_SHUTDOWN ||
2486 !list_empty(&tid_info->list)) {
2487 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2488#ifdef AR9170_TXAGG_DEBUG
2489 printk(KERN_INFO "%s: A-MPDU [ESS:[%pM] tid:[%d]] "
2490 "is in a very bad state!\n",
2491 wiphy_name(hw->wiphy), sta->addr, tid);
2492#endif /* AR9170_TXAGG_DEBUG */
2493 return -EBUSY;
2494 }
2495
2496 *ssn = tid_info->ssn;
2497 tid_info->state = AR9170_TID_STATE_PROGRESS;
2498 tid_info->active = false;
2499 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2500 ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
2501 break;
2502
2503 case IEEE80211_AMPDU_TX_STOP:
2504 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2505 tid_info->state = AR9170_TID_STATE_SHUTDOWN;
2506 list_del_init(&tid_info->list);
2507 tid_info->active = false;
2508 skb_queue_purge(&tid_info->queue);
2509 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2510 ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
2511 break;
2512
2513 case IEEE80211_AMPDU_TX_OPERATIONAL:
2514#ifdef AR9170_TXAGG_DEBUG
2515 printk(KERN_INFO "%s: A-MPDU for %pM [tid:%d] Operational.\n",
2516 wiphy_name(hw->wiphy), sta->addr, tid);
2517#endif /* AR9170_TXAGG_DEBUG */
2518 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2519 sta_info->agg[tid].state = AR9170_TID_STATE_COMPLETE;
2520 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2521 break;
2522
Johannes Berg9e52b06232009-04-20 18:27:04 +02002523 case IEEE80211_AMPDU_RX_START:
2524 case IEEE80211_AMPDU_RX_STOP:
Christian Lamparteracbadf02009-07-11 17:24:14 +02002525 /* Handled by firmware */
2526 break;
2527
Johannes Berg9e52b06232009-04-20 18:27:04 +02002528 default:
2529 return -EOPNOTSUPP;
2530 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02002531
2532 return 0;
Johannes Berg9e52b06232009-04-20 18:27:04 +02002533}
2534
Christian Lampartere9348cd2009-03-21 23:05:13 +01002535static const struct ieee80211_ops ar9170_ops = {
2536 .start = ar9170_op_start,
2537 .stop = ar9170_op_stop,
2538 .tx = ar9170_op_tx,
2539 .add_interface = ar9170_op_add_interface,
2540 .remove_interface = ar9170_op_remove_interface,
2541 .config = ar9170_op_config,
Christian Lampartere9348cd2009-03-21 23:05:13 +01002542 .configure_filter = ar9170_op_configure_filter,
2543 .conf_tx = ar9170_conf_tx,
2544 .bss_info_changed = ar9170_op_bss_info_changed,
2545 .get_tsf = ar9170_op_get_tsf,
2546 .set_key = ar9170_set_key,
2547 .sta_notify = ar9170_sta_notify,
2548 .get_stats = ar9170_get_stats,
2549 .get_tx_stats = ar9170_get_tx_stats,
Johannes Berg9e52b06232009-04-20 18:27:04 +02002550 .ampdu_action = ar9170_ampdu_action,
Christian Lampartere9348cd2009-03-21 23:05:13 +01002551};
2552
2553void *ar9170_alloc(size_t priv_size)
2554{
2555 struct ieee80211_hw *hw;
2556 struct ar9170 *ar;
Christian Lampartercca847992009-04-19 01:28:12 +02002557 struct sk_buff *skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002558 int i;
2559
Christian Lampartercca847992009-04-19 01:28:12 +02002560 /*
2561 * this buffer is used for rx stream reconstruction.
2562 * Under heavy load this device (or the transport layer?)
2563 * tends to split the streams into seperate rx descriptors.
2564 */
2565
2566 skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL);
2567 if (!skb)
2568 goto err_nomem;
2569
Christian Lampartere9348cd2009-03-21 23:05:13 +01002570 hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
2571 if (!hw)
Christian Lampartercca847992009-04-19 01:28:12 +02002572 goto err_nomem;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002573
2574 ar = hw->priv;
2575 ar->hw = hw;
Christian Lampartercca847992009-04-19 01:28:12 +02002576 ar->rx_failover = skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002577
2578 mutex_init(&ar->mutex);
2579 spin_lock_init(&ar->cmdlock);
2580 spin_lock_init(&ar->tx_stats_lock);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002581 spin_lock_init(&ar->tx_ampdu_list_lock);
2582 skb_queue_head_init(&ar->tx_status_ampdu);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002583 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
2584 skb_queue_head_init(&ar->tx_status[i]);
2585 skb_queue_head_init(&ar->tx_pending[i]);
2586 }
Christian Lampartercca847992009-04-19 01:28:12 +02002587 ar9170_rx_reset_rx_mpdu(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002588 INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
2589 INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002590 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002591 INIT_LIST_HEAD(&ar->tx_ampdu_list);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002592
2593 /* all hw supports 2.4 GHz, so set channel to 1 by default */
2594 ar->channel = &ar9170_2ghz_chantable[0];
2595
2596 /* first part of wiphy init */
2597 ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2598 BIT(NL80211_IFTYPE_WDS) |
2599 BIT(NL80211_IFTYPE_ADHOC);
2600 ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
2601 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
2602 IEEE80211_HW_SIGNAL_DBM |
2603 IEEE80211_HW_NOISE_DBM;
2604
Christian Lamparteracbadf02009-07-11 17:24:14 +02002605 if (modparam_ht) {
2606 ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
2607 } else {
2608 ar9170_band_2GHz.ht_cap.ht_supported = false;
2609 ar9170_band_5GHz.ht_cap.ht_supported = false;
2610 }
2611
Christian Lamparter4a48e2a2009-03-23 12:15:43 +01002612 ar->hw->queues = __AR9170_NUM_TXQ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002613 ar->hw->extra_tx_headroom = 8;
2614 ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
2615
2616 ar->hw->max_rates = 1;
2617 ar->hw->max_rate_tries = 3;
2618
2619 for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
2620 ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
2621
2622 return ar;
Christian Lampartercca847992009-04-19 01:28:12 +02002623
2624err_nomem:
2625 kfree_skb(skb);
2626 return ERR_PTR(-ENOMEM);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002627}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002628
2629static int ar9170_read_eeprom(struct ar9170 *ar)
2630{
2631#define RW 8 /* number of words to read at once */
2632#define RB (sizeof(u32) * RW)
Christian Lampartere9348cd2009-03-21 23:05:13 +01002633 u8 *eeprom = (void *)&ar->eeprom;
2634 u8 *addr = ar->eeprom.mac_address;
2635 __le32 offsets[RW];
Christian Lamparteracbadf02009-07-11 17:24:14 +02002636 unsigned int rx_streams, tx_streams, tx_params = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002637 int i, j, err, bands = 0;
2638
2639 BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
2640
2641 BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
2642#ifndef __CHECKER__
2643 /* don't want to handle trailing remains */
2644 BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
2645#endif
2646
2647 for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
2648 for (j = 0; j < RW; j++)
2649 offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
2650 RB * i + 4 * j);
2651
2652 err = ar->exec_cmd(ar, AR9170_CMD_RREG,
2653 RB, (u8 *) &offsets,
2654 RB, eeprom + RB * i);
2655 if (err)
2656 return err;
2657 }
2658
2659#undef RW
2660#undef RB
2661
2662 if (ar->eeprom.length == cpu_to_le16(0xFFFF))
2663 return -ENODATA;
2664
2665 if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
2666 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
2667 bands++;
2668 }
2669 if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
2670 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
2671 bands++;
2672 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02002673
2674 rx_streams = hweight8(ar->eeprom.rx_mask);
2675 tx_streams = hweight8(ar->eeprom.tx_mask);
2676
2677 if (rx_streams != tx_streams)
2678 tx_params = IEEE80211_HT_MCS_TX_RX_DIFF;
2679
2680 if (tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS)
2681 tx_params = (tx_streams - 1) <<
2682 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
2683
2684 ar9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
2685 ar9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params;
2686
Christian Lampartere9348cd2009-03-21 23:05:13 +01002687 /*
2688 * I measured this, a bandswitch takes roughly
2689 * 135 ms and a frequency switch about 80.
2690 *
2691 * FIXME: measure these values again once EEPROM settings
2692 * are used, that will influence them!
2693 */
2694 if (bands == 2)
2695 ar->hw->channel_change_time = 135 * 1000;
2696 else
2697 ar->hw->channel_change_time = 80 * 1000;
2698
Christian Lamparter1878f772009-03-30 22:30:32 -04002699 ar->regulatory.current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
2700 ar->regulatory.current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
2701
Christian Lampartere9348cd2009-03-21 23:05:13 +01002702 /* second part of wiphy init */
2703 SET_IEEE80211_PERM_ADDR(ar->hw, addr);
2704
2705 return bands ? 0 : -EINVAL;
2706}
2707
Christian Lamparter1878f772009-03-30 22:30:32 -04002708static int ar9170_reg_notifier(struct wiphy *wiphy,
2709 struct regulatory_request *request)
2710{
2711 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2712 struct ar9170 *ar = hw->priv;
2713
2714 return ath_reg_notifier_apply(wiphy, request, &ar->regulatory);
2715}
2716
Christian Lampartere9348cd2009-03-21 23:05:13 +01002717int ar9170_register(struct ar9170 *ar, struct device *pdev)
2718{
2719 int err;
2720
2721 /* try to read EEPROM, init MAC addr */
2722 err = ar9170_read_eeprom(ar);
2723 if (err)
2724 goto err_out;
2725
Christian Lamparter1878f772009-03-30 22:30:32 -04002726 err = ath_regd_init(&ar->regulatory, ar->hw->wiphy,
2727 ar9170_reg_notifier);
Luis R. Rodriguez85efc862009-04-13 21:41:46 -04002728 if (err)
2729 goto err_out;
Christian Lamparter1878f772009-03-30 22:30:32 -04002730
Christian Lampartere9348cd2009-03-21 23:05:13 +01002731 err = ieee80211_register_hw(ar->hw);
2732 if (err)
2733 goto err_out;
2734
Christian Lamparter1878f772009-03-30 22:30:32 -04002735 if (!ath_is_world_regd(&ar->regulatory))
2736 regulatory_hint(ar->hw->wiphy, ar->regulatory.alpha2);
2737
Christian Lampartere9348cd2009-03-21 23:05:13 +01002738 err = ar9170_init_leds(ar);
2739 if (err)
2740 goto err_unreg;
2741
2742#ifdef CONFIG_AR9170_LEDS
2743 err = ar9170_register_leds(ar);
2744 if (err)
2745 goto err_unreg;
2746#endif /* CONFIG_AR9170_LEDS */
2747
2748 dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
2749 wiphy_name(ar->hw->wiphy));
2750
2751 return err;
2752
2753err_unreg:
2754 ieee80211_unregister_hw(ar->hw);
2755
2756err_out:
2757 return err;
2758}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002759
2760void ar9170_unregister(struct ar9170 *ar)
2761{
2762#ifdef CONFIG_AR9170_LEDS
2763 ar9170_unregister_leds(ar);
2764#endif /* CONFIG_AR9170_LEDS */
2765
Christian Lampartercca847992009-04-19 01:28:12 +02002766 kfree_skb(ar->rx_failover);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002767 ieee80211_unregister_hw(ar->hw);
2768 mutex_destroy(&ar->mutex);
2769}