blob: b0654c873300578f39b0fd63feac9892e5c816f0 [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
52#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \
53 .bitrate = (_bitrate), \
54 .flags = (_flags), \
55 .hw_value = (_hw_rate) | (_txpidx) << 4, \
56}
57
58static struct ieee80211_rate __ar9170_ratetable[] = {
59 RATE(10, 0, 0, 0),
60 RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE),
61 RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE),
62 RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE),
63 RATE(60, 0xb, 0, 0),
64 RATE(90, 0xf, 0, 0),
65 RATE(120, 0xa, 0, 0),
66 RATE(180, 0xe, 0, 0),
67 RATE(240, 0x9, 0, 0),
68 RATE(360, 0xd, 1, 0),
69 RATE(480, 0x8, 2, 0),
70 RATE(540, 0xc, 3, 0),
71};
72#undef RATE
73
74#define ar9170_g_ratetable (__ar9170_ratetable + 0)
75#define ar9170_g_ratetable_size 12
76#define ar9170_a_ratetable (__ar9170_ratetable + 4)
77#define ar9170_a_ratetable_size 8
78
79/*
80 * NB: The hw_value is used as an index into the ar9170_phy_freq_params
81 * array in phy.c so that we don't have to do frequency lookups!
82 */
83#define CHAN(_freq, _idx) { \
84 .center_freq = (_freq), \
85 .hw_value = (_idx), \
86 .max_power = 18, /* XXX */ \
87}
88
89static struct ieee80211_channel ar9170_2ghz_chantable[] = {
90 CHAN(2412, 0),
91 CHAN(2417, 1),
92 CHAN(2422, 2),
93 CHAN(2427, 3),
94 CHAN(2432, 4),
95 CHAN(2437, 5),
96 CHAN(2442, 6),
97 CHAN(2447, 7),
98 CHAN(2452, 8),
99 CHAN(2457, 9),
100 CHAN(2462, 10),
101 CHAN(2467, 11),
102 CHAN(2472, 12),
103 CHAN(2484, 13),
104};
105
106static struct ieee80211_channel ar9170_5ghz_chantable[] = {
107 CHAN(4920, 14),
108 CHAN(4940, 15),
109 CHAN(4960, 16),
110 CHAN(4980, 17),
111 CHAN(5040, 18),
112 CHAN(5060, 19),
113 CHAN(5080, 20),
114 CHAN(5180, 21),
115 CHAN(5200, 22),
116 CHAN(5220, 23),
117 CHAN(5240, 24),
118 CHAN(5260, 25),
119 CHAN(5280, 26),
120 CHAN(5300, 27),
121 CHAN(5320, 28),
122 CHAN(5500, 29),
123 CHAN(5520, 30),
124 CHAN(5540, 31),
125 CHAN(5560, 32),
126 CHAN(5580, 33),
127 CHAN(5600, 34),
128 CHAN(5620, 35),
129 CHAN(5640, 36),
130 CHAN(5660, 37),
131 CHAN(5680, 38),
132 CHAN(5700, 39),
133 CHAN(5745, 40),
134 CHAN(5765, 41),
135 CHAN(5785, 42),
136 CHAN(5805, 43),
137 CHAN(5825, 44),
138 CHAN(5170, 45),
139 CHAN(5190, 46),
140 CHAN(5210, 47),
141 CHAN(5230, 48),
142};
143#undef CHAN
144
Johannes Berg9e52b06232009-04-20 18:27:04 +0200145#define AR9170_HT_CAP \
146{ \
147 .ht_supported = true, \
148 .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
Johannes Berg9e52b06232009-04-20 18:27:04 +0200149 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
150 IEEE80211_HT_CAP_SGI_40 | \
Christian Lamparteracbadf02009-07-11 17:24:14 +0200151 IEEE80211_HT_CAP_GRN_FLD | \
Johannes Berg9e52b06232009-04-20 18:27:04 +0200152 IEEE80211_HT_CAP_DSSSCCK40 | \
153 IEEE80211_HT_CAP_SM_PS, \
Christian Lamparter083c4682009-04-24 21:35:57 +0200154 .ampdu_factor = 3, \
155 .ampdu_density = 6, \
Johannes Berg9e52b06232009-04-20 18:27:04 +0200156 .mcs = { \
Christian Lamparteracbadf02009-07-11 17:24:14 +0200157 .rx_mask = { 0xff, 0xff, 0, 0, 0x1, 0, 0, 0, 0, 0, }, \
158 .rx_highest = cpu_to_le16(300), \
159 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
Johannes Berg9e52b06232009-04-20 18:27:04 +0200160 }, \
161}
162
Christian Lampartere9348cd2009-03-21 23:05:13 +0100163static struct ieee80211_supported_band ar9170_band_2GHz = {
164 .channels = ar9170_2ghz_chantable,
165 .n_channels = ARRAY_SIZE(ar9170_2ghz_chantable),
166 .bitrates = ar9170_g_ratetable,
167 .n_bitrates = ar9170_g_ratetable_size,
Johannes Berg9e52b06232009-04-20 18:27:04 +0200168 .ht_cap = AR9170_HT_CAP,
169};
170
171static struct ieee80211_supported_band ar9170_band_5GHz = {
172 .channels = ar9170_5ghz_chantable,
173 .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
174 .bitrates = ar9170_a_ratetable,
175 .n_bitrates = ar9170_a_ratetable_size,
176 .ht_cap = AR9170_HT_CAP,
Christian Lampartere9348cd2009-03-21 23:05:13 +0100177};
178
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200179static void ar9170_tx(struct ar9170 *ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100180
Christian Lamparteracbadf02009-07-11 17:24:14 +0200181static inline u16 ar9170_get_seq_h(struct ieee80211_hdr *hdr)
182{
183 return le16_to_cpu(hdr->seq_ctrl) >> 4;
184}
185
186static inline u16 ar9170_get_seq(struct sk_buff *skb)
187{
188 struct ar9170_tx_control *txc = (void *) skb->data;
189 return ar9170_get_seq_h((void *) txc->frame_data);
190}
191
Christian Lamparterf3926b42010-05-01 18:18:18 +0200192#ifdef AR9170_QUEUE_DEBUG
Christian Lampartere9348cd2009-03-21 23:05:13 +0100193static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
194{
195 struct ar9170_tx_control *txc = (void *) skb->data;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200196 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
197 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
198 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100199
Christian Lamparter15b098b2009-11-29 00:56:55 +0100200 printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] s:%d "
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200201 "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
Christian Lampartere9348cd2009-03-21 23:05:13 +0100202 wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
Christian Lamparter15b098b2009-11-29 00:56:55 +0100203 ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr),
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200204 le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
205 jiffies_to_msecs(arinfo->timeout - jiffies));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100206}
207
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200208static void __ar9170_dump_txqueue(struct ar9170 *ar,
209 struct sk_buff_head *queue)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100210{
211 struct sk_buff *skb;
212 int i = 0;
213
214 printk(KERN_DEBUG "---[ cut here ]---\n");
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200215 printk(KERN_DEBUG "%s: %d entries in queue.\n",
Christian Lampartere9348cd2009-03-21 23:05:13 +0100216 wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
217
218 skb_queue_walk(queue, skb) {
Luis de Bethencourtb4098942010-03-31 15:07:48 +0100219 printk(KERN_DEBUG "index:%d =>\n", i++);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100220 ar9170_print_txheader(ar, skb);
221 }
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200222 if (i != skb_queue_len(queue))
223 printk(KERN_DEBUG "WARNING: queue frame counter "
224 "mismatch %d != %d\n", skb_queue_len(queue), i);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100225 printk(KERN_DEBUG "---[ end ]---\n");
226}
Christian Lamparterf3926b42010-05-01 18:18:18 +0200227#endif /* AR9170_QUEUE_DEBUG */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100228
Christian Lamparteracbadf02009-07-11 17:24:14 +0200229#ifdef AR9170_QUEUE_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200230static void ar9170_dump_txqueue(struct ar9170 *ar,
231 struct sk_buff_head *queue)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100232{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200233 unsigned long flags;
234
235 spin_lock_irqsave(&queue->lock, flags);
236 __ar9170_dump_txqueue(ar, queue);
237 spin_unlock_irqrestore(&queue->lock, flags);
238}
Christian Lamparteracbadf02009-07-11 17:24:14 +0200239#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200240
Christian Lamparteracbadf02009-07-11 17:24:14 +0200241#ifdef AR9170_QUEUE_STOP_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200242static void __ar9170_dump_txstats(struct ar9170 *ar)
243{
244 int i;
245
246 printk(KERN_DEBUG "%s: QoS queue stats\n",
247 wiphy_name(ar->hw->wiphy));
248
249 for (i = 0; i < __AR9170_NUM_TXQ; i++)
Christian Lamparteracbadf02009-07-11 17:24:14 +0200250 printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d "
251 " stopped:%d\n", wiphy_name(ar->hw->wiphy), i,
252 ar->tx_stats[i].limit, ar->tx_stats[i].len,
253 skb_queue_len(&ar->tx_status[i]),
254 ieee80211_queue_stopped(ar->hw, i));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200255}
Christian Lamparteracbadf02009-07-11 17:24:14 +0200256#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200257
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200258/* caller must guarantee exclusive access for _bin_ queue. */
259static void ar9170_recycle_expired(struct ar9170 *ar,
260 struct sk_buff_head *queue,
261 struct sk_buff_head *bin)
262{
263 struct sk_buff *skb, *old = NULL;
264 unsigned long flags;
265
266 spin_lock_irqsave(&queue->lock, flags);
267 while ((skb = skb_peek(queue))) {
268 struct ieee80211_tx_info *txinfo;
269 struct ar9170_tx_info *arinfo;
270
271 txinfo = IEEE80211_SKB_CB(skb);
272 arinfo = (void *) txinfo->rate_driver_data;
273
274 if (time_is_before_jiffies(arinfo->timeout)) {
275#ifdef AR9170_QUEUE_DEBUG
276 printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => "
Luis de Bethencourtb4098942010-03-31 15:07:48 +0100277 "recycle\n", wiphy_name(ar->hw->wiphy),
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200278 jiffies, arinfo->timeout);
279 ar9170_print_txheader(ar, skb);
280#endif /* AR9170_QUEUE_DEBUG */
281 __skb_unlink(skb, queue);
282 __skb_queue_tail(bin, skb);
283 } else {
284 break;
285 }
286
287 if (unlikely(old == skb)) {
288 /* bail out - queue is shot. */
289
290 WARN_ON(1);
291 break;
292 }
293 old = skb;
294 }
295 spin_unlock_irqrestore(&queue->lock, flags);
296}
297
298static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
299 u16 tx_status)
300{
301 struct ieee80211_tx_info *txinfo;
302 unsigned int retries = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100303
304 txinfo = IEEE80211_SKB_CB(skb);
305 ieee80211_tx_info_clear_status(txinfo);
306
307 switch (tx_status) {
308 case AR9170_TX_STATUS_RETRY:
309 retries = 2;
310 case AR9170_TX_STATUS_COMPLETE:
311 txinfo->flags |= IEEE80211_TX_STAT_ACK;
312 break;
313
314 case AR9170_TX_STATUS_FAILED:
315 retries = ar->hw->conf.long_frame_max_tx_count;
316 break;
317
318 default:
319 printk(KERN_ERR "%s: invalid tx_status response (%x).\n",
320 wiphy_name(ar->hw->wiphy), tx_status);
321 break;
322 }
323
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200324 txinfo->status.rates[0].count = retries + 1;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100325 skb_pull(skb, sizeof(struct ar9170_tx_control));
326 ieee80211_tx_status_irqsafe(ar->hw, skb);
327}
Christian Lampartere9348cd2009-03-21 23:05:13 +0100328
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200329void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100330{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200331 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
332 struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data;
333 unsigned int queue = skb_get_queue_mapping(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100334 unsigned long flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100335
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200336 spin_lock_irqsave(&ar->tx_stats_lock, flags);
337 ar->tx_stats[queue].len--;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100338
Christian Lamparter53a76b52009-11-29 00:52:51 +0100339 if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200340#ifdef AR9170_QUEUE_STOP_DEBUG
341 printk(KERN_DEBUG "%s: wake queue %d\n",
342 wiphy_name(ar->hw->wiphy), queue);
343 __ar9170_dump_txstats(ar);
344#endif /* AR9170_QUEUE_STOP_DEBUG */
345 ieee80211_wake_queue(ar->hw, queue);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100346 }
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200347 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
348
Christian Lamparter15b098b2009-11-29 00:56:55 +0100349 if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200350 ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED);
351 } else {
Christian Lamparterf3926b42010-05-01 18:18:18 +0200352 arinfo->timeout = jiffies +
353 msecs_to_jiffies(AR9170_TX_TIMEOUT);
Christian Lamparter15b098b2009-11-29 00:56:55 +0100354
Christian Lamparterf3926b42010-05-01 18:18:18 +0200355 skb_queue_tail(&ar->tx_status[queue], skb);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200356 }
357
358 if (!ar->tx_stats[queue].len &&
359 !skb_queue_empty(&ar->tx_pending[queue])) {
360 ar9170_tx(ar);
361 }
Christian Lampartere9348cd2009-03-21 23:05:13 +0100362}
363
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200364static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
365 const u8 *mac,
366 struct sk_buff_head *queue,
367 const u32 rate)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100368{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200369 unsigned long flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100370 struct sk_buff *skb;
371
372 /*
373 * Unfortunately, the firmware does not tell to which (queued) frame
374 * this transmission status report belongs to.
375 *
376 * So we have to make risky guesses - with the scarce information
377 * the firmware provided (-> destination MAC, and phy_control) -
378 * and hope that we picked the right one...
379 */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100380
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200381 spin_lock_irqsave(&queue->lock, flags);
382 skb_queue_walk(queue, skb) {
383 struct ar9170_tx_control *txc = (void *) skb->data;
384 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
385 u32 r;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100386
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200387 if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) {
388#ifdef AR9170_QUEUE_DEBUG
389 printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n",
390 wiphy_name(ar->hw->wiphy), mac,
391 ieee80211_get_DA(hdr));
392 ar9170_print_txheader(ar, skb);
393#endif /* AR9170_QUEUE_DEBUG */
394 continue;
395 }
396
397 r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >>
398 AR9170_TX_PHY_MCS_SHIFT;
399
400 if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) {
401#ifdef AR9170_QUEUE_DEBUG
402 printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n",
403 wiphy_name(ar->hw->wiphy), rate, r);
404 ar9170_print_txheader(ar, skb);
405#endif /* AR9170_QUEUE_DEBUG */
406 continue;
407 }
408
409 __skb_unlink(skb, queue);
410 spin_unlock_irqrestore(&queue->lock, flags);
411 return skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100412 }
Christian Lampartere9348cd2009-03-21 23:05:13 +0100413
414#ifdef AR9170_QUEUE_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200415 printk(KERN_ERR "%s: ESS:[%pM] does not have any "
416 "outstanding frames in queue.\n",
417 wiphy_name(ar->hw->wiphy), mac);
418 __ar9170_dump_txqueue(ar, queue);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100419#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200420 spin_unlock_irqrestore(&queue->lock, flags);
421
422 return NULL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100423}
424
425/*
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200426 * This worker tries to keeps an maintain tx_status queues.
427 * So we can guarantee that incoming tx_status reports are
428 * actually for a pending frame.
Christian Lampartere9348cd2009-03-21 23:05:13 +0100429 */
430
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200431static void ar9170_tx_janitor(struct work_struct *work)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100432{
433 struct ar9170 *ar = container_of(work, struct ar9170,
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200434 tx_janitor.work);
435 struct sk_buff_head waste;
436 unsigned int i;
437 bool resched = false;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100438
Christian Lamparter4a48e2a2009-03-23 12:15:43 +0100439 if (unlikely(!IS_STARTED(ar)))
440 return ;
441
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200442 skb_queue_head_init(&waste);
443
444 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
Christian Lampartere9348cd2009-03-21 23:05:13 +0100445#ifdef AR9170_QUEUE_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200446 printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n",
447 wiphy_name(ar->hw->wiphy), i);
448 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
449 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100450#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200451
452 ar9170_recycle_expired(ar, &ar->tx_status[i], &waste);
453 ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste);
454 skb_queue_purge(&waste);
455
456 if (!skb_queue_empty(&ar->tx_status[i]) ||
457 !skb_queue_empty(&ar->tx_pending[i]))
458 resched = true;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100459 }
460
Luis R. Rodriguez42935ec2009-07-29 20:08:07 -0400461 if (!resched)
462 return;
463
464 ieee80211_queue_delayed_work(ar->hw,
465 &ar->tx_janitor,
466 msecs_to_jiffies(AR9170_JANITOR_DELAY));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100467}
468
Christian Lamparter66d00812009-05-28 17:04:27 +0200469void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100470{
471 struct ar9170_cmd_response *cmd = (void *) buf;
472
473 if ((cmd->type & 0xc0) != 0xc0) {
474 ar->callback_cmd(ar, len, buf);
475 return;
476 }
477
478 /* hardware event handlers */
479 switch (cmd->type) {
480 case 0xc1: {
481 /*
482 * TX status notification:
483 * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
484 *
485 * XX always 81
486 * YY always 00
487 * M1-M6 is the MAC address
488 * R1-R4 is the transmit rate
489 * S1-S2 is the transmit status
490 */
491
492 struct sk_buff *skb;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200493 u32 phy = le32_to_cpu(cmd->tx_status.rate);
494 u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >>
495 AR9170_TX_PHY_QOS_SHIFT;
496#ifdef AR9170_QUEUE_DEBUG
497 printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n",
498 wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q);
499#endif /* AR9170_QUEUE_DEBUG */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100500
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200501 skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst,
502 &ar->tx_status[q],
503 AR9170_TX_INVALID_RATE);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100504 if (unlikely(!skb))
505 return ;
506
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200507 ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100508 break;
509 }
510
511 case 0xc0:
512 /*
513 * pre-TBTT event
514 */
515 if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
Luis R. Rodriguez42935ec2009-07-29 20:08:07 -0400516 ieee80211_queue_work(ar->hw, &ar->beacon_work);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100517 break;
518
519 case 0xc2:
520 /*
521 * (IBSS) beacon send notification
522 * bytes: 04 c2 XX YY B4 B3 B2 B1
523 *
524 * XX always 80
525 * YY always 00
526 * B1-B4 "should" be the number of send out beacons.
527 */
528 break;
529
530 case 0xc3:
531 /* End of Atim Window */
532 break;
533
534 case 0xc4:
Christian Lamparteracbadf02009-07-11 17:24:14 +0200535 /* BlockACK bitmap */
536 break;
537
Christian Lampartere9348cd2009-03-21 23:05:13 +0100538 case 0xc5:
539 /* BlockACK events */
540 break;
541
542 case 0xc6:
543 /* Watchdog Interrupt */
544 break;
545
546 case 0xc9:
547 /* retransmission issue / SIFS/EIFS collision ?! */
548 break;
549
Johannes Berg2543a0c2009-06-05 11:47:43 +0200550 /* firmware debug */
551 case 0xca:
Luis de Bethencourtb4098942010-03-31 15:07:48 +0100552 printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4,
553 (char *)buf + 4);
Johannes Berg2543a0c2009-06-05 11:47:43 +0200554 break;
555 case 0xcb:
556 len -= 4;
557
558 switch (len) {
559 case 1:
560 printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n",
561 *((char *)buf + 4));
562 break;
563 case 2:
564 printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n",
565 le16_to_cpup((__le16 *)((char *)buf + 4)));
566 break;
567 case 4:
568 printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n",
569 le32_to_cpup((__le32 *)((char *)buf + 4)));
570 break;
571 case 8:
572 printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n",
573 (unsigned long)le64_to_cpup(
574 (__le64 *)((char *)buf + 4)));
575 break;
576 }
577 break;
578 case 0xcc:
579 print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE,
580 (char *)buf + 4, len - 4);
581 break;
582
Christian Lampartere9348cd2009-03-21 23:05:13 +0100583 default:
584 printk(KERN_INFO "received unhandled event %x\n", cmd->type);
585 print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
586 break;
587 }
588}
589
Christian Lampartercca847992009-04-19 01:28:12 +0200590static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100591{
Christian Lampartercca847992009-04-19 01:28:12 +0200592 memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head));
593 ar->rx_mpdu.has_plcp = false;
594}
Christian Lampartere9348cd2009-03-21 23:05:13 +0100595
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200596int ar9170_nag_limiter(struct ar9170 *ar)
Christian Lampartercca847992009-04-19 01:28:12 +0200597{
598 bool print_message;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100599
Christian Lampartercca847992009-04-19 01:28:12 +0200600 /*
601 * we expect all sorts of errors in promiscuous mode.
602 * don't bother with it, it's OK!
603 */
604 if (ar->sniffer_enabled)
605 return false;
606
607 /*
608 * only go for frequent errors! The hardware tends to
609 * do some stupid thing once in a while under load, in
610 * noisy environments or just for fun!
611 */
612 if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit())
613 print_message = true;
614 else
615 print_message = false;
616
617 /* reset threshold for "once in a while" */
618 ar->bad_hw_nagger = jiffies + HZ / 4;
619 return print_message;
620}
621
622static int ar9170_rx_mac_status(struct ar9170 *ar,
623 struct ar9170_rx_head *head,
624 struct ar9170_rx_macstatus *mac,
625 struct ieee80211_rx_status *status)
626{
627 u8 error, decrypt;
628
Christian Lampartere9348cd2009-03-21 23:05:13 +0100629 BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
Christian Lampartercca847992009-04-19 01:28:12 +0200630 BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100631
Christian Lampartercca847992009-04-19 01:28:12 +0200632 error = mac->error;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100633 if (error & AR9170_RX_ERROR_MMIC) {
Christian Lampartercca847992009-04-19 01:28:12 +0200634 status->flag |= RX_FLAG_MMIC_ERROR;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100635 error &= ~AR9170_RX_ERROR_MMIC;
636 }
637
638 if (error & AR9170_RX_ERROR_PLCP) {
Christian Lampartercca847992009-04-19 01:28:12 +0200639 status->flag |= RX_FLAG_FAILED_PLCP_CRC;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100640 error &= ~AR9170_RX_ERROR_PLCP;
Christian Lampartercca847992009-04-19 01:28:12 +0200641
642 if (!(ar->filter_state & FIF_PLCPFAIL))
643 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100644 }
645
646 if (error & AR9170_RX_ERROR_FCS) {
Christian Lampartercca847992009-04-19 01:28:12 +0200647 status->flag |= RX_FLAG_FAILED_FCS_CRC;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100648 error &= ~AR9170_RX_ERROR_FCS;
Christian Lampartercca847992009-04-19 01:28:12 +0200649
650 if (!(ar->filter_state & FIF_FCSFAIL))
651 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100652 }
653
Christian Lampartercca847992009-04-19 01:28:12 +0200654 decrypt = ar9170_get_decrypt_type(mac);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100655 if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
656 decrypt != AR9170_ENC_ALG_NONE)
Christian Lampartercca847992009-04-19 01:28:12 +0200657 status->flag |= RX_FLAG_DECRYPTED;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100658
659 /* ignore wrong RA errors */
660 error &= ~AR9170_RX_ERROR_WRONG_RA;
661
662 if (error & AR9170_RX_ERROR_DECRYPT) {
663 error &= ~AR9170_RX_ERROR_DECRYPT;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100664 /*
665 * Rx decryption is done in place,
666 * the original data is lost anyway.
667 */
Christian Lampartercca847992009-04-19 01:28:12 +0200668
669 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100670 }
671
672 /* drop any other error frames */
Christian Lampartercca847992009-04-19 01:28:12 +0200673 if (unlikely(error)) {
674 /* TODO: update netdevice's RX dropped/errors statistics */
675
676 if (ar9170_nag_limiter(ar))
677 printk(KERN_DEBUG "%s: received frame with "
678 "suspicious error code (%#x).\n",
679 wiphy_name(ar->hw->wiphy), error);
680
681 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100682 }
683
Christian Lampartercca847992009-04-19 01:28:12 +0200684 status->band = ar->channel->band;
685 status->freq = ar->channel->center_freq;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100686
Christian Lampartercca847992009-04-19 01:28:12 +0200687 switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) {
688 case AR9170_RX_STATUS_MODULATION_CCK:
689 if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
690 status->flag |= RX_FLAG_SHORTPRE;
691 switch (head->plcp[0]) {
692 case 0x0a:
693 status->rate_idx = 0;
694 break;
695 case 0x14:
696 status->rate_idx = 1;
697 break;
698 case 0x37:
699 status->rate_idx = 2;
700 break;
701 case 0x6e:
702 status->rate_idx = 3;
703 break;
704 default:
705 if (ar9170_nag_limiter(ar))
706 printk(KERN_ERR "%s: invalid plcp cck rate "
707 "(%x).\n", wiphy_name(ar->hw->wiphy),
708 head->plcp[0]);
709 return -EINVAL;
710 }
711 break;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100712
Christian Lamparter7d57b732009-11-14 00:57:58 +0100713 case AR9170_RX_STATUS_MODULATION_DUPOFDM:
Christian Lampartercca847992009-04-19 01:28:12 +0200714 case AR9170_RX_STATUS_MODULATION_OFDM:
715 switch (head->plcp[0] & 0xf) {
716 case 0xb:
717 status->rate_idx = 0;
718 break;
719 case 0xf:
720 status->rate_idx = 1;
721 break;
722 case 0xa:
723 status->rate_idx = 2;
724 break;
725 case 0xe:
726 status->rate_idx = 3;
727 break;
728 case 0x9:
729 status->rate_idx = 4;
730 break;
731 case 0xd:
732 status->rate_idx = 5;
733 break;
734 case 0x8:
735 status->rate_idx = 6;
736 break;
737 case 0xc:
738 status->rate_idx = 7;
739 break;
740 default:
741 if (ar9170_nag_limiter(ar))
742 printk(KERN_ERR "%s: invalid plcp ofdm rate "
743 "(%x).\n", wiphy_name(ar->hw->wiphy),
744 head->plcp[0]);
745 return -EINVAL;
746 }
747 if (status->band == IEEE80211_BAND_2GHZ)
748 status->rate_idx += 4;
749 break;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100750
Christian Lampartercca847992009-04-19 01:28:12 +0200751 case AR9170_RX_STATUS_MODULATION_HT:
752 if (head->plcp[3] & 0x80)
753 status->flag |= RX_FLAG_40MHZ;
754 if (head->plcp[6] & 0x80)
755 status->flag |= RX_FLAG_SHORT_GI;
756
757 status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f);
758 status->flag |= RX_FLAG_HT;
759 break;
760
Christian Lamparter7d57b732009-11-14 00:57:58 +0100761 default:
Christian Lampartercca847992009-04-19 01:28:12 +0200762 if (ar9170_nag_limiter(ar))
763 printk(KERN_ERR "%s: invalid modulation\n",
764 wiphy_name(ar->hw->wiphy));
765 return -EINVAL;
766 }
767
768 return 0;
769}
770
771static void ar9170_rx_phy_status(struct ar9170 *ar,
772 struct ar9170_rx_phystatus *phy,
773 struct ieee80211_rx_status *status)
774{
775 int i;
776
777 BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20);
778
779 for (i = 0; i < 3; i++)
780 if (phy->rssi[i] != 0x80)
781 status->antenna |= BIT(i);
782
783 /* post-process RSSI */
784 for (i = 0; i < 7; i++)
785 if (phy->rssi[i] & 0x80)
786 phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f;
787
788 /* TODO: we could do something with phy_errors */
789 status->signal = ar->noise[0] + phy->rssi_combined;
Christian Lampartercca847992009-04-19 01:28:12 +0200790}
791
792static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len)
793{
794 struct sk_buff *skb;
795 int reserved = 0;
796 struct ieee80211_hdr *hdr = (void *) buf;
797
798 if (ieee80211_is_data_qos(hdr->frame_control)) {
799 u8 *qc = ieee80211_get_qos_ctl(hdr);
800 reserved += NET_IP_ALIGN;
801
802 if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
803 reserved += NET_IP_ALIGN;
804 }
805
806 if (ieee80211_has_a4(hdr->frame_control))
807 reserved += NET_IP_ALIGN;
808
809 reserved = 32 + (reserved & NET_IP_ALIGN);
810
811 skb = dev_alloc_skb(len + reserved);
812 if (likely(skb)) {
813 skb_reserve(skb, reserved);
814 memcpy(skb_put(skb, len), buf, len);
815 }
816
817 return skb;
818}
819
820/*
821 * If the frame alignment is right (or the kernel has
822 * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
823 * is only a single MPDU in the USB frame, then we could
824 * submit to mac80211 the SKB directly. However, since
825 * there may be multiple packets in one SKB in stream
826 * mode, and we need to observe the proper ordering,
827 * this is non-trivial.
828 */
829
830static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
831{
832 struct ar9170_rx_head *head;
833 struct ar9170_rx_macstatus *mac;
834 struct ar9170_rx_phystatus *phy = NULL;
835 struct ieee80211_rx_status status;
836 struct sk_buff *skb;
837 int mpdu_len;
838
839 if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac))))
840 return ;
841
842 /* Received MPDU */
843 mpdu_len = len - sizeof(*mac);
844
845 mac = (void *)(buf + mpdu_len);
846 if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
847 /* this frame is too damaged and can't be used - drop it */
848
849 return ;
850 }
851
852 switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) {
853 case AR9170_RX_STATUS_MPDU_FIRST:
854 /* first mpdu packet has the plcp header */
855 if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
856 head = (void *) buf;
857 memcpy(&ar->rx_mpdu.plcp, (void *) buf,
858 sizeof(struct ar9170_rx_head));
859
860 mpdu_len -= sizeof(struct ar9170_rx_head);
861 buf += sizeof(struct ar9170_rx_head);
862 ar->rx_mpdu.has_plcp = true;
863 } else {
864 if (ar9170_nag_limiter(ar))
865 printk(KERN_ERR "%s: plcp info is clipped.\n",
866 wiphy_name(ar->hw->wiphy));
867 return ;
868 }
869 break;
870
871 case AR9170_RX_STATUS_MPDU_LAST:
872 /* last mpdu has a extra tail with phy status information */
873
874 if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
875 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
876 phy = (void *)(buf + mpdu_len);
877 } else {
878 if (ar9170_nag_limiter(ar))
879 printk(KERN_ERR "%s: frame tail is clipped.\n",
880 wiphy_name(ar->hw->wiphy));
881 return ;
882 }
883
884 case AR9170_RX_STATUS_MPDU_MIDDLE:
885 /* middle mpdus are just data */
886 if (unlikely(!ar->rx_mpdu.has_plcp)) {
887 if (!ar9170_nag_limiter(ar))
888 return ;
889
890 printk(KERN_ERR "%s: rx stream did not start "
891 "with a first_mpdu frame tag.\n",
892 wiphy_name(ar->hw->wiphy));
893
894 return ;
895 }
896
897 head = &ar->rx_mpdu.plcp;
898 break;
899
900 case AR9170_RX_STATUS_MPDU_SINGLE:
901 /* single mpdu - has plcp (head) and phy status (tail) */
902 head = (void *) buf;
903
904 mpdu_len -= sizeof(struct ar9170_rx_head);
905 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
906
907 buf += sizeof(struct ar9170_rx_head);
908 phy = (void *)(buf + mpdu_len);
909 break;
910
911 default:
912 BUG_ON(1);
913 break;
914 }
915
916 if (unlikely(mpdu_len < FCS_LEN))
917 return ;
918
919 memset(&status, 0, sizeof(status));
920 if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status)))
921 return ;
922
923 if (phy)
924 ar9170_rx_phy_status(ar, phy, &status);
925
926 skb = ar9170_rx_copy_data(buf, mpdu_len);
Johannes Bergf1d58c22009-06-17 13:13:00 +0200927 if (likely(skb)) {
928 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
929 ieee80211_rx_irqsafe(ar->hw, skb);
930 }
Christian Lampartere9348cd2009-03-21 23:05:13 +0100931}
932
Christian Lampartere9348cd2009-03-21 23:05:13 +0100933void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
934{
Christian Lampartercca847992009-04-19 01:28:12 +0200935 unsigned int i, tlen, resplen, wlen = 0, clen = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100936 u8 *tbuf, *respbuf;
937
938 tbuf = skb->data;
939 tlen = skb->len;
940
941 while (tlen >= 4) {
Christian Lampartercca847992009-04-19 01:28:12 +0200942 clen = tbuf[1] << 8 | tbuf[0];
943 wlen = ALIGN(clen, 4);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100944
Christian Lampartercca847992009-04-19 01:28:12 +0200945 /* check if this is stream has a valid tag.*/
Christian Lampartere9348cd2009-03-21 23:05:13 +0100946 if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
Christian Lampartercca847992009-04-19 01:28:12 +0200947 /*
948 * TODO: handle the highly unlikely event that the
949 * corrupted stream has the TAG at the right position.
950 */
951
952 /* check if the frame can be repaired. */
953 if (!ar->rx_failover_missing) {
954 /* this is no "short read". */
955 if (ar9170_nag_limiter(ar)) {
956 printk(KERN_ERR "%s: missing tag!\n",
957 wiphy_name(ar->hw->wiphy));
958 goto err_telluser;
959 } else
960 goto err_silent;
961 }
962
963 if (ar->rx_failover_missing > tlen) {
964 if (ar9170_nag_limiter(ar)) {
965 printk(KERN_ERR "%s: possible multi "
966 "stream corruption!\n",
967 wiphy_name(ar->hw->wiphy));
968 goto err_telluser;
969 } else
970 goto err_silent;
971 }
972
973 memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
974 ar->rx_failover_missing -= tlen;
975
976 if (ar->rx_failover_missing <= 0) {
977 /*
978 * nested ar9170_rx call!
979 * termination is guranteed, even when the
980 * combined frame also have a element with
981 * a bad tag.
982 */
983
984 ar->rx_failover_missing = 0;
985 ar9170_rx(ar, ar->rx_failover);
986
987 skb_reset_tail_pointer(ar->rx_failover);
988 skb_trim(ar->rx_failover, 0);
989 }
990
Christian Lampartere9348cd2009-03-21 23:05:13 +0100991 return ;
992 }
Christian Lampartercca847992009-04-19 01:28:12 +0200993
994 /* check if stream is clipped */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100995 if (wlen > tlen - 4) {
Christian Lampartercca847992009-04-19 01:28:12 +0200996 if (ar->rx_failover_missing) {
997 /* TODO: handle double stream corruption. */
998 if (ar9170_nag_limiter(ar)) {
999 printk(KERN_ERR "%s: double rx stream "
1000 "corruption!\n",
1001 wiphy_name(ar->hw->wiphy));
1002 goto err_telluser;
1003 } else
1004 goto err_silent;
1005 }
1006
1007 /*
1008 * save incomplete data set.
1009 * the firmware will resend the missing bits when
1010 * the rx - descriptor comes round again.
1011 */
1012
1013 memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
1014 ar->rx_failover_missing = clen - tlen;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001015 return ;
1016 }
1017 resplen = clen;
1018 respbuf = tbuf + 4;
1019 tbuf += wlen + 4;
1020 tlen -= wlen + 4;
1021
1022 i = 0;
1023
1024 /* weird thing, but this is the same in the original driver */
1025 while (resplen > 2 && i < 12 &&
1026 respbuf[0] == 0xff && respbuf[1] == 0xff) {
1027 i += 2;
1028 resplen -= 2;
1029 respbuf += 2;
1030 }
1031
1032 if (resplen < 4)
1033 continue;
1034
1035 /* found the 6 * 0xffff marker? */
1036 if (i == 12)
1037 ar9170_handle_command_response(ar, respbuf, resplen);
1038 else
Christian Lampartercca847992009-04-19 01:28:12 +02001039 ar9170_handle_mpdu(ar, respbuf, clen);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001040 }
1041
Christian Lampartercca847992009-04-19 01:28:12 +02001042 if (tlen) {
1043 if (net_ratelimit())
1044 printk(KERN_ERR "%s: %d bytes of unprocessed "
1045 "data left in rx stream!\n",
1046 wiphy_name(ar->hw->wiphy), tlen);
1047
1048 goto err_telluser;
1049 }
1050
1051 return ;
1052
1053err_telluser:
1054 printk(KERN_ERR "%s: damaged RX stream data [want:%d, "
1055 "data:%d, rx:%d, pending:%d ]\n",
1056 wiphy_name(ar->hw->wiphy), clen, wlen, tlen,
1057 ar->rx_failover_missing);
1058
1059 if (ar->rx_failover_missing)
1060 print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
1061 ar->rx_failover->data,
1062 ar->rx_failover->len);
1063
1064 print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
1065 skb->data, skb->len);
1066
1067 printk(KERN_ERR "%s: please check your hardware and cables, if "
1068 "you see this message frequently.\n",
1069 wiphy_name(ar->hw->wiphy));
1070
1071err_silent:
1072 if (ar->rx_failover_missing) {
1073 skb_reset_tail_pointer(ar->rx_failover);
1074 skb_trim(ar->rx_failover, 0);
1075 ar->rx_failover_missing = 0;
1076 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001077}
Christian Lampartere9348cd2009-03-21 23:05:13 +01001078
1079#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \
1080do { \
1081 queue.aifs = ai_fs; \
1082 queue.cw_min = cwmin; \
1083 queue.cw_max = cwmax; \
1084 queue.txop = _txop; \
1085} while (0)
1086
1087static int ar9170_op_start(struct ieee80211_hw *hw)
1088{
1089 struct ar9170 *ar = hw->priv;
1090 int err, i;
1091
1092 mutex_lock(&ar->mutex);
1093
1094 /* reinitialize queues statistics */
1095 memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001096 for (i = 0; i < __AR9170_NUM_TXQ; i++)
1097 ar->tx_stats[i].limit = AR9170_TXQ_DEPTH;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001098
1099 /* reset QoS defaults */
1100 AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/
1101 AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023, 0); /* BACKGROUND */
1102 AR9170_FILL_QUEUE(ar->edcf[2], 2, 7, 15, 94); /* VIDEO */
1103 AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */
1104 AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
1105
Christian Lamparteracbadf02009-07-11 17:24:14 +02001106 /* set sane AMPDU defaults */
1107 ar->global_ampdu_density = 6;
1108 ar->global_ampdu_factor = 3;
1109
Christian Lampartercca847992009-04-19 01:28:12 +02001110 ar->bad_hw_nagger = jiffies;
1111
Christian Lampartere9348cd2009-03-21 23:05:13 +01001112 err = ar->open(ar);
1113 if (err)
1114 goto out;
1115
1116 err = ar9170_init_mac(ar);
1117 if (err)
1118 goto out;
1119
1120 err = ar9170_set_qos(ar);
1121 if (err)
1122 goto out;
1123
1124 err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
1125 if (err)
1126 goto out;
1127
1128 err = ar9170_init_rf(ar);
1129 if (err)
1130 goto out;
1131
1132 /* start DMA */
1133 err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
1134 if (err)
1135 goto out;
1136
1137 ar->state = AR9170_STARTED;
1138
1139out:
1140 mutex_unlock(&ar->mutex);
1141 return err;
1142}
1143
1144static void ar9170_op_stop(struct ieee80211_hw *hw)
1145{
1146 struct ar9170 *ar = hw->priv;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001147 unsigned int i;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001148
1149 if (IS_STARTED(ar))
1150 ar->state = AR9170_IDLE;
1151
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001152 cancel_delayed_work_sync(&ar->tx_janitor);
Alexander Beregalovff8365c2009-07-24 11:55:44 +04001153#ifdef CONFIG_AR9170_LEDS
Christian Lamparteracbadf02009-07-11 17:24:14 +02001154 cancel_delayed_work_sync(&ar->led_work);
Alexander Beregalovff8365c2009-07-24 11:55:44 +04001155#endif
Christian Lampartere9348cd2009-03-21 23:05:13 +01001156 cancel_work_sync(&ar->beacon_work);
Luis R. Rodrigueze351cfb2009-07-27 12:51:37 -07001157
Christian Lamparterb55d6bc2009-05-23 20:31:21 +02001158 mutex_lock(&ar->mutex);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001159
1160 if (IS_ACCEPTING_CMD(ar)) {
1161 ar9170_set_leds_state(ar, 0);
1162
1163 /* stop DMA */
1164 ar9170_write_reg(ar, 0x1c3d30, 0);
1165 ar->stop(ar);
1166 }
1167
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001168 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1169 skb_queue_purge(&ar->tx_pending[i]);
1170 skb_queue_purge(&ar->tx_status[i]);
1171 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02001172
Christian Lampartere9348cd2009-03-21 23:05:13 +01001173 mutex_unlock(&ar->mutex);
1174}
1175
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001176static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001177{
Christian Lampartere9348cd2009-03-21 23:05:13 +01001178 struct ieee80211_hdr *hdr;
1179 struct ar9170_tx_control *txc;
1180 struct ieee80211_tx_info *info;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001181 struct ieee80211_tx_rate *txrate;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001182 struct ar9170_tx_info *arinfo;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001183 unsigned int queue = skb_get_queue_mapping(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001184 u16 keytype = 0;
1185 u16 len, icv = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001186
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001187 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001188
1189 hdr = (void *)skb->data;
1190 info = IEEE80211_SKB_CB(skb);
1191 len = skb->len;
1192
Christian Lampartere9348cd2009-03-21 23:05:13 +01001193 txc = (void *)skb_push(skb, sizeof(*txc));
1194
Christian Lampartere9348cd2009-03-21 23:05:13 +01001195 if (info->control.hw_key) {
1196 icv = info->control.hw_key->icv_len;
1197
1198 switch (info->control.hw_key->alg) {
1199 case ALG_WEP:
1200 keytype = AR9170_TX_MAC_ENCR_RC4;
1201 break;
1202 case ALG_TKIP:
1203 keytype = AR9170_TX_MAC_ENCR_RC4;
1204 break;
1205 case ALG_CCMP:
1206 keytype = AR9170_TX_MAC_ENCR_AES;
1207 break;
1208 default:
1209 WARN_ON(1);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001210 goto err_out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001211 }
1212 }
1213
1214 /* Length */
1215 txc->length = cpu_to_le16(len + icv + 4);
1216
1217 txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
1218 AR9170_TX_MAC_BACKOFF);
1219 txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
1220 AR9170_TX_MAC_QOS_SHIFT);
1221 txc->mac_control |= cpu_to_le16(keytype);
1222 txc->phy_control = cpu_to_le32(0);
1223
1224 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
1225 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
1226
Christian Lampartere9348cd2009-03-21 23:05:13 +01001227 txrate = &info->control.rates[0];
Christian Lampartere9348cd2009-03-21 23:05:13 +01001228 if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1229 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
1230 else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1231 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
1232
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001233 arinfo = (void *)info->rate_driver_data;
1234 arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT);
1235
1236 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
1237 (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001238 /*
1239 * WARNING:
1240 * Putting the QoS queue bits into an unexplored territory is
1241 * certainly not elegant.
1242 *
1243 * In my defense: This idea provides a reasonable way to
1244 * smuggle valuable information to the tx_status callback.
1245 * Also, the idea behind this bit-abuse came straight from
1246 * the original driver code.
1247 */
1248
1249 txc->phy_control |=
1250 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
Christian Lamparter15b098b2009-11-29 00:56:55 +01001251
Christian Lamparterf3926b42010-05-01 18:18:18 +02001252 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001253 }
1254
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001255 return 0;
1256
1257err_out:
1258 skb_pull(skb, sizeof(*txc));
1259 return -EINVAL;
1260}
1261
1262static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
1263{
1264 struct ar9170_tx_control *txc;
1265 struct ieee80211_tx_info *info;
1266 struct ieee80211_rate *rate = NULL;
1267 struct ieee80211_tx_rate *txrate;
1268 u32 power, chains;
1269
1270 txc = (void *) skb->data;
1271 info = IEEE80211_SKB_CB(skb);
1272 txrate = &info->control.rates[0];
1273
Christian Lampartere9348cd2009-03-21 23:05:13 +01001274 if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
1275 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
1276
1277 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1278 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
1279
1280 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1281 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
1282 /* this works because 40 MHz is 2 and dup is 3 */
1283 if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
1284 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
1285
1286 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
1287 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
1288
1289 if (txrate->flags & IEEE80211_TX_RC_MCS) {
1290 u32 r = txrate->idx;
1291 u8 *txpower;
1292
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001293 /* heavy clip control */
1294 txc->phy_control |= cpu_to_le32((r & 0x7) << 7);
1295
Christian Lampartere9348cd2009-03-21 23:05:13 +01001296 r <<= AR9170_TX_PHY_MCS_SHIFT;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001297 BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK);
1298
Christian Lampartere9348cd2009-03-21 23:05:13 +01001299 txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
1300 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
1301
1302 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1303 if (info->band == IEEE80211_BAND_5GHZ)
1304 txpower = ar->power_5G_ht40;
1305 else
1306 txpower = ar->power_2G_ht40;
1307 } else {
1308 if (info->band == IEEE80211_BAND_5GHZ)
1309 txpower = ar->power_5G_ht20;
1310 else
1311 txpower = ar->power_2G_ht20;
1312 }
1313
1314 power = txpower[(txrate->idx) & 7];
1315 } else {
1316 u8 *txpower;
1317 u32 mod;
1318 u32 phyrate;
1319 u8 idx = txrate->idx;
1320
1321 if (info->band != IEEE80211_BAND_2GHZ) {
1322 idx += 4;
1323 txpower = ar->power_5G_leg;
1324 mod = AR9170_TX_PHY_MOD_OFDM;
1325 } else {
1326 if (idx < 4) {
1327 txpower = ar->power_2G_cck;
1328 mod = AR9170_TX_PHY_MOD_CCK;
1329 } else {
1330 mod = AR9170_TX_PHY_MOD_OFDM;
1331 txpower = ar->power_2G_ofdm;
1332 }
1333 }
1334
1335 rate = &__ar9170_ratetable[idx];
1336
1337 phyrate = rate->hw_value & 0xF;
1338 power = txpower[(rate->hw_value & 0x30) >> 4];
1339 phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
1340
1341 txc->phy_control |= cpu_to_le32(mod);
1342 txc->phy_control |= cpu_to_le32(phyrate);
1343 }
1344
1345 power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
1346 power &= AR9170_TX_PHY_TX_PWR_MASK;
1347 txc->phy_control |= cpu_to_le32(power);
1348
1349 /* set TX chains */
1350 if (ar->eeprom.tx_mask == 1) {
1351 chains = AR9170_TX_PHY_TXCHAIN_1;
1352 } else {
1353 chains = AR9170_TX_PHY_TXCHAIN_2;
1354
1355 /* >= 36M legacy OFDM - use only one chain */
1356 if (rate && rate->bitrate >= 360)
1357 chains = AR9170_TX_PHY_TXCHAIN_1;
1358 }
1359 txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001360}
Christian Lampartere9348cd2009-03-21 23:05:13 +01001361
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001362static void ar9170_tx(struct ar9170 *ar)
1363{
1364 struct sk_buff *skb;
1365 unsigned long flags;
1366 struct ieee80211_tx_info *info;
1367 struct ar9170_tx_info *arinfo;
1368 unsigned int i, frames, frames_failed, remaining_space;
1369 int err;
1370 bool schedule_garbagecollector = false;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001371
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001372 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001373
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001374 if (unlikely(!IS_STARTED(ar)))
1375 return ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001376
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001377 remaining_space = AR9170_TX_MAX_PENDING;
1378
1379 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1380 spin_lock_irqsave(&ar->tx_stats_lock, flags);
Christian Lamparter53a76b52009-11-29 00:52:51 +01001381 frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
1382 skb_queue_len(&ar->tx_pending[i]));
1383
1384 if (remaining_space < frames) {
1385#ifdef AR9170_QUEUE_DEBUG
1386 printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
1387 "remaining slots:%d, needed:%d\n",
1388 wiphy_name(ar->hw->wiphy), i, remaining_space,
1389 frames);
1390#endif /* AR9170_QUEUE_DEBUG */
1391 frames = remaining_space;
1392 }
1393
1394 ar->tx_stats[i].len += frames;
1395 ar->tx_stats[i].count += frames;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001396 if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
1397#ifdef AR9170_QUEUE_DEBUG
1398 printk(KERN_DEBUG "%s: queue %d full\n",
1399 wiphy_name(ar->hw->wiphy), i);
1400
Luis de Bethencourtb4098942010-03-31 15:07:48 +01001401 printk(KERN_DEBUG "%s: stuck frames: ===>\n",
Christian Lamparteracbadf02009-07-11 17:24:14 +02001402 wiphy_name(ar->hw->wiphy));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001403 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1404 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
1405#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparteracbadf02009-07-11 17:24:14 +02001406
1407#ifdef AR9170_QUEUE_STOP_DEBUG
1408 printk(KERN_DEBUG "%s: stop queue %d\n",
1409 wiphy_name(ar->hw->wiphy), i);
1410 __ar9170_dump_txstats(ar);
1411#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001412 ieee80211_stop_queue(ar->hw, i);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001413 }
1414
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001415 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1416
1417 if (!frames)
1418 continue;
1419
1420 frames_failed = 0;
1421 while (frames) {
1422 skb = skb_dequeue(&ar->tx_pending[i]);
1423 if (unlikely(!skb)) {
1424 frames_failed += frames;
1425 frames = 0;
1426 break;
1427 }
1428
1429 info = IEEE80211_SKB_CB(skb);
1430 arinfo = (void *) info->rate_driver_data;
1431
1432 /* TODO: cancel stuck frames */
1433 arinfo->timeout = jiffies +
1434 msecs_to_jiffies(AR9170_TX_TIMEOUT);
1435
1436#ifdef AR9170_QUEUE_DEBUG
1437 printk(KERN_DEBUG "%s: send frame q:%d =>\n",
1438 wiphy_name(ar->hw->wiphy), i);
1439 ar9170_print_txheader(ar, skb);
1440#endif /* AR9170_QUEUE_DEBUG */
1441
1442 err = ar->tx(ar, skb);
1443 if (unlikely(err)) {
1444 frames_failed++;
1445 dev_kfree_skb_any(skb);
1446 } else {
1447 remaining_space--;
1448 schedule_garbagecollector = true;
1449 }
1450
1451 frames--;
1452 }
1453
1454#ifdef AR9170_QUEUE_DEBUG
1455 printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n",
1456 wiphy_name(ar->hw->wiphy), i);
1457
1458 printk(KERN_DEBUG "%s: unprocessed pending frames left:\n",
1459 wiphy_name(ar->hw->wiphy));
1460 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1461#endif /* AR9170_QUEUE_DEBUG */
1462
1463 if (unlikely(frames_failed)) {
1464#ifdef AR9170_QUEUE_DEBUG
Christian Lamparteracbadf02009-07-11 17:24:14 +02001465 printk(KERN_DEBUG "%s: frames failed %d =>\n",
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001466 wiphy_name(ar->hw->wiphy), frames_failed);
1467#endif /* AR9170_QUEUE_DEBUG */
1468
1469 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1470 ar->tx_stats[i].len -= frames_failed;
1471 ar->tx_stats[i].count -= frames_failed;
Christian Lamparteracbadf02009-07-11 17:24:14 +02001472#ifdef AR9170_QUEUE_STOP_DEBUG
1473 printk(KERN_DEBUG "%s: wake queue %d\n",
1474 wiphy_name(ar->hw->wiphy), i);
1475 __ar9170_dump_txstats(ar);
1476#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001477 ieee80211_wake_queue(ar->hw, i);
1478 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001479 }
1480 }
1481
Luis R. Rodriguez42935ec2009-07-29 20:08:07 -04001482 if (!schedule_garbagecollector)
1483 return;
1484
1485 ieee80211_queue_delayed_work(ar->hw,
1486 &ar->tx_janitor,
1487 msecs_to_jiffies(AR9170_JANITOR_DELAY));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001488}
1489
1490int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1491{
1492 struct ar9170 *ar = hw->priv;
1493 struct ieee80211_tx_info *info;
Christian Lamparterf3926b42010-05-01 18:18:18 +02001494 unsigned int queue;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001495
1496 if (unlikely(!IS_STARTED(ar)))
1497 goto err_free;
1498
1499 if (unlikely(ar9170_tx_prepare(ar, skb)))
1500 goto err_free;
1501
Christian Lamparterf3926b42010-05-01 18:18:18 +02001502 queue = skb_get_queue_mapping(skb);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001503 info = IEEE80211_SKB_CB(skb);
Christian Lamparterf3926b42010-05-01 18:18:18 +02001504 ar9170_tx_prepare_phy(ar, skb);
1505 skb_queue_tail(&ar->tx_pending[queue], skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001506
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001507 ar9170_tx(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001508 return NETDEV_TX_OK;
1509
Christian Lampartere9348cd2009-03-21 23:05:13 +01001510err_free:
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001511 dev_kfree_skb_any(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001512 return NETDEV_TX_OK;
1513}
1514
1515static int ar9170_op_add_interface(struct ieee80211_hw *hw,
Johannes Berg1ed32e42009-12-23 13:15:45 +01001516 struct ieee80211_vif *vif)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001517{
1518 struct ar9170 *ar = hw->priv;
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07001519 struct ath_common *common = &ar->common;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001520 int err = 0;
1521
1522 mutex_lock(&ar->mutex);
1523
1524 if (ar->vif) {
1525 err = -EBUSY;
1526 goto unlock;
1527 }
1528
Johannes Berg1ed32e42009-12-23 13:15:45 +01001529 ar->vif = vif;
1530 memcpy(common->macaddr, vif->addr, ETH_ALEN);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001531
1532 if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
1533 ar->rx_software_decryption = true;
1534 ar->disable_offload = true;
1535 }
1536
1537 ar->cur_filter = 0;
Christian Lampartereeef4182009-08-19 12:43:47 +02001538 err = ar9170_update_frame_filter(ar, AR9170_MAC_REG_FTF_DEFAULTS);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001539 if (err)
1540 goto unlock;
1541
1542 err = ar9170_set_operating_mode(ar);
1543
1544unlock:
1545 mutex_unlock(&ar->mutex);
1546 return err;
1547}
1548
1549static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
Johannes Berg1ed32e42009-12-23 13:15:45 +01001550 struct ieee80211_vif *vif)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001551{
1552 struct ar9170 *ar = hw->priv;
1553
1554 mutex_lock(&ar->mutex);
1555 ar->vif = NULL;
Christian Lampartereeef4182009-08-19 12:43:47 +02001556 ar9170_update_frame_filter(ar, 0);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001557 ar9170_set_beacon_timers(ar);
1558 dev_kfree_skb(ar->beacon);
1559 ar->beacon = NULL;
1560 ar->sniffer_enabled = false;
1561 ar->rx_software_decryption = false;
1562 ar9170_set_operating_mode(ar);
1563 mutex_unlock(&ar->mutex);
1564}
1565
1566static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
1567{
1568 struct ar9170 *ar = hw->priv;
1569 int err = 0;
1570
1571 mutex_lock(&ar->mutex);
1572
Christian Lampartere9348cd2009-03-21 23:05:13 +01001573 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
1574 /* TODO */
1575 err = 0;
1576 }
1577
1578 if (changed & IEEE80211_CONF_CHANGE_PS) {
1579 /* TODO */
1580 err = 0;
1581 }
1582
1583 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1584 /* TODO */
1585 err = 0;
1586 }
1587
1588 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
1589 /*
1590 * is it long_frame_max_tx_count or short_frame_max_tx_count?
1591 */
1592
1593 err = ar9170_set_hwretry_limit(ar,
1594 ar->hw->conf.long_frame_max_tx_count);
1595 if (err)
1596 goto out;
1597 }
1598
Christian Lampartere9348cd2009-03-21 23:05:13 +01001599 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02001600
1601 /* adjust slot time for 5 GHz */
1602 err = ar9170_set_slot_time(ar);
1603 if (err)
1604 goto out;
1605
1606 err = ar9170_set_dyn_sifs_ack(ar);
1607 if (err)
1608 goto out;
1609
Christian Lampartere9348cd2009-03-21 23:05:13 +01001610 err = ar9170_set_channel(ar, hw->conf.channel,
Johannes Berg9e52b06232009-04-20 18:27:04 +02001611 AR9170_RFI_NONE,
1612 nl80211_to_ar9170(hw->conf.channel_type));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001613 if (err)
1614 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001615 }
1616
1617out:
1618 mutex_unlock(&ar->mutex);
1619 return err;
1620}
1621
Johannes Berg3ac64be2009-08-17 16:16:53 +02001622static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
1623 struct dev_addr_list *mclist)
1624{
1625 u64 mchash;
1626 int i;
1627
1628 /* always get broadcast frames */
1629 mchash = 1ULL << (0xff >> 2);
1630
1631 for (i = 0; i < mc_count; i++) {
1632 if (WARN_ON(!mclist))
1633 break;
1634 mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
1635 mclist = mclist->next;
1636 }
1637
1638 return mchash;
1639}
1640
Christian Lampartere9348cd2009-03-21 23:05:13 +01001641static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
1642 unsigned int changed_flags,
1643 unsigned int *new_flags,
Johannes Berg3ac64be2009-08-17 16:16:53 +02001644 u64 multicast)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001645{
1646 struct ar9170 *ar = hw->priv;
1647
Christian Lampartereeef4182009-08-19 12:43:47 +02001648 if (unlikely(!IS_ACCEPTING_CMD(ar)))
1649 return ;
1650
1651 mutex_lock(&ar->mutex);
1652
Christian Lampartere9348cd2009-03-21 23:05:13 +01001653 /* mask supported flags */
1654 *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
Christian Lampartercca847992009-04-19 01:28:12 +02001655 FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
1656 ar->filter_state = *new_flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001657 /*
1658 * We can support more by setting the sniffer bit and
1659 * then checking the error flags, later.
1660 */
1661
Johannes Berg3ac64be2009-08-17 16:16:53 +02001662 if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
Christian Lampartereeef4182009-08-19 12:43:47 +02001663 multicast = ~0ULL;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001664
Christian Lampartereeef4182009-08-19 12:43:47 +02001665 if (multicast != ar->cur_mc_hash)
1666 ar9170_update_multicast(ar, multicast);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001667
1668 if (changed_flags & FIF_CONTROL) {
1669 u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
1670 AR9170_MAC_REG_FTF_RTS |
1671 AR9170_MAC_REG_FTF_CTS |
1672 AR9170_MAC_REG_FTF_ACK |
1673 AR9170_MAC_REG_FTF_CFE |
1674 AR9170_MAC_REG_FTF_CFE_ACK;
1675
1676 if (*new_flags & FIF_CONTROL)
Christian Lampartereeef4182009-08-19 12:43:47 +02001677 filter |= ar->cur_filter;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001678 else
Christian Lampartereeef4182009-08-19 12:43:47 +02001679 filter &= (~ar->cur_filter);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001680
Christian Lampartereeef4182009-08-19 12:43:47 +02001681 ar9170_update_frame_filter(ar, filter);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001682 }
1683
1684 if (changed_flags & FIF_PROMISC_IN_BSS) {
1685 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
Christian Lampartereeef4182009-08-19 12:43:47 +02001686 ar9170_set_operating_mode(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001687 }
1688
Christian Lampartereeef4182009-08-19 12:43:47 +02001689 mutex_unlock(&ar->mutex);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001690}
1691
Christian Lampartereeef4182009-08-19 12:43:47 +02001692
Christian Lampartere9348cd2009-03-21 23:05:13 +01001693static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
1694 struct ieee80211_vif *vif,
1695 struct ieee80211_bss_conf *bss_conf,
1696 u32 changed)
1697{
1698 struct ar9170 *ar = hw->priv;
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07001699 struct ath_common *common = &ar->common;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001700 int err = 0;
1701
1702 mutex_lock(&ar->mutex);
1703
Johannes Berg2d0ddec2009-04-23 16:13:26 +02001704 if (changed & BSS_CHANGED_BSSID) {
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07001705 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
Johannes Berg2d0ddec2009-04-23 16:13:26 +02001706 err = ar9170_set_operating_mode(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02001707 if (err)
1708 goto out;
Johannes Berg2d0ddec2009-04-23 16:13:26 +02001709 }
1710
Joerg Albertea39d1a2009-08-21 23:25:07 +02001711 if (changed & BSS_CHANGED_BEACON_ENABLED)
1712 ar->enable_beacon = bss_conf->enable_beacon;
1713
1714 if (changed & BSS_CHANGED_BEACON) {
Johannes Berg2d0ddec2009-04-23 16:13:26 +02001715 err = ar9170_update_beacon(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02001716 if (err)
1717 goto out;
Joerg Albertea39d1a2009-08-21 23:25:07 +02001718 }
Johannes Berg2d0ddec2009-04-23 16:13:26 +02001719
Joerg Albertea39d1a2009-08-21 23:25:07 +02001720 if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON |
1721 BSS_CHANGED_BEACON_INT)) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02001722 err = ar9170_set_beacon_timers(ar);
1723 if (err)
1724 goto out;
1725 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001726
1727 if (changed & BSS_CHANGED_ASSOC) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001728#ifndef CONFIG_AR9170_LEDS
1729 /* enable assoc LED. */
1730 err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
1731#endif /* CONFIG_AR9170_LEDS */
1732 }
1733
1734 if (changed & BSS_CHANGED_HT) {
1735 /* TODO */
1736 err = 0;
1737 }
1738
1739 if (changed & BSS_CHANGED_ERP_SLOT) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02001740 err = ar9170_set_slot_time(ar);
1741 if (err)
1742 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001743 }
1744
1745 if (changed & BSS_CHANGED_BASIC_RATES) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02001746 err = ar9170_set_basic_rates(ar);
1747 if (err)
1748 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001749 }
1750
Christian Lamparter29ceff52009-06-01 21:42:01 +02001751out:
Christian Lampartere9348cd2009-03-21 23:05:13 +01001752 mutex_unlock(&ar->mutex);
1753}
1754
1755static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
1756{
1757 struct ar9170 *ar = hw->priv;
1758 int err;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001759 u64 tsf;
Joerg Albert181af382009-09-15 23:27:53 +02001760#define NR 3
1761 static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H,
1762 AR9170_MAC_REG_TSF_L,
1763 AR9170_MAC_REG_TSF_H };
1764 u32 val[NR];
1765 int loops = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001766
1767 mutex_lock(&ar->mutex);
Joerg Albert181af382009-09-15 23:27:53 +02001768
1769 while (loops++ < 10) {
1770 err = ar9170_read_mreg(ar, NR, addr, val);
1771 if (err || val[0] == val[2])
1772 break;
1773 }
1774
Christian Lampartere9348cd2009-03-21 23:05:13 +01001775 mutex_unlock(&ar->mutex);
1776
1777 if (WARN_ON(err))
1778 return 0;
Joerg Albert181af382009-09-15 23:27:53 +02001779 tsf = val[0];
1780 tsf = (tsf << 32) | val[1];
Christian Lampartere9348cd2009-03-21 23:05:13 +01001781 return tsf;
Joerg Albert181af382009-09-15 23:27:53 +02001782#undef NR
Christian Lampartere9348cd2009-03-21 23:05:13 +01001783}
1784
1785static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1786 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
1787 struct ieee80211_key_conf *key)
1788{
1789 struct ar9170 *ar = hw->priv;
1790 int err = 0, i;
1791 u8 ktype;
1792
1793 if ((!ar->vif) || (ar->disable_offload))
1794 return -EOPNOTSUPP;
1795
1796 switch (key->alg) {
1797 case ALG_WEP:
Zhu Yie31a16d2009-05-21 21:47:03 +08001798 if (key->keylen == WLAN_KEY_LEN_WEP40)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001799 ktype = AR9170_ENC_ALG_WEP64;
1800 else
1801 ktype = AR9170_ENC_ALG_WEP128;
1802 break;
1803 case ALG_TKIP:
1804 ktype = AR9170_ENC_ALG_TKIP;
1805 break;
1806 case ALG_CCMP:
1807 ktype = AR9170_ENC_ALG_AESCCMP;
1808 break;
1809 default:
1810 return -EOPNOTSUPP;
1811 }
1812
1813 mutex_lock(&ar->mutex);
1814 if (cmd == SET_KEY) {
1815 if (unlikely(!IS_STARTED(ar))) {
1816 err = -EOPNOTSUPP;
1817 goto out;
1818 }
1819
1820 /* group keys need all-zeroes address */
1821 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1822 sta = NULL;
1823
1824 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
1825 for (i = 0; i < 64; i++)
1826 if (!(ar->usedkeys & BIT(i)))
1827 break;
1828 if (i == 64) {
1829 ar->rx_software_decryption = true;
1830 ar9170_set_operating_mode(ar);
1831 err = -ENOSPC;
1832 goto out;
1833 }
1834 } else {
1835 i = 64 + key->keyidx;
1836 }
1837
1838 key->hw_key_idx = i;
1839
1840 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
1841 key->key, min_t(u8, 16, key->keylen));
1842 if (err)
1843 goto out;
1844
1845 if (key->alg == ALG_TKIP) {
1846 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
1847 ktype, 1, key->key + 16, 16);
1848 if (err)
1849 goto out;
1850
1851 /*
1852 * hardware is not capable generating the MMIC
1853 * for fragmented frames!
1854 */
1855 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1856 }
1857
1858 if (i < 64)
1859 ar->usedkeys |= BIT(i);
1860
1861 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1862 } else {
1863 if (unlikely(!IS_STARTED(ar))) {
1864 /* The device is gone... together with the key ;-) */
1865 err = 0;
1866 goto out;
1867 }
1868
1869 err = ar9170_disable_key(ar, key->hw_key_idx);
1870 if (err)
1871 goto out;
1872
1873 if (key->hw_key_idx < 64) {
1874 ar->usedkeys &= ~BIT(key->hw_key_idx);
1875 } else {
1876 err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
1877 AR9170_ENC_ALG_NONE, 0,
1878 NULL, 0);
1879 if (err)
1880 goto out;
1881
1882 if (key->alg == ALG_TKIP) {
1883 err = ar9170_upload_key(ar, key->hw_key_idx,
1884 NULL,
1885 AR9170_ENC_ALG_NONE, 1,
1886 NULL, 0);
1887 if (err)
1888 goto out;
1889 }
1890
1891 }
1892 }
1893
1894 ar9170_regwrite_begin(ar);
1895 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
1896 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
1897 ar9170_regwrite_finish();
1898 err = ar9170_regwrite_result();
1899
1900out:
1901 mutex_unlock(&ar->mutex);
1902
1903 return err;
1904}
1905
Christian Lampartere9348cd2009-03-21 23:05:13 +01001906static int ar9170_get_stats(struct ieee80211_hw *hw,
1907 struct ieee80211_low_level_stats *stats)
1908{
1909 struct ar9170 *ar = hw->priv;
1910 u32 val;
1911 int err;
1912
1913 mutex_lock(&ar->mutex);
1914 err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
1915 ar->stats.dot11ACKFailureCount += val;
1916
1917 memcpy(stats, &ar->stats, sizeof(*stats));
1918 mutex_unlock(&ar->mutex);
1919
1920 return 0;
1921}
1922
Christian Lampartere9348cd2009-03-21 23:05:13 +01001923static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
1924 const struct ieee80211_tx_queue_params *param)
1925{
1926 struct ar9170 *ar = hw->priv;
1927 int ret;
1928
1929 mutex_lock(&ar->mutex);
Dan Carpentere9d126c2009-08-09 14:24:09 +02001930 if (queue < __AR9170_NUM_TXQ) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001931 memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
1932 param, sizeof(*param));
1933
1934 ret = ar9170_set_qos(ar);
Dan Carpentere9d126c2009-08-09 14:24:09 +02001935 } else {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001936 ret = -EINVAL;
Dan Carpentere9d126c2009-08-09 14:24:09 +02001937 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001938
1939 mutex_unlock(&ar->mutex);
1940 return ret;
1941}
1942
Johannes Berg9e52b06232009-04-20 18:27:04 +02001943static int ar9170_ampdu_action(struct ieee80211_hw *hw,
Johannes Bergc951ad32009-11-16 12:00:38 +01001944 struct ieee80211_vif *vif,
Johannes Berg9e52b06232009-04-20 18:27:04 +02001945 enum ieee80211_ampdu_mlme_action action,
1946 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
1947{
1948 switch (action) {
1949 case IEEE80211_AMPDU_RX_START:
1950 case IEEE80211_AMPDU_RX_STOP:
Christian Lamparteracbadf02009-07-11 17:24:14 +02001951 /* Handled by firmware */
1952 break;
1953
Johannes Berg9e52b06232009-04-20 18:27:04 +02001954 default:
1955 return -EOPNOTSUPP;
1956 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02001957
1958 return 0;
Johannes Berg9e52b06232009-04-20 18:27:04 +02001959}
1960
Christian Lampartere9348cd2009-03-21 23:05:13 +01001961static const struct ieee80211_ops ar9170_ops = {
1962 .start = ar9170_op_start,
1963 .stop = ar9170_op_stop,
1964 .tx = ar9170_op_tx,
1965 .add_interface = ar9170_op_add_interface,
1966 .remove_interface = ar9170_op_remove_interface,
1967 .config = ar9170_op_config,
Johannes Berg3ac64be2009-08-17 16:16:53 +02001968 .prepare_multicast = ar9170_op_prepare_multicast,
Christian Lampartere9348cd2009-03-21 23:05:13 +01001969 .configure_filter = ar9170_op_configure_filter,
1970 .conf_tx = ar9170_conf_tx,
1971 .bss_info_changed = ar9170_op_bss_info_changed,
1972 .get_tsf = ar9170_op_get_tsf,
1973 .set_key = ar9170_set_key,
Christian Lampartere9348cd2009-03-21 23:05:13 +01001974 .get_stats = ar9170_get_stats,
Johannes Berg9e52b06232009-04-20 18:27:04 +02001975 .ampdu_action = ar9170_ampdu_action,
Christian Lampartere9348cd2009-03-21 23:05:13 +01001976};
1977
1978void *ar9170_alloc(size_t priv_size)
1979{
1980 struct ieee80211_hw *hw;
1981 struct ar9170 *ar;
Christian Lampartercca847992009-04-19 01:28:12 +02001982 struct sk_buff *skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001983 int i;
1984
Christian Lampartercca847992009-04-19 01:28:12 +02001985 /*
1986 * this buffer is used for rx stream reconstruction.
1987 * Under heavy load this device (or the transport layer?)
1988 * tends to split the streams into seperate rx descriptors.
1989 */
1990
Christian Lamparter879999ce2010-03-23 21:51:14 +01001991 skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL);
Christian Lampartercca847992009-04-19 01:28:12 +02001992 if (!skb)
1993 goto err_nomem;
1994
Christian Lampartere9348cd2009-03-21 23:05:13 +01001995 hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
1996 if (!hw)
Christian Lampartercca847992009-04-19 01:28:12 +02001997 goto err_nomem;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001998
1999 ar = hw->priv;
2000 ar->hw = hw;
Christian Lampartercca847992009-04-19 01:28:12 +02002001 ar->rx_failover = skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002002
2003 mutex_init(&ar->mutex);
2004 spin_lock_init(&ar->cmdlock);
2005 spin_lock_init(&ar->tx_stats_lock);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002006 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
2007 skb_queue_head_init(&ar->tx_status[i]);
2008 skb_queue_head_init(&ar->tx_pending[i]);
2009 }
Christian Lampartercca847992009-04-19 01:28:12 +02002010 ar9170_rx_reset_rx_mpdu(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002011 INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002012 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002013
2014 /* all hw supports 2.4 GHz, so set channel to 1 by default */
2015 ar->channel = &ar9170_2ghz_chantable[0];
2016
2017 /* first part of wiphy init */
2018 ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2019 BIT(NL80211_IFTYPE_WDS) |
2020 BIT(NL80211_IFTYPE_ADHOC);
2021 ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
2022 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
John W. Linvillef5c044e2010-04-30 15:37:00 -04002023 IEEE80211_HW_SIGNAL_DBM;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002024
Christian Lamparter4a48e2a2009-03-23 12:15:43 +01002025 ar->hw->queues = __AR9170_NUM_TXQ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002026 ar->hw->extra_tx_headroom = 8;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002027
2028 ar->hw->max_rates = 1;
2029 ar->hw->max_rate_tries = 3;
2030
2031 for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
2032 ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
2033
2034 return ar;
Christian Lampartercca847992009-04-19 01:28:12 +02002035
2036err_nomem:
2037 kfree_skb(skb);
2038 return ERR_PTR(-ENOMEM);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002039}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002040
2041static int ar9170_read_eeprom(struct ar9170 *ar)
2042{
2043#define RW 8 /* number of words to read at once */
2044#define RB (sizeof(u32) * RW)
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002045 struct ath_regulatory *regulatory = &ar->common.regulatory;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002046 u8 *eeprom = (void *)&ar->eeprom;
2047 u8 *addr = ar->eeprom.mac_address;
2048 __le32 offsets[RW];
Christian Lamparteracbadf02009-07-11 17:24:14 +02002049 unsigned int rx_streams, tx_streams, tx_params = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002050 int i, j, err, bands = 0;
2051
2052 BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
2053
2054 BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
2055#ifndef __CHECKER__
2056 /* don't want to handle trailing remains */
2057 BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
2058#endif
2059
2060 for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
2061 for (j = 0; j < RW; j++)
2062 offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
2063 RB * i + 4 * j);
2064
2065 err = ar->exec_cmd(ar, AR9170_CMD_RREG,
2066 RB, (u8 *) &offsets,
2067 RB, eeprom + RB * i);
2068 if (err)
2069 return err;
2070 }
2071
2072#undef RW
2073#undef RB
2074
2075 if (ar->eeprom.length == cpu_to_le16(0xFFFF))
2076 return -ENODATA;
2077
2078 if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
2079 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
2080 bands++;
2081 }
2082 if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
2083 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
2084 bands++;
2085 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02002086
2087 rx_streams = hweight8(ar->eeprom.rx_mask);
2088 tx_streams = hweight8(ar->eeprom.tx_mask);
2089
2090 if (rx_streams != tx_streams)
2091 tx_params = IEEE80211_HT_MCS_TX_RX_DIFF;
2092
2093 if (tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS)
2094 tx_params = (tx_streams - 1) <<
2095 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
2096
2097 ar9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
2098 ar9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params;
2099
Christian Lampartere9348cd2009-03-21 23:05:13 +01002100 /*
2101 * I measured this, a bandswitch takes roughly
2102 * 135 ms and a frequency switch about 80.
2103 *
2104 * FIXME: measure these values again once EEPROM settings
2105 * are used, that will influence them!
2106 */
2107 if (bands == 2)
2108 ar->hw->channel_change_time = 135 * 1000;
2109 else
2110 ar->hw->channel_change_time = 80 * 1000;
2111
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002112 regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
2113 regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
Christian Lamparter1878f772009-03-30 22:30:32 -04002114
Christian Lampartere9348cd2009-03-21 23:05:13 +01002115 /* second part of wiphy init */
2116 SET_IEEE80211_PERM_ADDR(ar->hw, addr);
2117
2118 return bands ? 0 : -EINVAL;
2119}
2120
Christian Lamparter1878f772009-03-30 22:30:32 -04002121static int ar9170_reg_notifier(struct wiphy *wiphy,
2122 struct regulatory_request *request)
2123{
2124 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2125 struct ar9170 *ar = hw->priv;
2126
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002127 return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory);
Christian Lamparter1878f772009-03-30 22:30:32 -04002128}
2129
Christian Lampartere9348cd2009-03-21 23:05:13 +01002130int ar9170_register(struct ar9170 *ar, struct device *pdev)
2131{
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002132 struct ath_regulatory *regulatory = &ar->common.regulatory;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002133 int err;
2134
2135 /* try to read EEPROM, init MAC addr */
2136 err = ar9170_read_eeprom(ar);
2137 if (err)
2138 goto err_out;
2139
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002140 err = ath_regd_init(regulatory, ar->hw->wiphy,
Christian Lamparter1878f772009-03-30 22:30:32 -04002141 ar9170_reg_notifier);
Luis R. Rodriguez85efc862009-04-13 21:41:46 -04002142 if (err)
2143 goto err_out;
Christian Lamparter1878f772009-03-30 22:30:32 -04002144
Christian Lampartere9348cd2009-03-21 23:05:13 +01002145 err = ieee80211_register_hw(ar->hw);
2146 if (err)
2147 goto err_out;
2148
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002149 if (!ath_is_world_regd(regulatory))
2150 regulatory_hint(ar->hw->wiphy, regulatory->alpha2);
Christian Lamparter1878f772009-03-30 22:30:32 -04002151
Christian Lampartere9348cd2009-03-21 23:05:13 +01002152 err = ar9170_init_leds(ar);
2153 if (err)
2154 goto err_unreg;
2155
2156#ifdef CONFIG_AR9170_LEDS
2157 err = ar9170_register_leds(ar);
2158 if (err)
2159 goto err_unreg;
2160#endif /* CONFIG_AR9170_LEDS */
2161
2162 dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
2163 wiphy_name(ar->hw->wiphy));
2164
Johannes Berg53576512009-12-23 13:15:30 +01002165 ar->registered = true;
2166 return 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002167
2168err_unreg:
2169 ieee80211_unregister_hw(ar->hw);
2170
2171err_out:
2172 return err;
2173}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002174
2175void ar9170_unregister(struct ar9170 *ar)
2176{
Johannes Berg53576512009-12-23 13:15:30 +01002177 if (ar->registered) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002178#ifdef CONFIG_AR9170_LEDS
Johannes Berg53576512009-12-23 13:15:30 +01002179 ar9170_unregister_leds(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002180#endif /* CONFIG_AR9170_LEDS */
2181
2182 ieee80211_unregister_hw(ar->hw);
Johannes Berg53576512009-12-23 13:15:30 +01002183 }
2184
2185 kfree_skb(ar->rx_failover);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002186 mutex_destroy(&ar->mutex);
2187}