blob: de0ba2bf7691cfb09bd928bcefe72ce5cd44073a [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
Luis R. Rodriguez42935ec2009-07-29 20:08:07 -0400598 if (!resched)
599 return;
600
601 ieee80211_queue_delayed_work(ar->hw,
602 &ar->tx_janitor,
603 msecs_to_jiffies(AR9170_JANITOR_DELAY));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100604}
605
Christian Lamparter66d00812009-05-28 17:04:27 +0200606void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100607{
608 struct ar9170_cmd_response *cmd = (void *) buf;
609
610 if ((cmd->type & 0xc0) != 0xc0) {
611 ar->callback_cmd(ar, len, buf);
612 return;
613 }
614
615 /* hardware event handlers */
616 switch (cmd->type) {
617 case 0xc1: {
618 /*
619 * TX status notification:
620 * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
621 *
622 * XX always 81
623 * YY always 00
624 * M1-M6 is the MAC address
625 * R1-R4 is the transmit rate
626 * S1-S2 is the transmit status
627 */
628
629 struct sk_buff *skb;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200630 u32 phy = le32_to_cpu(cmd->tx_status.rate);
631 u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >>
632 AR9170_TX_PHY_QOS_SHIFT;
633#ifdef AR9170_QUEUE_DEBUG
634 printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n",
635 wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q);
636#endif /* AR9170_QUEUE_DEBUG */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100637
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200638 skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst,
639 &ar->tx_status[q],
640 AR9170_TX_INVALID_RATE);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100641 if (unlikely(!skb))
642 return ;
643
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200644 ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100645 break;
646 }
647
648 case 0xc0:
649 /*
650 * pre-TBTT event
651 */
652 if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
Luis R. Rodriguez42935ec2009-07-29 20:08:07 -0400653 ieee80211_queue_work(ar->hw, &ar->beacon_work);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100654 break;
655
656 case 0xc2:
657 /*
658 * (IBSS) beacon send notification
659 * bytes: 04 c2 XX YY B4 B3 B2 B1
660 *
661 * XX always 80
662 * YY always 00
663 * B1-B4 "should" be the number of send out beacons.
664 */
665 break;
666
667 case 0xc3:
668 /* End of Atim Window */
669 break;
670
671 case 0xc4:
Christian Lamparteracbadf02009-07-11 17:24:14 +0200672 /* BlockACK bitmap */
673 break;
674
Christian Lampartere9348cd2009-03-21 23:05:13 +0100675 case 0xc5:
676 /* BlockACK events */
Christian Lamparteracbadf02009-07-11 17:24:14 +0200677 ar9170_handle_block_ack(ar,
678 le16_to_cpu(cmd->ba_fail_cnt.failed),
679 le16_to_cpu(cmd->ba_fail_cnt.rate));
680 ar9170_tx_fake_ampdu_status(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100681 break;
682
683 case 0xc6:
684 /* Watchdog Interrupt */
685 break;
686
687 case 0xc9:
688 /* retransmission issue / SIFS/EIFS collision ?! */
689 break;
690
Johannes Berg2543a0c2009-06-05 11:47:43 +0200691 /* firmware debug */
692 case 0xca:
693 printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, (char *)buf + 4);
694 break;
695 case 0xcb:
696 len -= 4;
697
698 switch (len) {
699 case 1:
700 printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n",
701 *((char *)buf + 4));
702 break;
703 case 2:
704 printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n",
705 le16_to_cpup((__le16 *)((char *)buf + 4)));
706 break;
707 case 4:
708 printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n",
709 le32_to_cpup((__le32 *)((char *)buf + 4)));
710 break;
711 case 8:
712 printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n",
713 (unsigned long)le64_to_cpup(
714 (__le64 *)((char *)buf + 4)));
715 break;
716 }
717 break;
718 case 0xcc:
719 print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE,
720 (char *)buf + 4, len - 4);
721 break;
722
Christian Lampartere9348cd2009-03-21 23:05:13 +0100723 default:
724 printk(KERN_INFO "received unhandled event %x\n", cmd->type);
725 print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
726 break;
727 }
728}
729
Christian Lampartercca847992009-04-19 01:28:12 +0200730static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100731{
Christian Lampartercca847992009-04-19 01:28:12 +0200732 memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head));
733 ar->rx_mpdu.has_plcp = false;
734}
Christian Lampartere9348cd2009-03-21 23:05:13 +0100735
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200736int ar9170_nag_limiter(struct ar9170 *ar)
Christian Lampartercca847992009-04-19 01:28:12 +0200737{
738 bool print_message;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100739
Christian Lampartercca847992009-04-19 01:28:12 +0200740 /*
741 * we expect all sorts of errors in promiscuous mode.
742 * don't bother with it, it's OK!
743 */
744 if (ar->sniffer_enabled)
745 return false;
746
747 /*
748 * only go for frequent errors! The hardware tends to
749 * do some stupid thing once in a while under load, in
750 * noisy environments or just for fun!
751 */
752 if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit())
753 print_message = true;
754 else
755 print_message = false;
756
757 /* reset threshold for "once in a while" */
758 ar->bad_hw_nagger = jiffies + HZ / 4;
759 return print_message;
760}
761
762static int ar9170_rx_mac_status(struct ar9170 *ar,
763 struct ar9170_rx_head *head,
764 struct ar9170_rx_macstatus *mac,
765 struct ieee80211_rx_status *status)
766{
767 u8 error, decrypt;
768
Christian Lampartere9348cd2009-03-21 23:05:13 +0100769 BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
Christian Lampartercca847992009-04-19 01:28:12 +0200770 BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100771
Christian Lampartercca847992009-04-19 01:28:12 +0200772 error = mac->error;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100773 if (error & AR9170_RX_ERROR_MMIC) {
Christian Lampartercca847992009-04-19 01:28:12 +0200774 status->flag |= RX_FLAG_MMIC_ERROR;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100775 error &= ~AR9170_RX_ERROR_MMIC;
776 }
777
778 if (error & AR9170_RX_ERROR_PLCP) {
Christian Lampartercca847992009-04-19 01:28:12 +0200779 status->flag |= RX_FLAG_FAILED_PLCP_CRC;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100780 error &= ~AR9170_RX_ERROR_PLCP;
Christian Lampartercca847992009-04-19 01:28:12 +0200781
782 if (!(ar->filter_state & FIF_PLCPFAIL))
783 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100784 }
785
786 if (error & AR9170_RX_ERROR_FCS) {
Christian Lampartercca847992009-04-19 01:28:12 +0200787 status->flag |= RX_FLAG_FAILED_FCS_CRC;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100788 error &= ~AR9170_RX_ERROR_FCS;
Christian Lampartercca847992009-04-19 01:28:12 +0200789
790 if (!(ar->filter_state & FIF_FCSFAIL))
791 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100792 }
793
Christian Lampartercca847992009-04-19 01:28:12 +0200794 decrypt = ar9170_get_decrypt_type(mac);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100795 if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
796 decrypt != AR9170_ENC_ALG_NONE)
Christian Lampartercca847992009-04-19 01:28:12 +0200797 status->flag |= RX_FLAG_DECRYPTED;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100798
799 /* ignore wrong RA errors */
800 error &= ~AR9170_RX_ERROR_WRONG_RA;
801
802 if (error & AR9170_RX_ERROR_DECRYPT) {
803 error &= ~AR9170_RX_ERROR_DECRYPT;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100804 /*
805 * Rx decryption is done in place,
806 * the original data is lost anyway.
807 */
Christian Lampartercca847992009-04-19 01:28:12 +0200808
809 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100810 }
811
812 /* drop any other error frames */
Christian Lampartercca847992009-04-19 01:28:12 +0200813 if (unlikely(error)) {
814 /* TODO: update netdevice's RX dropped/errors statistics */
815
816 if (ar9170_nag_limiter(ar))
817 printk(KERN_DEBUG "%s: received frame with "
818 "suspicious error code (%#x).\n",
819 wiphy_name(ar->hw->wiphy), error);
820
821 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100822 }
823
Christian Lampartercca847992009-04-19 01:28:12 +0200824 status->band = ar->channel->band;
825 status->freq = ar->channel->center_freq;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100826
Christian Lampartercca847992009-04-19 01:28:12 +0200827 switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) {
828 case AR9170_RX_STATUS_MODULATION_CCK:
829 if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
830 status->flag |= RX_FLAG_SHORTPRE;
831 switch (head->plcp[0]) {
832 case 0x0a:
833 status->rate_idx = 0;
834 break;
835 case 0x14:
836 status->rate_idx = 1;
837 break;
838 case 0x37:
839 status->rate_idx = 2;
840 break;
841 case 0x6e:
842 status->rate_idx = 3;
843 break;
844 default:
845 if (ar9170_nag_limiter(ar))
846 printk(KERN_ERR "%s: invalid plcp cck rate "
847 "(%x).\n", wiphy_name(ar->hw->wiphy),
848 head->plcp[0]);
849 return -EINVAL;
850 }
851 break;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100852
Christian Lampartercca847992009-04-19 01:28:12 +0200853 case AR9170_RX_STATUS_MODULATION_OFDM:
854 switch (head->plcp[0] & 0xf) {
855 case 0xb:
856 status->rate_idx = 0;
857 break;
858 case 0xf:
859 status->rate_idx = 1;
860 break;
861 case 0xa:
862 status->rate_idx = 2;
863 break;
864 case 0xe:
865 status->rate_idx = 3;
866 break;
867 case 0x9:
868 status->rate_idx = 4;
869 break;
870 case 0xd:
871 status->rate_idx = 5;
872 break;
873 case 0x8:
874 status->rate_idx = 6;
875 break;
876 case 0xc:
877 status->rate_idx = 7;
878 break;
879 default:
880 if (ar9170_nag_limiter(ar))
881 printk(KERN_ERR "%s: invalid plcp ofdm rate "
882 "(%x).\n", wiphy_name(ar->hw->wiphy),
883 head->plcp[0]);
884 return -EINVAL;
885 }
886 if (status->band == IEEE80211_BAND_2GHZ)
887 status->rate_idx += 4;
888 break;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100889
Christian Lampartercca847992009-04-19 01:28:12 +0200890 case AR9170_RX_STATUS_MODULATION_HT:
891 if (head->plcp[3] & 0x80)
892 status->flag |= RX_FLAG_40MHZ;
893 if (head->plcp[6] & 0x80)
894 status->flag |= RX_FLAG_SHORT_GI;
895
896 status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f);
897 status->flag |= RX_FLAG_HT;
898 break;
899
900 case AR9170_RX_STATUS_MODULATION_DUPOFDM:
901 /* XXX */
902 if (ar9170_nag_limiter(ar))
903 printk(KERN_ERR "%s: invalid modulation\n",
904 wiphy_name(ar->hw->wiphy));
905 return -EINVAL;
906 }
907
908 return 0;
909}
910
911static void ar9170_rx_phy_status(struct ar9170 *ar,
912 struct ar9170_rx_phystatus *phy,
913 struct ieee80211_rx_status *status)
914{
915 int i;
916
917 BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20);
918
919 for (i = 0; i < 3; i++)
920 if (phy->rssi[i] != 0x80)
921 status->antenna |= BIT(i);
922
923 /* post-process RSSI */
924 for (i = 0; i < 7; i++)
925 if (phy->rssi[i] & 0x80)
926 phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f;
927
928 /* TODO: we could do something with phy_errors */
929 status->signal = ar->noise[0] + phy->rssi_combined;
930 status->noise = ar->noise[0];
931}
932
933static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len)
934{
935 struct sk_buff *skb;
936 int reserved = 0;
937 struct ieee80211_hdr *hdr = (void *) buf;
938
939 if (ieee80211_is_data_qos(hdr->frame_control)) {
940 u8 *qc = ieee80211_get_qos_ctl(hdr);
941 reserved += NET_IP_ALIGN;
942
943 if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
944 reserved += NET_IP_ALIGN;
945 }
946
947 if (ieee80211_has_a4(hdr->frame_control))
948 reserved += NET_IP_ALIGN;
949
950 reserved = 32 + (reserved & NET_IP_ALIGN);
951
952 skb = dev_alloc_skb(len + reserved);
953 if (likely(skb)) {
954 skb_reserve(skb, reserved);
955 memcpy(skb_put(skb, len), buf, len);
956 }
957
958 return skb;
959}
960
961/*
962 * If the frame alignment is right (or the kernel has
963 * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
964 * is only a single MPDU in the USB frame, then we could
965 * submit to mac80211 the SKB directly. However, since
966 * there may be multiple packets in one SKB in stream
967 * mode, and we need to observe the proper ordering,
968 * this is non-trivial.
969 */
970
971static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
972{
973 struct ar9170_rx_head *head;
974 struct ar9170_rx_macstatus *mac;
975 struct ar9170_rx_phystatus *phy = NULL;
976 struct ieee80211_rx_status status;
977 struct sk_buff *skb;
978 int mpdu_len;
979
980 if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac))))
981 return ;
982
983 /* Received MPDU */
984 mpdu_len = len - sizeof(*mac);
985
986 mac = (void *)(buf + mpdu_len);
987 if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
988 /* this frame is too damaged and can't be used - drop it */
989
990 return ;
991 }
992
993 switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) {
994 case AR9170_RX_STATUS_MPDU_FIRST:
995 /* first mpdu packet has the plcp header */
996 if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
997 head = (void *) buf;
998 memcpy(&ar->rx_mpdu.plcp, (void *) buf,
999 sizeof(struct ar9170_rx_head));
1000
1001 mpdu_len -= sizeof(struct ar9170_rx_head);
1002 buf += sizeof(struct ar9170_rx_head);
1003 ar->rx_mpdu.has_plcp = true;
1004 } else {
1005 if (ar9170_nag_limiter(ar))
1006 printk(KERN_ERR "%s: plcp info is clipped.\n",
1007 wiphy_name(ar->hw->wiphy));
1008 return ;
1009 }
1010 break;
1011
1012 case AR9170_RX_STATUS_MPDU_LAST:
1013 /* last mpdu has a extra tail with phy status information */
1014
1015 if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
1016 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
1017 phy = (void *)(buf + mpdu_len);
1018 } else {
1019 if (ar9170_nag_limiter(ar))
1020 printk(KERN_ERR "%s: frame tail is clipped.\n",
1021 wiphy_name(ar->hw->wiphy));
1022 return ;
1023 }
1024
1025 case AR9170_RX_STATUS_MPDU_MIDDLE:
1026 /* middle mpdus are just data */
1027 if (unlikely(!ar->rx_mpdu.has_plcp)) {
1028 if (!ar9170_nag_limiter(ar))
1029 return ;
1030
1031 printk(KERN_ERR "%s: rx stream did not start "
1032 "with a first_mpdu frame tag.\n",
1033 wiphy_name(ar->hw->wiphy));
1034
1035 return ;
1036 }
1037
1038 head = &ar->rx_mpdu.plcp;
1039 break;
1040
1041 case AR9170_RX_STATUS_MPDU_SINGLE:
1042 /* single mpdu - has plcp (head) and phy status (tail) */
1043 head = (void *) buf;
1044
1045 mpdu_len -= sizeof(struct ar9170_rx_head);
1046 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
1047
1048 buf += sizeof(struct ar9170_rx_head);
1049 phy = (void *)(buf + mpdu_len);
1050 break;
1051
1052 default:
1053 BUG_ON(1);
1054 break;
1055 }
1056
1057 if (unlikely(mpdu_len < FCS_LEN))
1058 return ;
1059
1060 memset(&status, 0, sizeof(status));
1061 if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status)))
1062 return ;
1063
1064 if (phy)
1065 ar9170_rx_phy_status(ar, phy, &status);
1066
1067 skb = ar9170_rx_copy_data(buf, mpdu_len);
Johannes Bergf1d58c22009-06-17 13:13:00 +02001068 if (likely(skb)) {
1069 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
1070 ieee80211_rx_irqsafe(ar->hw, skb);
1071 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001072}
1073
Christian Lampartere9348cd2009-03-21 23:05:13 +01001074void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
1075{
Christian Lampartercca847992009-04-19 01:28:12 +02001076 unsigned int i, tlen, resplen, wlen = 0, clen = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001077 u8 *tbuf, *respbuf;
1078
1079 tbuf = skb->data;
1080 tlen = skb->len;
1081
1082 while (tlen >= 4) {
Christian Lampartercca847992009-04-19 01:28:12 +02001083 clen = tbuf[1] << 8 | tbuf[0];
1084 wlen = ALIGN(clen, 4);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001085
Christian Lampartercca847992009-04-19 01:28:12 +02001086 /* check if this is stream has a valid tag.*/
Christian Lampartere9348cd2009-03-21 23:05:13 +01001087 if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
Christian Lampartercca847992009-04-19 01:28:12 +02001088 /*
1089 * TODO: handle the highly unlikely event that the
1090 * corrupted stream has the TAG at the right position.
1091 */
1092
1093 /* check if the frame can be repaired. */
1094 if (!ar->rx_failover_missing) {
1095 /* this is no "short read". */
1096 if (ar9170_nag_limiter(ar)) {
1097 printk(KERN_ERR "%s: missing tag!\n",
1098 wiphy_name(ar->hw->wiphy));
1099 goto err_telluser;
1100 } else
1101 goto err_silent;
1102 }
1103
1104 if (ar->rx_failover_missing > tlen) {
1105 if (ar9170_nag_limiter(ar)) {
1106 printk(KERN_ERR "%s: possible multi "
1107 "stream corruption!\n",
1108 wiphy_name(ar->hw->wiphy));
1109 goto err_telluser;
1110 } else
1111 goto err_silent;
1112 }
1113
1114 memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
1115 ar->rx_failover_missing -= tlen;
1116
1117 if (ar->rx_failover_missing <= 0) {
1118 /*
1119 * nested ar9170_rx call!
1120 * termination is guranteed, even when the
1121 * combined frame also have a element with
1122 * a bad tag.
1123 */
1124
1125 ar->rx_failover_missing = 0;
1126 ar9170_rx(ar, ar->rx_failover);
1127
1128 skb_reset_tail_pointer(ar->rx_failover);
1129 skb_trim(ar->rx_failover, 0);
1130 }
1131
Christian Lampartere9348cd2009-03-21 23:05:13 +01001132 return ;
1133 }
Christian Lampartercca847992009-04-19 01:28:12 +02001134
1135 /* check if stream is clipped */
Christian Lampartere9348cd2009-03-21 23:05:13 +01001136 if (wlen > tlen - 4) {
Christian Lampartercca847992009-04-19 01:28:12 +02001137 if (ar->rx_failover_missing) {
1138 /* TODO: handle double stream corruption. */
1139 if (ar9170_nag_limiter(ar)) {
1140 printk(KERN_ERR "%s: double rx stream "
1141 "corruption!\n",
1142 wiphy_name(ar->hw->wiphy));
1143 goto err_telluser;
1144 } else
1145 goto err_silent;
1146 }
1147
1148 /*
1149 * save incomplete data set.
1150 * the firmware will resend the missing bits when
1151 * the rx - descriptor comes round again.
1152 */
1153
1154 memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
1155 ar->rx_failover_missing = clen - tlen;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001156 return ;
1157 }
1158 resplen = clen;
1159 respbuf = tbuf + 4;
1160 tbuf += wlen + 4;
1161 tlen -= wlen + 4;
1162
1163 i = 0;
1164
1165 /* weird thing, but this is the same in the original driver */
1166 while (resplen > 2 && i < 12 &&
1167 respbuf[0] == 0xff && respbuf[1] == 0xff) {
1168 i += 2;
1169 resplen -= 2;
1170 respbuf += 2;
1171 }
1172
1173 if (resplen < 4)
1174 continue;
1175
1176 /* found the 6 * 0xffff marker? */
1177 if (i == 12)
1178 ar9170_handle_command_response(ar, respbuf, resplen);
1179 else
Christian Lampartercca847992009-04-19 01:28:12 +02001180 ar9170_handle_mpdu(ar, respbuf, clen);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001181 }
1182
Christian Lampartercca847992009-04-19 01:28:12 +02001183 if (tlen) {
1184 if (net_ratelimit())
1185 printk(KERN_ERR "%s: %d bytes of unprocessed "
1186 "data left in rx stream!\n",
1187 wiphy_name(ar->hw->wiphy), tlen);
1188
1189 goto err_telluser;
1190 }
1191
1192 return ;
1193
1194err_telluser:
1195 printk(KERN_ERR "%s: damaged RX stream data [want:%d, "
1196 "data:%d, rx:%d, pending:%d ]\n",
1197 wiphy_name(ar->hw->wiphy), clen, wlen, tlen,
1198 ar->rx_failover_missing);
1199
1200 if (ar->rx_failover_missing)
1201 print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
1202 ar->rx_failover->data,
1203 ar->rx_failover->len);
1204
1205 print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
1206 skb->data, skb->len);
1207
1208 printk(KERN_ERR "%s: please check your hardware and cables, if "
1209 "you see this message frequently.\n",
1210 wiphy_name(ar->hw->wiphy));
1211
1212err_silent:
1213 if (ar->rx_failover_missing) {
1214 skb_reset_tail_pointer(ar->rx_failover);
1215 skb_trim(ar->rx_failover, 0);
1216 ar->rx_failover_missing = 0;
1217 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001218}
Christian Lampartere9348cd2009-03-21 23:05:13 +01001219
1220#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \
1221do { \
1222 queue.aifs = ai_fs; \
1223 queue.cw_min = cwmin; \
1224 queue.cw_max = cwmax; \
1225 queue.txop = _txop; \
1226} while (0)
1227
1228static int ar9170_op_start(struct ieee80211_hw *hw)
1229{
1230 struct ar9170 *ar = hw->priv;
1231 int err, i;
1232
1233 mutex_lock(&ar->mutex);
1234
1235 /* 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 Lamparter9b9c5aa2009-06-06 05:07:23 +02001293 cancel_delayed_work_sync(&ar->tx_janitor);
Alexander Beregalovff8365c2009-07-24 11:55:44 +04001294#ifdef CONFIG_AR9170_LEDS
Christian Lamparteracbadf02009-07-11 17:24:14 +02001295 cancel_delayed_work_sync(&ar->led_work);
Alexander Beregalovff8365c2009-07-24 11:55:44 +04001296#endif
Christian Lampartere9348cd2009-03-21 23:05:13 +01001297 cancel_work_sync(&ar->beacon_work);
Luis R. Rodrigueze351cfb2009-07-27 12:51:37 -07001298
Christian Lamparterb55d6bc2009-05-23 20:31:21 +02001299 mutex_lock(&ar->mutex);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001300
1301 if (IS_ACCEPTING_CMD(ar)) {
1302 ar9170_set_leds_state(ar, 0);
1303
1304 /* stop DMA */
1305 ar9170_write_reg(ar, 0x1c3d30, 0);
1306 ar->stop(ar);
1307 }
1308
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001309 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1310 skb_queue_purge(&ar->tx_pending[i]);
1311 skb_queue_purge(&ar->tx_status[i]);
1312 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02001313 skb_queue_purge(&ar->tx_status_ampdu);
1314
Christian Lampartere9348cd2009-03-21 23:05:13 +01001315 mutex_unlock(&ar->mutex);
1316}
1317
Christian Lamparteracbadf02009-07-11 17:24:14 +02001318static void ar9170_tx_indicate_immba(struct ar9170 *ar, struct sk_buff *skb)
1319{
1320 struct ar9170_tx_control *txc = (void *) skb->data;
1321
1322 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_IMM_AMPDU);
1323}
1324
1325static void ar9170_tx_copy_phy(struct ar9170 *ar, struct sk_buff *dst,
1326 struct sk_buff *src)
1327{
1328 struct ar9170_tx_control *dst_txc, *src_txc;
1329 struct ieee80211_tx_info *dst_info, *src_info;
1330 struct ar9170_tx_info *dst_arinfo, *src_arinfo;
1331
1332 src_txc = (void *) src->data;
1333 src_info = IEEE80211_SKB_CB(src);
1334 src_arinfo = (void *) src_info->rate_driver_data;
1335
1336 dst_txc = (void *) dst->data;
1337 dst_info = IEEE80211_SKB_CB(dst);
1338 dst_arinfo = (void *) dst_info->rate_driver_data;
1339
1340 dst_txc->phy_control = src_txc->phy_control;
1341
1342 /* same MCS for the whole aggregate */
1343 memcpy(dst_info->driver_rates, src_info->driver_rates,
1344 sizeof(dst_info->driver_rates));
1345}
1346
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001347static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001348{
Christian Lampartere9348cd2009-03-21 23:05:13 +01001349 struct ieee80211_hdr *hdr;
1350 struct ar9170_tx_control *txc;
1351 struct ieee80211_tx_info *info;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001352 struct ieee80211_tx_rate *txrate;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001353 struct ar9170_tx_info *arinfo;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001354 unsigned int queue = skb_get_queue_mapping(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001355 u16 keytype = 0;
1356 u16 len, icv = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001357
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001358 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001359
1360 hdr = (void *)skb->data;
1361 info = IEEE80211_SKB_CB(skb);
1362 len = skb->len;
1363
Christian Lampartere9348cd2009-03-21 23:05:13 +01001364 txc = (void *)skb_push(skb, sizeof(*txc));
1365
Christian Lampartere9348cd2009-03-21 23:05:13 +01001366 if (info->control.hw_key) {
1367 icv = info->control.hw_key->icv_len;
1368
1369 switch (info->control.hw_key->alg) {
1370 case ALG_WEP:
1371 keytype = AR9170_TX_MAC_ENCR_RC4;
1372 break;
1373 case ALG_TKIP:
1374 keytype = AR9170_TX_MAC_ENCR_RC4;
1375 break;
1376 case ALG_CCMP:
1377 keytype = AR9170_TX_MAC_ENCR_AES;
1378 break;
1379 default:
1380 WARN_ON(1);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001381 goto err_out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001382 }
1383 }
1384
1385 /* Length */
1386 txc->length = cpu_to_le16(len + icv + 4);
1387
1388 txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
1389 AR9170_TX_MAC_BACKOFF);
1390 txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
1391 AR9170_TX_MAC_QOS_SHIFT);
1392 txc->mac_control |= cpu_to_le16(keytype);
1393 txc->phy_control = cpu_to_le32(0);
1394
1395 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
1396 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
1397
Christian Lampartere9348cd2009-03-21 23:05:13 +01001398 txrate = &info->control.rates[0];
Christian Lampartere9348cd2009-03-21 23:05:13 +01001399 if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1400 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
1401 else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1402 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
1403
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001404 arinfo = (void *)info->rate_driver_data;
1405 arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT);
1406
1407 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
1408 (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
1409 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1410 if (unlikely(!info->control.sta))
1411 goto err_out;
1412
1413 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
1414 arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK;
Christian Lamparteracbadf02009-07-11 17:24:14 +02001415
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001416 goto out;
1417 }
1418
1419 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
1420 /*
1421 * WARNING:
1422 * Putting the QoS queue bits into an unexplored territory is
1423 * certainly not elegant.
1424 *
1425 * In my defense: This idea provides a reasonable way to
1426 * smuggle valuable information to the tx_status callback.
1427 * Also, the idea behind this bit-abuse came straight from
1428 * the original driver code.
1429 */
1430
1431 txc->phy_control |=
1432 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
1433 arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK;
1434 } else {
1435 arinfo->flags = AR9170_TX_FLAG_NO_ACK;
1436 }
1437
1438out:
1439 return 0;
1440
1441err_out:
1442 skb_pull(skb, sizeof(*txc));
1443 return -EINVAL;
1444}
1445
1446static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
1447{
1448 struct ar9170_tx_control *txc;
1449 struct ieee80211_tx_info *info;
1450 struct ieee80211_rate *rate = NULL;
1451 struct ieee80211_tx_rate *txrate;
1452 u32 power, chains;
1453
1454 txc = (void *) skb->data;
1455 info = IEEE80211_SKB_CB(skb);
1456 txrate = &info->control.rates[0];
1457
Christian Lampartere9348cd2009-03-21 23:05:13 +01001458 if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
1459 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
1460
1461 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1462 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
1463
1464 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1465 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
1466 /* this works because 40 MHz is 2 and dup is 3 */
1467 if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
1468 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
1469
1470 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
1471 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
1472
1473 if (txrate->flags & IEEE80211_TX_RC_MCS) {
1474 u32 r = txrate->idx;
1475 u8 *txpower;
1476
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001477 /* heavy clip control */
1478 txc->phy_control |= cpu_to_le32((r & 0x7) << 7);
1479
Christian Lampartere9348cd2009-03-21 23:05:13 +01001480 r <<= AR9170_TX_PHY_MCS_SHIFT;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001481 BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK);
1482
Christian Lampartere9348cd2009-03-21 23:05:13 +01001483 txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
1484 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
1485
1486 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1487 if (info->band == IEEE80211_BAND_5GHZ)
1488 txpower = ar->power_5G_ht40;
1489 else
1490 txpower = ar->power_2G_ht40;
1491 } else {
1492 if (info->band == IEEE80211_BAND_5GHZ)
1493 txpower = ar->power_5G_ht20;
1494 else
1495 txpower = ar->power_2G_ht20;
1496 }
1497
1498 power = txpower[(txrate->idx) & 7];
1499 } else {
1500 u8 *txpower;
1501 u32 mod;
1502 u32 phyrate;
1503 u8 idx = txrate->idx;
1504
1505 if (info->band != IEEE80211_BAND_2GHZ) {
1506 idx += 4;
1507 txpower = ar->power_5G_leg;
1508 mod = AR9170_TX_PHY_MOD_OFDM;
1509 } else {
1510 if (idx < 4) {
1511 txpower = ar->power_2G_cck;
1512 mod = AR9170_TX_PHY_MOD_CCK;
1513 } else {
1514 mod = AR9170_TX_PHY_MOD_OFDM;
1515 txpower = ar->power_2G_ofdm;
1516 }
1517 }
1518
1519 rate = &__ar9170_ratetable[idx];
1520
1521 phyrate = rate->hw_value & 0xF;
1522 power = txpower[(rate->hw_value & 0x30) >> 4];
1523 phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
1524
1525 txc->phy_control |= cpu_to_le32(mod);
1526 txc->phy_control |= cpu_to_le32(phyrate);
1527 }
1528
1529 power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
1530 power &= AR9170_TX_PHY_TX_PWR_MASK;
1531 txc->phy_control |= cpu_to_le32(power);
1532
1533 /* set TX chains */
1534 if (ar->eeprom.tx_mask == 1) {
1535 chains = AR9170_TX_PHY_TXCHAIN_1;
1536 } else {
1537 chains = AR9170_TX_PHY_TXCHAIN_2;
1538
1539 /* >= 36M legacy OFDM - use only one chain */
1540 if (rate && rate->bitrate >= 360)
1541 chains = AR9170_TX_PHY_TXCHAIN_1;
1542 }
1543 txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001544}
Christian Lampartere9348cd2009-03-21 23:05:13 +01001545
Christian Lamparteracbadf02009-07-11 17:24:14 +02001546static bool ar9170_tx_ampdu(struct ar9170 *ar)
1547{
1548 struct sk_buff_head agg;
1549 struct ar9170_sta_tid *tid_info = NULL, *tmp;
1550 struct sk_buff *skb, *first = NULL;
1551 unsigned long flags, f2;
1552 unsigned int i = 0;
1553 u16 seq, queue, tmpssn;
1554 bool run = false;
1555
1556 skb_queue_head_init(&agg);
1557
1558 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1559 if (list_empty(&ar->tx_ampdu_list)) {
1560#ifdef AR9170_TXAGG_DEBUG
1561 printk(KERN_DEBUG "%s: aggregation list is empty.\n",
1562 wiphy_name(ar->hw->wiphy));
1563#endif /* AR9170_TXAGG_DEBUG */
1564 goto out_unlock;
1565 }
1566
1567 list_for_each_entry_safe(tid_info, tmp, &ar->tx_ampdu_list, list) {
1568 if (tid_info->state != AR9170_TID_STATE_COMPLETE) {
1569#ifdef AR9170_TXAGG_DEBUG
1570 printk(KERN_DEBUG "%s: dangling aggregation entry!\n",
1571 wiphy_name(ar->hw->wiphy));
1572#endif /* AR9170_TXAGG_DEBUG */
1573 continue;
1574 }
1575
1576 if (++i > 64) {
1577#ifdef AR9170_TXAGG_DEBUG
1578 printk(KERN_DEBUG "%s: enough frames aggregated.\n",
1579 wiphy_name(ar->hw->wiphy));
1580#endif /* AR9170_TXAGG_DEBUG */
1581 break;
1582 }
1583
1584 queue = TID_TO_WME_AC(tid_info->tid);
1585
1586 if (skb_queue_len(&ar->tx_pending[queue]) >=
1587 AR9170_NUM_TX_AGG_MAX) {
1588#ifdef AR9170_TXAGG_DEBUG
1589 printk(KERN_DEBUG "%s: queue %d full.\n",
1590 wiphy_name(ar->hw->wiphy), queue);
1591#endif /* AR9170_TXAGG_DEBUG */
1592 continue;
1593 }
1594
1595 list_del_init(&tid_info->list);
1596
1597 spin_lock_irqsave(&tid_info->queue.lock, f2);
1598 tmpssn = seq = tid_info->ssn;
1599 first = skb_peek(&tid_info->queue);
1600
1601 if (likely(first))
1602 tmpssn = ar9170_get_seq(first);
1603
1604 if (unlikely(tmpssn != seq)) {
1605#ifdef AR9170_TXAGG_DEBUG
1606 printk(KERN_DEBUG "%s: ssn mismatch [%d != %d]\n.",
1607 wiphy_name(ar->hw->wiphy), seq, tmpssn);
1608#endif /* AR9170_TXAGG_DEBUG */
1609 tid_info->ssn = tmpssn;
1610 }
1611
1612#ifdef AR9170_TXAGG_DEBUG
1613 printk(KERN_DEBUG "%s: generate A-MPDU for tid:%d ssn:%d with "
1614 "%d queued frames.\n", wiphy_name(ar->hw->wiphy),
1615 tid_info->tid, tid_info->ssn,
1616 skb_queue_len(&tid_info->queue));
1617 __ar9170_dump_txqueue(ar, &tid_info->queue);
1618#endif /* AR9170_TXAGG_DEBUG */
1619
1620 while ((skb = skb_peek(&tid_info->queue))) {
1621 if (unlikely(ar9170_get_seq(skb) != seq))
1622 break;
1623
1624 __skb_unlink(skb, &tid_info->queue);
1625 tid_info->ssn = seq = GET_NEXT_SEQ(seq);
1626
1627 if (unlikely(skb_get_queue_mapping(skb) != queue)) {
1628#ifdef AR9170_TXAGG_DEBUG
1629 printk(KERN_DEBUG "%s: tid:%d(q:%d) queue:%d "
1630 "!match.\n", wiphy_name(ar->hw->wiphy),
1631 tid_info->tid,
1632 TID_TO_WME_AC(tid_info->tid),
1633 skb_get_queue_mapping(skb));
1634#endif /* AR9170_TXAGG_DEBUG */
1635 dev_kfree_skb_any(skb);
1636 continue;
1637 }
1638
1639 if (unlikely(first == skb)) {
1640 ar9170_tx_prepare_phy(ar, skb);
1641 __skb_queue_tail(&agg, skb);
1642 first = skb;
1643 } else {
1644 ar9170_tx_copy_phy(ar, skb, first);
1645 __skb_queue_tail(&agg, skb);
1646 }
1647
1648 if (unlikely(skb_queue_len(&agg) ==
1649 AR9170_NUM_TX_AGG_MAX))
1650 break;
1651 }
1652
1653 if (skb_queue_empty(&tid_info->queue))
1654 tid_info->active = false;
1655 else
1656 list_add_tail(&tid_info->list,
1657 &ar->tx_ampdu_list);
1658
1659 spin_unlock_irqrestore(&tid_info->queue.lock, f2);
1660
1661 if (unlikely(skb_queue_empty(&agg))) {
1662#ifdef AR9170_TXAGG_DEBUG
1663 printk(KERN_DEBUG "%s: queued empty list!\n",
1664 wiphy_name(ar->hw->wiphy));
1665#endif /* AR9170_TXAGG_DEBUG */
1666 continue;
1667 }
1668
1669 /*
1670 * tell the FW/HW that this is the last frame,
1671 * that way it will wait for the immediate block ack.
1672 */
1673 if (likely(skb_peek_tail(&agg)))
1674 ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg));
1675
1676#ifdef AR9170_TXAGG_DEBUG
1677 printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n",
1678 wiphy_name(ar->hw->wiphy));
1679 __ar9170_dump_txqueue(ar, &agg);
1680#endif /* AR9170_TXAGG_DEBUG */
1681
1682 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1683
1684 spin_lock_irqsave(&ar->tx_pending[queue].lock, flags);
1685 skb_queue_splice_tail_init(&agg, &ar->tx_pending[queue]);
1686 spin_unlock_irqrestore(&ar->tx_pending[queue].lock, flags);
1687 run = true;
1688
1689 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1690 }
1691
1692out_unlock:
1693 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1694 __skb_queue_purge(&agg);
1695
1696 return run;
1697}
1698
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001699static void ar9170_tx(struct ar9170 *ar)
1700{
1701 struct sk_buff *skb;
1702 unsigned long flags;
1703 struct ieee80211_tx_info *info;
1704 struct ar9170_tx_info *arinfo;
1705 unsigned int i, frames, frames_failed, remaining_space;
1706 int err;
1707 bool schedule_garbagecollector = false;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001708
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001709 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001710
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001711 if (unlikely(!IS_STARTED(ar)))
1712 return ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001713
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001714 remaining_space = AR9170_TX_MAX_PENDING;
1715
1716 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1717 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1718 if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
1719#ifdef AR9170_QUEUE_DEBUG
1720 printk(KERN_DEBUG "%s: queue %d full\n",
1721 wiphy_name(ar->hw->wiphy), i);
1722
Christian Lamparteracbadf02009-07-11 17:24:14 +02001723 printk(KERN_DEBUG "%s: stuck frames: ===> \n",
1724 wiphy_name(ar->hw->wiphy));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001725 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1726 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
1727#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparteracbadf02009-07-11 17:24:14 +02001728
1729#ifdef AR9170_QUEUE_STOP_DEBUG
1730 printk(KERN_DEBUG "%s: stop queue %d\n",
1731 wiphy_name(ar->hw->wiphy), i);
1732 __ar9170_dump_txstats(ar);
1733#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001734 ieee80211_stop_queue(ar->hw, i);
1735 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1736 continue;
1737 }
1738
1739 frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
1740 skb_queue_len(&ar->tx_pending[i]));
1741
1742 if (remaining_space < frames) {
1743#ifdef AR9170_QUEUE_DEBUG
1744 printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
1745 "remaining slots:%d, needed:%d\n",
1746 wiphy_name(ar->hw->wiphy), i, remaining_space,
1747 frames);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001748#endif /* AR9170_QUEUE_DEBUG */
1749 frames = remaining_space;
1750 }
1751
1752 ar->tx_stats[i].len += frames;
1753 ar->tx_stats[i].count += frames;
1754 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1755
1756 if (!frames)
1757 continue;
1758
1759 frames_failed = 0;
1760 while (frames) {
1761 skb = skb_dequeue(&ar->tx_pending[i]);
1762 if (unlikely(!skb)) {
1763 frames_failed += frames;
1764 frames = 0;
1765 break;
1766 }
1767
1768 info = IEEE80211_SKB_CB(skb);
1769 arinfo = (void *) info->rate_driver_data;
1770
1771 /* TODO: cancel stuck frames */
1772 arinfo->timeout = jiffies +
1773 msecs_to_jiffies(AR9170_TX_TIMEOUT);
1774
Christian Lamparteracbadf02009-07-11 17:24:14 +02001775 if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK)
1776 ar->tx_ampdu_pending++;
1777
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001778#ifdef AR9170_QUEUE_DEBUG
1779 printk(KERN_DEBUG "%s: send frame q:%d =>\n",
1780 wiphy_name(ar->hw->wiphy), i);
1781 ar9170_print_txheader(ar, skb);
1782#endif /* AR9170_QUEUE_DEBUG */
1783
1784 err = ar->tx(ar, skb);
1785 if (unlikely(err)) {
Christian Lamparteracbadf02009-07-11 17:24:14 +02001786 if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK)
1787 ar->tx_ampdu_pending--;
1788
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001789 frames_failed++;
1790 dev_kfree_skb_any(skb);
1791 } else {
1792 remaining_space--;
1793 schedule_garbagecollector = true;
1794 }
1795
1796 frames--;
1797 }
1798
1799#ifdef AR9170_QUEUE_DEBUG
1800 printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n",
1801 wiphy_name(ar->hw->wiphy), i);
1802
1803 printk(KERN_DEBUG "%s: unprocessed pending frames left:\n",
1804 wiphy_name(ar->hw->wiphy));
1805 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1806#endif /* AR9170_QUEUE_DEBUG */
1807
1808 if (unlikely(frames_failed)) {
1809#ifdef AR9170_QUEUE_DEBUG
Christian Lamparteracbadf02009-07-11 17:24:14 +02001810 printk(KERN_DEBUG "%s: frames failed %d =>\n",
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001811 wiphy_name(ar->hw->wiphy), frames_failed);
1812#endif /* AR9170_QUEUE_DEBUG */
1813
1814 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1815 ar->tx_stats[i].len -= frames_failed;
1816 ar->tx_stats[i].count -= frames_failed;
Christian Lamparteracbadf02009-07-11 17:24:14 +02001817#ifdef AR9170_QUEUE_STOP_DEBUG
1818 printk(KERN_DEBUG "%s: wake queue %d\n",
1819 wiphy_name(ar->hw->wiphy), i);
1820 __ar9170_dump_txstats(ar);
1821#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001822 ieee80211_wake_queue(ar->hw, i);
1823 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001824 }
1825 }
1826
Luis R. Rodriguez42935ec2009-07-29 20:08:07 -04001827 if (!schedule_garbagecollector)
1828 return;
1829
1830 ieee80211_queue_delayed_work(ar->hw,
1831 &ar->tx_janitor,
1832 msecs_to_jiffies(AR9170_JANITOR_DELAY));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001833}
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;
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07001955 struct ath_common *common = &ar->common;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001956 int err = 0;
1957
1958 mutex_lock(&ar->mutex);
1959
1960 if (ar->vif) {
1961 err = -EBUSY;
1962 goto unlock;
1963 }
1964
1965 ar->vif = conf->vif;
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07001966 memcpy(common->macaddr, conf->mac_addr, ETH_ALEN);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001967
1968 if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
1969 ar->rx_software_decryption = true;
1970 ar->disable_offload = true;
1971 }
1972
1973 ar->cur_filter = 0;
Christian Lampartereeef4182009-08-19 12:43:47 +02001974 err = ar9170_update_frame_filter(ar, AR9170_MAC_REG_FTF_DEFAULTS);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001975 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;
Christian Lampartereeef4182009-08-19 12:43:47 +02001992 ar9170_update_frame_filter(ar, 0);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001993 ar9170_set_beacon_timers(ar);
1994 dev_kfree_skb(ar->beacon);
1995 ar->beacon = NULL;
1996 ar->sniffer_enabled = false;
1997 ar->rx_software_decryption = false;
1998 ar9170_set_operating_mode(ar);
1999 mutex_unlock(&ar->mutex);
2000}
2001
2002static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
2003{
2004 struct ar9170 *ar = hw->priv;
2005 int err = 0;
2006
2007 mutex_lock(&ar->mutex);
2008
Christian Lampartere9348cd2009-03-21 23:05:13 +01002009 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
2010 /* TODO */
2011 err = 0;
2012 }
2013
2014 if (changed & IEEE80211_CONF_CHANGE_PS) {
2015 /* TODO */
2016 err = 0;
2017 }
2018
2019 if (changed & IEEE80211_CONF_CHANGE_POWER) {
2020 /* TODO */
2021 err = 0;
2022 }
2023
2024 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
2025 /*
2026 * is it long_frame_max_tx_count or short_frame_max_tx_count?
2027 */
2028
2029 err = ar9170_set_hwretry_limit(ar,
2030 ar->hw->conf.long_frame_max_tx_count);
2031 if (err)
2032 goto out;
2033 }
2034
Christian Lampartere9348cd2009-03-21 23:05:13 +01002035 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002036
2037 /* adjust slot time for 5 GHz */
2038 err = ar9170_set_slot_time(ar);
2039 if (err)
2040 goto out;
2041
2042 err = ar9170_set_dyn_sifs_ack(ar);
2043 if (err)
2044 goto out;
2045
Christian Lampartere9348cd2009-03-21 23:05:13 +01002046 err = ar9170_set_channel(ar, hw->conf.channel,
Johannes Berg9e52b06232009-04-20 18:27:04 +02002047 AR9170_RFI_NONE,
2048 nl80211_to_ar9170(hw->conf.channel_type));
Christian Lampartere9348cd2009-03-21 23:05:13 +01002049 if (err)
2050 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002051 }
2052
2053out:
2054 mutex_unlock(&ar->mutex);
2055 return err;
2056}
2057
Johannes Berg3ac64be2009-08-17 16:16:53 +02002058static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
2059 struct dev_addr_list *mclist)
2060{
2061 u64 mchash;
2062 int i;
2063
2064 /* always get broadcast frames */
2065 mchash = 1ULL << (0xff >> 2);
2066
2067 for (i = 0; i < mc_count; i++) {
2068 if (WARN_ON(!mclist))
2069 break;
2070 mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
2071 mclist = mclist->next;
2072 }
2073
2074 return mchash;
2075}
2076
Christian Lampartere9348cd2009-03-21 23:05:13 +01002077static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
2078 unsigned int changed_flags,
2079 unsigned int *new_flags,
Johannes Berg3ac64be2009-08-17 16:16:53 +02002080 u64 multicast)
Christian Lampartere9348cd2009-03-21 23:05:13 +01002081{
2082 struct ar9170 *ar = hw->priv;
2083
Christian Lampartereeef4182009-08-19 12:43:47 +02002084 if (unlikely(!IS_ACCEPTING_CMD(ar)))
2085 return ;
2086
2087 mutex_lock(&ar->mutex);
2088
Christian Lampartere9348cd2009-03-21 23:05:13 +01002089 /* mask supported flags */
2090 *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
Christian Lampartercca847992009-04-19 01:28:12 +02002091 FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
2092 ar->filter_state = *new_flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002093 /*
2094 * We can support more by setting the sniffer bit and
2095 * then checking the error flags, later.
2096 */
2097
Johannes Berg3ac64be2009-08-17 16:16:53 +02002098 if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
Christian Lampartereeef4182009-08-19 12:43:47 +02002099 multicast = ~0ULL;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002100
Christian Lampartereeef4182009-08-19 12:43:47 +02002101 if (multicast != ar->cur_mc_hash)
2102 ar9170_update_multicast(ar, multicast);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002103
2104 if (changed_flags & FIF_CONTROL) {
2105 u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
2106 AR9170_MAC_REG_FTF_RTS |
2107 AR9170_MAC_REG_FTF_CTS |
2108 AR9170_MAC_REG_FTF_ACK |
2109 AR9170_MAC_REG_FTF_CFE |
2110 AR9170_MAC_REG_FTF_CFE_ACK;
2111
2112 if (*new_flags & FIF_CONTROL)
Christian Lampartereeef4182009-08-19 12:43:47 +02002113 filter |= ar->cur_filter;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002114 else
Christian Lampartereeef4182009-08-19 12:43:47 +02002115 filter &= (~ar->cur_filter);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002116
Christian Lampartereeef4182009-08-19 12:43:47 +02002117 ar9170_update_frame_filter(ar, filter);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002118 }
2119
2120 if (changed_flags & FIF_PROMISC_IN_BSS) {
2121 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
Christian Lampartereeef4182009-08-19 12:43:47 +02002122 ar9170_set_operating_mode(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002123 }
2124
Christian Lampartereeef4182009-08-19 12:43:47 +02002125 mutex_unlock(&ar->mutex);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002126}
2127
Christian Lampartereeef4182009-08-19 12:43:47 +02002128
Christian Lampartere9348cd2009-03-21 23:05:13 +01002129static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
2130 struct ieee80211_vif *vif,
2131 struct ieee80211_bss_conf *bss_conf,
2132 u32 changed)
2133{
2134 struct ar9170 *ar = hw->priv;
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07002135 struct ath_common *common = &ar->common;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002136 int err = 0;
2137
2138 mutex_lock(&ar->mutex);
2139
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002140 if (changed & BSS_CHANGED_BSSID) {
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07002141 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002142 err = ar9170_set_operating_mode(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02002143 if (err)
2144 goto out;
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002145 }
2146
Joerg Albertea39d1a2009-08-21 23:25:07 +02002147 if (changed & BSS_CHANGED_BEACON_ENABLED)
2148 ar->enable_beacon = bss_conf->enable_beacon;
2149
2150 if (changed & BSS_CHANGED_BEACON) {
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002151 err = ar9170_update_beacon(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02002152 if (err)
2153 goto out;
Joerg Albertea39d1a2009-08-21 23:25:07 +02002154 }
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002155
Joerg Albertea39d1a2009-08-21 23:25:07 +02002156 if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON |
2157 BSS_CHANGED_BEACON_INT)) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002158 err = ar9170_set_beacon_timers(ar);
2159 if (err)
2160 goto out;
2161 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01002162
2163 if (changed & BSS_CHANGED_ASSOC) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002164#ifndef CONFIG_AR9170_LEDS
2165 /* enable assoc LED. */
2166 err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
2167#endif /* CONFIG_AR9170_LEDS */
2168 }
2169
2170 if (changed & BSS_CHANGED_HT) {
2171 /* TODO */
2172 err = 0;
2173 }
2174
2175 if (changed & BSS_CHANGED_ERP_SLOT) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002176 err = ar9170_set_slot_time(ar);
2177 if (err)
2178 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002179 }
2180
2181 if (changed & BSS_CHANGED_BASIC_RATES) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002182 err = ar9170_set_basic_rates(ar);
2183 if (err)
2184 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002185 }
2186
Christian Lamparter29ceff52009-06-01 21:42:01 +02002187out:
Christian Lampartere9348cd2009-03-21 23:05:13 +01002188 mutex_unlock(&ar->mutex);
2189}
2190
2191static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
2192{
2193 struct ar9170 *ar = hw->priv;
2194 int err;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002195 u64 tsf;
Joerg Albert181af382009-09-15 23:27:53 +02002196#define NR 3
2197 static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H,
2198 AR9170_MAC_REG_TSF_L,
2199 AR9170_MAC_REG_TSF_H };
2200 u32 val[NR];
2201 int loops = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002202
2203 mutex_lock(&ar->mutex);
Joerg Albert181af382009-09-15 23:27:53 +02002204
2205 while (loops++ < 10) {
2206 err = ar9170_read_mreg(ar, NR, addr, val);
2207 if (err || val[0] == val[2])
2208 break;
2209 }
2210
Christian Lampartere9348cd2009-03-21 23:05:13 +01002211 mutex_unlock(&ar->mutex);
2212
2213 if (WARN_ON(err))
2214 return 0;
Joerg Albert181af382009-09-15 23:27:53 +02002215 tsf = val[0];
2216 tsf = (tsf << 32) | val[1];
Christian Lampartere9348cd2009-03-21 23:05:13 +01002217 return tsf;
Joerg Albert181af382009-09-15 23:27:53 +02002218#undef NR
Christian Lampartere9348cd2009-03-21 23:05:13 +01002219}
2220
2221static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2222 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
2223 struct ieee80211_key_conf *key)
2224{
2225 struct ar9170 *ar = hw->priv;
2226 int err = 0, i;
2227 u8 ktype;
2228
2229 if ((!ar->vif) || (ar->disable_offload))
2230 return -EOPNOTSUPP;
2231
2232 switch (key->alg) {
2233 case ALG_WEP:
Zhu Yie31a16d2009-05-21 21:47:03 +08002234 if (key->keylen == WLAN_KEY_LEN_WEP40)
Christian Lampartere9348cd2009-03-21 23:05:13 +01002235 ktype = AR9170_ENC_ALG_WEP64;
2236 else
2237 ktype = AR9170_ENC_ALG_WEP128;
2238 break;
2239 case ALG_TKIP:
2240 ktype = AR9170_ENC_ALG_TKIP;
2241 break;
2242 case ALG_CCMP:
2243 ktype = AR9170_ENC_ALG_AESCCMP;
2244 break;
2245 default:
2246 return -EOPNOTSUPP;
2247 }
2248
2249 mutex_lock(&ar->mutex);
2250 if (cmd == SET_KEY) {
2251 if (unlikely(!IS_STARTED(ar))) {
2252 err = -EOPNOTSUPP;
2253 goto out;
2254 }
2255
2256 /* group keys need all-zeroes address */
2257 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
2258 sta = NULL;
2259
2260 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
2261 for (i = 0; i < 64; i++)
2262 if (!(ar->usedkeys & BIT(i)))
2263 break;
2264 if (i == 64) {
2265 ar->rx_software_decryption = true;
2266 ar9170_set_operating_mode(ar);
2267 err = -ENOSPC;
2268 goto out;
2269 }
2270 } else {
2271 i = 64 + key->keyidx;
2272 }
2273
2274 key->hw_key_idx = i;
2275
2276 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
2277 key->key, min_t(u8, 16, key->keylen));
2278 if (err)
2279 goto out;
2280
2281 if (key->alg == ALG_TKIP) {
2282 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
2283 ktype, 1, key->key + 16, 16);
2284 if (err)
2285 goto out;
2286
2287 /*
2288 * hardware is not capable generating the MMIC
2289 * for fragmented frames!
2290 */
2291 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
2292 }
2293
2294 if (i < 64)
2295 ar->usedkeys |= BIT(i);
2296
2297 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
2298 } else {
2299 if (unlikely(!IS_STARTED(ar))) {
2300 /* The device is gone... together with the key ;-) */
2301 err = 0;
2302 goto out;
2303 }
2304
2305 err = ar9170_disable_key(ar, key->hw_key_idx);
2306 if (err)
2307 goto out;
2308
2309 if (key->hw_key_idx < 64) {
2310 ar->usedkeys &= ~BIT(key->hw_key_idx);
2311 } else {
2312 err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
2313 AR9170_ENC_ALG_NONE, 0,
2314 NULL, 0);
2315 if (err)
2316 goto out;
2317
2318 if (key->alg == ALG_TKIP) {
2319 err = ar9170_upload_key(ar, key->hw_key_idx,
2320 NULL,
2321 AR9170_ENC_ALG_NONE, 1,
2322 NULL, 0);
2323 if (err)
2324 goto out;
2325 }
2326
2327 }
2328 }
2329
2330 ar9170_regwrite_begin(ar);
2331 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
2332 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
2333 ar9170_regwrite_finish();
2334 err = ar9170_regwrite_result();
2335
2336out:
2337 mutex_unlock(&ar->mutex);
2338
2339 return err;
2340}
2341
2342static void ar9170_sta_notify(struct ieee80211_hw *hw,
2343 struct ieee80211_vif *vif,
2344 enum sta_notify_cmd cmd,
2345 struct ieee80211_sta *sta)
2346{
Christian Lamparteracbadf02009-07-11 17:24:14 +02002347 struct ar9170 *ar = hw->priv;
2348 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2349 unsigned int i;
2350
2351 switch (cmd) {
2352 case STA_NOTIFY_ADD:
2353 memset(sta_info, 0, sizeof(*sta_info));
2354
2355 if (!sta->ht_cap.ht_supported)
2356 break;
2357
2358 if (sta->ht_cap.ampdu_density > ar->global_ampdu_density)
2359 ar->global_ampdu_density = sta->ht_cap.ampdu_density;
2360
2361 if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor)
2362 ar->global_ampdu_factor = sta->ht_cap.ampdu_factor;
2363
2364 for (i = 0; i < AR9170_NUM_TID; i++) {
2365 sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN;
2366 sta_info->agg[i].active = false;
2367 sta_info->agg[i].ssn = 0;
2368 sta_info->agg[i].retry = 0;
2369 sta_info->agg[i].tid = i;
2370 INIT_LIST_HEAD(&sta_info->agg[i].list);
2371 skb_queue_head_init(&sta_info->agg[i].queue);
2372 }
2373
2374 sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor);
2375 break;
2376
2377 case STA_NOTIFY_REMOVE:
2378 if (!sta->ht_cap.ht_supported)
2379 break;
2380
2381 for (i = 0; i < AR9170_NUM_TID; i++) {
2382 sta_info->agg[i].state = AR9170_TID_STATE_INVALID;
2383 skb_queue_purge(&sta_info->agg[i].queue);
2384 }
2385
2386 break;
2387
2388 default:
2389 break;
2390 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01002391}
2392
2393static int ar9170_get_stats(struct ieee80211_hw *hw,
2394 struct ieee80211_low_level_stats *stats)
2395{
2396 struct ar9170 *ar = hw->priv;
2397 u32 val;
2398 int err;
2399
2400 mutex_lock(&ar->mutex);
2401 err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
2402 ar->stats.dot11ACKFailureCount += val;
2403
2404 memcpy(stats, &ar->stats, sizeof(*stats));
2405 mutex_unlock(&ar->mutex);
2406
2407 return 0;
2408}
2409
2410static int ar9170_get_tx_stats(struct ieee80211_hw *hw,
2411 struct ieee80211_tx_queue_stats *tx_stats)
2412{
2413 struct ar9170 *ar = hw->priv;
2414
2415 spin_lock_bh(&ar->tx_stats_lock);
2416 memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues);
2417 spin_unlock_bh(&ar->tx_stats_lock);
2418
2419 return 0;
2420}
2421
2422static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
2423 const struct ieee80211_tx_queue_params *param)
2424{
2425 struct ar9170 *ar = hw->priv;
2426 int ret;
2427
2428 mutex_lock(&ar->mutex);
Dan Carpentere9d126c2009-08-09 14:24:09 +02002429 if (queue < __AR9170_NUM_TXQ) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002430 memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
2431 param, sizeof(*param));
2432
2433 ret = ar9170_set_qos(ar);
Dan Carpentere9d126c2009-08-09 14:24:09 +02002434 } else {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002435 ret = -EINVAL;
Dan Carpentere9d126c2009-08-09 14:24:09 +02002436 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01002437
2438 mutex_unlock(&ar->mutex);
2439 return ret;
2440}
2441
Johannes Berg9e52b06232009-04-20 18:27:04 +02002442static int ar9170_ampdu_action(struct ieee80211_hw *hw,
2443 enum ieee80211_ampdu_mlme_action action,
2444 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
2445{
Christian Lamparteracbadf02009-07-11 17:24:14 +02002446 struct ar9170 *ar = hw->priv;
2447 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2448 struct ar9170_sta_tid *tid_info = &sta_info->agg[tid];
2449 unsigned long flags;
2450
2451 if (!modparam_ht)
2452 return -EOPNOTSUPP;
2453
Johannes Berg9e52b06232009-04-20 18:27:04 +02002454 switch (action) {
Christian Lamparteracbadf02009-07-11 17:24:14 +02002455 case IEEE80211_AMPDU_TX_START:
2456 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2457 if (tid_info->state != AR9170_TID_STATE_SHUTDOWN ||
2458 !list_empty(&tid_info->list)) {
2459 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2460#ifdef AR9170_TXAGG_DEBUG
2461 printk(KERN_INFO "%s: A-MPDU [ESS:[%pM] tid:[%d]] "
2462 "is in a very bad state!\n",
2463 wiphy_name(hw->wiphy), sta->addr, tid);
2464#endif /* AR9170_TXAGG_DEBUG */
2465 return -EBUSY;
2466 }
2467
2468 *ssn = tid_info->ssn;
2469 tid_info->state = AR9170_TID_STATE_PROGRESS;
2470 tid_info->active = false;
2471 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2472 ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
2473 break;
2474
2475 case IEEE80211_AMPDU_TX_STOP:
2476 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2477 tid_info->state = AR9170_TID_STATE_SHUTDOWN;
2478 list_del_init(&tid_info->list);
2479 tid_info->active = false;
2480 skb_queue_purge(&tid_info->queue);
2481 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2482 ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
2483 break;
2484
2485 case IEEE80211_AMPDU_TX_OPERATIONAL:
2486#ifdef AR9170_TXAGG_DEBUG
2487 printk(KERN_INFO "%s: A-MPDU for %pM [tid:%d] Operational.\n",
2488 wiphy_name(hw->wiphy), sta->addr, tid);
2489#endif /* AR9170_TXAGG_DEBUG */
2490 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2491 sta_info->agg[tid].state = AR9170_TID_STATE_COMPLETE;
2492 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2493 break;
2494
Johannes Berg9e52b06232009-04-20 18:27:04 +02002495 case IEEE80211_AMPDU_RX_START:
2496 case IEEE80211_AMPDU_RX_STOP:
Christian Lamparteracbadf02009-07-11 17:24:14 +02002497 /* Handled by firmware */
2498 break;
2499
Johannes Berg9e52b06232009-04-20 18:27:04 +02002500 default:
2501 return -EOPNOTSUPP;
2502 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02002503
2504 return 0;
Johannes Berg9e52b06232009-04-20 18:27:04 +02002505}
2506
Christian Lampartere9348cd2009-03-21 23:05:13 +01002507static const struct ieee80211_ops ar9170_ops = {
2508 .start = ar9170_op_start,
2509 .stop = ar9170_op_stop,
2510 .tx = ar9170_op_tx,
2511 .add_interface = ar9170_op_add_interface,
2512 .remove_interface = ar9170_op_remove_interface,
2513 .config = ar9170_op_config,
Johannes Berg3ac64be2009-08-17 16:16:53 +02002514 .prepare_multicast = ar9170_op_prepare_multicast,
Christian Lampartere9348cd2009-03-21 23:05:13 +01002515 .configure_filter = ar9170_op_configure_filter,
2516 .conf_tx = ar9170_conf_tx,
2517 .bss_info_changed = ar9170_op_bss_info_changed,
2518 .get_tsf = ar9170_op_get_tsf,
2519 .set_key = ar9170_set_key,
2520 .sta_notify = ar9170_sta_notify,
2521 .get_stats = ar9170_get_stats,
2522 .get_tx_stats = ar9170_get_tx_stats,
Johannes Berg9e52b06232009-04-20 18:27:04 +02002523 .ampdu_action = ar9170_ampdu_action,
Christian Lampartere9348cd2009-03-21 23:05:13 +01002524};
2525
2526void *ar9170_alloc(size_t priv_size)
2527{
2528 struct ieee80211_hw *hw;
2529 struct ar9170 *ar;
Christian Lampartercca847992009-04-19 01:28:12 +02002530 struct sk_buff *skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002531 int i;
2532
Christian Lampartercca847992009-04-19 01:28:12 +02002533 /*
2534 * this buffer is used for rx stream reconstruction.
2535 * Under heavy load this device (or the transport layer?)
2536 * tends to split the streams into seperate rx descriptors.
2537 */
2538
2539 skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL);
2540 if (!skb)
2541 goto err_nomem;
2542
Christian Lampartere9348cd2009-03-21 23:05:13 +01002543 hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
2544 if (!hw)
Christian Lampartercca847992009-04-19 01:28:12 +02002545 goto err_nomem;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002546
2547 ar = hw->priv;
2548 ar->hw = hw;
Christian Lampartercca847992009-04-19 01:28:12 +02002549 ar->rx_failover = skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002550
2551 mutex_init(&ar->mutex);
2552 spin_lock_init(&ar->cmdlock);
2553 spin_lock_init(&ar->tx_stats_lock);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002554 spin_lock_init(&ar->tx_ampdu_list_lock);
2555 skb_queue_head_init(&ar->tx_status_ampdu);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002556 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
2557 skb_queue_head_init(&ar->tx_status[i]);
2558 skb_queue_head_init(&ar->tx_pending[i]);
2559 }
Christian Lampartercca847992009-04-19 01:28:12 +02002560 ar9170_rx_reset_rx_mpdu(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002561 INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002562 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002563 INIT_LIST_HEAD(&ar->tx_ampdu_list);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002564
2565 /* all hw supports 2.4 GHz, so set channel to 1 by default */
2566 ar->channel = &ar9170_2ghz_chantable[0];
2567
2568 /* first part of wiphy init */
2569 ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2570 BIT(NL80211_IFTYPE_WDS) |
2571 BIT(NL80211_IFTYPE_ADHOC);
2572 ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
2573 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
2574 IEEE80211_HW_SIGNAL_DBM |
2575 IEEE80211_HW_NOISE_DBM;
2576
Christian Lamparteracbadf02009-07-11 17:24:14 +02002577 if (modparam_ht) {
2578 ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
2579 } else {
2580 ar9170_band_2GHz.ht_cap.ht_supported = false;
2581 ar9170_band_5GHz.ht_cap.ht_supported = false;
2582 }
2583
Christian Lamparter4a48e2a2009-03-23 12:15:43 +01002584 ar->hw->queues = __AR9170_NUM_TXQ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002585 ar->hw->extra_tx_headroom = 8;
2586 ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
2587
2588 ar->hw->max_rates = 1;
2589 ar->hw->max_rate_tries = 3;
2590
2591 for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
2592 ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
2593
2594 return ar;
Christian Lampartercca847992009-04-19 01:28:12 +02002595
2596err_nomem:
2597 kfree_skb(skb);
2598 return ERR_PTR(-ENOMEM);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002599}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002600
2601static int ar9170_read_eeprom(struct ar9170 *ar)
2602{
2603#define RW 8 /* number of words to read at once */
2604#define RB (sizeof(u32) * RW)
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002605 struct ath_regulatory *regulatory = &ar->common.regulatory;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002606 u8 *eeprom = (void *)&ar->eeprom;
2607 u8 *addr = ar->eeprom.mac_address;
2608 __le32 offsets[RW];
Christian Lamparteracbadf02009-07-11 17:24:14 +02002609 unsigned int rx_streams, tx_streams, tx_params = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002610 int i, j, err, bands = 0;
2611
2612 BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
2613
2614 BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
2615#ifndef __CHECKER__
2616 /* don't want to handle trailing remains */
2617 BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
2618#endif
2619
2620 for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
2621 for (j = 0; j < RW; j++)
2622 offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
2623 RB * i + 4 * j);
2624
2625 err = ar->exec_cmd(ar, AR9170_CMD_RREG,
2626 RB, (u8 *) &offsets,
2627 RB, eeprom + RB * i);
2628 if (err)
2629 return err;
2630 }
2631
2632#undef RW
2633#undef RB
2634
2635 if (ar->eeprom.length == cpu_to_le16(0xFFFF))
2636 return -ENODATA;
2637
2638 if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
2639 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
2640 bands++;
2641 }
2642 if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
2643 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
2644 bands++;
2645 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02002646
2647 rx_streams = hweight8(ar->eeprom.rx_mask);
2648 tx_streams = hweight8(ar->eeprom.tx_mask);
2649
2650 if (rx_streams != tx_streams)
2651 tx_params = IEEE80211_HT_MCS_TX_RX_DIFF;
2652
2653 if (tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS)
2654 tx_params = (tx_streams - 1) <<
2655 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
2656
2657 ar9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
2658 ar9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params;
2659
Christian Lampartere9348cd2009-03-21 23:05:13 +01002660 /*
2661 * I measured this, a bandswitch takes roughly
2662 * 135 ms and a frequency switch about 80.
2663 *
2664 * FIXME: measure these values again once EEPROM settings
2665 * are used, that will influence them!
2666 */
2667 if (bands == 2)
2668 ar->hw->channel_change_time = 135 * 1000;
2669 else
2670 ar->hw->channel_change_time = 80 * 1000;
2671
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002672 regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
2673 regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
Christian Lamparter1878f772009-03-30 22:30:32 -04002674
Christian Lampartere9348cd2009-03-21 23:05:13 +01002675 /* second part of wiphy init */
2676 SET_IEEE80211_PERM_ADDR(ar->hw, addr);
2677
2678 return bands ? 0 : -EINVAL;
2679}
2680
Christian Lamparter1878f772009-03-30 22:30:32 -04002681static int ar9170_reg_notifier(struct wiphy *wiphy,
2682 struct regulatory_request *request)
2683{
2684 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2685 struct ar9170 *ar = hw->priv;
2686
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002687 return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory);
Christian Lamparter1878f772009-03-30 22:30:32 -04002688}
2689
Christian Lampartere9348cd2009-03-21 23:05:13 +01002690int ar9170_register(struct ar9170 *ar, struct device *pdev)
2691{
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002692 struct ath_regulatory *regulatory = &ar->common.regulatory;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002693 int err;
2694
2695 /* try to read EEPROM, init MAC addr */
2696 err = ar9170_read_eeprom(ar);
2697 if (err)
2698 goto err_out;
2699
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002700 err = ath_regd_init(regulatory, ar->hw->wiphy,
Christian Lamparter1878f772009-03-30 22:30:32 -04002701 ar9170_reg_notifier);
Luis R. Rodriguez85efc862009-04-13 21:41:46 -04002702 if (err)
2703 goto err_out;
Christian Lamparter1878f772009-03-30 22:30:32 -04002704
Christian Lampartere9348cd2009-03-21 23:05:13 +01002705 err = ieee80211_register_hw(ar->hw);
2706 if (err)
2707 goto err_out;
2708
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002709 if (!ath_is_world_regd(regulatory))
2710 regulatory_hint(ar->hw->wiphy, regulatory->alpha2);
Christian Lamparter1878f772009-03-30 22:30:32 -04002711
Christian Lampartere9348cd2009-03-21 23:05:13 +01002712 err = ar9170_init_leds(ar);
2713 if (err)
2714 goto err_unreg;
2715
2716#ifdef CONFIG_AR9170_LEDS
2717 err = ar9170_register_leds(ar);
2718 if (err)
2719 goto err_unreg;
2720#endif /* CONFIG_AR9170_LEDS */
2721
2722 dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
2723 wiphy_name(ar->hw->wiphy));
2724
2725 return err;
2726
2727err_unreg:
2728 ieee80211_unregister_hw(ar->hw);
2729
2730err_out:
2731 return err;
2732}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002733
2734void ar9170_unregister(struct ar9170 *ar)
2735{
2736#ifdef CONFIG_AR9170_LEDS
2737 ar9170_unregister_leds(ar);
2738#endif /* CONFIG_AR9170_LEDS */
2739
Christian Lampartercca847992009-04-19 01:28:12 +02002740 kfree_skb(ar->rx_failover);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002741 ieee80211_unregister_hw(ar->hw);
2742 mutex_destroy(&ar->mutex);
2743}