blob: 88c3d8573869dbfab02b3738a26fed16d38d80ee [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 Berg9e52b062009-04-20 18:27:04 +0200145#define AR9170_HT_CAP \
146{ \
147 .ht_supported = true, \
148 .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
Johannes Berg9e52b062009-04-20 18:27:04 +0200149 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
150 IEEE80211_HT_CAP_SGI_40 | \
151 IEEE80211_HT_CAP_DSSSCCK40 | \
152 IEEE80211_HT_CAP_SM_PS, \
Christian Lamparter083c4682009-04-24 21:35:57 +0200153 .ampdu_factor = 3, \
154 .ampdu_density = 6, \
Johannes Berg9e52b062009-04-20 18:27:04 +0200155 .mcs = { \
156 .rx_mask = { 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, }, \
157 }, \
158}
159
Christian Lampartere9348cd2009-03-21 23:05:13 +0100160static struct ieee80211_supported_band ar9170_band_2GHz = {
161 .channels = ar9170_2ghz_chantable,
162 .n_channels = ARRAY_SIZE(ar9170_2ghz_chantable),
163 .bitrates = ar9170_g_ratetable,
164 .n_bitrates = ar9170_g_ratetable_size,
Johannes Berg9e52b062009-04-20 18:27:04 +0200165 .ht_cap = AR9170_HT_CAP,
166};
167
168static struct ieee80211_supported_band ar9170_band_5GHz = {
169 .channels = ar9170_5ghz_chantable,
170 .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
171 .bitrates = ar9170_a_ratetable,
172 .n_bitrates = ar9170_a_ratetable_size,
173 .ht_cap = AR9170_HT_CAP,
Christian Lampartere9348cd2009-03-21 23:05:13 +0100174};
175
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200176static void ar9170_tx(struct ar9170 *ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100177
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200178#ifdef AR9170_QUEUE_DEBUG
Christian Lampartere9348cd2009-03-21 23:05:13 +0100179static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
180{
181 struct ar9170_tx_control *txc = (void *) skb->data;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200182 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
183 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
184 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100185
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200186 printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x "
187 "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
Christian Lampartere9348cd2009-03-21 23:05:13 +0100188 wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200189 ieee80211_get_DA(hdr), arinfo->flags,
190 le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
191 jiffies_to_msecs(arinfo->timeout - jiffies));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100192}
193
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200194static void __ar9170_dump_txqueue(struct ar9170 *ar,
195 struct sk_buff_head *queue)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100196{
197 struct sk_buff *skb;
198 int i = 0;
199
200 printk(KERN_DEBUG "---[ cut here ]---\n");
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200201 printk(KERN_DEBUG "%s: %d entries in queue.\n",
Christian Lampartere9348cd2009-03-21 23:05:13 +0100202 wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
203
204 skb_queue_walk(queue, skb) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200205 printk(KERN_DEBUG "index:%d => \n", i++);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100206 ar9170_print_txheader(ar, skb);
207 }
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200208 if (i != skb_queue_len(queue))
209 printk(KERN_DEBUG "WARNING: queue frame counter "
210 "mismatch %d != %d\n", skb_queue_len(queue), i);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100211 printk(KERN_DEBUG "---[ end ]---\n");
212}
Christian Lampartere9348cd2009-03-21 23:05:13 +0100213
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200214static void ar9170_dump_txqueue(struct ar9170 *ar,
215 struct sk_buff_head *queue)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100216{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200217 unsigned long flags;
218
219 spin_lock_irqsave(&queue->lock, flags);
220 __ar9170_dump_txqueue(ar, queue);
221 spin_unlock_irqrestore(&queue->lock, flags);
222}
223
224static void __ar9170_dump_txstats(struct ar9170 *ar)
225{
226 int i;
227
228 printk(KERN_DEBUG "%s: QoS queue stats\n",
229 wiphy_name(ar->hw->wiphy));
230
231 for (i = 0; i < __AR9170_NUM_TXQ; i++)
232 printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d\n",
233 wiphy_name(ar->hw->wiphy), i, ar->tx_stats[i].limit,
234 ar->tx_stats[i].len, skb_queue_len(&ar->tx_status[i]));
235}
236
237static void ar9170_dump_txstats(struct ar9170 *ar)
238{
Christian Lampartere9348cd2009-03-21 23:05:13 +0100239 unsigned long flags;
240
241 spin_lock_irqsave(&ar->tx_stats_lock, flags);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200242 __ar9170_dump_txstats(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100243 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200244}
245#endif /* AR9170_QUEUE_DEBUG */
246
247/* caller must guarantee exclusive access for _bin_ queue. */
248static void ar9170_recycle_expired(struct ar9170 *ar,
249 struct sk_buff_head *queue,
250 struct sk_buff_head *bin)
251{
252 struct sk_buff *skb, *old = NULL;
253 unsigned long flags;
254
255 spin_lock_irqsave(&queue->lock, flags);
256 while ((skb = skb_peek(queue))) {
257 struct ieee80211_tx_info *txinfo;
258 struct ar9170_tx_info *arinfo;
259
260 txinfo = IEEE80211_SKB_CB(skb);
261 arinfo = (void *) txinfo->rate_driver_data;
262
263 if (time_is_before_jiffies(arinfo->timeout)) {
264#ifdef AR9170_QUEUE_DEBUG
265 printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => "
266 "recycle \n", wiphy_name(ar->hw->wiphy),
267 jiffies, arinfo->timeout);
268 ar9170_print_txheader(ar, skb);
269#endif /* AR9170_QUEUE_DEBUG */
270 __skb_unlink(skb, queue);
271 __skb_queue_tail(bin, skb);
272 } else {
273 break;
274 }
275
276 if (unlikely(old == skb)) {
277 /* bail out - queue is shot. */
278
279 WARN_ON(1);
280 break;
281 }
282 old = skb;
283 }
284 spin_unlock_irqrestore(&queue->lock, flags);
285}
286
287static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
288 u16 tx_status)
289{
290 struct ieee80211_tx_info *txinfo;
291 unsigned int retries = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100292
293 txinfo = IEEE80211_SKB_CB(skb);
294 ieee80211_tx_info_clear_status(txinfo);
295
296 switch (tx_status) {
297 case AR9170_TX_STATUS_RETRY:
298 retries = 2;
299 case AR9170_TX_STATUS_COMPLETE:
300 txinfo->flags |= IEEE80211_TX_STAT_ACK;
301 break;
302
303 case AR9170_TX_STATUS_FAILED:
304 retries = ar->hw->conf.long_frame_max_tx_count;
305 break;
306
307 default:
308 printk(KERN_ERR "%s: invalid tx_status response (%x).\n",
309 wiphy_name(ar->hw->wiphy), tx_status);
310 break;
311 }
312
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200313 txinfo->status.rates[0].count = retries + 1;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100314 skb_pull(skb, sizeof(struct ar9170_tx_control));
315 ieee80211_tx_status_irqsafe(ar->hw, skb);
316}
Christian Lampartere9348cd2009-03-21 23:05:13 +0100317
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200318void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100319{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200320 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
321 struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data;
322 unsigned int queue = skb_get_queue_mapping(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100323 unsigned long flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100324
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200325 spin_lock_irqsave(&ar->tx_stats_lock, flags);
326 ar->tx_stats[queue].len--;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100327
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200328 if (skb_queue_empty(&ar->tx_pending[queue])) {
329#ifdef AR9170_QUEUE_STOP_DEBUG
330 printk(KERN_DEBUG "%s: wake queue %d\n",
331 wiphy_name(ar->hw->wiphy), queue);
332 __ar9170_dump_txstats(ar);
333#endif /* AR9170_QUEUE_STOP_DEBUG */
334 ieee80211_wake_queue(ar->hw, queue);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100335 }
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200336 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
337
338 if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) {
339 dev_kfree_skb_any(skb);
340 } else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) {
341 arinfo->timeout = jiffies +
342 msecs_to_jiffies(AR9170_TX_TIMEOUT);
343
344 skb_queue_tail(&ar->tx_status[queue], skb);
345 } else if (arinfo->flags & AR9170_TX_FLAG_NO_ACK) {
346 ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED);
347 } else {
348#ifdef AR9170_QUEUE_DEBUG
349 printk(KERN_DEBUG "%s: unsupported frame flags!\n",
350 wiphy_name(ar->hw->wiphy));
351 ar9170_print_txheader(ar, skb);
352#endif /* AR9170_QUEUE_DEBUG */
353 dev_kfree_skb_any(skb);
354 }
355
356 if (!ar->tx_stats[queue].len &&
357 !skb_queue_empty(&ar->tx_pending[queue])) {
358 ar9170_tx(ar);
359 }
Christian Lampartere9348cd2009-03-21 23:05:13 +0100360}
361
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200362static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
363 const u8 *mac,
364 struct sk_buff_head *queue,
365 const u32 rate)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100366{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200367 unsigned long flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100368 struct sk_buff *skb;
369
370 /*
371 * Unfortunately, the firmware does not tell to which (queued) frame
372 * this transmission status report belongs to.
373 *
374 * So we have to make risky guesses - with the scarce information
375 * the firmware provided (-> destination MAC, and phy_control) -
376 * and hope that we picked the right one...
377 */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100378
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200379 spin_lock_irqsave(&queue->lock, flags);
380 skb_queue_walk(queue, skb) {
381 struct ar9170_tx_control *txc = (void *) skb->data;
382 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
383 u32 r;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100384
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200385 if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) {
386#ifdef AR9170_QUEUE_DEBUG
387 printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n",
388 wiphy_name(ar->hw->wiphy), mac,
389 ieee80211_get_DA(hdr));
390 ar9170_print_txheader(ar, skb);
391#endif /* AR9170_QUEUE_DEBUG */
392 continue;
393 }
394
395 r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >>
396 AR9170_TX_PHY_MCS_SHIFT;
397
398 if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) {
399#ifdef AR9170_QUEUE_DEBUG
400 printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n",
401 wiphy_name(ar->hw->wiphy), rate, r);
402 ar9170_print_txheader(ar, skb);
403#endif /* AR9170_QUEUE_DEBUG */
404 continue;
405 }
406
407 __skb_unlink(skb, queue);
408 spin_unlock_irqrestore(&queue->lock, flags);
409 return skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100410 }
Christian Lampartere9348cd2009-03-21 23:05:13 +0100411
412#ifdef AR9170_QUEUE_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200413 printk(KERN_ERR "%s: ESS:[%pM] does not have any "
414 "outstanding frames in queue.\n",
415 wiphy_name(ar->hw->wiphy), mac);
416 __ar9170_dump_txqueue(ar, queue);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100417#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200418 spin_unlock_irqrestore(&queue->lock, flags);
419
420 return NULL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100421}
422
423/*
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200424 * This worker tries to keeps an maintain tx_status queues.
425 * So we can guarantee that incoming tx_status reports are
426 * actually for a pending frame.
Christian Lampartere9348cd2009-03-21 23:05:13 +0100427 */
428
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200429static void ar9170_tx_janitor(struct work_struct *work)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100430{
431 struct ar9170 *ar = container_of(work, struct ar9170,
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200432 tx_janitor.work);
433 struct sk_buff_head waste;
434 unsigned int i;
435 bool resched = false;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100436
Christian Lamparter4a48e2a2009-03-23 12:15:43 +0100437 if (unlikely(!IS_STARTED(ar)))
438 return ;
439
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200440 skb_queue_head_init(&waste);
441
442 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
Christian Lampartere9348cd2009-03-21 23:05:13 +0100443#ifdef AR9170_QUEUE_DEBUG
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200444 printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n",
445 wiphy_name(ar->hw->wiphy), i);
446 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
447 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100448#endif /* AR9170_QUEUE_DEBUG */
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200449
450 ar9170_recycle_expired(ar, &ar->tx_status[i], &waste);
451 ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste);
452 skb_queue_purge(&waste);
453
454 if (!skb_queue_empty(&ar->tx_status[i]) ||
455 !skb_queue_empty(&ar->tx_pending[i]))
456 resched = true;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100457 }
458
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200459 if (resched)
460 queue_delayed_work(ar->hw->workqueue,
461 &ar->tx_janitor,
462 msecs_to_jiffies(AR9170_JANITOR_DELAY));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100463}
464
Christian Lamparter66d00812009-05-28 17:04:27 +0200465void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100466{
467 struct ar9170_cmd_response *cmd = (void *) buf;
468
469 if ((cmd->type & 0xc0) != 0xc0) {
470 ar->callback_cmd(ar, len, buf);
471 return;
472 }
473
474 /* hardware event handlers */
475 switch (cmd->type) {
476 case 0xc1: {
477 /*
478 * TX status notification:
479 * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
480 *
481 * XX always 81
482 * YY always 00
483 * M1-M6 is the MAC address
484 * R1-R4 is the transmit rate
485 * S1-S2 is the transmit status
486 */
487
488 struct sk_buff *skb;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200489 u32 phy = le32_to_cpu(cmd->tx_status.rate);
490 u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >>
491 AR9170_TX_PHY_QOS_SHIFT;
492#ifdef AR9170_QUEUE_DEBUG
493 printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n",
494 wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q);
495#endif /* AR9170_QUEUE_DEBUG */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100496
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200497 skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst,
498 &ar->tx_status[q],
499 AR9170_TX_INVALID_RATE);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100500 if (unlikely(!skb))
501 return ;
502
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200503 ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status));
Christian Lampartere9348cd2009-03-21 23:05:13 +0100504 break;
505 }
506
507 case 0xc0:
508 /*
509 * pre-TBTT event
510 */
511 if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
512 queue_work(ar->hw->workqueue, &ar->beacon_work);
513 break;
514
515 case 0xc2:
516 /*
517 * (IBSS) beacon send notification
518 * bytes: 04 c2 XX YY B4 B3 B2 B1
519 *
520 * XX always 80
521 * YY always 00
522 * B1-B4 "should" be the number of send out beacons.
523 */
524 break;
525
526 case 0xc3:
527 /* End of Atim Window */
528 break;
529
530 case 0xc4:
531 case 0xc5:
532 /* BlockACK events */
533 break;
534
535 case 0xc6:
536 /* Watchdog Interrupt */
537 break;
538
539 case 0xc9:
540 /* retransmission issue / SIFS/EIFS collision ?! */
541 break;
542
Johannes Berg2543a0c2009-06-05 11:47:43 +0200543 /* firmware debug */
544 case 0xca:
545 printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, (char *)buf + 4);
546 break;
547 case 0xcb:
548 len -= 4;
549
550 switch (len) {
551 case 1:
552 printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n",
553 *((char *)buf + 4));
554 break;
555 case 2:
556 printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n",
557 le16_to_cpup((__le16 *)((char *)buf + 4)));
558 break;
559 case 4:
560 printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n",
561 le32_to_cpup((__le32 *)((char *)buf + 4)));
562 break;
563 case 8:
564 printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n",
565 (unsigned long)le64_to_cpup(
566 (__le64 *)((char *)buf + 4)));
567 break;
568 }
569 break;
570 case 0xcc:
571 print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE,
572 (char *)buf + 4, len - 4);
573 break;
574
Christian Lampartere9348cd2009-03-21 23:05:13 +0100575 default:
576 printk(KERN_INFO "received unhandled event %x\n", cmd->type);
577 print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
578 break;
579 }
580}
581
Christian Lampartercca847992009-04-19 01:28:12 +0200582static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar)
Christian Lampartere9348cd2009-03-21 23:05:13 +0100583{
Christian Lampartercca847992009-04-19 01:28:12 +0200584 memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head));
585 ar->rx_mpdu.has_plcp = false;
586}
Christian Lampartere9348cd2009-03-21 23:05:13 +0100587
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200588int ar9170_nag_limiter(struct ar9170 *ar)
Christian Lampartercca847992009-04-19 01:28:12 +0200589{
590 bool print_message;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100591
Christian Lampartercca847992009-04-19 01:28:12 +0200592 /*
593 * we expect all sorts of errors in promiscuous mode.
594 * don't bother with it, it's OK!
595 */
596 if (ar->sniffer_enabled)
597 return false;
598
599 /*
600 * only go for frequent errors! The hardware tends to
601 * do some stupid thing once in a while under load, in
602 * noisy environments or just for fun!
603 */
604 if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit())
605 print_message = true;
606 else
607 print_message = false;
608
609 /* reset threshold for "once in a while" */
610 ar->bad_hw_nagger = jiffies + HZ / 4;
611 return print_message;
612}
613
614static int ar9170_rx_mac_status(struct ar9170 *ar,
615 struct ar9170_rx_head *head,
616 struct ar9170_rx_macstatus *mac,
617 struct ieee80211_rx_status *status)
618{
619 u8 error, decrypt;
620
Christian Lampartere9348cd2009-03-21 23:05:13 +0100621 BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
Christian Lampartercca847992009-04-19 01:28:12 +0200622 BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100623
Christian Lampartercca847992009-04-19 01:28:12 +0200624 error = mac->error;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100625 if (error & AR9170_RX_ERROR_MMIC) {
Christian Lampartercca847992009-04-19 01:28:12 +0200626 status->flag |= RX_FLAG_MMIC_ERROR;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100627 error &= ~AR9170_RX_ERROR_MMIC;
628 }
629
630 if (error & AR9170_RX_ERROR_PLCP) {
Christian Lampartercca847992009-04-19 01:28:12 +0200631 status->flag |= RX_FLAG_FAILED_PLCP_CRC;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100632 error &= ~AR9170_RX_ERROR_PLCP;
Christian Lampartercca847992009-04-19 01:28:12 +0200633
634 if (!(ar->filter_state & FIF_PLCPFAIL))
635 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100636 }
637
638 if (error & AR9170_RX_ERROR_FCS) {
Christian Lampartercca847992009-04-19 01:28:12 +0200639 status->flag |= RX_FLAG_FAILED_FCS_CRC;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100640 error &= ~AR9170_RX_ERROR_FCS;
Christian Lampartercca847992009-04-19 01:28:12 +0200641
642 if (!(ar->filter_state & FIF_FCSFAIL))
643 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100644 }
645
Christian Lampartercca847992009-04-19 01:28:12 +0200646 decrypt = ar9170_get_decrypt_type(mac);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100647 if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
648 decrypt != AR9170_ENC_ALG_NONE)
Christian Lampartercca847992009-04-19 01:28:12 +0200649 status->flag |= RX_FLAG_DECRYPTED;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100650
651 /* ignore wrong RA errors */
652 error &= ~AR9170_RX_ERROR_WRONG_RA;
653
654 if (error & AR9170_RX_ERROR_DECRYPT) {
655 error &= ~AR9170_RX_ERROR_DECRYPT;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100656 /*
657 * Rx decryption is done in place,
658 * the original data is lost anyway.
659 */
Christian Lampartercca847992009-04-19 01:28:12 +0200660
661 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100662 }
663
664 /* drop any other error frames */
Christian Lampartercca847992009-04-19 01:28:12 +0200665 if (unlikely(error)) {
666 /* TODO: update netdevice's RX dropped/errors statistics */
667
668 if (ar9170_nag_limiter(ar))
669 printk(KERN_DEBUG "%s: received frame with "
670 "suspicious error code (%#x).\n",
671 wiphy_name(ar->hw->wiphy), error);
672
673 return -EINVAL;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100674 }
675
Christian Lampartercca847992009-04-19 01:28:12 +0200676 status->band = ar->channel->band;
677 status->freq = ar->channel->center_freq;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100678
Christian Lampartercca847992009-04-19 01:28:12 +0200679 switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) {
680 case AR9170_RX_STATUS_MODULATION_CCK:
681 if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
682 status->flag |= RX_FLAG_SHORTPRE;
683 switch (head->plcp[0]) {
684 case 0x0a:
685 status->rate_idx = 0;
686 break;
687 case 0x14:
688 status->rate_idx = 1;
689 break;
690 case 0x37:
691 status->rate_idx = 2;
692 break;
693 case 0x6e:
694 status->rate_idx = 3;
695 break;
696 default:
697 if (ar9170_nag_limiter(ar))
698 printk(KERN_ERR "%s: invalid plcp cck rate "
699 "(%x).\n", wiphy_name(ar->hw->wiphy),
700 head->plcp[0]);
701 return -EINVAL;
702 }
703 break;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100704
Christian Lampartercca847992009-04-19 01:28:12 +0200705 case AR9170_RX_STATUS_MODULATION_OFDM:
706 switch (head->plcp[0] & 0xf) {
707 case 0xb:
708 status->rate_idx = 0;
709 break;
710 case 0xf:
711 status->rate_idx = 1;
712 break;
713 case 0xa:
714 status->rate_idx = 2;
715 break;
716 case 0xe:
717 status->rate_idx = 3;
718 break;
719 case 0x9:
720 status->rate_idx = 4;
721 break;
722 case 0xd:
723 status->rate_idx = 5;
724 break;
725 case 0x8:
726 status->rate_idx = 6;
727 break;
728 case 0xc:
729 status->rate_idx = 7;
730 break;
731 default:
732 if (ar9170_nag_limiter(ar))
733 printk(KERN_ERR "%s: invalid plcp ofdm rate "
734 "(%x).\n", wiphy_name(ar->hw->wiphy),
735 head->plcp[0]);
736 return -EINVAL;
737 }
738 if (status->band == IEEE80211_BAND_2GHZ)
739 status->rate_idx += 4;
740 break;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100741
Christian Lampartercca847992009-04-19 01:28:12 +0200742 case AR9170_RX_STATUS_MODULATION_HT:
743 if (head->plcp[3] & 0x80)
744 status->flag |= RX_FLAG_40MHZ;
745 if (head->plcp[6] & 0x80)
746 status->flag |= RX_FLAG_SHORT_GI;
747
748 status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f);
749 status->flag |= RX_FLAG_HT;
750 break;
751
752 case AR9170_RX_STATUS_MODULATION_DUPOFDM:
753 /* XXX */
754 if (ar9170_nag_limiter(ar))
755 printk(KERN_ERR "%s: invalid modulation\n",
756 wiphy_name(ar->hw->wiphy));
757 return -EINVAL;
758 }
759
760 return 0;
761}
762
763static void ar9170_rx_phy_status(struct ar9170 *ar,
764 struct ar9170_rx_phystatus *phy,
765 struct ieee80211_rx_status *status)
766{
767 int i;
768
769 BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20);
770
771 for (i = 0; i < 3; i++)
772 if (phy->rssi[i] != 0x80)
773 status->antenna |= BIT(i);
774
775 /* post-process RSSI */
776 for (i = 0; i < 7; i++)
777 if (phy->rssi[i] & 0x80)
778 phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f;
779
780 /* TODO: we could do something with phy_errors */
781 status->signal = ar->noise[0] + phy->rssi_combined;
782 status->noise = ar->noise[0];
783}
784
785static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len)
786{
787 struct sk_buff *skb;
788 int reserved = 0;
789 struct ieee80211_hdr *hdr = (void *) buf;
790
791 if (ieee80211_is_data_qos(hdr->frame_control)) {
792 u8 *qc = ieee80211_get_qos_ctl(hdr);
793 reserved += NET_IP_ALIGN;
794
795 if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
796 reserved += NET_IP_ALIGN;
797 }
798
799 if (ieee80211_has_a4(hdr->frame_control))
800 reserved += NET_IP_ALIGN;
801
802 reserved = 32 + (reserved & NET_IP_ALIGN);
803
804 skb = dev_alloc_skb(len + reserved);
805 if (likely(skb)) {
806 skb_reserve(skb, reserved);
807 memcpy(skb_put(skb, len), buf, len);
808 }
809
810 return skb;
811}
812
813/*
814 * If the frame alignment is right (or the kernel has
815 * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
816 * is only a single MPDU in the USB frame, then we could
817 * submit to mac80211 the SKB directly. However, since
818 * there may be multiple packets in one SKB in stream
819 * mode, and we need to observe the proper ordering,
820 * this is non-trivial.
821 */
822
823static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
824{
825 struct ar9170_rx_head *head;
826 struct ar9170_rx_macstatus *mac;
827 struct ar9170_rx_phystatus *phy = NULL;
828 struct ieee80211_rx_status status;
829 struct sk_buff *skb;
830 int mpdu_len;
831
832 if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac))))
833 return ;
834
835 /* Received MPDU */
836 mpdu_len = len - sizeof(*mac);
837
838 mac = (void *)(buf + mpdu_len);
839 if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
840 /* this frame is too damaged and can't be used - drop it */
841
842 return ;
843 }
844
845 switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) {
846 case AR9170_RX_STATUS_MPDU_FIRST:
847 /* first mpdu packet has the plcp header */
848 if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
849 head = (void *) buf;
850 memcpy(&ar->rx_mpdu.plcp, (void *) buf,
851 sizeof(struct ar9170_rx_head));
852
853 mpdu_len -= sizeof(struct ar9170_rx_head);
854 buf += sizeof(struct ar9170_rx_head);
855 ar->rx_mpdu.has_plcp = true;
856 } else {
857 if (ar9170_nag_limiter(ar))
858 printk(KERN_ERR "%s: plcp info is clipped.\n",
859 wiphy_name(ar->hw->wiphy));
860 return ;
861 }
862 break;
863
864 case AR9170_RX_STATUS_MPDU_LAST:
865 /* last mpdu has a extra tail with phy status information */
866
867 if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
868 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
869 phy = (void *)(buf + mpdu_len);
870 } else {
871 if (ar9170_nag_limiter(ar))
872 printk(KERN_ERR "%s: frame tail is clipped.\n",
873 wiphy_name(ar->hw->wiphy));
874 return ;
875 }
876
877 case AR9170_RX_STATUS_MPDU_MIDDLE:
878 /* middle mpdus are just data */
879 if (unlikely(!ar->rx_mpdu.has_plcp)) {
880 if (!ar9170_nag_limiter(ar))
881 return ;
882
883 printk(KERN_ERR "%s: rx stream did not start "
884 "with a first_mpdu frame tag.\n",
885 wiphy_name(ar->hw->wiphy));
886
887 return ;
888 }
889
890 head = &ar->rx_mpdu.plcp;
891 break;
892
893 case AR9170_RX_STATUS_MPDU_SINGLE:
894 /* single mpdu - has plcp (head) and phy status (tail) */
895 head = (void *) buf;
896
897 mpdu_len -= sizeof(struct ar9170_rx_head);
898 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
899
900 buf += sizeof(struct ar9170_rx_head);
901 phy = (void *)(buf + mpdu_len);
902 break;
903
904 default:
905 BUG_ON(1);
906 break;
907 }
908
909 if (unlikely(mpdu_len < FCS_LEN))
910 return ;
911
912 memset(&status, 0, sizeof(status));
913 if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status)))
914 return ;
915
916 if (phy)
917 ar9170_rx_phy_status(ar, phy, &status);
918
919 skb = ar9170_rx_copy_data(buf, mpdu_len);
920 if (likely(skb))
921 ieee80211_rx_irqsafe(ar->hw, skb, &status);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100922}
923
Christian Lampartere9348cd2009-03-21 23:05:13 +0100924void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
925{
Christian Lampartercca847992009-04-19 01:28:12 +0200926 unsigned int i, tlen, resplen, wlen = 0, clen = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +0100927 u8 *tbuf, *respbuf;
928
929 tbuf = skb->data;
930 tlen = skb->len;
931
932 while (tlen >= 4) {
Christian Lampartercca847992009-04-19 01:28:12 +0200933 clen = tbuf[1] << 8 | tbuf[0];
934 wlen = ALIGN(clen, 4);
Christian Lampartere9348cd2009-03-21 23:05:13 +0100935
Christian Lampartercca847992009-04-19 01:28:12 +0200936 /* check if this is stream has a valid tag.*/
Christian Lampartere9348cd2009-03-21 23:05:13 +0100937 if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
Christian Lampartercca847992009-04-19 01:28:12 +0200938 /*
939 * TODO: handle the highly unlikely event that the
940 * corrupted stream has the TAG at the right position.
941 */
942
943 /* check if the frame can be repaired. */
944 if (!ar->rx_failover_missing) {
945 /* this is no "short read". */
946 if (ar9170_nag_limiter(ar)) {
947 printk(KERN_ERR "%s: missing tag!\n",
948 wiphy_name(ar->hw->wiphy));
949 goto err_telluser;
950 } else
951 goto err_silent;
952 }
953
954 if (ar->rx_failover_missing > tlen) {
955 if (ar9170_nag_limiter(ar)) {
956 printk(KERN_ERR "%s: possible multi "
957 "stream corruption!\n",
958 wiphy_name(ar->hw->wiphy));
959 goto err_telluser;
960 } else
961 goto err_silent;
962 }
963
964 memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
965 ar->rx_failover_missing -= tlen;
966
967 if (ar->rx_failover_missing <= 0) {
968 /*
969 * nested ar9170_rx call!
970 * termination is guranteed, even when the
971 * combined frame also have a element with
972 * a bad tag.
973 */
974
975 ar->rx_failover_missing = 0;
976 ar9170_rx(ar, ar->rx_failover);
977
978 skb_reset_tail_pointer(ar->rx_failover);
979 skb_trim(ar->rx_failover, 0);
980 }
981
Christian Lampartere9348cd2009-03-21 23:05:13 +0100982 return ;
983 }
Christian Lampartercca847992009-04-19 01:28:12 +0200984
985 /* check if stream is clipped */
Christian Lampartere9348cd2009-03-21 23:05:13 +0100986 if (wlen > tlen - 4) {
Christian Lampartercca847992009-04-19 01:28:12 +0200987 if (ar->rx_failover_missing) {
988 /* TODO: handle double stream corruption. */
989 if (ar9170_nag_limiter(ar)) {
990 printk(KERN_ERR "%s: double rx stream "
991 "corruption!\n",
992 wiphy_name(ar->hw->wiphy));
993 goto err_telluser;
994 } else
995 goto err_silent;
996 }
997
998 /*
999 * save incomplete data set.
1000 * the firmware will resend the missing bits when
1001 * the rx - descriptor comes round again.
1002 */
1003
1004 memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
1005 ar->rx_failover_missing = clen - tlen;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001006 return ;
1007 }
1008 resplen = clen;
1009 respbuf = tbuf + 4;
1010 tbuf += wlen + 4;
1011 tlen -= wlen + 4;
1012
1013 i = 0;
1014
1015 /* weird thing, but this is the same in the original driver */
1016 while (resplen > 2 && i < 12 &&
1017 respbuf[0] == 0xff && respbuf[1] == 0xff) {
1018 i += 2;
1019 resplen -= 2;
1020 respbuf += 2;
1021 }
1022
1023 if (resplen < 4)
1024 continue;
1025
1026 /* found the 6 * 0xffff marker? */
1027 if (i == 12)
1028 ar9170_handle_command_response(ar, respbuf, resplen);
1029 else
Christian Lampartercca847992009-04-19 01:28:12 +02001030 ar9170_handle_mpdu(ar, respbuf, clen);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001031 }
1032
Christian Lampartercca847992009-04-19 01:28:12 +02001033 if (tlen) {
1034 if (net_ratelimit())
1035 printk(KERN_ERR "%s: %d bytes of unprocessed "
1036 "data left in rx stream!\n",
1037 wiphy_name(ar->hw->wiphy), tlen);
1038
1039 goto err_telluser;
1040 }
1041
1042 return ;
1043
1044err_telluser:
1045 printk(KERN_ERR "%s: damaged RX stream data [want:%d, "
1046 "data:%d, rx:%d, pending:%d ]\n",
1047 wiphy_name(ar->hw->wiphy), clen, wlen, tlen,
1048 ar->rx_failover_missing);
1049
1050 if (ar->rx_failover_missing)
1051 print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
1052 ar->rx_failover->data,
1053 ar->rx_failover->len);
1054
1055 print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
1056 skb->data, skb->len);
1057
1058 printk(KERN_ERR "%s: please check your hardware and cables, if "
1059 "you see this message frequently.\n",
1060 wiphy_name(ar->hw->wiphy));
1061
1062err_silent:
1063 if (ar->rx_failover_missing) {
1064 skb_reset_tail_pointer(ar->rx_failover);
1065 skb_trim(ar->rx_failover, 0);
1066 ar->rx_failover_missing = 0;
1067 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001068}
Christian Lampartere9348cd2009-03-21 23:05:13 +01001069
1070#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \
1071do { \
1072 queue.aifs = ai_fs; \
1073 queue.cw_min = cwmin; \
1074 queue.cw_max = cwmax; \
1075 queue.txop = _txop; \
1076} while (0)
1077
1078static int ar9170_op_start(struct ieee80211_hw *hw)
1079{
1080 struct ar9170 *ar = hw->priv;
1081 int err, i;
1082
1083 mutex_lock(&ar->mutex);
1084
Christian Lamparter864cc022009-05-23 20:28:21 +02001085 ar->filter_changed = 0;
1086
Christian Lampartere9348cd2009-03-21 23:05:13 +01001087 /* reinitialize queues statistics */
1088 memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001089 for (i = 0; i < __AR9170_NUM_TXQ; i++)
1090 ar->tx_stats[i].limit = AR9170_TXQ_DEPTH;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001091
1092 /* reset QoS defaults */
1093 AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/
1094 AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023, 0); /* BACKGROUND */
1095 AR9170_FILL_QUEUE(ar->edcf[2], 2, 7, 15, 94); /* VIDEO */
1096 AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */
1097 AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
1098
Christian Lampartercca847992009-04-19 01:28:12 +02001099 ar->bad_hw_nagger = jiffies;
1100
Christian Lampartere9348cd2009-03-21 23:05:13 +01001101 err = ar->open(ar);
1102 if (err)
1103 goto out;
1104
1105 err = ar9170_init_mac(ar);
1106 if (err)
1107 goto out;
1108
1109 err = ar9170_set_qos(ar);
1110 if (err)
1111 goto out;
1112
1113 err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
1114 if (err)
1115 goto out;
1116
1117 err = ar9170_init_rf(ar);
1118 if (err)
1119 goto out;
1120
1121 /* start DMA */
1122 err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
1123 if (err)
1124 goto out;
1125
1126 ar->state = AR9170_STARTED;
1127
1128out:
1129 mutex_unlock(&ar->mutex);
1130 return err;
1131}
1132
1133static void ar9170_op_stop(struct ieee80211_hw *hw)
1134{
1135 struct ar9170 *ar = hw->priv;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001136 unsigned int i;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001137
1138 if (IS_STARTED(ar))
1139 ar->state = AR9170_IDLE;
1140
Christian Lamparter32c16282009-03-28 01:46:14 +01001141 flush_workqueue(ar->hw->workqueue);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001142
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001143 cancel_delayed_work_sync(&ar->tx_janitor);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001144 cancel_work_sync(&ar->filter_config_work);
1145 cancel_work_sync(&ar->beacon_work);
Christian Lamparterb55d6bc2009-05-23 20:31:21 +02001146 mutex_lock(&ar->mutex);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001147
1148 if (IS_ACCEPTING_CMD(ar)) {
1149 ar9170_set_leds_state(ar, 0);
1150
1151 /* stop DMA */
1152 ar9170_write_reg(ar, 0x1c3d30, 0);
1153 ar->stop(ar);
1154 }
1155
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001156 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1157 skb_queue_purge(&ar->tx_pending[i]);
1158 skb_queue_purge(&ar->tx_status[i]);
1159 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001160 mutex_unlock(&ar->mutex);
1161}
1162
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001163static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001164{
Christian Lampartere9348cd2009-03-21 23:05:13 +01001165 struct ieee80211_hdr *hdr;
1166 struct ar9170_tx_control *txc;
1167 struct ieee80211_tx_info *info;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001168 struct ieee80211_tx_rate *txrate;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001169 struct ar9170_tx_info *arinfo;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001170 unsigned int queue = skb_get_queue_mapping(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001171 u16 keytype = 0;
1172 u16 len, icv = 0;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001173
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001174 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001175
1176 hdr = (void *)skb->data;
1177 info = IEEE80211_SKB_CB(skb);
1178 len = skb->len;
1179
Christian Lampartere9348cd2009-03-21 23:05:13 +01001180 txc = (void *)skb_push(skb, sizeof(*txc));
1181
Christian Lampartere9348cd2009-03-21 23:05:13 +01001182 if (info->control.hw_key) {
1183 icv = info->control.hw_key->icv_len;
1184
1185 switch (info->control.hw_key->alg) {
1186 case ALG_WEP:
1187 keytype = AR9170_TX_MAC_ENCR_RC4;
1188 break;
1189 case ALG_TKIP:
1190 keytype = AR9170_TX_MAC_ENCR_RC4;
1191 break;
1192 case ALG_CCMP:
1193 keytype = AR9170_TX_MAC_ENCR_AES;
1194 break;
1195 default:
1196 WARN_ON(1);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001197 goto err_out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001198 }
1199 }
1200
1201 /* Length */
1202 txc->length = cpu_to_le16(len + icv + 4);
1203
1204 txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
1205 AR9170_TX_MAC_BACKOFF);
1206 txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
1207 AR9170_TX_MAC_QOS_SHIFT);
1208 txc->mac_control |= cpu_to_le16(keytype);
1209 txc->phy_control = cpu_to_le32(0);
1210
1211 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
1212 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
1213
Christian Lampartere9348cd2009-03-21 23:05:13 +01001214 txrate = &info->control.rates[0];
Christian Lampartere9348cd2009-03-21 23:05:13 +01001215 if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1216 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
1217 else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1218 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
1219
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001220 arinfo = (void *)info->rate_driver_data;
1221 arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT);
1222
1223 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
1224 (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
1225 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1226 if (unlikely(!info->control.sta))
1227 goto err_out;
1228
1229 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
1230 arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK;
1231 goto out;
1232 }
1233
1234 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
1235 /*
1236 * WARNING:
1237 * Putting the QoS queue bits into an unexplored territory is
1238 * certainly not elegant.
1239 *
1240 * In my defense: This idea provides a reasonable way to
1241 * smuggle valuable information to the tx_status callback.
1242 * Also, the idea behind this bit-abuse came straight from
1243 * the original driver code.
1244 */
1245
1246 txc->phy_control |=
1247 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
1248 arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK;
1249 } else {
1250 arinfo->flags = AR9170_TX_FLAG_NO_ACK;
1251 }
1252
1253out:
1254 return 0;
1255
1256err_out:
1257 skb_pull(skb, sizeof(*txc));
1258 return -EINVAL;
1259}
1260
1261static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
1262{
1263 struct ar9170_tx_control *txc;
1264 struct ieee80211_tx_info *info;
1265 struct ieee80211_rate *rate = NULL;
1266 struct ieee80211_tx_rate *txrate;
1267 u32 power, chains;
1268
1269 txc = (void *) skb->data;
1270 info = IEEE80211_SKB_CB(skb);
1271 txrate = &info->control.rates[0];
1272
Christian Lampartere9348cd2009-03-21 23:05:13 +01001273 if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
1274 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
1275
1276 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1277 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
1278
1279 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1280 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
1281 /* this works because 40 MHz is 2 and dup is 3 */
1282 if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
1283 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
1284
1285 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
1286 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
1287
1288 if (txrate->flags & IEEE80211_TX_RC_MCS) {
1289 u32 r = txrate->idx;
1290 u8 *txpower;
1291
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001292 /* heavy clip control */
1293 txc->phy_control |= cpu_to_le32((r & 0x7) << 7);
1294
Christian Lampartere9348cd2009-03-21 23:05:13 +01001295 r <<= AR9170_TX_PHY_MCS_SHIFT;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001296 BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK);
1297
Christian Lampartere9348cd2009-03-21 23:05:13 +01001298 txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
1299 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
1300
1301 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1302 if (info->band == IEEE80211_BAND_5GHZ)
1303 txpower = ar->power_5G_ht40;
1304 else
1305 txpower = ar->power_2G_ht40;
1306 } else {
1307 if (info->band == IEEE80211_BAND_5GHZ)
1308 txpower = ar->power_5G_ht20;
1309 else
1310 txpower = ar->power_2G_ht20;
1311 }
1312
1313 power = txpower[(txrate->idx) & 7];
1314 } else {
1315 u8 *txpower;
1316 u32 mod;
1317 u32 phyrate;
1318 u8 idx = txrate->idx;
1319
1320 if (info->band != IEEE80211_BAND_2GHZ) {
1321 idx += 4;
1322 txpower = ar->power_5G_leg;
1323 mod = AR9170_TX_PHY_MOD_OFDM;
1324 } else {
1325 if (idx < 4) {
1326 txpower = ar->power_2G_cck;
1327 mod = AR9170_TX_PHY_MOD_CCK;
1328 } else {
1329 mod = AR9170_TX_PHY_MOD_OFDM;
1330 txpower = ar->power_2G_ofdm;
1331 }
1332 }
1333
1334 rate = &__ar9170_ratetable[idx];
1335
1336 phyrate = rate->hw_value & 0xF;
1337 power = txpower[(rate->hw_value & 0x30) >> 4];
1338 phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
1339
1340 txc->phy_control |= cpu_to_le32(mod);
1341 txc->phy_control |= cpu_to_le32(phyrate);
1342 }
1343
1344 power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
1345 power &= AR9170_TX_PHY_TX_PWR_MASK;
1346 txc->phy_control |= cpu_to_le32(power);
1347
1348 /* set TX chains */
1349 if (ar->eeprom.tx_mask == 1) {
1350 chains = AR9170_TX_PHY_TXCHAIN_1;
1351 } else {
1352 chains = AR9170_TX_PHY_TXCHAIN_2;
1353
1354 /* >= 36M legacy OFDM - use only one chain */
1355 if (rate && rate->bitrate >= 360)
1356 chains = AR9170_TX_PHY_TXCHAIN_1;
1357 }
1358 txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001359}
Christian Lampartere9348cd2009-03-21 23:05:13 +01001360
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001361static void ar9170_tx(struct ar9170 *ar)
1362{
1363 struct sk_buff *skb;
1364 unsigned long flags;
1365 struct ieee80211_tx_info *info;
1366 struct ar9170_tx_info *arinfo;
1367 unsigned int i, frames, frames_failed, remaining_space;
1368 int err;
1369 bool schedule_garbagecollector = false;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001370
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001371 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001372
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001373 if (unlikely(!IS_STARTED(ar)))
1374 return ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001375
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001376 remaining_space = AR9170_TX_MAX_PENDING;
1377
1378 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1379 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1380 if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
1381#ifdef AR9170_QUEUE_DEBUG
1382 printk(KERN_DEBUG "%s: queue %d full\n",
1383 wiphy_name(ar->hw->wiphy), i);
1384
1385 __ar9170_dump_txstats(ar);
1386 printk(KERN_DEBUG "stuck frames: ===> \n");
1387 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1388 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
1389#endif /* AR9170_QUEUE_DEBUG */
1390 ieee80211_stop_queue(ar->hw, i);
1391 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1392 continue;
1393 }
1394
1395 frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
1396 skb_queue_len(&ar->tx_pending[i]));
1397
1398 if (remaining_space < frames) {
1399#ifdef AR9170_QUEUE_DEBUG
1400 printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
1401 "remaining slots:%d, needed:%d\n",
1402 wiphy_name(ar->hw->wiphy), i, remaining_space,
1403 frames);
1404
1405 ar9170_dump_txstats(ar);
1406#endif /* AR9170_QUEUE_DEBUG */
1407 frames = remaining_space;
1408 }
1409
1410 ar->tx_stats[i].len += frames;
1411 ar->tx_stats[i].count += frames;
1412 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1413
1414 if (!frames)
1415 continue;
1416
1417 frames_failed = 0;
1418 while (frames) {
1419 skb = skb_dequeue(&ar->tx_pending[i]);
1420 if (unlikely(!skb)) {
1421 frames_failed += frames;
1422 frames = 0;
1423 break;
1424 }
1425
1426 info = IEEE80211_SKB_CB(skb);
1427 arinfo = (void *) info->rate_driver_data;
1428
1429 /* TODO: cancel stuck frames */
1430 arinfo->timeout = jiffies +
1431 msecs_to_jiffies(AR9170_TX_TIMEOUT);
1432
1433#ifdef AR9170_QUEUE_DEBUG
1434 printk(KERN_DEBUG "%s: send frame q:%d =>\n",
1435 wiphy_name(ar->hw->wiphy), i);
1436 ar9170_print_txheader(ar, skb);
1437#endif /* AR9170_QUEUE_DEBUG */
1438
1439 err = ar->tx(ar, skb);
1440 if (unlikely(err)) {
1441 frames_failed++;
1442 dev_kfree_skb_any(skb);
1443 } else {
1444 remaining_space--;
1445 schedule_garbagecollector = true;
1446 }
1447
1448 frames--;
1449 }
1450
1451#ifdef AR9170_QUEUE_DEBUG
1452 printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n",
1453 wiphy_name(ar->hw->wiphy), i);
1454
1455 printk(KERN_DEBUG "%s: unprocessed pending frames left:\n",
1456 wiphy_name(ar->hw->wiphy));
1457 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1458#endif /* AR9170_QUEUE_DEBUG */
1459
1460 if (unlikely(frames_failed)) {
1461#ifdef AR9170_QUEUE_DEBUG
1462 printk(KERN_DEBUG "%s: frames failed =>\n",
1463 wiphy_name(ar->hw->wiphy), frames_failed);
1464#endif /* AR9170_QUEUE_DEBUG */
1465
1466 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1467 ar->tx_stats[i].len -= frames_failed;
1468 ar->tx_stats[i].count -= frames_failed;
1469 ieee80211_wake_queue(ar->hw, i);
1470 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001471 }
1472 }
1473
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001474 if (schedule_garbagecollector)
1475 queue_delayed_work(ar->hw->workqueue,
1476 &ar->tx_janitor,
1477 msecs_to_jiffies(AR9170_JANITOR_DELAY));
1478}
1479
1480int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1481{
1482 struct ar9170 *ar = hw->priv;
1483 struct ieee80211_tx_info *info;
1484
1485 if (unlikely(!IS_STARTED(ar)))
1486 goto err_free;
1487
1488 if (unlikely(ar9170_tx_prepare(ar, skb)))
1489 goto err_free;
1490
1491 info = IEEE80211_SKB_CB(skb);
1492 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1493 /* drop frame, we do not allow TX A-MPDU aggregation yet. */
1494 goto err_free;
1495 } else {
1496 unsigned int queue = skb_get_queue_mapping(skb);
1497
1498 ar9170_tx_prepare_phy(ar, skb);
1499 skb_queue_tail(&ar->tx_pending[queue], skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001500 }
1501
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001502 ar9170_tx(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001503 return NETDEV_TX_OK;
1504
Christian Lampartere9348cd2009-03-21 23:05:13 +01001505err_free:
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02001506 dev_kfree_skb_any(skb);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001507 return NETDEV_TX_OK;
1508}
1509
1510static int ar9170_op_add_interface(struct ieee80211_hw *hw,
1511 struct ieee80211_if_init_conf *conf)
1512{
1513 struct ar9170 *ar = hw->priv;
1514 int err = 0;
1515
1516 mutex_lock(&ar->mutex);
1517
1518 if (ar->vif) {
1519 err = -EBUSY;
1520 goto unlock;
1521 }
1522
1523 ar->vif = conf->vif;
1524 memcpy(ar->mac_addr, conf->mac_addr, ETH_ALEN);
1525
1526 if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
1527 ar->rx_software_decryption = true;
1528 ar->disable_offload = true;
1529 }
1530
1531 ar->cur_filter = 0;
1532 ar->want_filter = AR9170_MAC_REG_FTF_DEFAULTS;
1533 err = ar9170_update_frame_filter(ar);
1534 if (err)
1535 goto unlock;
1536
1537 err = ar9170_set_operating_mode(ar);
1538
1539unlock:
1540 mutex_unlock(&ar->mutex);
1541 return err;
1542}
1543
1544static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
1545 struct ieee80211_if_init_conf *conf)
1546{
1547 struct ar9170 *ar = hw->priv;
1548
1549 mutex_lock(&ar->mutex);
1550 ar->vif = NULL;
1551 ar->want_filter = 0;
1552 ar9170_update_frame_filter(ar);
1553 ar9170_set_beacon_timers(ar);
1554 dev_kfree_skb(ar->beacon);
1555 ar->beacon = NULL;
1556 ar->sniffer_enabled = false;
1557 ar->rx_software_decryption = false;
1558 ar9170_set_operating_mode(ar);
1559 mutex_unlock(&ar->mutex);
1560}
1561
1562static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
1563{
1564 struct ar9170 *ar = hw->priv;
1565 int err = 0;
1566
1567 mutex_lock(&ar->mutex);
1568
Christian Lampartere9348cd2009-03-21 23:05:13 +01001569 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
1570 /* TODO */
1571 err = 0;
1572 }
1573
1574 if (changed & IEEE80211_CONF_CHANGE_PS) {
1575 /* TODO */
1576 err = 0;
1577 }
1578
1579 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1580 /* TODO */
1581 err = 0;
1582 }
1583
1584 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
1585 /*
1586 * is it long_frame_max_tx_count or short_frame_max_tx_count?
1587 */
1588
1589 err = ar9170_set_hwretry_limit(ar,
1590 ar->hw->conf.long_frame_max_tx_count);
1591 if (err)
1592 goto out;
1593 }
1594
Johannes Berg57c4d7b2009-04-23 16:10:04 +02001595 if (changed & BSS_CHANGED_BEACON_INT) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001596 err = ar9170_set_beacon_timers(ar);
1597 if (err)
1598 goto out;
1599 }
1600
1601 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02001602
1603 /* adjust slot time for 5 GHz */
1604 err = ar9170_set_slot_time(ar);
1605 if (err)
1606 goto out;
1607
1608 err = ar9170_set_dyn_sifs_ack(ar);
1609 if (err)
1610 goto out;
1611
Christian Lampartere9348cd2009-03-21 23:05:13 +01001612 err = ar9170_set_channel(ar, hw->conf.channel,
Johannes Berg9e52b062009-04-20 18:27:04 +02001613 AR9170_RFI_NONE,
1614 nl80211_to_ar9170(hw->conf.channel_type));
Christian Lampartere9348cd2009-03-21 23:05:13 +01001615 if (err)
1616 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001617 }
1618
1619out:
1620 mutex_unlock(&ar->mutex);
1621 return err;
1622}
1623
Christian Lampartere9348cd2009-03-21 23:05:13 +01001624static void ar9170_set_filters(struct work_struct *work)
1625{
1626 struct ar9170 *ar = container_of(work, struct ar9170,
1627 filter_config_work);
1628 int err;
1629
Christian Lampartere9348cd2009-03-21 23:05:13 +01001630 if (unlikely(!IS_STARTED(ar)))
Christian Lamparter32c16282009-03-28 01:46:14 +01001631 return ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001632
Christian Lamparter32c16282009-03-28 01:46:14 +01001633 mutex_lock(&ar->mutex);
Christian Lamparter864cc022009-05-23 20:28:21 +02001634 if (test_and_clear_bit(AR9170_FILTER_CHANGED_MODE,
1635 &ar->filter_changed)) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001636 err = ar9170_set_operating_mode(ar);
1637 if (err)
1638 goto unlock;
1639 }
1640
Christian Lamparter864cc022009-05-23 20:28:21 +02001641 if (test_and_clear_bit(AR9170_FILTER_CHANGED_MULTICAST,
1642 &ar->filter_changed)) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001643 err = ar9170_update_multicast(ar);
1644 if (err)
1645 goto unlock;
1646 }
1647
Christian Lamparter864cc022009-05-23 20:28:21 +02001648 if (test_and_clear_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
1649 &ar->filter_changed)) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001650 err = ar9170_update_frame_filter(ar);
Christian Lamparter864cc022009-05-23 20:28:21 +02001651 if (err)
1652 goto unlock;
1653 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001654
1655unlock:
1656 mutex_unlock(&ar->mutex);
1657}
1658
1659static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
1660 unsigned int changed_flags,
1661 unsigned int *new_flags,
1662 int mc_count, struct dev_mc_list *mclist)
1663{
1664 struct ar9170 *ar = hw->priv;
1665
1666 /* mask supported flags */
1667 *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
Christian Lampartercca847992009-04-19 01:28:12 +02001668 FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
1669 ar->filter_state = *new_flags;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001670 /*
1671 * We can support more by setting the sniffer bit and
1672 * then checking the error flags, later.
1673 */
1674
1675 if (changed_flags & FIF_ALLMULTI) {
1676 if (*new_flags & FIF_ALLMULTI) {
1677 ar->want_mc_hash = ~0ULL;
1678 } else {
1679 u64 mchash;
1680 int i;
1681
1682 /* always get broadcast frames */
Christian Lamparter864cc022009-05-23 20:28:21 +02001683 mchash = 1ULL << (0xff >> 2);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001684
1685 for (i = 0; i < mc_count; i++) {
1686 if (WARN_ON(!mclist))
1687 break;
1688 mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
1689 mclist = mclist->next;
1690 }
1691 ar->want_mc_hash = mchash;
1692 }
Christian Lamparter864cc022009-05-23 20:28:21 +02001693 set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001694 }
1695
1696 if (changed_flags & FIF_CONTROL) {
1697 u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
1698 AR9170_MAC_REG_FTF_RTS |
1699 AR9170_MAC_REG_FTF_CTS |
1700 AR9170_MAC_REG_FTF_ACK |
1701 AR9170_MAC_REG_FTF_CFE |
1702 AR9170_MAC_REG_FTF_CFE_ACK;
1703
1704 if (*new_flags & FIF_CONTROL)
1705 ar->want_filter = ar->cur_filter | filter;
1706 else
1707 ar->want_filter = ar->cur_filter & ~filter;
1708
Christian Lamparter864cc022009-05-23 20:28:21 +02001709 set_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
1710 &ar->filter_changed);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001711 }
1712
1713 if (changed_flags & FIF_PROMISC_IN_BSS) {
1714 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
Christian Lamparter864cc022009-05-23 20:28:21 +02001715 set_bit(AR9170_FILTER_CHANGED_MODE,
1716 &ar->filter_changed);
Christian Lampartere9348cd2009-03-21 23:05:13 +01001717 }
1718
1719 if (likely(IS_STARTED(ar)))
1720 queue_work(ar->hw->workqueue, &ar->filter_config_work);
1721}
1722
1723static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
1724 struct ieee80211_vif *vif,
1725 struct ieee80211_bss_conf *bss_conf,
1726 u32 changed)
1727{
1728 struct ar9170 *ar = hw->priv;
1729 int err = 0;
1730
1731 mutex_lock(&ar->mutex);
1732
Johannes Berg2d0ddec2009-04-23 16:13:26 +02001733 if (changed & BSS_CHANGED_BSSID) {
1734 memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN);
1735 err = ar9170_set_operating_mode(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02001736 if (err)
1737 goto out;
Johannes Berg2d0ddec2009-04-23 16:13:26 +02001738 }
1739
1740 if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) {
1741 err = ar9170_update_beacon(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02001742 if (err)
1743 goto out;
Johannes Berg2d0ddec2009-04-23 16:13:26 +02001744
Christian Lamparter29ceff52009-06-01 21:42:01 +02001745 err = ar9170_set_beacon_timers(ar);
1746 if (err)
1747 goto out;
1748 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001749
1750 if (changed & BSS_CHANGED_ASSOC) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001751#ifndef CONFIG_AR9170_LEDS
1752 /* enable assoc LED. */
1753 err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
1754#endif /* CONFIG_AR9170_LEDS */
1755 }
1756
Christian Lamparter29ceff52009-06-01 21:42:01 +02001757 if (changed & BSS_CHANGED_BEACON_INT) {
Johannes Berg57c4d7b2009-04-23 16:10:04 +02001758 err = ar9170_set_beacon_timers(ar);
Christian Lamparter29ceff52009-06-01 21:42:01 +02001759 if (err)
1760 goto out;
1761 }
Johannes Berg57c4d7b2009-04-23 16:10:04 +02001762
Christian Lampartere9348cd2009-03-21 23:05:13 +01001763 if (changed & BSS_CHANGED_HT) {
1764 /* TODO */
1765 err = 0;
1766 }
1767
1768 if (changed & BSS_CHANGED_ERP_SLOT) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02001769 err = ar9170_set_slot_time(ar);
1770 if (err)
1771 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001772 }
1773
1774 if (changed & BSS_CHANGED_BASIC_RATES) {
Christian Lamparter29ceff52009-06-01 21:42:01 +02001775 err = ar9170_set_basic_rates(ar);
1776 if (err)
1777 goto out;
Christian Lampartere9348cd2009-03-21 23:05:13 +01001778 }
1779
Christian Lamparter29ceff52009-06-01 21:42:01 +02001780out:
Christian Lampartere9348cd2009-03-21 23:05:13 +01001781 mutex_unlock(&ar->mutex);
1782}
1783
1784static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
1785{
1786 struct ar9170 *ar = hw->priv;
1787 int err;
1788 u32 tsf_low;
1789 u32 tsf_high;
1790 u64 tsf;
1791
1792 mutex_lock(&ar->mutex);
1793 err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low);
1794 if (!err)
1795 err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high);
1796 mutex_unlock(&ar->mutex);
1797
1798 if (WARN_ON(err))
1799 return 0;
1800
1801 tsf = tsf_high;
1802 tsf = (tsf << 32) | tsf_low;
1803 return tsf;
1804}
1805
1806static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1807 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
1808 struct ieee80211_key_conf *key)
1809{
1810 struct ar9170 *ar = hw->priv;
1811 int err = 0, i;
1812 u8 ktype;
1813
1814 if ((!ar->vif) || (ar->disable_offload))
1815 return -EOPNOTSUPP;
1816
1817 switch (key->alg) {
1818 case ALG_WEP:
Zhu Yie31a16d2009-05-21 21:47:03 +08001819 if (key->keylen == WLAN_KEY_LEN_WEP40)
Christian Lampartere9348cd2009-03-21 23:05:13 +01001820 ktype = AR9170_ENC_ALG_WEP64;
1821 else
1822 ktype = AR9170_ENC_ALG_WEP128;
1823 break;
1824 case ALG_TKIP:
1825 ktype = AR9170_ENC_ALG_TKIP;
1826 break;
1827 case ALG_CCMP:
1828 ktype = AR9170_ENC_ALG_AESCCMP;
1829 break;
1830 default:
1831 return -EOPNOTSUPP;
1832 }
1833
1834 mutex_lock(&ar->mutex);
1835 if (cmd == SET_KEY) {
1836 if (unlikely(!IS_STARTED(ar))) {
1837 err = -EOPNOTSUPP;
1838 goto out;
1839 }
1840
1841 /* group keys need all-zeroes address */
1842 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1843 sta = NULL;
1844
1845 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
1846 for (i = 0; i < 64; i++)
1847 if (!(ar->usedkeys & BIT(i)))
1848 break;
1849 if (i == 64) {
1850 ar->rx_software_decryption = true;
1851 ar9170_set_operating_mode(ar);
1852 err = -ENOSPC;
1853 goto out;
1854 }
1855 } else {
1856 i = 64 + key->keyidx;
1857 }
1858
1859 key->hw_key_idx = i;
1860
1861 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
1862 key->key, min_t(u8, 16, key->keylen));
1863 if (err)
1864 goto out;
1865
1866 if (key->alg == ALG_TKIP) {
1867 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
1868 ktype, 1, key->key + 16, 16);
1869 if (err)
1870 goto out;
1871
1872 /*
1873 * hardware is not capable generating the MMIC
1874 * for fragmented frames!
1875 */
1876 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1877 }
1878
1879 if (i < 64)
1880 ar->usedkeys |= BIT(i);
1881
1882 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1883 } else {
1884 if (unlikely(!IS_STARTED(ar))) {
1885 /* The device is gone... together with the key ;-) */
1886 err = 0;
1887 goto out;
1888 }
1889
1890 err = ar9170_disable_key(ar, key->hw_key_idx);
1891 if (err)
1892 goto out;
1893
1894 if (key->hw_key_idx < 64) {
1895 ar->usedkeys &= ~BIT(key->hw_key_idx);
1896 } else {
1897 err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
1898 AR9170_ENC_ALG_NONE, 0,
1899 NULL, 0);
1900 if (err)
1901 goto out;
1902
1903 if (key->alg == ALG_TKIP) {
1904 err = ar9170_upload_key(ar, key->hw_key_idx,
1905 NULL,
1906 AR9170_ENC_ALG_NONE, 1,
1907 NULL, 0);
1908 if (err)
1909 goto out;
1910 }
1911
1912 }
1913 }
1914
1915 ar9170_regwrite_begin(ar);
1916 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
1917 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
1918 ar9170_regwrite_finish();
1919 err = ar9170_regwrite_result();
1920
1921out:
1922 mutex_unlock(&ar->mutex);
1923
1924 return err;
1925}
1926
1927static void ar9170_sta_notify(struct ieee80211_hw *hw,
1928 struct ieee80211_vif *vif,
1929 enum sta_notify_cmd cmd,
1930 struct ieee80211_sta *sta)
1931{
Christian Lampartere9348cd2009-03-21 23:05:13 +01001932}
1933
1934static int ar9170_get_stats(struct ieee80211_hw *hw,
1935 struct ieee80211_low_level_stats *stats)
1936{
1937 struct ar9170 *ar = hw->priv;
1938 u32 val;
1939 int err;
1940
1941 mutex_lock(&ar->mutex);
1942 err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
1943 ar->stats.dot11ACKFailureCount += val;
1944
1945 memcpy(stats, &ar->stats, sizeof(*stats));
1946 mutex_unlock(&ar->mutex);
1947
1948 return 0;
1949}
1950
1951static int ar9170_get_tx_stats(struct ieee80211_hw *hw,
1952 struct ieee80211_tx_queue_stats *tx_stats)
1953{
1954 struct ar9170 *ar = hw->priv;
1955
1956 spin_lock_bh(&ar->tx_stats_lock);
1957 memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues);
1958 spin_unlock_bh(&ar->tx_stats_lock);
1959
1960 return 0;
1961}
1962
1963static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
1964 const struct ieee80211_tx_queue_params *param)
1965{
1966 struct ar9170 *ar = hw->priv;
1967 int ret;
1968
1969 mutex_lock(&ar->mutex);
Dan Carpentere9d126c2009-08-09 14:24:09 +02001970 if (queue < __AR9170_NUM_TXQ) {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001971 memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
1972 param, sizeof(*param));
1973
1974 ret = ar9170_set_qos(ar);
Dan Carpentere9d126c2009-08-09 14:24:09 +02001975 } else {
Christian Lampartere9348cd2009-03-21 23:05:13 +01001976 ret = -EINVAL;
Dan Carpentere9d126c2009-08-09 14:24:09 +02001977 }
Christian Lampartere9348cd2009-03-21 23:05:13 +01001978
1979 mutex_unlock(&ar->mutex);
1980 return ret;
1981}
1982
Johannes Berg9e52b062009-04-20 18:27:04 +02001983static int ar9170_ampdu_action(struct ieee80211_hw *hw,
1984 enum ieee80211_ampdu_mlme_action action,
1985 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
1986{
1987 switch (action) {
1988 case IEEE80211_AMPDU_RX_START:
1989 case IEEE80211_AMPDU_RX_STOP:
1990 /*
1991 * Something goes wrong -- RX locks up
1992 * after a while of receiving aggregated
1993 * frames -- not enabling for now.
1994 */
1995 return -EOPNOTSUPP;
1996 default:
1997 return -EOPNOTSUPP;
1998 }
1999}
2000
Christian Lampartere9348cd2009-03-21 23:05:13 +01002001static const struct ieee80211_ops ar9170_ops = {
2002 .start = ar9170_op_start,
2003 .stop = ar9170_op_stop,
2004 .tx = ar9170_op_tx,
2005 .add_interface = ar9170_op_add_interface,
2006 .remove_interface = ar9170_op_remove_interface,
2007 .config = ar9170_op_config,
Christian Lampartere9348cd2009-03-21 23:05:13 +01002008 .configure_filter = ar9170_op_configure_filter,
2009 .conf_tx = ar9170_conf_tx,
2010 .bss_info_changed = ar9170_op_bss_info_changed,
2011 .get_tsf = ar9170_op_get_tsf,
2012 .set_key = ar9170_set_key,
2013 .sta_notify = ar9170_sta_notify,
2014 .get_stats = ar9170_get_stats,
2015 .get_tx_stats = ar9170_get_tx_stats,
Johannes Berg9e52b062009-04-20 18:27:04 +02002016 .ampdu_action = ar9170_ampdu_action,
Christian Lampartere9348cd2009-03-21 23:05:13 +01002017};
2018
2019void *ar9170_alloc(size_t priv_size)
2020{
2021 struct ieee80211_hw *hw;
2022 struct ar9170 *ar;
Christian Lampartercca847992009-04-19 01:28:12 +02002023 struct sk_buff *skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002024 int i;
2025
Christian Lampartercca847992009-04-19 01:28:12 +02002026 /*
2027 * this buffer is used for rx stream reconstruction.
2028 * Under heavy load this device (or the transport layer?)
2029 * tends to split the streams into seperate rx descriptors.
2030 */
2031
2032 skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL);
2033 if (!skb)
2034 goto err_nomem;
2035
Christian Lampartere9348cd2009-03-21 23:05:13 +01002036 hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
2037 if (!hw)
Christian Lampartercca847992009-04-19 01:28:12 +02002038 goto err_nomem;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002039
2040 ar = hw->priv;
2041 ar->hw = hw;
Christian Lampartercca847992009-04-19 01:28:12 +02002042 ar->rx_failover = skb;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002043
2044 mutex_init(&ar->mutex);
2045 spin_lock_init(&ar->cmdlock);
2046 spin_lock_init(&ar->tx_stats_lock);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002047 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
2048 skb_queue_head_init(&ar->tx_status[i]);
2049 skb_queue_head_init(&ar->tx_pending[i]);
2050 }
Christian Lampartercca847992009-04-19 01:28:12 +02002051 ar9170_rx_reset_rx_mpdu(ar);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002052 INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
2053 INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +02002054 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002055
2056 /* all hw supports 2.4 GHz, so set channel to 1 by default */
2057 ar->channel = &ar9170_2ghz_chantable[0];
2058
2059 /* first part of wiphy init */
2060 ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2061 BIT(NL80211_IFTYPE_WDS) |
2062 BIT(NL80211_IFTYPE_ADHOC);
2063 ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
2064 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
2065 IEEE80211_HW_SIGNAL_DBM |
2066 IEEE80211_HW_NOISE_DBM;
2067
Christian Lamparter4a48e2a2009-03-23 12:15:43 +01002068 ar->hw->queues = __AR9170_NUM_TXQ;
Christian Lampartere9348cd2009-03-21 23:05:13 +01002069 ar->hw->extra_tx_headroom = 8;
2070 ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
2071
2072 ar->hw->max_rates = 1;
2073 ar->hw->max_rate_tries = 3;
2074
2075 for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
2076 ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
2077
2078 return ar;
Christian Lampartercca847992009-04-19 01:28:12 +02002079
2080err_nomem:
2081 kfree_skb(skb);
2082 return ERR_PTR(-ENOMEM);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002083}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002084
2085static int ar9170_read_eeprom(struct ar9170 *ar)
2086{
2087#define RW 8 /* number of words to read at once */
2088#define RB (sizeof(u32) * RW)
2089 DECLARE_MAC_BUF(mbuf);
2090 u8 *eeprom = (void *)&ar->eeprom;
2091 u8 *addr = ar->eeprom.mac_address;
2092 __le32 offsets[RW];
2093 int i, j, err, bands = 0;
2094
2095 BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
2096
2097 BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
2098#ifndef __CHECKER__
2099 /* don't want to handle trailing remains */
2100 BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
2101#endif
2102
2103 for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
2104 for (j = 0; j < RW; j++)
2105 offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
2106 RB * i + 4 * j);
2107
2108 err = ar->exec_cmd(ar, AR9170_CMD_RREG,
2109 RB, (u8 *) &offsets,
2110 RB, eeprom + RB * i);
2111 if (err)
2112 return err;
2113 }
2114
2115#undef RW
2116#undef RB
2117
2118 if (ar->eeprom.length == cpu_to_le16(0xFFFF))
2119 return -ENODATA;
2120
2121 if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
2122 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
2123 bands++;
2124 }
2125 if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
2126 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
2127 bands++;
2128 }
2129 /*
2130 * I measured this, a bandswitch takes roughly
2131 * 135 ms and a frequency switch about 80.
2132 *
2133 * FIXME: measure these values again once EEPROM settings
2134 * are used, that will influence them!
2135 */
2136 if (bands == 2)
2137 ar->hw->channel_change_time = 135 * 1000;
2138 else
2139 ar->hw->channel_change_time = 80 * 1000;
2140
Christian Lamparter1878f772009-03-30 22:30:32 -04002141 ar->regulatory.current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
2142 ar->regulatory.current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
2143
Christian Lampartere9348cd2009-03-21 23:05:13 +01002144 /* second part of wiphy init */
2145 SET_IEEE80211_PERM_ADDR(ar->hw, addr);
2146
2147 return bands ? 0 : -EINVAL;
2148}
2149
Christian Lamparter1878f772009-03-30 22:30:32 -04002150static int ar9170_reg_notifier(struct wiphy *wiphy,
2151 struct regulatory_request *request)
2152{
2153 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2154 struct ar9170 *ar = hw->priv;
2155
2156 return ath_reg_notifier_apply(wiphy, request, &ar->regulatory);
2157}
2158
Christian Lampartere9348cd2009-03-21 23:05:13 +01002159int ar9170_register(struct ar9170 *ar, struct device *pdev)
2160{
2161 int err;
2162
2163 /* try to read EEPROM, init MAC addr */
2164 err = ar9170_read_eeprom(ar);
2165 if (err)
2166 goto err_out;
2167
Christian Lamparter1878f772009-03-30 22:30:32 -04002168 err = ath_regd_init(&ar->regulatory, ar->hw->wiphy,
2169 ar9170_reg_notifier);
Luis R. Rodriguez85efc862009-04-13 21:41:46 -04002170 if (err)
2171 goto err_out;
Christian Lamparter1878f772009-03-30 22:30:32 -04002172
Christian Lampartere9348cd2009-03-21 23:05:13 +01002173 err = ieee80211_register_hw(ar->hw);
2174 if (err)
2175 goto err_out;
2176
Christian Lamparter1878f772009-03-30 22:30:32 -04002177 if (!ath_is_world_regd(&ar->regulatory))
2178 regulatory_hint(ar->hw->wiphy, ar->regulatory.alpha2);
2179
Christian Lampartere9348cd2009-03-21 23:05:13 +01002180 err = ar9170_init_leds(ar);
2181 if (err)
2182 goto err_unreg;
2183
2184#ifdef CONFIG_AR9170_LEDS
2185 err = ar9170_register_leds(ar);
2186 if (err)
2187 goto err_unreg;
2188#endif /* CONFIG_AR9170_LEDS */
2189
2190 dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
2191 wiphy_name(ar->hw->wiphy));
2192
2193 return err;
2194
2195err_unreg:
2196 ieee80211_unregister_hw(ar->hw);
2197
2198err_out:
2199 return err;
2200}
Christian Lampartere9348cd2009-03-21 23:05:13 +01002201
2202void ar9170_unregister(struct ar9170 *ar)
2203{
2204#ifdef CONFIG_AR9170_LEDS
2205 ar9170_unregister_leds(ar);
2206#endif /* CONFIG_AR9170_LEDS */
2207
Christian Lampartercca847992009-04-19 01:28:12 +02002208 kfree_skb(ar->rx_failover);
Christian Lampartere9348cd2009-03-21 23:05:13 +01002209 ieee80211_unregister_hw(ar->hw);
2210 mutex_destroy(&ar->mutex);
2211}