blob: d8ecf8554d016dbda395d9b7244cdff334d54be4 [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 Berg9e52b062009-04-20 18:27:04 +0200149#define AR9170_HT_CAP \
150{ \
151 .ht_supported = true, \
152 .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
Johannes Berg9e52b062009-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 Berg9e52b062009-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 Berg9e52b062009-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 Berg9e52b062009-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 Berg9e52b062009-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 Lamparter15b098b2009-11-29 00:56:55 +0100216 printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] 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 Lamparter15b098b2009-11-29 00:56:55 +0100219 ieee80211_get_DA(hdr), 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);
Christian Lamparteracbadf02009-07-11 17:24:14 +0200417
Christian Lamparter02bdf5b2009-10-17 21:56:43 +0200418 if (atomic_dec_and_test(&ar->tx_ampdu_pending) &&
419 !list_empty(&ar->tx_ampdu_list))
Christian Lamparteracbadf02009-07-11 17:24:14 +0200420 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 Lamparter53a76b52009-11-29 00:52:51 +0100433 if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200434#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
Christian Lamparter15b098b2009-11-29 00:56:55 +0100443 if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200444 ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED);
445 } else {
Christian Lamparter15b098b2009-11-29 00:56:55 +0100446 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
447 ar9170_tx_ampdu_callback(ar, skb);
448 } else {
449 arinfo->timeout = jiffies +
450 msecs_to_jiffies(AR9170_TX_TIMEOUT);
451
452 skb_queue_tail(&ar->tx_status[queue], skb);
453 }
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200454 }
455
456 if (!ar->tx_stats[queue].len &&
457 !skb_queue_empty(&ar->tx_pending[queue])) {
458 ar9170_tx(ar);
459 }
Christian Lampartere9348cd2009-03-21 23:05:13 +0100460}
461
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200462static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
463 const u8 *mac,
464 struct sk_buff_head *queue,
465 const u32 rate)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100466{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200467 unsigned long flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100468 struct sk_buff *skb;
469
470 /*
471 * Unfortunately, the firmware does not tell to which (queued) frame
472 * this transmission status report belongs to.
473 *
474 * So we have to make risky guesses - with the scarce information
475 * the firmware provided (-> destination MAC, and phy_control) -
476 * and hope that we picked the right one...
477 */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100478
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200479 spin_lock_irqsave(&queue->lock, flags);
480 skb_queue_walk(queue, skb) {
481 struct ar9170_tx_control *txc = (void *) skb->data;
482 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
483 u32 r;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100484
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200485 if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) {
486#ifdef AR9170_QUEUE_DEBUG
487 printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n",
488 wiphy_name(ar->hw->wiphy), mac,
489 ieee80211_get_DA(hdr));
490 ar9170_print_txheader(ar, skb);
491#endif /* AR9170_QUEUE_DEBUG */
492 continue;
493 }
494
495 r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >>
496 AR9170_TX_PHY_MCS_SHIFT;
497
498 if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) {
499#ifdef AR9170_QUEUE_DEBUG
500 printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n",
501 wiphy_name(ar->hw->wiphy), rate, r);
502 ar9170_print_txheader(ar, skb);
503#endif /* AR9170_QUEUE_DEBUG */
504 continue;
505 }
506
507 __skb_unlink(skb, queue);
508 spin_unlock_irqrestore(&queue->lock, flags);
509 return skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100510 }
Christian Lampartere9348cd2009-03-21 23:05:13 +0100511
512#ifdef AR9170_QUEUE_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200513 printk(KERN_ERR "%s: ESS:[%pM] does not have any "
514 "outstanding frames in queue.\n",
515 wiphy_name(ar->hw->wiphy), mac);
516 __ar9170_dump_txqueue(ar, queue);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100517#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200518 spin_unlock_irqrestore(&queue->lock, flags);
519
520 return NULL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100521}
522
Christian Lamparteracbadf02009-07-11 17:24:14 +0200523static void ar9170_handle_block_ack(struct ar9170 *ar, u16 count, u16 r)
524{
525 struct sk_buff *skb;
526 struct ieee80211_tx_info *txinfo;
527
528 while (count) {
529 skb = ar9170_get_queued_skb(ar, NULL, &ar->tx_status_ampdu, r);
530 if (!skb)
531 break;
532
533 txinfo = IEEE80211_SKB_CB(skb);
534 ieee80211_tx_info_clear_status(txinfo);
535
536 /* FIXME: maybe more ? */
537 txinfo->status.rates[0].count = 1;
538
539 skb_pull(skb, sizeof(struct ar9170_tx_control));
540 ieee80211_tx_status_irqsafe(ar->hw, skb);
541 count--;
542 }
543
544#ifdef AR9170_TXAGG_DEBUG
545 if (count) {
546 printk(KERN_DEBUG "%s: got %d more failed mpdus, but no more "
547 "suitable frames left in tx_status queue.\n",
548 wiphy_name(ar->hw->wiphy), count);
549
550 ar9170_dump_tx_status_ampdu(ar);
551 }
552#endif /* AR9170_TXAGG_DEBUG */
553}
554
Christian Lampartere9348cd2009-03-21 23:05:13 +0100555/*
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200556 * This worker tries to keeps an maintain tx_status queues.
557 * So we can guarantee that incoming tx_status reports are
558 * actually for a pending frame.
Christian Lampartere9348cd2009-03-21 23:05:13 +0100559 */
560
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200561static void ar9170_tx_janitor(struct work_struct *work)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100562{
563 struct ar9170 *ar = container_of(work, struct ar9170,
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200564 tx_janitor.work);
565 struct sk_buff_head waste;
566 unsigned int i;
567 bool resched = false;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100568
Christian Lamparter4a48e2a2009-03-23 12:15:43 +0100569 if (unlikely(!IS_STARTED(ar)))
570 return ;
571
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200572 skb_queue_head_init(&waste);
573
574 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
Christian Lampartere9348cd2009-03-21 23:05:13 +0100575#ifdef AR9170_QUEUE_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200576 printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n",
577 wiphy_name(ar->hw->wiphy), i);
578 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
579 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100580#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200581
582 ar9170_recycle_expired(ar, &ar->tx_status[i], &waste);
583 ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste);
584 skb_queue_purge(&waste);
585
586 if (!skb_queue_empty(&ar->tx_status[i]) ||
587 !skb_queue_empty(&ar->tx_pending[i]))
588 resched = true;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100589 }
590
Christian Lamparteracbadf02009-07-11 17:24:14 +0200591 ar9170_tx_fake_ampdu_status(ar);
592
Luis R. Rodriguez42935ec2009-07-29 20:08:07 -0400593 if (!resched)
594 return;
595
596 ieee80211_queue_delayed_work(ar->hw,
597 &ar->tx_janitor,
598 msecs_to_jiffies(AR9170_JANITOR_DELAY));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100599}
600
Christian Lamparter66d00812009-05-28 17:04:27 +0200601void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100602{
603 struct ar9170_cmd_response *cmd = (void *) buf;
604
605 if ((cmd->type & 0xc0) != 0xc0) {
606 ar->callback_cmd(ar, len, buf);
607 return;
608 }
609
610 /* hardware event handlers */
611 switch (cmd->type) {
612 case 0xc1: {
613 /*
614 * TX status notification:
615 * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
616 *
617 * XX always 81
618 * YY always 00
619 * M1-M6 is the MAC address
620 * R1-R4 is the transmit rate
621 * S1-S2 is the transmit status
622 */
623
624 struct sk_buff *skb;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200625 u32 phy = le32_to_cpu(cmd->tx_status.rate);
626 u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >>
627 AR9170_TX_PHY_QOS_SHIFT;
628#ifdef AR9170_QUEUE_DEBUG
629 printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n",
630 wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q);
631#endif /* AR9170_QUEUE_DEBUG */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100632
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200633 skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst,
634 &ar->tx_status[q],
635 AR9170_TX_INVALID_RATE);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100636 if (unlikely(!skb))
637 return ;
638
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200639 ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100640 break;
641 }
642
643 case 0xc0:
644 /*
645 * pre-TBTT event
646 */
647 if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
Luis R. Rodriguez42935ec2009-07-29 20:08:07 -0400648 ieee80211_queue_work(ar->hw, &ar->beacon_work);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100649 break;
650
651 case 0xc2:
652 /*
653 * (IBSS) beacon send notification
654 * bytes: 04 c2 XX YY B4 B3 B2 B1
655 *
656 * XX always 80
657 * YY always 00
658 * B1-B4 "should" be the number of send out beacons.
659 */
660 break;
661
662 case 0xc3:
663 /* End of Atim Window */
664 break;
665
666 case 0xc4:
Christian Lamparteracbadf02009-07-11 17:24:14 +0200667 /* BlockACK bitmap */
668 break;
669
Christian Lampartere9348cd2009-03-21 23:05:13 +0100670 case 0xc5:
671 /* BlockACK events */
Christian Lamparteracbadf02009-07-11 17:24:14 +0200672 ar9170_handle_block_ack(ar,
673 le16_to_cpu(cmd->ba_fail_cnt.failed),
674 le16_to_cpu(cmd->ba_fail_cnt.rate));
675 ar9170_tx_fake_ampdu_status(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100676 break;
677
678 case 0xc6:
679 /* Watchdog Interrupt */
680 break;
681
682 case 0xc9:
683 /* retransmission issue / SIFS/EIFS collision ?! */
684 break;
685
Johannes Berg2543a0c2009-06-05 11:47:43 +0200686 /* firmware debug */
687 case 0xca:
688 printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, (char *)buf + 4);
689 break;
690 case 0xcb:
691 len -= 4;
692
693 switch (len) {
694 case 1:
695 printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n",
696 *((char *)buf + 4));
697 break;
698 case 2:
699 printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n",
700 le16_to_cpup((__le16 *)((char *)buf + 4)));
701 break;
702 case 4:
703 printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n",
704 le32_to_cpup((__le32 *)((char *)buf + 4)));
705 break;
706 case 8:
707 printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n",
708 (unsigned long)le64_to_cpup(
709 (__le64 *)((char *)buf + 4)));
710 break;
711 }
712 break;
713 case 0xcc:
714 print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE,
715 (char *)buf + 4, len - 4);
716 break;
717
Christian Lampartere9348cd2009-03-21 23:05:13 +0100718 default:
719 printk(KERN_INFO "received unhandled event %x\n", cmd->type);
720 print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
721 break;
722 }
723}
724
Christian Lampartercca847992009-04-19 01:28:12 +0200725static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100726{
Christian Lampartercca847992009-04-19 01:28:12 +0200727 memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head));
728 ar->rx_mpdu.has_plcp = false;
729}
Christian Lampartere9348cd2009-03-21 23:05:13 +0100730
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200731int ar9170_nag_limiter(struct ar9170 *ar)
Christian Lampartercca847992009-04-19 01:28:12 +0200732{
733 bool print_message;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100734
Christian Lampartercca847992009-04-19 01:28:12 +0200735 /*
736 * we expect all sorts of errors in promiscuous mode.
737 * don't bother with it, it's OK!
738 */
739 if (ar->sniffer_enabled)
740 return false;
741
742 /*
743 * only go for frequent errors! The hardware tends to
744 * do some stupid thing once in a while under load, in
745 * noisy environments or just for fun!
746 */
747 if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit())
748 print_message = true;
749 else
750 print_message = false;
751
752 /* reset threshold for "once in a while" */
753 ar->bad_hw_nagger = jiffies + HZ / 4;
754 return print_message;
755}
756
757static int ar9170_rx_mac_status(struct ar9170 *ar,
758 struct ar9170_rx_head *head,
759 struct ar9170_rx_macstatus *mac,
760 struct ieee80211_rx_status *status)
761{
762 u8 error, decrypt;
763
Christian Lampartere9348cd2009-03-21 23:05:13 +0100764 BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
Christian Lampartercca847992009-04-19 01:28:12 +0200765 BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100766
Christian Lampartercca847992009-04-19 01:28:12 +0200767 error = mac->error;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100768 if (error & AR9170_RX_ERROR_MMIC) {
Christian Lampartercca847992009-04-19 01:28:12 +0200769 status->flag |= RX_FLAG_MMIC_ERROR;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100770 error &= ~AR9170_RX_ERROR_MMIC;
771 }
772
773 if (error & AR9170_RX_ERROR_PLCP) {
Christian Lampartercca847992009-04-19 01:28:12 +0200774 status->flag |= RX_FLAG_FAILED_PLCP_CRC;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100775 error &= ~AR9170_RX_ERROR_PLCP;
Christian Lampartercca847992009-04-19 01:28:12 +0200776
777 if (!(ar->filter_state & FIF_PLCPFAIL))
778 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100779 }
780
781 if (error & AR9170_RX_ERROR_FCS) {
Christian Lampartercca847992009-04-19 01:28:12 +0200782 status->flag |= RX_FLAG_FAILED_FCS_CRC;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100783 error &= ~AR9170_RX_ERROR_FCS;
Christian Lampartercca847992009-04-19 01:28:12 +0200784
785 if (!(ar->filter_state & FIF_FCSFAIL))
786 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100787 }
788
Christian Lampartercca847992009-04-19 01:28:12 +0200789 decrypt = ar9170_get_decrypt_type(mac);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100790 if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
791 decrypt != AR9170_ENC_ALG_NONE)
Christian Lampartercca847992009-04-19 01:28:12 +0200792 status->flag |= RX_FLAG_DECRYPTED;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100793
794 /* ignore wrong RA errors */
795 error &= ~AR9170_RX_ERROR_WRONG_RA;
796
797 if (error & AR9170_RX_ERROR_DECRYPT) {
798 error &= ~AR9170_RX_ERROR_DECRYPT;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100799 /*
800 * Rx decryption is done in place,
801 * the original data is lost anyway.
802 */
Christian Lampartercca847992009-04-19 01:28:12 +0200803
804 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100805 }
806
807 /* drop any other error frames */
Christian Lampartercca847992009-04-19 01:28:12 +0200808 if (unlikely(error)) {
809 /* TODO: update netdevice's RX dropped/errors statistics */
810
811 if (ar9170_nag_limiter(ar))
812 printk(KERN_DEBUG "%s: received frame with "
813 "suspicious error code (%#x).\n",
814 wiphy_name(ar->hw->wiphy), error);
815
816 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100817 }
818
Christian Lampartercca847992009-04-19 01:28:12 +0200819 status->band = ar->channel->band;
820 status->freq = ar->channel->center_freq;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100821
Christian Lampartercca847992009-04-19 01:28:12 +0200822 switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) {
823 case AR9170_RX_STATUS_MODULATION_CCK:
824 if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
825 status->flag |= RX_FLAG_SHORTPRE;
826 switch (head->plcp[0]) {
827 case 0x0a:
828 status->rate_idx = 0;
829 break;
830 case 0x14:
831 status->rate_idx = 1;
832 break;
833 case 0x37:
834 status->rate_idx = 2;
835 break;
836 case 0x6e:
837 status->rate_idx = 3;
838 break;
839 default:
840 if (ar9170_nag_limiter(ar))
841 printk(KERN_ERR "%s: invalid plcp cck rate "
842 "(%x).\n", wiphy_name(ar->hw->wiphy),
843 head->plcp[0]);
844 return -EINVAL;
845 }
846 break;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100847
Christian Lamparter7d57b732009-11-14 00:57:58 +0100848 case AR9170_RX_STATUS_MODULATION_DUPOFDM:
Christian Lampartercca847992009-04-19 01:28:12 +0200849 case AR9170_RX_STATUS_MODULATION_OFDM:
850 switch (head->plcp[0] & 0xf) {
851 case 0xb:
852 status->rate_idx = 0;
853 break;
854 case 0xf:
855 status->rate_idx = 1;
856 break;
857 case 0xa:
858 status->rate_idx = 2;
859 break;
860 case 0xe:
861 status->rate_idx = 3;
862 break;
863 case 0x9:
864 status->rate_idx = 4;
865 break;
866 case 0xd:
867 status->rate_idx = 5;
868 break;
869 case 0x8:
870 status->rate_idx = 6;
871 break;
872 case 0xc:
873 status->rate_idx = 7;
874 break;
875 default:
876 if (ar9170_nag_limiter(ar))
877 printk(KERN_ERR "%s: invalid plcp ofdm rate "
878 "(%x).\n", wiphy_name(ar->hw->wiphy),
879 head->plcp[0]);
880 return -EINVAL;
881 }
882 if (status->band == IEEE80211_BAND_2GHZ)
883 status->rate_idx += 4;
884 break;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100885
Christian Lampartercca847992009-04-19 01:28:12 +0200886 case AR9170_RX_STATUS_MODULATION_HT:
887 if (head->plcp[3] & 0x80)
888 status->flag |= RX_FLAG_40MHZ;
889 if (head->plcp[6] & 0x80)
890 status->flag |= RX_FLAG_SHORT_GI;
891
892 status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f);
893 status->flag |= RX_FLAG_HT;
894 break;
895
Christian Lamparter7d57b732009-11-14 00:57:58 +0100896 default:
Christian Lampartercca847992009-04-19 01:28:12 +0200897 if (ar9170_nag_limiter(ar))
898 printk(KERN_ERR "%s: invalid modulation\n",
899 wiphy_name(ar->hw->wiphy));
900 return -EINVAL;
901 }
902
903 return 0;
904}
905
906static void ar9170_rx_phy_status(struct ar9170 *ar,
907 struct ar9170_rx_phystatus *phy,
908 struct ieee80211_rx_status *status)
909{
910 int i;
911
912 BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20);
913
914 for (i = 0; i < 3; i++)
915 if (phy->rssi[i] != 0x80)
916 status->antenna |= BIT(i);
917
918 /* post-process RSSI */
919 for (i = 0; i < 7; i++)
920 if (phy->rssi[i] & 0x80)
921 phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f;
922
923 /* TODO: we could do something with phy_errors */
924 status->signal = ar->noise[0] + phy->rssi_combined;
925 status->noise = ar->noise[0];
926}
927
928static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len)
929{
930 struct sk_buff *skb;
931 int reserved = 0;
932 struct ieee80211_hdr *hdr = (void *) buf;
933
934 if (ieee80211_is_data_qos(hdr->frame_control)) {
935 u8 *qc = ieee80211_get_qos_ctl(hdr);
936 reserved += NET_IP_ALIGN;
937
938 if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
939 reserved += NET_IP_ALIGN;
940 }
941
942 if (ieee80211_has_a4(hdr->frame_control))
943 reserved += NET_IP_ALIGN;
944
945 reserved = 32 + (reserved & NET_IP_ALIGN);
946
947 skb = dev_alloc_skb(len + reserved);
948 if (likely(skb)) {
949 skb_reserve(skb, reserved);
950 memcpy(skb_put(skb, len), buf, len);
951 }
952
953 return skb;
954}
955
956/*
957 * If the frame alignment is right (or the kernel has
958 * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
959 * is only a single MPDU in the USB frame, then we could
960 * submit to mac80211 the SKB directly. However, since
961 * there may be multiple packets in one SKB in stream
962 * mode, and we need to observe the proper ordering,
963 * this is non-trivial.
964 */
965
966static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
967{
968 struct ar9170_rx_head *head;
969 struct ar9170_rx_macstatus *mac;
970 struct ar9170_rx_phystatus *phy = NULL;
971 struct ieee80211_rx_status status;
972 struct sk_buff *skb;
973 int mpdu_len;
974
975 if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac))))
976 return ;
977
978 /* Received MPDU */
979 mpdu_len = len - sizeof(*mac);
980
981 mac = (void *)(buf + mpdu_len);
982 if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
983 /* this frame is too damaged and can't be used - drop it */
984
985 return ;
986 }
987
988 switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) {
989 case AR9170_RX_STATUS_MPDU_FIRST:
990 /* first mpdu packet has the plcp header */
991 if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
992 head = (void *) buf;
993 memcpy(&ar->rx_mpdu.plcp, (void *) buf,
994 sizeof(struct ar9170_rx_head));
995
996 mpdu_len -= sizeof(struct ar9170_rx_head);
997 buf += sizeof(struct ar9170_rx_head);
998 ar->rx_mpdu.has_plcp = true;
999 } else {
1000 if (ar9170_nag_limiter(ar))
1001 printk(KERN_ERR "%s: plcp info is clipped.\n",
1002 wiphy_name(ar->hw->wiphy));
1003 return ;
1004 }
1005 break;
1006
1007 case AR9170_RX_STATUS_MPDU_LAST:
1008 /* last mpdu has a extra tail with phy status information */
1009
1010 if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
1011 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
1012 phy = (void *)(buf + mpdu_len);
1013 } else {
1014 if (ar9170_nag_limiter(ar))
1015 printk(KERN_ERR "%s: frame tail is clipped.\n",
1016 wiphy_name(ar->hw->wiphy));
1017 return ;
1018 }
1019
1020 case AR9170_RX_STATUS_MPDU_MIDDLE:
1021 /* middle mpdus are just data */
1022 if (unlikely(!ar->rx_mpdu.has_plcp)) {
1023 if (!ar9170_nag_limiter(ar))
1024 return ;
1025
1026 printk(KERN_ERR "%s: rx stream did not start "
1027 "with a first_mpdu frame tag.\n",
1028 wiphy_name(ar->hw->wiphy));
1029
1030 return ;
1031 }
1032
1033 head = &ar->rx_mpdu.plcp;
1034 break;
1035
1036 case AR9170_RX_STATUS_MPDU_SINGLE:
1037 /* single mpdu - has plcp (head) and phy status (tail) */
1038 head = (void *) buf;
1039
1040 mpdu_len -= sizeof(struct ar9170_rx_head);
1041 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
1042
1043 buf += sizeof(struct ar9170_rx_head);
1044 phy = (void *)(buf + mpdu_len);
1045 break;
1046
1047 default:
1048 BUG_ON(1);
1049 break;
1050 }
1051
1052 if (unlikely(mpdu_len < FCS_LEN))
1053 return ;
1054
1055 memset(&status, 0, sizeof(status));
1056 if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status)))
1057 return ;
1058
1059 if (phy)
1060 ar9170_rx_phy_status(ar, phy, &status);
1061
1062 skb = ar9170_rx_copy_data(buf, mpdu_len);
Johannes Bergf1d58c22009-06-17 13:13:00 +02001063 if (likely(skb)) {
1064 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
1065 ieee80211_rx_irqsafe(ar->hw, skb);
1066 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001067}
1068
Christian Lampartere9348cd2009-03-21 23:05:13 +01001069void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
1070{
Christian Lampartercca847992009-04-19 01:28:12 +02001071 unsigned int i, tlen, resplen, wlen = 0, clen = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001072 u8 *tbuf, *respbuf;
1073
1074 tbuf = skb->data;
1075 tlen = skb->len;
1076
1077 while (tlen >= 4) {
Christian Lampartercca847992009-04-19 01:28:12 +02001078 clen = tbuf[1] << 8 | tbuf[0];
1079 wlen = ALIGN(clen, 4);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001080
Christian Lampartercca847992009-04-19 01:28:12 +02001081 /* check if this is stream has a valid tag.*/
Christian Lampartere9348cd2009-03-21 23:05:13 +01001082 if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
Christian Lampartercca847992009-04-19 01:28:12 +02001083 /*
1084 * TODO: handle the highly unlikely event that the
1085 * corrupted stream has the TAG at the right position.
1086 */
1087
1088 /* check if the frame can be repaired. */
1089 if (!ar->rx_failover_missing) {
1090 /* this is no "short read". */
1091 if (ar9170_nag_limiter(ar)) {
1092 printk(KERN_ERR "%s: missing tag!\n",
1093 wiphy_name(ar->hw->wiphy));
1094 goto err_telluser;
1095 } else
1096 goto err_silent;
1097 }
1098
1099 if (ar->rx_failover_missing > tlen) {
1100 if (ar9170_nag_limiter(ar)) {
1101 printk(KERN_ERR "%s: possible multi "
1102 "stream corruption!\n",
1103 wiphy_name(ar->hw->wiphy));
1104 goto err_telluser;
1105 } else
1106 goto err_silent;
1107 }
1108
1109 memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
1110 ar->rx_failover_missing -= tlen;
1111
1112 if (ar->rx_failover_missing <= 0) {
1113 /*
1114 * nested ar9170_rx call!
1115 * termination is guranteed, even when the
1116 * combined frame also have a element with
1117 * a bad tag.
1118 */
1119
1120 ar->rx_failover_missing = 0;
1121 ar9170_rx(ar, ar->rx_failover);
1122
1123 skb_reset_tail_pointer(ar->rx_failover);
1124 skb_trim(ar->rx_failover, 0);
1125 }
1126
Christian Lampartere9348cd2009-03-21 23:05:13 +01001127 return ;
1128 }
Christian Lampartercca847992009-04-19 01:28:12 +02001129
1130 /* check if stream is clipped */
Christian Lampartere9348cd2009-03-21 23:05:13 +01001131 if (wlen > tlen - 4) {
Christian Lampartercca847992009-04-19 01:28:12 +02001132 if (ar->rx_failover_missing) {
1133 /* TODO: handle double stream corruption. */
1134 if (ar9170_nag_limiter(ar)) {
1135 printk(KERN_ERR "%s: double rx stream "
1136 "corruption!\n",
1137 wiphy_name(ar->hw->wiphy));
1138 goto err_telluser;
1139 } else
1140 goto err_silent;
1141 }
1142
1143 /*
1144 * save incomplete data set.
1145 * the firmware will resend the missing bits when
1146 * the rx - descriptor comes round again.
1147 */
1148
1149 memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
1150 ar->rx_failover_missing = clen - tlen;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001151 return ;
1152 }
1153 resplen = clen;
1154 respbuf = tbuf + 4;
1155 tbuf += wlen + 4;
1156 tlen -= wlen + 4;
1157
1158 i = 0;
1159
1160 /* weird thing, but this is the same in the original driver */
1161 while (resplen > 2 && i < 12 &&
1162 respbuf[0] == 0xff && respbuf[1] == 0xff) {
1163 i += 2;
1164 resplen -= 2;
1165 respbuf += 2;
1166 }
1167
1168 if (resplen < 4)
1169 continue;
1170
1171 /* found the 6 * 0xffff marker? */
1172 if (i == 12)
1173 ar9170_handle_command_response(ar, respbuf, resplen);
1174 else
Christian Lampartercca847992009-04-19 01:28:12 +02001175 ar9170_handle_mpdu(ar, respbuf, clen);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001176 }
1177
Christian Lampartercca847992009-04-19 01:28:12 +02001178 if (tlen) {
1179 if (net_ratelimit())
1180 printk(KERN_ERR "%s: %d bytes of unprocessed "
1181 "data left in rx stream!\n",
1182 wiphy_name(ar->hw->wiphy), tlen);
1183
1184 goto err_telluser;
1185 }
1186
1187 return ;
1188
1189err_telluser:
1190 printk(KERN_ERR "%s: damaged RX stream data [want:%d, "
1191 "data:%d, rx:%d, pending:%d ]\n",
1192 wiphy_name(ar->hw->wiphy), clen, wlen, tlen,
1193 ar->rx_failover_missing);
1194
1195 if (ar->rx_failover_missing)
1196 print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
1197 ar->rx_failover->data,
1198 ar->rx_failover->len);
1199
1200 print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
1201 skb->data, skb->len);
1202
1203 printk(KERN_ERR "%s: please check your hardware and cables, if "
1204 "you see this message frequently.\n",
1205 wiphy_name(ar->hw->wiphy));
1206
1207err_silent:
1208 if (ar->rx_failover_missing) {
1209 skb_reset_tail_pointer(ar->rx_failover);
1210 skb_trim(ar->rx_failover, 0);
1211 ar->rx_failover_missing = 0;
1212 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001213}
Christian Lampartere9348cd2009-03-21 23:05:13 +01001214
1215#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \
1216do { \
1217 queue.aifs = ai_fs; \
1218 queue.cw_min = cwmin; \
1219 queue.cw_max = cwmax; \
1220 queue.txop = _txop; \
1221} while (0)
1222
1223static int ar9170_op_start(struct ieee80211_hw *hw)
1224{
1225 struct ar9170 *ar = hw->priv;
1226 int err, i;
1227
1228 mutex_lock(&ar->mutex);
1229
1230 /* reinitialize queues statistics */
1231 memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001232 for (i = 0; i < __AR9170_NUM_TXQ; i++)
1233 ar->tx_stats[i].limit = AR9170_TXQ_DEPTH;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001234
1235 /* reset QoS defaults */
1236 AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/
1237 AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023, 0); /* BACKGROUND */
1238 AR9170_FILL_QUEUE(ar->edcf[2], 2, 7, 15, 94); /* VIDEO */
1239 AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */
1240 AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
1241
Christian Lamparteracbadf02009-07-11 17:24:14 +02001242 /* set sane AMPDU defaults */
1243 ar->global_ampdu_density = 6;
1244 ar->global_ampdu_factor = 3;
1245
Christian Lamparter02bdf5b2009-10-17 21:56:43 +02001246 atomic_set(&ar->tx_ampdu_pending, 0);
Christian Lampartercca847992009-04-19 01:28:12 +02001247 ar->bad_hw_nagger = jiffies;
1248
Christian Lampartere9348cd2009-03-21 23:05:13 +01001249 err = ar->open(ar);
1250 if (err)
1251 goto out;
1252
1253 err = ar9170_init_mac(ar);
1254 if (err)
1255 goto out;
1256
1257 err = ar9170_set_qos(ar);
1258 if (err)
1259 goto out;
1260
1261 err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
1262 if (err)
1263 goto out;
1264
1265 err = ar9170_init_rf(ar);
1266 if (err)
1267 goto out;
1268
1269 /* start DMA */
1270 err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
1271 if (err)
1272 goto out;
1273
1274 ar->state = AR9170_STARTED;
1275
1276out:
1277 mutex_unlock(&ar->mutex);
1278 return err;
1279}
1280
1281static void ar9170_op_stop(struct ieee80211_hw *hw)
1282{
1283 struct ar9170 *ar = hw->priv;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001284 unsigned int i;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001285
1286 if (IS_STARTED(ar))
1287 ar->state = AR9170_IDLE;
1288
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001289 cancel_delayed_work_sync(&ar->tx_janitor);
Alexander Beregalovff8365c2009-07-24 11:55:44 +04001290#ifdef CONFIG_AR9170_LEDS
Christian Lamparteracbadf02009-07-11 17:24:14 +02001291 cancel_delayed_work_sync(&ar->led_work);
Alexander Beregalovff8365c2009-07-24 11:55:44 +04001292#endif
Christian Lampartere9348cd2009-03-21 23:05:13 +01001293 cancel_work_sync(&ar->beacon_work);
Luis R. Rodrigueze351cfb2009-07-27 12:51:37 -07001294
Christian Lamparterb55d6bc2009-05-23 20:31:21 +02001295 mutex_lock(&ar->mutex);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001296
1297 if (IS_ACCEPTING_CMD(ar)) {
1298 ar9170_set_leds_state(ar, 0);
1299
1300 /* stop DMA */
1301 ar9170_write_reg(ar, 0x1c3d30, 0);
1302 ar->stop(ar);
1303 }
1304
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001305 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1306 skb_queue_purge(&ar->tx_pending[i]);
1307 skb_queue_purge(&ar->tx_status[i]);
1308 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02001309 skb_queue_purge(&ar->tx_status_ampdu);
1310
Christian Lampartere9348cd2009-03-21 23:05:13 +01001311 mutex_unlock(&ar->mutex);
1312}
1313
Christian Lamparteracbadf02009-07-11 17:24:14 +02001314static void ar9170_tx_indicate_immba(struct ar9170 *ar, struct sk_buff *skb)
1315{
1316 struct ar9170_tx_control *txc = (void *) skb->data;
1317
1318 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_IMM_AMPDU);
1319}
1320
1321static void ar9170_tx_copy_phy(struct ar9170 *ar, struct sk_buff *dst,
1322 struct sk_buff *src)
1323{
1324 struct ar9170_tx_control *dst_txc, *src_txc;
1325 struct ieee80211_tx_info *dst_info, *src_info;
1326 struct ar9170_tx_info *dst_arinfo, *src_arinfo;
1327
1328 src_txc = (void *) src->data;
1329 src_info = IEEE80211_SKB_CB(src);
1330 src_arinfo = (void *) src_info->rate_driver_data;
1331
1332 dst_txc = (void *) dst->data;
1333 dst_info = IEEE80211_SKB_CB(dst);
1334 dst_arinfo = (void *) dst_info->rate_driver_data;
1335
1336 dst_txc->phy_control = src_txc->phy_control;
1337
1338 /* same MCS for the whole aggregate */
1339 memcpy(dst_info->driver_rates, src_info->driver_rates,
1340 sizeof(dst_info->driver_rates));
1341}
1342
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001343static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001344{
Christian Lampartere9348cd2009-03-21 23:05:13 +01001345 struct ieee80211_hdr *hdr;
1346 struct ar9170_tx_control *txc;
1347 struct ieee80211_tx_info *info;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001348 struct ieee80211_tx_rate *txrate;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001349 struct ar9170_tx_info *arinfo;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001350 unsigned int queue = skb_get_queue_mapping(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001351 u16 keytype = 0;
1352 u16 len, icv = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001353
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001354 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001355
1356 hdr = (void *)skb->data;
1357 info = IEEE80211_SKB_CB(skb);
1358 len = skb->len;
1359
Christian Lampartere9348cd2009-03-21 23:05:13 +01001360 txc = (void *)skb_push(skb, sizeof(*txc));
1361
Christian Lampartere9348cd2009-03-21 23:05:13 +01001362 if (info->control.hw_key) {
1363 icv = info->control.hw_key->icv_len;
1364
1365 switch (info->control.hw_key->alg) {
1366 case ALG_WEP:
1367 keytype = AR9170_TX_MAC_ENCR_RC4;
1368 break;
1369 case ALG_TKIP:
1370 keytype = AR9170_TX_MAC_ENCR_RC4;
1371 break;
1372 case ALG_CCMP:
1373 keytype = AR9170_TX_MAC_ENCR_AES;
1374 break;
1375 default:
1376 WARN_ON(1);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001377 goto err_out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001378 }
1379 }
1380
1381 /* Length */
1382 txc->length = cpu_to_le16(len + icv + 4);
1383
1384 txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
1385 AR9170_TX_MAC_BACKOFF);
1386 txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
1387 AR9170_TX_MAC_QOS_SHIFT);
1388 txc->mac_control |= cpu_to_le16(keytype);
1389 txc->phy_control = cpu_to_le32(0);
1390
1391 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
1392 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
1393
Christian Lampartere9348cd2009-03-21 23:05:13 +01001394 txrate = &info->control.rates[0];
Christian Lampartere9348cd2009-03-21 23:05:13 +01001395 if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1396 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
1397 else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1398 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
1399
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001400 arinfo = (void *)info->rate_driver_data;
1401 arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT);
1402
1403 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
1404 (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001405 /*
1406 * WARNING:
1407 * Putting the QoS queue bits into an unexplored territory is
1408 * certainly not elegant.
1409 *
1410 * In my defense: This idea provides a reasonable way to
1411 * smuggle valuable information to the tx_status callback.
1412 * Also, the idea behind this bit-abuse came straight from
1413 * the original driver code.
1414 */
1415
1416 txc->phy_control |=
1417 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
Christian Lamparter15b098b2009-11-29 00:56:55 +01001418
1419 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1420 if (unlikely(!info->control.sta))
1421 goto err_out;
1422
1423 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
1424 } else {
1425 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
1426 }
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001427 }
1428
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001429 return 0;
1430
1431err_out:
1432 skb_pull(skb, sizeof(*txc));
1433 return -EINVAL;
1434}
1435
1436static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
1437{
1438 struct ar9170_tx_control *txc;
1439 struct ieee80211_tx_info *info;
1440 struct ieee80211_rate *rate = NULL;
1441 struct ieee80211_tx_rate *txrate;
1442 u32 power, chains;
1443
1444 txc = (void *) skb->data;
1445 info = IEEE80211_SKB_CB(skb);
1446 txrate = &info->control.rates[0];
1447
Christian Lampartere9348cd2009-03-21 23:05:13 +01001448 if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
1449 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
1450
1451 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1452 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
1453
1454 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1455 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
1456 /* this works because 40 MHz is 2 and dup is 3 */
1457 if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
1458 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
1459
1460 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
1461 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
1462
1463 if (txrate->flags & IEEE80211_TX_RC_MCS) {
1464 u32 r = txrate->idx;
1465 u8 *txpower;
1466
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001467 /* heavy clip control */
1468 txc->phy_control |= cpu_to_le32((r & 0x7) << 7);
1469
Christian Lampartere9348cd2009-03-21 23:05:13 +01001470 r <<= AR9170_TX_PHY_MCS_SHIFT;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001471 BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK);
1472
Christian Lampartere9348cd2009-03-21 23:05:13 +01001473 txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
1474 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
1475
1476 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1477 if (info->band == IEEE80211_BAND_5GHZ)
1478 txpower = ar->power_5G_ht40;
1479 else
1480 txpower = ar->power_2G_ht40;
1481 } else {
1482 if (info->band == IEEE80211_BAND_5GHZ)
1483 txpower = ar->power_5G_ht20;
1484 else
1485 txpower = ar->power_2G_ht20;
1486 }
1487
1488 power = txpower[(txrate->idx) & 7];
1489 } else {
1490 u8 *txpower;
1491 u32 mod;
1492 u32 phyrate;
1493 u8 idx = txrate->idx;
1494
1495 if (info->band != IEEE80211_BAND_2GHZ) {
1496 idx += 4;
1497 txpower = ar->power_5G_leg;
1498 mod = AR9170_TX_PHY_MOD_OFDM;
1499 } else {
1500 if (idx < 4) {
1501 txpower = ar->power_2G_cck;
1502 mod = AR9170_TX_PHY_MOD_CCK;
1503 } else {
1504 mod = AR9170_TX_PHY_MOD_OFDM;
1505 txpower = ar->power_2G_ofdm;
1506 }
1507 }
1508
1509 rate = &__ar9170_ratetable[idx];
1510
1511 phyrate = rate->hw_value & 0xF;
1512 power = txpower[(rate->hw_value & 0x30) >> 4];
1513 phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
1514
1515 txc->phy_control |= cpu_to_le32(mod);
1516 txc->phy_control |= cpu_to_le32(phyrate);
1517 }
1518
1519 power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
1520 power &= AR9170_TX_PHY_TX_PWR_MASK;
1521 txc->phy_control |= cpu_to_le32(power);
1522
1523 /* set TX chains */
1524 if (ar->eeprom.tx_mask == 1) {
1525 chains = AR9170_TX_PHY_TXCHAIN_1;
1526 } else {
1527 chains = AR9170_TX_PHY_TXCHAIN_2;
1528
1529 /* >= 36M legacy OFDM - use only one chain */
1530 if (rate && rate->bitrate >= 360)
1531 chains = AR9170_TX_PHY_TXCHAIN_1;
1532 }
1533 txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001534}
Christian Lampartere9348cd2009-03-21 23:05:13 +01001535
Christian Lamparteracbadf02009-07-11 17:24:14 +02001536static bool ar9170_tx_ampdu(struct ar9170 *ar)
1537{
1538 struct sk_buff_head agg;
1539 struct ar9170_sta_tid *tid_info = NULL, *tmp;
1540 struct sk_buff *skb, *first = NULL;
1541 unsigned long flags, f2;
1542 unsigned int i = 0;
1543 u16 seq, queue, tmpssn;
1544 bool run = false;
1545
1546 skb_queue_head_init(&agg);
1547
1548 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1549 if (list_empty(&ar->tx_ampdu_list)) {
1550#ifdef AR9170_TXAGG_DEBUG
1551 printk(KERN_DEBUG "%s: aggregation list is empty.\n",
1552 wiphy_name(ar->hw->wiphy));
1553#endif /* AR9170_TXAGG_DEBUG */
1554 goto out_unlock;
1555 }
1556
1557 list_for_each_entry_safe(tid_info, tmp, &ar->tx_ampdu_list, list) {
1558 if (tid_info->state != AR9170_TID_STATE_COMPLETE) {
1559#ifdef AR9170_TXAGG_DEBUG
1560 printk(KERN_DEBUG "%s: dangling aggregation entry!\n",
1561 wiphy_name(ar->hw->wiphy));
1562#endif /* AR9170_TXAGG_DEBUG */
1563 continue;
1564 }
1565
1566 if (++i > 64) {
1567#ifdef AR9170_TXAGG_DEBUG
1568 printk(KERN_DEBUG "%s: enough frames aggregated.\n",
1569 wiphy_name(ar->hw->wiphy));
1570#endif /* AR9170_TXAGG_DEBUG */
1571 break;
1572 }
1573
1574 queue = TID_TO_WME_AC(tid_info->tid);
1575
1576 if (skb_queue_len(&ar->tx_pending[queue]) >=
1577 AR9170_NUM_TX_AGG_MAX) {
1578#ifdef AR9170_TXAGG_DEBUG
1579 printk(KERN_DEBUG "%s: queue %d full.\n",
1580 wiphy_name(ar->hw->wiphy), queue);
1581#endif /* AR9170_TXAGG_DEBUG */
1582 continue;
1583 }
1584
1585 list_del_init(&tid_info->list);
1586
1587 spin_lock_irqsave(&tid_info->queue.lock, f2);
1588 tmpssn = seq = tid_info->ssn;
1589 first = skb_peek(&tid_info->queue);
1590
1591 if (likely(first))
1592 tmpssn = ar9170_get_seq(first);
1593
1594 if (unlikely(tmpssn != seq)) {
1595#ifdef AR9170_TXAGG_DEBUG
1596 printk(KERN_DEBUG "%s: ssn mismatch [%d != %d]\n.",
1597 wiphy_name(ar->hw->wiphy), seq, tmpssn);
1598#endif /* AR9170_TXAGG_DEBUG */
1599 tid_info->ssn = tmpssn;
1600 }
1601
1602#ifdef AR9170_TXAGG_DEBUG
1603 printk(KERN_DEBUG "%s: generate A-MPDU for tid:%d ssn:%d with "
1604 "%d queued frames.\n", wiphy_name(ar->hw->wiphy),
1605 tid_info->tid, tid_info->ssn,
1606 skb_queue_len(&tid_info->queue));
1607 __ar9170_dump_txqueue(ar, &tid_info->queue);
1608#endif /* AR9170_TXAGG_DEBUG */
1609
1610 while ((skb = skb_peek(&tid_info->queue))) {
1611 if (unlikely(ar9170_get_seq(skb) != seq))
1612 break;
1613
1614 __skb_unlink(skb, &tid_info->queue);
1615 tid_info->ssn = seq = GET_NEXT_SEQ(seq);
1616
1617 if (unlikely(skb_get_queue_mapping(skb) != queue)) {
1618#ifdef AR9170_TXAGG_DEBUG
1619 printk(KERN_DEBUG "%s: tid:%d(q:%d) queue:%d "
1620 "!match.\n", wiphy_name(ar->hw->wiphy),
1621 tid_info->tid,
1622 TID_TO_WME_AC(tid_info->tid),
1623 skb_get_queue_mapping(skb));
1624#endif /* AR9170_TXAGG_DEBUG */
1625 dev_kfree_skb_any(skb);
1626 continue;
1627 }
1628
1629 if (unlikely(first == skb)) {
1630 ar9170_tx_prepare_phy(ar, skb);
1631 __skb_queue_tail(&agg, skb);
1632 first = skb;
1633 } else {
1634 ar9170_tx_copy_phy(ar, skb, first);
1635 __skb_queue_tail(&agg, skb);
1636 }
1637
1638 if (unlikely(skb_queue_len(&agg) ==
1639 AR9170_NUM_TX_AGG_MAX))
1640 break;
1641 }
1642
1643 if (skb_queue_empty(&tid_info->queue))
1644 tid_info->active = false;
1645 else
1646 list_add_tail(&tid_info->list,
1647 &ar->tx_ampdu_list);
1648
1649 spin_unlock_irqrestore(&tid_info->queue.lock, f2);
1650
1651 if (unlikely(skb_queue_empty(&agg))) {
1652#ifdef AR9170_TXAGG_DEBUG
1653 printk(KERN_DEBUG "%s: queued empty list!\n",
1654 wiphy_name(ar->hw->wiphy));
1655#endif /* AR9170_TXAGG_DEBUG */
1656 continue;
1657 }
1658
1659 /*
1660 * tell the FW/HW that this is the last frame,
1661 * that way it will wait for the immediate block ack.
1662 */
1663 if (likely(skb_peek_tail(&agg)))
1664 ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg));
1665
1666#ifdef AR9170_TXAGG_DEBUG
1667 printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n",
1668 wiphy_name(ar->hw->wiphy));
1669 __ar9170_dump_txqueue(ar, &agg);
1670#endif /* AR9170_TXAGG_DEBUG */
1671
1672 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1673
1674 spin_lock_irqsave(&ar->tx_pending[queue].lock, flags);
1675 skb_queue_splice_tail_init(&agg, &ar->tx_pending[queue]);
1676 spin_unlock_irqrestore(&ar->tx_pending[queue].lock, flags);
1677 run = true;
1678
1679 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1680 }
1681
1682out_unlock:
1683 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1684 __skb_queue_purge(&agg);
1685
1686 return run;
1687}
1688
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001689static void ar9170_tx(struct ar9170 *ar)
1690{
1691 struct sk_buff *skb;
1692 unsigned long flags;
1693 struct ieee80211_tx_info *info;
1694 struct ar9170_tx_info *arinfo;
1695 unsigned int i, frames, frames_failed, remaining_space;
1696 int err;
1697 bool schedule_garbagecollector = false;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001698
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001699 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001700
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001701 if (unlikely(!IS_STARTED(ar)))
1702 return ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001703
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001704 remaining_space = AR9170_TX_MAX_PENDING;
1705
1706 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1707 spin_lock_irqsave(&ar->tx_stats_lock, flags);
Christian Lamparter53a76b52009-11-29 00:52:51 +01001708 frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
1709 skb_queue_len(&ar->tx_pending[i]));
1710
1711 if (remaining_space < frames) {
1712#ifdef AR9170_QUEUE_DEBUG
1713 printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
1714 "remaining slots:%d, needed:%d\n",
1715 wiphy_name(ar->hw->wiphy), i, remaining_space,
1716 frames);
1717#endif /* AR9170_QUEUE_DEBUG */
1718 frames = remaining_space;
1719 }
1720
1721 ar->tx_stats[i].len += frames;
1722 ar->tx_stats[i].count += frames;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001723 if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
1724#ifdef AR9170_QUEUE_DEBUG
1725 printk(KERN_DEBUG "%s: queue %d full\n",
1726 wiphy_name(ar->hw->wiphy), i);
1727
Christian Lamparteracbadf02009-07-11 17:24:14 +02001728 printk(KERN_DEBUG "%s: stuck frames: ===> \n",
1729 wiphy_name(ar->hw->wiphy));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001730 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1731 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
1732#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparteracbadf02009-07-11 17:24:14 +02001733
1734#ifdef AR9170_QUEUE_STOP_DEBUG
1735 printk(KERN_DEBUG "%s: stop queue %d\n",
1736 wiphy_name(ar->hw->wiphy), i);
1737 __ar9170_dump_txstats(ar);
1738#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001739 ieee80211_stop_queue(ar->hw, i);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001740 }
1741
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001742 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1743
1744 if (!frames)
1745 continue;
1746
1747 frames_failed = 0;
1748 while (frames) {
1749 skb = skb_dequeue(&ar->tx_pending[i]);
1750 if (unlikely(!skb)) {
1751 frames_failed += frames;
1752 frames = 0;
1753 break;
1754 }
1755
1756 info = IEEE80211_SKB_CB(skb);
1757 arinfo = (void *) info->rate_driver_data;
1758
1759 /* TODO: cancel stuck frames */
1760 arinfo->timeout = jiffies +
1761 msecs_to_jiffies(AR9170_TX_TIMEOUT);
1762
Christian Lamparter15b098b2009-11-29 00:56:55 +01001763 if (info->flags & IEEE80211_TX_CTL_AMPDU)
Christian Lamparter02bdf5b2009-10-17 21:56:43 +02001764 atomic_inc(&ar->tx_ampdu_pending);
Christian Lamparteracbadf02009-07-11 17:24:14 +02001765
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001766#ifdef AR9170_QUEUE_DEBUG
1767 printk(KERN_DEBUG "%s: send frame q:%d =>\n",
1768 wiphy_name(ar->hw->wiphy), i);
1769 ar9170_print_txheader(ar, skb);
1770#endif /* AR9170_QUEUE_DEBUG */
1771
1772 err = ar->tx(ar, skb);
1773 if (unlikely(err)) {
Christian Lamparter15b098b2009-11-29 00:56:55 +01001774 if (info->flags & IEEE80211_TX_CTL_AMPDU)
Christian Lamparter02bdf5b2009-10-17 21:56:43 +02001775 atomic_dec(&ar->tx_ampdu_pending);
Christian Lamparteracbadf02009-07-11 17:24:14 +02001776
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001777 frames_failed++;
1778 dev_kfree_skb_any(skb);
1779 } else {
1780 remaining_space--;
1781 schedule_garbagecollector = true;
1782 }
1783
1784 frames--;
1785 }
1786
1787#ifdef AR9170_QUEUE_DEBUG
1788 printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n",
1789 wiphy_name(ar->hw->wiphy), i);
1790
1791 printk(KERN_DEBUG "%s: unprocessed pending frames left:\n",
1792 wiphy_name(ar->hw->wiphy));
1793 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1794#endif /* AR9170_QUEUE_DEBUG */
1795
1796 if (unlikely(frames_failed)) {
1797#ifdef AR9170_QUEUE_DEBUG
Christian Lamparteracbadf02009-07-11 17:24:14 +02001798 printk(KERN_DEBUG "%s: frames failed %d =>\n",
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001799 wiphy_name(ar->hw->wiphy), frames_failed);
1800#endif /* AR9170_QUEUE_DEBUG */
1801
1802 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1803 ar->tx_stats[i].len -= frames_failed;
1804 ar->tx_stats[i].count -= frames_failed;
Christian Lamparteracbadf02009-07-11 17:24:14 +02001805#ifdef AR9170_QUEUE_STOP_DEBUG
1806 printk(KERN_DEBUG "%s: wake queue %d\n",
1807 wiphy_name(ar->hw->wiphy), i);
1808 __ar9170_dump_txstats(ar);
1809#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001810 ieee80211_wake_queue(ar->hw, i);
1811 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001812 }
1813 }
1814
Luis R. Rodriguez42935ec2009-07-29 20:08:07 -04001815 if (!schedule_garbagecollector)
1816 return;
1817
1818 ieee80211_queue_delayed_work(ar->hw,
1819 &ar->tx_janitor,
1820 msecs_to_jiffies(AR9170_JANITOR_DELAY));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001821}
1822
Christian Lamparteracbadf02009-07-11 17:24:14 +02001823static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb)
1824{
1825 struct ieee80211_tx_info *txinfo;
1826 struct ar9170_sta_info *sta_info;
1827 struct ar9170_sta_tid *agg;
1828 struct sk_buff *iter;
1829 unsigned long flags, f2;
1830 unsigned int max;
1831 u16 tid, seq, qseq;
1832 bool run = false, queue = false;
1833
1834 tid = ar9170_get_tid(skb);
1835 seq = ar9170_get_seq(skb);
1836 txinfo = IEEE80211_SKB_CB(skb);
1837 sta_info = (void *) txinfo->control.sta->drv_priv;
1838 agg = &sta_info->agg[tid];
1839 max = sta_info->ampdu_max_len;
1840
1841 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1842
1843 if (unlikely(agg->state != AR9170_TID_STATE_COMPLETE)) {
1844#ifdef AR9170_TXAGG_DEBUG
1845 printk(KERN_DEBUG "%s: BlockACK session not fully initialized "
1846 "for ESS:%pM tid:%d state:%d.\n",
1847 wiphy_name(ar->hw->wiphy), agg->addr, agg->tid,
1848 agg->state);
1849#endif /* AR9170_TXAGG_DEBUG */
1850 goto err_unlock;
1851 }
1852
1853 if (!agg->active) {
1854 agg->active = true;
1855 agg->ssn = seq;
1856 queue = true;
1857 }
1858
1859 /* check if seq is within the BA window */
1860 if (unlikely(!BAW_WITHIN(agg->ssn, max, seq))) {
1861#ifdef AR9170_TXAGG_DEBUG
1862 printk(KERN_DEBUG "%s: frame with tid:%d seq:%d does not "
1863 "fit into BA window (%d - %d)\n",
1864 wiphy_name(ar->hw->wiphy), tid, seq, agg->ssn,
1865 (agg->ssn + max) & 0xfff);
1866#endif /* AR9170_TXAGG_DEBUG */
1867 goto err_unlock;
1868 }
1869
1870 spin_lock_irqsave(&agg->queue.lock, f2);
1871
1872 skb_queue_reverse_walk(&agg->queue, iter) {
1873 qseq = ar9170_get_seq(iter);
1874
1875 if (GET_NEXT_SEQ(qseq) == seq) {
1876 __skb_queue_after(&agg->queue, iter, skb);
1877 goto queued;
1878 }
1879 }
1880
1881 __skb_queue_head(&agg->queue, skb);
1882
1883queued:
1884 spin_unlock_irqrestore(&agg->queue.lock, f2);
1885
1886#ifdef AR9170_TXAGG_DEBUG
1887 printk(KERN_DEBUG "%s: new aggregate %p queued.\n",
1888 wiphy_name(ar->hw->wiphy), skb);
1889 __ar9170_dump_txqueue(ar, &agg->queue);
1890#endif /* AR9170_TXAGG_DEBUG */
1891
1892 if (skb_queue_len(&agg->queue) >= AR9170_NUM_TX_AGG_MAX)
1893 run = true;
1894
1895 if (queue)
1896 list_add_tail(&agg->list, &ar->tx_ampdu_list);
1897
1898 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1899 return run;
1900
1901err_unlock:
1902 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1903 dev_kfree_skb_irq(skb);
1904 return false;
1905}
1906
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001907int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1908{
1909 struct ar9170 *ar = hw->priv;
1910 struct ieee80211_tx_info *info;
1911
1912 if (unlikely(!IS_STARTED(ar)))
1913 goto err_free;
1914
1915 if (unlikely(ar9170_tx_prepare(ar, skb)))
1916 goto err_free;
1917
1918 info = IEEE80211_SKB_CB(skb);
1919 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
Christian Lamparteracbadf02009-07-11 17:24:14 +02001920 bool run = ar9170_tx_ampdu_queue(ar, skb);
1921
Christian Lamparter02bdf5b2009-10-17 21:56:43 +02001922 if (run || !atomic_read(&ar->tx_ampdu_pending))
Christian Lamparteracbadf02009-07-11 17:24:14 +02001923 ar9170_tx_ampdu(ar);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001924 } else {
1925 unsigned int queue = skb_get_queue_mapping(skb);
1926
1927 ar9170_tx_prepare_phy(ar, skb);
1928 skb_queue_tail(&ar->tx_pending[queue], skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001929 }
1930
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001931 ar9170_tx(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001932 return NETDEV_TX_OK;
1933
Christian Lampartere9348cd2009-03-21 23:05:13 +01001934err_free:
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001935 dev_kfree_skb_any(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001936 return NETDEV_TX_OK;
1937}
1938
1939static int ar9170_op_add_interface(struct ieee80211_hw *hw,
1940 struct ieee80211_if_init_conf *conf)
1941{
1942 struct ar9170 *ar = hw->priv;
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07001943 struct ath_common *common = &ar->common;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001944 int err = 0;
1945
1946 mutex_lock(&ar->mutex);
1947
1948 if (ar->vif) {
1949 err = -EBUSY;
1950 goto unlock;
1951 }
1952
1953 ar->vif = conf->vif;
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07001954 memcpy(common->macaddr, conf->mac_addr, ETH_ALEN);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001955
1956 if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
1957 ar->rx_software_decryption = true;
1958 ar->disable_offload = true;
1959 }
1960
1961 ar->cur_filter = 0;
Christian Lampartereeef4182009-08-19 12:43:47 +02001962 err = ar9170_update_frame_filter(ar, AR9170_MAC_REG_FTF_DEFAULTS);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001963 if (err)
1964 goto unlock;
1965
1966 err = ar9170_set_operating_mode(ar);
1967
1968unlock:
1969 mutex_unlock(&ar->mutex);
1970 return err;
1971}
1972
1973static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
1974 struct ieee80211_if_init_conf *conf)
1975{
1976 struct ar9170 *ar = hw->priv;
1977
1978 mutex_lock(&ar->mutex);
1979 ar->vif = NULL;
Christian Lampartereeef4182009-08-19 12:43:47 +02001980 ar9170_update_frame_filter(ar, 0);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001981 ar9170_set_beacon_timers(ar);
1982 dev_kfree_skb(ar->beacon);
1983 ar->beacon = NULL;
1984 ar->sniffer_enabled = false;
1985 ar->rx_software_decryption = false;
1986 ar9170_set_operating_mode(ar);
1987 mutex_unlock(&ar->mutex);
1988}
1989
1990static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
1991{
1992 struct ar9170 *ar = hw->priv;
1993 int err = 0;
1994
1995 mutex_lock(&ar->mutex);
1996
Christian Lampartere9348cd2009-03-21 23:05:13 +01001997 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
1998 /* TODO */
1999 err = 0;
2000 }
2001
2002 if (changed & IEEE80211_CONF_CHANGE_PS) {
2003 /* TODO */
2004 err = 0;
2005 }
2006
2007 if (changed & IEEE80211_CONF_CHANGE_POWER) {
2008 /* TODO */
2009 err = 0;
2010 }
2011
2012 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
2013 /*
2014 * is it long_frame_max_tx_count or short_frame_max_tx_count?
2015 */
2016
2017 err = ar9170_set_hwretry_limit(ar,
2018 ar->hw->conf.long_frame_max_tx_count);
2019 if (err)
2020 goto out;
2021 }
2022
Christian Lampartere9348cd2009-03-21 23:05:13 +01002023 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002024
2025 /* adjust slot time for 5 GHz */
2026 err = ar9170_set_slot_time(ar);
2027 if (err)
2028 goto out;
2029
2030 err = ar9170_set_dyn_sifs_ack(ar);
2031 if (err)
2032 goto out;
2033
Christian Lampartere9348cd2009-03-21 23:05:13 +01002034 err = ar9170_set_channel(ar, hw->conf.channel,
Johannes Berg9e52b062009-04-20 18:27:04 +02002035 AR9170_RFI_NONE,
2036 nl80211_to_ar9170(hw->conf.channel_type));
Christian Lampartere9348cd2009-03-21 23:05:13 +01002037 if (err)
2038 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002039 }
2040
2041out:
2042 mutex_unlock(&ar->mutex);
2043 return err;
2044}
2045
Johannes Berg3ac64be2009-08-17 16:16:53 +02002046static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
2047 struct dev_addr_list *mclist)
2048{
2049 u64 mchash;
2050 int i;
2051
2052 /* always get broadcast frames */
2053 mchash = 1ULL << (0xff >> 2);
2054
2055 for (i = 0; i < mc_count; i++) {
2056 if (WARN_ON(!mclist))
2057 break;
2058 mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
2059 mclist = mclist->next;
2060 }
2061
2062 return mchash;
2063}
2064
Christian Lampartere9348cd2009-03-21 23:05:13 +01002065static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
2066 unsigned int changed_flags,
2067 unsigned int *new_flags,
Johannes Berg3ac64be2009-08-17 16:16:53 +02002068 u64 multicast)
Christian Lampartere9348cd2009-03-21 23:05:13 +01002069{
2070 struct ar9170 *ar = hw->priv;
2071
Christian Lampartereeef4182009-08-19 12:43:47 +02002072 if (unlikely(!IS_ACCEPTING_CMD(ar)))
2073 return ;
2074
2075 mutex_lock(&ar->mutex);
2076
Christian Lampartere9348cd2009-03-21 23:05:13 +01002077 /* mask supported flags */
2078 *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
Christian Lampartercca847992009-04-19 01:28:12 +02002079 FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
2080 ar->filter_state = *new_flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002081 /*
2082 * We can support more by setting the sniffer bit and
2083 * then checking the error flags, later.
2084 */
2085
Johannes Berg3ac64be2009-08-17 16:16:53 +02002086 if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
Christian Lampartereeef4182009-08-19 12:43:47 +02002087 multicast = ~0ULL;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002088
Christian Lampartereeef4182009-08-19 12:43:47 +02002089 if (multicast != ar->cur_mc_hash)
2090 ar9170_update_multicast(ar, multicast);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002091
2092 if (changed_flags & FIF_CONTROL) {
2093 u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
2094 AR9170_MAC_REG_FTF_RTS |
2095 AR9170_MAC_REG_FTF_CTS |
2096 AR9170_MAC_REG_FTF_ACK |
2097 AR9170_MAC_REG_FTF_CFE |
2098 AR9170_MAC_REG_FTF_CFE_ACK;
2099
2100 if (*new_flags & FIF_CONTROL)
Christian Lampartereeef4182009-08-19 12:43:47 +02002101 filter |= ar->cur_filter;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002102 else
Christian Lampartereeef4182009-08-19 12:43:47 +02002103 filter &= (~ar->cur_filter);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002104
Christian Lampartereeef4182009-08-19 12:43:47 +02002105 ar9170_update_frame_filter(ar, filter);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002106 }
2107
2108 if (changed_flags & FIF_PROMISC_IN_BSS) {
2109 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
Christian Lampartereeef4182009-08-19 12:43:47 +02002110 ar9170_set_operating_mode(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002111 }
2112
Christian Lampartereeef4182009-08-19 12:43:47 +02002113 mutex_unlock(&ar->mutex);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002114}
2115
Christian Lampartereeef4182009-08-19 12:43:47 +02002116
Christian Lampartere9348cd2009-03-21 23:05:13 +01002117static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
2118 struct ieee80211_vif *vif,
2119 struct ieee80211_bss_conf *bss_conf,
2120 u32 changed)
2121{
2122 struct ar9170 *ar = hw->priv;
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07002123 struct ath_common *common = &ar->common;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002124 int err = 0;
2125
2126 mutex_lock(&ar->mutex);
2127
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002128 if (changed & BSS_CHANGED_BSSID) {
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07002129 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002130 err = ar9170_set_operating_mode(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02002131 if (err)
2132 goto out;
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002133 }
2134
Joerg Albertea39d1a2009-08-21 23:25:07 +02002135 if (changed & BSS_CHANGED_BEACON_ENABLED)
2136 ar->enable_beacon = bss_conf->enable_beacon;
2137
2138 if (changed & BSS_CHANGED_BEACON) {
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002139 err = ar9170_update_beacon(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02002140 if (err)
2141 goto out;
Joerg Albertea39d1a2009-08-21 23:25:07 +02002142 }
Johannes Berg2d0ddec2009-04-23 16:13:26 +02002143
Joerg Albertea39d1a2009-08-21 23:25:07 +02002144 if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON |
2145 BSS_CHANGED_BEACON_INT)) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002146 err = ar9170_set_beacon_timers(ar);
2147 if (err)
2148 goto out;
2149 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01002150
2151 if (changed & BSS_CHANGED_ASSOC) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002152#ifndef CONFIG_AR9170_LEDS
2153 /* enable assoc LED. */
2154 err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
2155#endif /* CONFIG_AR9170_LEDS */
2156 }
2157
2158 if (changed & BSS_CHANGED_HT) {
2159 /* TODO */
2160 err = 0;
2161 }
2162
2163 if (changed & BSS_CHANGED_ERP_SLOT) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002164 err = ar9170_set_slot_time(ar);
2165 if (err)
2166 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002167 }
2168
2169 if (changed & BSS_CHANGED_BASIC_RATES) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02002170 err = ar9170_set_basic_rates(ar);
2171 if (err)
2172 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002173 }
2174
Christian Lamparter29ceff52009-06-01 21:42:01 +02002175out:
Christian Lampartere9348cd2009-03-21 23:05:13 +01002176 mutex_unlock(&ar->mutex);
2177}
2178
2179static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
2180{
2181 struct ar9170 *ar = hw->priv;
2182 int err;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002183 u64 tsf;
Joerg Albert181af382009-09-15 23:27:53 +02002184#define NR 3
2185 static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H,
2186 AR9170_MAC_REG_TSF_L,
2187 AR9170_MAC_REG_TSF_H };
2188 u32 val[NR];
2189 int loops = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002190
2191 mutex_lock(&ar->mutex);
Joerg Albert181af382009-09-15 23:27:53 +02002192
2193 while (loops++ < 10) {
2194 err = ar9170_read_mreg(ar, NR, addr, val);
2195 if (err || val[0] == val[2])
2196 break;
2197 }
2198
Christian Lampartere9348cd2009-03-21 23:05:13 +01002199 mutex_unlock(&ar->mutex);
2200
2201 if (WARN_ON(err))
2202 return 0;
Joerg Albert181af382009-09-15 23:27:53 +02002203 tsf = val[0];
2204 tsf = (tsf << 32) | val[1];
Christian Lampartere9348cd2009-03-21 23:05:13 +01002205 return tsf;
Joerg Albert181af382009-09-15 23:27:53 +02002206#undef NR
Christian Lampartere9348cd2009-03-21 23:05:13 +01002207}
2208
2209static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2210 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
2211 struct ieee80211_key_conf *key)
2212{
2213 struct ar9170 *ar = hw->priv;
2214 int err = 0, i;
2215 u8 ktype;
2216
2217 if ((!ar->vif) || (ar->disable_offload))
2218 return -EOPNOTSUPP;
2219
2220 switch (key->alg) {
2221 case ALG_WEP:
Zhu Yie31a16d2009-05-21 21:47:03 +08002222 if (key->keylen == WLAN_KEY_LEN_WEP40)
Christian Lampartere9348cd2009-03-21 23:05:13 +01002223 ktype = AR9170_ENC_ALG_WEP64;
2224 else
2225 ktype = AR9170_ENC_ALG_WEP128;
2226 break;
2227 case ALG_TKIP:
2228 ktype = AR9170_ENC_ALG_TKIP;
2229 break;
2230 case ALG_CCMP:
2231 ktype = AR9170_ENC_ALG_AESCCMP;
2232 break;
2233 default:
2234 return -EOPNOTSUPP;
2235 }
2236
2237 mutex_lock(&ar->mutex);
2238 if (cmd == SET_KEY) {
2239 if (unlikely(!IS_STARTED(ar))) {
2240 err = -EOPNOTSUPP;
2241 goto out;
2242 }
2243
2244 /* group keys need all-zeroes address */
2245 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
2246 sta = NULL;
2247
2248 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
2249 for (i = 0; i < 64; i++)
2250 if (!(ar->usedkeys & BIT(i)))
2251 break;
2252 if (i == 64) {
2253 ar->rx_software_decryption = true;
2254 ar9170_set_operating_mode(ar);
2255 err = -ENOSPC;
2256 goto out;
2257 }
2258 } else {
2259 i = 64 + key->keyidx;
2260 }
2261
2262 key->hw_key_idx = i;
2263
2264 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
2265 key->key, min_t(u8, 16, key->keylen));
2266 if (err)
2267 goto out;
2268
2269 if (key->alg == ALG_TKIP) {
2270 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
2271 ktype, 1, key->key + 16, 16);
2272 if (err)
2273 goto out;
2274
2275 /*
2276 * hardware is not capable generating the MMIC
2277 * for fragmented frames!
2278 */
2279 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
2280 }
2281
2282 if (i < 64)
2283 ar->usedkeys |= BIT(i);
2284
2285 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
2286 } else {
2287 if (unlikely(!IS_STARTED(ar))) {
2288 /* The device is gone... together with the key ;-) */
2289 err = 0;
2290 goto out;
2291 }
2292
2293 err = ar9170_disable_key(ar, key->hw_key_idx);
2294 if (err)
2295 goto out;
2296
2297 if (key->hw_key_idx < 64) {
2298 ar->usedkeys &= ~BIT(key->hw_key_idx);
2299 } else {
2300 err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
2301 AR9170_ENC_ALG_NONE, 0,
2302 NULL, 0);
2303 if (err)
2304 goto out;
2305
2306 if (key->alg == ALG_TKIP) {
2307 err = ar9170_upload_key(ar, key->hw_key_idx,
2308 NULL,
2309 AR9170_ENC_ALG_NONE, 1,
2310 NULL, 0);
2311 if (err)
2312 goto out;
2313 }
2314
2315 }
2316 }
2317
2318 ar9170_regwrite_begin(ar);
2319 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
2320 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
2321 ar9170_regwrite_finish();
2322 err = ar9170_regwrite_result();
2323
2324out:
2325 mutex_unlock(&ar->mutex);
2326
2327 return err;
2328}
2329
2330static void ar9170_sta_notify(struct ieee80211_hw *hw,
2331 struct ieee80211_vif *vif,
2332 enum sta_notify_cmd cmd,
2333 struct ieee80211_sta *sta)
2334{
Christian Lamparteracbadf02009-07-11 17:24:14 +02002335 struct ar9170 *ar = hw->priv;
2336 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2337 unsigned int i;
2338
2339 switch (cmd) {
2340 case STA_NOTIFY_ADD:
2341 memset(sta_info, 0, sizeof(*sta_info));
2342
2343 if (!sta->ht_cap.ht_supported)
2344 break;
2345
2346 if (sta->ht_cap.ampdu_density > ar->global_ampdu_density)
2347 ar->global_ampdu_density = sta->ht_cap.ampdu_density;
2348
2349 if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor)
2350 ar->global_ampdu_factor = sta->ht_cap.ampdu_factor;
2351
2352 for (i = 0; i < AR9170_NUM_TID; i++) {
2353 sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN;
2354 sta_info->agg[i].active = false;
2355 sta_info->agg[i].ssn = 0;
Christian Lamparteracbadf02009-07-11 17:24:14 +02002356 sta_info->agg[i].tid = i;
2357 INIT_LIST_HEAD(&sta_info->agg[i].list);
2358 skb_queue_head_init(&sta_info->agg[i].queue);
2359 }
2360
2361 sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor);
2362 break;
2363
2364 case STA_NOTIFY_REMOVE:
2365 if (!sta->ht_cap.ht_supported)
2366 break;
2367
2368 for (i = 0; i < AR9170_NUM_TID; i++) {
2369 sta_info->agg[i].state = AR9170_TID_STATE_INVALID;
2370 skb_queue_purge(&sta_info->agg[i].queue);
2371 }
2372
2373 break;
2374
2375 default:
2376 break;
2377 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01002378}
2379
2380static int ar9170_get_stats(struct ieee80211_hw *hw,
2381 struct ieee80211_low_level_stats *stats)
2382{
2383 struct ar9170 *ar = hw->priv;
2384 u32 val;
2385 int err;
2386
2387 mutex_lock(&ar->mutex);
2388 err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
2389 ar->stats.dot11ACKFailureCount += val;
2390
2391 memcpy(stats, &ar->stats, sizeof(*stats));
2392 mutex_unlock(&ar->mutex);
2393
2394 return 0;
2395}
2396
2397static int ar9170_get_tx_stats(struct ieee80211_hw *hw,
2398 struct ieee80211_tx_queue_stats *tx_stats)
2399{
2400 struct ar9170 *ar = hw->priv;
2401
2402 spin_lock_bh(&ar->tx_stats_lock);
2403 memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues);
2404 spin_unlock_bh(&ar->tx_stats_lock);
2405
2406 return 0;
2407}
2408
2409static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
2410 const struct ieee80211_tx_queue_params *param)
2411{
2412 struct ar9170 *ar = hw->priv;
2413 int ret;
2414
2415 mutex_lock(&ar->mutex);
Dan Carpentere9d126c2009-08-09 14:24:09 +02002416 if (queue < __AR9170_NUM_TXQ) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002417 memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
2418 param, sizeof(*param));
2419
2420 ret = ar9170_set_qos(ar);
Dan Carpentere9d126c2009-08-09 14:24:09 +02002421 } else {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002422 ret = -EINVAL;
Dan Carpentere9d126c2009-08-09 14:24:09 +02002423 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01002424
2425 mutex_unlock(&ar->mutex);
2426 return ret;
2427}
2428
Johannes Berg9e52b062009-04-20 18:27:04 +02002429static int ar9170_ampdu_action(struct ieee80211_hw *hw,
Johannes Bergc951ad32009-11-16 12:00:38 +01002430 struct ieee80211_vif *vif,
Johannes Berg9e52b062009-04-20 18:27:04 +02002431 enum ieee80211_ampdu_mlme_action action,
2432 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
2433{
Christian Lamparteracbadf02009-07-11 17:24:14 +02002434 struct ar9170 *ar = hw->priv;
2435 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2436 struct ar9170_sta_tid *tid_info = &sta_info->agg[tid];
2437 unsigned long flags;
2438
2439 if (!modparam_ht)
2440 return -EOPNOTSUPP;
2441
Johannes Berg9e52b062009-04-20 18:27:04 +02002442 switch (action) {
Christian Lamparteracbadf02009-07-11 17:24:14 +02002443 case IEEE80211_AMPDU_TX_START:
2444 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2445 if (tid_info->state != AR9170_TID_STATE_SHUTDOWN ||
2446 !list_empty(&tid_info->list)) {
2447 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2448#ifdef AR9170_TXAGG_DEBUG
2449 printk(KERN_INFO "%s: A-MPDU [ESS:[%pM] tid:[%d]] "
2450 "is in a very bad state!\n",
2451 wiphy_name(hw->wiphy), sta->addr, tid);
2452#endif /* AR9170_TXAGG_DEBUG */
2453 return -EBUSY;
2454 }
2455
2456 *ssn = tid_info->ssn;
2457 tid_info->state = AR9170_TID_STATE_PROGRESS;
2458 tid_info->active = false;
2459 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
Johannes Bergc951ad32009-11-16 12:00:38 +01002460 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002461 break;
2462
2463 case IEEE80211_AMPDU_TX_STOP:
2464 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2465 tid_info->state = AR9170_TID_STATE_SHUTDOWN;
2466 list_del_init(&tid_info->list);
2467 tid_info->active = false;
2468 skb_queue_purge(&tid_info->queue);
2469 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
Johannes Bergc951ad32009-11-16 12:00:38 +01002470 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002471 break;
2472
2473 case IEEE80211_AMPDU_TX_OPERATIONAL:
2474#ifdef AR9170_TXAGG_DEBUG
2475 printk(KERN_INFO "%s: A-MPDU for %pM [tid:%d] Operational.\n",
2476 wiphy_name(hw->wiphy), sta->addr, tid);
2477#endif /* AR9170_TXAGG_DEBUG */
2478 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2479 sta_info->agg[tid].state = AR9170_TID_STATE_COMPLETE;
2480 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2481 break;
2482
Johannes Berg9e52b062009-04-20 18:27:04 +02002483 case IEEE80211_AMPDU_RX_START:
2484 case IEEE80211_AMPDU_RX_STOP:
Christian Lamparteracbadf02009-07-11 17:24:14 +02002485 /* Handled by firmware */
2486 break;
2487
Johannes Berg9e52b062009-04-20 18:27:04 +02002488 default:
2489 return -EOPNOTSUPP;
2490 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02002491
2492 return 0;
Johannes Berg9e52b062009-04-20 18:27:04 +02002493}
2494
Christian Lampartere9348cd2009-03-21 23:05:13 +01002495static const struct ieee80211_ops ar9170_ops = {
2496 .start = ar9170_op_start,
2497 .stop = ar9170_op_stop,
2498 .tx = ar9170_op_tx,
2499 .add_interface = ar9170_op_add_interface,
2500 .remove_interface = ar9170_op_remove_interface,
2501 .config = ar9170_op_config,
Johannes Berg3ac64be2009-08-17 16:16:53 +02002502 .prepare_multicast = ar9170_op_prepare_multicast,
Christian Lampartere9348cd2009-03-21 23:05:13 +01002503 .configure_filter = ar9170_op_configure_filter,
2504 .conf_tx = ar9170_conf_tx,
2505 .bss_info_changed = ar9170_op_bss_info_changed,
2506 .get_tsf = ar9170_op_get_tsf,
2507 .set_key = ar9170_set_key,
2508 .sta_notify = ar9170_sta_notify,
2509 .get_stats = ar9170_get_stats,
2510 .get_tx_stats = ar9170_get_tx_stats,
Johannes Berg9e52b062009-04-20 18:27:04 +02002511 .ampdu_action = ar9170_ampdu_action,
Christian Lampartere9348cd2009-03-21 23:05:13 +01002512};
2513
2514void *ar9170_alloc(size_t priv_size)
2515{
2516 struct ieee80211_hw *hw;
2517 struct ar9170 *ar;
Christian Lampartercca847992009-04-19 01:28:12 +02002518 struct sk_buff *skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002519 int i;
2520
Christian Lampartercca847992009-04-19 01:28:12 +02002521 /*
2522 * this buffer is used for rx stream reconstruction.
2523 * Under heavy load this device (or the transport layer?)
2524 * tends to split the streams into seperate rx descriptors.
2525 */
2526
2527 skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL);
2528 if (!skb)
2529 goto err_nomem;
2530
Christian Lampartere9348cd2009-03-21 23:05:13 +01002531 hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
2532 if (!hw)
Christian Lampartercca847992009-04-19 01:28:12 +02002533 goto err_nomem;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002534
2535 ar = hw->priv;
2536 ar->hw = hw;
Christian Lampartercca847992009-04-19 01:28:12 +02002537 ar->rx_failover = skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002538
2539 mutex_init(&ar->mutex);
2540 spin_lock_init(&ar->cmdlock);
2541 spin_lock_init(&ar->tx_stats_lock);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002542 spin_lock_init(&ar->tx_ampdu_list_lock);
2543 skb_queue_head_init(&ar->tx_status_ampdu);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002544 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
2545 skb_queue_head_init(&ar->tx_status[i]);
2546 skb_queue_head_init(&ar->tx_pending[i]);
2547 }
Christian Lampartercca847992009-04-19 01:28:12 +02002548 ar9170_rx_reset_rx_mpdu(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002549 INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002550 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
Christian Lamparteracbadf02009-07-11 17:24:14 +02002551 INIT_LIST_HEAD(&ar->tx_ampdu_list);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002552
2553 /* all hw supports 2.4 GHz, so set channel to 1 by default */
2554 ar->channel = &ar9170_2ghz_chantable[0];
2555
2556 /* first part of wiphy init */
2557 ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2558 BIT(NL80211_IFTYPE_WDS) |
2559 BIT(NL80211_IFTYPE_ADHOC);
2560 ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
2561 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
2562 IEEE80211_HW_SIGNAL_DBM |
2563 IEEE80211_HW_NOISE_DBM;
2564
Christian Lamparteracbadf02009-07-11 17:24:14 +02002565 if (modparam_ht) {
2566 ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
2567 } else {
2568 ar9170_band_2GHz.ht_cap.ht_supported = false;
2569 ar9170_band_5GHz.ht_cap.ht_supported = false;
2570 }
2571
Christian Lamparter4a48e2a2009-03-23 12:15:43 +01002572 ar->hw->queues = __AR9170_NUM_TXQ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002573 ar->hw->extra_tx_headroom = 8;
2574 ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
2575
2576 ar->hw->max_rates = 1;
2577 ar->hw->max_rate_tries = 3;
2578
2579 for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
2580 ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
2581
2582 return ar;
Christian Lampartercca847992009-04-19 01:28:12 +02002583
2584err_nomem:
2585 kfree_skb(skb);
2586 return ERR_PTR(-ENOMEM);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002587}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002588
2589static int ar9170_read_eeprom(struct ar9170 *ar)
2590{
2591#define RW 8 /* number of words to read at once */
2592#define RB (sizeof(u32) * RW)
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002593 struct ath_regulatory *regulatory = &ar->common.regulatory;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002594 u8 *eeprom = (void *)&ar->eeprom;
2595 u8 *addr = ar->eeprom.mac_address;
2596 __le32 offsets[RW];
Christian Lamparteracbadf02009-07-11 17:24:14 +02002597 unsigned int rx_streams, tx_streams, tx_params = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002598 int i, j, err, bands = 0;
2599
2600 BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
2601
2602 BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
2603#ifndef __CHECKER__
2604 /* don't want to handle trailing remains */
2605 BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
2606#endif
2607
2608 for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
2609 for (j = 0; j < RW; j++)
2610 offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
2611 RB * i + 4 * j);
2612
2613 err = ar->exec_cmd(ar, AR9170_CMD_RREG,
2614 RB, (u8 *) &offsets,
2615 RB, eeprom + RB * i);
2616 if (err)
2617 return err;
2618 }
2619
2620#undef RW
2621#undef RB
2622
2623 if (ar->eeprom.length == cpu_to_le16(0xFFFF))
2624 return -ENODATA;
2625
2626 if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
2627 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
2628 bands++;
2629 }
2630 if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
2631 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
2632 bands++;
2633 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02002634
2635 rx_streams = hweight8(ar->eeprom.rx_mask);
2636 tx_streams = hweight8(ar->eeprom.tx_mask);
2637
2638 if (rx_streams != tx_streams)
2639 tx_params = IEEE80211_HT_MCS_TX_RX_DIFF;
2640
2641 if (tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS)
2642 tx_params = (tx_streams - 1) <<
2643 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
2644
2645 ar9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
2646 ar9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params;
2647
Christian Lampartere9348cd2009-03-21 23:05:13 +01002648 /*
2649 * I measured this, a bandswitch takes roughly
2650 * 135 ms and a frequency switch about 80.
2651 *
2652 * FIXME: measure these values again once EEPROM settings
2653 * are used, that will influence them!
2654 */
2655 if (bands == 2)
2656 ar->hw->channel_change_time = 135 * 1000;
2657 else
2658 ar->hw->channel_change_time = 80 * 1000;
2659
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002660 regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
2661 regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
Christian Lamparter1878f772009-03-30 22:30:32 -04002662
Christian Lampartere9348cd2009-03-21 23:05:13 +01002663 /* second part of wiphy init */
2664 SET_IEEE80211_PERM_ADDR(ar->hw, addr);
2665
2666 return bands ? 0 : -EINVAL;
2667}
2668
Christian Lamparter1878f772009-03-30 22:30:32 -04002669static int ar9170_reg_notifier(struct wiphy *wiphy,
2670 struct regulatory_request *request)
2671{
2672 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2673 struct ar9170 *ar = hw->priv;
2674
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002675 return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory);
Christian Lamparter1878f772009-03-30 22:30:32 -04002676}
2677
Christian Lampartere9348cd2009-03-21 23:05:13 +01002678int ar9170_register(struct ar9170 *ar, struct device *pdev)
2679{
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002680 struct ath_regulatory *regulatory = &ar->common.regulatory;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002681 int err;
2682
2683 /* try to read EEPROM, init MAC addr */
2684 err = ar9170_read_eeprom(ar);
2685 if (err)
2686 goto err_out;
2687
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002688 err = ath_regd_init(regulatory, ar->hw->wiphy,
Christian Lamparter1878f772009-03-30 22:30:32 -04002689 ar9170_reg_notifier);
Luis R. Rodriguez85efc862009-04-13 21:41:46 -04002690 if (err)
2691 goto err_out;
Christian Lamparter1878f772009-03-30 22:30:32 -04002692
Christian Lampartere9348cd2009-03-21 23:05:13 +01002693 err = ieee80211_register_hw(ar->hw);
2694 if (err)
2695 goto err_out;
2696
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002697 if (!ath_is_world_regd(regulatory))
2698 regulatory_hint(ar->hw->wiphy, regulatory->alpha2);
Christian Lamparter1878f772009-03-30 22:30:32 -04002699
Christian Lampartere9348cd2009-03-21 23:05:13 +01002700 err = ar9170_init_leds(ar);
2701 if (err)
2702 goto err_unreg;
2703
2704#ifdef CONFIG_AR9170_LEDS
2705 err = ar9170_register_leds(ar);
2706 if (err)
2707 goto err_unreg;
2708#endif /* CONFIG_AR9170_LEDS */
2709
2710 dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
2711 wiphy_name(ar->hw->wiphy));
2712
2713 return err;
2714
2715err_unreg:
2716 ieee80211_unregister_hw(ar->hw);
2717
2718err_out:
2719 return err;
2720}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002721
2722void ar9170_unregister(struct ar9170 *ar)
2723{
2724#ifdef CONFIG_AR9170_LEDS
2725 ar9170_unregister_leds(ar);
2726#endif /* CONFIG_AR9170_LEDS */
2727
Christian Lampartercca847992009-04-19 01:28:12 +02002728 kfree_skb(ar->rx_failover);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002729 ieee80211_unregister_hw(ar->hw);
2730 mutex_destroy(&ar->mutex);
2731}