blob: 1202bb0a55349fc7e64b97becf2be871941ab8dd [file] [log] [blame]
Sujith55624202010-01-08 10:36:02 +05301/*
Sujith Manoharan5b681382011-05-17 13:36:18 +05302 * Copyright (c) 2008-2011 Atheros Communications Inc.
Sujith55624202010-01-08 10:36:02 +05303 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
Alexey Dobriyanb7f080c2011-06-16 11:01:34 +000017#include <linux/dma-mapping.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090018#include <linux/slab.h>
Felix Fietkau6fb1b1e2011-03-19 13:55:39 +010019#include <linux/ath9k_platform.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090020
Sujith55624202010-01-08 10:36:02 +053021#include "ath9k.h"
22
23static char *dev_info = "ath9k";
24
25MODULE_AUTHOR("Atheros Communications");
26MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
27MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
28MODULE_LICENSE("Dual BSD/GPL");
29
30static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
31module_param_named(debug, ath9k_debug, uint, 0);
32MODULE_PARM_DESC(debug, "Debugging mask");
33
John W. Linville3e6109c2011-01-05 09:39:17 -050034int ath9k_modparam_nohwcrypt;
35module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
Sujith55624202010-01-08 10:36:02 +053036MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
37
Vivek Natarajan93dbbcc2010-08-25 19:34:52 +053038int led_blink;
Vivek Natarajan9a75c2f2010-06-22 11:52:37 +053039module_param_named(blink, led_blink, int, 0444);
40MODULE_PARM_DESC(blink, "Enable LED blink on activity");
41
Vasanthakumar Thiagarajan8f5dcb12010-11-26 06:10:06 -080042static int ath9k_btcoex_enable;
43module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
44MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
45
Rajkumar Manoharand5847472010-12-20 14:39:51 +053046bool is_ath9k_unloaded;
Sujith55624202010-01-08 10:36:02 +053047/* We use the hw_value as an index into our private channel structure */
48
49#define CHAN2G(_freq, _idx) { \
Mohammed Shafi Shajakhanb1c1d002010-12-17 20:44:36 +053050 .band = IEEE80211_BAND_2GHZ, \
Sujith55624202010-01-08 10:36:02 +053051 .center_freq = (_freq), \
52 .hw_value = (_idx), \
53 .max_power = 20, \
54}
55
56#define CHAN5G(_freq, _idx) { \
57 .band = IEEE80211_BAND_5GHZ, \
58 .center_freq = (_freq), \
59 .hw_value = (_idx), \
60 .max_power = 20, \
61}
62
63/* Some 2 GHz radios are actually tunable on 2312-2732
64 * on 5 MHz steps, we support the channels which we know
65 * we have calibration data for all cards though to make
66 * this static */
Felix Fietkauf209f522010-10-01 01:06:53 +020067static const struct ieee80211_channel ath9k_2ghz_chantable[] = {
Sujith55624202010-01-08 10:36:02 +053068 CHAN2G(2412, 0), /* Channel 1 */
69 CHAN2G(2417, 1), /* Channel 2 */
70 CHAN2G(2422, 2), /* Channel 3 */
71 CHAN2G(2427, 3), /* Channel 4 */
72 CHAN2G(2432, 4), /* Channel 5 */
73 CHAN2G(2437, 5), /* Channel 6 */
74 CHAN2G(2442, 6), /* Channel 7 */
75 CHAN2G(2447, 7), /* Channel 8 */
76 CHAN2G(2452, 8), /* Channel 9 */
77 CHAN2G(2457, 9), /* Channel 10 */
78 CHAN2G(2462, 10), /* Channel 11 */
79 CHAN2G(2467, 11), /* Channel 12 */
80 CHAN2G(2472, 12), /* Channel 13 */
81 CHAN2G(2484, 13), /* Channel 14 */
82};
83
84/* Some 5 GHz radios are actually tunable on XXXX-YYYY
85 * on 5 MHz steps, we support the channels which we know
86 * we have calibration data for all cards though to make
87 * this static */
Felix Fietkauf209f522010-10-01 01:06:53 +020088static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
Sujith55624202010-01-08 10:36:02 +053089 /* _We_ call this UNII 1 */
90 CHAN5G(5180, 14), /* Channel 36 */
91 CHAN5G(5200, 15), /* Channel 40 */
92 CHAN5G(5220, 16), /* Channel 44 */
93 CHAN5G(5240, 17), /* Channel 48 */
94 /* _We_ call this UNII 2 */
95 CHAN5G(5260, 18), /* Channel 52 */
96 CHAN5G(5280, 19), /* Channel 56 */
97 CHAN5G(5300, 20), /* Channel 60 */
98 CHAN5G(5320, 21), /* Channel 64 */
99 /* _We_ call this "Middle band" */
100 CHAN5G(5500, 22), /* Channel 100 */
101 CHAN5G(5520, 23), /* Channel 104 */
102 CHAN5G(5540, 24), /* Channel 108 */
103 CHAN5G(5560, 25), /* Channel 112 */
104 CHAN5G(5580, 26), /* Channel 116 */
105 CHAN5G(5600, 27), /* Channel 120 */
106 CHAN5G(5620, 28), /* Channel 124 */
107 CHAN5G(5640, 29), /* Channel 128 */
108 CHAN5G(5660, 30), /* Channel 132 */
109 CHAN5G(5680, 31), /* Channel 136 */
110 CHAN5G(5700, 32), /* Channel 140 */
111 /* _We_ call this UNII 3 */
112 CHAN5G(5745, 33), /* Channel 149 */
113 CHAN5G(5765, 34), /* Channel 153 */
114 CHAN5G(5785, 35), /* Channel 157 */
115 CHAN5G(5805, 36), /* Channel 161 */
116 CHAN5G(5825, 37), /* Channel 165 */
117};
118
119/* Atheros hardware rate code addition for short premble */
120#define SHPCHECK(__hw_rate, __flags) \
121 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
122
123#define RATE(_bitrate, _hw_rate, _flags) { \
124 .bitrate = (_bitrate), \
125 .flags = (_flags), \
126 .hw_value = (_hw_rate), \
127 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
128}
129
130static struct ieee80211_rate ath9k_legacy_rates[] = {
131 RATE(10, 0x1b, 0),
132 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
133 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
134 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
135 RATE(60, 0x0b, 0),
136 RATE(90, 0x0f, 0),
137 RATE(120, 0x0a, 0),
138 RATE(180, 0x0e, 0),
139 RATE(240, 0x09, 0),
140 RATE(360, 0x0d, 0),
141 RATE(480, 0x08, 0),
142 RATE(540, 0x0c, 0),
143};
144
Felix Fietkau0cf55c22011-02-27 22:26:40 +0100145#ifdef CONFIG_MAC80211_LEDS
146static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = {
147 { .throughput = 0 * 1024, .blink_time = 334 },
148 { .throughput = 1 * 1024, .blink_time = 260 },
149 { .throughput = 5 * 1024, .blink_time = 220 },
150 { .throughput = 10 * 1024, .blink_time = 190 },
151 { .throughput = 20 * 1024, .blink_time = 170 },
152 { .throughput = 50 * 1024, .blink_time = 150 },
153 { .throughput = 70 * 1024, .blink_time = 130 },
154 { .throughput = 100 * 1024, .blink_time = 110 },
155 { .throughput = 200 * 1024, .blink_time = 80 },
156 { .throughput = 300 * 1024, .blink_time = 50 },
157};
158#endif
159
Sujith285f2dd2010-01-08 10:36:07 +0530160static void ath9k_deinit_softc(struct ath_softc *sc);
Sujith55624202010-01-08 10:36:02 +0530161
162/*
163 * Read and write, they both share the same lock. We do this to serialize
164 * reads and writes on Atheros 802.11n PCI devices only. This is required
165 * as the FIFO on these devices can only accept sanely 2 requests.
166 */
167
168static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
169{
170 struct ath_hw *ah = (struct ath_hw *) hw_priv;
171 struct ath_common *common = ath9k_hw_common(ah);
172 struct ath_softc *sc = (struct ath_softc *) common->priv;
173
174 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
175 unsigned long flags;
176 spin_lock_irqsave(&sc->sc_serial_rw, flags);
177 iowrite32(val, sc->mem + reg_offset);
178 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
179 } else
180 iowrite32(val, sc->mem + reg_offset);
181}
182
183static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
184{
185 struct ath_hw *ah = (struct ath_hw *) hw_priv;
186 struct ath_common *common = ath9k_hw_common(ah);
187 struct ath_softc *sc = (struct ath_softc *) common->priv;
188 u32 val;
189
190 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
191 unsigned long flags;
192 spin_lock_irqsave(&sc->sc_serial_rw, flags);
193 val = ioread32(sc->mem + reg_offset);
194 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
195 } else
196 val = ioread32(sc->mem + reg_offset);
197 return val;
198}
199
Felix Fietkau845e03c2011-03-23 20:57:25 +0100200static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
201{
202 struct ath_hw *ah = (struct ath_hw *) hw_priv;
203 struct ath_common *common = ath9k_hw_common(ah);
204 struct ath_softc *sc = (struct ath_softc *) common->priv;
205 unsigned long uninitialized_var(flags);
206 u32 val;
207
208 if (ah->config.serialize_regmode == SER_REG_MODE_ON)
209 spin_lock_irqsave(&sc->sc_serial_rw, flags);
210
211 val = ioread32(sc->mem + reg_offset);
212 val &= ~clr;
213 val |= set;
214 iowrite32(val, sc->mem + reg_offset);
215
216 if (ah->config.serialize_regmode == SER_REG_MODE_ON)
217 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
218
219 return val;
220}
221
Sujith55624202010-01-08 10:36:02 +0530222/**************************/
223/* Initialization */
224/**************************/
225
226static void setup_ht_cap(struct ath_softc *sc,
227 struct ieee80211_sta_ht_cap *ht_info)
228{
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200229 struct ath_hw *ah = sc->sc_ah;
230 struct ath_common *common = ath9k_hw_common(ah);
Sujith55624202010-01-08 10:36:02 +0530231 u8 tx_streams, rx_streams;
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200232 int i, max_streams;
Sujith55624202010-01-08 10:36:02 +0530233
234 ht_info->ht_supported = true;
235 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
236 IEEE80211_HT_CAP_SM_PS |
237 IEEE80211_HT_CAP_SGI_40 |
238 IEEE80211_HT_CAP_DSSSCCK40;
239
Luis R. Rodriguezb0a33442010-04-15 17:39:39 -0400240 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
241 ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
242
Vasanthakumar Thiagarajan6473d242010-05-13 18:42:38 -0700243 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
244 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
245
Sujith55624202010-01-08 10:36:02 +0530246 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
247 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
248
Vasanthakumar Thiagarajan7f1c7a62010-12-06 04:27:41 -0800249 if (AR_SREV_9485(ah))
250 max_streams = 1;
251 else if (AR_SREV_9300_20_OR_LATER(ah))
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200252 max_streams = 3;
253 else
254 max_streams = 2;
255
Felix Fietkau7a370812010-09-22 12:34:52 +0200256 if (AR_SREV_9280_20_OR_LATER(ah)) {
Felix Fietkau074a8c02010-04-19 19:57:36 +0200257 if (max_streams >= 2)
258 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
259 ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
260 }
261
Sujith55624202010-01-08 10:36:02 +0530262 /* set up supported mcs set */
263 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
Sujith61389f32010-06-02 15:53:37 +0530264 tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams);
265 rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams);
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200266
Joe Perches226afe62010-12-02 19:12:37 -0800267 ath_dbg(common, ATH_DBG_CONFIG,
268 "TX streams %d, RX streams: %d\n",
269 tx_streams, rx_streams);
Sujith55624202010-01-08 10:36:02 +0530270
271 if (tx_streams != rx_streams) {
Sujith55624202010-01-08 10:36:02 +0530272 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
273 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
274 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
275 }
276
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200277 for (i = 0; i < rx_streams; i++)
278 ht_info->mcs.rx_mask[i] = 0xff;
Sujith55624202010-01-08 10:36:02 +0530279
280 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
281}
282
283static int ath9k_reg_notifier(struct wiphy *wiphy,
284 struct regulatory_request *request)
285{
286 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
Felix Fietkau9ac58612011-01-24 19:23:18 +0100287 struct ath_softc *sc = hw->priv;
Sujith55624202010-01-08 10:36:02 +0530288 struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
289
290 return ath_reg_notifier_apply(wiphy, request, reg);
291}
292
293/*
294 * This function will allocate both the DMA descriptor structure, and the
295 * buffers it contains. These are used to contain the descriptors used
296 * by the system.
297*/
298int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
299 struct list_head *head, const char *name,
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400300 int nbuf, int ndesc, bool is_tx)
Sujith55624202010-01-08 10:36:02 +0530301{
302#define DS2PHYS(_dd, _ds) \
303 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
304#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
305#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
306 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400307 u8 *ds;
Sujith55624202010-01-08 10:36:02 +0530308 struct ath_buf *bf;
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400309 int i, bsize, error, desc_len;
Sujith55624202010-01-08 10:36:02 +0530310
Joe Perches226afe62010-12-02 19:12:37 -0800311 ath_dbg(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
312 name, nbuf, ndesc);
Sujith55624202010-01-08 10:36:02 +0530313
314 INIT_LIST_HEAD(head);
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400315
316 if (is_tx)
317 desc_len = sc->sc_ah->caps.tx_desc_len;
318 else
319 desc_len = sizeof(struct ath_desc);
320
Sujith55624202010-01-08 10:36:02 +0530321 /* ath_desc must be a multiple of DWORDs */
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400322 if ((desc_len % 4) != 0) {
Joe Perches38002762010-12-02 19:12:36 -0800323 ath_err(common, "ath_desc not DWORD aligned\n");
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400324 BUG_ON((desc_len % 4) != 0);
Sujith55624202010-01-08 10:36:02 +0530325 error = -ENOMEM;
326 goto fail;
327 }
328
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400329 dd->dd_desc_len = desc_len * nbuf * ndesc;
Sujith55624202010-01-08 10:36:02 +0530330
331 /*
332 * Need additional DMA memory because we can't use
333 * descriptors that cross the 4K page boundary. Assume
334 * one skipped descriptor per 4K page.
335 */
336 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
337 u32 ndesc_skipped =
338 ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
339 u32 dma_len;
340
341 while (ndesc_skipped) {
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400342 dma_len = ndesc_skipped * desc_len;
Sujith55624202010-01-08 10:36:02 +0530343 dd->dd_desc_len += dma_len;
344
345 ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
Joe Perchesee289b62010-05-17 22:47:34 -0700346 }
Sujith55624202010-01-08 10:36:02 +0530347 }
348
349 /* allocate descriptors */
350 dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
351 &dd->dd_desc_paddr, GFP_KERNEL);
352 if (dd->dd_desc == NULL) {
353 error = -ENOMEM;
354 goto fail;
355 }
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400356 ds = (u8 *) dd->dd_desc;
Joe Perches226afe62010-12-02 19:12:37 -0800357 ath_dbg(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
358 name, ds, (u32) dd->dd_desc_len,
359 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
Sujith55624202010-01-08 10:36:02 +0530360
361 /* allocate buffers */
362 bsize = sizeof(struct ath_buf) * nbuf;
363 bf = kzalloc(bsize, GFP_KERNEL);
364 if (bf == NULL) {
365 error = -ENOMEM;
366 goto fail2;
367 }
368 dd->dd_bufptr = bf;
369
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400370 for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
Sujith55624202010-01-08 10:36:02 +0530371 bf->bf_desc = ds;
372 bf->bf_daddr = DS2PHYS(dd, ds);
373
374 if (!(sc->sc_ah->caps.hw_caps &
375 ATH9K_HW_CAP_4KB_SPLITTRANS)) {
376 /*
377 * Skip descriptor addresses which can cause 4KB
378 * boundary crossing (addr + length) with a 32 dword
379 * descriptor fetch.
380 */
381 while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
382 BUG_ON((caddr_t) bf->bf_desc >=
383 ((caddr_t) dd->dd_desc +
384 dd->dd_desc_len));
385
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400386 ds += (desc_len * ndesc);
Sujith55624202010-01-08 10:36:02 +0530387 bf->bf_desc = ds;
388 bf->bf_daddr = DS2PHYS(dd, ds);
389 }
390 }
391 list_add_tail(&bf->list, head);
392 }
393 return 0;
394fail2:
395 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
396 dd->dd_desc_paddr);
397fail:
398 memset(dd, 0, sizeof(*dd));
399 return error;
400#undef ATH_DESC_4KB_BOUND_CHECK
401#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
402#undef DS2PHYS
403}
404
Mohammed Shafi Shajakhandb7ec382010-12-22 12:20:12 +0530405void ath9k_init_crypto(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530406{
Sujith285f2dd2010-01-08 10:36:07 +0530407 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
408 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530409
410 /* Get the hardware key cache size. */
Felix Fietkau6de12a12011-03-23 20:57:31 +0100411 common->keymax = AR_KEYTABLE_SIZE;
Sujith55624202010-01-08 10:36:02 +0530412
413 /*
414 * Reset the key cache since some parts do not
415 * reset the contents on initial power up.
416 */
417 for (i = 0; i < common->keymax; i++)
Bruno Randolf040e5392010-09-08 16:05:04 +0900418 ath_hw_keyreset(common, (u16) i);
Sujith55624202010-01-08 10:36:02 +0530419
Felix Fietkau716f7fc2010-06-12 17:22:28 +0200420 /*
Sujith55624202010-01-08 10:36:02 +0530421 * Check whether the separate key cache entries
422 * are required to handle both tx+rx MIC keys.
423 * With split mic keys the number of stations is limited
424 * to 27 otherwise 59.
425 */
Bruno Randolf117675d2010-09-08 16:04:54 +0900426 if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
427 common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
Sujith285f2dd2010-01-08 10:36:07 +0530428}
Sujith55624202010-01-08 10:36:02 +0530429
Sujith285f2dd2010-01-08 10:36:07 +0530430static int ath9k_init_btcoex(struct ath_softc *sc)
431{
Felix Fietkau066dae92010-11-07 14:59:39 +0100432 struct ath_txq *txq;
433 int r;
Sujith285f2dd2010-01-08 10:36:07 +0530434
435 switch (sc->sc_ah->btcoex_hw.scheme) {
436 case ATH_BTCOEX_CFG_NONE:
437 break;
438 case ATH_BTCOEX_CFG_2WIRE:
439 ath9k_hw_btcoex_init_2wire(sc->sc_ah);
440 break;
441 case ATH_BTCOEX_CFG_3WIRE:
442 ath9k_hw_btcoex_init_3wire(sc->sc_ah);
443 r = ath_init_btcoex_timer(sc);
444 if (r)
445 return -1;
Felix Fietkau066dae92010-11-07 14:59:39 +0100446 txq = sc->tx.txq_map[WME_AC_BE];
447 ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
Sujith285f2dd2010-01-08 10:36:07 +0530448 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
449 break;
450 default:
451 WARN_ON(1);
452 break;
Sujith55624202010-01-08 10:36:02 +0530453 }
454
Sujith285f2dd2010-01-08 10:36:07 +0530455 return 0;
456}
Sujith55624202010-01-08 10:36:02 +0530457
Sujith285f2dd2010-01-08 10:36:07 +0530458static int ath9k_init_queues(struct ath_softc *sc)
459{
Sujith285f2dd2010-01-08 10:36:07 +0530460 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530461
Sujith285f2dd2010-01-08 10:36:07 +0530462 sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
Sujith285f2dd2010-01-08 10:36:07 +0530463 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
Sujith55624202010-01-08 10:36:02 +0530464
Sujith285f2dd2010-01-08 10:36:07 +0530465 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
466 ath_cabq_update(sc);
467
Ben Greear60f2d1d2011-01-09 23:11:52 -0800468 for (i = 0; i < WME_NUM_AC; i++) {
Felix Fietkau066dae92010-11-07 14:59:39 +0100469 sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
Ben Greear60f2d1d2011-01-09 23:11:52 -0800470 sc->tx.txq_map[i]->mac80211_qnum = i;
471 }
Sujith285f2dd2010-01-08 10:36:07 +0530472 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530473}
474
Felix Fietkauf209f522010-10-01 01:06:53 +0200475static int ath9k_init_channels_rates(struct ath_softc *sc)
Sujith285f2dd2010-01-08 10:36:07 +0530476{
Felix Fietkauf209f522010-10-01 01:06:53 +0200477 void *channels;
478
Felix Fietkaucac42202010-10-09 02:39:30 +0200479 BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
480 ARRAY_SIZE(ath9k_5ghz_chantable) !=
481 ATH9K_NUM_CHANNELS);
482
Felix Fietkaud4659912010-10-14 16:02:39 +0200483 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
Felix Fietkauf209f522010-10-01 01:06:53 +0200484 channels = kmemdup(ath9k_2ghz_chantable,
485 sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
486 if (!channels)
487 return -ENOMEM;
488
489 sc->sbands[IEEE80211_BAND_2GHZ].channels = channels;
Sujith55624202010-01-08 10:36:02 +0530490 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
491 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
492 ARRAY_SIZE(ath9k_2ghz_chantable);
493 sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
494 sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
495 ARRAY_SIZE(ath9k_legacy_rates);
496 }
497
Felix Fietkaud4659912010-10-14 16:02:39 +0200498 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
Felix Fietkauf209f522010-10-01 01:06:53 +0200499 channels = kmemdup(ath9k_5ghz_chantable,
500 sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
501 if (!channels) {
502 if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
503 kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
504 return -ENOMEM;
505 }
506
507 sc->sbands[IEEE80211_BAND_5GHZ].channels = channels;
Sujith55624202010-01-08 10:36:02 +0530508 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
509 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
510 ARRAY_SIZE(ath9k_5ghz_chantable);
511 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
512 ath9k_legacy_rates + 4;
513 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
514 ARRAY_SIZE(ath9k_legacy_rates) - 4;
515 }
Felix Fietkauf209f522010-10-01 01:06:53 +0200516 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530517}
Sujith55624202010-01-08 10:36:02 +0530518
Sujith285f2dd2010-01-08 10:36:07 +0530519static void ath9k_init_misc(struct ath_softc *sc)
520{
521 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
522 int i = 0;
Sujith285f2dd2010-01-08 10:36:07 +0530523 setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
524
525 sc->config.txpowlimit = ATH_TXPOWER_MAX;
526
527 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
528 sc->sc_flags |= SC_OP_TXAGGR;
529 sc->sc_flags |= SC_OP_RXAGGR;
Sujith55624202010-01-08 10:36:02 +0530530 }
531
Sujith285f2dd2010-01-08 10:36:07 +0530532 common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
533 common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
534
Luis R. Rodriguez8fe65362010-04-15 17:38:14 -0400535 ath9k_hw_set_diversity(sc->sc_ah, true);
Sujith285f2dd2010-01-08 10:36:07 +0530536 sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
537
Felix Fietkau364734f2010-09-14 20:22:44 +0200538 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
Sujith285f2dd2010-01-08 10:36:07 +0530539
540 sc->beacon.slottime = ATH9K_SLOT_TIME_9;
541
Felix Fietkau7545daf2011-01-24 19:23:16 +0100542 for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
Sujith285f2dd2010-01-08 10:36:07 +0530543 sc->beacon.bslot[i] = NULL;
Vasanthakumar Thiagarajan102885a2010-09-02 01:34:43 -0700544
545 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
546 sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT;
Sujith285f2dd2010-01-08 10:36:07 +0530547}
548
549static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
550 const struct ath_bus_ops *bus_ops)
551{
Felix Fietkau6fb1b1e2011-03-19 13:55:39 +0100552 struct ath9k_platform_data *pdata = sc->dev->platform_data;
Sujith285f2dd2010-01-08 10:36:07 +0530553 struct ath_hw *ah = NULL;
554 struct ath_common *common;
555 int ret = 0, i;
556 int csz = 0;
557
Sujith285f2dd2010-01-08 10:36:07 +0530558 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
559 if (!ah)
560 return -ENOMEM;
561
Ben Greear233536e2011-01-09 23:11:44 -0800562 ah->hw = sc->hw;
Sujith285f2dd2010-01-08 10:36:07 +0530563 ah->hw_version.devid = devid;
564 ah->hw_version.subsysid = subsysid;
Felix Fietkauf9f84e92011-03-23 20:57:24 +0100565 ah->reg_ops.read = ath9k_ioread32;
566 ah->reg_ops.write = ath9k_iowrite32;
Felix Fietkau845e03c2011-03-23 20:57:25 +0100567 ah->reg_ops.rmw = ath9k_reg_rmw;
Sujith285f2dd2010-01-08 10:36:07 +0530568 sc->sc_ah = ah;
569
Felix Fietkau6de66dd2011-03-19 13:55:40 +0100570 if (!pdata) {
Felix Fietkaua05b5d42010-11-17 04:25:33 +0100571 ah->ah_flags |= AH_USE_EEPROM;
Felix Fietkau6de66dd2011-03-19 13:55:40 +0100572 sc->sc_ah->led_pin = -1;
573 } else {
574 sc->sc_ah->gpio_mask = pdata->gpio_mask;
575 sc->sc_ah->gpio_val = pdata->gpio_val;
576 sc->sc_ah->led_pin = pdata->led_pin;
Vasanthakumar Thiagarajanf2f5f2a2011-04-19 19:29:01 +0530577 ah->is_clk_25mhz = pdata->is_clk_25mhz;
Felix Fietkau6de66dd2011-03-19 13:55:40 +0100578 }
Felix Fietkaua05b5d42010-11-17 04:25:33 +0100579
Sujith285f2dd2010-01-08 10:36:07 +0530580 common = ath9k_hw_common(ah);
Felix Fietkauf9f84e92011-03-23 20:57:24 +0100581 common->ops = &ah->reg_ops;
Sujith285f2dd2010-01-08 10:36:07 +0530582 common->bus_ops = bus_ops;
583 common->ah = ah;
584 common->hw = sc->hw;
585 common->priv = sc;
586 common->debug_mask = ath9k_debug;
Vasanthakumar Thiagarajan8f5dcb12010-11-26 06:10:06 -0800587 common->btcoex_enabled = ath9k_btcoex_enable == 1;
Mohammed Shafi Shajakhan05c0be22011-05-26 10:56:15 +0530588 common->disable_ani = false;
Ben Greear20b25742010-10-15 15:04:09 -0700589 spin_lock_init(&common->cc_lock);
Sujith285f2dd2010-01-08 10:36:07 +0530590
Sujith285f2dd2010-01-08 10:36:07 +0530591 spin_lock_init(&sc->sc_serial_rw);
592 spin_lock_init(&sc->sc_pm_lock);
593 mutex_init(&sc->mutex);
Ben Greear7f010c92011-01-09 23:11:49 -0800594#ifdef CONFIG_ATH9K_DEBUGFS
595 spin_lock_init(&sc->nodes_lock);
596 INIT_LIST_HEAD(&sc->nodes);
597#endif
Sujith285f2dd2010-01-08 10:36:07 +0530598 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
599 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
600 (unsigned long)sc);
601
602 /*
603 * Cache line size is used to size and align various
604 * structures used to communicate with the hardware.
605 */
606 ath_read_cachesize(common, &csz);
607 common->cachelsz = csz << 2; /* convert to bytes */
608
Luis R. Rodriguezd70357d2010-04-15 17:38:06 -0400609 /* Initializes the hardware for all supported chipsets */
Sujith285f2dd2010-01-08 10:36:07 +0530610 ret = ath9k_hw_init(ah);
Luis R. Rodriguezd70357d2010-04-15 17:38:06 -0400611 if (ret)
Sujith285f2dd2010-01-08 10:36:07 +0530612 goto err_hw;
Sujith285f2dd2010-01-08 10:36:07 +0530613
Felix Fietkau6fb1b1e2011-03-19 13:55:39 +0100614 if (pdata && pdata->macaddr)
615 memcpy(common->macaddr, pdata->macaddr, ETH_ALEN);
616
Sujith285f2dd2010-01-08 10:36:07 +0530617 ret = ath9k_init_queues(sc);
618 if (ret)
619 goto err_queues;
620
621 ret = ath9k_init_btcoex(sc);
622 if (ret)
623 goto err_btcoex;
624
Felix Fietkauf209f522010-10-01 01:06:53 +0200625 ret = ath9k_init_channels_rates(sc);
626 if (ret)
627 goto err_btcoex;
628
Sujith285f2dd2010-01-08 10:36:07 +0530629 ath9k_init_crypto(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530630 ath9k_init_misc(sc);
631
Sujith55624202010-01-08 10:36:02 +0530632 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530633
634err_btcoex:
Sujith55624202010-01-08 10:36:02 +0530635 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
636 if (ATH_TXQ_SETUP(sc, i))
637 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
Sujith285f2dd2010-01-08 10:36:07 +0530638err_queues:
Sujith285f2dd2010-01-08 10:36:07 +0530639 ath9k_hw_deinit(ah);
640err_hw:
Sujith55624202010-01-08 10:36:02 +0530641
Sujith285f2dd2010-01-08 10:36:07 +0530642 kfree(ah);
643 sc->sc_ah = NULL;
644
645 return ret;
Sujith55624202010-01-08 10:36:02 +0530646}
647
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200648static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
649{
650 struct ieee80211_supported_band *sband;
651 struct ieee80211_channel *chan;
652 struct ath_hw *ah = sc->sc_ah;
653 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
654 int i;
655
656 sband = &sc->sbands[band];
657 for (i = 0; i < sband->n_channels; i++) {
658 chan = &sband->channels[i];
659 ah->curchan = &ah->channels[chan->hw_value];
660 ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
661 ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
662 chan->max_power = reg->max_power_level / 2;
663 }
664}
665
666static void ath9k_init_txpower_limits(struct ath_softc *sc)
667{
668 struct ath_hw *ah = sc->sc_ah;
669 struct ath9k_channel *curchan = ah->curchan;
670
671 if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
672 ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
673 if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
674 ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
675
676 ah->curchan = curchan;
677}
678
Sujith285f2dd2010-01-08 10:36:07 +0530679void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
Sujith55624202010-01-08 10:36:02 +0530680{
Sujith285f2dd2010-01-08 10:36:07 +0530681 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
682
Sujith55624202010-01-08 10:36:02 +0530683 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
684 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
685 IEEE80211_HW_SIGNAL_DBM |
Sujith55624202010-01-08 10:36:02 +0530686 IEEE80211_HW_SUPPORTS_PS |
687 IEEE80211_HW_PS_NULLFUNC_STACK |
Vivek Natarajan05df4982010-02-09 11:34:50 +0530688 IEEE80211_HW_SPECTRUM_MGMT |
Mohammed Shafi Shajakhanbd8027a2010-12-30 12:18:01 +0530689 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
Sujith55624202010-01-08 10:36:02 +0530690
Luis R. Rodriguez5ffaf8a2010-02-02 11:58:33 -0500691 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
692 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
693
John W. Linville3e6109c2011-01-05 09:39:17 -0500694 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
Sujith55624202010-01-08 10:36:02 +0530695 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
696
697 hw->wiphy->interface_modes =
Johannes Bergc426ee22010-11-26 11:38:04 +0100698 BIT(NL80211_IFTYPE_P2P_GO) |
699 BIT(NL80211_IFTYPE_P2P_CLIENT) |
Sujith55624202010-01-08 10:36:02 +0530700 BIT(NL80211_IFTYPE_AP) |
Bill Jordane51f3ef2010-10-01 11:20:39 -0400701 BIT(NL80211_IFTYPE_WDS) |
Sujith55624202010-01-08 10:36:02 +0530702 BIT(NL80211_IFTYPE_STATION) |
703 BIT(NL80211_IFTYPE_ADHOC) |
704 BIT(NL80211_IFTYPE_MESH_POINT);
705
Luis R. Rodriguez008443d2010-09-16 15:12:36 -0400706 if (AR_SREV_5416(sc->sc_ah))
707 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
Sujith55624202010-01-08 10:36:02 +0530708
Jouni Malinencfdc9a82011-03-23 14:52:19 +0200709 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
710
Sujith55624202010-01-08 10:36:02 +0530711 hw->queues = 4;
712 hw->max_rates = 4;
713 hw->channel_change_time = 5000;
714 hw->max_listen_interval = 10;
Felix Fietkau65896512010-01-24 03:26:11 +0100715 hw->max_rate_tries = 10;
Sujith55624202010-01-08 10:36:02 +0530716 hw->sta_data_size = sizeof(struct ath_node);
717 hw->vif_data_size = sizeof(struct ath_vif);
718
Felix Fietkau6e5c2b42010-09-20 13:45:40 +0200719#ifdef CONFIG_ATH9K_RATE_CONTROL
Sujith55624202010-01-08 10:36:02 +0530720 hw->rate_control_algorithm = "ath9k_rate_control";
Felix Fietkau6e5c2b42010-09-20 13:45:40 +0200721#endif
Sujith55624202010-01-08 10:36:02 +0530722
Felix Fietkaud4659912010-10-14 16:02:39 +0200723 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
Sujith55624202010-01-08 10:36:02 +0530724 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
725 &sc->sbands[IEEE80211_BAND_2GHZ];
Felix Fietkaud4659912010-10-14 16:02:39 +0200726 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
Sujith55624202010-01-08 10:36:02 +0530727 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
728 &sc->sbands[IEEE80211_BAND_5GHZ];
Sujith285f2dd2010-01-08 10:36:07 +0530729
730 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
Felix Fietkaud4659912010-10-14 16:02:39 +0200731 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
Sujith285f2dd2010-01-08 10:36:07 +0530732 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
Felix Fietkaud4659912010-10-14 16:02:39 +0200733 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
Sujith285f2dd2010-01-08 10:36:07 +0530734 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
735 }
736
737 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
Sujith55624202010-01-08 10:36:02 +0530738}
739
Sujith285f2dd2010-01-08 10:36:07 +0530740int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
Sujith55624202010-01-08 10:36:02 +0530741 const struct ath_bus_ops *bus_ops)
742{
743 struct ieee80211_hw *hw = sc->hw;
744 struct ath_common *common;
745 struct ath_hw *ah;
Sujith285f2dd2010-01-08 10:36:07 +0530746 int error = 0;
Sujith55624202010-01-08 10:36:02 +0530747 struct ath_regulatory *reg;
748
Sujith285f2dd2010-01-08 10:36:07 +0530749 /* Bring up device */
750 error = ath9k_init_softc(devid, sc, subsysid, bus_ops);
Sujith55624202010-01-08 10:36:02 +0530751 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530752 goto error_init;
Sujith55624202010-01-08 10:36:02 +0530753
754 ah = sc->sc_ah;
755 common = ath9k_hw_common(ah);
Sujith285f2dd2010-01-08 10:36:07 +0530756 ath9k_set_hw_capab(sc, hw);
Sujith55624202010-01-08 10:36:02 +0530757
Sujith285f2dd2010-01-08 10:36:07 +0530758 /* Initialize regulatory */
Sujith55624202010-01-08 10:36:02 +0530759 error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
760 ath9k_reg_notifier);
761 if (error)
Sujith285f2dd2010-01-08 10:36:07 +0530762 goto error_regd;
Sujith55624202010-01-08 10:36:02 +0530763
764 reg = &common->regulatory;
765
Sujith285f2dd2010-01-08 10:36:07 +0530766 /* Setup TX DMA */
Sujith55624202010-01-08 10:36:02 +0530767 error = ath_tx_init(sc, ATH_TXBUF);
768 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530769 goto error_tx;
Sujith55624202010-01-08 10:36:02 +0530770
Sujith285f2dd2010-01-08 10:36:07 +0530771 /* Setup RX DMA */
Sujith55624202010-01-08 10:36:02 +0530772 error = ath_rx_init(sc, ATH_RXBUF);
773 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530774 goto error_rx;
775
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200776 ath9k_init_txpower_limits(sc);
777
Felix Fietkau0cf55c22011-02-27 22:26:40 +0100778#ifdef CONFIG_MAC80211_LEDS
779 /* must be initialized before ieee80211_register_hw */
780 sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
781 IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
782 ARRAY_SIZE(ath9k_tpt_blink));
783#endif
784
Sujith285f2dd2010-01-08 10:36:07 +0530785 /* Register with mac80211 */
786 error = ieee80211_register_hw(hw);
787 if (error)
788 goto error_register;
789
Ben Greeareb272442010-11-29 14:13:22 -0800790 error = ath9k_init_debug(ah);
791 if (error) {
Joe Perches38002762010-12-02 19:12:36 -0800792 ath_err(common, "Unable to create debugfs files\n");
Ben Greeareb272442010-11-29 14:13:22 -0800793 goto error_world;
794 }
795
Sujith285f2dd2010-01-08 10:36:07 +0530796 /* Handle world regulatory */
797 if (!ath_is_world_regd(reg)) {
798 error = regulatory_hint(hw->wiphy, reg->alpha2);
799 if (error)
800 goto error_world;
801 }
Sujith55624202010-01-08 10:36:02 +0530802
Felix Fietkau347809f2010-07-02 00:09:52 +0200803 INIT_WORK(&sc->hw_check_work, ath_hw_check);
Felix Fietkau9f42c2b2010-06-12 00:34:01 -0400804 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
Senthil Balasubramanian9eab61c2011-04-22 11:32:11 +0530805 INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
Felix Fietkau9ac58612011-01-24 19:23:18 +0100806 sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
Sujith55624202010-01-08 10:36:02 +0530807
Sujith55624202010-01-08 10:36:02 +0530808 ath_init_leds(sc);
Sujith55624202010-01-08 10:36:02 +0530809 ath_start_rfkill_poll(sc);
810
811 return 0;
812
Sujith285f2dd2010-01-08 10:36:07 +0530813error_world:
814 ieee80211_unregister_hw(hw);
815error_register:
816 ath_rx_cleanup(sc);
817error_rx:
818 ath_tx_cleanup(sc);
819error_tx:
820 /* Nothing */
821error_regd:
822 ath9k_deinit_softc(sc);
823error_init:
Sujith55624202010-01-08 10:36:02 +0530824 return error;
825}
826
827/*****************************/
828/* De-Initialization */
829/*****************************/
830
Sujith285f2dd2010-01-08 10:36:07 +0530831static void ath9k_deinit_softc(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530832{
Sujith285f2dd2010-01-08 10:36:07 +0530833 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530834
Felix Fietkauf209f522010-10-01 01:06:53 +0200835 if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
836 kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
837
838 if (sc->sbands[IEEE80211_BAND_5GHZ].channels)
839 kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels);
840
Sujith285f2dd2010-01-08 10:36:07 +0530841 if ((sc->btcoex.no_stomp_timer) &&
842 sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
843 ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
Sujith55624202010-01-08 10:36:02 +0530844
Sujith285f2dd2010-01-08 10:36:07 +0530845 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
846 if (ATH_TXQ_SETUP(sc, i))
847 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
848
Sujith285f2dd2010-01-08 10:36:07 +0530849 ath9k_hw_deinit(sc->sc_ah);
850
Sujith736b3a22010-03-17 14:25:24 +0530851 kfree(sc->sc_ah);
852 sc->sc_ah = NULL;
Sujith55624202010-01-08 10:36:02 +0530853}
854
Sujith285f2dd2010-01-08 10:36:07 +0530855void ath9k_deinit_device(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530856{
857 struct ieee80211_hw *hw = sc->hw;
Sujith55624202010-01-08 10:36:02 +0530858
859 ath9k_ps_wakeup(sc);
860
Sujith55624202010-01-08 10:36:02 +0530861 wiphy_rfkill_stop_polling(sc->hw->wiphy);
Sujith285f2dd2010-01-08 10:36:07 +0530862 ath_deinit_leds(sc);
Sujith55624202010-01-08 10:36:02 +0530863
Rajkumar Manoharanc7c18062011-01-27 18:39:38 +0530864 ath9k_ps_restore(sc);
865
Sujith55624202010-01-08 10:36:02 +0530866 ieee80211_unregister_hw(hw);
867 ath_rx_cleanup(sc);
868 ath_tx_cleanup(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530869 ath9k_deinit_softc(sc);
Sujith55624202010-01-08 10:36:02 +0530870}
871
872void ath_descdma_cleanup(struct ath_softc *sc,
873 struct ath_descdma *dd,
874 struct list_head *head)
875{
876 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
877 dd->dd_desc_paddr);
878
879 INIT_LIST_HEAD(head);
880 kfree(dd->dd_bufptr);
881 memset(dd, 0, sizeof(*dd));
882}
883
Sujith55624202010-01-08 10:36:02 +0530884/************************/
885/* Module Hooks */
886/************************/
887
888static int __init ath9k_init(void)
889{
890 int error;
891
892 /* Register rate control algorithm */
893 error = ath_rate_control_register();
894 if (error != 0) {
895 printk(KERN_ERR
896 "ath9k: Unable to register rate control "
897 "algorithm: %d\n",
898 error);
899 goto err_out;
900 }
901
Sujith55624202010-01-08 10:36:02 +0530902 error = ath_pci_init();
903 if (error < 0) {
904 printk(KERN_ERR
905 "ath9k: No PCI devices found, driver not installed.\n");
906 error = -ENODEV;
Ben Greeareb272442010-11-29 14:13:22 -0800907 goto err_rate_unregister;
Sujith55624202010-01-08 10:36:02 +0530908 }
909
910 error = ath_ahb_init();
911 if (error < 0) {
912 error = -ENODEV;
913 goto err_pci_exit;
914 }
915
916 return 0;
917
918 err_pci_exit:
919 ath_pci_exit();
920
Sujith55624202010-01-08 10:36:02 +0530921 err_rate_unregister:
922 ath_rate_control_unregister();
923 err_out:
924 return error;
925}
926module_init(ath9k_init);
927
928static void __exit ath9k_exit(void)
929{
Rajkumar Manoharand5847472010-12-20 14:39:51 +0530930 is_ath9k_unloaded = true;
Sujith55624202010-01-08 10:36:02 +0530931 ath_ahb_exit();
932 ath_pci_exit();
Sujith55624202010-01-08 10:36:02 +0530933 ath_rate_control_unregister();
934 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
935}
936module_exit(ath9k_exit);