blob: ccc2edaaeda03ae97e18b817e4905bd9e1113fcf [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>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090041#include <linux/slab.h>
Christian Lampartere9348cd2009-03-21 23:05:13 +010042#include <linux/module.h>
43#include <linux/etherdevice.h>
44#include <net/mac80211.h>
45#include "ar9170.h"
46#include "hw.h"
47#include "cmd.h"
48
49static int modparam_nohwcrypt;
50module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
51MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
Christian Lampartere9348cd2009-03-21 23:05:13 +010052
53#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \
54 .bitrate = (_bitrate), \
55 .flags = (_flags), \
56 .hw_value = (_hw_rate) | (_txpidx) << 4, \
57}
58
59static struct ieee80211_rate __ar9170_ratetable[] = {
60 RATE(10, 0, 0, 0),
61 RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE),
62 RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE),
63 RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE),
64 RATE(60, 0xb, 0, 0),
65 RATE(90, 0xf, 0, 0),
66 RATE(120, 0xa, 0, 0),
67 RATE(180, 0xe, 0, 0),
68 RATE(240, 0x9, 0, 0),
69 RATE(360, 0xd, 1, 0),
70 RATE(480, 0x8, 2, 0),
71 RATE(540, 0xc, 3, 0),
72};
73#undef RATE
74
75#define ar9170_g_ratetable (__ar9170_ratetable + 0)
76#define ar9170_g_ratetable_size 12
77#define ar9170_a_ratetable (__ar9170_ratetable + 4)
78#define ar9170_a_ratetable_size 8
79
80/*
81 * NB: The hw_value is used as an index into the ar9170_phy_freq_params
82 * array in phy.c so that we don't have to do frequency lookups!
83 */
84#define CHAN(_freq, _idx) { \
85 .center_freq = (_freq), \
86 .hw_value = (_idx), \
87 .max_power = 18, /* XXX */ \
88}
89
90static struct ieee80211_channel ar9170_2ghz_chantable[] = {
91 CHAN(2412, 0),
92 CHAN(2417, 1),
93 CHAN(2422, 2),
94 CHAN(2427, 3),
95 CHAN(2432, 4),
96 CHAN(2437, 5),
97 CHAN(2442, 6),
98 CHAN(2447, 7),
99 CHAN(2452, 8),
100 CHAN(2457, 9),
101 CHAN(2462, 10),
102 CHAN(2467, 11),
103 CHAN(2472, 12),
104 CHAN(2484, 13),
105};
106
107static struct ieee80211_channel ar9170_5ghz_chantable[] = {
108 CHAN(4920, 14),
109 CHAN(4940, 15),
110 CHAN(4960, 16),
111 CHAN(4980, 17),
112 CHAN(5040, 18),
113 CHAN(5060, 19),
114 CHAN(5080, 20),
115 CHAN(5180, 21),
116 CHAN(5200, 22),
117 CHAN(5220, 23),
118 CHAN(5240, 24),
119 CHAN(5260, 25),
120 CHAN(5280, 26),
121 CHAN(5300, 27),
122 CHAN(5320, 28),
123 CHAN(5500, 29),
124 CHAN(5520, 30),
125 CHAN(5540, 31),
126 CHAN(5560, 32),
127 CHAN(5580, 33),
128 CHAN(5600, 34),
129 CHAN(5620, 35),
130 CHAN(5640, 36),
131 CHAN(5660, 37),
132 CHAN(5680, 38),
133 CHAN(5700, 39),
134 CHAN(5745, 40),
135 CHAN(5765, 41),
136 CHAN(5785, 42),
137 CHAN(5805, 43),
138 CHAN(5825, 44),
139 CHAN(5170, 45),
140 CHAN(5190, 46),
141 CHAN(5210, 47),
142 CHAN(5230, 48),
143};
144#undef CHAN
145
Johannes Berg9e52b062009-04-20 18:27:04 +0200146#define AR9170_HT_CAP \
147{ \
148 .ht_supported = true, \
149 .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
Johannes Berg9e52b062009-04-20 18:27:04 +0200150 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
151 IEEE80211_HT_CAP_SGI_40 | \
Christian Lamparteracbadf02009-07-11 17:24:14 +0200152 IEEE80211_HT_CAP_GRN_FLD | \
Johannes Berg9e52b062009-04-20 18:27:04 +0200153 IEEE80211_HT_CAP_DSSSCCK40 | \
154 IEEE80211_HT_CAP_SM_PS, \
Christian Lamparter083c4682009-04-24 21:35:57 +0200155 .ampdu_factor = 3, \
156 .ampdu_density = 6, \
Johannes Berg9e52b062009-04-20 18:27:04 +0200157 .mcs = { \
Christian Lamparteracbadf02009-07-11 17:24:14 +0200158 .rx_mask = { 0xff, 0xff, 0, 0, 0x1, 0, 0, 0, 0, 0, }, \
159 .rx_highest = cpu_to_le16(300), \
160 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
Johannes Berg9e52b062009-04-20 18:27:04 +0200161 }, \
162}
163
Christian Lampartere9348cd2009-03-21 23:05:13 +0100164static struct ieee80211_supported_band ar9170_band_2GHz = {
165 .channels = ar9170_2ghz_chantable,
166 .n_channels = ARRAY_SIZE(ar9170_2ghz_chantable),
167 .bitrates = ar9170_g_ratetable,
168 .n_bitrates = ar9170_g_ratetable_size,
Johannes Berg9e52b062009-04-20 18:27:04 +0200169 .ht_cap = AR9170_HT_CAP,
170};
171
172static struct ieee80211_supported_band ar9170_band_5GHz = {
173 .channels = ar9170_5ghz_chantable,
174 .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
175 .bitrates = ar9170_a_ratetable,
176 .n_bitrates = ar9170_a_ratetable_size,
177 .ht_cap = AR9170_HT_CAP,
Christian Lampartere9348cd2009-03-21 23:05:13 +0100178};
179
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200180static void ar9170_tx(struct ar9170 *ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100181
Christian Lamparteracbadf02009-07-11 17:24:14 +0200182static inline u16 ar9170_get_seq_h(struct ieee80211_hdr *hdr)
183{
184 return le16_to_cpu(hdr->seq_ctrl) >> 4;
185}
186
187static inline u16 ar9170_get_seq(struct sk_buff *skb)
188{
189 struct ar9170_tx_control *txc = (void *) skb->data;
190 return ar9170_get_seq_h((void *) txc->frame_data);
191}
192
Christian Lamparterf3926b42010-05-01 18:18:18 +0200193#ifdef AR9170_QUEUE_DEBUG
Christian Lampartere9348cd2009-03-21 23:05:13 +0100194static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
195{
196 struct ar9170_tx_control *txc = (void *) skb->data;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200197 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
198 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
199 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100200
Joe Perchesc96c31e2010-07-26 14:39:58 -0700201 wiphy_debug(ar->hw->wiphy,
202 "=> FRAME [skb:%p, q:%d, DA:[%pM] s:%d "
203 "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
204 skb, skb_get_queue_mapping(skb),
205 ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr),
206 le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
207 jiffies_to_msecs(arinfo->timeout - jiffies));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100208}
209
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200210static void __ar9170_dump_txqueue(struct ar9170 *ar,
211 struct sk_buff_head *queue)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100212{
213 struct sk_buff *skb;
214 int i = 0;
215
216 printk(KERN_DEBUG "---[ cut here ]---\n");
Joe Perchesc96c31e2010-07-26 14:39:58 -0700217 wiphy_debug(ar->hw->wiphy, "%d entries in queue.\n",
218 skb_queue_len(queue));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100219
220 skb_queue_walk(queue, skb) {
Luis de Bethencourtb4098942010-03-31 15:07:48 +0100221 printk(KERN_DEBUG "index:%d =>\n", i++);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100222 ar9170_print_txheader(ar, skb);
223 }
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200224 if (i != skb_queue_len(queue))
225 printk(KERN_DEBUG "WARNING: queue frame counter "
226 "mismatch %d != %d\n", skb_queue_len(queue), i);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100227 printk(KERN_DEBUG "---[ end ]---\n");
228}
Christian Lamparterf3926b42010-05-01 18:18:18 +0200229#endif /* AR9170_QUEUE_DEBUG */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100230
Christian Lamparteracbadf02009-07-11 17:24:14 +0200231#ifdef AR9170_QUEUE_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200232static void ar9170_dump_txqueue(struct ar9170 *ar,
233 struct sk_buff_head *queue)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100234{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200235 unsigned long flags;
236
237 spin_lock_irqsave(&queue->lock, flags);
238 __ar9170_dump_txqueue(ar, queue);
239 spin_unlock_irqrestore(&queue->lock, flags);
240}
Christian Lamparteracbadf02009-07-11 17:24:14 +0200241#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200242
Christian Lamparteracbadf02009-07-11 17:24:14 +0200243#ifdef AR9170_QUEUE_STOP_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200244static void __ar9170_dump_txstats(struct ar9170 *ar)
245{
246 int i;
247
Joe Perches5db55842010-08-11 19:11:19 -0700248 wiphy_debug(ar->hw->wiphy, "QoS queue stats\n");
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200249
250 for (i = 0; i < __AR9170_NUM_TXQ; i++)
Joe Perchesc96c31e2010-07-26 14:39:58 -0700251 wiphy_debug(ar->hw->wiphy,
252 "queue:%d limit:%d len:%d waitack:%d stopped:%d\n",
253 i, ar->tx_stats[i].limit, ar->tx_stats[i].len,
254 skb_queue_len(&ar->tx_status[i]),
255 ieee80211_queue_stopped(ar->hw, i));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200256}
Christian Lamparteracbadf02009-07-11 17:24:14 +0200257#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200258
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200259/* caller must guarantee exclusive access for _bin_ queue. */
260static void ar9170_recycle_expired(struct ar9170 *ar,
261 struct sk_buff_head *queue,
262 struct sk_buff_head *bin)
263{
264 struct sk_buff *skb, *old = NULL;
265 unsigned long flags;
266
267 spin_lock_irqsave(&queue->lock, flags);
268 while ((skb = skb_peek(queue))) {
269 struct ieee80211_tx_info *txinfo;
270 struct ar9170_tx_info *arinfo;
271
272 txinfo = IEEE80211_SKB_CB(skb);
273 arinfo = (void *) txinfo->rate_driver_data;
274
275 if (time_is_before_jiffies(arinfo->timeout)) {
276#ifdef AR9170_QUEUE_DEBUG
Joe Perchesc96c31e2010-07-26 14:39:58 -0700277 wiphy_debug(ar->hw->wiphy,
278 "[%ld > %ld] frame expired => recycle\n",
279 jiffies, arinfo->timeout);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200280 ar9170_print_txheader(ar, skb);
281#endif /* AR9170_QUEUE_DEBUG */
282 __skb_unlink(skb, queue);
283 __skb_queue_tail(bin, skb);
284 } else {
285 break;
286 }
287
288 if (unlikely(old == skb)) {
289 /* bail out - queue is shot. */
290
291 WARN_ON(1);
292 break;
293 }
294 old = skb;
295 }
296 spin_unlock_irqrestore(&queue->lock, flags);
297}
298
299static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
300 u16 tx_status)
301{
302 struct ieee80211_tx_info *txinfo;
303 unsigned int retries = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100304
305 txinfo = IEEE80211_SKB_CB(skb);
306 ieee80211_tx_info_clear_status(txinfo);
307
308 switch (tx_status) {
309 case AR9170_TX_STATUS_RETRY:
310 retries = 2;
311 case AR9170_TX_STATUS_COMPLETE:
312 txinfo->flags |= IEEE80211_TX_STAT_ACK;
313 break;
314
315 case AR9170_TX_STATUS_FAILED:
316 retries = ar->hw->conf.long_frame_max_tx_count;
317 break;
318
319 default:
Joe Perchesc96c31e2010-07-26 14:39:58 -0700320 wiphy_err(ar->hw->wiphy,
321 "invalid tx_status response (%x)\n", tx_status);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100322 break;
323 }
324
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200325 txinfo->status.rates[0].count = retries + 1;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100326 skb_pull(skb, sizeof(struct ar9170_tx_control));
327 ieee80211_tx_status_irqsafe(ar->hw, skb);
328}
Christian Lampartere9348cd2009-03-21 23:05:13 +0100329
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200330void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100331{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200332 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
333 struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data;
334 unsigned int queue = skb_get_queue_mapping(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100335 unsigned long flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100336
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200337 spin_lock_irqsave(&ar->tx_stats_lock, flags);
338 ar->tx_stats[queue].len--;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100339
Christian Lamparter53a76b52009-11-29 00:52:51 +0100340 if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200341#ifdef AR9170_QUEUE_STOP_DEBUG
Joe Perchesc96c31e2010-07-26 14:39:58 -0700342 wiphy_debug(ar->hw->wiphy, "wake queue %d\n", queue);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200343 __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
Joe Perchesc96c31e2010-07-26 14:39:58 -0700389 wiphy_debug(ar->hw->wiphy,
Joe Perches5db55842010-08-11 19:11:19 -0700390 "skip frame => DA %pM != %pM\n",
Joe Perchesc96c31e2010-07-26 14:39:58 -0700391 mac, ieee80211_get_DA(hdr));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200392 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
Joe Perchesc96c31e2010-07-26 14:39:58 -0700402 wiphy_debug(ar->hw->wiphy,
403 "skip frame => rate %d != %d\n", rate, r);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200404 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
Joe Perchesc96c31e2010-07-26 14:39:58 -0700415 wiphy_err(ar->hw->wiphy,
416 "ESS:[%pM] does not have any outstanding frames in queue.\n",
417 mac);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200418 __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
Joe Perchesc96c31e2010-07-26 14:39:58 -0700446 wiphy_debug(ar->hw->wiphy, "garbage collector scans queue:%d\n",
447 i);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200448 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
Joe Perchesc96c31e2010-07-26 14:39:58 -0700497 wiphy_debug(ar->hw->wiphy,
498 "recv tx_status for %pm, p:%08x, q:%d\n",
499 cmd->tx_status.dst, phy, q);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200500#endif /* AR9170_QUEUE_DEBUG */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100501
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200502 skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst,
503 &ar->tx_status[q],
504 AR9170_TX_INVALID_RATE);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100505 if (unlikely(!skb))
506 return ;
507
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200508 ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100509 break;
510 }
511
512 case 0xc0:
513 /*
514 * pre-TBTT event
515 */
516 if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
Luis R. Rodriguez42935ec2009-07-29 20:08:07 -0400517 ieee80211_queue_work(ar->hw, &ar->beacon_work);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100518 break;
519
520 case 0xc2:
521 /*
522 * (IBSS) beacon send notification
523 * bytes: 04 c2 XX YY B4 B3 B2 B1
524 *
525 * XX always 80
526 * YY always 00
527 * B1-B4 "should" be the number of send out beacons.
528 */
529 break;
530
531 case 0xc3:
532 /* End of Atim Window */
533 break;
534
535 case 0xc4:
Christian Lamparteracbadf02009-07-11 17:24:14 +0200536 /* BlockACK bitmap */
537 break;
538
Christian Lampartere9348cd2009-03-21 23:05:13 +0100539 case 0xc5:
540 /* BlockACK events */
541 break;
542
543 case 0xc6:
544 /* Watchdog Interrupt */
545 break;
546
547 case 0xc9:
548 /* retransmission issue / SIFS/EIFS collision ?! */
549 break;
550
Johannes Berg2543a0c2009-06-05 11:47:43 +0200551 /* firmware debug */
552 case 0xca:
Luis de Bethencourtb4098942010-03-31 15:07:48 +0100553 printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4,
554 (char *)buf + 4);
Johannes Berg2543a0c2009-06-05 11:47:43 +0200555 break;
556 case 0xcb:
557 len -= 4;
558
559 switch (len) {
560 case 1:
561 printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n",
562 *((char *)buf + 4));
563 break;
564 case 2:
565 printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n",
566 le16_to_cpup((__le16 *)((char *)buf + 4)));
567 break;
568 case 4:
569 printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n",
570 le32_to_cpup((__le32 *)((char *)buf + 4)));
571 break;
572 case 8:
573 printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n",
574 (unsigned long)le64_to_cpup(
575 (__le64 *)((char *)buf + 4)));
576 break;
577 }
578 break;
579 case 0xcc:
580 print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE,
581 (char *)buf + 4, len - 4);
582 break;
583
Christian Lampartere9348cd2009-03-21 23:05:13 +0100584 default:
Joe Perchesc96c31e2010-07-26 14:39:58 -0700585 pr_info("received unhandled event %x\n", cmd->type);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100586 print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
587 break;
588 }
589}
590
Christian Lampartercca847992009-04-19 01:28:12 +0200591static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100592{
Christian Lampartercca847992009-04-19 01:28:12 +0200593 memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head));
594 ar->rx_mpdu.has_plcp = false;
595}
Christian Lampartere9348cd2009-03-21 23:05:13 +0100596
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200597int ar9170_nag_limiter(struct ar9170 *ar)
Christian Lampartercca847992009-04-19 01:28:12 +0200598{
599 bool print_message;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100600
Christian Lampartercca847992009-04-19 01:28:12 +0200601 /*
602 * we expect all sorts of errors in promiscuous mode.
603 * don't bother with it, it's OK!
604 */
605 if (ar->sniffer_enabled)
606 return false;
607
608 /*
609 * only go for frequent errors! The hardware tends to
610 * do some stupid thing once in a while under load, in
611 * noisy environments or just for fun!
612 */
613 if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit())
614 print_message = true;
615 else
616 print_message = false;
617
618 /* reset threshold for "once in a while" */
619 ar->bad_hw_nagger = jiffies + HZ / 4;
620 return print_message;
621}
622
623static int ar9170_rx_mac_status(struct ar9170 *ar,
624 struct ar9170_rx_head *head,
625 struct ar9170_rx_macstatus *mac,
626 struct ieee80211_rx_status *status)
627{
628 u8 error, decrypt;
629
Christian Lampartere9348cd2009-03-21 23:05:13 +0100630 BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
Christian Lampartercca847992009-04-19 01:28:12 +0200631 BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100632
Christian Lampartercca847992009-04-19 01:28:12 +0200633 error = mac->error;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100634 if (error & AR9170_RX_ERROR_MMIC) {
Christian Lampartercca847992009-04-19 01:28:12 +0200635 status->flag |= RX_FLAG_MMIC_ERROR;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100636 error &= ~AR9170_RX_ERROR_MMIC;
637 }
638
639 if (error & AR9170_RX_ERROR_PLCP) {
Christian Lampartercca847992009-04-19 01:28:12 +0200640 status->flag |= RX_FLAG_FAILED_PLCP_CRC;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100641 error &= ~AR9170_RX_ERROR_PLCP;
Christian Lampartercca847992009-04-19 01:28:12 +0200642
643 if (!(ar->filter_state & FIF_PLCPFAIL))
644 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100645 }
646
647 if (error & AR9170_RX_ERROR_FCS) {
Christian Lampartercca847992009-04-19 01:28:12 +0200648 status->flag |= RX_FLAG_FAILED_FCS_CRC;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100649 error &= ~AR9170_RX_ERROR_FCS;
Christian Lampartercca847992009-04-19 01:28:12 +0200650
651 if (!(ar->filter_state & FIF_FCSFAIL))
652 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100653 }
654
Christian Lampartercca847992009-04-19 01:28:12 +0200655 decrypt = ar9170_get_decrypt_type(mac);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100656 if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
657 decrypt != AR9170_ENC_ALG_NONE)
Christian Lampartercca847992009-04-19 01:28:12 +0200658 status->flag |= RX_FLAG_DECRYPTED;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100659
660 /* ignore wrong RA errors */
661 error &= ~AR9170_RX_ERROR_WRONG_RA;
662
663 if (error & AR9170_RX_ERROR_DECRYPT) {
664 error &= ~AR9170_RX_ERROR_DECRYPT;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100665 /*
666 * Rx decryption is done in place,
667 * the original data is lost anyway.
668 */
Christian Lampartercca847992009-04-19 01:28:12 +0200669
670 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100671 }
672
673 /* drop any other error frames */
Christian Lampartercca847992009-04-19 01:28:12 +0200674 if (unlikely(error)) {
675 /* TODO: update netdevice's RX dropped/errors statistics */
676
677 if (ar9170_nag_limiter(ar))
Joe Perchesc96c31e2010-07-26 14:39:58 -0700678 wiphy_debug(ar->hw->wiphy,
679 "received frame with suspicious error code (%#x).\n",
680 error);
Christian Lampartercca847992009-04-19 01:28:12 +0200681
682 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100683 }
684
Christian Lampartercca847992009-04-19 01:28:12 +0200685 status->band = ar->channel->band;
686 status->freq = ar->channel->center_freq;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100687
Christian Lampartercca847992009-04-19 01:28:12 +0200688 switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) {
689 case AR9170_RX_STATUS_MODULATION_CCK:
690 if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
691 status->flag |= RX_FLAG_SHORTPRE;
692 switch (head->plcp[0]) {
693 case 0x0a:
694 status->rate_idx = 0;
695 break;
696 case 0x14:
697 status->rate_idx = 1;
698 break;
699 case 0x37:
700 status->rate_idx = 2;
701 break;
702 case 0x6e:
703 status->rate_idx = 3;
704 break;
705 default:
706 if (ar9170_nag_limiter(ar))
Joe Perchesc96c31e2010-07-26 14:39:58 -0700707 wiphy_err(ar->hw->wiphy,
708 "invalid plcp cck rate (%x).\n",
709 head->plcp[0]);
Christian Lampartercca847992009-04-19 01:28:12 +0200710 return -EINVAL;
711 }
712 break;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100713
Christian Lamparter7d57b732009-11-14 00:57:58 +0100714 case AR9170_RX_STATUS_MODULATION_DUPOFDM:
Christian Lampartercca847992009-04-19 01:28:12 +0200715 case AR9170_RX_STATUS_MODULATION_OFDM:
716 switch (head->plcp[0] & 0xf) {
717 case 0xb:
718 status->rate_idx = 0;
719 break;
720 case 0xf:
721 status->rate_idx = 1;
722 break;
723 case 0xa:
724 status->rate_idx = 2;
725 break;
726 case 0xe:
727 status->rate_idx = 3;
728 break;
729 case 0x9:
730 status->rate_idx = 4;
731 break;
732 case 0xd:
733 status->rate_idx = 5;
734 break;
735 case 0x8:
736 status->rate_idx = 6;
737 break;
738 case 0xc:
739 status->rate_idx = 7;
740 break;
741 default:
742 if (ar9170_nag_limiter(ar))
Joe Perchesc96c31e2010-07-26 14:39:58 -0700743 wiphy_err(ar->hw->wiphy,
744 "invalid plcp ofdm rate (%x).\n",
745 head->plcp[0]);
Christian Lampartercca847992009-04-19 01:28:12 +0200746 return -EINVAL;
747 }
748 if (status->band == IEEE80211_BAND_2GHZ)
749 status->rate_idx += 4;
750 break;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100751
Christian Lampartercca847992009-04-19 01:28:12 +0200752 case AR9170_RX_STATUS_MODULATION_HT:
753 if (head->plcp[3] & 0x80)
754 status->flag |= RX_FLAG_40MHZ;
755 if (head->plcp[6] & 0x80)
756 status->flag |= RX_FLAG_SHORT_GI;
757
758 status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f);
759 status->flag |= RX_FLAG_HT;
760 break;
761
Christian Lamparter7d57b732009-11-14 00:57:58 +0100762 default:
Christian Lampartercca847992009-04-19 01:28:12 +0200763 if (ar9170_nag_limiter(ar))
Joe Perchesc96c31e2010-07-26 14:39:58 -0700764 wiphy_err(ar->hw->wiphy, "invalid modulation\n");
Christian Lampartercca847992009-04-19 01:28:12 +0200765 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))
Joe Perchesc96c31e2010-07-26 14:39:58 -0700865 wiphy_err(ar->hw->wiphy,
866 "plcp info is clipped.\n");
Christian Lampartercca847992009-04-19 01:28:12 +0200867 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))
Joe Perchesc96c31e2010-07-26 14:39:58 -0700879 wiphy_err(ar->hw->wiphy,
880 "frame tail is clipped.\n");
Christian Lampartercca847992009-04-19 01:28:12 +0200881 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
Joe Perchesc96c31e2010-07-26 14:39:58 -0700890 wiphy_err(ar->hw->wiphy,
891 "rx stream did not start with a first_mpdu frame tag.\n");
Christian Lampartercca847992009-04-19 01:28:12 +0200892
893 return ;
894 }
895
896 head = &ar->rx_mpdu.plcp;
897 break;
898
899 case AR9170_RX_STATUS_MPDU_SINGLE:
900 /* single mpdu - has plcp (head) and phy status (tail) */
901 head = (void *) buf;
902
903 mpdu_len -= sizeof(struct ar9170_rx_head);
904 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
905
906 buf += sizeof(struct ar9170_rx_head);
907 phy = (void *)(buf + mpdu_len);
908 break;
909
910 default:
911 BUG_ON(1);
912 break;
913 }
914
915 if (unlikely(mpdu_len < FCS_LEN))
916 return ;
917
918 memset(&status, 0, sizeof(status));
919 if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status)))
920 return ;
921
922 if (phy)
923 ar9170_rx_phy_status(ar, phy, &status);
924
925 skb = ar9170_rx_copy_data(buf, mpdu_len);
Johannes Bergf1d58c22009-06-17 13:13:00 +0200926 if (likely(skb)) {
927 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
928 ieee80211_rx_irqsafe(ar->hw, skb);
929 }
Christian Lampartere9348cd2009-03-21 23:05:13 +0100930}
931
Christian Lampartere9348cd2009-03-21 23:05:13 +0100932void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
933{
Christian Lampartercca847992009-04-19 01:28:12 +0200934 unsigned int i, tlen, resplen, wlen = 0, clen = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100935 u8 *tbuf, *respbuf;
936
937 tbuf = skb->data;
938 tlen = skb->len;
939
940 while (tlen >= 4) {
Christian Lampartercca847992009-04-19 01:28:12 +0200941 clen = tbuf[1] << 8 | tbuf[0];
942 wlen = ALIGN(clen, 4);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100943
Christian Lampartercca847992009-04-19 01:28:12 +0200944 /* check if this is stream has a valid tag.*/
Christian Lampartere9348cd2009-03-21 23:05:13 +0100945 if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
Christian Lampartercca847992009-04-19 01:28:12 +0200946 /*
947 * TODO: handle the highly unlikely event that the
948 * corrupted stream has the TAG at the right position.
949 */
950
951 /* check if the frame can be repaired. */
952 if (!ar->rx_failover_missing) {
953 /* this is no "short read". */
954 if (ar9170_nag_limiter(ar)) {
Joe Perchesc96c31e2010-07-26 14:39:58 -0700955 wiphy_err(ar->hw->wiphy,
956 "missing tag!\n");
Christian Lampartercca847992009-04-19 01:28:12 +0200957 goto err_telluser;
958 } else
959 goto err_silent;
960 }
961
962 if (ar->rx_failover_missing > tlen) {
963 if (ar9170_nag_limiter(ar)) {
Joe Perchesc96c31e2010-07-26 14:39:58 -0700964 wiphy_err(ar->hw->wiphy,
965 "possible multi stream corruption!\n");
Christian Lampartercca847992009-04-19 01:28:12 +0200966 goto err_telluser;
967 } else
968 goto err_silent;
969 }
970
971 memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
972 ar->rx_failover_missing -= tlen;
973
974 if (ar->rx_failover_missing <= 0) {
975 /*
976 * nested ar9170_rx call!
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300977 * termination is guaranteed, even when the
Christian Lampartercca847992009-04-19 01:28:12 +0200978 * combined frame also have a element with
979 * a bad tag.
980 */
981
982 ar->rx_failover_missing = 0;
983 ar9170_rx(ar, ar->rx_failover);
984
985 skb_reset_tail_pointer(ar->rx_failover);
986 skb_trim(ar->rx_failover, 0);
987 }
988
Christian Lampartere9348cd2009-03-21 23:05:13 +0100989 return ;
990 }
Christian Lampartercca847992009-04-19 01:28:12 +0200991
992 /* check if stream is clipped */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100993 if (wlen > tlen - 4) {
Christian Lampartercca847992009-04-19 01:28:12 +0200994 if (ar->rx_failover_missing) {
995 /* TODO: handle double stream corruption. */
996 if (ar9170_nag_limiter(ar)) {
Joe Perchesc96c31e2010-07-26 14:39:58 -0700997 wiphy_err(ar->hw->wiphy,
998 "double rx stream corruption!\n");
Christian Lampartercca847992009-04-19 01:28:12 +0200999 goto err_telluser;
1000 } else
1001 goto err_silent;
1002 }
1003
1004 /*
1005 * save incomplete data set.
1006 * the firmware will resend the missing bits when
1007 * the rx - descriptor comes round again.
1008 */
1009
1010 memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
1011 ar->rx_failover_missing = clen - tlen;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001012 return ;
1013 }
1014 resplen = clen;
1015 respbuf = tbuf + 4;
1016 tbuf += wlen + 4;
1017 tlen -= wlen + 4;
1018
1019 i = 0;
1020
1021 /* weird thing, but this is the same in the original driver */
1022 while (resplen > 2 && i < 12 &&
1023 respbuf[0] == 0xff && respbuf[1] == 0xff) {
1024 i += 2;
1025 resplen -= 2;
1026 respbuf += 2;
1027 }
1028
1029 if (resplen < 4)
1030 continue;
1031
1032 /* found the 6 * 0xffff marker? */
1033 if (i == 12)
1034 ar9170_handle_command_response(ar, respbuf, resplen);
1035 else
Christian Lampartercca847992009-04-19 01:28:12 +02001036 ar9170_handle_mpdu(ar, respbuf, clen);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001037 }
1038
Christian Lampartercca847992009-04-19 01:28:12 +02001039 if (tlen) {
1040 if (net_ratelimit())
Joe Perchesc96c31e2010-07-26 14:39:58 -07001041 wiphy_err(ar->hw->wiphy,
1042 "%d bytes of unprocessed data left in rx stream!\n",
1043 tlen);
Christian Lampartercca847992009-04-19 01:28:12 +02001044
1045 goto err_telluser;
1046 }
1047
1048 return ;
1049
1050err_telluser:
Joe Perchesc96c31e2010-07-26 14:39:58 -07001051 wiphy_err(ar->hw->wiphy,
1052 "damaged RX stream data [want:%d, data:%d, rx:%d, pending:%d ]\n",
1053 clen, wlen, tlen, ar->rx_failover_missing);
Christian Lampartercca847992009-04-19 01:28:12 +02001054
1055 if (ar->rx_failover_missing)
1056 print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
1057 ar->rx_failover->data,
1058 ar->rx_failover->len);
1059
1060 print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
1061 skb->data, skb->len);
1062
Joe Perchesc96c31e2010-07-26 14:39:58 -07001063 wiphy_err(ar->hw->wiphy,
1064 "If you see this message frequently, please check your hardware and cables.\n");
Christian Lampartercca847992009-04-19 01:28:12 +02001065
1066err_silent:
1067 if (ar->rx_failover_missing) {
1068 skb_reset_tail_pointer(ar->rx_failover);
1069 skb_trim(ar->rx_failover, 0);
1070 ar->rx_failover_missing = 0;
1071 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001072}
Christian Lampartere9348cd2009-03-21 23:05:13 +01001073
1074#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \
1075do { \
1076 queue.aifs = ai_fs; \
1077 queue.cw_min = cwmin; \
1078 queue.cw_max = cwmax; \
1079 queue.txop = _txop; \
1080} while (0)
1081
1082static int ar9170_op_start(struct ieee80211_hw *hw)
1083{
1084 struct ar9170 *ar = hw->priv;
1085 int err, i;
1086
1087 mutex_lock(&ar->mutex);
1088
1089 /* reinitialize queues statistics */
1090 memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001091 for (i = 0; i < __AR9170_NUM_TXQ; i++)
1092 ar->tx_stats[i].limit = AR9170_TXQ_DEPTH;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001093
1094 /* reset QoS defaults */
1095 AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/
1096 AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023, 0); /* BACKGROUND */
1097 AR9170_FILL_QUEUE(ar->edcf[2], 2, 7, 15, 94); /* VIDEO */
1098 AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */
1099 AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
1100
Christian Lamparteracbadf02009-07-11 17:24:14 +02001101 /* set sane AMPDU defaults */
1102 ar->global_ampdu_density = 6;
1103 ar->global_ampdu_factor = 3;
1104
Christian Lampartercca847992009-04-19 01:28:12 +02001105 ar->bad_hw_nagger = jiffies;
1106
Christian Lampartere9348cd2009-03-21 23:05:13 +01001107 err = ar->open(ar);
1108 if (err)
1109 goto out;
1110
1111 err = ar9170_init_mac(ar);
1112 if (err)
1113 goto out;
1114
1115 err = ar9170_set_qos(ar);
1116 if (err)
1117 goto out;
1118
1119 err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
1120 if (err)
1121 goto out;
1122
1123 err = ar9170_init_rf(ar);
1124 if (err)
1125 goto out;
1126
1127 /* start DMA */
1128 err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
1129 if (err)
1130 goto out;
1131
1132 ar->state = AR9170_STARTED;
1133
1134out:
1135 mutex_unlock(&ar->mutex);
1136 return err;
1137}
1138
1139static void ar9170_op_stop(struct ieee80211_hw *hw)
1140{
1141 struct ar9170 *ar = hw->priv;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001142 unsigned int i;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001143
1144 if (IS_STARTED(ar))
1145 ar->state = AR9170_IDLE;
1146
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001147 cancel_delayed_work_sync(&ar->tx_janitor);
Alexander Beregalovff8365c2009-07-24 11:55:44 +04001148#ifdef CONFIG_AR9170_LEDS
Christian Lamparteracbadf02009-07-11 17:24:14 +02001149 cancel_delayed_work_sync(&ar->led_work);
Alexander Beregalovff8365c2009-07-24 11:55:44 +04001150#endif
Christian Lampartere9348cd2009-03-21 23:05:13 +01001151 cancel_work_sync(&ar->beacon_work);
Luis R. Rodrigueze351cfb2009-07-27 12:51:37 -07001152
Christian Lamparterb55d6bc2009-05-23 20:31:21 +02001153 mutex_lock(&ar->mutex);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001154
1155 if (IS_ACCEPTING_CMD(ar)) {
1156 ar9170_set_leds_state(ar, 0);
1157
1158 /* stop DMA */
1159 ar9170_write_reg(ar, 0x1c3d30, 0);
1160 ar->stop(ar);
1161 }
1162
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001163 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1164 skb_queue_purge(&ar->tx_pending[i]);
1165 skb_queue_purge(&ar->tx_status[i]);
1166 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02001167
Christian Lampartere9348cd2009-03-21 23:05:13 +01001168 mutex_unlock(&ar->mutex);
1169}
1170
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001171static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001172{
Christian Lampartere9348cd2009-03-21 23:05:13 +01001173 struct ieee80211_hdr *hdr;
1174 struct ar9170_tx_control *txc;
1175 struct ieee80211_tx_info *info;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001176 struct ieee80211_tx_rate *txrate;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001177 struct ar9170_tx_info *arinfo;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001178 unsigned int queue = skb_get_queue_mapping(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001179 u16 keytype = 0;
1180 u16 len, icv = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001181
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001182 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001183
1184 hdr = (void *)skb->data;
1185 info = IEEE80211_SKB_CB(skb);
1186 len = skb->len;
1187
Christian Lampartere9348cd2009-03-21 23:05:13 +01001188 txc = (void *)skb_push(skb, sizeof(*txc));
1189
Christian Lampartere9348cd2009-03-21 23:05:13 +01001190 if (info->control.hw_key) {
1191 icv = info->control.hw_key->icv_len;
1192
Johannes Berg97359d12010-08-10 09:46:38 +02001193 switch (info->control.hw_key->cipher) {
1194 case WLAN_CIPHER_SUITE_WEP40:
1195 case WLAN_CIPHER_SUITE_WEP104:
1196 case WLAN_CIPHER_SUITE_TKIP:
Christian Lampartere9348cd2009-03-21 23:05:13 +01001197 keytype = AR9170_TX_MAC_ENCR_RC4;
1198 break;
Johannes Berg97359d12010-08-10 09:46:38 +02001199 case WLAN_CIPHER_SUITE_CCMP:
Christian Lampartere9348cd2009-03-21 23:05:13 +01001200 keytype = AR9170_TX_MAC_ENCR_AES;
1201 break;
1202 default:
1203 WARN_ON(1);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001204 goto err_out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001205 }
1206 }
1207
1208 /* Length */
1209 txc->length = cpu_to_le16(len + icv + 4);
1210
1211 txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
1212 AR9170_TX_MAC_BACKOFF);
1213 txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
1214 AR9170_TX_MAC_QOS_SHIFT);
1215 txc->mac_control |= cpu_to_le16(keytype);
1216 txc->phy_control = cpu_to_le32(0);
1217
1218 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
1219 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
1220
Christian Lampartere9348cd2009-03-21 23:05:13 +01001221 txrate = &info->control.rates[0];
Christian Lampartere9348cd2009-03-21 23:05:13 +01001222 if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1223 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
1224 else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1225 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
1226
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001227 arinfo = (void *)info->rate_driver_data;
1228 arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT);
1229
1230 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
1231 (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001232 /*
1233 * WARNING:
1234 * Putting the QoS queue bits into an unexplored territory is
1235 * certainly not elegant.
1236 *
1237 * In my defense: This idea provides a reasonable way to
1238 * smuggle valuable information to the tx_status callback.
1239 * Also, the idea behind this bit-abuse came straight from
1240 * the original driver code.
1241 */
1242
1243 txc->phy_control |=
1244 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
Christian Lamparter15b098b2009-11-29 00:56:55 +01001245
Christian Lamparterf3926b42010-05-01 18:18:18 +02001246 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001247 }
1248
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001249 return 0;
1250
1251err_out:
1252 skb_pull(skb, sizeof(*txc));
1253 return -EINVAL;
1254}
1255
1256static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
1257{
1258 struct ar9170_tx_control *txc;
1259 struct ieee80211_tx_info *info;
1260 struct ieee80211_rate *rate = NULL;
1261 struct ieee80211_tx_rate *txrate;
1262 u32 power, chains;
1263
1264 txc = (void *) skb->data;
1265 info = IEEE80211_SKB_CB(skb);
1266 txrate = &info->control.rates[0];
1267
Christian Lampartere9348cd2009-03-21 23:05:13 +01001268 if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
1269 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
1270
1271 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1272 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
1273
1274 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1275 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
1276 /* this works because 40 MHz is 2 and dup is 3 */
1277 if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
1278 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
1279
1280 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
1281 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
1282
1283 if (txrate->flags & IEEE80211_TX_RC_MCS) {
1284 u32 r = txrate->idx;
1285 u8 *txpower;
1286
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001287 /* heavy clip control */
1288 txc->phy_control |= cpu_to_le32((r & 0x7) << 7);
1289
Christian Lampartere9348cd2009-03-21 23:05:13 +01001290 r <<= AR9170_TX_PHY_MCS_SHIFT;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001291 BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK);
1292
Christian Lampartere9348cd2009-03-21 23:05:13 +01001293 txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
1294 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
1295
1296 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1297 if (info->band == IEEE80211_BAND_5GHZ)
1298 txpower = ar->power_5G_ht40;
1299 else
1300 txpower = ar->power_2G_ht40;
1301 } else {
1302 if (info->band == IEEE80211_BAND_5GHZ)
1303 txpower = ar->power_5G_ht20;
1304 else
1305 txpower = ar->power_2G_ht20;
1306 }
1307
1308 power = txpower[(txrate->idx) & 7];
1309 } else {
1310 u8 *txpower;
1311 u32 mod;
1312 u32 phyrate;
1313 u8 idx = txrate->idx;
1314
1315 if (info->band != IEEE80211_BAND_2GHZ) {
1316 idx += 4;
1317 txpower = ar->power_5G_leg;
1318 mod = AR9170_TX_PHY_MOD_OFDM;
1319 } else {
1320 if (idx < 4) {
1321 txpower = ar->power_2G_cck;
1322 mod = AR9170_TX_PHY_MOD_CCK;
1323 } else {
1324 mod = AR9170_TX_PHY_MOD_OFDM;
1325 txpower = ar->power_2G_ofdm;
1326 }
1327 }
1328
1329 rate = &__ar9170_ratetable[idx];
1330
1331 phyrate = rate->hw_value & 0xF;
1332 power = txpower[(rate->hw_value & 0x30) >> 4];
1333 phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
1334
1335 txc->phy_control |= cpu_to_le32(mod);
1336 txc->phy_control |= cpu_to_le32(phyrate);
1337 }
1338
1339 power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
1340 power &= AR9170_TX_PHY_TX_PWR_MASK;
1341 txc->phy_control |= cpu_to_le32(power);
1342
1343 /* set TX chains */
1344 if (ar->eeprom.tx_mask == 1) {
1345 chains = AR9170_TX_PHY_TXCHAIN_1;
1346 } else {
1347 chains = AR9170_TX_PHY_TXCHAIN_2;
1348
1349 /* >= 36M legacy OFDM - use only one chain */
1350 if (rate && rate->bitrate >= 360)
1351 chains = AR9170_TX_PHY_TXCHAIN_1;
1352 }
1353 txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001354}
Christian Lampartere9348cd2009-03-21 23:05:13 +01001355
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001356static void ar9170_tx(struct ar9170 *ar)
1357{
1358 struct sk_buff *skb;
1359 unsigned long flags;
1360 struct ieee80211_tx_info *info;
1361 struct ar9170_tx_info *arinfo;
1362 unsigned int i, frames, frames_failed, remaining_space;
1363 int err;
1364 bool schedule_garbagecollector = false;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001365
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001366 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001367
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001368 if (unlikely(!IS_STARTED(ar)))
1369 return ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001370
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001371 remaining_space = AR9170_TX_MAX_PENDING;
1372
1373 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1374 spin_lock_irqsave(&ar->tx_stats_lock, flags);
Christian Lamparter53a76b52009-11-29 00:52:51 +01001375 frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
1376 skb_queue_len(&ar->tx_pending[i]));
1377
1378 if (remaining_space < frames) {
1379#ifdef AR9170_QUEUE_DEBUG
Joe Perchesc96c31e2010-07-26 14:39:58 -07001380 wiphy_debug(ar->hw->wiphy,
1381 "tx quota reached queue:%d, "
1382 "remaining slots:%d, needed:%d\n",
1383 i, remaining_space, frames);
Christian Lamparter53a76b52009-11-29 00:52:51 +01001384#endif /* AR9170_QUEUE_DEBUG */
1385 frames = remaining_space;
1386 }
1387
1388 ar->tx_stats[i].len += frames;
1389 ar->tx_stats[i].count += frames;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001390 if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
1391#ifdef AR9170_QUEUE_DEBUG
Joe Perchesc96c31e2010-07-26 14:39:58 -07001392 wiphy_debug(ar->hw->wiphy, "queue %d full\n", i);
1393 wiphy_debug(ar->hw->wiphy, "stuck frames: ===>\n");
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001394 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1395 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
1396#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparteracbadf02009-07-11 17:24:14 +02001397
1398#ifdef AR9170_QUEUE_STOP_DEBUG
Joe Perchesc96c31e2010-07-26 14:39:58 -07001399 wiphy_debug(ar->hw->wiphy, "stop queue %d\n", i);
Christian Lamparteracbadf02009-07-11 17:24:14 +02001400 __ar9170_dump_txstats(ar);
1401#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001402 ieee80211_stop_queue(ar->hw, i);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001403 }
1404
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001405 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1406
1407 if (!frames)
1408 continue;
1409
1410 frames_failed = 0;
1411 while (frames) {
1412 skb = skb_dequeue(&ar->tx_pending[i]);
1413 if (unlikely(!skb)) {
1414 frames_failed += frames;
1415 frames = 0;
1416 break;
1417 }
1418
1419 info = IEEE80211_SKB_CB(skb);
1420 arinfo = (void *) info->rate_driver_data;
1421
1422 /* TODO: cancel stuck frames */
1423 arinfo->timeout = jiffies +
1424 msecs_to_jiffies(AR9170_TX_TIMEOUT);
1425
1426#ifdef AR9170_QUEUE_DEBUG
Joe Perchesc96c31e2010-07-26 14:39:58 -07001427 wiphy_debug(ar->hw->wiphy, "send frame q:%d =>\n", i);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001428 ar9170_print_txheader(ar, skb);
1429#endif /* AR9170_QUEUE_DEBUG */
1430
1431 err = ar->tx(ar, skb);
1432 if (unlikely(err)) {
1433 frames_failed++;
1434 dev_kfree_skb_any(skb);
1435 } else {
1436 remaining_space--;
1437 schedule_garbagecollector = true;
1438 }
1439
1440 frames--;
1441 }
1442
1443#ifdef AR9170_QUEUE_DEBUG
Joe Perchesc96c31e2010-07-26 14:39:58 -07001444 wiphy_debug(ar->hw->wiphy,
1445 "ar9170_tx report for queue %d\n", i);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001446
Joe Perchesc96c31e2010-07-26 14:39:58 -07001447 wiphy_debug(ar->hw->wiphy,
1448 "unprocessed pending frames left:\n");
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001449 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1450#endif /* AR9170_QUEUE_DEBUG */
1451
1452 if (unlikely(frames_failed)) {
1453#ifdef AR9170_QUEUE_DEBUG
Joe Perchesc96c31e2010-07-26 14:39:58 -07001454 wiphy_debug(ar->hw->wiphy,
1455 "frames failed %d =>\n", frames_failed);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001456#endif /* AR9170_QUEUE_DEBUG */
1457
1458 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1459 ar->tx_stats[i].len -= frames_failed;
1460 ar->tx_stats[i].count -= frames_failed;
Christian Lamparteracbadf02009-07-11 17:24:14 +02001461#ifdef AR9170_QUEUE_STOP_DEBUG
Joe Perchesc96c31e2010-07-26 14:39:58 -07001462 wiphy_debug(ar->hw->wiphy, "wake queue %d\n", i);
Christian Lamparteracbadf02009-07-11 17:24:14 +02001463 __ar9170_dump_txstats(ar);
1464#endif /* AR9170_QUEUE_STOP_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001465 ieee80211_wake_queue(ar->hw, i);
1466 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001467 }
1468 }
1469
Luis R. Rodriguez42935ec2009-07-29 20:08:07 -04001470 if (!schedule_garbagecollector)
1471 return;
1472
1473 ieee80211_queue_delayed_work(ar->hw,
1474 &ar->tx_janitor,
1475 msecs_to_jiffies(AR9170_JANITOR_DELAY));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001476}
1477
Johannes Berg7bb45682011-02-24 14:42:06 +01001478void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001479{
1480 struct ar9170 *ar = hw->priv;
1481 struct ieee80211_tx_info *info;
Christian Lamparterf3926b42010-05-01 18:18:18 +02001482 unsigned int queue;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001483
1484 if (unlikely(!IS_STARTED(ar)))
1485 goto err_free;
1486
1487 if (unlikely(ar9170_tx_prepare(ar, skb)))
1488 goto err_free;
1489
Christian Lamparterf3926b42010-05-01 18:18:18 +02001490 queue = skb_get_queue_mapping(skb);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001491 info = IEEE80211_SKB_CB(skb);
Christian Lamparterf3926b42010-05-01 18:18:18 +02001492 ar9170_tx_prepare_phy(ar, skb);
1493 skb_queue_tail(&ar->tx_pending[queue], skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001494
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001495 ar9170_tx(ar);
Johannes Berg7bb45682011-02-24 14:42:06 +01001496 return;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001497
Christian Lampartere9348cd2009-03-21 23:05:13 +01001498err_free:
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001499 dev_kfree_skb_any(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001500}
1501
1502static int ar9170_op_add_interface(struct ieee80211_hw *hw,
Johannes Berg1ed32e42009-12-23 13:15:45 +01001503 struct ieee80211_vif *vif)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001504{
1505 struct ar9170 *ar = hw->priv;
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07001506 struct ath_common *common = &ar->common;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001507 int err = 0;
1508
1509 mutex_lock(&ar->mutex);
1510
1511 if (ar->vif) {
1512 err = -EBUSY;
1513 goto unlock;
1514 }
1515
Johannes Berg1ed32e42009-12-23 13:15:45 +01001516 ar->vif = vif;
1517 memcpy(common->macaddr, vif->addr, ETH_ALEN);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001518
1519 if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
1520 ar->rx_software_decryption = true;
1521 ar->disable_offload = true;
1522 }
1523
1524 ar->cur_filter = 0;
Christian Lampartereeef4182009-08-19 12:43:47 +02001525 err = ar9170_update_frame_filter(ar, AR9170_MAC_REG_FTF_DEFAULTS);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001526 if (err)
1527 goto unlock;
1528
1529 err = ar9170_set_operating_mode(ar);
1530
1531unlock:
1532 mutex_unlock(&ar->mutex);
1533 return err;
1534}
1535
1536static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
Johannes Berg1ed32e42009-12-23 13:15:45 +01001537 struct ieee80211_vif *vif)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001538{
1539 struct ar9170 *ar = hw->priv;
1540
1541 mutex_lock(&ar->mutex);
1542 ar->vif = NULL;
Christian Lampartereeef4182009-08-19 12:43:47 +02001543 ar9170_update_frame_filter(ar, 0);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001544 ar9170_set_beacon_timers(ar);
1545 dev_kfree_skb(ar->beacon);
1546 ar->beacon = NULL;
1547 ar->sniffer_enabled = false;
1548 ar->rx_software_decryption = false;
1549 ar9170_set_operating_mode(ar);
1550 mutex_unlock(&ar->mutex);
1551}
1552
1553static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
1554{
1555 struct ar9170 *ar = hw->priv;
1556 int err = 0;
1557
1558 mutex_lock(&ar->mutex);
1559
Christian Lampartere9348cd2009-03-21 23:05:13 +01001560 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
1561 /* TODO */
1562 err = 0;
1563 }
1564
1565 if (changed & IEEE80211_CONF_CHANGE_PS) {
1566 /* TODO */
1567 err = 0;
1568 }
1569
1570 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1571 /* TODO */
1572 err = 0;
1573 }
1574
1575 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
1576 /*
1577 * is it long_frame_max_tx_count or short_frame_max_tx_count?
1578 */
1579
1580 err = ar9170_set_hwretry_limit(ar,
1581 ar->hw->conf.long_frame_max_tx_count);
1582 if (err)
1583 goto out;
1584 }
1585
Christian Lampartere9348cd2009-03-21 23:05:13 +01001586 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02001587
1588 /* adjust slot time for 5 GHz */
1589 err = ar9170_set_slot_time(ar);
1590 if (err)
1591 goto out;
1592
1593 err = ar9170_set_dyn_sifs_ack(ar);
1594 if (err)
1595 goto out;
1596
Christian Lampartere9348cd2009-03-21 23:05:13 +01001597 err = ar9170_set_channel(ar, hw->conf.channel,
Johannes Berg9e52b062009-04-20 18:27:04 +02001598 AR9170_RFI_NONE,
1599 nl80211_to_ar9170(hw->conf.channel_type));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001600 if (err)
1601 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001602 }
1603
1604out:
1605 mutex_unlock(&ar->mutex);
1606 return err;
1607}
1608
Jiri Pirko22bedad2010-04-01 21:22:57 +00001609static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw,
1610 struct netdev_hw_addr_list *mc_list)
Johannes Berg3ac64be2009-08-17 16:16:53 +02001611{
1612 u64 mchash;
Jiri Pirko22bedad2010-04-01 21:22:57 +00001613 struct netdev_hw_addr *ha;
Johannes Berg3ac64be2009-08-17 16:16:53 +02001614
1615 /* always get broadcast frames */
1616 mchash = 1ULL << (0xff >> 2);
1617
Jiri Pirko22bedad2010-04-01 21:22:57 +00001618 netdev_hw_addr_list_for_each(ha, mc_list)
1619 mchash |= 1ULL << (ha->addr[5] >> 2);
Johannes Berg3ac64be2009-08-17 16:16:53 +02001620
1621 return mchash;
1622}
1623
Christian Lampartere9348cd2009-03-21 23:05:13 +01001624static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
1625 unsigned int changed_flags,
1626 unsigned int *new_flags,
Johannes Berg3ac64be2009-08-17 16:16:53 +02001627 u64 multicast)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001628{
1629 struct ar9170 *ar = hw->priv;
1630
Christian Lampartereeef4182009-08-19 12:43:47 +02001631 if (unlikely(!IS_ACCEPTING_CMD(ar)))
1632 return ;
1633
1634 mutex_lock(&ar->mutex);
1635
Christian Lampartere9348cd2009-03-21 23:05:13 +01001636 /* mask supported flags */
1637 *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
Christian Lampartercca847992009-04-19 01:28:12 +02001638 FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
1639 ar->filter_state = *new_flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001640 /*
1641 * We can support more by setting the sniffer bit and
1642 * then checking the error flags, later.
1643 */
1644
Johannes Berg3ac64be2009-08-17 16:16:53 +02001645 if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
Christian Lampartereeef4182009-08-19 12:43:47 +02001646 multicast = ~0ULL;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001647
Christian Lampartereeef4182009-08-19 12:43:47 +02001648 if (multicast != ar->cur_mc_hash)
1649 ar9170_update_multicast(ar, multicast);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001650
1651 if (changed_flags & FIF_CONTROL) {
1652 u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
1653 AR9170_MAC_REG_FTF_RTS |
1654 AR9170_MAC_REG_FTF_CTS |
1655 AR9170_MAC_REG_FTF_ACK |
1656 AR9170_MAC_REG_FTF_CFE |
1657 AR9170_MAC_REG_FTF_CFE_ACK;
1658
1659 if (*new_flags & FIF_CONTROL)
Christian Lampartereeef4182009-08-19 12:43:47 +02001660 filter |= ar->cur_filter;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001661 else
Christian Lampartereeef4182009-08-19 12:43:47 +02001662 filter &= (~ar->cur_filter);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001663
Christian Lampartereeef4182009-08-19 12:43:47 +02001664 ar9170_update_frame_filter(ar, filter);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001665 }
1666
1667 if (changed_flags & FIF_PROMISC_IN_BSS) {
1668 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
Christian Lampartereeef4182009-08-19 12:43:47 +02001669 ar9170_set_operating_mode(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001670 }
1671
Christian Lampartereeef4182009-08-19 12:43:47 +02001672 mutex_unlock(&ar->mutex);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001673}
1674
Christian Lampartereeef4182009-08-19 12:43:47 +02001675
Christian Lampartere9348cd2009-03-21 23:05:13 +01001676static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
1677 struct ieee80211_vif *vif,
1678 struct ieee80211_bss_conf *bss_conf,
1679 u32 changed)
1680{
1681 struct ar9170 *ar = hw->priv;
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07001682 struct ath_common *common = &ar->common;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001683 int err = 0;
1684
1685 mutex_lock(&ar->mutex);
1686
Johannes Berg2d0ddec2009-04-23 16:13:26 +02001687 if (changed & BSS_CHANGED_BSSID) {
Luis R. Rodriguez8c727e72009-09-10 10:10:54 -07001688 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
Johannes Berg2d0ddec2009-04-23 16:13:26 +02001689 err = ar9170_set_operating_mode(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02001690 if (err)
1691 goto out;
Johannes Berg2d0ddec2009-04-23 16:13:26 +02001692 }
1693
Joerg Albertea39d1a2009-08-21 23:25:07 +02001694 if (changed & BSS_CHANGED_BEACON_ENABLED)
1695 ar->enable_beacon = bss_conf->enable_beacon;
1696
1697 if (changed & BSS_CHANGED_BEACON) {
Johannes Berg2d0ddec2009-04-23 16:13:26 +02001698 err = ar9170_update_beacon(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02001699 if (err)
1700 goto out;
Joerg Albertea39d1a2009-08-21 23:25:07 +02001701 }
Johannes Berg2d0ddec2009-04-23 16:13:26 +02001702
Joerg Albertea39d1a2009-08-21 23:25:07 +02001703 if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON |
1704 BSS_CHANGED_BEACON_INT)) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02001705 err = ar9170_set_beacon_timers(ar);
1706 if (err)
1707 goto out;
1708 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001709
1710 if (changed & BSS_CHANGED_ASSOC) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001711#ifndef CONFIG_AR9170_LEDS
1712 /* enable assoc LED. */
1713 err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
1714#endif /* CONFIG_AR9170_LEDS */
1715 }
1716
1717 if (changed & BSS_CHANGED_HT) {
1718 /* TODO */
1719 err = 0;
1720 }
1721
1722 if (changed & BSS_CHANGED_ERP_SLOT) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02001723 err = ar9170_set_slot_time(ar);
1724 if (err)
1725 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001726 }
1727
1728 if (changed & BSS_CHANGED_BASIC_RATES) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02001729 err = ar9170_set_basic_rates(ar);
1730 if (err)
1731 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001732 }
1733
Christian Lamparter29ceff52009-06-01 21:42:01 +02001734out:
Christian Lampartere9348cd2009-03-21 23:05:13 +01001735 mutex_unlock(&ar->mutex);
1736}
1737
1738static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
1739{
1740 struct ar9170 *ar = hw->priv;
1741 int err;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001742 u64 tsf;
Joerg Albert181af382009-09-15 23:27:53 +02001743#define NR 3
1744 static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H,
1745 AR9170_MAC_REG_TSF_L,
1746 AR9170_MAC_REG_TSF_H };
1747 u32 val[NR];
1748 int loops = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001749
1750 mutex_lock(&ar->mutex);
Joerg Albert181af382009-09-15 23:27:53 +02001751
1752 while (loops++ < 10) {
1753 err = ar9170_read_mreg(ar, NR, addr, val);
1754 if (err || val[0] == val[2])
1755 break;
1756 }
1757
Christian Lampartere9348cd2009-03-21 23:05:13 +01001758 mutex_unlock(&ar->mutex);
1759
1760 if (WARN_ON(err))
1761 return 0;
Joerg Albert181af382009-09-15 23:27:53 +02001762 tsf = val[0];
1763 tsf = (tsf << 32) | val[1];
Christian Lampartere9348cd2009-03-21 23:05:13 +01001764 return tsf;
Joerg Albert181af382009-09-15 23:27:53 +02001765#undef NR
Christian Lampartere9348cd2009-03-21 23:05:13 +01001766}
1767
1768static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1769 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
1770 struct ieee80211_key_conf *key)
1771{
1772 struct ar9170 *ar = hw->priv;
1773 int err = 0, i;
1774 u8 ktype;
1775
1776 if ((!ar->vif) || (ar->disable_offload))
1777 return -EOPNOTSUPP;
1778
Johannes Berg97359d12010-08-10 09:46:38 +02001779 switch (key->cipher) {
1780 case WLAN_CIPHER_SUITE_WEP40:
1781 ktype = AR9170_ENC_ALG_WEP64;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001782 break;
Johannes Berg97359d12010-08-10 09:46:38 +02001783 case WLAN_CIPHER_SUITE_WEP104:
1784 ktype = AR9170_ENC_ALG_WEP128;
1785 break;
1786 case WLAN_CIPHER_SUITE_TKIP:
Christian Lampartere9348cd2009-03-21 23:05:13 +01001787 ktype = AR9170_ENC_ALG_TKIP;
1788 break;
Johannes Berg97359d12010-08-10 09:46:38 +02001789 case WLAN_CIPHER_SUITE_CCMP:
Christian Lampartere9348cd2009-03-21 23:05:13 +01001790 ktype = AR9170_ENC_ALG_AESCCMP;
1791 break;
1792 default:
1793 return -EOPNOTSUPP;
1794 }
1795
1796 mutex_lock(&ar->mutex);
1797 if (cmd == SET_KEY) {
1798 if (unlikely(!IS_STARTED(ar))) {
1799 err = -EOPNOTSUPP;
1800 goto out;
1801 }
1802
1803 /* group keys need all-zeroes address */
1804 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1805 sta = NULL;
1806
1807 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
1808 for (i = 0; i < 64; i++)
1809 if (!(ar->usedkeys & BIT(i)))
1810 break;
1811 if (i == 64) {
1812 ar->rx_software_decryption = true;
1813 ar9170_set_operating_mode(ar);
1814 err = -ENOSPC;
1815 goto out;
1816 }
1817 } else {
1818 i = 64 + key->keyidx;
1819 }
1820
1821 key->hw_key_idx = i;
1822
1823 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
1824 key->key, min_t(u8, 16, key->keylen));
1825 if (err)
1826 goto out;
1827
Johannes Berg97359d12010-08-10 09:46:38 +02001828 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001829 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
1830 ktype, 1, key->key + 16, 16);
1831 if (err)
1832 goto out;
1833
1834 /*
1835 * hardware is not capable generating the MMIC
1836 * for fragmented frames!
1837 */
1838 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1839 }
1840
1841 if (i < 64)
1842 ar->usedkeys |= BIT(i);
1843
1844 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1845 } else {
1846 if (unlikely(!IS_STARTED(ar))) {
1847 /* The device is gone... together with the key ;-) */
1848 err = 0;
1849 goto out;
1850 }
1851
1852 err = ar9170_disable_key(ar, key->hw_key_idx);
1853 if (err)
1854 goto out;
1855
1856 if (key->hw_key_idx < 64) {
1857 ar->usedkeys &= ~BIT(key->hw_key_idx);
1858 } else {
1859 err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
1860 AR9170_ENC_ALG_NONE, 0,
1861 NULL, 0);
1862 if (err)
1863 goto out;
1864
Johannes Berg97359d12010-08-10 09:46:38 +02001865 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001866 err = ar9170_upload_key(ar, key->hw_key_idx,
1867 NULL,
1868 AR9170_ENC_ALG_NONE, 1,
1869 NULL, 0);
1870 if (err)
1871 goto out;
1872 }
1873
1874 }
1875 }
1876
1877 ar9170_regwrite_begin(ar);
1878 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
1879 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
1880 ar9170_regwrite_finish();
1881 err = ar9170_regwrite_result();
1882
1883out:
1884 mutex_unlock(&ar->mutex);
1885
1886 return err;
1887}
1888
Christian Lampartere9348cd2009-03-21 23:05:13 +01001889static int ar9170_get_stats(struct ieee80211_hw *hw,
1890 struct ieee80211_low_level_stats *stats)
1891{
1892 struct ar9170 *ar = hw->priv;
1893 u32 val;
1894 int err;
1895
1896 mutex_lock(&ar->mutex);
1897 err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
1898 ar->stats.dot11ACKFailureCount += val;
1899
1900 memcpy(stats, &ar->stats, sizeof(*stats));
1901 mutex_unlock(&ar->mutex);
1902
1903 return 0;
1904}
1905
John W. Linvillea55427e2010-07-28 14:47:49 -04001906static int ar9170_get_survey(struct ieee80211_hw *hw, int idx,
1907 struct survey_info *survey)
1908{
1909 struct ar9170 *ar = hw->priv;
1910 struct ieee80211_conf *conf = &hw->conf;
1911
1912 if (idx != 0)
1913 return -ENOENT;
1914
1915 /* TODO: update noise value, e.g. call ar9170_set_channel */
1916
1917 survey->channel = conf->channel;
1918 survey->filled = SURVEY_INFO_NOISE_DBM;
1919 survey->noise = ar->noise[0];
1920
1921 return 0;
1922}
1923
Christian Lampartere9348cd2009-03-21 23:05:13 +01001924static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
1925 const struct ieee80211_tx_queue_params *param)
1926{
1927 struct ar9170 *ar = hw->priv;
1928 int ret;
1929
1930 mutex_lock(&ar->mutex);
Dan Carpentere9d126c2009-08-09 14:24:09 +02001931 if (queue < __AR9170_NUM_TXQ) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001932 memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
1933 param, sizeof(*param));
1934
1935 ret = ar9170_set_qos(ar);
Dan Carpentere9d126c2009-08-09 14:24:09 +02001936 } else {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001937 ret = -EINVAL;
Dan Carpentere9d126c2009-08-09 14:24:09 +02001938 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001939
1940 mutex_unlock(&ar->mutex);
1941 return ret;
1942}
1943
Johannes Berg9e52b062009-04-20 18:27:04 +02001944static int ar9170_ampdu_action(struct ieee80211_hw *hw,
Johannes Bergc951ad32009-11-16 12:00:38 +01001945 struct ieee80211_vif *vif,
Johannes Berg9e52b062009-04-20 18:27:04 +02001946 enum ieee80211_ampdu_mlme_action action,
Johannes Berg0b01f032011-01-18 13:51:05 +01001947 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
1948 u8 buf_size)
Johannes Berg9e52b062009-04-20 18:27:04 +02001949{
1950 switch (action) {
1951 case IEEE80211_AMPDU_RX_START:
1952 case IEEE80211_AMPDU_RX_STOP:
Christian Lamparteracbadf02009-07-11 17:24:14 +02001953 /* Handled by firmware */
1954 break;
1955
Johannes Berg9e52b062009-04-20 18:27:04 +02001956 default:
1957 return -EOPNOTSUPP;
1958 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02001959
1960 return 0;
Johannes Berg9e52b062009-04-20 18:27:04 +02001961}
1962
Christian Lampartere9348cd2009-03-21 23:05:13 +01001963static const struct ieee80211_ops ar9170_ops = {
1964 .start = ar9170_op_start,
1965 .stop = ar9170_op_stop,
1966 .tx = ar9170_op_tx,
1967 .add_interface = ar9170_op_add_interface,
1968 .remove_interface = ar9170_op_remove_interface,
1969 .config = ar9170_op_config,
Johannes Berg3ac64be2009-08-17 16:16:53 +02001970 .prepare_multicast = ar9170_op_prepare_multicast,
Christian Lampartere9348cd2009-03-21 23:05:13 +01001971 .configure_filter = ar9170_op_configure_filter,
1972 .conf_tx = ar9170_conf_tx,
1973 .bss_info_changed = ar9170_op_bss_info_changed,
1974 .get_tsf = ar9170_op_get_tsf,
1975 .set_key = ar9170_set_key,
Christian Lampartere9348cd2009-03-21 23:05:13 +01001976 .get_stats = ar9170_get_stats,
John W. Linvillea55427e2010-07-28 14:47:49 -04001977 .get_survey = ar9170_get_survey,
Johannes Berg9e52b062009-04-20 18:27:04 +02001978 .ampdu_action = ar9170_ampdu_action,
Christian Lampartere9348cd2009-03-21 23:05:13 +01001979};
1980
1981void *ar9170_alloc(size_t priv_size)
1982{
1983 struct ieee80211_hw *hw;
1984 struct ar9170 *ar;
Christian Lampartercca847992009-04-19 01:28:12 +02001985 struct sk_buff *skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001986 int i;
1987
Christian Lampartercca847992009-04-19 01:28:12 +02001988 /*
1989 * this buffer is used for rx stream reconstruction.
1990 * Under heavy load this device (or the transport layer?)
Daniel Mack3ad2f3f2010-02-03 08:01:28 +08001991 * tends to split the streams into separate rx descriptors.
Christian Lampartercca847992009-04-19 01:28:12 +02001992 */
1993
Christian Lamparter879999c2010-03-23 21:51:14 +01001994 skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL);
Christian Lampartercca847992009-04-19 01:28:12 +02001995 if (!skb)
1996 goto err_nomem;
1997
Christian Lampartere9348cd2009-03-21 23:05:13 +01001998 hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
1999 if (!hw)
Christian Lampartercca847992009-04-19 01:28:12 +02002000 goto err_nomem;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002001
2002 ar = hw->priv;
2003 ar->hw = hw;
Christian Lampartercca847992009-04-19 01:28:12 +02002004 ar->rx_failover = skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002005
2006 mutex_init(&ar->mutex);
2007 spin_lock_init(&ar->cmdlock);
2008 spin_lock_init(&ar->tx_stats_lock);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002009 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
2010 skb_queue_head_init(&ar->tx_status[i]);
2011 skb_queue_head_init(&ar->tx_pending[i]);
2012 }
Christian Lampartercca847992009-04-19 01:28:12 +02002013 ar9170_rx_reset_rx_mpdu(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002014 INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002015 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002016
2017 /* all hw supports 2.4 GHz, so set channel to 1 by default */
2018 ar->channel = &ar9170_2ghz_chantable[0];
2019
2020 /* first part of wiphy init */
2021 ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2022 BIT(NL80211_IFTYPE_WDS) |
2023 BIT(NL80211_IFTYPE_ADHOC);
2024 ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
2025 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
John W. Linvillef5c044e2010-04-30 15:37:00 -04002026 IEEE80211_HW_SIGNAL_DBM;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002027
Christian Lamparter4a48e2a2009-03-23 12:15:43 +01002028 ar->hw->queues = __AR9170_NUM_TXQ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002029 ar->hw->extra_tx_headroom = 8;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002030
2031 ar->hw->max_rates = 1;
2032 ar->hw->max_rate_tries = 3;
2033
2034 for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
2035 ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
2036
2037 return ar;
Christian Lampartercca847992009-04-19 01:28:12 +02002038
2039err_nomem:
2040 kfree_skb(skb);
2041 return ERR_PTR(-ENOMEM);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002042}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002043
2044static int ar9170_read_eeprom(struct ar9170 *ar)
2045{
2046#define RW 8 /* number of words to read at once */
2047#define RB (sizeof(u32) * RW)
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002048 struct ath_regulatory *regulatory = &ar->common.regulatory;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002049 u8 *eeprom = (void *)&ar->eeprom;
2050 u8 *addr = ar->eeprom.mac_address;
2051 __le32 offsets[RW];
Christian Lamparteracbadf02009-07-11 17:24:14 +02002052 unsigned int rx_streams, tx_streams, tx_params = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002053 int i, j, err, bands = 0;
2054
2055 BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
2056
2057 BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
2058#ifndef __CHECKER__
2059 /* don't want to handle trailing remains */
2060 BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
2061#endif
2062
2063 for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
2064 for (j = 0; j < RW; j++)
2065 offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
2066 RB * i + 4 * j);
2067
2068 err = ar->exec_cmd(ar, AR9170_CMD_RREG,
2069 RB, (u8 *) &offsets,
2070 RB, eeprom + RB * i);
2071 if (err)
2072 return err;
2073 }
2074
2075#undef RW
2076#undef RB
2077
2078 if (ar->eeprom.length == cpu_to_le16(0xFFFF))
2079 return -ENODATA;
2080
2081 if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
2082 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
2083 bands++;
2084 }
2085 if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
2086 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
2087 bands++;
2088 }
Christian Lamparteracbadf02009-07-11 17:24:14 +02002089
2090 rx_streams = hweight8(ar->eeprom.rx_mask);
2091 tx_streams = hweight8(ar->eeprom.tx_mask);
2092
2093 if (rx_streams != tx_streams)
2094 tx_params = IEEE80211_HT_MCS_TX_RX_DIFF;
2095
2096 if (tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS)
2097 tx_params = (tx_streams - 1) <<
2098 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
2099
2100 ar9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
2101 ar9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params;
2102
Christian Lampartere9348cd2009-03-21 23:05:13 +01002103 /*
2104 * I measured this, a bandswitch takes roughly
2105 * 135 ms and a frequency switch about 80.
2106 *
2107 * FIXME: measure these values again once EEPROM settings
2108 * are used, that will influence them!
2109 */
2110 if (bands == 2)
2111 ar->hw->channel_change_time = 135 * 1000;
2112 else
2113 ar->hw->channel_change_time = 80 * 1000;
2114
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002115 regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
2116 regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
Christian Lamparter1878f772009-03-30 22:30:32 -04002117
Christian Lampartere9348cd2009-03-21 23:05:13 +01002118 /* second part of wiphy init */
2119 SET_IEEE80211_PERM_ADDR(ar->hw, addr);
2120
2121 return bands ? 0 : -EINVAL;
2122}
2123
Christian Lamparter1878f772009-03-30 22:30:32 -04002124static int ar9170_reg_notifier(struct wiphy *wiphy,
2125 struct regulatory_request *request)
2126{
2127 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2128 struct ar9170 *ar = hw->priv;
2129
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002130 return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory);
Christian Lamparter1878f772009-03-30 22:30:32 -04002131}
2132
Christian Lampartere9348cd2009-03-21 23:05:13 +01002133int ar9170_register(struct ar9170 *ar, struct device *pdev)
2134{
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002135 struct ath_regulatory *regulatory = &ar->common.regulatory;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002136 int err;
2137
2138 /* try to read EEPROM, init MAC addr */
2139 err = ar9170_read_eeprom(ar);
2140 if (err)
2141 goto err_out;
2142
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002143 err = ath_regd_init(regulatory, ar->hw->wiphy,
Christian Lamparter1878f772009-03-30 22:30:32 -04002144 ar9170_reg_notifier);
Luis R. Rodriguez85efc862009-04-13 21:41:46 -04002145 if (err)
2146 goto err_out;
Christian Lamparter1878f772009-03-30 22:30:32 -04002147
Christian Lampartere9348cd2009-03-21 23:05:13 +01002148 err = ieee80211_register_hw(ar->hw);
2149 if (err)
2150 goto err_out;
2151
Luis R. Rodriguez608b88c2009-08-17 18:07:23 -07002152 if (!ath_is_world_regd(regulatory))
2153 regulatory_hint(ar->hw->wiphy, regulatory->alpha2);
Christian Lamparter1878f772009-03-30 22:30:32 -04002154
Christian Lampartere9348cd2009-03-21 23:05:13 +01002155 err = ar9170_init_leds(ar);
2156 if (err)
2157 goto err_unreg;
2158
2159#ifdef CONFIG_AR9170_LEDS
2160 err = ar9170_register_leds(ar);
2161 if (err)
2162 goto err_unreg;
2163#endif /* CONFIG_AR9170_LEDS */
2164
2165 dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
2166 wiphy_name(ar->hw->wiphy));
2167
Johannes Berg53576512009-12-23 13:15:30 +01002168 ar->registered = true;
2169 return 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002170
2171err_unreg:
2172 ieee80211_unregister_hw(ar->hw);
2173
2174err_out:
2175 return err;
2176}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002177
2178void ar9170_unregister(struct ar9170 *ar)
2179{
Johannes Berg53576512009-12-23 13:15:30 +01002180 if (ar->registered) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01002181#ifdef CONFIG_AR9170_LEDS
Johannes Berg53576512009-12-23 13:15:30 +01002182 ar9170_unregister_leds(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002183#endif /* CONFIG_AR9170_LEDS */
2184
2185 ieee80211_unregister_hw(ar->hw);
Johannes Berg53576512009-12-23 13:15:30 +01002186 }
2187
2188 kfree_skb(ar->rx_failover);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002189 mutex_destroy(&ar->mutex);
2190}